From 101cea8c3e61fa6635817a928b43eaa72303c32d Mon Sep 17 00:00:00 2001 From: Pham Hai Duong Date: Mon, 13 Jul 2020 15:39:02 +0700 Subject: [PATCH 1/4] feat: #1038 pwa for geo-diary-v2 (#2045) --- package.json | 2 +- packages/geo-diary-v2/manifest.json | 25 ++ packages/geo-diary-v2/package.json | 2 +- packages/geo-diary-v2/src/core/index.tsx | 10 +- .../geo-diary-v2/src/core/service-worker.ts | 140 +++++++++ scripts/webpack/webpack.pwa.prod.js | 293 ++++++++++++++++++ yarn.lock | 273 ++++++++-------- 7 files changed, 617 insertions(+), 128 deletions(-) create mode 100644 packages/geo-diary-v2/manifest.json create mode 100644 packages/geo-diary-v2/src/core/service-worker.ts create mode 100644 scripts/webpack/webpack.pwa.prod.js diff --git a/package.json b/package.json index 4afdd6910a..5646cf6718 100644 --- a/package.json +++ b/package.json @@ -179,6 +179,6 @@ "webpack": "^4.41.5", "webpack-cli": "^3.3.2", "webpack-dev-server": "^3.4.1", - "workbox-webpack-plugin": "^4.3.1" + "workbox-webpack-plugin": "^5.1.3" } } diff --git a/packages/geo-diary-v2/manifest.json b/packages/geo-diary-v2/manifest.json new file mode 100644 index 0000000000..f83ccae22b --- /dev/null +++ b/packages/geo-diary-v2/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "Geo Diary", + "name": "Geo Diary App", + "icons": [ + { + "src": "logo.png", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/packages/geo-diary-v2/package.json b/packages/geo-diary-v2/package.json index f620e9c61d..16be1c105e 100644 --- a/packages/geo-diary-v2/package.json +++ b/packages/geo-diary-v2/package.json @@ -11,7 +11,7 @@ "author": "Reapit", "main": "./src/index.ts", "scripts": { - "build:prod": "rimraf public/dist && webpack --config ../../scripts/webpack/webpack.config.prod.js", + "build:prod": "rimraf public/dist && webpack --config ../../scripts/webpack/webpack.pwa.prod.js", "fetch-config": "yarn config-manager fetchConfig geo-diary-v2", "release:dev": "node ../../scripts/release/release-dev.js geo-diary-v2 reapit-geo-diary-v2-dev", "start:dev": "webpack-dev-server --hot --progress --color --mode development --config ../../scripts/webpack/webpack.config.dev.js", diff --git a/packages/geo-diary-v2/src/core/index.tsx b/packages/geo-diary-v2/src/core/index.tsx index e591f430fa..9fd00545aa 100644 --- a/packages/geo-diary-v2/src/core/index.tsx +++ b/packages/geo-diary-v2/src/core/index.tsx @@ -1,4 +1,5 @@ import * as Sentry from '@sentry/browser' +import { injectSwitchModeToWindow } from '@reapit/elements' import load from 'little-loader' import qs from 'query-string' import React from 'react' @@ -6,7 +7,7 @@ import { render } from 'react-dom' import ReactGA from 'react-ga' import { Config } from '@/types/global' import App from './app' -import { injectSwitchModeToWindow } from '@reapit/elements' +import * as serviceWorker from './service-worker' injectSwitchModeToWindow() @@ -71,3 +72,10 @@ if (module['hot']) { } run() +if (process.env.NODE_ENV === 'development') { + serviceWorker.unregister() + console.info(`UnRegister-${process.env.APP_VERSION}`) +} else { + serviceWorker.register() + console.info(`Register-${process.env.APP_VERSION}`) +} diff --git a/packages/geo-diary-v2/src/core/service-worker.ts b/packages/geo-diary-v2/src/core/service-worker.ts new file mode 100644 index 0000000000..b06a126765 --- /dev/null +++ b/packages/geo-diary-v2/src/core/service-worker.ts @@ -0,0 +1,140 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +import { notification } from '@reapit/elements' + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://bit.ly/CRA-PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/), +) + +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void + onUpdate?: (registration: ServiceWorkerRegistration) => void +} + +export function register(config?: Config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL('/', window.location.href) + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return + } + + window.addEventListener('load', () => { + const swUrl = '/service-worker.js' + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config) + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA', + ) + }) + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config) + } + }) + } +} + +function registerValidSW(swUrl: string, config?: Config) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing + if (installingWorker == null) { + return + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + notification.success({ + message: 'New version available, please press CTRL-SHIFT-R to update', + duration: 0, + placement: 'bottomRight', + }) + + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.', + ) + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration) + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.') + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration) + } + } + } + } + } + }) + .catch(error => { + console.error('Error during service worker registration:', error) + }) +} + +function checkValidServiceWorker(swUrl: string, config?: Config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' }, + }) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type') + if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload() + }) + }) + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config) + } + }) + .catch(() => { + console.log('No internet connection found. App is running in offline mode.') + }) +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister() + }) + } +} diff --git a/scripts/webpack/webpack.pwa.prod.js b/scripts/webpack/webpack.pwa.prod.js new file mode 100644 index 0000000000..48de570e93 --- /dev/null +++ b/scripts/webpack/webpack.pwa.prod.js @@ -0,0 +1,293 @@ +const path = require('path') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FaviconsWebpackPlugin = require('favicons-webpack-plugin') +const WorkboxWebpackPlugin = require('workbox-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const ResolveTSPathsToWebpackAlias = require('ts-paths-to-webpack-alias') +const CopyPlugin = require('copy-webpack-plugin') +const SentryWebpackPlugin = require('@sentry/webpack-plugin') +const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') +const { EnvironmentPlugin, SourceMapDevToolPlugin, HashedModuleIdsPlugin } = require('webpack') +const { PATHS } = require('./constants') +const hashFiles = require('../utils/hash-files') +const { getVersionTag, getRef } = require('../release/utils') + +const EXCLUDE_PACKAGES = ['linaria'] + +const generateRegexExcludePackages = () => { + const listPackagesString = EXCLUDE_PACKAGES.join('|') + return new RegExp(`node_modules/(?!(${listPackagesString})/).*`) +} + +const tagName = getVersionTag() +const hashOfCommit = getRef() +const APP_VERSION = `${tagName.packageName}_${tagName.version}` +const outputFileName = `[name].${hashOfCommit}.js` + +const babelLoaderOptions = { + presets: [ + [ + '@babel/preset-env', + { + useBuiltIns: 'entry', + corejs: '3', + targets: { + chrome: '58', + ie: '11', + }, + }, + ], + 'linaria/babel', + ], +} + +const webpackConfig = { + mode: 'production', + bail: true, + context: process.cwd(), + entry: ['@babel/polyfill', 'core-js', 'isomorphic-fetch', 'regenerator-runtime/runtime', PATHS.entryWeb], + output: { + path: PATHS.output, + filename: outputFileName, + }, + optimization: { + nodeEnv: 'production', + splitChunks: { + cacheGroups: { + styles: { + name: 'styles', + test: /\.css$/, + chunks: 'all', + enforce: true, + }, + }, + chunks: 'all', + }, + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: generateRegexExcludePackages(), + use: { + loader: 'babel-loader', + options: babelLoaderOptions, + }, + }, + { + test: /.tsx?$/, + exclude: generateRegexExcludePackages(), + use: [ + { + loader: 'cache-loader', + options: { + // each package has its own .webpack-cache + cacheDirectory: `${PATHS.cacheWebpackDir}/cache-loader`, + // use yarn.lock at the root of the monorepo as hash, relative to this file + cacheIdentifier: hashFiles([path.join(__dirname, '../..', 'yarn.lock')]), + }, + }, + 'thread-loader', + { + loader: 'babel-loader', + options: babelLoaderOptions, + }, + { + loader: 'linaria/loader', + options: { + sourceMap: process.env.NODE_ENV !== 'production', + }, + }, + { loader: 'ts-loader', options: { happyPackMode: true, transpileOnly: true } }, + ], + }, + { + test: /\.(css)$/, + use: [ + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { + importLoaders: 1, + }, + }, + 'postcss-loader', + ], + }, + { + test: /\.(sass|scss)$/, + oneOf: [ + { + resourceQuery: /\?mod$/, + use: [ + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { + importLoaders: 1, + modules: { + localIdentName: '[hash:base64:5]', + }, + localsConvention: 'camelCase', + }, + }, + 'postcss-loader', + { + loader: 'sass-loader', + options: { + sourceMap: false, + }, + }, + ], + }, + { + use: [ + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { + importLoaders: 1, + }, + }, + 'postcss-loader', + { + loader: 'sass-loader', + options: { + sourceMap: false, + }, + }, + ], + }, + ], + }, + { + test: /\.(graphql|gql)$/, + exclude: /node_modules/, + use: 'graphql-tag/loader', + }, + { + test: /\.(woff(2)?|ttf|eot|svg|png|jpg|jpeg|gif|pdf)$/, + use: [ + { + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: '/assets', + }, + }, + ], + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + alias: { + '@': `${PATHS.src}/`, + }, + }, + stats: { + cached: false, + cachedAssets: false, + chunks: false, + chunkModules: false, + chunkOrigins: false, + modules: false, + }, + plugins: [ + new ResolveTSPathsToWebpackAlias({ + tsconfig: PATHS.tsConfig, + }), + new SourceMapDevToolPlugin({ + filename: '[file].map', + }), + new CopyPlugin([ + { from: 'config.json', to: PATHS.output }, + { from: 'manifest.json', to: PATHS.output }, + ]), + new HtmlWebpackPlugin({ + hash: true, + inject: true, + template: PATHS.template, + minify: { + removeComments: true, + collapseWhitespace: true, + removeRedundantAttributes: true, + useShortDoctype: true, + removeEmptyAttributes: true, + removeStyleLinkTypeAttributes: true, + keepClosingSlash: true, + minifyJS: true, + minifyCSS: true, + minifyURLs: true, + }, + }), + new MiniCssExtractPlugin({ + filename: 'styles.css', + }), + new FaviconsWebpackPlugin({ + logo: PATHS.logo, + emitStats: false, + persistentCache: true, + inject: true, + background: '#fff', + title: 'Reapit', + icons: { + android: true, + appleIcon: true, + appleStartup: true, + coast: false, + favicons: true, + firefox: true, + opengraph: false, + twitter: false, + yandex: false, + windows: false, + }, + }), + new EnvironmentPlugin({ + APP_VERSION: APP_VERSION, + }), + new WorkboxWebpackPlugin.GenerateSW({ + clientsClaim: true, + exclude: [/\.map$/, /asset-manifest\.json$/], + navigateFallback: '/index.html', + navigateFallbackDenylist: [ + // Exclude URLs starting with /_, as they're likely an API call + new RegExp('^/_'), + // Exclude any URLs whose last part seems to be a file extension + // as they're likely a resource and not a SPA route. + // URLs containing a "?" character won't be blacklisted as they're likely + // a route with query params (e.g. auth callbacks). + new RegExp('/[^/?]+\\.[^/]+$'), + ], + }), + new HashedModuleIdsPlugin(), + new HardSourceWebpackPlugin({ + // each package has its own .webpack-cache + cacheDirectory: `${PATHS.cacheWebpackDir}/hard-source/[confighash]`, + environmentHash: { + root: path.join(__dirname, '../..'), + directories: [], + // use yarn.lock at the root of the monorepo as hash, relative to this file + files: ['yarn.lock'], + }, + }), + ], +} + +if (process.env.IS_RELEASE) { + webpackConfig.plugins.push( + new SentryWebpackPlugin({ + release: APP_VERSION, + include: './public/dist/', + ignore: ['node_modules', 'webpack.config.js'], + configFile: '.sentryclirc', + setCommits: { + repo: 'reapit/foundations', + auto: true, + }, + }), + ) +} + +module.exports = webpackConfig diff --git a/yarn.lock b/yarn.lock index 6d950d511c..e996c5c909 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1163,7 +1163,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@7.10.2", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2", "@babel/runtime@^7.9.6": +"@babel/runtime@7.10.2", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2", "@babel/runtime@^7.9.6": version "7.10.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839" integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg== @@ -1832,7 +1832,7 @@ "@hapi/cryptiles" "4.x.x" "@hapi/hoek" "8.x.x" -"@hapi/joi@15.x.x", "@hapi/joi@^15.0.0": +"@hapi/joi@15.x.x", "@hapi/joi@^15.1.0": version "15.1.1" resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== @@ -5314,6 +5314,14 @@ telejson "^3.2.0" util-deprecate "^1.0.2" +"@surma/rollup-plugin-off-main-thread@^1.1.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.1.tgz#bf1343e5a926e5a1da55e3affd761dda4ce143ef" + integrity sha512-ZPBWYQDdO4JZiTmTP3DABsHhIPA7bEJk9Znk7tZsrbPGanoGo8YxMv//WLx5Cvb+lRgS42+6yiOIYYHCKDmkpQ== + dependencies: + ejs "^2.6.1" + magic-string "^0.25.0" + "@svgr/babel-plugin-add-jsx-attribute@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" @@ -13441,7 +13449,7 @@ fast-json-patch@~2.1.0: dependencies: deep-equal "^1.0.1" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -14131,7 +14139,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^4.0.2, fs-extra@^4.0.3: +fs-extra@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== @@ -18477,13 +18485,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -18544,11 +18545,6 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -19646,7 +19642,7 @@ macos-release@^2.2.0: resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== -magic-string@^0.25.2, magic-string@^0.25.5, magic-string@^0.25.7: +magic-string@^0.25.0, magic-string@^0.25.2, magic-string@^0.25.5, magic-string@^0.25.7: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== @@ -22668,7 +22664,7 @@ prettier@^2.0.5: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== -pretty-bytes@5.3.0, pretty-bytes@^5.1.0, pretty-bytes@^5.2.0: +pretty-bytes@5.3.0, pretty-bytes@^5.2.0, pretty-bytes@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== @@ -24884,7 +24880,7 @@ rollup@1.27.13: "@types/node" "*" acorn "^7.1.0" -rollup@^1.27.8, rollup@^1.32.0: +rollup@^1.27.8, rollup@^1.31.1, rollup@^1.32.0: version "1.32.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.1.tgz#4480e52d9d9e2ae4b46ba0d9ddeaf3163940f9c4" integrity sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A== @@ -27442,6 +27438,15 @@ tempfile@^2.0.0: temp-dir "^1.0.0" uuid "^3.0.1" +tempy@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8" + integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== + dependencies: + temp-dir "^1.0.0" + type-fest "^0.3.1" + unique-string "^1.0.0" + term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -28233,7 +28238,7 @@ type-fest@^0.13.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== -type-fest@^0.3.0: +type-fest@^0.3.0, type-fest@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== @@ -28636,7 +28641,7 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= -upath@^1.1.1, upath@^1.2.0: +upath@^1.1.1, upath@^1.1.2, upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== @@ -29340,7 +29345,7 @@ webpack-node-externals@^1.7.2: resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== -webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -29599,140 +29604,158 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -workbox-background-sync@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz#26821b9bf16e9e37fd1d640289edddc08afd1950" - integrity sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg== +workbox-background-sync@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-5.1.3.tgz#121c5cf439b627f6320ff490be65fd2bd440c6ea" + integrity sha512-V/R95aPxYjbKCaVzUTihrZ9ObGOnzoA5n60r0DQ747p8Pj15/dDTYixonKhhlvavTiNezUrp+wTQBvZvcd/ETA== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-broadcast-update@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz#e2c0280b149e3a504983b757606ad041f332c35b" - integrity sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA== +workbox-broadcast-update@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-5.1.3.tgz#312e0f065f06a6fb04a050143c84aa6ba0ed8add" + integrity sha512-HJ7FDmgweRcYp8fMiFbkmhaTjMYhMByURe5+TempnCi7cT5NNbyaG4T+rg8NWYxAeumSAB3JQF6XD/z34vRRHA== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-build@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-4.3.1.tgz#414f70fb4d6de47f6538608b80ec52412d233e64" - integrity sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw== +workbox-build@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-5.1.3.tgz#ec0dbcb7e260ad792c49407d063f4bcc8a8f08b8" + integrity sha512-cssa2cKAi/FNp2P2m2DjF/UsXlVX6b1HgkXOjBTraFkIeyZEKxN1F1DnxOpGkdM/bPPRa7y5OmUvjOpgOd9apA== dependencies: - "@babel/runtime" "^7.3.4" - "@hapi/joi" "^15.0.0" + "@babel/core" "^7.8.4" + "@babel/preset-env" "^7.8.4" + "@babel/runtime" "^7.8.4" + "@hapi/joi" "^15.1.0" + "@rollup/plugin-node-resolve" "^7.1.1" + "@rollup/plugin-replace" "^2.3.1" + "@surma/rollup-plugin-off-main-thread" "^1.1.1" common-tags "^1.8.0" - fs-extra "^4.0.2" - glob "^7.1.3" - lodash.template "^4.4.0" - pretty-bytes "^5.1.0" + fast-json-stable-stringify "^2.1.0" + fs-extra "^8.1.0" + glob "^7.1.6" + lodash.template "^4.5.0" + pretty-bytes "^5.3.0" + rollup "^1.31.1" + rollup-plugin-babel "^4.3.3" + rollup-plugin-terser "^5.2.0" + source-map "^0.7.3" + source-map-url "^0.4.0" stringify-object "^3.3.0" strip-comments "^1.0.2" - workbox-background-sync "^4.3.1" - workbox-broadcast-update "^4.3.1" - workbox-cacheable-response "^4.3.1" - workbox-core "^4.3.1" - workbox-expiration "^4.3.1" - workbox-google-analytics "^4.3.1" - workbox-navigation-preload "^4.3.1" - workbox-precaching "^4.3.1" - workbox-range-requests "^4.3.1" - workbox-routing "^4.3.1" - workbox-strategies "^4.3.1" - workbox-streams "^4.3.1" - workbox-sw "^4.3.1" - workbox-window "^4.3.1" - -workbox-cacheable-response@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz#f53e079179c095a3f19e5313b284975c91428c91" - integrity sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw== + tempy "^0.3.0" + upath "^1.2.0" + workbox-background-sync "^5.1.3" + workbox-broadcast-update "^5.1.3" + workbox-cacheable-response "^5.1.3" + workbox-core "^5.1.3" + workbox-expiration "^5.1.3" + workbox-google-analytics "^5.1.3" + workbox-navigation-preload "^5.1.3" + workbox-precaching "^5.1.3" + workbox-range-requests "^5.1.3" + workbox-routing "^5.1.3" + workbox-strategies "^5.1.3" + workbox-streams "^5.1.3" + workbox-sw "^5.1.3" + workbox-window "^5.1.3" + +workbox-cacheable-response@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-5.1.3.tgz#79ec05c9f22796833d653e7cad43774a8f8bf7db" + integrity sha512-lOJEwK2T4KWFNdhRFUKxTPBIO5hIYm9E/nYgMq5h/IH3iHPHlBPuFwRMaQy+TTCGWWTA85NomQOjVw1bj65RLw== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-core@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6" - integrity sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg== +workbox-core@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-5.1.3.tgz#0607acd0018c149162777fe4aae08553bd1559f5" + integrity sha512-TFSIPxxciX9sFaj0FDiohBeIKpwMcCyNduydi9i3LChItcndDS6TJpErxybv8aBWeCMraXt33TWtF6kKuIObNw== -workbox-expiration@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921" - integrity sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw== +workbox-expiration@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-5.1.3.tgz#c793eef17513de86c9c1b8254eb2c9ba3ed17568" + integrity sha512-8YhpmIHqIx+xmtxONADc+di4a3zzCsvVHLiKq6T3vJZUPnqV2jzx+51+UHMUh3T5w5Z5SFC14l0V/jesRbuMKg== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-google-analytics@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a" - integrity sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg== +workbox-google-analytics@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-5.1.3.tgz#dba0cadcf438d14389f2f2da0fd9c8cb605d35e6" + integrity sha512-ouK6xIJa+raFcO29TgwKFU/Hv1ejqSYzCzH9lI2B/4z/Wdnb8maL6mMIojQ8j5SohwKswMZmLDl0Az2PCmX11w== dependencies: - workbox-background-sync "^4.3.1" - workbox-core "^4.3.1" - workbox-routing "^4.3.1" - workbox-strategies "^4.3.1" + workbox-background-sync "^5.1.3" + workbox-core "^5.1.3" + workbox-routing "^5.1.3" + workbox-strategies "^5.1.3" -workbox-navigation-preload@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz#29c8e4db5843803b34cd96dc155f9ebd9afa453d" - integrity sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw== +workbox-navigation-preload@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-5.1.3.tgz#8e49b935aaef16ac614d06db4a0677cbd59f9cae" + integrity sha512-29SPQMAccOgbq3BT9Gz7k+ydy0mcKKR0Rmkmd46tnujutiL4ooE57fBhwsA+c6OlLcYdisvilKlV2YWEtKWfgQ== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-precaching@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-4.3.1.tgz#9fc45ed122d94bbe1f0ea9584ff5940960771cba" - integrity sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ== +workbox-precaching@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-5.1.3.tgz#08f0b48f4a390872a994c4a6ce8e43d08c6cba57" + integrity sha512-9jjBiB00AOI0NnI320ddnhvlL3bjMrDoI3211kEaxcRWh0N2fX25uVn0O8N8u1gWY4tIfwZAn/DgtAU13cFhYA== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-range-requests@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74" - integrity sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA== +workbox-range-requests@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-5.1.3.tgz#f0fc6370ea549d002af1fe902b4ee94bfef6e006" + integrity sha512-uUvEoyEUx86LJc7mtmy/6U8xuK0guXU2FnPimt17zDbsC8FSOaPxc92rxtD6xmDSYrI4FqIebypBCjgIe+sfxA== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-routing@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-4.3.1.tgz#a675841af623e0bb0c67ce4ed8e724ac0bed0cda" - integrity sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g== +workbox-routing@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-5.1.3.tgz#9946da0e9ace45af3db09cc0b4bdc4696723e1f7" + integrity sha512-F+sAp9Iy3lVl3BEG+pzXWVq4AftzjiFpHDaZ4Kf4vLoBoKQE0hIHet4zE5DpHqYdyw+Udhp4wrfHamX6PN6z1Q== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" -workbox-strategies@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646" - integrity sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw== +workbox-strategies@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-5.1.3.tgz#220cc9f5519ed76f2452ccb9407a5fd967c37110" + integrity sha512-wiXHfmOKnWABeIVW+/ye0e00+2CcS5y7SIj2f9zcdy2ZLEbcOf7B+yOl5OrWpBGlTUwRjIYhV++ZqiKm3Dc+8w== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" + workbox-routing "^5.1.3" -workbox-streams@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3" - integrity sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA== +workbox-streams@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-5.1.3.tgz#8f381d395ea2e57106b7b6542b9ffcd769a3047b" + integrity sha512-8kt70eBd1RXL0qenxEnch3Cd7VyW3O0CkeGBN4Bikt307nIV5Q0JciLA5o0CRteijawYOiTq0/px4GDBv1obgQ== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" + workbox-routing "^5.1.3" -workbox-sw@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-4.3.1.tgz#df69e395c479ef4d14499372bcd84c0f5e246164" - integrity sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w== +workbox-sw@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-5.1.3.tgz#7bffbf034f2f5b58e1734b5b86d240019a5332bb" + integrity sha512-Syk6RhYr/8VdFwXrxo5IpVz8Og2xapHTWJhqsZRF+TbxSvlaJs8hrvVPd7edn5ZiiVdPhE9NTeOTOg1+D+FGoA== -workbox-webpack-plugin@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz#47ff5ea1cc074b6c40fb5a86108863a24120d4bd" - integrity sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ== +workbox-webpack-plugin@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-5.1.3.tgz#a7070e3ea0eedb6f87e11fd916ec5d4430a6e348" + integrity sha512-gxSkZ9GFLrMNC/8DGNRjcMhrt8iu+MMXhH/Fpo3wo9rKaSMsI7esGq0klTH/UloP9pNvBizVydysrB52eRhI7w== dependencies: - "@babel/runtime" "^7.0.0" - json-stable-stringify "^1.0.1" - workbox-build "^4.3.1" + "@babel/runtime" "^7.5.5" + fast-json-stable-stringify "^2.0.0" + source-map-url "^0.4.0" + upath "^1.1.2" + webpack-sources "^1.3.0" + workbox-build "^5.1.3" -workbox-window@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-4.3.1.tgz#ee6051bf10f06afa5483c9b8dfa0531994ede0f3" - integrity sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg== +workbox-window@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-5.1.3.tgz#24a2acb2903b0ff2789a4ce32f355621e769eb23" + integrity sha512-oYvfVtPLET7FUrhOzbk0R+aATVmpdQBkmDqwyFH4W2dfVqJXTvTXzuGP5Pn9oZ8jMTB3AYW43yhYBlLYM3mYyg== dependencies: - workbox-core "^4.3.1" + workbox-core "^5.1.3" worker-farm@^1.7.0: version "1.7.0" From d5c8ce2beae7a39640b87c562fa3a2eadd2f68e8 Mon Sep 17 00:00:00 2001 From: Will McVay Date: Mon, 13 Jul 2020 09:44:38 +0100 Subject: [PATCH 2/4] feat: #2024 scaffolder v1 first alpha (#2039) * feat: adds external scaffolded apps * feat: adds internal scaffolds * feat: wip * feat: wip * feat: basic structure seems to be working * feat: rename new folder to app * feat: revert some lost files * feat: wip * feat: external apps both working locally * feat: internal scaffolds good, needs testing * feat: all scaffolds working, tested --- .gitignore | 4 + packages/elements/package.json | 1 + packages/react-app-scaffolder/README.md | 18 +- packages/react-app-scaffolder/app/index.js | 222 +- .../app/templates/_README.md | 11 +- .../app/templates/_config.external.json | 7 + ...fig.example.json => _config.internal.json} | 2 +- .../app/templates/_gitignore | 8 + .../app/templates/_jest.config.js | 26 - .../app/templates/_package.json | 9 + .../__snapshots__/authenticated.tsx.snap | 20 - .../__tests__/__snapshots__/home.tsx.snap | 27 - .../__tests__/__snapshots__/login.tsx.snap | 37 - .../src/components/pages/__tests__/home.tsx | 23 - .../src/components/pages/__tests__/login.tsx | 22 - .../src/components/pages/authenticated.tsx | 21 - .../apollo/src/components/pages/home.tsx | 27 - .../apollo/src/components/pages/login.tsx | 135 - .../core/__tests__/__snapshots__/app.tsx.snap | 1847 --- .../private-route-wrapper.tsx.snap | 835 -- .../apollo/src/core/private-route-wrapper.tsx | 53 - .../apollo/src/graphql/__mocks__/contact.ts | 24 - .../apollo/src/graphql/__mocks__/contacts.ts | 243 - .../apollo/src/graphql/__mocks__/error.ts | 7 - .../apollo/src/graphql/__mocks__/token.ts | 14 - .../src/graphql/__tests__/client.test.ts | 72 - .../src/graphql/__tests__/resolver.test.ts | 14 - .../templates/apollo/src/graphql/client.ts | 54 - .../templates/apollo/src/graphql/resolvers.ts | 14 - .../apollo/src/graphql/schema.graphql | 3 - .../base-is-linaria/src/styles/index.css | 9 - .../base-is-sass/src/styles/base/colors.scss | 27 - .../base-is-sass/src/styles/base/layout.scss | 14 - .../base-is-sass/src/styles/index.scss | 8 - .../app/templates/base/.npmrc | 1 - .../app/templates/base/public/index.js | 38 - .../353acc2c-88f2-4de3-83eb-6cc2c9b05af1.ttf | Bin 63352 -> 0 bytes ...9803fddf-c005-431a-92d5-0f18688f945d.woff2 | Bin 28760 -> 0 bytes .../ea9b8ac3-ff16-4387-a473-32a6a617329f.woff | Bin 35568 -> 0 bytes .../f2cf6cf9-9ec6-4945-a525-f5873d143c2a.eot | Bin 29628 -> 0 bytes .../1c070cdb-18d8-440e-be9d-2448fa3930c4.eot | Bin 29671 -> 0 bytes ...66c06801-da3e-4587-a89c-674cfbe39c21.woff2 | Bin 28776 -> 0 bytes .../c21bf502-6b58-4bf0-9ddd-169929c263e7.ttf | Bin 63700 -> 0 bytes .../f3c7f613-9728-4ed6-a383-1c8519b215d2.woff | Bin 35528 -> 0 bytes .../app/templates/hooks-external/.eslintrc.js | 76 + .../app/templates/hooks-external/.gitignore | 24 + .../.prettierrc.js | 0 .../hooks-external/config.example.json | 7 + .../templates/hooks-external/jest.config.js | 42 + .../app/templates/hooks-external/package.json | 80 + .../postcss.config.js | 0 .../hooks-external/public/index.html | 13 + .../{base => hooks-external}/public/logo.png | Bin .../src/assets/images/reapit-connect.png | Bin .../src/assets/images/reapit-graphic.jpg | Bin .../__snapshots__/error-boundary.tsx.snap | 9 + .../hocs/__tests__/error-boundary.tsx | 0 .../src/components/hocs/error-boundary.tsx | 0 .../src/components/pages/__styles__/styles.ts | 0 .../__snapshots__/authenticated.tsx.snap | 3 + .../__tests__/__snapshots__/login.tsx.snap | 199 + .../pages/__tests__/authenticated.tsx | 0 .../src/components/pages/__tests__/login.tsx | 0 .../src/components/pages/authenticated.tsx | 0 .../src/components/pages/login.tsx | 8 +- .../ui/__tests__/__snapshots__/menu.tsx.snap | 45 + .../src/components/ui/__tests__/menu.tsx | 0 .../src/components/ui/menu.tsx | 0 .../src/constants/api.ts | 2 +- .../src/constants/auth.ts | 0 .../src/constants/error-messages.ts | 0 .../src/constants/routes.ts | 0 .../src/context/__mocks__/mock-context.tsx | 0 .../__snapshots__/auth-context.test.tsx.snap | 0 .../context/__tests__/auth-context.test.tsx | 0 .../src/context/auth-context.tsx | 0 .../src/context/index.tsx | 0 .../src/core/__mocks__/mock-router.tsx | 0 .../src/core/__mocks__/router.tsx | 0 .../core/__tests__/__snapshots__/app.tsx.snap | 19 + .../private-route-wrapper.tsx.snap | 359 + .../__snapshots__/private-route.tsx.snap | 0 .../__tests__/__snapshots__/router.tsx.snap | 40 +- .../src/core/__tests__/app.tsx | 0 .../core/__tests__/private-route-wrapper.tsx | 0 .../src/core/__tests__/private-route.tsx | 0 .../src/core/__tests__/router.tsx | 0 .../src/core/app.tsx | 6 +- .../hooks-external/src/core/index.tsx | 43 + .../src/core/private-route-wrapper.tsx | 0 .../src/core/private-route.tsx | 0 .../src/core/router.tsx | 0 .../src/hooks/__mocks__/mount-react-hook.tsx | 0 .../__snapshots__/use-auth.test.tsx.snap | 5 +- .../src/hooks/__tests__/use-auth.test.tsx | 0 .../src/hooks/use-auth.ts | 0 .../src/scripts/constants.js | 0 .../src/scripts/jest/css-stub.js | 0 .../src/scripts/jest/jest-global.js | 0 .../src/scripts/jest/jest-setup.js | 491 + .../src/scripts/jest/svg-transform.js | 0 .../src/scripts/utils.js | 0 .../src/scripts/webpack-dev.js | 53 - .../src/scripts/webpack-prod.js | 53 - .../hooks-external/src/styles/index.css | 3 + .../src/types/core.ts | 0 .../src/types/global.d.ts | 7 +- .../src/types/index.d.ts | 0 .../tsconfig.json | 2 + .../config.example.json} | 2 +- .../jest.config.js | 0 .../package.json | 18 +- .../public/index.html | 2 +- .../templates/hooks-internal/public/logo.png | Bin 0 -> 2229 bytes .../src/assets/images/reapit-connect.png | Bin 0 -> 22433 bytes .../src/assets/images/reapit-graphic.jpg | Bin 0 -> 203436 bytes .../hocs/__tests__/error-boundary.tsx | 29 + .../src/components/hocs/error-boundary.tsx | 38 + .../components/pages/__styles__/styles.ts} | 25 +- .../pages/__tests__/authenticated.tsx | 20 + .../src/components/pages/__tests__/login.tsx | 46 + .../src/components/pages/authenticated.tsx | 15 + .../src/components/pages/login.tsx | 50 + .../src/components/ui/__tests__/menu.tsx | 39 + .../src/components/ui/menu.tsx | 29 +- .../hooks-internal/src/constants/api.ts | 12 + .../src/constants/auth.ts | 0 .../src/constants/error-messages.ts | 0 .../src/constants/routes.ts | 0 .../src/context/__mocks__/mock-context.tsx | 3 +- .../__snapshots__/auth-context.test.tsx.snap | 0 .../context/__tests__/auth-context.test.tsx | 0 .../src/context/auth-context.tsx | 2 +- .../src/context/index.tsx | 0 .../src/core/__mocks__/mock-router.tsx | 0 .../src/core/__mocks__/router.tsx | 0 .../src/core/__tests__/app.tsx | 0 .../core/__tests__/private-route-wrapper.tsx | 0 .../src/core/__tests__/private-route.tsx | 0 .../src/core/__tests__/router.tsx | 0 .../templates/hooks-internal/src/core/app.tsx | 28 + .../src/core/index.tsx | 0 .../src/core/private-route-wrapper.tsx | 58 + .../src/core/private-route.tsx | 1 + .../src/core/router.tsx | 0 .../src/hooks/__mocks__/mount-react-hook.tsx | 0 .../__snapshots__/use-auth.test.tsx.snap | 0 .../src/hooks/__tests__/use-auth.test.tsx | 2 +- .../src/hooks/use-auth.ts | 4 +- .../hooks-internal/src/styles/index.css | 6 + .../src/types/core.ts | 0 .../src/types/global.d.ts | 0 .../src/types/index.d.ts | 0 .../tsconfig.json | 0 .../is-foundation-no-redux/package.json | 102 - .../is-foundation-redux/package.json | 106 - .../app/templates/redux-external/.eslintrc.js | 76 + .../app/templates/redux-external/.gitignore | 24 + .../templates/redux-external/.prettierrc.js | 7 + .../redux-external/config.example.json | 7 + .../jest.config.js | 0 .../app/templates/redux-external/package.json | 84 + .../redux-external/postcss.config.js | 3 + .../redux-external/public/index.html | 13 + .../templates/redux-external/public/logo.png | Bin 0 -> 2229 bytes .../src/actions/__tests__/auth.ts | 0 .../src/actions/__tests__/authenticated.ts | 0 .../src/actions/__tests__/error.ts | 0 .../src/actions/auth.ts | 0 .../src/actions/authenticated.ts | 0 .../src/actions/error.ts | 0 .../src/assets/images/reapit-connect.png | Bin 0 -> 22433 bytes .../src/assets/images/reapit-graphic.jpg | Bin 0 -> 203436 bytes .../__snapshots__/error-boundary.tsx.snap | 9 + .../__snapshots__/route-fetcher.tsx.snap | 3 + .../hocs/__tests__/error-boundary.tsx | 0 .../hocs/__tests__/route-fetcher.tsx | 0 .../src/components/hocs/error-boundary.tsx | 0 .../src/components/hocs/route-fetcher.tsx | 0 .../src/components/pages/__styles__/styles.ts | 69 + .../__snapshots__/authenticated.tsx.snap | 12 + .../__tests__/__snapshots__/login.tsx.snap | 44 + .../pages/__tests__/authenticated.tsx | 0 .../src/components/pages/__tests__/login.tsx | 0 .../src/components/pages/authenticated.tsx | 0 .../src/components/pages/login.tsx | 8 +- .../ui/__tests__/__snapshots__/menu.tsx.snap | 2 +- .../src/components/ui/__tests__/menu.tsx | 0 .../src/components/ui/menu.tsx | 0 .../src/constants/action-types.ts | 0 .../redux-external/src/constants/api.ts | 13 + .../src/constants/auth.ts | 0 .../src/constants/error-messages.ts | 0 .../src/constants/routes.ts | 1 - .../src/core/__mocks__/router.tsx | 1 - .../src/core/__mocks__/store.ts | 0 .../core/__tests__/__snapshots__/app.tsx.snap | 19 + .../private-route-wrapper.tsx.snap | 3 + .../__snapshots__/private-route.tsx.snap | 7 + .../__tests__/__snapshots__/router.tsx.snap | 63 + .../src/core/__tests__/app.tsx | 0 .../core/__tests__/private-route-wrapper.tsx | 0 .../src/core/__tests__/private-route.tsx | 0 .../src/core/__tests__/router.tsx | 0 .../src/core/__tests__/store.ts | 0 .../src/core/app.tsx | 6 +- .../redux-external/src/core/index.tsx | 43 + .../src/core/private-route-wrapper.tsx | 0 .../src/core/private-route.tsx | 0 .../src/core/router.tsx | 11 +- .../src/core/store.ts | 0 .../src/reducers/__tests__/auth.ts | 0 .../src/reducers/__tests__/authenticated.ts | 0 .../src/reducers/__tests__/error.ts | 0 .../src/reducers/auth.ts | 0 .../src/reducers/authenticated.ts | 0 .../src/reducers/error.ts | 0 .../src/sagas/__tests__/auth.ts | 0 .../src/sagas/__tests__/authenticated.ts | 0 .../src/sagas/auth.ts | 0 .../src/sagas/authenticated.ts | 0 .../redux-external/src/scripts/constants.js | 15 + .../src/scripts/jest/css-stub.js | 1 + .../src/scripts/jest/jest-global.js | 3 + .../src/scripts/jest/jest-setup.js | 0 .../src/scripts/jest/svg-transform.js | 9 + .../redux-external/src/scripts/utils.js | 15 + .../redux-external/src/scripts/webpack-dev.js | 183 + .../src/scripts/webpack-prod.js | 197 + .../src/selectors/auth.ts | 0 .../redux-external/src/styles/index.css | 4 + .../src/types/core.ts | 0 .../redux-external/src/types/global.d.ts | 16 + .../src/types/index.d.ts | 5 +- .../src/utils/__mocks__/session.ts | 0 .../src/utils/__tests__/actions.ts | 0 .../src/utils/__tests__/route-dispatcher.ts | 0 .../src/utils/__tests__/session.ts | 0 .../src/utils/actions.ts | 0 .../src/utils/route-dispatcher.ts | 0 .../src/utils/session.ts | 0 .../templates/redux-external/tsconfig.json | 61 + .../redux-internal/config.example.json | 9 + .../templates/redux-internal/jest.config.js | 23 + .../node_modules/.yarn-integrity | 19 + .../foundations-ts-definitions/README.md | 9 + .../foundations-ts-definitions/package.json | 23 + .../foundations-ts-definitions/types/index.ts | 4 + .../types/marketplace-api-schema.ts | 943 ++ .../types/platform-schema.ts | 11530 ++++++++++++++++ .../app/templates/redux-internal/package.json | 28 + .../redux-internal/public/index.html | 13 + .../templates/redux-internal/public/logo.png | Bin 0 -> 2229 bytes .../src/actions/__tests__/auth.ts | 20 + .../src/actions/__tests__/authenticated.ts | 18 + .../src/actions/__tests__/error.ts | 11 + .../redux-internal/src/actions/auth.ts | 10 + .../src/actions/authenticated.ts | 8 + .../redux-internal/src/actions/error.ts | 8 + .../src/assets/images/reapit-connect.png | Bin 0 -> 22433 bytes .../src/assets/images/reapit-graphic.jpg | Bin 0 -> 203436 bytes .../hocs/__tests__/error-boundary.tsx | 58 + .../hocs/__tests__/route-fetcher.tsx | 38 + .../src/components/hocs/error-boundary.tsx | 65 + .../src/components/hocs/route-fetcher.tsx | 17 + .../src/components/pages/__styles__/styles.ts | 69 + .../pages/__tests__/authenticated.tsx | 7 +- .../src/components/pages/__tests__/login.tsx | 72 + .../src/components/pages/authenticated.tsx | 30 + .../src/components/pages/login.tsx | 55 + .../src/components/ui/__tests__/menu.tsx | 11 +- .../redux-internal/src/components/ui/menu.tsx | 72 + .../src/constants/action-types.ts | 28 + .../redux-internal/src/constants/api.ts | 12 + .../redux-internal/src/constants/auth.ts | 5 + .../src/constants/error-messages.ts | 0 .../src/constants/routes.ts | 1 - .../src/core/__mocks__/router.tsx | 3 + .../src/core/__mocks__/store.ts | 9 + .../redux-internal/src/core/__tests__/app.tsx | 19 + .../core/__tests__/private-route-wrapper.tsx | 20 + .../src/core/__tests__/private-route.tsx | 49 + .../src/core/__tests__/router.tsx | 25 + .../src/core/__tests__/store.ts | 22 + .../templates/redux-internal/src/core/app.tsx | 20 + .../redux-internal/src/core/index.tsx | 65 + .../src/core/private-route-wrapper.tsx | 78 + .../redux-internal/src/core/private-route.tsx | 50 + .../redux-internal/src/core/router.tsx | 51 + .../redux-internal/src/core/store.ts | 85 + .../src/reducers/__tests__/auth.ts | 80 + .../src/reducers/__tests__/authenticated.ts | 46 + .../src/reducers/__tests__/error.ts | 83 + .../redux-internal/src/reducers/auth.ts | 62 + .../src/reducers/authenticated.ts | 54 + .../redux-internal/src/reducers/error.ts | 39 + .../src/sagas/__tests__/auth.ts | 90 + .../src/sagas/__tests__/authenticated.ts | 41 + .../redux-internal/src/sagas/auth.ts | 44 + .../redux-internal/src/sagas/authenticated.ts | 39 + .../redux-internal/src/selectors/auth.ts | 17 + .../redux-internal/src/styles/index.css | 6 + .../redux-internal/src/types/core.ts | 42 + .../src/types/global.d.ts | 0 .../redux-internal/src/types/index.d.ts | 14 + .../src/utils/__mocks__/session.ts | 17 + .../src/utils/__tests__/actions.ts | 27 + .../src/utils/__tests__/route-dispatcher.ts | 16 + .../src/utils/__tests__/session.ts | 55 + .../redux-internal/src/utils/actions.ts | 12 + .../src/utils/route-dispatcher.ts | 19 + .../redux-internal/src/utils/session.ts | 18 + .../templates/redux-internal/tsconfig.json | 30 + packages/react-app-scaffolder/package.json | 10 +- yarn.lock | 138 +- 315 files changed, 17554 insertions(+), 4317 deletions(-) create mode 100644 packages/react-app-scaffolder/app/templates/_config.external.json rename packages/react-app-scaffolder/app/templates/{_config.example.json => _config.internal.json} (99%) delete mode 100644 packages/react-app-scaffolder/app/templates/_jest.config.js create mode 100644 packages/react-app-scaffolder/app/templates/_package.json delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/home.tsx.snap delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/login.tsx.snap delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/home.tsx delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/login.tsx delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/authenticated.tsx delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/home.tsx delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/components/pages/login.tsx delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/app.tsx.snap delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/private-route-wrapper.tsx.snap delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/core/private-route-wrapper.tsx delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contact.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contacts.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/error.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/token.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/client.test.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/resolver.test.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/client.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/resolvers.ts delete mode 100644 packages/react-app-scaffolder/app/templates/apollo/src/graphql/schema.graphql delete mode 100644 packages/react-app-scaffolder/app/templates/base-is-linaria/src/styles/index.css delete mode 100644 packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/colors.scss delete mode 100644 packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/layout.scss delete mode 100644 packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/index.scss delete mode 100644 packages/react-app-scaffolder/app/templates/base/.npmrc delete mode 100644 packages/react-app-scaffolder/app/templates/base/public/index.js delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/353acc2c-88f2-4de3-83eb-6cc2c9b05af1.ttf delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/9803fddf-c005-431a-92d5-0f18688f945d.woff2 delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/ea9b8ac3-ff16-4387-a473-32a6a617329f.woff delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/f2cf6cf9-9ec6-4945-a525-f5873d143c2a.eot delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/1c070cdb-18d8-440e-be9d-2448fa3930c4.eot delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/66c06801-da3e-4587-a89c-674cfbe39c21.woff2 delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/c21bf502-6b58-4bf0-9ddd-169929c263e7.ttf delete mode 100755 packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/f3c7f613-9728-4ed6-a383-1c8519b215d2.woff create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/.eslintrc.js create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/.gitignore rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/.prettierrc.js (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/config.example.json create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/jest.config.js create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/package.json rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/postcss.config.js (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/public/index.html rename packages/react-app-scaffolder/app/templates/{base => hooks-external}/public/logo.png (100%) rename packages/react-app-scaffolder/app/templates/{base => hooks-external}/src/assets/images/reapit-connect.png (100%) rename packages/react-app-scaffolder/app/templates/{base => hooks-external}/src/assets/images/reapit-graphic.jpg (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/__tests__/__snapshots__/error-boundary.tsx.snap rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/hocs/__tests__/error-boundary.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/hocs/error-boundary.tsx (100%) rename packages/react-app-scaffolder/app/templates/{base-is-linaria => hooks-external}/src/components/pages/__styles__/styles.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/pages/__tests__/authenticated.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/pages/__tests__/login.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/pages/authenticated.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/pages/login.tsx (90%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/components/ui/__tests__/__snapshots__/menu.tsx.snap rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/ui/__tests__/menu.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/components/ui/menu.tsx (100%) rename packages/react-app-scaffolder/app/templates/{base => hooks-external}/src/constants/api.ts (78%) rename packages/react-app-scaffolder/app/templates/{base => hooks-external}/src/constants/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/constants/error-messages.ts (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/constants/routes.ts (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/context/__mocks__/mock-context.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/context/__tests__/__snapshots__/auth-context.test.tsx.snap (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/context/__tests__/auth-context.test.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/context/auth-context.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/context/index.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__mocks__/mock-router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/core/__mocks__/router.tsx (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/core/__tests__/__snapshots__/app.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/core/__tests__/__snapshots__/private-route-wrapper.tsx.snap rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__tests__/__snapshots__/private-route.tsx.snap (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__tests__/__snapshots__/router.tsx.snap (56%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__tests__/app.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__tests__/private-route-wrapper.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__tests__/private-route.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/core/__tests__/router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/core/app.tsx (91%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/core/index.tsx rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/core/private-route-wrapper.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/core/private-route.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/core/router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/hooks/__mocks__/mount-react-hook.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/hooks/__tests__/__snapshots__/use-auth.test.tsx.snap (92%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/hooks/__tests__/use-auth.test.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/hooks/use-auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/constants.js (100%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/jest/css-stub.js (100%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/jest/jest-global.js (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/scripts/jest/jest-setup.js rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/jest/svg-transform.js (100%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/utils.js (100%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/webpack-dev.js (79%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/src/scripts/webpack-prod.js (78%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-external/src/styles/index.css rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/types/core.ts (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-external}/src/types/global.d.ts (61%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-external}/src/types/index.d.ts (100%) rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => hooks-external}/tsconfig.json (94%) rename packages/react-app-scaffolder/app/templates/{_config.json => hooks-internal/config.example.json} (85%) rename packages/react-app-scaffolder/app/templates/{base-is-foundation => hooks-internal}/jest.config.js (100%) rename packages/react-app-scaffolder/app/templates/{base-is-foundation => hooks-internal}/package.json (82%) rename packages/react-app-scaffolder/app/templates/{base => hooks-internal}/public/index.html (90%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/public/logo.png create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/assets/images/reapit-connect.png create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/assets/images/reapit-graphic.jpg create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/hocs/__tests__/error-boundary.tsx create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/hocs/error-boundary.tsx rename packages/react-app-scaffolder/app/templates/{base-is-sass/src/styles/pages/login.scss => hooks-internal/src/components/pages/__styles__/styles.ts} (79%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/pages/__tests__/authenticated.tsx create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/pages/__tests__/login.tsx create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/pages/authenticated.tsx create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/pages/login.tsx create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/__tests__/menu.tsx rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/components/ui/menu.tsx (61%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/api.ts rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/constants/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{base => hooks-internal}/src/constants/error-messages.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => hooks-internal}/src/constants/routes.ts (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/context/__mocks__/mock-context.tsx (92%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/context/__tests__/__snapshots__/auth-context.test.tsx.snap (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/context/__tests__/auth-context.test.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/context/auth-context.tsx (76%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/context/index.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/core/__mocks__/mock-router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => hooks-internal}/src/core/__mocks__/router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/core/__tests__/app.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/core/__tests__/private-route-wrapper.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/core/__tests__/private-route.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/core/__tests__/router.tsx (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/core/app.tsx rename packages/react-app-scaffolder/app/templates/{base => hooks-internal}/src/core/index.tsx (100%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route-wrapper.tsx rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/core/private-route.tsx (97%) rename packages/react-app-scaffolder/app/templates/{redux => hooks-internal}/src/core/router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/hooks/__mocks__/mount-react-hook.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/hooks/__tests__/__snapshots__/use-auth.test.tsx.snap (100%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/hooks/__tests__/use-auth.test.tsx (99%) rename packages/react-app-scaffolder/app/templates/{apollo => hooks-internal}/src/hooks/use-auth.ts (94%) create mode 100644 packages/react-app-scaffolder/app/templates/hooks-internal/src/styles/index.css rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/types/core.ts (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => hooks-internal}/src/types/global.d.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => hooks-internal}/src/types/index.d.ts (100%) rename packages/react-app-scaffolder/app/templates/{base-is-foundation => hooks-internal}/tsconfig.json (100%) delete mode 100644 packages/react-app-scaffolder/app/templates/is-foundation-no-redux/package.json delete mode 100644 packages/react-app-scaffolder/app/templates/is-foundation-redux/package.json create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/.eslintrc.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/.gitignore create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/.prettierrc.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/config.example.json rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => redux-external}/jest.config.js (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/package.json create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/postcss.config.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/public/index.html create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/public/logo.png rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/actions/__tests__/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/actions/__tests__/authenticated.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/actions/__tests__/error.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/actions/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/actions/authenticated.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/actions/error.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/assets/images/reapit-connect.png create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/assets/images/reapit-graphic.jpg create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/__snapshots__/error-boundary.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/__snapshots__/route-fetcher.tsx.snap rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/hocs/__tests__/error-boundary.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/hocs/__tests__/route-fetcher.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/hocs/error-boundary.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/hocs/route-fetcher.tsx (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__styles__/styles.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/pages/__tests__/authenticated.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/pages/__tests__/login.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/pages/authenticated.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/pages/login.tsx (91%) rename packages/react-app-scaffolder/app/templates/{apollo => redux-external}/src/components/ui/__tests__/__snapshots__/menu.tsx.snap (97%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/ui/__tests__/menu.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/components/ui/menu.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/constants/action-types.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/constants/api.ts rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/constants/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{no-redux => redux-external}/src/constants/error-messages.ts (100%) rename packages/react-app-scaffolder/app/templates/{apollo => redux-external}/src/constants/routes.ts (67%) rename packages/react-app-scaffolder/app/templates/{apollo => redux-external}/src/core/__mocks__/router.tsx (78%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/__mocks__/store.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/core/__tests__/__snapshots__/app.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/core/__tests__/__snapshots__/private-route-wrapper.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/core/__tests__/__snapshots__/private-route.tsx.snap create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/core/__tests__/__snapshots__/router.tsx.snap rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/__tests__/app.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/__tests__/private-route-wrapper.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/__tests__/private-route.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/__tests__/router.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/__tests__/store.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/app.tsx (85%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/core/index.tsx rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/private-route-wrapper.tsx (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/private-route.tsx (100%) rename packages/react-app-scaffolder/app/templates/{apollo => redux-external}/src/core/router.tsx (75%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/core/store.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/reducers/__tests__/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/reducers/__tests__/authenticated.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/reducers/__tests__/error.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/reducers/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/reducers/authenticated.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/reducers/error.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/sagas/__tests__/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/sagas/__tests__/authenticated.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/sagas/auth.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/sagas/authenticated.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/constants.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/jest/css-stub.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/jest/jest-global.js rename packages/react-app-scaffolder/app/templates/{base-is-not-foundation => redux-external}/src/scripts/jest/jest-setup.js (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/jest/svg-transform.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/utils.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/webpack-dev.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/scripts/webpack-prod.js rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/selectors/auth.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/styles/index.css rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/types/core.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/src/types/global.d.ts rename packages/react-app-scaffolder/app/templates/{apollo => redux-external}/src/types/index.d.ts (80%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/__mocks__/session.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/__tests__/actions.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/__tests__/route-dispatcher.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/__tests__/session.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/actions.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/route-dispatcher.ts (100%) rename packages/react-app-scaffolder/app/templates/{redux => redux-external}/src/utils/session.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-external/tsconfig.json create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/config.example.json create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/jest.config.js create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/node_modules/.yarn-integrity create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/node_modules/@reapit/foundations-ts-definitions/README.md create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/node_modules/@reapit/foundations-ts-definitions/package.json create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/node_modules/@reapit/foundations-ts-definitions/types/index.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/node_modules/@reapit/foundations-ts-definitions/types/marketplace-api-schema.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/node_modules/@reapit/foundations-ts-definitions/types/platform-schema.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/package.json create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/public/index.html create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/public/logo.png create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/actions/__tests__/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/actions/__tests__/authenticated.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/actions/__tests__/error.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/actions/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/actions/authenticated.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/actions/error.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/assets/images/reapit-connect.png create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/assets/images/reapit-graphic.jpg create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/hocs/__tests__/error-boundary.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/hocs/__tests__/route-fetcher.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/hocs/error-boundary.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/hocs/route-fetcher.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/pages/__styles__/styles.ts rename packages/react-app-scaffolder/app/templates/{apollo => redux-internal}/src/components/pages/__tests__/authenticated.tsx (73%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/pages/__tests__/login.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/pages/authenticated.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/pages/login.tsx rename packages/react-app-scaffolder/app/templates/{apollo => redux-internal}/src/components/ui/__tests__/menu.tsx (67%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/menu.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/constants/action-types.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/constants/api.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/constants/auth.ts rename packages/react-app-scaffolder/app/templates/{redux => redux-internal}/src/constants/error-messages.ts (100%) rename packages/react-app-scaffolder/app/templates/{base => redux-internal}/src/constants/routes.ts (67%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/router.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/store.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/app.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route-wrapper.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/router.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/store.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/app.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/index.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route-wrapper.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/router.tsx create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/core/store.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/authenticated.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/error.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/authenticated.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/error.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/authenticated.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/authenticated.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/selectors/auth.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/styles/index.css create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/types/core.ts rename packages/react-app-scaffolder/app/templates/{redux => redux-internal}/src/types/global.d.ts (100%) create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/types/index.d.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__mocks__/session.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/actions.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/route-dispatcher.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/session.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/actions.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/route-dispatcher.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/src/utils/session.ts create mode 100644 packages/react-app-scaffolder/app/templates/redux-internal/tsconfig.json diff --git a/.gitignore b/.gitignore index 7eece73b15..bae85f9b0b 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,7 @@ scripts/jest/.jest-cache # credentials file to load credentials.json +# Locally I have had to add these because of: https://github.com/yarnpkg/yarn/issues/7807 +# May need to include globally if other people experienece installing issues +.yarnrc +.yarn \ No newline at end of file diff --git a/packages/elements/package.json b/packages/elements/package.json index 98af1bda6e..543eec48e3 100644 --- a/packages/elements/package.json +++ b/packages/elements/package.json @@ -95,6 +95,7 @@ "rollup-plugin-typescript2": "^0.27.1" }, "peerDependencies": { + "dayjs": "^1.8.19", "react": "^16.11.0", "react-dom": "^16.11.0", "react-router": "^5.1.2", diff --git a/packages/react-app-scaffolder/README.md b/packages/react-app-scaffolder/README.md index 96c1031493..b9184f76de 100644 --- a/packages/react-app-scaffolder/README.md +++ b/packages/react-app-scaffolder/README.md @@ -1,9 +1,23 @@ -# Reapit React-Redux App Scaffolder +# Reapit React App Scaffolder A CLI for generating React Apps, optimised for the marketplace, including Reapit Connect authentication and Elements. For usage visit [here](https://foundations-documentation.reapit.cloud/api/web#react-app-scaffolder). -- **Tech Stack**: Yeoman, React, Redux, Jest, React, Router, Styled-Components, Sass, CSS Modules +- **Tech Stack**: Yeoman, React, Redux, Jest, React, Router, Linaria - **Cloud Services**: NPM - **Production**: https://www.npmjs.com/package/@reapit/generator-react-redux-app For detailed documentation [visit here](https://foundations-documentation.reapit.cloud/open-source/packages#react-app-scaffolder). + +For internal scaffolds, navigate to project folder and execute `yarn scaffold` to load the CLI. + +For external users first; + +`npm install -g yo @reapit/generator-react-app-scaffolder` + +Then + +`yo @reapit/react-app-scaffolder` to load the CLI. + +For internal maintainers, to build an app locally, navigate to one of the external options within the templates folder, `yarn` and `yarn start:dev` to develop the scaffold. + +For internal apps, scaffold a local app and copy your changes back to the main directory. \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/index.js b/packages/react-app-scaffolder/app/index.js index 07fc6908ba..c13dbcf2d9 100644 --- a/packages/react-app-scaffolder/app/index.js +++ b/packages/react-app-scaffolder/app/index.js @@ -3,26 +3,23 @@ const { promisify } = require('util') const process = require('process') const exec = promisify(require('child_process').exec) const spawn = require('cross-spawn') -const { execSync } = require('child_process') const path = require('path') const fs = require('fs') const yosay = require('yosay') -const { constantCase } = require('change-case') module.exports = class extends Generator { _installAndExport() { return new Promise(async (resolve, reject) => { - const { isFoundation } = this.answers + const { isFoundations } = this.answers this.log(yosay('Installing dependencies... this may take a minute!')) - if (!isFoundation) { + if (!isFoundations) { await exec(`yarn`) } - const prettierConfigPath = path.resolve(__dirname, '../../../.prettierrc.js') await exec(`yarn prettier --write ./package.json`) - await exec(`yarn prettier "**/*.ts" "**/*.tsx" --write`) + this.log(yosay('App installed successfully!')) this._pushToGithub() @@ -58,62 +55,30 @@ module.exports = class extends Generator { } _addPackageJson() { - const { isFoundation, name, author, repo, description } = this.answers - - if (isFoundation) { - return - } + const { isFoundations, name, author, repo, description } = this.answers - if (this.redux) { - this.fs.copyTpl(this.templatePath('./is-foundation-redux/**/*'), this.destinationPath('./'), { - name, author, repo, description - }) - } + const local = require(this.templatePath('./_package.json')) + const base = require(this.destinationPath('./package.json')) - if (!this.redux) { - this.fs.copyTpl(this.templatePath('./is-foundation-no-redux/**/*'), this.destinationPath('./'), { - name, author, repo, description - }) + const merged = { + ...local, + ...base, } - } - _addPackageJson() { - const { isFoundation, name, author, repo, description } = this.answers - - if (isFoundation) { - return - } - - if (this.redux) { - this.fs.copyTpl(this.templatePath('./is-foundation-redux/**/*'), this.destinationPath('./'), { - name, author, repo, description - }) - } - - if (!this.redux) { - this.fs.copyTpl(this.templatePath('./is-foundation-no-redux/**/*'), this.destinationPath('./'), { - name, author, repo, description + this.fs.delete(this.destinationPath('./package.json')) + this.fs.commit([], () => { + this.fs.write(this.destinationPath('./temp.package.json'), JSON.stringify(merged)) + this.fs.commit([], () => { + this.fs.copyTpl(this.destinationPath('./temp.package.json'), this.destinationPath('./package.json'), { + name, + author, + repo, + description, + }) + this.fs.delete(this.destinationPath('./temp.package.json')) + this.fs.commit([], () => {}) }) - } - } - - - _addAzure() { - const { name, azure } = this.answers - if (azure) { - this.fs.copy(this.templatePath('redu'), this.destinationPath(`./azure-pipelines.yml`)) - } - } - - _addStyleSolution() { - const { sass, name, isFoundation } = this.answers - - - if (sass) { - this.fs.copyTpl(this.templatePath('./base-is-sass/**/*'), this.destinationPath('./'), { isFoundation }) - } else { - this.fs.copyTpl(this.templatePath('./base-is-linaria/**/*'), this.destinationPath('./'), { isFoundation }) - } + }) } constructor(args, opts) { @@ -123,94 +88,35 @@ module.exports = class extends Generator { async writeBaseFiles() { return new Promise((resolve, reject) => { - const { name, repo, description, author, isFoundation, stylesSolution, clientId, sass } = this.answers - const { redux, graphql } = this - - /** - * settings destination path - * for non isFoundation: it will be the folder where the scaffolder is executed - * for isFoundation: we have to deter - */ - - this.fs.copyTpl(this.templatePath('_README.md'), this.destinationPath('./README.md'), { - name, - }) - - this.fs.copyTpl(this.templatePath('_gitignore'), this.destinationPath('./.gitignore'), { - name, - }) - - this.fs.copyTpl(this.templatePath('_eslintrc.js'), this.destinationPath('./.eslintrc.js'), { - name, - }) - - this.fs.copyTpl(this.templatePath('_prettierrc.js'), this.destinationPath('./.prettierrc.js'), { - name, - }) + const { name, isFoundations, clientId } = this.answers + const configPath = isFoundations ? './_config.internal.json' : './_config.external.json' - this.fs.copyTpl(this.templatePath('_config.json'), this.destinationPath('./config.json'), { + this.fs.copyTpl(this.templatePath(configPath), this.destinationPath('./config.json'), { clientId, }) - this.fs.copyTpl(this.templatePath('_config.example.json'), this.destinationPath('./config.example.json'), { - clientId, - }) - - this.fs.copyTpl(this.templatePath('./base'), this.destinationPath('./'), { + this.fs.copyTpl(this.templatePath('_README.md'), this.destinationPath('./README.md'), { name, - nameInConstantCase: constantCase(name), - redux, - graphql, - stylesSolution, - isFoundation }) - if (isFoundation) { - // Any any additional base files specialized for non-foundation project will need to uncomment this like - // Select recursively dot files - // glob isn't really smart at the moment. In the future, when need to add non dot files, uncomment this - // this.fs.copyTpl(this.templatePath('./base-is-foundation/**/.*'), this.destinationPath('./'), { - // name, - // repo, - // description, - // author, - // }) - this.fs.copyTpl(this.templatePath('./base-is-foundation/*'), this.destinationPath('./'), { - name, - repo, - description, - author, - }) - } else { - this.fs.copyTpl(this.templatePath('./base-is-not-foundation/**/*'), this.destinationPath('./'), { - name, - nameInConstantCase: constantCase(name), - repo, - description, - author, - clientId, - }) - } - - this.fs.copyTpl(this.templatePath(this.projectTypePath), this.destinationPath('./'), { - name, - nameInConstantCase: constantCase(name), - redux, - graphql, - stylesSolution, - graphql, - stylesSolution, - sass - }) + this.fs.copyTpl(this.templatePath(this.projectPath), this.destinationPath('./')) this.fs.commit([], () => { - this._addStyleSolution(), - this._addPackageJson(), - this._addAzure() + + if (!isFoundations) { + this.fs.copyTpl(this.templatePath('_prettierrc.js'), this.destinationPath('./.prettierrc.js')) + this.fs.copyTpl(this.templatePath('_eslintrc.js'), this.destinationPath('./.eslintrc.js')) + this.fs.copyTpl(this.templatePath('_gitignore'), this.destinationPath('./.gitignore')) + } + this.fs.commit([], () => { - this._installAndExport() - .then(resolve) - .catch(reject) + this._addPackageJson() + + this.fs.commit([], () => { + this._installAndExport() + .then(resolve) + .catch(reject) + }) }) }) }) @@ -250,21 +156,15 @@ module.exports = class extends Generator { }, { type: 'confirm', - name: 'isFoundation', - message: 'Is this project for internal use (mono-repo)', - default: true, - }, - { - name: 'sass', - message: 'Would you like to use Sass?', - type: 'confirm', + name: 'isFoundations', + message: 'Is this a Reapit internal project?', default: false, }, { type: 'list', name: 'stateManagementStyle', - message: 'Pick project type', - choices: ['Redux', 'No Redux'], + message: 'How do you want to manage state?', + choices: ['Redux', 'React Hooks & Context'], }, { type: 'confirm', @@ -274,36 +174,28 @@ module.exports = class extends Generator { }, ]) - const { stateManagementStyle, stylesSolution } = this.answers - if (stateManagementStyle === 'Redux') { - this.projectTypePath = 'redux' - this.redux = true - } - - if (stateManagementStyle === 'No Redux') { - this.projectTypePath = 'no-redux' - this.redux = false + const { stateManagementStyle, isFoundations } = this.answers + if (stateManagementStyle === 'Redux' && isFoundations) { + this.projectPath = './redux-internal' } - if (stateManagementStyle === 'Apollo GraphQL') { - this.projectTypePath = 'apollo' - this.graphql = true + if (stateManagementStyle === 'Redux' && !isFoundations) { + this.projectPath = './redux-external' } - if (stylesSolution === 'Styled Components') { - this.answers.stylesSolution = 'styledComponents' + if (stateManagementStyle === 'React Hooks & Context' && isFoundations) { + this.projectPath = './hooks-internal' } - if (stylesSolution === 'Sass/CSS') { - this.answers.stylesSolution = 'sass' + if (stateManagementStyle === 'React Hooks & Context' && !isFoundations) { + this.projectPath = './hooks-external' } - /** * Destination path - * isFoundation ->./package/{appName} - * else current path + * isFoundations ->./package/{appName} + * else current path/{appName} */ - if (this.answers.isFoundation) { + if (isFoundations) { this.packagePath = path.resolve(__dirname, '../..', this.answers.name) /** * create directory if not diff --git a/packages/react-app-scaffolder/app/templates/_README.md b/packages/react-app-scaffolder/app/templates/_README.md index ba91c0cfec..dd0eea6719 100644 --- a/packages/react-app-scaffolder/app/templates/_README.md +++ b/packages/react-app-scaffolder/app/templates/_README.md @@ -1,12 +1,5 @@ # <%= name %> -<%= name %> for Reapit PAAS platform. Initial scaffold from [React App Boilerplate](https://github.com/reapit/react-app) +<%= name %> an app built for Reapit Marketplace. -## Read on: - -- [Getting Started](./src/docs/GETTING_STARTED.md) -- [Api Platform](./src/docs/API_PLATFORM.md) -- [Code Style](./src/docs/CODE_STYLE.md) -- [Version Control](./VERSION_CONTROL.md) -- [Definition of Done](./src/docs/DEFINITION_OF_DONE.md) -- [Deployment](./src/docs/DEPLOYMENT.md) +Initial scaffold using the steps from [here](https://foundations-documentation.reapit.cloud/developer-portal), using [Reapit React App Scaffolder](https://www.npmjs.com/package/@reapit/generator-react-app-scaffolder) \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/templates/_config.external.json b/packages/react-app-scaffolder/app/templates/_config.external.json new file mode 100644 index 0000000000..6d156b8f08 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/_config.external.json @@ -0,0 +1,7 @@ +{ + "appEnv": "local", + "cognitoClientId": "<%= clientId %>", + "cognitoOAuthUrl": "https://dev.connect.reapit.cloud", + "cognitoUserPoolId": "eu-west-2_hbt0B7yys", + "platformApiUrl": "https://dev.platform.reapit.cloud" +} diff --git a/packages/react-app-scaffolder/app/templates/_config.example.json b/packages/react-app-scaffolder/app/templates/_config.internal.json similarity index 99% rename from packages/react-app-scaffolder/app/templates/_config.example.json rename to packages/react-app-scaffolder/app/templates/_config.internal.json index 692adaf253..5d3433212c 100644 --- a/packages/react-app-scaffolder/app/templates/_config.example.json +++ b/packages/react-app-scaffolder/app/templates/_config.internal.json @@ -6,4 +6,4 @@ "cognitoOAuthUrl": "https://dev.connect.reapit.cloud", "cognitoUserPoolId": "eu-west-2_hbt0B7yys", "platformApiUrl": "https://dev.platform.reapit.cloud" -} +} \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/templates/_gitignore b/packages/react-app-scaffolder/app/templates/_gitignore index bcd5078bd8..a2e8df3890 100644 --- a/packages/react-app-scaffolder/app/templates/_gitignore +++ b/packages/react-app-scaffolder/app/templates/_gitignore @@ -16,3 +16,11 @@ yarn-error.log* *.log .cache/ +yarn.lock + +public/dist +src/tests + +.jest-cache +.linaria-cache +.webpack-cache diff --git a/packages/react-app-scaffolder/app/templates/_jest.config.js b/packages/react-app-scaffolder/app/templates/_jest.config.js deleted file mode 100644 index e3d7b18525..0000000000 --- a/packages/react-app-scaffolder/app/templates/_jest.config.js +++ /dev/null @@ -1,26 +0,0 @@ -const { pathsToModuleNameMapper } = require('ts-jest/utils') -const { compilerOptions } = require('./tsconfig') - -module.exports = { - preset: 'ts-jest', - setupFiles: ['/src/scripts/jest-setup.js'], - collectCoverageFrom: ['/src/**/*.ts', '/src/**/*.tsx'], - coverageDirectory: './src/tests/coverage', - coveragePathIgnorePatterns: ['[/\\\\](node_modules|src/types|src/tests|src/scripts)[/\\\\]', 'index.tsx'], - modulePathIgnorePatterns: ['[/\\\\](node_modules)[/\\\\]'], - snapshotSerializers: ['enzyme-to-json/serializer'], - moduleNameMapper: { - '^.+.(?=.*scss|sass|css|jpg|png).*': '/src/scripts/css-stub.js', - ...pathsToModuleNameMapper(compilerOptions.paths, { - prefix: '/' - }) - }, - coverageThreshold: { - global: { - branches: 0, - functions: 0, - lines: 0, - statements: 0 - } - } -} \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/templates/_package.json b/packages/react-app-scaffolder/app/templates/_package.json new file mode 100644 index 0000000000..7c76605044 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/_package.json @@ -0,0 +1,9 @@ +{ + "name": "<%= name %>", + "description": "<%= description %>", + "repository": { + "type": "git", + "url": "git+<%= repo %>" + }, + "author": "<%= author %>" +} diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap deleted file mode 100644 index 5b71532eb0..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap +++ /dev/null @@ -1,20 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Authenticated should match a snapshot 1`] = ` - - -

- Welcome To Reapit Elements -

- - You are now authenticated against our sandbox data - -
-
-`; diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/home.tsx.snap b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/home.tsx.snap deleted file mode 100644 index 903688c646..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/home.tsx.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Home should match a snapshot 1`] = ` - - -

- Welcome To Reapit Elements -

- - Click - - here - - to login - -
-
-`; diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/login.tsx.snap b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/login.tsx.snap deleted file mode 100644 index da5a785eb6..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/__snapshots__/login.tsx.snap +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Login should match a snapshot 1`] = ` -
-
-

- Sign in -

-

- Welcome to smb -

- -
-
- Reapit Graphic -
-
-`; diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/home.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/home.tsx deleted file mode 100644 index 644f30ccc3..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/home.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react' -import { shallow } from 'enzyme' -import toJson from 'enzyme-to-json' -import { Home, HomeProps } from '../home' - -const props: HomeProps = { - approvalsState: { - loading: false, - homeData: {}, - }, - // @ts-ignore: just pick the needed props for the test - match: { - params: { - page: '2', - }, - }, -} - -describe('Home', () => { - it('should match a snapshot', () => { - expect(toJson(shallow())).toMatchSnapshot() - }) -}) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/login.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/login.tsx deleted file mode 100644 index 4abbad8af0..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/__tests__/login.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { shallow } from 'enzyme' -import toJson from 'enzyme-to-json' -import { Login, LoginProps } from '../login' - -const props: LoginProps = { - error: false, - isLogin: false, - login: jest.fn(), - authChangeLoginType: jest.fn(), - loginType: 'CLIENT', - // @ts-ignore: ignore to fullfil the definition of RouteComponentProps - location: { - pathname: '/client', - }, -} - -describe('Login', () => { - it('should match a snapshot', () => { - expect(toJson(shallow())).toMatchSnapshot() - }) -}) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/authenticated.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/authenticated.tsx deleted file mode 100644 index d46ac3db14..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/authenticated.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { H3, FlexContainerBasic, FlexContainerResponsive, SubTitleH5 } from '@reapit/elements' - -export interface AuthenticatedMappedActions {} - -export interface AuthenticatedMappedProps {} - -export type AuthenticatedProps = AuthenticatedMappedActions & AuthenticatedMappedProps - -export const Authenticated: React.FunctionComponent = () => { - return ( - - -

Welcome To Reapit Foundations

- You are now authenticated against our sandbox data -
-
- ) -} - -export default Authenticated diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/home.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/home.tsx deleted file mode 100644 index 6dd617ae62..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/home.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react' -import { withRouter, RouteComponentProps } from 'react-router' -import { Link } from 'react-router-dom' -import { H3, FlexContainerBasic, FlexContainerResponsive, SubTitleH5 } from '@reapit/elements' - -export type HomeMappedActions = {} - -export type HomeMappedProps = { - homeState: any -} - -export type HomeProps = HomeMappedActions & HomeMappedProps & RouteComponentProps<{ page?: any }> - -export const Home: React.FunctionComponent = () => { - return ( - - -

Welcome To Reapit Foundations

- - Click here to login - -
-
- ) -} - -export default withRouter(Home) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/login.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/login.tsx deleted file mode 100644 index 536357f15e..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/pages/login.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import * as React from 'react' -import { Redirect } from 'react-router-dom' -import { withRouter, RouteComponentProps } from 'react-router' -import Routes from '@/constants/routes' -import { Input, Button, H1, Level, Alert, isEmail, Formik, Form } from '@reapit/elements' -import { LoginParams } from '@reapit/cognito-auth' -<% if (stylesSolution == 'sass') { %>import loginStyles from '@/styles/pages/login.scss?mod'<%}%> -<% if (stylesSolution == 'styledComponents') { %>import { Container, Wrapper, ImageContainer } from './__styles__/login'<%}%> -import logoImage from '@/assets/images/reapit-graphic.jpg' - -export type LoginMappedActions = { - login: (params: LoginParams) => void -} - -export type LoginMappedProps = { - hasSession: boolean - error: boolean -} - -export type LoginFormValues = { - email: string - password: string -} - -export type LoginFormError = { - email?: string - password?: string -} - -export function validate(values: LoginFormValues) { - let errors = {} as LoginFormError - - if (!values.email) { - errors.email = 'Required' - } else if (!isEmail(values.email)) { - errors.email = 'Invalid email address' - } - - if (!values.password) { - errors.password = 'Required' - } - - return errors -} - -export type LoginProps = LoginMappedActions & LoginMappedProps & RouteComponentProps - -export const onSubmitHandler = (setIsSubmitting: any, login: any, values: LoginFormValues) => { - const { email, password } = values - - setIsSubmitting(true) - login({ userName: email, password, loginType: 'CLIENT' } as LoginParams) -} - -export const Login: React.FunctionComponent = (props: LoginProps) => { - const [isSubmitting, setIsSubmitting] = React.useState(false) - const { hasSession, error, login } = props - <% if (stylesSolution == 'sass') { %>const { disabled, wrapper, container, image } = loginStyles<%}%> - - React.useEffect(() => { - if (error) { - setIsSubmitting(false) - } - }, [error]) - - if (hasSession) { - return - } - - return ( - <% if (stylesSolution == 'sass') { %>
-
-

Sign in

-

Welcome to <%= name %>

<%}%> - - <% if (stylesSolution == 'styledComponents') { %> - -

Sign in

-

Welcome to <%= name %>

<%}%> - - onSubmitHandler(setIsSubmitting, login, values)} - render={() => ( -
- - - - - - - - {error && } - - )} - /> - - - <% if (stylesSolution == 'sass') { %> -
- -
- Reapit Graphic -
-
- <%}%> - <% if (stylesSolution == 'styledComponents') { %> - - - - Reapit Graphic - - - <%}%> - ) -} - -export default withRouter(Login) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/app.tsx.snap b/packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/app.tsx.snap deleted file mode 100644 index 11f21ac70a..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/app.tsx.snap +++ /dev/null @@ -1,1847 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`App should match a snapshot 1`] = ` - - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - }, - "watches": Set {}, - }, - "clearStoreCallbacks": Array [], - "defaultOptions": Object {}, - "disableNetworkFetches": false, - "link": ApolloLink { - "request": [Function], - }, - "localState": LocalState { - "cache": InMemoryCache { - "addTypename": true, - "cacheKeyRoot": KeyTrie { - "weakness": true, - }, - "config": Object { - "addTypename": true, - "dataIdFromObject": [Function], - "fragmentMatcher": HeuristicFragmentMatcher {}, - "freezeResults": false, - "resultCaching": true, - }, - "data": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "maybeBroadcastWatch": [Function], - "optimisticData": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "silenceBroadcast": false, - "storeReader": StoreReader { - "executeSelectionSet": [Function], - "executeStoreQuery": [Function], - "executeSubSelectedArray": [Function], - "freezeResults": false, - }, - "storeWriter": StoreWriter {}, - "typenameDocumentCache": Map { - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - }, - "watches": Set {}, - }, - "client": [Circular], - "resolvers": Object { - "Mutation": Object {}, - "Query": Object { - "contacts": [Function], - }, - }, - }, - "mutate": [Function], - "query": [Function], - "queryDeduplication": true, - "queryManager": QueryManager { - "assumeImmutableResults": false, - "clientAwareness": Object { - "name": undefined, - "version": undefined, - }, - "dataStore": DataStore { - "cache": InMemoryCache { - "addTypename": true, - "cacheKeyRoot": KeyTrie { - "weakness": true, - }, - "config": Object { - "addTypename": true, - "dataIdFromObject": [Function], - "fragmentMatcher": HeuristicFragmentMatcher {}, - "freezeResults": false, - "resultCaching": true, - }, - "data": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "maybeBroadcastWatch": [Function], - "optimisticData": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "silenceBroadcast": false, - "storeReader": StoreReader { - "executeSelectionSet": [Function], - "executeStoreQuery": [Function], - "executeSubSelectedArray": [Function], - "freezeResults": false, - }, - "storeWriter": StoreWriter {}, - "typenameDocumentCache": Map { - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - }, - "watches": Set {}, - }, - }, - "fetchQueryRejectFns": Map {}, - "idCounter": 1, - "inFlightLinkObservables": Map {}, - "link": ApolloLink { - "request": [Function], - }, - "localState": LocalState { - "cache": InMemoryCache { - "addTypename": true, - "cacheKeyRoot": KeyTrie { - "weakness": true, - }, - "config": Object { - "addTypename": true, - "dataIdFromObject": [Function], - "fragmentMatcher": HeuristicFragmentMatcher {}, - "freezeResults": false, - "resultCaching": true, - }, - "data": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "maybeBroadcastWatch": [Function], - "optimisticData": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "silenceBroadcast": false, - "storeReader": StoreReader { - "executeSelectionSet": [Function], - "executeStoreQuery": [Function], - "executeSubSelectedArray": [Function], - "freezeResults": false, - }, - "storeWriter": StoreWriter {}, - "typenameDocumentCache": Map { - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - }, - "watches": Set {}, - }, - "client": [Circular], - "resolvers": Object { - "Mutation": Object {}, - "Query": Object { - "contacts": [Function], - }, - }, - }, - "mutationStore": MutationStore { - "store": Object {}, - }, - "onBroadcast": [Function], - "pollingInfoByQueryId": Map {}, - "queries": Map {}, - "queryDeduplication": true, - "queryStore": QueryStore { - "store": Object {}, - }, - "ssrMode": false, - "transformCache": WeakMap {}, - }, - "reFetchObservableQueries": [Function], - "resetStore": [Function], - "resetStoreCallbacks": Array [], - "store": DataStore { - "cache": InMemoryCache { - "addTypename": true, - "cacheKeyRoot": KeyTrie { - "weakness": true, - }, - "config": Object { - "addTypename": true, - "dataIdFromObject": [Function], - "fragmentMatcher": HeuristicFragmentMatcher {}, - "freezeResults": false, - "resultCaching": true, - }, - "data": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "maybeBroadcastWatch": [Function], - "optimisticData": DepTrackingCache { - "data": Object {}, - "depend": [Function], - }, - "silenceBroadcast": false, - "storeReader": StoreReader { - "executeSelectionSet": [Function], - "executeStoreQuery": [Function], - "executeSubSelectedArray": [Function], - "freezeResults": false, - }, - "storeWriter": StoreWriter {}, - "typenameDocumentCache": Map { - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - } => Object { - "definitions": Array [ - Object { - "kind": "OperationDefinition", - "name": Object { - "kind": "Name", - "value": "GeneratedClientQuery", - }, - "operation": "query", - "selectionSet": Object { - "kind": "SelectionSet", - "selections": Array [], - }, - }, - ], - "kind": "Document", - }, - }, - "watches": Set {}, - }, - }, - "typeDefs": Object { - "definitions": Array [ - Object { - "directives": Array [], - "fields": Array [ - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "id", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "contact", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Contact", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "name", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "address", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "negotiatorId", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "officeId", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "active", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Boolean", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "pageNumber", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Int", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "pageSize", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Int", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "sortBy", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "identityCheck", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "marketingConsent", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "contacts", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Contacts", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "id", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "checkId", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "contactIdentityCheck", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactIdentityCheck", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "id", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "pageNumber", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Int", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "pageSize", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Int", - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "contactIdentityChecks", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactIdentityChecks", - }, - }, - }, - }, - ], - "interfaces": Array [], - "kind": "ObjectTypeDefinition", - "name": Object { - "kind": "Name", - "value": "Query", - }, - }, - Object { - "directives": Array [], - "fields": Array [ - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "title", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "forename", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "surname", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "dateOfBirth", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "active", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Boolean", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "marketingConsent", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "communications", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactCommunicationInput", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "officeIds", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "negotiatorIds", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "addresses", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactAddressInput", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "metadata", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "JSON", - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "createContact", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Contact", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "id", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "title", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "forename", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "surname", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "dateOfBirth", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "active", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Boolean", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "marketingConsent", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "communications", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactCommunicationInput", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "officeIds", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "negotiatorIds", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "addresses", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactAddressInput", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "metadata", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "JSON", - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "updateContact", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Contact", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "contactId", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "checkDate", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "status", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "negotiatorId", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "documents", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactIdentityDocumentInput", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "metadata", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "JSON", - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "createContactIdentityCheck", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactIdentityCheck", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "id", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "contactId", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "checkDate", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "status", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "negotiatorId", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "documents", - }, - "type": Object { - "kind": "ListType", - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactIdentityDocumentInput", - }, - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "metadata", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "JSON", - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "updateIdentityCheck", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "ContactIdentityCheck", - }, - }, - }, - }, - Object { - "arguments": Array [ - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "userName", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "password", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "String", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "loginType", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "LoginType", - }, - }, - }, - }, - Object { - "directives": Array [], - "kind": "InputValueDefinition", - "name": Object { - "kind": "Name", - "value": "mode", - }, - "type": Object { - "kind": "NonNullType", - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "LoginMode", - }, - }, - }, - }, - ], - "directives": Array [], - "kind": "FieldDefinition", - "name": Object { - "kind": "Name", - "value": "login", - }, - "type": Object { - "kind": "NamedType", - "name": Object { - "kind": "Name", - "value": "Token", - }, - }, - }, - ], - "interfaces": Array [], - "kind": "ObjectTypeDefinition", - "name": Object { - "kind": "Name", - "value": "Mutation", - }, - }, - ], - "kind": "Document", - "loc": Object { - "end": 1872, - "source": Object { - "body": "type Query { - # contact - contact( - id: String!, - ): Contact! - - contacts( - name: String, - address: String, - negotiatorId: [String!], - officeId: [String!], - active: Boolean, - pageNumber: Int, - pageSize: Int, - sortBy: String, - identityCheck: [String!], - marketingConsent: [String!], - ): Contacts! - - # contact-identity-check - contactIdentityCheck( - id: String!, - checkId: String!, - ): ContactIdentityCheck! - - contactIdentityChecks( - id: String!, - pageNumber: Int, - pageSize: Int, - ): ContactIdentityChecks! - -} - -type Mutation { - # contact - createContact( - title: String, - forename: String, - surname: String, - dateOfBirth: String, - active: Boolean, - marketingConsent: String, - communications: [ContactCommunicationInput!], - officeIds: [String!], - negotiatorIds: [String!], - addresses: [ContactAddressInput!], - metadata: JSON, - ): Contact! - - updateContact( - id: String!, - title: String, - forename: String, - surname: String, - dateOfBirth: String, - active: Boolean, - marketingConsent: String, - communications: [ContactCommunicationInput!], - officeIds: [String!], - negotiatorIds: [String!], - addresses: [ContactAddressInput!], - metadata: JSON, - ): Contact! - - # contact-identity-check - createContactIdentityCheck( - contactId: String!, - checkDate: String, - status: String, - negotiatorId: String, - documents: [ContactIdentityDocumentInput!], - metadata: JSON, - ): ContactIdentityCheck! - - updateIdentityCheck( - id: String!, - contactId: String!, - checkDate: String, - status: String, - negotiatorId: String, - documents: [ContactIdentityDocumentInput!], - metadata: JSON, - ): ContactIdentityCheck! - - login( - userName: String!, - password: String!, - loginType: LoginType!, - mode: LoginMode!, - ): Token -} -", - "locationOffset": Object { - "column": 1, - "line": 1, - }, - "name": "GraphQL request", - }, - "start": 0, - }, - }, - "version": "2.6.8", - "watchQuery": [Function], - } - } - > - - - - -`; diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/private-route-wrapper.tsx.snap b/packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/private-route-wrapper.tsx.snap deleted file mode 100644 index faa51af46d..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/core/__tests__/__snapshots__/private-route-wrapper.tsx.snap +++ /dev/null @@ -1,835 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PrivateRouter should match a snapshot 1`] = ` -Object { - "asFragment": [Function], - "baseElement": -
- - , - "container":
- , - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; - -exports[`PrivateRouter should match a snapshot 2`] = ` -Object { - "asFragment": [Function], - "baseElement": -
- , - "container":
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/core/private-route-wrapper.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/core/private-route-wrapper.tsx deleted file mode 100644 index 58587d8930..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/core/private-route-wrapper.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react' -import { withRouter, RouteComponentProps, Redirect } from 'react-router-dom' -import Menu from '@/components/ui/menu' -import { Loader, AppNavContainer, Section, FlexContainerBasic } from '@reapit/elements' -import { redirectToOAuth } from '@reapit/cognito-auth' -import { AuthContext } from '@/context' -import Routes from '@/constants/routes' - -const { Suspense } = React - -export type PrivateRouteWrapperProps = RouteComponentProps & { - path: string -} - -export const PrivateRouteWrapper: React.FunctionComponent = ({ children }) => { - const { loginSession, refreshParams, getLoginSession } = React.useContext(AuthContext) - - if (!loginSession && !refreshParams) { - redirectToOAuth(window.reapit.config.cognitoClientId) - return null - } - - if (!loginSession && refreshParams) { - getLoginSession(refreshParams) - } - - if (!loginSession) { - return null - } - - if (location.pathname === '/') { - return - } - - return ( - - - - - - - } - > - {children} - - - - ) -} - -export default withRouter(PrivateRouteWrapper) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contact.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contact.ts deleted file mode 100644 index 63fd063889..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contact.ts +++ /dev/null @@ -1,24 +0,0 @@ -export const contact = { - __typename: 'Contact', - active: false, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: 'building name', - buildingNumber: '1', - line1: '15 Furzen Crescent', - line2: 'line2', - line3: 'line3', - postcode: 'AL10 9QN', - }, - ], - created: '2019-11-26T11:19:23.0000000Z', - dateOfBirth: '1986-06-29T13:00:00.0000000Z', - forename: 'Development', - id: 'MOD19000001', - identityCheck: 'pass', - marketingConsent: 'notAsked', - modified: '2019-12-13T13:32:28.0000000Z', - surname: 'Environment', - title: 'Mrs', -} diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contacts.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contacts.ts deleted file mode 100644 index 58008eacc2..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/contacts.ts +++ /dev/null @@ -1,243 +0,0 @@ -export const contacts = { - __typename: 'Contacts', - _embedded: [ - { - __typename: 'Contact', - active: false, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: 'building name', - buildingNumber: '1', - line1: '15 Furzen Crescent', - line2: 'line2', - line3: 'line3', - postcode: 'AL10 9QN', - }, - ], - created: '2019-11-26T11:19:23.0000000Z', - dateOfBirth: '1986-06-29T13:00:00.0000000Z', - forename: 'Development', - id: 'MOD19000001', - identityCheck: 'pass', - marketingConsent: 'notAsked', - modified: '2019-12-13T13:32:28.0000000Z', - surname: 'Environment', - title: 'Mrs', - }, - { - __typename: 'Contact', - active: true, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: '', - buildingNumber: '38', - line1: 'Stephen Crescent', - line2: 'Humberston', - line3: 'Grimsby', - postcode: 'DN36 4DT', - }, - ], - created: '2019-11-05T12:47:50.0000000Z', - dateOfBirth: '1981-03-25', - forename: 'Paul', - id: 'AYL19000004', - identityCheck: 'cancelled', - marketingConsent: 'notAsked', - modified: '2019-11-26T13:18:04.0000000Z', - surname: 'Rideout', - title: 'Mr', - }, - { - __typename: 'Contact', - active: false, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: '', - buildingNumber: '86a', - line1: 'Potternewton Lane', - line2: 'Chapel Allerton', - line3: 'Leeds', - postcode: 'LS7 3LW', - }, - ], - created: '2019-11-05T12:35:44.0000000Z', - dateOfBirth: '1981-03-25', - forename: 'Dave', - id: 'AYL19000003', - identityCheck: 'pending', - marketingConsent: 'notAsked', - modified: '2019-11-26T13:18:04.0000000Z', - surname: 'Gilbert', - title: 'Mr', - }, - { - __typename: 'Contact', - active: false, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: 'Tyto Alba', - buildingNumber: '38', - line1: 'Stephen Crescent', - line2: 'Humberston', - line3: 'Grimsby', - postcode: 'DN36 4DT', - }, - ], - created: '2019-11-04T11:32:55.0000000Z', - dateOfBirth: '1981-03-26', - forename: 'Charles', - id: 'AYL19000002', - identityCheck: 'cancelled', - marketingConsent: 'notAsked', - modified: '2019-11-26T13:18:04.0000000Z', - surname: 'Babbage', - title: 'Mr', - }, - { - __typename: 'Contact', - active: true, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: 'Name', - buildingNumber: '38', - line1: 'Stephen Crescent', - line2: 'Grimsby', - line3: 'N E Lincs', - postcode: 'DN36 4DT', - }, - ], - created: '2019-11-03T19:45:29.0000000Z', - dateOfBirth: '1981-03-24T17:00:00.0000000Z', - forename: 'Dawson', - id: 'RPT19000366', - identityCheck: 'pending', - marketingConsent: 'notAsked', - modified: '2019-12-11T07:11:42.0000000Z', - surname: 'Scott', - title: 'Mr', - }, - { - __typename: 'Contact', - active: true, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: 'Ash Lodge', - buildingNumber: '3', - line1: 'Northbourne Road', - line2: 'London', - line3: '', - postcode: 'SE5 9RL', - }, - ], - created: '2019-11-03T19:09:58.0000000Z', - dateOfBirth: '1984-09-24', - forename: 'Katy', - id: 'RPT19000365', - identityCheck: 'pending', - marketingConsent: 'notAsked', - modified: '2019-11-04T16:16:28.0000000Z', - surname: 'Easton', - title: 'Ms', - }, - { - __typename: 'Contact', - active: true, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: 'aa', - buildingNumber: '37', - line1: 'Kingsway Place', - line2: 'London', - line3: 'a', - postcode: 'EC1R 0LU', - }, - ], - created: '2019-10-31T14:19:51.0000000Z', - dateOfBirth: '2019-12-12', - forename: 'H', - id: 'AYL19000001', - identityCheck: 'pass', - marketingConsent: 'grant', - modified: '2019-12-13T05:38:17.0000000Z', - surname: 'Phillips', - title: 'Mrs', - }, - { - __typename: 'Contact', - active: true, - addresses: [ - { - __typename: 'ContactAddress', - buildingName: '', - buildingNumber: '46', - line1: 'Farm Street', - line2: 'High Wycombe', - line3: 'Milton Keynes', - postcode: 'MK4 4AG', - }, - ], - created: '2019-10-25T11:09:08.0000000Z', - dateOfBirth: '1986-06-30', - forename: 'Rogan', - id: 'RPT19000363', - identityCheck: 'pending', - marketingConsent: 'notAsked', - modified: '2019-12-10T10:13:44.0000000Z', - surname: 'Johnstone', - title: 'Mr', - }, - { - __typename: 'Contact', - active: true, - addresses: null, - created: '2019-10-24T09:11:29.0000000Z', - dateOfBirth: null, - forename: 'James', - id: 'BED19000003', - identityCheck: 'pending', - marketingConsent: 'notAsked', - modified: '2019-10-24T09:14:55.0000000Z', - surname: 'Brown', - title: 'Mr', - }, - { - __typename: 'Contact', - active: true, - addresses: null, - created: '2019-10-24T08:29:00.0000000Z', - dateOfBirth: null, - forename: '', - id: 'RPT19000362', - identityCheck: 'unchecked', - marketingConsent: 'notAsked', - modified: '2019-10-24T08:30:17.0000000Z', - surname: '', - title: '', - }, - ], - _links: { - first: { - href: '/contacts/?PageNumber=1&PageSize=10', - }, - last: { - href: '/contacts/?PageNumber=397&PageSize=10', - }, - next: { - href: '/contacts/?PageNumber=2&PageSize=10', - }, - self: { - href: '/contacts/?PageNumber=1&PageSize=10', - }, - }, - pageCount: 10, - pageNumber: 1, - pageSize: 10, - totalCount: 3966, -} diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/error.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/error.ts deleted file mode 100644 index 7d2d3432ee..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/error.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const error = { - message: 'mockError', - graphQLErrors: [], - networkError: { name: 'Error', message: 'Error' }, - extraInfo: [], - name: 'Error', -} diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/token.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/token.ts deleted file mode 100644 index b24f710d1c..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__mocks__/token.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LoginParams } from '@reapit/cognito-auth' - -export const token = { - __typename: 'Token', - accessToken: 'mockAccessToken', - refreshToken: 'mockRefreshToken', -} - -export const loginParams = { - userName: 'mockUsername', - password: 'mockPassword', - loginType: 'CLIENT', - mode: 'WEB', -} as LoginParams diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/client.test.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/client.test.ts deleted file mode 100644 index 1795abcefd..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/client.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Operation, IdGetterObj } from 'apollo-boost' -import { ErrorResponse } from 'apollo-link-error' -import { GraphQLError } from 'graphql' -import { getClient, generateRequest, onError, dataIdFromObject } from '@/graphql/client' - -describe('client', () => { - describe('getClient', () => { - it('should run correctly', () => { - const mockAccessToken = 'mockAccessToken' - const result = getClient(mockAccessToken) - expect(result).toBeDefined() - }) - }) - describe('generateRequest', () => { - it('should run correctly', done => { - // @ts-ignore - const mockOperation = { - setContext: jest.fn(), - } as Operation - generateRequest('mockToken')(mockOperation) - setTimeout(() => { - expect(mockOperation.setContext).toBeCalled() - done() - }, 1000) - }) - }) - describe('onError', () => { - it('should run correctly when have both', () => { - const mockError = { - graphQLErrors: [new GraphQLError('123')] as ReadonlyArray, - networkError: new Error('abc'), - } as ErrorResponse - onError(mockError) - }) - - it('should run correctly when no graphQLErrors', () => { - const mockError = { - graphQLErrors: [] as ReadonlyArray, - networkError: new Error('abc'), - } as ErrorResponse - onError(mockError) - }) - - it('should run correctly when no networkError', () => { - const mockError = { - graphQLErrors: [new GraphQLError('123')] as ReadonlyArray, - networkError: undefined, - } as ErrorResponse - onError(mockError) - }) - - it('should run correctly when no error', () => { - const mockError = { - graphQLErrors: [] as ReadonlyArray, - networkError: undefined, - } as ErrorResponse - onError(mockError) - }) - }) - - describe('dataIdFromObject', () => { - it('should run correctly', () => { - const mockObject = { - __typename: 'mockType', - id: '1', - } as IdGetterObj - const result = dataIdFromObject(mockObject) - const output = `${mockObject.__typename}:${mockObject.id}` - expect(result).toEqual(output) - }) - }) -}) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/resolver.test.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/resolver.test.ts deleted file mode 100644 index cb8c68a361..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/__tests__/resolver.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import resolvers from '../resolvers' -import { contacts } from '../__mocks__/contacts' - -describe('resolvers', () => { - describe('contacts', () => { - it('should run correctly', async done => { - const result = await resolvers.Query.contacts() - setTimeout(() => { - expect(result).toEqual(contacts) - done() - }, 2000) - }) - }) -}) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/client.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/client.ts deleted file mode 100644 index 8d768100af..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/client.ts +++ /dev/null @@ -1,54 +0,0 @@ -import ApolloClient, { InMemoryCache, Operation, defaultDataIdFromObject, IdGetterObj } from 'apollo-boost' -import { ErrorHandler, ErrorResponse } from 'apollo-link-error' -import { ApolloCache } from 'apollo-cache' -import typeDefs from './schema.graphql' -import resolvers from './resolvers' - -export const generateRequest = (accessToken: string) => async (operation: Operation) => { - operation.setContext({ - headers: { - authorization: accessToken, - }, - }) -} - -export const onError: ErrorHandler = ({ graphQLErrors, networkError }: ErrorResponse) => { - if (graphQLErrors) { - graphQLErrors.map(({ message, locations, path }) => - console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`), - ) - } - if (networkError) console.log(`[Network error]: ${networkError}`) -} - -export const dataIdFromObject = (object: IdGetterObj) => { - // Will open when custom object ID for caching - // switch (object.__typename) { - // // Custom keycache here! - // default: - // return defaultDataIdFromObject(object) - // } - return defaultDataIdFromObject(object) -} - -const cache: ApolloCache = new InMemoryCache({ - dataIdFromObject, -}) - -const clientState = { - cache, - defaults: {}, - resolvers, - typeDefs, -} - -export const getClient = (accessToken: string, uri: string) => - new ApolloClient({ - uri, - onError, - cache, - request: generateRequest(accessToken), - clientState, - }) - -export default getClient diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/resolvers.ts b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/resolvers.ts deleted file mode 100644 index cbc9e3919e..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/resolvers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import sleep from '@/utils/sleep' -import { contacts } from './__mocks__/contacts' - -const resolvers = { - Query: { - contacts: async () => { - await sleep(1000) - return contacts - }, - }, - Mutation: {}, -} - -export default resolvers diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/schema.graphql b/packages/react-app-scaffolder/app/templates/apollo/src/graphql/schema.graphql deleted file mode 100644 index 4253cc49dc..0000000000 --- a/packages/react-app-scaffolder/app/templates/apollo/src/graphql/schema.graphql +++ /dev/null @@ -1,3 +0,0 @@ -type Query {} - -type Mutation {} diff --git a/packages/react-app-scaffolder/app/templates/base-is-linaria/src/styles/index.css b/packages/react-app-scaffolder/app/templates/base-is-linaria/src/styles/index.css deleted file mode 100644 index 3c02e6809d..0000000000 --- a/packages/react-app-scaffolder/app/templates/base-is-linaria/src/styles/index.css +++ /dev/null @@ -1,9 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap'); -@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap'); - - -<%if (!isFoundation) { %> -/* need this because we import production elements. in foundation we import the code from element directly which imports the element styles */ -@import "~@reapit/elements/dist/index.css" -<% } %> - diff --git a/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/colors.scss b/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/colors.scss deleted file mode 100644 index cefdf1553b..0000000000 --- a/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/colors.scss +++ /dev/null @@ -1,27 +0,0 @@ -$white: #fff; -$black: #12263f; -$grey-dark: #6e84a3; -$grey: #95aac9; -$grey-lighter: #e3ebf6; -$grey-lightest: #f9fbfd; - -$green: #5fe781; -$green-lighter: #acf2bd; -$green-lightest: #e6ffed; -$red: #e96171; -$red-lighter: #fdb8c0; -$red-lightest: #ffeef0; - -$reapit-dark-blue: #262f69; -$reapit-mid-blue: #0061a8; -$reapit-light-blue: #23a4de; -$reapit-lightest-blue: #7bc9eb; - -$reapit-orange: #ec631b; -$reapit-lime: #cddb00; -$reapit-teal: #006580; -$reapit-plumb: #7a2c81; -$reapit-purple: #a4185c; -$reapit-gold: #ffb71b; -$reapit-green: #a0c862; -$reapit-red: #d3033d; diff --git a/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/layout.scss b/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/layout.scss deleted file mode 100644 index a21cb393db..0000000000 --- a/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/base/layout.scss +++ /dev/null @@ -1,14 +0,0 @@ -$layout-base: 1rem; -// Generic layout values that scale to rem base -$layout-quarter: calc(1rem / 4); -$layout-third: calc(1rem / 3); -$layout-half: calc(1rem / 2); -$layout-two-third: calc(1rem * 0.67); -$layout-three-quarter: calc(1rem * 0.75); -$layout-one-quarter: calc(1rem * 1.25); -$layout-one-half: calc(1rem * 1.5); -$layout-double: calc(1rem * 2); -$layout-two-half: calc(1rem * 2.5); -$layout-triple: calc(1rem * 3); -$layout-quadruple: calc(1rem * 4); -$layout-sextuple: calc(1rem * 6); diff --git a/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/index.scss b/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/index.scss deleted file mode 100644 index 279ed39041..0000000000 --- a/packages/react-app-scaffolder/app/templates/base-is-sass/src/styles/index.scss +++ /dev/null @@ -1,8 +0,0 @@ -@charset "utf-8"; -@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap'); -@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap'); - -<%if (!isFoundation) { %> -/* need this because we import production elements. in foundation we import the code from element directly which imports the element styles */ -@import "~@reapit/elements/dist/index.css" -<% } %> diff --git a/packages/react-app-scaffolder/app/templates/base/.npmrc b/packages/react-app-scaffolder/app/templates/base/.npmrc deleted file mode 100644 index bd3327ab5a..0000000000 --- a/packages/react-app-scaffolder/app/templates/base/.npmrc +++ /dev/null @@ -1 +0,0 @@ -//registry.npmjs.org/:_authToken=${NPM_TOKEN} \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/templates/base/public/index.js b/packages/react-app-scaffolder/app/templates/base/public/index.js deleted file mode 100644 index d0e80f1ee1..0000000000 --- a/packages/react-app-scaffolder/app/templates/base/public/index.js +++ /dev/null @@ -1,38 +0,0 @@ -const http = require('http') -const url = require('url') -const fs = require('fs') -const path = require('path') -const port = 8080 - -http - .createServer((request, response) => { - try { - const requestUrl = url.parse(request.url) - const fsPath = `${__dirname}/dist${path.normalize(requestUrl.pathname)}` // need to use path.normalize so people can't access directories underneath baseDirectory - const fileStream = /\.(js|css|woff|gif|jpg|jpeg|tiff|png)$/i.test(fsPath) - ? fs.createReadStream(fsPath) - : fs.createReadStream(`${__dirname}/dist/index.html`) - - fileStream.pipe(response) - fileStream.on('open', () => { - response.writeHead(200) - }) - fileStream.on('error', e => { - response.writeHead(404) // assume the file doesn't exist - response.end() - }) - } catch (e) { - response.writeHead(500) - response.end() // end the response so browsers don't hang - console.log(e.stack) - } - }) - .listen(port) - -process.title = process.argv[2] -process.on('SIGINT', () => { - console.log(`Gracefully shutting down ${process.title}`) - process.exit() -}) - -console.log(`Listening on port ${port}`) diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/353acc2c-88f2-4de3-83eb-6cc2c9b05af1.ttf b/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/353acc2c-88f2-4de3-83eb-6cc2c9b05af1.ttf deleted file mode 100755 index 7a2e60c6d8c7e70500fc8b459d26d3edf1f2aa9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63352 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 diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/9803fddf-c005-431a-92d5-0f18688f945d.woff2 b/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/9803fddf-c005-431a-92d5-0f18688f945d.woff2 deleted file mode 100755 index c38d9ef1e7fc1bcef327b7118a8d14efcb112d48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28760 zcmV(_K-9l?Pew8T0RR910B~3U5C8xG0Qk@V0B`pI0RR9100000000000000000000 z0000R$a)-&BnDs>i(mkU6bOT436f9>g2VuVn^6Ha0we>DC<~4(00bZfhTj#?7cPFR(_R#|J#NQ{g#)yd;K+)WHB(eCY!J+8C{}k_TT{B0HdGCF3V+>x1fp@IsOYv@z4IulbB3sF2dZ3xCbM#fTC-SxkR{;tC4! zaDf85St_$P2jfq<^FMW^br%BfC9J^LD6BBrmIDrW_na9kD9`w2p-N39>Y%Ehukxk> zs(_0&6>tP3f&k$E=`7nBdv^mQ2N>JER4L0p(!z|qyKlyOAT3&la!@|B4+zQt@@P>G z%7@yZ9kfG0Wx5niiaKTLbXCgRE_KT4;OSeI(k*4jK$VaQQ3Aw(nZT;r+0lO2wP#zo z6%x8}9;djoH>a480W={Y9Tc+wG&BIr&j8skXRkPzg~I=|I`T&Lca-#UFWj;gFnhI< zl6!a$g0Nv>A-=y*&OD&CuK|qPJKQ-6u9kXS5Gg$N(~_T8SJEn@Yrqx;LA|fT1lHMO*kWiC4BqWbs0KjF?GeUPB|8N?liC85ZnxB)A9 zJs5y1fRy%-bfV<6AqHZj=`62PsM-)qyK>hWhC209Va?bLr0Q>mhUs|qW+>?jA>>3P zh=@quH}-O9HG1wfhe*g(cyj1#9@n)p=|aCJ7g^M@ zT;vdk%yq_`n8nE805p(Nvd@?9_n2agSA?!E2r=9;oSyEx*i`F4u|ToAnTRvzmLEpk zeGwA29m7dV2IQk`Z(+uXZYL!9GlQ}^wf9;$ll^_V3mtz>+J~)^chZF^#*Jg(DK z5CGT%(9j1=y)P#nKmic&Sii*Gfu=l^-IBAGq0eADNCpO_UDZ?G!M(C>W`+waiv=BZ zH^2yEOm&ZC*1O+9C!F)W-vffl2Q>m>EN0?Dyo~pWgj3Tn8CjCeIi6?p?|l7&S2;v1 zS{YYBC00Q-*I=EkOLeP0H-x|-sBPHRy{C(Mu&4W4uMU~vK1xQ__-|}X`Ds5Lr~CAs z>{&lWb9_$E8}rdzp6}=PT>uJ?BFavzqoAq|cO==eB590r81JMjdIjeVV&#HGgtt7bjllE;5#hhz>$D~n!#yNbzZwxS6O5(SP@7o(i2tO#8h^-Vx zBzsCm>Q2uPYUE~VSC4T4c{T5G?9N&%tOo)=hk#2+vl6a!8p>2tK&eX!M-7t#qgoqr z%S=c3Ya+PQhPEQg6eh0A>tucCnP7#l!|*z?x3bTHqG-ly4#q|h!PoCaFK2lJ2^I{v zxzNw37W7=lg3lv)!j^<$qU>a>mglT5D6bshjdJG_p}YhzmxrDJEc~g22(3jyFm0eJ z1qEmqxr|c`>anc3dk2w9f!%&Z&Z63tR|Yt6t_}vS+)~KWDg`Fzs}UTabaLVmY$LT1 z#5imq2Hq9hMkE$2VF{Y+V1oBj1cNw%G0jLwt+D}*K~(twx@)2(N+>vrj{z+V@IueQ z8=)72fYv2ZV~@=;0tU(L0y6_TlAS=*EN?dAMIs1m$aZu!BQ-%=Fazi@(mT<>aIRL2 z3oD1A`m9Ak+(aLBaVW>O;K6x{fFJ?X8iAo|g)Uu;Fd84z)Tfg{R#sf2C_ofNA!v=r zi zCP~qN>mnFI6c}(IPy5G~Kpv8=hf7F&07DjkrH};~FXyC5WWECof*EMKl0oxJ9G;gv zu+m)#gvJH1#{~mQ|JvwphM5dnf-^c44?w*n*!YBw2^MFUBJZz`z=)2p!X&DN4cul^ zpvxo?QnJDSlF-1KCg159b!+h=1o$Ud%98cZ0AF9a6|4tfL*O7~?0z#4=% z;WoucZ1X=OEa}kc|FPGY7jSCY&qLBsK~v2e-SBv`p_k;TgmPrmn4Kq({+k6 zm2RE2n|0v3d%lpp0_a~L#}cHRv1_T$G1p+vn$<1_m4Ow!ISX>9x*EL(VR3*``P%Kp zpcN8Ey(^u@=RDnzeT33MjsBm*Py}uWa({d8&i8a)2b)bL!kaTWVEYk#zfz%P(wN6m zZU^qnXZ`lFgnks7T!IXIgLo#L9;CU13llb>W56*ZX!pcFlEIun48vC z8?TYBxXeH!?fTK1rB!}EMoQT};|&Fpldthm4f!Lt@BZ@v?$)0p_1D1DL>@k~O4 zN)ZX=k_S-Gqk@h9xVH3!3T{6bQ6vEkW@xy64X`Ur3L~oIp0k!Su9SVTiLm6|=(_Y` zgHzM{b9y4z@_m}JK#&s(oBZOAcAA+T{Lc?1q`RVX3hNeR$aiH7GFHcRb$}nxB5vj| zlx9duUn0-Pj2R*)g z(vCr??>k5pf9B)S#;R>EYzGd8pF zpx5)3Doi=1Qv4w8!=}hFNWgW+R}3&ASthlHE#^h!l1Rg!0okS$DQ1Vlr|&uK8C1IB z>Jxy6^fr);<1EuA3&}xfta{B{WE>XTgHNd*iH9XZ=|zy|U!$8iB(bF6_w=oMMll>*1%gXUQ96cNVi&Hjm?+s zu*VT+Tpi}M-0{W-76I&nP2i`k6-)@Bgb_{zJPQ5Pwu^2K`H@>ExXEo^;nBacB~7|2 zs%osM=2~c_jdnWdp|^e!;MQF8t!ek#U=vQj0A{HH3>u(XLLdgA>-KYMc%WX4($&Bh ze>4kH(A^Q?(ZiG0gd$o`q_i{eI);Sck~m&2(*pImn^W9?!!5G8v(erIIXr;RBlhq& zx%@*O%jENv0{(ppS>?s&`x2D%nhM@h$$P5!h=7gHYCiLg8h#+;CwtkZf#3f%A_nn5 zlLY1Im$Y>lk$f1H`em$c(KuAQ%k#g+UsVpPzI~Wb^KeA%!=$>0qv{`~G|W(Ntje}6 z$K8S8+|F`f&N@ptudjYw*53)P*4&QanmGurSKrKKz5!-F3t_BL!41eDZsTQ>U<~%X zq?%~BqLVw0d{-xs4sww8g|i8OH!>0a{%EL3DtNZZmis z(DG`c)wN|pOxymz=7d~rQ109wyYOUVBM-W(;hIk|BG=8O6%r`Chwyhb0vsyPJsEYN z_tb#Aw+G+!Iret4ryBHkRM<1{70>}wN!nIi8OYo_Q-8)UvQGY8@O7`nSJobO757C# zX_n;P?q(*Jf_E=WjC&4C&466ZtD3xHR)vUCnGj<kshBLCQM@pvHg2tZ$(ebq^Ua z&GqexHUWZToI_(?hBZ48k(?BsI*_fxAFIvk#*SM#nstpv0dwNbqN$mx(KdxaB@rsZ z9Zms)sNY4HE-&os!WUq(12`m%usM&*0X8>tt+>2>q-km(+)fN5uB;9oclLmJvK98+ z;8drFia8mGRJyzt``M{mpuqJ%Ibf>l7zoHVlS2#j*huhh@*bg{FQhK@+?`T z+EmFBcZeh#r4lI7rH%#R>YPi?&CT)Tww`|e*(=SHPakWqD$u&^Ah4e_fNS^FRreQ| z#98GVzxEDSmOXMd$LzD7n`%##exsRedUDRHFc4T`b?ds9m3VK|?()12i> zCgD-e;6;u|U#T6RSP>t2Tfjk#n1OmJ`eG@L!V->TOSSaKwA@*KcK4n9Dryo_iIaMn zn*DhT_m-~0J``w|N@*DU7c%mRFPCGX-C$mRM}buqB^Fz0I@09|EV1;Jc8k>)MG#** z(p1yX#aM0w_PXI|{3U&?O9;anJF88b1fyY%6Z$;kK=`FY@z$jUfK@Vve?KQv@7#ht z1)X?2C&sYWTX^5TcmE?J*+8mDZ^dqZ7zlVKdXv*Z21s}idRgOL)scYPqSt(MNB~8= zwMdWrbB_r25;W`=dcTkNd<6__8I?z)a=b8V?@=#KKX#xIm8rvq6Jc#_knOVCn7dl* z%y}#v*f^Yew>|dSXTQz1*lL^YcG&4Yk`H8sh4rmY?Mz-`vMJ18|1{IhFw-ov*@UZJS%$JG*=POK=W+`iTvX*T*mZ zD+@50Y%ZT51Jyj(hBP$BLpJisW-?odgfw9MzZgl;R-4`7bh)9x2It=SRYHW;#({u& z8G7B*YbNnFfcBiwK!oFvxaE5JTnhEnOSZv=tfa9U_YzB=-(pu)%nl6Y5q!FiDPcwM zO=^Qc-AY#s%K$t^8uu7@AHj~gG!{wP6H#H$Yn`CpB7@)$O_z&9>rI@i| zAETM13|5>^9J^geNyTsdF7Qdx1P*I2{As^*^=6C*AY22#Jf0Ccizty|x3=|`f_t>& z6opj1L>=3*xshdPDRV^sPfRM}z^nj_t+NSq0mthP1058$1=s;#Vu3w1F`;)M&A?$7 za3nwF1z9k_lzmrR5oJ( zTeE@v>@dU#rM!q^_A&x^1(<7Z;_zpDB&2!l69MOGKb+4K!sh~f0q`YYUims2hii4B z-T@5&jeuk7JAWb-H1`2nIM%-NR-S0>LzKQY(e8i_fKI@1^|;eBBRA32h5lV1h(jr{u*l|KTZs-Hk345lVo>hP?RK!;q{U%U_5h5Z$tU8GrPBp1oAXA52Jqp5?^8H(7FKP{F zG^W)Qc&5_~^ja`z#i(senYD*CS#$uaPHgsJw?BsiZg@^z(8UNY98pFZek z02cy81r1ODg$!cCL<|u%T+Bi4wYU+GFiO&xDfZB>Oukk=@6IH$Hgoi>Uks=Yso;#g zE4r}g24&Awo~k$A>(dA7ei{Lq!KW39v+agKCo-PI@{}!}{oUr@RpS@> z%?kL#YIRSDfwf@Xc^zDeZvuaw_~*4p&`ESE zoxa}Y^*QviBXQgR+o2S5f3@*w8e8F(vUB3U!)s^Ptky_t#5KYib`8E(u~x7~fAv%N z)l;iBE3y@bmBK#U=bd@o;N!<uS9~@t>!vgw%Za9%}F1x*sWzV(5 z0hoC3wuvNp4Y#CVHm8xy469_}6dp$5wG2Wl&2wpgf6^`MA zzc9iHd~gyQoWccXFu^%Ia2^X}a6k?N6t+eGlypx;@6>coL*KM?O-Ii_I;N*z2D;@K zm-NaLo$^edtmu+8J@QS{#T6r9AVWmR3etiOMOjf_si)hLTarNjY>t z%`rzKqm|Lg=w%EtMj4YpBFqLX2dsx;tDWrvW98JpKq9U`zHcbyaGUc=vvExoVzRuFKRkA#d7xUS45{1Fo9}NfnUboY3d9GtyP19)TnySc>DDWJM5p)G-j!g+h zaLaaZfO!M37^E=QJt&42SQ$y5j{80TNBIEcQiN>Ku5D&Z2?Ge#_zv^DKuq%r;Pe_G z)m8F&z}Nb}Ma5(vP8!hKVTwFcl+bSFyjK5=h&SJeznT7{>;c9*JV#4>w>vhX^(6E zAVZKdbDjj`ja^G&xW63p&AgJF70PgA*4F7>;+;*M-LvBz_I*f>8iSfGhpS z?>}b=9=@gKcx72!5m+vTaVggwsi{F|%oRJgp0WuPmAM+7 zo_1l+7A5C~UF^;9PWXePD8|cl2u3y?1Pt(_u~|kDnQbo>BjqkOx(@9fmF;`|wB^i2uRzGPS?O$#V@ z#zQu9-U`gL>ZEbPfN+8?3tecsbIz^zk-Z3fmbI~yQ$CPGyJ_c)t&FjQD!VkWPjYgxK z;?Tl6A}FX4_Meb6$xA*E6ML00e1m$-mcvV`aFd1Imr)KZ(Q7R_=9QW$z@WVLpT_7c z!*j1yQC2s-0zIXi1UN0qY>`bp>%w_*7tb0Fs@hx9OyADZWZ0ftY;k;1XUxq01|O?1jr{G;bChRZ%N~_I4a@X!I$jM2wKi8X~(gw7LmN*|5cP7 zxsY#t*(>t0qm3cii{FMbFG{<$vD6dvA-Rn+26!2Zm5+an!D~nnkRlH}HP+4>q^Sc< z?*-jP!diRyzL8q|>7599V3){NH`AsuF>1}Rvm3~|2Zjsf>{zw~V-xq5_Rthhsb@Jr zVj@2*+0zgsCocfd&u;_l`Xt-Pl9Y7c3JAk!;i|e_>lU*oxG6qZ$$i;b9xx2a9e&d^ z5L>{!b5f11(^d?Z=r84csi_LJypc&56E|#ND)q&xLAp;P>a+np&|jTP1CT~=Af@6N zn_Aw7j`8h^SReF_45lBL1%Vf5p%f@M19lc+0Com+Izt==0xz96i1(O&qBWEA4Zj4Q zPtbA?{hg z7d-E%X4(ehUjKEQhaq};H9CtQV~N$N|B!g24M8(vsl0^>QHDMxJ}!RLr&};JDT0gW zaIA=f84V51tj`J}aUn3?ME^S%rfC+=`(W&}kT>yIyl5fU z3I06>&~idl7h1Wzf1m=s%a_BWEOA*%mWI+O6oXmKJ6(zFAc9wS868SSa3iQ2330F) z+_{qZEL^;3bPY1rJ~u|ybw0Lam#NzL#``r@^KlQ5h?oNby&wpt;j|v(u@~-i<*19;@Qr} z9PpRoq%6*PzUCb+a@q<28kH=+Ra0zA(z(ojGh+|T{oN_9T3dE(dzhA_=FFgAz%D;Y)ocayJ`>&E@ zYYUnX@d$>KJVrQ+K-e}ssJ+w`*TADMm|?IHkV!yFwdS38S>{O@L4cv~rGlw21J#0y zMxZn+H9r`tqN-8LEC*eKgs^V~bqj@`K9SL`jbdN*qsq}8JPipQZQf3D$NvckET?@a z{Q;~tbRd&HA~kOoQ9)Y&po>cMa{FIXKs8@`N~_AY5}LBAQI;jq@u6-~>p)YTOTCtW zf5mWfPE-})V9%hI#`G6FsXe}dY}dRohPnrYg$mc>Bb3mc?KY-M}!3mE!V z${y)TE4n#j6fHAQ#BFr=cn6yZ5WQQRfHums!rR=X-3xlr?ds;kqK9D&M;;BOyKg!` zhEw9uQ5$LF>(!twpHLku%12KPyO4PQW`Mi9Kir*FpmUCFZ zC%(rZ50{z;76qd>X7 zBfNg18UCznaR4bYKn0rgc+A9^mR1*-f~*csqCo+6fka@uHx}W{B6Euamf)mZG^%ob zgE4)S)Wo%Uv9MXfjnj3zJ$BkrGzag;c{PttbUD<7ySkJ)e3p+X$8&F*AT^Q4l*N@qE8W+ zo~lV`Q}DTnIm1;Ag}Fzdfsmu&fN?5AjBH3m8q$UX4wA>xAmF}iqxEdLw5gh_bJ>7= z7M?uRRi6rXx-N9kvw9<-4PLS+ZQNvPbT4x)a#qm`Zn%v9h>W*5J2INT7Tc54Z?uC^ z2zYn~xIl-}ig2`H-?NRLq9iwUOTB;Z^AlQpY0ku z5%iTXC-%ctjrzL&j)1$slV5FZzT?8|I7k0X{9L~a{SlJ7gx28N2Qi{RVViU?wdm<* zh=Q&9L25{Rq`c*;C1Nf!RT&-fMm?{lKYQ92Vwp2t-3FRAR>_Fbspr^bV8V_~YW%_I zS;42OmR9o=kYi!j`VTwZo5XtG@;UkN3Zayts(W;7q<^G4C&PfaS~~XAAKYhDMTL|W z{J{mY$>;=kXOyvkiP0IMsM^(YqwfBsGLdU7FZpvk^k?MPik%R{OxNI@Y&m(zSnDK1la-|$c&twP| z2&9v_@EYxvK1my!zzuDgY6q7K+^dzcYW;JMX&&RnfRUjEQX)~~{dr6eb0%vD1_!e- z*fMf8m{Wfhb;8mm>f%ADawFh7gd(e^@P(8MY*^J5+X`i0t*t0BNO{?1x1 zos^1fTVbt+RaY%F3tjX0dIwvVgquArs~yr>lLMnT6xNn#$2I#G*=P9A)XmqEMHEjt~O z!E_2DAGKRmzSLj{29MFpm&yUdna(WWj(GI!+IPl|7*2FO+3Y>U3eO5~J-7*q+S_RB!aDsR|q`FM5w zh#A)KR|_9efRUJ$bQBflNt2va0iEPq3$f;~9FJT$;wcMdw8!Jtk^9xp6=oT}{T)1? zEx<|(X5yP79?-PLVW12Og|{=|fF{x?x=w~M++V||>UOaM*?`+jHIB<*;`}=jeAur; zUPH>>w#;gNYF!1y+iyzstPV3l*U>zV*~DEv*+vE8E{~F?0|wfmU?2=1oyd%(@ocD} zkSK%BX3NCD(ExC@Q>yZlRK3iYF=~*L2he|MjBhEO;D^_>7J6ht)#?a+8EIz{3m7V;#{^+f$})NCTt&3U;*C|-_KI`WXax^)8sN4N+(sxDPv=Wxdp4GSE*gb{ zraY-xj#R#lxMoljU;~t1+|v&}r8yQOmff#**RA%&p^id@yxgeat%n{3kUnmt{P7__ zmxpWgWeRf~z~#p|eQ%Bw5Q3#n#`Cda(nk82X6;oJoKO5p5Wie#tYWV|TFtkmfbzOR zA*6F@;@GPZDBC=ATE~t94*nGUn)Zz@6kqk0a)mgYMcC7+_ujd6)vm5q zqgi3pAF~Q0pU$xl|YgBp|bZ0#J6?vOg7J;YlBszaY<%3 zE5LV9I&>X8tSf-=YGOX+_PgCX_o!c!mbGwl@uNnNq{d`bNjKhn3%-^bcz8c`zM|Vf zOi51w+9(77bFe63W+@Cc6?R8Hl#{b2dvQhdl5Z7trlJ5(zD6O2N$@f}6=Y^VTlvm2DKJ4-@=j+* zAqdSzlM3jDom3V(q!DZ|TY+a(^oc=}=(KH{CY76%J`Q|kI&a`aXDydHTM+-l;nCoJ zqhxY*ksr~av?xvi4}ut9p^fq|vtYFL^L-F4KL2etz2GBtj>DsSz9y;fO22JF{vM@M zU}x*oACKYz%!PIWeh5YU--I_?VX`*#V57=Oc#`V-c=D~nHKx2t#NNFW+)>4kPTCn} zrIga(N;Do=&?FaeB4Z?GvBYcDpgOY3_l1#jGfI$otbkW03K=`F*1>I}(OVW5<)h50 zxK44(Ld;^Fg@pySjFM_rWRbAYk zuls}-JTcI`C9yuVJo#Yfx^15B1MccDhS4uBU%HBBv}$3r0yeU*{)iBiUg223g35Cp zk0jviRtqUX5zFUBb0uu?w>ncwcGKYtwmoehIchJne$u%%(n+jgH-%$2S?OQkH4+u& zY|Jnn86E=|G9Qc`6^|sg8Dx~s4jVHzJ&WqHJRFN|(K?_^+K}~5rv-UUe=q2es+Py7 z${|<6RMFWw3HqZ5He>W`i>z4Qw4oVvcn3NBaVw+$ur=8Bq~j0JR31uT2DTaQxFYpv zU~%C~XipH#aqB3>ctyk6pzq~B*t;bscC^3hbvA~$tY;oQ@V&3>YglNn;npHf0xxq& zYl=LA-wgGz_0V)CA^|V+yPEW>F>HO*?F|@tqd70l_|n!E=`H|2yek37`^2TIM_Ttq z8R@9B_S64uQ81oAz4f{N>C6VA5Yap&HwqK&SOeTG_5c)ANq_|NSofikj^@8_nE z*q7wRnSmOGq9(wg*Z396cpxS-Sff&MI-}$&1qA(@-XfUT-zE+FNqym^UUlf6mv5-6 zJ%6=9wQ}~#!tDP78e9kmk#gf8qsgz7Z*qlvcl0x1vnNlp>HBk7tr*K{>K9KnX!Xyq zp)szvNpT+_IHgj5HCu(#GbbXBeMEQZmd^7}X!j6^%iCpHL5Pwq`8%a}s&9(`*;LHO zzA$_9a>?a4%AIZuRGeY7w4CF_Bf=f?F>Fk@LA|C{qZmLp*s&XfuVAARD4P<~hDu(X z&Ts5XnZ9HZZg`ck3i{Bu5^HX|Fp_>bw*I}>yfe{PlU*)#-Rn5>^-=~EI#P!o|0JIS zJm3O9pUJnyfo}kPBVridlEz46*rA#cgV+YZ^>597r&mHpK)a*EOPFHJJGqZ1g?W#3 z?r>LUdMx$LD%ZFu`S{S_@Svo|ogYT%e$iNR8OgDM*yd8K#V!?G3+}>a=FDH=&CVi^ zJ{uF=y(U@NoAQ~7_zAmu5%kGOnexX3s=*&vn;0JtmzMyr|EJ214)GybN~t(W$a;7G z8UBtPp;iHZd>I15il;-zBsGOj_SV4QSa8}kW()Y)JyHhBtCY4O`3Pb5#XS69$YfWf zo}3M^g@3-*8{8A)kn$0H zlZ84Ulj8pmZp%1cNp}=uBKa1O^5WB_EJP&FR*EhGoTogmCg5A1kc`Hq$C|u~6KhMK zl!Pd@9CaC|a^r_}b~DA@*L>^Fd;GpJ40M%u!MATF@4T>`>B>b7{!bb_nR?1A3nO1s z>({8-sBuVQl?$}Rhvh_vi|Ra!f}VcvF@HpKu5Vz8=bVs6iE0~ija*T?#$fKnNhL#Q zhmhP*gDdjaG;vHCuA{0NcYF8Km4Pc$kZ9x8Ve&%!hzEIx)s{cH#}??R)z|TGd%A)g zI#yh2B#OwRExrY2t9OAMZDLIsh(%7A4lVLrC(g_5sWOnY&LG-4)NzUza-U{Qbf^}H zI4!nX%4aqb0<~=zX^Oy1pd+>krL-=mrXR)S^dN0=Y7l;KxvQ^xP_~PuglsP)7~!p4 zI@+q@v_QGSmP%>SI%b(`rG-xCCpl{Q8U*A#8-hO4TLlrxnpqa z(7PVd@$k<_D#JcMF!n6EYG8j(*RwBV6KZ!cP(GR5hi3d|wzVU^My^2lA+(VfoQIz8 zP+29~KkB7BsS~Lc%|-R=uAw*1qH7%n=c8pAa{C_zHsSqt+JrIU-m6Cf(nEP{8>Exx z;%({j?;$t-Q}Gv;YN@Q}LTzh- zS{FttMUfW?0Zt^#rKo`{lOy!<0GbD#-EZQLziB&gAn=2Dx$(iyvA<)=DDEsHSqgnk zsAJN4Ue+2{nyP)E?p$8@3h6-8$hxq@xa+mt1%GW2&6#^DA@%q~LfX|?^zOmeE|v)1 z^FFYZ{n30g`@@|b%BmtSWS4S9$Mze7tc9e}mOXVz$|Ne)a>E!!@)xZ*w1*?=-3CSq9cihq~EcU_43<}q^FTy2N%rgv#!HDZcISMU& zS?WIe^-KeeM7EIKab$*c_x?=^n^c!(4@^!VCgu(mzp!C!SZ&eufq-vNK^K}BaQpHk zS#VMNV8XgSM|M4ZdlB+bUhYag6Adavyrv9(!I6x#JgA;FTOdM}~ zuyf#4*c*U89e77vjCSE@%T@efqp4{p8slO7Y8)@_N+C3L0}I%X74{`CLyHq z>ad`ZAOGxk#patRH9^HQw|h#0askWbl@8O_(ucWT%eE2*6(`XXT4Z}2>(MEV9WFgh zcX%RVVFaP%99E-OFic%b8|HiMThA<7#%v^Xfa$Ai$}%X5z}NX&`B;b$l2p1s4lsG4 z)@Mnsi<-wGX`4d6Efl+bD<$lwZFVlsj_0Xw&etw@77RQuYgxy-*-Kd7A=*d!#kD(+ zGcdo_!+7&RE@xK>z;z$Qw|}#g9pLt^oc3(lXb$YRaRuXTB|lw`@FAg81Xyl6aA+V8 z5LJ`=OX2g$0oihZrBrw*oSX01T=c7GT$=b>#Y|4yyY%J%e}CZU$oA3g)W_Qo0jHmw zd@K3;(AdGFxBeg2{SmWy?cqE$zdZ9ZP4mYWVPz6cPg%gFY`=T%!!79Mvs2sYuONa& zCp%dtH>m{28s^yAG46f22Z?^a=OUjiUF7b`HukK0@Rhn*$~KeyCJs~Df8sYeUORx8 z{){Jwhq!-N-Z`<#Q7^7ZUICx-hyb$dNFHAG8xcn_R>Vhy35Q>Ieyfp+&jrVl3*Y|Z zK*N_fMo(%G#9GzUs6@f=N_|?HtjZ@~+e@jO<_g_gbpP6!3;jBwZoYJ9{&JfjD=!O! z#XyrABsU&NlZ)dHR=MTO=z2qCxp1u!LYH<4wXLX0K8AtxuL$D;R1FcQ#HI>F!mqjb zTKSmSChX#uX|oBzB~{mY*4^F$!QFwq$Gm;D%4|*`Q+RVGUTW|n2nyVhtTu4QQz>MXGZ z-eotvm42^s2eZeEjSb}@AD~EM8x^BrU zNYrKW6xi51?a)dDghgl8d>f!K%JLcJ zH_2J!y97DaMYLhE1^!Nm6w0S^MRSu)d*2xZRrWK5TUmK>Iq;|E=swMA4I!1L$&y+U zg63*qBYxBtN$ZYquK{YAhZxC0BLRf=_8T|SH z(nI&FnlE~Ky1vmwl-9QpOnO$!UvZ>ReVbi_=pFK4XQ)p-L$Qf$D@4tpeG@8@Syx8` zZ*6M2%F60MAc$#EzVYs+ma74qRHs16=5iX@+glh*dA1uCu4%--D6vVpZpSqc=( zZqgFO<)qu^B+%?H9$Qduu*hhy6*^C} z&ZqPN)%|vS^dy9~s5!35b0OS#zJg`YyUT3zocLwBY<#5g0bmj{3)b) zvR3e6%Z3z8Rsb=Hmp5h7&06v@hd?)4SR?=e9J}H=a)$`~7 z0SDDw0>G53-s1lE?%Y;pAfZRW=^JF@40OK?Xxw}kYbFy|Sdm}KT(|2T< z#C$o%#XmpYxn%@J)G!P;H~a7cB#5ZRN9EhsmK)Y$@txPIj|9#VMcz>mwce|Up$?2@so4V zxs}u5l~Ymm?_fgnJ3(oRTP+Do&dg2uhE-~sJD-z6s^(Vai159(h7r7mY%KkscU`<& zy}R*TC01Mh4%DBNWynb$;}7_|w7Z*cR*s|rJ`L58v%zlq^nv8_`7mvcgitdtqc{!4 zQ1SzF9<7TtM*<4 z68&3~cvqgyloB0Cd07(S>SKGv?s)O774z{Zow_4aYgtn4W zV$CjoU!2EEzV_!PfCiEqAm2iRD3}uQX6};!S#st4;P#sMKHd&~=jz=|g-R$;NVr=d zr0lg%Z$>tgN%}S9S~X>N;=#d;DC|9|Zr5cswTnxhl0sFz52NCf+~+ZB(!&^Ia3({; z%~q-FbyPL^VU-ga-242y8oJzy=o40{cyr4iO*&jopjs@1JE(P)4Ggh@rXi|`?;)Ja z?giwF&a32M1Z~e-Za%H6&-;PNFhQvX!b2dj2~lB{;N|Dv}9Ja`B_424*~k1-rd(b+>4=? z<`njSPKnciFlF9cv#W}Dul;x~_TcNsp34x0uawF`A5f4YhyjuAqtKNLmspsbBoy*{ z$#WoD{-VE+NcP;bDa5ORAHg(Yws?SOvyum;5^}%IGC&Zglt2)c#EF%Gj=a@X)t?8n}&Ap09KABCkJD z5AqPST!DbaWf24*4N*5`R+D;EPODaBA~kUda3Tb`k4&Jj+37&PvC<=|qA@7?^)$2+cVQ9q{FDhF<9`q!&)S>)kbmm?j|R znEFjc70xxe9f^<2#UJ#$o_u`bz2EWD50^ge_{6s}AC}CF2GqYs^Q}5I!MRq?bWWb- z4D#nH_nG2qS=()TAk{r>q|sYZ87rRbG8=z!XU<3PH$9Rpr&JPE>bFEuk_Vfa#4hc{)l9R49&DyA-qzE9CGBmT9M2=7Ul> z?N#PbuZ=Y25k0(IxWxn>BlS<`IsvS&#<|jtH&QuxxYX1XmE9C}b)?Ul*;kai6L?dP z2Mtb(p7~(KE?ak=?4NkjzfaZ*}Fw)PC#K@%fQ0={Lm*Q#Ch&B>2%wronP8)h>*yrXV#OMiqV6a~6oK!aqBDTwT z*oa9pfRWoK*=9d#lviYB>f@OQ_8l1g_9*twkxv5@?auuJDHHJ5Rq1+`qE#nxz1Z*L zJ0#=KQ_7aw8ps0{S@4~?3XWjU)61O;T&22R=LE31fwjr_?v~D|B4PkgQ6AOMC!5cC zI7zG|q>4pxWr(J-`p_Y@3*PRXo_zk@zQ&_IKCIg7Kgq+xzIycNEryPMo=O<2vxEsd zn(WwZ+mUW-=Av=|c z5+YZa5_`r1eL+qM1IderhtcoHhl)&+y2UvfC zdW8T9(+k%h5(_W{8{N%LJU$k``7AdJ9t{5Ia3nW<=L<~(|HdZEypHw-wxJXg*e0M> zNRBMm8*E+yhIL8^ECvaeICnHEU{`MvGq8F$VEO&wJAzn1%(E037@KGW)eexC^2~by z<15z1QNdu;HDWsechy%174OEoGw4I$qU-TD#Roa7c?eMWDscqk0O1F5*ES}M8b01J z{5Y}_NF=ynM_?WT2{?A;2M*S}9An4wv#>?L6ssy}8?C@m)l(=TbEHP0j3m+)Q zWt5|?jC0!F;!6-!X>0%DGeh@I>spULpmsexCbj!3H~n)d5 zx-SkWFmxHV&+hjIS(g$kCkRb<|H+@$KTn6?Lt?5r2Y3>l16oKaj}aKE>1M*fxTr6? z7>cA%5y3;y*XbbaMS-6#p*=B(J%3rR|F`! zm_Y+NvsW0_DbQNmVR#0wUBxwK?}ol+;;rOL}0n$(a3A>{kAA(k{b( zo?cDVl*vdS0*aJD)fHEYi(jhsgO+uGDAn4Q z#8{R|rTih76ktSN-+^2TGO<)eQ-DN38vy|+zh-9o%L<9(dXQrs z{_-E#;s@QY@)Fif3LAupMfN(NXdbi*9i-&QxLGIBPzw{77Vk#PvigAps> zej2UXCsTyb{6oHi`C6{^%oM~B%@fL->ul9rL8X-pn}fYM{0nhuvge`uiM;WJ%H$t! zS35VQU<0Q&WjiA&PmQ)7j`mdG6X&vO4V#B|FWED@Z0SOKL&u_X`JUNF54U8+4mj6Z zr}X?=a~rXZopoKCvCUtnNTZ)`9GmrhY_n(ct*ONgXm>5E8KY8RnprGNNTrSjix~n% zT@&Ip%`H$?vg^iT6gu46P~ULh>f1#r-2umRZT(@0l{JiQG!;@YMw=X>R^&9ji_R?& z&ahy!S5B)9Rk~nVM^!rRv{?JNR7i`=O>V@RbD5v?5Tabv7yGfhYCAB+SRkY$GzRP$ zx_7>5g;k0YC2f9Dtvc@8?AZ!-AE!@+sqiI@(Y#={aan`doEN|pIo>0WgCI#}8cMzOK*(nmx z`e(Brw=?x(*G+%bMOLC*ARejSc~9cWuM z(;lLGoBLno_QYyV{`;d4`mrN~X>&uiAgz|-*#Kw}wrH6JsgigWs{*Vf+GL5$OcfRp z5$L9|VXp`rBs-FvdX;M8=`OWzTdOu{8+}Np1F5lXPxbOB{j9mLEvBi zlR<@!)k(KETEJm+1^m%cv*Gy#QHJ>B+A3n_CT=*9ouA1(g!@ZB;h)f0G=|ylulVhJ zS~NFINr<4mD8Xm4&`=p8;e7W5Z9_f=4&Mx1KQjrOd?(&|e|Ag}3z@e3^90*@0 zjkwlMMjawvujSHFUYXq6_9yfcDIKuC&-g8Ev$lF++uY!xZ~bI%C6Y%k-}LR%A=~K- zs#Pt-nM=bK{L3>78t^~28z=C>(yZ{jc&=a(rM5f*)3i-P z>Q=dI=x>0V(-MlBVV|aCdAtiCL~f|a{-W@?Yw%xNoSE#K$DfWoQ}<{~OV*P{RBg?g zwHU1ySu-mRQYc-et+ZEq1}?-5=+@RW{#%H{C9~_jjEIB!;USgD6j$lv$b$wW5|nsc zx$%(losL+@s4w7rmam;DlLhUY9es%TyNv0Meja}YEc_gt=h@f%+mi1#XqyN=~?kJx{!YU94Aq!$SZue4GlGSJ-C*nxCflN zT9i|(;>W8!YG#*GL60^m*HrUqjsnbFUPFa)-TuOAggQrFicUtHBR{K^A~=pwN5b+w z{-AtuJo`K|KyJ)ZD009fPv=n9YE2bSa8G)7O!Ln1+nLU6)IcVw>v+n^Zg`pGYtVkB zDn#vvOssN(4mU+Xh70PN7TMh$yuGfF=x|@xLAIm&if!$p$NeoveBzulHlff-qd1ib z*&`NVI*r;`O}9ihq=QS=L2Ea;KS(euV^DKtdA8d7d2;1pb~ zbwsk4rG%DPibrI2roQ;8;qzz1eg@GLCI(a zakxQ=#Lhkw$fYtuX0K_9=N%L`!(|Bj>b#4?Be*LYyUEfI&z|g!5-p z(^K0)H7m#g37-(L8skI-fJL3-#*}qCKMRyldz<{cquucXT1VO${s}!`*z^+EEDW#u zIEjarYZGLD6Ma&vLm-HLwDL|==;I`pR0;0IxQTw%A^x!iSbEiV5A%*t2K&bbY|Xa! zG>oaJcQ4JU=m+1T7Rj5dJFxbWI#CNkCW70Duf3D}c;Ljq9mJibMbjSxzmIP}diMQI z#Eqx3+v(ef2aJDT3=!+YSVPD_o1=|gvD|PjS2zUa=G-rSjL_a}jBVCWJITM5vzqiK z!eP)5wPgy}xZ(mD9eh4(u`GlIVXXI8@G-SHs{>&QSXK7m$}!oZ{7hQKh;LJY#j}5B z!5iXQ#EZNG(R;f$c_v(U6M9VQu6!<|z{}JFRH(eX+^Rg!AB7BEw8yXu=Yn%qcby1S z^dCvO>W#vTyzJ5)3+yXy+(s_$RGE9klEI2&9(To2f_NaaIVKhla<``h1llFBPq_Q&hk3YeCqY|!z@-&e!9#mBA{uYG5gF{ z`Vh59uM!2&$o2Pp+*tR<+`$Bt4A==4p^zZ)xEzRvot8{9`K7q?*Wz8-`*Ij1rNw}k z>dhL20G<%dG7RU zeL%Yb>BUm*p4mAuIGIUUq)=2BgV~3XCoJ6&2{2E(hp4|)^-L?0ZGeA3=F>9g_BX)& z)VS!jCD}eh3MY3_mGpAN!2N}_E^d#xwLH@Y3z;iP<9!)?_Ihw-Fk*0fqE%%yPJrdf zt-v#FID38snYy>!-U8gPOn@~sv|Lg)bTt}55S;%A(a+oLxvwzCm+P#C#H(4oMXD&uS6#H(UgYARc<8Hp!!*5hg zey|44Y5{Y43*>gxeSLx}5tNg>jgp3e%+iDFA}lHg@R_^BwFH}#nmb9U1(}>w{nh0W zb8wr}rY4+S8rLZkEC!d35#=EEoVCgB(f!P3>expdu~WBT|1^fzgA1z(SvXVzX*G0f zDKshJI)OTqqb4UW0&}e75OvD1JY?~O?#6YFp@zZZ4QiUGM9-VW% zOy<05bUXphGilnMsA802VlO&qZr2Lu2_~Pn7NiDPS@(K4R=>)HBe{LLsDmXtaIJ8X z60G8?3$oV2JtvE#U%FE#-Q7)tZ}Hiksba=i#yFgHu`5VOkR3b74=)m1RmyVb;dtfs zI)Pa{^Y<$ARkC1-l8X8rWS+;VLB7Ylqc~zaUs$_&3@pbR+#Sl70}dD0adC^FpjMh% z)h8)BavL≺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 Tfl5Gf1Y06(tOAA3X=@1pEwc%@ diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/ea9b8ac3-ff16-4387-a473-32a6a617329f.woff b/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427936/ea9b8ac3-ff16-4387-a473-32a6a617329f.woff deleted file mode 100755 index 8695bba38d931b13a72b3f198b836df5993d00d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35568 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 diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/1c070cdb-18d8-440e-be9d-2448fa3930c4.eot b/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/1c070cdb-18d8-440e-be9d-2448fa3930c4.eot deleted file mode 100755 index 3c246ee6fb7ec87d7e8b508eeb9b755d817beae9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29671 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 diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/66c06801-da3e-4587-a89c-674cfbe39c21.woff2 b/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/66c06801-da3e-4587-a89c-674cfbe39c21.woff2 deleted file mode 100755 index 0c0e23f86f62449c78d0f5c30773a284890a84cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28776 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 diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/c21bf502-6b58-4bf0-9ddd-169929c263e7.ttf b/packages/react-app-scaffolder/app/templates/base/src/assets/fonts/1427944/c21bf502-6b58-4bf0-9ddd-169929c263e7.ttf deleted file mode 100755 index 406dc21fd04b41da79bc409d95ad2bcc7a021729..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63700 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 diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/.eslintrc.js b/packages/react-app-scaffolder/app/templates/hooks-external/.eslintrc.js new file mode 100644 index 0000000000..bc51f80efb --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/.eslintrc.js @@ -0,0 +1,76 @@ +module.exports = { + env: { + browser: true, + es6: true, + node: true, + amd: true, + jest: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'prettier', + 'prettier/@typescript-eslint', + 'prettier/react', + 'prettier/standard', + ], + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly', + }, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 2018, + sourceType: 'module', + }, + plugins: ['react', '@typescript-eslint', 'prettier', 'react-hooks'], + ignorePatterns: [ + '__mocks__/', + 'node_modules/', + 'setup-tests.ts', + 'jest.config.js', + '.prettierrc.js', + 'react-app-scaffolder/', + 'marketplace-api-schema.ts', + 'platform-schema.ts', + ], + rules: { + quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }], + semi: ['error', 'never'], + 'no-unused-vars': ['error', { vars: 'all', args: 'after-used' }], + '@typescript-eslint/no-unused-vars': [2, { args: 'none' }], + 'prettier/prettier': ['error', { + 'endOfLine': 'auto' + }], + 'max-len': ['error', { code: 120, ignoreUrls: true }], + 'no-confusing-arrow': ['error', { allowParens: false }], + 'no-mixed-operators': [ + 'error', + { + groups: [ + ['&', '|', '^', '~', '<<', '>>', '>>>'], + ['==', '!=', '===', '!==', '>', '>=', '<', '<='], + ['&&', '||'], + ['in', 'instanceof'], + ], + }, + ], + 'no-tabs': ['error', { allowIndentationTabs: true }], + 'no-unexpected-multiline': 'error', + // Disabling as conflicts with Prettier + indent: 0, + // Disabling as we are validating types with TypeScript not PropTypes + 'react/prop-types': 0, + "react-hooks/rules-of-hooks": 0, + "react-hooks/exhaustive-deps": 0, + }, + settings: { + react: { + version: 'detect', + }, + }, +} diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/.gitignore b/packages/react-app-scaffolder/app/templates/hooks-external/.gitignore new file mode 100644 index 0000000000..aeb663f439 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/.gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/src/tests/coverage + +# misc +.DS_Store +reapit-config.json +config.json + +# log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +*.log + +.cache/ +yarn.lock + +public/dist +src/tests + +.jest-cache \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/templates/base-is-not-foundation/.prettierrc.js b/packages/react-app-scaffolder/app/templates/hooks-external/.prettierrc.js similarity index 100% rename from packages/react-app-scaffolder/app/templates/base-is-not-foundation/.prettierrc.js rename to packages/react-app-scaffolder/app/templates/hooks-external/.prettierrc.js diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/config.example.json b/packages/react-app-scaffolder/app/templates/hooks-external/config.example.json new file mode 100644 index 0000000000..98a80ad258 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/config.example.json @@ -0,0 +1,7 @@ +{ + "appEnv": "local", + "cognitoClientId": "", + "cognitoOAuthUrl": "https://dev.connect.reapit.cloud", + "cognitoUserPoolId": "eu-west-2_hbt0B7yys", + "platformApiUrl": "https://dev.platform.reapit.cloud" +} diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/jest.config.js b/packages/react-app-scaffolder/app/templates/hooks-external/jest.config.js new file mode 100644 index 0000000000..92f778077a --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/jest.config.js @@ -0,0 +1,42 @@ +const path = require('path') +const { defaults } = require('jest-config') +const { pathsToModuleNameMapper } = require('ts-jest/utils') +const { compilerOptions } = require('./tsconfig') + +module.exports = { + preset: 'ts-jest', + testPathIgnorePatterns: ['/src/tests/'], + setupFiles: ['/src/scripts/jest/jest-setup.js'], + collectCoverageFrom: ['/src/**/*.ts', '/src/**/*.tsx'], + coverageDirectory: './src/tests/coverage', + coveragePathIgnorePatterns: [ + '[/\\\\](node_modules|src/types|src/tests|src/scripts)[/\\\\]', + 'index.tsx', + '.d.ts', + ], + modulePathIgnorePatterns: ['[/\\\\](node_modules)[/\\\\]'], + moduleNameMapper: { + '^.+.(?=.*scss|sass|css|png|jpg|pdf).*': '/src/scripts/jest/css-stub.js', + ...pathsToModuleNameMapper(compilerOptions.paths, { + prefix: '/', + }), + }, + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'], + snapshotSerializers: ['enzyme-to-json/serializer'], + verbose: false, + projects: ['/jest.config.js'], + transform: { + '^.+\\.svg$': '/src/scripts/jest/svg-transform.js', + }, + globalSetup: '/src/scripts/jest/jest-global.js', + coverageThreshold: { + global: { + branches: 65, + functions: 55, + lines: 85, + statements: 85, + }, + }, + coverageReporters: ['json-summary', 'text', 'lcov'], + cacheDirectory: path.join(__dirname, '.jest-cache'), +} diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/package.json b/packages/react-app-scaffolder/app/templates/hooks-external/package.json new file mode 100644 index 0000000000..9ea8dccb76 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/package.json @@ -0,0 +1,80 @@ +{ + "version": "0.0.1", + "main": "./src/index.ts", + "license": "MIT", + "private": true, + "scripts": { + "build:prod": "webpack --color --mode production --config './src/scripts/webpack-prod.js'", + "start:dev": "webpack-dev-server --hot --progress --color --mode development --config ./src/scripts/webpack-dev.js", + "lint": "concurrently \"tsc --noEmit\" \"eslint --cache --ext=ts,tsx src\"", + "lint:fix": "eslint --cache --ext=ts,tsx src --fix", + "start:prod": "serve public/dist -s -l 8080", + "test:ci": "cross-env TZ=UTC jest --ci --colors --coverage --silent --forceExit --detectOpenHandles --runInBand", + "test:dev": "cross-env TZ=UTC jest --watch --verbose" + }, + "dependencies": { + "@reapit/cognito-auth": "2.1.7", + "@reapit/elements": "0.5.61", + "@reapit/foundations-ts-definitions": "2020-02-13", + "dayjs": "^1.8.19", + "react": "~16.12.0", + "react-dom": "~16.12.0", + "react-router": "~5.1.2", + "react-router-dom": "~5.1.2" + }, + "devDependencies": { + "@babel/core": "~7.7.2", + "@babel/polyfill": "~7.7.0", + "@babel/preset-env": "~7.7.1", + "@testing-library/react": "~10.0.1", + "@testing-library/react-hooks": "~3.3.0", + "@types/enzyme": "~3.10.3", + "@types/enzyme-adapter-react-16": "~1.0.5", + "@types/jest": "~24.0.23", + "@types/node": "10.17.13", + "@types/react": "~16.9.0", + "@types/react-dom": "~16.9.0", + "@types/react-router": "~5.1.3", + "@types/react-router-dom": "~5.1.3", + "@typescript-eslint/eslint-plugin": "~2.23.0", + "@typescript-eslint/parser": "~2.23.0", + "autoprefixer": "~9.8.0", + "babel-loader": "~8.1.0", + "concurrently": "~5.2.0", + "cross-env": "~7.0.2", + "css-loader": "~3.6.0", + "enzyme": "~3.10.0", + "enzyme-adapter-react-16": "~1.15.1", + "enzyme-to-json": "~3.4.3", + "eslint": "~6.7.2", + "eslint-config-prettier": "~6.7.0", + "eslint-plugin-prettier": "~3.1.1", + "eslint-plugin-react": "~7.17.0", + "eslint-plugin-react-hooks": "~2.3.0", + "favicons-webpack-plugin": "~2.1.0", + "file-loader": "~3.0.1", + "fork-ts-checker-notifier-webpack-plugin": "~1.0.0", + "fork-ts-checker-webpack-plugin": "~1.3.4", + "hard-source-webpack-plugin": "~0.13.1", + "html-webpack-plugin": "~3.2.0", + "jest": "~25.1.0", + "jest-config": "~25.1.0", + "jest-fetch-mock": "~2.1.2", + "mini-css-extract-plugin": "~0.9.0", + "mockdate": "~3.0.2", + "postcss-flexbugs-fixes": "~4.2.1", + "postcss-loader": "~3.0.0", + "prettier": "~1.19.1", + "serve": "~11.3.2", + "style-loader": "~1.1.3", + "thread-loader": "~2.1.3", + "ts-jest": "~25.2.0", + "ts-loader": "~6.0.1", + "ts-paths-to-webpack-alias": "~0.3.1", + "typescript": "3.7.2", + "typescript-eslint": "~0.0.1-alpha.0", + "webpack": "~4.41.5", + "webpack-cli": "~3.3.2", + "webpack-dev-server": "~3.4.1" + } +} diff --git a/packages/react-app-scaffolder/app/templates/base-is-not-foundation/postcss.config.js b/packages/react-app-scaffolder/app/templates/hooks-external/postcss.config.js similarity index 100% rename from packages/react-app-scaffolder/app/templates/base-is-not-foundation/postcss.config.js rename to packages/react-app-scaffolder/app/templates/hooks-external/postcss.config.js diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/public/index.html b/packages/react-app-scaffolder/app/templates/hooks-external/public/index.html new file mode 100644 index 0000000000..72cb6e98ef --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/public/index.html @@ -0,0 +1,13 @@ + + + + + + + Reapit Foundations + + + +

+ + diff --git a/packages/react-app-scaffolder/app/templates/base/public/logo.png b/packages/react-app-scaffolder/app/templates/hooks-external/public/logo.png similarity index 100% rename from packages/react-app-scaffolder/app/templates/base/public/logo.png rename to packages/react-app-scaffolder/app/templates/hooks-external/public/logo.png diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/images/reapit-connect.png b/packages/react-app-scaffolder/app/templates/hooks-external/src/assets/images/reapit-connect.png similarity index 100% rename from packages/react-app-scaffolder/app/templates/base/src/assets/images/reapit-connect.png rename to packages/react-app-scaffolder/app/templates/hooks-external/src/assets/images/reapit-connect.png diff --git a/packages/react-app-scaffolder/app/templates/base/src/assets/images/reapit-graphic.jpg b/packages/react-app-scaffolder/app/templates/hooks-external/src/assets/images/reapit-graphic.jpg similarity index 100% rename from packages/react-app-scaffolder/app/templates/base/src/assets/images/reapit-graphic.jpg rename to packages/react-app-scaffolder/app/templates/hooks-external/src/assets/images/reapit-graphic.jpg diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/__tests__/__snapshots__/error-boundary.tsx.snap b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/__tests__/__snapshots__/error-boundary.tsx.snap new file mode 100644 index 0000000000..c971b7b33b --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/__tests__/__snapshots__/error-boundary.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ErrorBoundary should match a snapshot when has an error 1`] = ` +

+ Something went wrong here, try refreshing your page. +

+`; + +exports[`ErrorBoundary should match a snapshot when no error 1`] = ``; diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/components/hocs/__tests__/error-boundary.tsx b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/__tests__/error-boundary.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/components/hocs/__tests__/error-boundary.tsx rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/__tests__/error-boundary.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/components/hocs/error-boundary.tsx b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/error-boundary.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/components/hocs/error-boundary.tsx rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/hocs/error-boundary.tsx diff --git a/packages/react-app-scaffolder/app/templates/base-is-linaria/src/components/pages/__styles__/styles.ts b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__styles__/styles.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/base-is-linaria/src/components/pages/__styles__/styles.ts rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__styles__/styles.ts diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap new file mode 100644 index 0000000000..6bd6fcc0cc --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Authenticated should match a snapshot 1`] = ``; diff --git a/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap new file mode 100644 index 0000000000..0486a88694 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap @@ -0,0 +1,199 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Login should match a snapshot 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+ , + "container":
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`Login should match a snapshot 2`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+
+ Reapit Connect Graphic +
+
+ +
+
+
+ Reapit Graphic +
+
+
+ , + "container":
+
+
+
+ Reapit Connect Graphic +
+
+ +
+
+
+ Reapit Graphic +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/__tests__/authenticated.tsx b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/authenticated.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/__tests__/authenticated.tsx rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/authenticated.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/__tests__/login.tsx b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/login.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/__tests__/login.tsx rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/__tests__/login.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/authenticated.tsx b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/authenticated.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/authenticated.tsx rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/authenticated.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/login.tsx b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/login.tsx similarity index 90% rename from packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/login.tsx rename to packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/login.tsx index 3b40d25bd4..89ecda0ac3 100644 --- a/packages/react-app-scaffolder/app/templates/no-redux/src/components/pages/login.tsx +++ b/packages/react-app-scaffolder/app/templates/hooks-external/src/components/pages/login.tsx @@ -4,11 +4,9 @@ import { Redirect } from 'react-router-dom' import Routes from '@/constants/routes' import { Button, Level } from '@reapit/elements' -<% if(sass){ %> -import loginStyles from '@/styles/pages/login.scss?mod' -<% } else { %> + import * as loginStyles from './__styles__/styles' - <% } %> + import logoImage from '@/assets/images/reapit-graphic.jpg' import connectImage from '@/assets/images/reapit-connect.png' @@ -37,8 +35,6 @@ export const Login: React.FunctionComponent = () => { Reapit Connect Graphic -

Welcome to app-name

-
+ +
+ +
+ Reapit Graphic +
+
+ ) +} + +export default Login diff --git a/packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/__tests__/menu.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/__tests__/menu.tsx new file mode 100644 index 0000000000..636d02aa37 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/__tests__/menu.tsx @@ -0,0 +1,39 @@ +import * as React from 'react' +import { shallow } from 'enzyme' +import { getMockRouterProps } from '@/core/__mocks__/mock-router' +import { AuthContext } from '@/context' +import { mockContext } from '@/context/__mocks__/mock-context' +import { Menu, MenuProps, generateMenuConfig, callbackAppClick } from '../menu' + +describe('Menu', () => { + it('should match a snapshot', () => { + const props = { + ...getMockRouterProps({ params: {}, search: '' }), + } + const wrapper = shallow( + + + , + ) + expect(wrapper).toMatchSnapshot() + }) + + describe('generateMenuConfig', () => { + it('should return config', () => { + const props = { + ...getMockRouterProps({ params: {}, search: '' }), + } as MenuProps + const logoutCallback = jest.fn() + const result = generateMenuConfig(logoutCallback, props.location, 'WEB') + expect(result).toBeDefined() + }) + }) + + describe('callbackAppClick', () => { + it('should run correcly', () => { + window.location.href = 'dev' + const fn = callbackAppClick() + expect(fn).toEqual('https://dev.marketplace.reapit.cloud/client/installed') + }) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/ui/menu.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/menu.tsx similarity index 61% rename from packages/react-app-scaffolder/app/templates/apollo/src/components/ui/menu.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/menu.tsx index 0fa7f9f895..82f7a5c15a 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/ui/menu.tsx +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/components/ui/menu.tsx @@ -1,9 +1,10 @@ import * as React from 'react' import { withRouter, RouteComponentProps } from 'react-router' import { Menu as Sidebar, MenuConfig, ReapitLogo } from '@reapit/elements' -import { LoginMode } from '@reapit/cognito-auth' import { Location } from 'history' import { FaSignOutAlt, FaCloud } from 'react-icons/fa' +import { LoginMode } from '@reapit/cognito-auth' +import { AuthContext } from '@/context' export const generateMenuConfig = ( logoutCallback: () => void, @@ -24,10 +25,7 @@ export const generateMenuConfig = ( title: 'Apps', key: 'APPS', icon: , - callback: () => - (window.location.href = window.location.href.includes('dev') || window.location.href.includes('localhost') - ? 'https://dev.marketplace.reapit.cloud/client/installed' - : 'https://marketplace.reapit.cloud/client/installed'), + callback: callbackAppClick, type: 'PRIMARY', }, { @@ -41,19 +39,20 @@ export const generateMenuConfig = ( } } -export type DispatchProps = { - logout: () => void -} +export const callbackAppClick = () => + (window.location.href = + window.location.href.includes('dev') || window.location.href.includes('localhost') + ? 'https://dev.marketplace.reapit.cloud/client/installed' + : 'https://marketplace.reapit.cloud/client/installed') -export type StateProps = { - mode: LoginMode -} +export type MenuProps = RouteComponentProps + +export const Menu: React.FunctionComponent = ({ location }) => { + const { logout, loginSession } = React.useContext(AuthContext) + const mode = loginSession?.mode || 'WEB' -export type MenuProps = DispatchProps & StateProps & RouteComponentProps & {} + const menuConfigs = generateMenuConfig(logout, location, mode) -export const Menu: React.FC = ({ logout, location, mode }: MenuProps) => { - const logoutCallback = () => logout() - const menuConfigs = generateMenuConfig(logoutCallback, location, mode) return } diff --git a/packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/api.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/api.ts new file mode 100644 index 0000000000..c737c935cb --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/api.ts @@ -0,0 +1,12 @@ +import { StringMap } from '@/types/core' +import { COOKIE_SESSION_KEY as COGNITIO_COOKIE_SESSION_KEY } from '@reapit/cognito-auth' + +export const CONTACTS_HEADERS = { + 'Content-Type': 'application/json', +} as StringMap + +export const API_VERSION = '2020-01-31' + +export const COOKIE_SESSION_KEY = COGNITIO_COOKIE_SESSION_KEY + +export const URLS = {} diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/constants/auth.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/auth.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/constants/auth.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/auth.ts diff --git a/packages/react-app-scaffolder/app/templates/base/src/constants/error-messages.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/error-messages.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/base/src/constants/error-messages.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/error-messages.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/constants/routes.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/routes.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/constants/routes.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/constants/routes.ts diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__mocks__/mock-context.tsx similarity index 92% rename from packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__mocks__/mock-context.tsx index 2d737f68d2..117e7fb056 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__mocks__/mock-context.tsx @@ -19,9 +19,10 @@ export const mockContext = { groups: [], }, loginType: 'CLIENT', - cognitoClientId: 'mockCognitoClientId', + cognitoClientId: '123', refreshToken: 'mockRefreshToken', }, + isFetchSession: false, logout: jest.fn(), getLoginSession: jest.fn(), refreshParams: null, diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/context/__tests__/__snapshots__/auth-context.test.tsx.snap b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__tests__/__snapshots__/auth-context.test.tsx.snap similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/context/__tests__/__snapshots__/auth-context.test.tsx.snap rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__tests__/__snapshots__/auth-context.test.tsx.snap diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/context/__tests__/auth-context.test.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__tests__/auth-context.test.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/context/__tests__/auth-context.test.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/context/__tests__/auth-context.test.tsx diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/context/auth-context.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/auth-context.tsx similarity index 76% rename from packages/react-app-scaffolder/app/templates/apollo/src/context/auth-context.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/context/auth-context.tsx index a7a3f5223f..26b0642902 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/context/auth-context.tsx +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/auth-context.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { useAuth, AuthHook } from '@/hooks/use-auth' +import { AuthHook } from '@/hooks/use-auth' export const AuthContext = React.createContext({} as AuthHook) AuthContext.displayName = 'AuthContext' diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/context/index.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/context/index.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/context/index.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/context/index.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/core/__mocks__/mock-router.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__mocks__/mock-router.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/core/__mocks__/mock-router.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__mocks__/mock-router.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/core/__mocks__/router.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__mocks__/router.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/core/__mocks__/router.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__mocks__/router.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/app.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/app.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/app.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/app.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/private-route-wrapper.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/private-route-wrapper.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/private-route-wrapper.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/private-route-wrapper.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/private-route.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/private-route.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/private-route.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/private-route.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/router.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/router.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/core/__tests__/router.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/__tests__/router.tsx diff --git a/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/app.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/app.tsx new file mode 100644 index 0000000000..987db1242e --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/app.tsx @@ -0,0 +1,28 @@ +import * as React from 'react' +import Router from './router' +import ErrorBoundary from '@/components/hocs/error-boundary' + +import { useAuth } from '@/hooks/use-auth' +import { AuthContext } from '@/context' +import { injectSwitchModeToWindow } from '@reapit/elements' + +injectSwitchModeToWindow() + +import '@/styles/index.css' + +const App = () => { + const { loginSession, refreshParams, getLoginSession, isFetchSession, ...rest } = useAuth() + if (!loginSession && refreshParams && !isFetchSession) { + getLoginSession(refreshParams) + } + + return ( + + + + + + ) +} + +export default App diff --git a/packages/react-app-scaffolder/app/templates/base/src/core/index.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/index.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/base/src/core/index.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/index.tsx diff --git a/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route-wrapper.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route-wrapper.tsx new file mode 100644 index 0000000000..cc20eae5e0 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route-wrapper.tsx @@ -0,0 +1,58 @@ +import * as React from 'react' +import { Loader, Section, FlexContainerResponsive, AppNavContainer, FlexContainerBasic } from '@reapit/elements' +import { withRouter, RouteComponentProps } from 'react-router-dom' +import Menu from '@/components/ui/menu' +import { redirectToOAuth } from '@reapit/cognito-auth' +import { AuthContext } from '@/context' + +const { Suspense } = React + +export type PrivateRouteWrapperProps = RouteComponentProps & { + path: string +} + +export const PrivateRouteWrapper: React.FunctionComponent = ({ children }) => { + const { loginSession, refreshParams, getLoginSession, isFetchSession } = React.useContext(AuthContext) + + if (!loginSession && !refreshParams) { + redirectToOAuth(window.reapit.config.cognitoClientId) + return null + } + + if (!loginSession && refreshParams && !isFetchSession) { + getLoginSession(refreshParams) + } + + if (!loginSession) { + return null + } + + if (isFetchSession) { + return ( +
+ +
+ ) + } + + return ( + + + + + + + + } + > + {children} + + + + + ) +} + +export default withRouter(PrivateRouteWrapper) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/core/private-route.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route.tsx similarity index 97% rename from packages/react-app-scaffolder/app/templates/apollo/src/core/private-route.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route.tsx index b97e05b820..b9b77dd07c 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/core/private-route.tsx +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/private-route.tsx @@ -12,6 +12,7 @@ export interface PrivateRouteProps extends PrivateRouteConnectProps { allow: LoginType | LoginType[] component: React.FunctionComponent exact?: boolean + fetcher?: boolean } export const PrivateRoute = ({ component, allow, loginType = 'CLIENT', ...rest }: PrivateRouteProps & RouteProps) => { diff --git a/packages/react-app-scaffolder/app/templates/redux/src/core/router.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/core/router.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/core/router.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/core/router.tsx diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/hooks/__mocks__/mount-react-hook.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__mocks__/mount-react-hook.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/hooks/__mocks__/mount-react-hook.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__mocks__/mount-react-hook.tsx diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/hooks/__tests__/__snapshots__/use-auth.test.tsx.snap b/packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__tests__/__snapshots__/use-auth.test.tsx.snap similarity index 100% rename from packages/react-app-scaffolder/app/templates/apollo/src/hooks/__tests__/__snapshots__/use-auth.test.tsx.snap rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__tests__/__snapshots__/use-auth.test.tsx.snap diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/hooks/__tests__/use-auth.test.tsx b/packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__tests__/use-auth.test.tsx similarity index 99% rename from packages/react-app-scaffolder/app/templates/apollo/src/hooks/__tests__/use-auth.test.tsx rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__tests__/use-auth.test.tsx index bdefa12fd5..3f7dffa1bf 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/hooks/__tests__/use-auth.test.tsx +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/__tests__/use-auth.test.tsx @@ -4,7 +4,7 @@ import { useAuth, AuthHook } from '../use-auth' import mountReactHook from '../__mocks__/mount-react-hook' const refreshParams: RefreshParams = { - cognitoClientId: '1', + cognitoClientId: '123', loginType: 'CLIENT', mode: 'WEB', redirectUri: '1', diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/hooks/use-auth.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/use-auth.ts similarity index 94% rename from packages/react-app-scaffolder/app/templates/apollo/src/hooks/use-auth.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/use-auth.ts index 004d60504a..1ecbc9e5be 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/hooks/use-auth.ts +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/hooks/use-auth.ts @@ -15,6 +15,7 @@ export type AuthHook = { logout: () => void getLoginSession: (refreshParams: RefreshParams | null) => Promise refreshParams?: RefreshParams | null + isFetchSession: boolean } export const useAuth = (): AuthHook => { @@ -22,7 +23,7 @@ export const useAuth = (): AuthHook => { const [loginSession, setLoginSession] = React.useState(null) const urlParams: RefreshParams | null = getTokenFromQueryString( window.location.search, - window.reapit.config.cognitoClientId + window.reapit.config.cognitoClientId, ) const cookieParams = getSessionCookie(COOKIE_SESSION_KEY) const refreshParams = cookieParams ? cookieParams : urlParams @@ -51,6 +52,7 @@ export const useAuth = (): AuthHook => { loginSession, logout, getLoginSession, + isFetchSession, } } diff --git a/packages/react-app-scaffolder/app/templates/hooks-internal/src/styles/index.css b/packages/react-app-scaffolder/app/templates/hooks-internal/src/styles/index.css new file mode 100644 index 0000000000..f1323ff4b3 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/hooks-internal/src/styles/index.css @@ -0,0 +1,6 @@ +@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap'); +@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap'); + + + + diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/types/core.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/types/core.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/types/core.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/types/core.ts diff --git a/packages/react-app-scaffolder/app/templates/no-redux/src/types/global.d.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/types/global.d.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/no-redux/src/types/global.d.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/types/global.d.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/types/index.d.ts b/packages/react-app-scaffolder/app/templates/hooks-internal/src/types/index.d.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/types/index.d.ts rename to packages/react-app-scaffolder/app/templates/hooks-internal/src/types/index.d.ts diff --git a/packages/react-app-scaffolder/app/templates/base-is-foundation/tsconfig.json b/packages/react-app-scaffolder/app/templates/hooks-internal/tsconfig.json similarity index 100% rename from packages/react-app-scaffolder/app/templates/base-is-foundation/tsconfig.json rename to packages/react-app-scaffolder/app/templates/hooks-internal/tsconfig.json diff --git a/packages/react-app-scaffolder/app/templates/is-foundation-no-redux/package.json b/packages/react-app-scaffolder/app/templates/is-foundation-no-redux/package.json deleted file mode 100644 index 575a333d24..0000000000 --- a/packages/react-app-scaffolder/app/templates/is-foundation-no-redux/package.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "name": "<%= name %>", - "version": "0.0.1", - "description": "<%= description %>", - "main": "./src/index.ts", - "repository": { - "type": "git", - "url": "git+<%= repo %>" - }, - "author": "<%= author %>", - "license": "MIT", - "private": true, - "scripts": { - "build:prod": "webpack --color --mode production --config './src/scripts/webpack-prod.js'", - "start:dev": "webpack-dev-server --hot --progress --color --mode development --config ./src/scripts/webpack-dev.js", - "lint": "concurrently \"tsc --noEmit\" \"eslint --cache --ext=ts,tsx src\"", - "lint:fix": "eslint --cache --ext=ts,tsx src --fix", - "start:prod": "serve public/dist -s -l 8080", - "test:ci": "cross-env TZ=UTC jest --ci --colors --coverage --silent --forceExit --detectOpenHandles --runInBand", - "test:dev": "cross-env TZ=UTC jest --watch --verbose", - "fetch-config": "yarn config-manager fetchConfig app-name" - }, - "dependencies": { - "@reapit/cognito-auth": "latest", - "@reapit/elements": "0.5.61-alpha.1", - "@reapit/foundations-ts-definitions": "2020-02-13", - "@sentry/browser": "^5.11.1", - "@testing-library/react": "^10.0.1", - "dayjs": "latest", - "offline-plugin": "^5.0.7", - "react": "^16.11.0", - "react-dom": "^16.11.0", - "react-ga": "^2.7.0", - "react-router": "^5.1.2", - "react-router-dom": "^5.1.2" - }, - "devDependencies": { - "@babel/core": "^7.7.2", - "@babel/polyfill": "^7.7.0", - "@babel/preset-env": "^7.7.1", - "@sentry/webpack-plugin": "^1.10.0", - "@testing-library/react-hooks": "^2.0.3", - "@types/enzyme": "^3.9.3", - "@types/jest": "^24.0.13", - "@types/node": "^12.0.2", - "@types/react": "^16.8.19", - "@types/react-dom": "^16.8.4", - "@types/react-router": "^5.1.2", - "@types/react-router-dom": "^5.1.2", - "@typescript-eslint/eslint-plugin": "^2.10.0", - "@typescript-eslint/parser": "^2.10.0", - "babel-loader": "^8.0.6", - "copy-webpack-plugin": "5.1.1", - "cross-env": "^7.0.0", - "css-loader": "^3.5.1", - "enzyme": "^3.10.0", - "enzyme-adapter-react-16": "^1.14.0", - "enzyme-to-json": "^3.3.5", - "eslint": "^6.7.2", - "eslint-config-prettier": "^6.7.0", - "eslint-plugin-prettier": "^3.1.1", - "eslint-plugin-react": "^7.17.0", - "eslint-plugin-react-hooks": "^2.3.0", - "favicons-webpack-plugin": "^2.1.0", - "file-loader": "^3.0.1", - "fork-ts-checker-notifier-webpack-plugin": "^1.0.0", - "fork-ts-checker-webpack-plugin": "^1.3.4", - "html-webpack-plugin": "^3.2.0", - "husky": "^2.3.0", - "isomorphic-fetch": "^2.2.1", - "jest": "^25.1.0", - "jest-config": "^25.1.0", - "jest-fetch-mock": "^2.1.2", - "lint-staged": "^8.1.7", - "loader-utils": "^1.2.3", - "node-sass": "^4.12.0", - "prettier": "^1.19.1", - "prettier-plugin-packagejson": "^2.0.1", - "raw-loader": "^3.1.0", - "sass-loader": "^7.1.0", - "serve": "^11.3.0", - "source-map-loader": "^0.2.4", - "style-loader": "^1.1.3", - "ts-jest": "^25.2.0", - "ts-loader": "^6.0.1", - "ts-node": "^8.3.0", - "ts-paths-to-webpack-alias": "^0.3.1", - "typescript": "3.7.2", - "typescript-eslint": "^0.0.1-alpha.0", - "webpack": "^4.41.5", - "webpack-cli": "^3.3.2", - "webpack-dev-server": "^3.4.1", - "mini-css-extract-plugin": "^0.9.0", - "hard-source-webpack-plugin": "^0.13.1", - "postcss-loader": "^3.0.0", - "autoprefixer": "^9.8.0", - "postcss-flexbugs-fixes": "^4.2.1", - "thread-loader": "^2.1.3", - "mockdate": "^3.0.2", - "concurrently": "^5.2.0" - } -} diff --git a/packages/react-app-scaffolder/app/templates/is-foundation-redux/package.json b/packages/react-app-scaffolder/app/templates/is-foundation-redux/package.json deleted file mode 100644 index c24122d1cb..0000000000 --- a/packages/react-app-scaffolder/app/templates/is-foundation-redux/package.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "name": "<%= name %>", - "version": "0.0.1", - "description": "<%= description %>", - "main": "./src/index.ts", - "repository": { - "type": "git", - "url": "git+<%= repo %>" - }, - "author": "<%= author %>", - "license": "MIT", - "private": true, - "scripts": { - "build:prod": "webpack --color --mode production --config './src/scripts/webpack-prod.js'", - "start:dev": "webpack-dev-server --hot --progress --color --mode development --config ./src/scripts/webpack-dev.js", - "lint": "concurrently \"tsc --noEmit\" \"eslint --cache --ext=ts,tsx src\"", - "lint:fix": "eslint --cache --ext=ts,tsx src --fix", - "start:prod": "serve public/dist -s -l 8080", - "test:ci": "cross-env TZ=UTC jest --ci --colors --coverage --silent --forceExit --detectOpenHandles --runInBand", - "test:dev": "cross-env TZ=UTC jest --watch --verbose", - "fetch-config": "yarn config-manager fetchConfig app-name" - }, - "dependencies": { - "offline-plugin": "^5.0.7", - "@reapit/cognito-auth": "latest", - "@reapit/elements": "latest", - "@reapit/foundations-ts-definitions": "2020-02-13", - "dayjs": "latest", - "react": "^16.11.0", - "react-dom": "^16.11.0", - "react-router": "^5.1.2", - "react-router-dom": "^5.1.2", - "@sentry/browser": "^5.11.1", - "react-ga": "^2.7.0", - "react-redux": "^7.1.3", - "redux": "^4.0.4", - "redux-saga": "^1.1.3" - }, - "devDependencies": { - "babel-loader": "^8.0.6", - "@babel/core": "^7.7.2", - "@babel/polyfill": "^7.7.0", - "@babel/preset-env": "^7.7.1", - "@testing-library/react-hooks": "^2.0.3", - "@types/enzyme": "^3.9.3", - "@types/jest": "^24.0.13", - "@types/node": "^12.0.2", - "@types/react": "^16.8.19", - "@types/react-dom": "^16.8.4", - "@types/react-router": "^5.1.2", - "@types/react-router-dom": "^5.1.2", - "@typescript-eslint/eslint-plugin": "^2.10.0", - "@typescript-eslint/parser": "^2.10.0", - "@sentry/webpack-plugin": "^1.10.0", - "cross-env": "^7.0.0", - "enzyme": "^3.10.0", - "enzyme-adapter-react-16": "^1.14.0", - "enzyme-to-json": "^3.3.5", - "eslint": "^6.7.2", - "eslint-config-prettier": "^6.7.0", - "eslint-plugin-prettier": "^3.1.1", - "eslint-plugin-react": "^7.17.0", - "eslint-plugin-react-hooks": "^2.3.0", - "favicons-webpack-plugin": "^2.1.0", - "file-loader": "^3.0.1", - "fork-ts-checker-notifier-webpack-plugin": "^1.0.0", - "fork-ts-checker-webpack-plugin": "^1.3.4", - "html-webpack-plugin": "^3.2.0", - "husky": "^2.3.0", - "isomorphic-fetch": "^2.2.1", - "jest": "^25.1.0", - "jest-config": "^25.1.0", - "jest-fetch-mock": "^2.1.2", - "lint-staged": "^8.1.7", - "loader-utils": "^1.2.3", - "prettier": "^1.19.1", - "prettier-plugin-packagejson": "^2.0.1", - "raw-loader": "^3.1.0", - "serve": "^11.3.0", - "source-map-loader": "^0.2.4", - "ts-jest": "^25.2.0", - "ts-loader": "^6.0.1", - "ts-node": "^8.3.0", - "ts-paths-to-webpack-alias": "^0.3.1", - "typescript": "3.7.2", - "typescript-eslint": "^0.0.1-alpha.0", - "webpack": "^4.41.5", - "webpack-cli": "^3.3.2", - "webpack-dev-server": "^3.4.1", - "sass-loader": "^7.1.0", - "node-sass": "^4.12.0", - "copy-webpack-plugin": "5.1.1", - "style-loader": "^1.1.3", - "css-loader": "^3.5.1", - "@redux-saga/testing-utils": "^1.0.5", - "@types/react-redux": "^7.0.9", - "mini-css-extract-plugin": "^0.9.0", - "hard-source-webpack-plugin": "^0.13.1", - "postcss-loader": "^3.0.0", - "autoprefixer": "^9.8.0", - "postcss-flexbugs-fixes": "^4.2.1", - "thread-loader": "^2.1.3", - "mockdate": "^3.0.2", - "concurrently": "^5.2.0" - } -} diff --git a/packages/react-app-scaffolder/app/templates/redux-external/.eslintrc.js b/packages/react-app-scaffolder/app/templates/redux-external/.eslintrc.js new file mode 100644 index 0000000000..bc51f80efb --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/.eslintrc.js @@ -0,0 +1,76 @@ +module.exports = { + env: { + browser: true, + es6: true, + node: true, + amd: true, + jest: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'prettier', + 'prettier/@typescript-eslint', + 'prettier/react', + 'prettier/standard', + ], + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly', + }, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 2018, + sourceType: 'module', + }, + plugins: ['react', '@typescript-eslint', 'prettier', 'react-hooks'], + ignorePatterns: [ + '__mocks__/', + 'node_modules/', + 'setup-tests.ts', + 'jest.config.js', + '.prettierrc.js', + 'react-app-scaffolder/', + 'marketplace-api-schema.ts', + 'platform-schema.ts', + ], + rules: { + quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }], + semi: ['error', 'never'], + 'no-unused-vars': ['error', { vars: 'all', args: 'after-used' }], + '@typescript-eslint/no-unused-vars': [2, { args: 'none' }], + 'prettier/prettier': ['error', { + 'endOfLine': 'auto' + }], + 'max-len': ['error', { code: 120, ignoreUrls: true }], + 'no-confusing-arrow': ['error', { allowParens: false }], + 'no-mixed-operators': [ + 'error', + { + groups: [ + ['&', '|', '^', '~', '<<', '>>', '>>>'], + ['==', '!=', '===', '!==', '>', '>=', '<', '<='], + ['&&', '||'], + ['in', 'instanceof'], + ], + }, + ], + 'no-tabs': ['error', { allowIndentationTabs: true }], + 'no-unexpected-multiline': 'error', + // Disabling as conflicts with Prettier + indent: 0, + // Disabling as we are validating types with TypeScript not PropTypes + 'react/prop-types': 0, + "react-hooks/rules-of-hooks": 0, + "react-hooks/exhaustive-deps": 0, + }, + settings: { + react: { + version: 'detect', + }, + }, +} diff --git a/packages/react-app-scaffolder/app/templates/redux-external/.gitignore b/packages/react-app-scaffolder/app/templates/redux-external/.gitignore new file mode 100644 index 0000000000..aeb663f439 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/.gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/src/tests/coverage + +# misc +.DS_Store +reapit-config.json +config.json + +# log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +*.log + +.cache/ +yarn.lock + +public/dist +src/tests + +.jest-cache \ No newline at end of file diff --git a/packages/react-app-scaffolder/app/templates/redux-external/.prettierrc.js b/packages/react-app-scaffolder/app/templates/redux-external/.prettierrc.js new file mode 100644 index 0000000000..39b61eca68 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + semi: false, + trailingComma: 'all', + singleQuote: true, + printWidth: 120, + tabWidth: 2, +} diff --git a/packages/react-app-scaffolder/app/templates/redux-external/config.example.json b/packages/react-app-scaffolder/app/templates/redux-external/config.example.json new file mode 100644 index 0000000000..98a80ad258 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/config.example.json @@ -0,0 +1,7 @@ +{ + "appEnv": "local", + "cognitoClientId": "", + "cognitoOAuthUrl": "https://dev.connect.reapit.cloud", + "cognitoUserPoolId": "eu-west-2_hbt0B7yys", + "platformApiUrl": "https://dev.platform.reapit.cloud" +} diff --git a/packages/react-app-scaffolder/app/templates/base-is-not-foundation/jest.config.js b/packages/react-app-scaffolder/app/templates/redux-external/jest.config.js similarity index 100% rename from packages/react-app-scaffolder/app/templates/base-is-not-foundation/jest.config.js rename to packages/react-app-scaffolder/app/templates/redux-external/jest.config.js diff --git a/packages/react-app-scaffolder/app/templates/redux-external/package.json b/packages/react-app-scaffolder/app/templates/redux-external/package.json new file mode 100644 index 0000000000..c1574e5caf --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/package.json @@ -0,0 +1,84 @@ +{ + "version": "0.0.1", + "main": "./src/index.ts", + "license": "MIT", + "private": true, + "scripts": { + "build:prod": "webpack --color --mode production --config './src/scripts/webpack-prod.js'", + "start:dev": "webpack-dev-server --hot --progress --color --mode development --config ./src/scripts/webpack-dev.js", + "lint": "concurrently \"tsc --noEmit\" \"eslint --cache --ext=ts,tsx src\"", + "lint:fix": "eslint --cache --ext=ts,tsx src --fix", + "start:prod": "serve public/dist -s -l 8080", + "test:ci": "cross-env TZ=UTC jest --ci --colors --coverage --silent --forceExit --detectOpenHandles --runInBand", + "test:dev": "cross-env TZ=UTC jest --watch --verbose" + }, + "dependencies": { + "@reapit/cognito-auth": "2.1.7", + "@reapit/elements": "0.5.61", + "@reapit/foundations-ts-definitions": "2020-02-13", + "dayjs": "^1.8.19", + "react": "~16.12.0", + "react-dom": "~16.12.0", + "react-router": "~5.1.2", + "react-router-dom": "~5.1.2", + "react-redux": "~7.2.0", + "redux": "~4.0.5", + "redux-saga": "~1.1.3" + }, + "devDependencies": { + "@babel/core": "~7.7.2", + "@babel/polyfill": "~7.7.0", + "@babel/preset-env": "~7.7.1", + "@redux-saga/testing-utils": "^1.0.5", + "@testing-library/react": "~10.0.1", + "@testing-library/react-hooks": "~3.3.0", + "@types/enzyme": "~3.10.3", + "@types/enzyme-adapter-react-16": "~1.0.5", + "@types/jest": "~24.0.23", + "@types/node": "10.17.13", + "@types/react": "~16.9.0", + "@types/react-dom": "~16.9.0", + "@types/react-router": "~5.1.3", + "@types/react-router-dom": "~5.1.3", + "@typescript-eslint/eslint-plugin": "~2.23.0", + "@typescript-eslint/parser": "~2.23.0", + "autoprefixer": "~9.8.0", + "babel-loader": "~8.1.0", + "concurrently": "~5.2.0", + "cross-env": "~7.0.2", + "css-loader": "~3.6.0", + "enzyme": "~3.10.0", + "enzyme-adapter-react-16": "~1.15.1", + "enzyme-to-json": "~3.4.3", + "eslint": "~6.7.2", + "eslint-config-prettier": "~6.7.0", + "eslint-plugin-prettier": "~3.1.1", + "eslint-plugin-react": "~7.17.0", + "eslint-plugin-react-hooks": "~2.3.0", + "favicons-webpack-plugin": "~2.1.0", + "file-loader": "~3.0.1", + "fork-ts-checker-notifier-webpack-plugin": "~1.0.0", + "fork-ts-checker-webpack-plugin": "~1.3.4", + "hard-source-webpack-plugin": "~0.13.1", + "html-webpack-plugin": "~3.2.0", + "jest": "~25.1.0", + "jest-config": "~25.1.0", + "jest-fetch-mock": "~2.1.2", + "mini-css-extract-plugin": "~0.9.0", + "mockdate": "~3.0.2", + "postcss-flexbugs-fixes": "~4.2.1", + "postcss-loader": "~3.0.0", + "prettier": "~1.19.1", + "serve": "~11.3.2", + "style-loader": "~1.1.3", + "thread-loader": "~2.1.3", + "ts-jest": "~25.2.0", + "ts-loader": "~6.0.1", + "ts-paths-to-webpack-alias": "~0.3.1", + "typescript": "3.7.2", + "typescript-eslint": "~0.0.1-alpha.0", + "webpack": "~4.41.5", + "webpack-cli": "~3.3.2", + "webpack-dev-server": "~3.4.1" + } +} diff --git a/packages/react-app-scaffolder/app/templates/redux-external/postcss.config.js b/packages/react-app-scaffolder/app/templates/redux-external/postcss.config.js new file mode 100644 index 0000000000..ee5eb8627a --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/postcss.config.js @@ -0,0 +1,3 @@ +module.exports = { + plugins: [require('autoprefixer'), require('postcss-flexbugs-fixes')], +} diff --git a/packages/react-app-scaffolder/app/templates/redux-external/public/index.html b/packages/react-app-scaffolder/app/templates/redux-external/public/index.html new file mode 100644 index 0000000000..72cb6e98ef --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/public/index.html @@ -0,0 +1,13 @@ + + + + + + + Reapit Foundations + + + +
+ + diff --git a/packages/react-app-scaffolder/app/templates/redux-external/public/logo.png b/packages/react-app-scaffolder/app/templates/redux-external/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf5e2e1f31b1568b76e6c10302f2bdbfaf6c2d2 GIT binary patch literal 2229 zcmV;m2uk;fP) z-Xo;mBc$FVq~18G-9w?$Rfe*9$m@E@>U_%Vd&um2$m(di;UuQtD5&5grQRKy)+3|d z9irYMrQRT--9xhDBBS05cDVpxr~qK70AZ*ISez?Ri61+7CNF6vE@>t&XeBRbB`#PXJjFT-A>SMPSuW7a?RtfLwn%9+y~E1lRV1tq3sx z|ITM6oq?7C;5|Q)^ng*0YXTMz?B~? zMaBty{`%{AnrRQ?42%=_`YZl3C3=K}qEAi}`1&h~N8_n3AsYXfWdNprk|c@${3iN{ zGP4Z8@c&O(0;3^A;4BG=3SjQxm0M5ll_Q3U3Gnkg_e zq^Sr{o_}aJCUzBp*7G0x;e}{Krg?sPt;lW`RYD^J^#s1q|36JngI3btnfXx90CfD& z0(2I=4NU`|L? z5uo^?5nVXf*ir2-NrAK0VFgs z5$b7(a;=b_15orcK&WY|F$l>k0$D%N1wX71#mVy&4UwcGQ1WwuP|BtNhmdqF0!2TA zgv8MjiIAisK&d~6LS%N!czPC+$N-f5Tp~o5@!1VgZV(a~fTEvaLJ_N^c!XpW0ZRQj z1YScVsR(5HA9+Ijq8E>lL@fg4`-fpdXH9ixSrK5>pZ)1RGI?dDzN3MB{gEQXmhtfw zS8g1Ga{!8dE)t^47@5$pB0%-S_pl=?x*A1&dl~-@%|Ak$O;OM&tHTaW$=H2m zhE1ropzmLw;=ZEPG(;W}YT|vj-q%&$=bgMV<4v`vgzBgcJ9K>3a_oPqS~{XQkM@F2PCf;6Hv@DHth!=Xoy9v(p?V!f^~pyJ@d3+ZlHr6p zq4!l+R9z`lqOP_UG>_9;#_O&Dc|tX$_JU6Lp8|$JsEJj(QR0T^6l8%AYC@bE_%!fy z&4dI)sEK+(^Q(-W4_JI9R7d$)Mrg;D z@qVzW(5tJ?2$lO~d>DK|kFzictyb&%B`35GJ`HtU^`8(!)H2jSV$(oZLkNV54ny;% zu4dA^n>#|y6wFVfSoSsFC!@cIcdVOK8On&AVg1-=W9e z5-L`GhT28xg$$p_|cG?Y*CxlwB%)%s8pKAgpq}^2eLP)!*_Jt5_ zs&~tftI)tJvp@(n=bCT{X>Mj75!$g2SVAVW5+AUHOGwXBkErDACw*+np+!DAYU@-mz5AlWMLvYXV00000NkvXXu0mjf D^ym6T literal 0 HcmV?d00001 diff --git a/packages/react-app-scaffolder/app/templates/redux/src/actions/__tests__/auth.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/actions/__tests__/auth.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/actions/__tests__/auth.ts rename to packages/react-app-scaffolder/app/templates/redux-external/src/actions/__tests__/auth.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/actions/__tests__/authenticated.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/actions/__tests__/authenticated.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/actions/__tests__/authenticated.ts rename to packages/react-app-scaffolder/app/templates/redux-external/src/actions/__tests__/authenticated.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/actions/__tests__/error.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/actions/__tests__/error.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/actions/__tests__/error.ts rename to packages/react-app-scaffolder/app/templates/redux-external/src/actions/__tests__/error.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/actions/auth.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/actions/auth.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/actions/auth.ts rename to packages/react-app-scaffolder/app/templates/redux-external/src/actions/auth.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/actions/authenticated.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/actions/authenticated.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/actions/authenticated.ts rename to packages/react-app-scaffolder/app/templates/redux-external/src/actions/authenticated.ts diff --git a/packages/react-app-scaffolder/app/templates/redux/src/actions/error.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/actions/error.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/actions/error.ts rename to packages/react-app-scaffolder/app/templates/redux-external/src/actions/error.ts diff --git a/packages/react-app-scaffolder/app/templates/redux-external/src/assets/images/reapit-connect.png b/packages/react-app-scaffolder/app/templates/redux-external/src/assets/images/reapit-connect.png new file mode 100644 index 0000000000000000000000000000000000000000..207e7c5599305f3994bc2b0bf3de445c1c5c05c6 GIT binary patch literal 22433 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 XC7?3rOU}7+;d5h7+nAM^y2t$o$l(nb literal 0 HcmV?d00001 diff --git a/packages/react-app-scaffolder/app/templates/redux-external/src/assets/images/reapit-graphic.jpg b/packages/react-app-scaffolder/app/templates/redux-external/src/assets/images/reapit-graphic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..99137577d8626f21c6e7c81c323b2ab10b62f70f GIT binary patch literal 203436 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 + Something went wrong here, try refreshing your page. +

+`; + +exports[`ErrorBoundary should match a snapshot when no error 1`] = ``; diff --git a/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/__snapshots__/route-fetcher.tsx.snap b/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/__snapshots__/route-fetcher.tsx.snap new file mode 100644 index 0000000000..aea42c8cb2 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/__snapshots__/route-fetcher.tsx.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RouteFetcher should match a snapshot 1`] = ``; diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/hocs/__tests__/error-boundary.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/error-boundary.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/hocs/__tests__/error-boundary.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/error-boundary.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/hocs/__tests__/route-fetcher.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/route-fetcher.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/hocs/__tests__/route-fetcher.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/__tests__/route-fetcher.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/hocs/error-boundary.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/error-boundary.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/hocs/error-boundary.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/error-boundary.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/hocs/route-fetcher.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/route-fetcher.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/hocs/route-fetcher.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/hocs/route-fetcher.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__styles__/styles.ts b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__styles__/styles.ts new file mode 100644 index 0000000000..f1b00b614a --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__styles__/styles.ts @@ -0,0 +1,69 @@ +import { css } from 'linaria' + +export const container = css` + min-width: 100vw; + min-height: 100vh; + display: flex; + justify-content: flex-end; + align-items: center; + flex-direction: row; + background-color: #fff; + + @media screen and (max-width: 900px) { + flex-direction: column-reverse; + } +` + +export const wrapper = css` + background-color: #fff; + width: 33.33%; + padding: 1rem; + pointer-events: auto; + + &.disabled { + pointer-events: none; + } + + h1, + p, + img { + text-align: center; + } + + div > img { + margin: 0 auto; + max-width: 200px; + display: block; + } + + button { + margin: 0 auto; + max-width: 400px; + } + + @media screen and (max-width: 900px) { + width: 100%; + } + + @media screen and (min-width: 1200px) { + padding: 0 3rem; + } +` + +export const image = css` + background-color: #fff; + width: 66.66%; + height: 100vh; + font-size: 0; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } + + @media screen and (max-width: 900px) { + width: 100%; + height: 300px; + } +` diff --git a/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap new file mode 100644 index 0000000000..51209aa1bd --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/authenticated.tsx.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Authenticated should match a snapshot 1`] = ` +
+

+ Welcome To Reapit Foundations +

+ + You are now authenticated against our sandbox data + +
+`; diff --git a/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap new file mode 100644 index 0000000000..dbbd7122ac --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/__snapshots__/login.tsx.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Login should match a snapshot 1`] = ` +
+
+ + Reapit Connect Graphic + + + + +
+
+ Reapit Graphic +
+
+`; + +exports[`Login should match a snapshot when hasSession 1`] = ` + +`; diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/pages/__tests__/authenticated.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/authenticated.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/pages/__tests__/authenticated.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/authenticated.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/pages/__tests__/login.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/login.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/pages/__tests__/login.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/__tests__/login.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/pages/authenticated.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/authenticated.tsx similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/components/pages/authenticated.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/authenticated.tsx diff --git a/packages/react-app-scaffolder/app/templates/redux/src/components/pages/login.tsx b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/login.tsx similarity index 91% rename from packages/react-app-scaffolder/app/templates/redux/src/components/pages/login.tsx rename to packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/login.tsx index e132957165..bfd8a4b4f2 100644 --- a/packages/react-app-scaffolder/app/templates/redux/src/components/pages/login.tsx +++ b/packages/react-app-scaffolder/app/templates/redux-external/src/components/pages/login.tsx @@ -7,11 +7,9 @@ import Routes from '@/constants/routes' import { Button, Level } from '@reapit/elements' import connectImage from '@/assets/images/reapit-connect.png' -<% if(sass){ %> -import loginStyles from '@/styles/pages/login.scss?mod' -<% } else { %> + import * as loginStyles from './__styles__/styles' - <% } %> + import { redirectToLogin } from '@reapit/cognito-auth' @@ -38,8 +36,6 @@ export const Login: React.FunctionComponent = (props: LoginProps) => Reapit Connect Graphic -

Welcome to app-name

- + +
+ +
+ Reapit Graphic +
+
+ ) +} + +export const mapStateToProps = (state: ReduxState): LoginProps => ({ + hasSession: !!state.auth.loginSession || !!state.auth.refreshSession, +}) + +export default withRouter(connect(mapStateToProps, {})(Login)) diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/components/ui/__tests__/menu.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/__tests__/menu.tsx similarity index 67% rename from packages/react-app-scaffolder/app/templates/apollo/src/components/ui/__tests__/menu.tsx rename to packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/__tests__/menu.tsx index 8b6bd1d770..17c6ade2e7 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/components/ui/__tests__/menu.tsx +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/__tests__/menu.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { shallow } from 'enzyme' -import { Menu, MenuProps, generateMenuConfig } from '../menu' +import { Menu, MenuProps, mapDispatchToProps, generateMenuConfig } from '../menu' import toJson from 'enzyme-to-json' const props: MenuProps = { @@ -16,6 +16,15 @@ describe('Menu', () => { expect(toJson(shallow())).toMatchSnapshot() }) + describe('mapDispatchToProps', () => { + it('should return loginType', () => { + const dispatch = jest.fn() + const fn = mapDispatchToProps(dispatch) + fn.logout() + expect(dispatch).toBeCalled() + }) + }) + describe('generateMenuConfig', () => { it('should return config', () => { const logoutCallback = jest.fn() diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/menu.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/menu.tsx new file mode 100644 index 0000000000..1e0a3cd10c --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/components/ui/menu.tsx @@ -0,0 +1,72 @@ +import * as React from 'react' +import { connect } from 'react-redux' +import { withRouter, RouteComponentProps } from 'react-router' +import { Menu as Sidebar, MenuConfig, ReapitLogo } from '@reapit/elements' +import { authLogout } from '@/actions/auth' +import { LoginMode } from '@reapit/cognito-auth' +import { Location } from 'history' +import { FaSignOutAlt, FaCloud } from 'react-icons/fa' +import { ReduxState } from '../../types/core' + +export const generateMenuConfig = ( + logoutCallback: () => void, + location: Location, + mode: LoginMode, +): MenuConfig => { + return { + defaultActiveKey: 'LOGO', + mode, + location, + menu: [ + { + key: 'LOGO', + icon: , + type: 'LOGO', + }, + { + title: 'Apps', + key: 'APPS', + icon: , + callback: () => + (window.location.href = + !window.location.href.includes('dev') || window.location.href.includes('localhost') + ? 'https://marketplace.reapit.cloud/client/installed' + : 'https://dev.marketplace.reapit.cloud/client/installed'), + type: 'PRIMARY', + }, + { + title: 'Logout', + key: 'LOGOUT', + callback: logoutCallback, + icon: , + type: 'SECONDARY', + }, + ], + } +} + +export interface MenuMappedActions { + logout: () => void +} + +export interface MenuMappedState { + mode: LoginMode +} + +export type MenuProps = MenuMappedActions & MenuMappedState & RouteComponentProps & {} + +export const Menu: React.FunctionComponent = ({ logout, location, mode }) => { + const logoutCallback = () => logout() + const menuConfigs = generateMenuConfig(logoutCallback, location, mode) + return +} + +export const mapDispatchToProps = (dispatch: any): MenuMappedActions => ({ + logout: () => dispatch(authLogout()), +}) + +export const mapStateToProps = (state: ReduxState): MenuMappedState => ({ + mode: state?.auth?.refreshSession?.mode || 'WEB', +}) + +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Menu)) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/action-types.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/action-types.ts new file mode 100644 index 0000000000..290df77999 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/action-types.ts @@ -0,0 +1,28 @@ +/** + * Please follow the <>_<> pattern and group actions by STATE + */ +const ActionTypes = { + // Auth actions + AUTH_LOGIN: 'AUTH_LOGIN', + AUTH_LOGIN_SUCCESS: 'AUTH_LOGIN_SUCCESS', + AUTH_LOGIN_FAILURE: 'AUTH_LOGIN_FAILURE', + AUTH_LOGOUT: 'AUTH_LOGOUT', + AUTH_LOGOUT_SUCCESS: 'AUTH_LOGOUT_SUCCESS', + AUTH_CHANGE_LOGIN_TYPE: 'AUTH_CHANGE_LOGIN_TYPE', + AUTH_SET_DESKTOP_SESSION: 'AUTH_SET_DESKTOP_SESSION', + AUTH_SET_REFRESH_SESSION: 'AUTH_SET_REFRESH_SESSION', + + // Error actions + ERROR_THROWN_COMPONENT: 'ERROR_THROWN_COMPONENT', + ERROR_THROWN_SERVER: 'ERROR_THROWN_SERVER', + ERROR_CLEARED_COMPONENT: 'ERROR_CLEARED_COMPONENT', + ERROR_CLEARED_SERVER: 'ERROR_CLEARED_SERVER', + + AUTHENTICATED_REQUEST_DATA: 'AUTHENTICATED_REQUEST_DATA', + AUTHENTICATED_REQUEST_FAILURE: 'AUTHENTICATED_REQUEST_FAILURE', + AUTHENTICATED_LOADING: 'AUTHENTICATED_LOADING', + AUTHENTICATED_RECEIVE_DATA: 'AUTHENTICATED_RECEIVE_DATA', + AUTHENTICATED_CLEAR_DATA: 'AUTHENTICATED_CLEAR_DATA', +} + +export default ActionTypes diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/api.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/api.ts new file mode 100644 index 0000000000..c737c935cb --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/api.ts @@ -0,0 +1,12 @@ +import { StringMap } from '@/types/core' +import { COOKIE_SESSION_KEY as COGNITIO_COOKIE_SESSION_KEY } from '@reapit/cognito-auth' + +export const CONTACTS_HEADERS = { + 'Content-Type': 'application/json', +} as StringMap + +export const API_VERSION = '2020-01-31' + +export const COOKIE_SESSION_KEY = COGNITIO_COOKIE_SESSION_KEY + +export const URLS = {} diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/auth.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/auth.ts new file mode 100644 index 0000000000..1ef168b5f5 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/auth.ts @@ -0,0 +1,5 @@ +import { StringMap } from '@/types/core' + +export const LOGIN_TYPE = { + CLIENT: 'CLIENT', +} as StringMap diff --git a/packages/react-app-scaffolder/app/templates/redux/src/constants/error-messages.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/error-messages.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/constants/error-messages.ts rename to packages/react-app-scaffolder/app/templates/redux-internal/src/constants/error-messages.ts diff --git a/packages/react-app-scaffolder/app/templates/base/src/constants/routes.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/routes.ts similarity index 67% rename from packages/react-app-scaffolder/app/templates/base/src/constants/routes.ts rename to packages/react-app-scaffolder/app/templates/redux-internal/src/constants/routes.ts index e4d9057eab..2403b74c67 100644 --- a/packages/react-app-scaffolder/app/templates/base/src/constants/routes.ts +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/constants/routes.ts @@ -1,7 +1,6 @@ const Routes = { HOME: '/', LOGIN: '/login', - AUTHENTICATED: '/authenticated', } export default Routes diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/router.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/router.tsx new file mode 100644 index 0000000000..1f5a0334cc --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/router.tsx @@ -0,0 +1,3 @@ +import * as React from 'react' + +export default () =>
I am a router
diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/store.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/store.ts new file mode 100644 index 0000000000..29161eef08 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__mocks__/store.ts @@ -0,0 +1,9 @@ +export default { + dispatch: jest.fn(), + state: { + auth: { + loginSession: null, + refreshSession: null, + }, + }, +} diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/app.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/app.tsx new file mode 100644 index 0000000000..873ca25aae --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/app.tsx @@ -0,0 +1,19 @@ +import * as React from 'react' +import { shallow } from 'enzyme' +import toJson from 'enzyme-to-json' +import App from '../app' +import { render, unmountComponentAtNode } from 'react-dom' + +jest.mock('../router') + +describe('App', () => { + it('should render without crashing', () => { + const div = document.createElement('div') + render(, div) + unmountComponentAtNode(div) + }) + + it('should match a snapshot', () => { + expect(toJson(shallow())).toMatchSnapshot() + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route-wrapper.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route-wrapper.tsx new file mode 100644 index 0000000000..7c479e2167 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route-wrapper.tsx @@ -0,0 +1,20 @@ +import * as React from 'react' +import { shallow } from 'enzyme' +import toJson from 'enzyme-to-json' +import { PrivateRouteWrapper, PrivateRouteWrapperProps } from '../private-route-wrapper' + +const props: PrivateRouteWrapperProps = { + path: '/', + hasSession: false, + setDesktopSession: jest.fn(), + // @ts-ignore: ignore to fullfil the definition of RouteComponentProps + location: { + search: '/client/apps?username=wmcvay@reapit.com&desktopToken=TOKEN', + }, +} + +describe('PrivateRouter', () => { + it('should match a snapshot', () => { + expect(toJson(shallow())).toMatchSnapshot() + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route.tsx new file mode 100644 index 0000000000..329ebf3ac9 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/private-route.tsx @@ -0,0 +1,49 @@ +import * as React from 'react' +import { shallow, mount } from 'enzyme' +import toJson from 'enzyme-to-json' +import { MemoryRouter, Route } from 'react-router' +import { PrivateRoute } from '../private-route' + +describe('PrivateRouter', () => { + it('should match a snapshot', () => { + expect(toJson(shallow( null} />))).toMatchSnapshot() + }) + + it('should redirect to /404 page if isLogin is false', () => { + const wrapper = mount( + + null} path="/my-path" /> +
} /> + , + ) + expect(wrapper.find('.not-found')).toHaveLength(1) + }) + + it('should return render component if loginType matches allow is true', () => { + const wrapper = mount( + +
} + path="/client" + /> + , + ) + expect(wrapper.find('.render-class')).toHaveLength(1) + }) + + it('should return render component if loginType is included in allow array is true', () => { + const wrapper = mount( + +
} + path="/developer/my-apps" + /> + , + ) + expect(wrapper.find('.render-class')).toHaveLength(1) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/router.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/router.tsx new file mode 100644 index 0000000000..f9875cafb3 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/router.tsx @@ -0,0 +1,25 @@ +import * as React from 'react' +import { shallow } from 'enzyme' +import toJson from 'enzyme-to-json' +import Router, { catchChunkError } from '../router' + +describe('Router', () => { + it('should match a snapshot', () => { + expect(toJson(shallow())).toMatchSnapshot() + }) + + describe('catchChunkError', () => { + it('should return promise', done => { + const fn = jest.fn().mockResolvedValue(
Test
) + const promiseFn = catchChunkError(fn) + expect(promiseFn).toBeDefined() + expect(fn).toBeCalled() + expect( + promiseFn.then(result => { + expect(result).toEqual(
Test
) + done() + }), + ) + }) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/store.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/store.ts new file mode 100644 index 0000000000..912f2c4908 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/__tests__/store.ts @@ -0,0 +1,22 @@ +import StoreInstance, { Store } from '../store' + +describe('Store', () => { + it('should return a singleton instance of Store', () => { + expect(StoreInstance instanceof Store).toBe(true) + }) + + it('should export a store', () => { + expect(StoreInstance.reduxStore).toBeDefined() + expect(typeof StoreInstance.reduxStore).toBe('object') + }) + + it('should export a state', () => { + expect(StoreInstance.state).toBeDefined() + expect(typeof StoreInstance.state).toBe('object') + }) + + it('should export a dispatch', () => { + expect(StoreInstance.dispatch).toBeDefined() + expect(typeof StoreInstance.dispatch).toBe('function') + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/app.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/app.tsx new file mode 100644 index 0000000000..e2d5d8daa9 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/app.tsx @@ -0,0 +1,20 @@ +import * as React from 'react' +import Router from './router' +import ErrorBoundary from '@/components/hocs/error-boundary' + +import store from './store' +import { Provider } from 'react-redux' + +import '@/styles/index.css' + +const App = () => { + return ( + + + + + + ) +} + +export default App diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/index.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/index.tsx new file mode 100644 index 0000000000..afcbec1bbd --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/index.tsx @@ -0,0 +1,65 @@ +import * as Sentry from '@sentry/browser' +import React from 'react' +import { render } from 'react-dom' +import ReactGA from 'react-ga' +import { Config } from '@/types/global' +import App from './app' +import { getMarketplaceGlobalsByKey } from '@reapit/elements' + +// Init global config +window.reapit = { + config: { + appEnv: 'production', + sentryDns: '', + cognitoClientId: '', + googleAnalyticsKey: '', + cognitoOAuthUrl: '', + cognitoUserPoolId: '', + }, +} + +export const renderApp = (Component: React.ComponentType) => { + const rootElement = document.querySelector('#root') as Element + const isDesktop = getMarketplaceGlobalsByKey() + const html = document.querySelector('html') + if (isDesktop && html) { + html.classList.add('is-desktop') + } + + if (rootElement) { + render(, rootElement) + } +} + +const run = async () => { + await fetch('config.json') + .then(response => response.json()) + .then((config: Config) => { + window.reapit.config = config + const isLocal = config.appEnv === 'local' + if (!isLocal && config.sentryDns) { + Sentry.init({ + release: process.env.APP_VERSION, + dsn: config.sentryDns, + environment: config.appEnv, + }) + } + if (!isLocal && config.googleAnalyticsKey) { + ReactGA.initialize(config.googleAnalyticsKey) + ReactGA.pageview(window.location.pathname + window.location.search) + } + renderApp(App) + }) + .catch(error => { + console.error('Cannot fetch config', error) + }) +} + +if (module['hot']) { + module['hot'].accept('./app', () => { + const NextApp = require('./app').default + renderApp(NextApp) + }) +} + +run() diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route-wrapper.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route-wrapper.tsx new file mode 100644 index 0000000000..9294c0de87 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route-wrapper.tsx @@ -0,0 +1,78 @@ +import * as React from 'react' +import { RouteComponentProps } from 'react-router-dom' +import { connect } from 'react-redux' +import { ReduxState } from 'src/types/core' +import Menu from '@/components/ui/menu' +import { Loader, Section, FlexContainerResponsive, AppNavContainer, FlexContainerBasic } from '@reapit/elements' +import { RefreshParams, getTokenFromQueryString } from '@reapit/cognito-auth' +import { authSetRefreshSession } from '../actions/auth' +import { Dispatch } from 'redux' +import { withRouter } from 'react-router' +import { redirectToOAuth } from '@reapit/cognito-auth' + +const { Suspense } = React + +export interface PrivateRouteWrapperConnectActions { + setRefreshSession: (refreshParams: RefreshParams) => void +} + +export interface PrivateRouteWrapperConnectState { + hasSession: boolean + isDesktopMode: boolean +} + +export type PrivateRouteWrapperProps = PrivateRouteWrapperConnectState & + PrivateRouteWrapperConnectActions & + RouteComponentProps & { + path: string + } + +export const PrivateRouteWrapper: React.FunctionComponent = ({ + setRefreshSession, + children, + location, + hasSession, +}) => { + const cognitoClientId = window.reapit.config.cognitoClientId + const refreshParams = getTokenFromQueryString(location.search, cognitoClientId) + + if (refreshParams && !hasSession) { + setRefreshSession(refreshParams) + return null + } + + if (!hasSession) { + redirectToOAuth(cognitoClientId) + return null + } + + return ( + + + + + + + + } + > + {children} + + + + + ) +} + +const mapStateToProps = (state: ReduxState): PrivateRouteWrapperConnectState => ({ + hasSession: !!state.auth.loginSession || !!state.auth.refreshSession, + isDesktopMode: state?.auth?.refreshSession?.mode === 'DESKTOP', +}) + +const mapDispatchToProps = (dispatch: Dispatch): PrivateRouteWrapperConnectActions => ({ + setRefreshSession: refreshParams => dispatch(authSetRefreshSession(refreshParams)), +}) + +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(PrivateRouteWrapper)) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route.tsx new file mode 100644 index 0000000000..3c57f7e292 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/private-route.tsx @@ -0,0 +1,50 @@ +import * as React from 'react' +import { Route, RouteProps } from 'react-router' +import { Redirect } from 'react-router-dom' +import { connect } from 'react-redux' +import RouteFetcher from '../components/hocs/route-fetcher' + +export type LoginType = 'CLIENT' | 'DEVELOPER' + +export interface PrivateRouteConnectProps { + loginType: LoginType +} + +export interface PrivateRouteProps extends PrivateRouteConnectProps { + allow: LoginType | LoginType[] + component: React.FunctionComponent + exact?: boolean + fetcher?: boolean +} + +export const PrivateRoute = ({ + component, + allow, + fetcher = false, + loginType, + ...rest +}: PrivateRouteProps & RouteProps) => { + const allowTypes = Array.isArray(allow) ? allow : [allow] + allowTypes.includes(loginType) + return ( + { + if (!allowTypes.includes(loginType)) { + return + } + if (fetcher) { + return + } + const Component = component + + return + }} + /> + ) +} + +const mapStateToProps = (): PrivateRouteConnectProps => ({ + loginType: 'CLIENT', +}) +export default connect(mapStateToProps)(PrivateRoute) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/router.tsx b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/router.tsx new file mode 100644 index 0000000000..1c55587792 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/router.tsx @@ -0,0 +1,51 @@ +import * as React from 'react' +import { Route, Router as BrowserRouter, Switch, Redirect } from 'react-router-dom' +import { createBrowserHistory } from 'history' +import Routes from '../constants/routes' +import PrivateRoute from './private-route' +import PrivateRouteWrapper from './private-route-wrapper' + +export const history = createBrowserHistory() + +export const catchChunkError = ( + fn: Function, + retriesLeft = 3, + interval = 500, +): Promise<{ default: React.ComponentType }> => { + return new Promise((resolve, reject) => { + fn() + .then(resolve) + .catch((error: Error) => { + // Ignore chunk cache error and retry to fetch, if cannot reload browser + console.info(error) + setTimeout(() => { + if (retriesLeft === 1) { + window.location.reload() + return + } + catchChunkError(fn, retriesLeft - 1, interval).then(resolve, reject) + }, interval) + }) + }) +} + +const LoginPage = React.lazy(() => catchChunkError(() => import('../components/pages/login'))) +const AuthenticatedPage = React.lazy(() => catchChunkError(() => import('../components/pages/authenticated'))) + +const Router = () => ( + + + + + + + + + + + + + +) + +export default Router diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/core/store.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/store.ts new file mode 100644 index 0000000000..3980f23ee9 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/core/store.ts @@ -0,0 +1,85 @@ +import { injectSwitchModeToWindow } from '@reapit/elements' +import { + createStore, + applyMiddleware, + compose, + combineReducers, + Store as ReduxStore, + Dispatch, + Reducer, + CombinedState, + AnyAction, +} from 'redux' +import createSagaMiddleware from 'redux-saga' +import { all, fork } from '@redux-saga/core/effects' +import authenticated from '../reducers/authenticated' +import error from '../reducers/error' +import auth from '@/reducers/auth' +import { ReduxState, Action } from '../types/core' +import authenticatedSagas from '../sagas/authenticated' +import authSagas from '@/sagas/auth' + +export class Store { + static _instance: Store + + static get instance() { + if (!Store._instance) { + Store._instance = new Store() + } + + return Store._instance + } + + static isProd = process.env.NODE_ENV === 'production' + + static sagaMiddleware = createSagaMiddleware() + + static reducers = combineReducers({ + error, + authenticated, + auth, + }) as Reducer, Action | AnyAction> + + static sagas = function*() { + yield all([fork(authenticatedSagas), fork(authSagas)]) + } + + static composeEnhancers = + !Store.isProd && window && (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ + ? (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) + : compose + + reduxStore: ReduxStore + + constructor() { + injectSwitchModeToWindow() + const composed = Store.composeEnhancers(applyMiddleware(Store.sagaMiddleware)) + + this.reduxStore = createStore(Store.reducers, composed) + + Store.sagaMiddleware.run(Store.sagas) + + this.hotModuleReloading() + } + + hotModuleReloading() { + const hotModule = (module as any).hot + + if (hotModule) { + // Enable Webpack hot module replacement for reducers + hotModule.accept('../reducers', () => { + this.reduxStore.replaceReducer(Store.reducers) + }) + } + } + + get dispatch(): Dispatch { + return this.reduxStore.dispatch + } + + get state(): ReduxState { + return this.reduxStore.getState() + } +} + +export default Store.instance diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/auth.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/auth.ts new file mode 100644 index 0000000000..b4551d051f --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/auth.ts @@ -0,0 +1,80 @@ +import reducer, { defaultState as getDefaultState } from '../auth' +import { ActionType } from '../../types/core' +import ActionTypes from '../../constants/action-types' + +const defaultState = getDefaultState() + +describe('auth reducer', () => { + it('should return default state if action not matched', () => { + const newState = reducer(undefined, { + type: 'UNKNOWN' as ActionType, + data: undefined, + }) + expect(newState).toEqual(defaultState) + }) + + it('authLogin', () => { + const newState = reducer(undefined, { + type: ActionTypes.AUTH_LOGIN as ActionType, + data: null, + }) + const expected = { + ...defaultState, + error: false, + } + expect(newState).toEqual(expected) + }) + + it('authLoginSuccess', () => { + const data = { userName: '' } + const newState = reducer(undefined, { + type: ActionTypes.AUTH_LOGIN_SUCCESS as ActionType, + data, + }) + const expected = { + ...defaultState, + error: false, + loginSession: data, + } + expect(newState).toEqual(expected) + }) + + it('authLoginFailure', () => { + const newState = reducer(undefined, { + type: ActionTypes.AUTH_LOGIN_FAILURE as ActionType, + data: null, + }) + const expected = { + ...defaultState, + error: true, + } + expect(newState).toEqual(expected) + }) + + it('authLogoutSuccess', () => { + const newState = reducer(undefined, { + type: ActionTypes.AUTH_LOGOUT_SUCCESS as ActionType, + data: null, + }) + const expected = defaultState + expect(newState).toEqual(expected) + }) + + it('authSetRefreshSession', () => { + const data = { + refreshToken: '', + userName: '', + loginType: 'CLIENT', + mode: 'WEB', + } + const newState = reducer(undefined, { + type: ActionTypes.AUTH_SET_REFRESH_SESSION as ActionType, + data, + }) + const expected = { + ...defaultState, + refreshSession: data, + } + expect(newState).toEqual(expected) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/authenticated.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/authenticated.ts new file mode 100644 index 0000000000..c8aa2452b4 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/authenticated.ts @@ -0,0 +1,46 @@ +import authenticatedReducer, { defaultState } from '../authenticated' +import { ActionType } from '../../types/core' +import ActionTypes from '../../constants/action-types' + +describe('authenticated reducer', () => { + it('should return default state if action not matched', () => { + const newState = authenticatedReducer(undefined, { type: 'UNKNOWN' as ActionType, data: undefined }) + expect(newState).toEqual(defaultState) + }) + + it('should set loading to true when AUTHENTICATED_LOADING action is called', () => { + const newState = authenticatedReducer(undefined, { + type: ActionTypes.AUTHENTICATED_LOADING as ActionType, + data: true, + }) + const expected = { + ...defaultState, + loading: true, + } + expect(newState).toEqual(expected) + }) + + it('should set approvals list data when AUTHENTICATED_RECEIVE_DATA action is called', () => { + const newState = authenticatedReducer(undefined, { + type: ActionTypes.AUTHENTICATED_RECEIVE_DATA as ActionType, + data: {}, + }) + const expected = { + ...defaultState, + authenticatedData: {}, + } + expect(newState).toEqual(expected) + }) + + it('should clear approvals list data when AUTHENTICATED_CLEAR_DATA action is called', () => { + const newState = authenticatedReducer(undefined, { + type: ActionTypes.AUTHENTICATED_CLEAR_DATA as ActionType, + data: null, + }) + const expected = { + ...defaultState, + authenticatedData: null, + } + expect(newState).toEqual(expected) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/error.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/error.ts new file mode 100644 index 0000000000..8244e3f611 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/__tests__/error.ts @@ -0,0 +1,83 @@ +import errorReducer, { defaultState, ErrorData } from '../error' +import { ActionType } from '../../types/core' +import ActionTypes from '../../constants/action-types' +import errorMessages from '../../constants/error-messages' + +describe('error reducer', () => { + it('should return default state if action not matched', () => { + const newState = errorReducer(undefined, { type: 'UNKNOWN' as ActionType, data: undefined }) + expect(newState).toEqual(defaultState) + }) + + it('should set a component error', () => { + const errorData = { + type: 'COMPONENT', + message: errorMessages.DEFAULT_COMPONENT_ERROR, + } as ErrorData + const newState = errorReducer(undefined, { + type: ActionTypes.ERROR_THROWN_COMPONENT as ActionType, + data: errorData, + }) + const expected = { + ...defaultState, + componentError: errorData, + } + expect(newState).toEqual(expected) + }) + + it('should clear a component error', () => { + const errorData = { + type: 'COMPONENT', + message: errorMessages.DEFAULT_COMPONENT_ERROR, + } as ErrorData + + const newState = errorReducer( + { ...defaultState, componentError: errorData }, + { + type: ActionTypes.ERROR_CLEARED_COMPONENT as ActionType, + data: null, + }, + ) + const expected = { + ...defaultState, + componentError: null, + } + expect(newState).toEqual(expected) + }) + + it('should set a server error', () => { + const errorData = { + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + } as ErrorData + const newState = errorReducer(undefined, { + type: ActionTypes.ERROR_THROWN_SERVER as ActionType, + data: errorData, + }) + const expected = { + ...defaultState, + serverError: errorData, + } + expect(newState).toEqual(expected) + }) + + it('should clear a server error', () => { + const errorData = { + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + } as ErrorData + + const newState = errorReducer( + { ...defaultState, serverError: errorData }, + { + type: ActionTypes.ERROR_CLEARED_SERVER as ActionType, + data: null, + }, + ) + const expected = { + ...defaultState, + serverError: null, + } + expect(newState).toEqual(expected) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/auth.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/auth.ts new file mode 100644 index 0000000000..0da6498c8a --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/auth.ts @@ -0,0 +1,62 @@ +import { Action } from '@/types/core' +import { isType } from '@/utils/actions' +import { authLogin, authLoginFailure, authLoginSuccess, authLogoutSuccess, authSetRefreshSession } from '@/actions/auth' +import { RefreshParams, LoginSession, getSessionCookie } from '@reapit/cognito-auth' +import { COOKIE_SESSION_KEY } from '../constants/api' + +export interface AuthState { + error: boolean + loginSession: LoginSession | null + refreshSession: RefreshParams | null +} + +export const defaultState = (): AuthState => { + const refreshSession = getSessionCookie(COOKIE_SESSION_KEY) + return { + error: false, + loginSession: null, + refreshSession, + } +} + +const authReducer = (state: AuthState = defaultState(), action: Action): AuthState => { + if (isType(action, authLogin)) { + return { + ...state, + error: false, + } + } + + if (isType(action, authLoginSuccess)) { + return { + ...state, + error: false, + loginSession: action.data, + } + } + + if (isType(action, authLoginFailure)) { + return { + ...state, + error: true, + } + } + + if (isType(action, authLogoutSuccess)) { + return { + ...defaultState(), + refreshSession: null, + } + } + + if (isType(action, authSetRefreshSession)) { + return { + ...state, + refreshSession: action.data, + } + } + + return state +} + +export default authReducer diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/authenticated.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/authenticated.ts new file mode 100644 index 0000000000..9e53c751de --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/authenticated.ts @@ -0,0 +1,54 @@ +import { Action } from '../types/core' +import { isType } from '../utils/actions' +import { + authenticatedLoading, + authenticatedReceiveData, + authenticatedClearData, + authenticatedRequestDataFailure, +} from '../actions/authenticated' + +export interface AuthenticatedState { + loading: boolean + authenticatedData: {} | null +} + +export const defaultState: AuthenticatedState = { + loading: false, + authenticatedData: null, +} + +const authenticatedReducer = (state: AuthenticatedState = defaultState, action: Action): AuthenticatedState => { + if (isType(action, authenticatedLoading)) { + return { + ...state, + loading: action.data, + } + } + + if (isType(action, authenticatedReceiveData)) { + return { + ...state, + loading: false, + authenticatedData: action.data || null, + } + } + + if (isType(action, authenticatedClearData)) { + return { + ...state, + loading: false, + authenticatedData: action.data, + } + } + + if (isType(action, authenticatedRequestDataFailure)) { + return { + ...state, + loading: false, + } + } + + return state +} + +export default authenticatedReducer diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/error.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/error.ts new file mode 100644 index 0000000000..a97165d4b9 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/reducers/error.ts @@ -0,0 +1,39 @@ +import { Action } from '../types/core' +import { isType } from '../utils/actions' +import { errorClearedComponent, errorClearedServer, errorThrownComponent, errorThrownServer } from '../actions/error' + +export interface ErrorData { + readonly status?: number + readonly message?: string + readonly type: 'COMPONENT' | 'SERVER' +} + +export interface ErrorState { + componentError: ErrorData | null + serverError: ErrorData | null +} + +export const defaultState: ErrorState = { + componentError: null, + serverError: null, +} + +const errorReducer = (state: ErrorState = defaultState, action: Action): ErrorState => { + if (isType(action, errorClearedServer) || isType(action, errorThrownServer)) { + return { + ...state, + serverError: action.data, + } + } + + if (isType(action, errorClearedComponent) || isType(action, errorThrownComponent)) { + return { + ...state, + componentError: action.data, + } + } + + return state +} + +export default errorReducer diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/auth.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/auth.ts new file mode 100644 index 0000000000..5e8614d50f --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/auth.ts @@ -0,0 +1,90 @@ +import authSagas, { doLogin, doLogout, loginListen, logoutListen } from '../auth' +import ActionTypes from '../../constants/action-types' +import { put, all, takeLatest, call } from '@redux-saga/core/effects' +import { LoginParams, setUserSession, removeSession, redirectToLogout } from '@reapit/cognito-auth' +import { Action, ActionType } from '@/types/core' +import { mockLoginSession } from '../../utils/__mocks__/session' +import { authLoginSuccess, authLoginFailure } from '@/actions/auth' +import { COOKIE_SESSION_KEY } from '../../constants/api' + +jest.mock('../../utils/session') +jest.mock('../../core/store.ts') +jest.mock('../../core/router', () => ({ + history: { + push: jest.fn(), + }, +})) + +jest.mock('@reapit/cognito-auth', () => ({ + setUserSession: jest.fn(), + removeSession: jest.fn(), + redirectToLogout: jest.fn(), +})) + +describe('auth sagas', () => { + describe('login submit', () => { + const loginParams: LoginParams = { + loginType: 'CLIENT', + userName: 'bob@acme.com', + password: 'xxxxxx', + mode: 'WEB', + cognitoClientId: '123', + } + const action: Action = { + type: ActionTypes.AUTH_LOGIN as ActionType, + data: loginParams, + } + + test('login success', () => { + const gen = doLogin(action) + expect(gen.next(mockLoginSession).value).toEqual(call(setUserSession, loginParams)) + expect(gen.next(mockLoginSession).value).toEqual(put(authLoginSuccess(mockLoginSession))) + expect(gen.next().done).toBe(true) + }) + + test('login fail', () => { + const gen = doLogin(action) + expect(gen.next(null).value).toEqual(call(setUserSession, loginParams)) + expect(gen.next(null).value).toEqual(put(authLoginFailure())) + expect(gen.next().done).toBe(true) + }) + }) + + describe('authLogout', () => { + it('should redirect to login page', () => { + const gen = doLogout() + expect(gen.next().value).toEqual(call(removeSession, COOKIE_SESSION_KEY)) + expect(gen.next().value).toEqual( + call(redirectToLogout, window.reapit.config.cognitoClientId, `${window.location.origin}/login`), + ) + expect(gen.next().done).toBe(true) + }) + }) + + describe('authLoginListen', () => { + it('should trigger login action', () => { + const gen = loginListen() + + expect(gen.next().value).toEqual(takeLatest(ActionTypes.AUTH_LOGIN, doLogin)) + expect(gen.next().done).toBe(true) + }) + }) + + describe('authLogoutListen', () => { + it('should trigger logout action', () => { + const gen = logoutListen() + + expect(gen.next().value).toEqual(takeLatest(ActionTypes.AUTH_LOGOUT, doLogout)) + expect(gen.next().done).toBe(true) + }) + }) + + describe('itemSagas', () => { + it('should wait for login and logout action get called', () => { + const gen = authSagas() + + expect(gen.next().value).toEqual(all([loginListen(), logoutListen()])) + expect(gen.next().done).toBe(true) + }) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/authenticated.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/authenticated.ts new file mode 100644 index 0000000000..da7be73bb4 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/__tests__/authenticated.ts @@ -0,0 +1,41 @@ +import authenticatedSagas, { authenticatedDataFetch, authenticatedDataListen } from '../authenticated' +import ActionTypes from '@/constants/action-types' +import { put, takeLatest, all, fork } from '@redux-saga/core/effects' +import { authenticatedLoading, authenticatedReceiveData } from '@/actions/authenticated' +import { cloneableGenerator } from '@redux-saga/testing-utils' +import { Action } from '@/types/core' + +describe('authenticated fetch data', () => { + const gen = cloneableGenerator(authenticatedDataFetch)() + + expect(gen.next().value).toEqual(put(authenticatedLoading(true))) + expect(gen.next().value).toEqual(true) + + test('api call success', () => { + const clone = gen.clone() + expect(clone.next().value).toEqual(put(authenticatedReceiveData({}))) + expect(clone.next().done).toBe(true) + }) +}) + +describe('authenticated sagas', () => { + describe('authenticatedListen', () => { + it('should request data when called', () => { + const gen = authenticatedDataListen() + + expect(gen.next().value).toEqual( + takeLatest>(ActionTypes.AUTHENTICATED_REQUEST_DATA, authenticatedDataFetch), + ) + expect(gen.next().done).toBe(true) + }) + }) + + describe('authenticatedSagas', () => { + it('should listen data request', () => { + const gen = authenticatedSagas() + + expect(gen.next().value).toEqual(all([fork(authenticatedDataListen)])) + expect(gen.next().done).toBe(true) + }) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/auth.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/auth.ts new file mode 100644 index 0000000000..1fe9f1e0ed --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/auth.ts @@ -0,0 +1,44 @@ +import { takeLatest, put, call, all } from '@redux-saga/core/effects' +import { Action } from '@/types/core.ts' +import ActionTypes from '@/constants/action-types' +import { authLoginSuccess, authLoginFailure } from '@/actions/auth' +import { LoginParams, LoginSession, setUserSession, removeSession, redirectToLogout } from '@reapit/cognito-auth' +import { COOKIE_SESSION_KEY } from '../constants/api' + +export const doLogin = function*({ data }: Action) { + try { + const loginSession: LoginSession | null = yield call(setUserSession, data) + + if (loginSession) { + yield put(authLoginSuccess(loginSession)) + } else { + yield put(authLoginFailure()) + } + } catch (err) { + console.error(err.message) + yield put(authLoginFailure()) + } +} + +export const doLogout = function*() { + try { + yield call(removeSession, COOKIE_SESSION_KEY) + yield call(redirectToLogout, window.reapit.config.cognitoClientId, `${window.location.origin}/login`) + } catch (err) { + console.error(err.message) + } +} + +export const loginListen = function*() { + yield takeLatest(ActionTypes.AUTH_LOGIN, doLogin) +} + +export const logoutListen = function*() { + yield takeLatest(ActionTypes.AUTH_LOGOUT, doLogout) +} + +const authSaga = function*() { + yield all([loginListen(), logoutListen()]) +} + +export default authSaga diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/authenticated.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/authenticated.ts new file mode 100644 index 0000000000..6fd515eb0d --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/sagas/authenticated.ts @@ -0,0 +1,39 @@ +import { + authenticatedLoading, + authenticatedReceiveData, + authenticatedRequestDataFailure, +} from '../actions/authenticated' +import { put, fork, takeLatest, all } from '@redux-saga/core/effects' +import ActionTypes from '../constants/action-types' +import { errorThrownServer } from '../actions/error' +import errorMessages from '../constants/error-messages' +import { Action } from '@/types/core' + +export const authenticatedDataFetch = function*() { + yield put(authenticatedLoading(true)) + + try { + const response = yield true // Your fetch module here + + yield put(authenticatedReceiveData({ data: response })) + } catch (err) { + console.error(err.message) + yield put(authenticatedRequestDataFailure()) + yield put( + errorThrownServer({ + type: 'SERVER', + message: errorMessages.DEFAULT_SERVER_ERROR, + }), + ) + } +} + +export const authenticatedDataListen = function*() { + yield takeLatest>(ActionTypes.AUTHENTICATED_REQUEST_DATA, authenticatedDataFetch) +} + +const authenticatedSagas = function*() { + yield all([fork(authenticatedDataListen)]) +} + +export default authenticatedSagas diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/selectors/auth.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/selectors/auth.ts new file mode 100644 index 0000000000..342b9a9bf6 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/selectors/auth.ts @@ -0,0 +1,17 @@ +import { ReduxState } from '@/types/core' + +export const selectUserCode = (state: ReduxState) => { + return state?.auth?.loginSession?.loginIdentity?.userCode || '' +} + +export const selectUserLoginStatus = (state: ReduxState) => { + return !!state?.auth?.refreshSession || !!state?.auth?.loginSession +} + +export const checkIsDesktopMode = (state: ReduxState) => { + return state?.auth?.refreshSession?.mode === 'DESKTOP' +} + +export const checkIsWebMode = (state: ReduxState) => { + return state?.auth?.refreshSession?.mode === 'WEB' +} diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/styles/index.css b/packages/react-app-scaffolder/app/templates/redux-internal/src/styles/index.css new file mode 100644 index 0000000000..f1323ff4b3 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/styles/index.css @@ -0,0 +1,6 @@ +@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap'); +@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap'); + + + + diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/types/core.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/types/core.ts new file mode 100644 index 0000000000..1d4158730c --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/types/core.ts @@ -0,0 +1,42 @@ +import Routes from '../constants/routes' +import ActionTypes from '../constants/action-types' +import { ErrorState } from '../reducers/error' +import { AuthenticatedState } from '@/reducers/authenticated' +import { AuthState } from '@/reducers/auth' + +export interface Action { + readonly type: ActionType + readonly data: T +} + +export interface ActionCreator { + readonly type: string + (data: T): Action +} + +export interface StringMap { + [key: string]: string +} + +export type PartialRecord = { [P in K]?: T } + +export type RouteValue = keyof typeof Routes + +export type ActionType = keyof typeof ActionTypes + +export type FormState = 'PENDING' | 'DONE' | 'SUBMITTING' | 'ERROR' | 'SUCCESS' + +export interface FetcherParams { + method: 'GET' | 'POST' | 'PUT' | 'DELETE' + api: string + url: string + headers: StringMap + isPrivate?: boolean + body?: T +} + +export interface ReduxState { + error: ErrorState + authenticated: AuthenticatedState + auth: AuthState +} diff --git a/packages/react-app-scaffolder/app/templates/redux/src/types/global.d.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/types/global.d.ts similarity index 100% rename from packages/react-app-scaffolder/app/templates/redux/src/types/global.d.ts rename to packages/react-app-scaffolder/app/templates/redux-internal/src/types/global.d.ts diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/types/index.d.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/types/index.d.ts new file mode 100644 index 0000000000..5940037217 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/types/index.d.ts @@ -0,0 +1,14 @@ +/** + * Gobal override types to make the compiler happy + */ + +declare namespace yargs { + export type Arguments = any +} + +declare module '*.css' +declare module '*.scss' +declare module '*.scss?mod' +declare module '*.sass' +declare module '*.jpg' +declare module '*.png' diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__mocks__/session.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__mocks__/session.ts new file mode 100644 index 0000000000..7e7050905f --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__mocks__/session.ts @@ -0,0 +1,17 @@ +import { LoginSession } from '@reapit/cognito-auth' + +export const mockLoginSession = { + userName: 'bob@acme.com', + accessTokenExpiry: 2, + loginType: 'CLIENT', + refreshToken: 'MOCK_REFRESH_TOKEN', + accessToken: 'MOCK_ACCESS_TOKEN', + idToken: 'MOCK_ID_TOKEN', + loginIdentity: { + developerId: 'SOME_DEV_ID', + clientId: 'SOME_CLIENT_ID', + adminId: 'SOME_ADMIN_ID', + }, +} as LoginSession + +export const getAccessToken = jest.fn() diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/actions.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/actions.ts new file mode 100644 index 0000000000..31a48fe095 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/actions.ts @@ -0,0 +1,27 @@ +import { actionCreator, isType } from '../actions' +import ActionTypes from '../../constants/action-types' +import { authenticatedLoading } from '../../actions/authenticated' +import { Action } from '../../types/core' + +describe('actions utils', () => { + describe('actionCreator', () => { + it('should create an action of the correct type', () => { + const loadingAction = { data: true, type: 'AUTHENTICATED_LOADING' } + expect(actionCreator(ActionTypes.AUTHENTICATED_LOADING)(true)).toEqual(loadingAction) + }) + }) + + describe('isType', () => { + it('should return true if actions are equal', () => { + const loadingAction: Action = { data: true, type: 'AUTHENTICATED_LOADING' } + + expect(isType(loadingAction, authenticatedLoading)).toBe(true) + }) + + it('should return false if actions are not equal', () => { + const anotherAction: Action = { data: true, type: 'AUTHENTICATED_RECEIVE_DATA' } + + expect(isType(anotherAction, authenticatedLoading)).toBe(false) + }) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/route-dispatcher.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/route-dispatcher.ts new file mode 100644 index 0000000000..137372de91 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/route-dispatcher.ts @@ -0,0 +1,16 @@ +import routeDispatcher from '../route-dispatcher' +import store from '../../core/store' +import Routes from '../../constants/routes' +import { RouteValue } from '../../types/core' +import { authenticatedRequestData } from '../../actions/authenticated' + +jest.mock('../../core/store') +jest.mock('../../sagas/authenticated') +jest.mock('@/utils/session') + +describe('routeDispatcher', () => { + it('should dispatch to authenticatedRequestData for the home route', async () => { + await routeDispatcher(Routes.HOME as RouteValue) + expect(store.dispatch).toHaveBeenCalledWith(authenticatedRequestData()) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/session.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/session.ts new file mode 100644 index 0000000000..6a86921e3c --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/__tests__/session.ts @@ -0,0 +1,55 @@ +import { getAccessToken } from '../session' +import { authLogout, authLoginSuccess } from '@/actions/auth' +import { getSession, LoginSession, RefreshParams } from '@reapit/cognito-auth' +import { COOKIE_SESSION_KEY } from '@/constants/api' + +import store from '@/core/store' + +jest.mock('@/actions/auth') +jest.mock('@/core/store', () => ({ + dispatch: jest.fn(), + state: { + auth: {}, + }, +})) +jest.mock('@reapit/cognito-auth', () => ({ + getSession: jest.fn(), +})) + +describe('session utils', () => { + describe('getAccessToken', () => { + it('should correctly return null when sessions are not available', async () => { + store.state.auth.loginSession = null + store.state.auth.refreshSession = null + ;(getSession as jest.Mock).mockResolvedValueOnce(null) + const returnValue = await getAccessToken() + expect(getSession).toHaveBeenCalledWith( + store.state.auth.loginSession, + store.state.auth.refreshSession, + COOKIE_SESSION_KEY, + ) + expect(store.dispatch).toHaveBeenCalledWith(authLogout()) + expect(returnValue).toBeNull() + }) + + it('should correctly return value', async () => { + store.state.auth.loginSession = {} as LoginSession + store.state.auth.refreshSession = {} as RefreshParams + const mockGetSessionReturnValue = { accessToken: 'accessToken' } as LoginSession + ;(getSession as jest.Mock).mockResolvedValueOnce(mockGetSessionReturnValue) + const returnValue = await getAccessToken() + + expect(getSession).toHaveBeenCalledWith( + store.state.auth.loginSession, + store.state.auth.refreshSession, + COOKIE_SESSION_KEY, + ) + expect(store.dispatch).toHaveBeenCalledWith(authLoginSuccess(mockGetSessionReturnValue)) + expect(returnValue).toEqual(mockGetSessionReturnValue.accessToken) + }) + + afterEach(() => { + jest.resetAllMocks() + }) + }) +}) diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/actions.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/actions.ts new file mode 100644 index 0000000000..553e24424c --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/actions.ts @@ -0,0 +1,12 @@ +import { ActionCreator, Action } from '../types/core' + +export const actionCreator = (type: string): ActionCreator => + Object.assign((data: T): any => ({ type, data }), { type }) + +/* This is a type guard used to strongly type reducers see: https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#user-defined-type-guard-functions + * you will note the value + * FYI, does NOT work if reducer is a switch statement - TS not smart enough to infer type of data + * hence use of conditionals in reducers + */ +export const isType = (action: Action, actionCreator: ActionCreator): action is Action => + action.type === actionCreator.type diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/route-dispatcher.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/route-dispatcher.ts new file mode 100644 index 0000000000..f385ce2bd3 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/route-dispatcher.ts @@ -0,0 +1,19 @@ +import { RouteValue } from '@/types/core' +import { getAccessToken } from '@/utils/session' +import store from '@/core/store' +import Routes from '@/constants/routes' +import { authenticatedRequestData } from '@/actions/authenticated' + +const routeDispatcher = async (route: RouteValue) => { + await getAccessToken() + + switch (route) { + case Routes.HOME: + store.dispatch(authenticatedRequestData()) + break + default: + console.error('Route not found, nothing to fetch') + } +} + +export default routeDispatcher diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/session.ts b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/session.ts new file mode 100644 index 0000000000..f770dbff8f --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/src/utils/session.ts @@ -0,0 +1,18 @@ +import store from '@/core/store' +import { authLoginSuccess, authLogout } from '@/actions/auth' +import { getSession } from '@reapit/cognito-auth' +import { COOKIE_SESSION_KEY } from '../constants/api' + +export const getAccessToken = async (): Promise => { + const { loginSession, refreshSession } = store.state.auth + + const session = await getSession(loginSession, refreshSession, COOKIE_SESSION_KEY) + + if (session) { + store.dispatch(authLoginSuccess(session)) + return session.accessToken + } + + store.dispatch(authLogout()) + return null +} diff --git a/packages/react-app-scaffolder/app/templates/redux-internal/tsconfig.json b/packages/react-app-scaffolder/app/templates/redux-internal/tsconfig.json new file mode 100644 index 0000000000..1047af33b1 --- /dev/null +++ b/packages/react-app-scaffolder/app/templates/redux-internal/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@/*": [ + "src/*" + ], + "@reapit/cognito-auth": [ + "../cognito-auth/src" + ], + "@reapit/elements": [ + "../elements/src" + ], + "@reapit/elements/*": [ + "../elements/src/*" + ] + } + }, + "include": [ + "src" + ], + "exclude": [ + "public", + "dist", + "./webpack.config.js", + "node_modules", + "src/tests/coverage" + ] +} diff --git a/packages/react-app-scaffolder/package.json b/packages/react-app-scaffolder/package.json index 34ce250676..98d400134e 100644 --- a/packages/react-app-scaffolder/package.json +++ b/packages/react-app-scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@reapit/generator-react-app-scaffolder", - "version": "0.0.32", + "version": "1.0.0-alpha.1", "description": "An opinionated gnerator for scaffolding TypeScript React Redux apps", "keywords": [ "yeoman-generator" @@ -23,12 +23,8 @@ "scaffold": "yo ./app --force" }, "dependencies": { - "yeoman-generator": "^4.0.1", + "yeoman-generator": "^4.11.0", "yo": "^3.1.1", - "yosay": "^2.0.2", - "change-case": "^4.1.1" - }, - "devDependencies": { - "raw-loader": "^3.1.0" + "yosay": "^2.0.2" } } diff --git a/yarn.lock b/yarn.lock index e996c5c909..3bfe4b976a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9317,15 +9317,6 @@ capability@^0.2.5: resolved "https://registry.yarnpkg.com/capability/-/capability-0.2.5.tgz#51ad87353f1936ffd77f2f21c74633a4dea88801" integrity sha1-Ua2HNT8ZNv/Xfy8hx0YzpN6oiAE= -capital-case@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.3.tgz#339bd77e8fab6cf75111d4fca509b3edf7c117c8" - integrity sha512-OlUSJpUr7SY0uZFOxcwnDOU7/MpHlKTZx2mqnDYQFrDudXLFm0JJ9wr/l4csB+rh2Ug0OPuoSO53PqiZBqno9A== - dependencies: - no-case "^3.0.3" - tslib "^1.10.0" - upper-case-first "^2.0.1" - capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -9442,24 +9433,6 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -change-case@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.1.tgz#d5005709275952e7963fed7b91e4f9fdb6180afa" - integrity sha512-qRlUWn/hXnX1R1LBDF/RelJLiqNjKjUqlmuBVSEIyye8kq49CXqkZWKmi8XeUAdDXWFOcGLUMZ+aHn3Q5lzUXw== - dependencies: - camel-case "^4.1.1" - capital-case "^1.0.3" - constant-case "^3.0.3" - dot-case "^3.0.3" - header-case "^2.0.3" - no-case "^3.0.3" - param-case "^3.0.3" - pascal-case "^3.1.1" - path-case "^3.0.3" - sentence-case "^3.0.3" - snake-case "^3.0.3" - tslib "^1.10.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -10324,15 +10297,6 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -constant-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.3.tgz#ac910a99caf3926ac5112f352e3af599d8c5fc0a" - integrity sha512-FXtsSnnrFYpzDmvwDGQW+l8XK3GV1coLyBN0eBz16ZUzGaZcT2ANVCJmLeuw2GQgxKHQIe9e0w2dzkSfaRlUmA== - dependencies: - no-case "^3.0.3" - tslib "^1.10.0" - upper-case "^2.0.1" - constantinople@^3.0.1, constantinople@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.2.tgz#d45ed724f57d3d10500017a7d3a889c1381ae647" @@ -15433,14 +15397,6 @@ he@1.2.x, he@^1.1.0, he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -header-case@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.3.tgz#8a7407d16edfd5c970f8ebb116e6383f855b5a72" - integrity sha512-LChe/V32mnUQnTwTxd3aAlNMk8ia9tjCDb/LjYtoMrdAPApxLB+azejUk5ERZIZdIqvinwv6BAUuFXH/tQPdZA== - dependencies: - capital-case "^1.0.3" - tslib "^1.10.0" - highlight.js@~9.13.0: version "9.13.1" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" @@ -19898,6 +19854,23 @@ mem-fs-editor@^6.0.0: through2 "^3.0.1" vinyl "^2.2.0" +mem-fs-editor@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-7.0.1.tgz#e0797802b7797acf43ef3c511f3d3ad5ea765783" + integrity sha512-eD8r4/d2ayp9HHIgBPHB6Ds0ggA8F9cf9HxcNtbqrwqJXfIDrOSMG5K4fV3+Ib3B+HIdrWqkeDDDvrO7i9EbvQ== + dependencies: + commondir "^1.0.1" + deep-extend "^0.6.0" + ejs "^3.0.1" + glob "^7.1.4" + globby "^9.2.0" + isbinaryfile "^4.0.0" + mkdirp "^1.0.0" + multimatch "^4.0.0" + rimraf "^3.0.0" + through2 "^3.0.1" + vinyl "^2.2.0" + mem-fs@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.2.0.tgz#5f29b2d02a5875cd14cd836c388385892d556cde" @@ -20370,7 +20343,7 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" -mkdirp@*, mkdirp@1.x, mkdirp@^1.0.4, mkdirp@~1.0.3: +mkdirp@*, mkdirp@1.x, mkdirp@^1.0.0, mkdirp@^1.0.4, mkdirp@~1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -22164,14 +22137,6 @@ path-browserify@0.0.1: resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== -path-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.3.tgz#d48119aed52c4712e036ca40c6b15984f909554f" - integrity sha512-UMFU6UETFpCNWbIWNczshPrnK/7JAXBP2NYw80ojElbQ2+JYxdqWDBkvvqM93u4u6oLmuJ/tPOf2tM8KtXv4eg== - dependencies: - dot-case "^3.0.3" - tslib "^1.10.0" - path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -25231,15 +25196,6 @@ send@0.17.1, send@latest: range-parser "~1.2.1" statuses "~1.5.0" -sentence-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.3.tgz#47576e4adff7abf42c63c815b0543c9d2f85a930" - integrity sha512-ZPr4dgTcNkEfcGOMFQyDdJrTU9uQO1nb1cjf+nuzb6FxgMDgKddZOM29qEsB7jvsZSMruLRcL2KfM4ypKpa0LA== - dependencies: - no-case "^3.0.3" - tslib "^1.10.0" - upper-case-first "^2.0.1" - seq-queue@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" @@ -25793,14 +25749,6 @@ smart-buffer@^4.1.0: resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== -snake-case@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.3.tgz#c598b822ab443fcbb145ae8a82c5e43526d5bbee" - integrity sha512-WM1sIXEO+rsAHBKjGf/6R1HBBcgbncKS08d2Aqec/mrDSpU80SiOU41hO7ny6DToHSyrlwTYzQBIK1FPSx4Y3Q== - dependencies: - dot-case "^3.0.3" - tslib "^1.10.0" - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -28714,25 +28662,11 @@ upper-case-first@^1.1.0: dependencies: upper-case "^1.1.1" -upper-case-first@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.1.tgz#32ab436747d891cc20ab1e43d601cb4d0a7fbf4a" - integrity sha512-105J8XqQ+9RxW3l9gHZtgve5oaiR9TIwvmZAMAIZWRHe00T21cdvewKORTlOJf/zXW6VukuTshM+HXZNWz7N5w== - dependencies: - tslib "^1.10.0" - upper-case@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= -upper-case@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.1.tgz#6214d05e235dc817822464ccbae85822b3d8665f" - integrity sha512-laAsbea9SY5osxrv7S99vH9xAaJKrw5Qpdh4ENRLcaxipjKsiaBwiAsxfa8X5mObKNTQPsupSq0J/VIxsSJe3A== - dependencies: - tslib "^1.10.0" - uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -30293,7 +30227,41 @@ yeoman-environment@^2.4.0, yeoman-environment@^2.9.5: untildify "^3.0.3" yeoman-generator "^4.8.2" -yeoman-generator@^4.0.1, yeoman-generator@^4.8.2: +yeoman-generator@^4.11.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-4.11.0.tgz#c9e2fab77f17a4d7acff571f31e002bc066ed6a8" + integrity sha512-++t6t2Z6HjL5F1/UM7+uNvGknKmQdF8tstJx8WKzsUSEpB+19kLVtapSfQIh9uWqm0L59fLWDzUui//WXoynPw== + dependencies: + async "^2.6.2" + chalk "^2.4.2" + cli-table "^0.3.1" + cross-spawn "^6.0.5" + dargs "^6.1.0" + dateformat "^3.0.3" + debug "^4.1.1" + diff "^4.0.1" + error "^7.0.2" + find-up "^3.0.0" + github-username "^3.0.0" + istextorbinary "^2.5.1" + lodash "^4.17.11" + make-dir "^3.0.0" + mem-fs-editor "^7.0.1" + minimist "^1.2.5" + pretty-bytes "^5.2.0" + read-chunk "^3.2.0" + read-pkg-up "^5.0.0" + rimraf "^2.6.3" + run-async "^2.0.0" + semver "^7.2.1" + shelljs "^0.8.3" + text-table "^0.2.0" + through2 "^3.0.1" + optionalDependencies: + grouped-queue "^1.1.0" + yeoman-environment "^2.9.5" + +yeoman-generator@^4.8.2: version "4.10.1" resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-4.10.1.tgz#82853f55856ba14f180ab6c6a70acd89b11c956b" integrity sha512-QgbtHSaqBAkyJJM0heQUhT63ubCt34NBFMEBydOBUdAuy8RBvGSzeqVBSZOjdh1tSLrwWXlU3Ck6y14awinF6Q== From d480d507eba76abda0b6b5f2d92b86a5e0075cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C6=B0=E1=BB=9Dng=20An?= Date: Mon, 13 Jul 2020 16:21:20 +0700 Subject: [PATCH 3/4] feat: #2013 add download now option when subscribing on developer portal (#2044) --- .../__snapshots__/success-content.tsx.snap | 23 +++++++++++++------ .../__tests__/success-content.tsx | 13 ++++++++++- .../success-content.tsx | 15 +++++++++--- .../src/tests/badges/badge-branches.svg | 2 +- .../src/tests/badges/badge-functions.svg | 2 +- .../src/tests/badges/badge-lines.svg | 2 +- .../src/tests/badges/badge-statements.svg | 2 +- 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/__snapshots__/success-content.tsx.snap b/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/__snapshots__/success-content.tsx.snap index 112aedc5e0..c10aa6e5e3 100644 --- a/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/__snapshots__/success-content.tsx.snap +++ b/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/__snapshots__/success-content.tsx.snap @@ -34,13 +34,22 @@ exports[`SuccessContent should match snapshot 1`] = ` /> - CLOSE - + + + CLOSE + + + DOWNLOAD NOW + + } /> diff --git a/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/success-content.tsx b/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/success-content.tsx index 5395cef13c..a32b61fbf2 100644 --- a/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/success-content.tsx +++ b/packages/developer-portal/src/components/ui/developer-edition-modal/__tests__/success-content.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { shallow } from 'enzyme' -import { SuccessContent } from '../success-content' +import { SuccessContent, handleDownload } from '../success-content' import { developerStub } from '@/sagas/__stubs__/developer' describe('SuccessContent', () => { @@ -9,3 +9,14 @@ describe('SuccessContent', () => { expect(wrapper).toMatchSnapshot() }) }) + +describe('handleDownload', () => { + it('should open download link', () => { + const downloadURL = 'downloadURL' + window.reapit.config.developerEditionDownloadUrl = downloadURL + window.open = jest.fn() + + handleDownload() + expect(window.open).toBeCalledWith(downloadURL, '_self') + }) +}) diff --git a/packages/developer-portal/src/components/ui/developer-edition-modal/success-content.tsx b/packages/developer-portal/src/components/ui/developer-edition-modal/success-content.tsx index 78daad4f0e..fd0744772a 100644 --- a/packages/developer-portal/src/components/ui/developer-edition-modal/success-content.tsx +++ b/packages/developer-portal/src/components/ui/developer-edition-modal/success-content.tsx @@ -8,6 +8,10 @@ export type SuccessContentProps = Pick & { developer?: DeveloperModel } +export const handleDownload = () => { + window.open(window.reapit.config.developerEditionDownloadUrl, '_self') +} + export const SuccessContent: React.FC = ({ developer, afterClose }) => { if (!developer) return null @@ -44,9 +48,14 @@ export const SuccessContent: React.FC = ({ developer, after /> - CLOSE - + <> + + + } /> diff --git a/packages/developer-portal/src/tests/badges/badge-branches.svg b/packages/developer-portal/src/tests/badges/badge-branches.svg index 828389066b..bc9049555a 100644 --- a/packages/developer-portal/src/tests/badges/badge-branches.svg +++ b/packages/developer-portal/src/tests/badges/badge-branches.svg @@ -1 +1 @@ -Coverage:branchesCoverage:branches69.97%69.97% \ No newline at end of file +Coverage:branchesCoverage:branches68.64%68.64% \ No newline at end of file diff --git a/packages/developer-portal/src/tests/badges/badge-functions.svg b/packages/developer-portal/src/tests/badges/badge-functions.svg index c306084d0c..c5dbd4c6b6 100644 --- a/packages/developer-portal/src/tests/badges/badge-functions.svg +++ b/packages/developer-portal/src/tests/badges/badge-functions.svg @@ -1 +1 @@ -Coverage:functionsCoverage:functions81.82%81.82% \ No newline at end of file +Coverage:functionsCoverage:functions79.36%79.36% \ No newline at end of file diff --git a/packages/developer-portal/src/tests/badges/badge-lines.svg b/packages/developer-portal/src/tests/badges/badge-lines.svg index 2a4ce36294..ddec17d912 100644 --- a/packages/developer-portal/src/tests/badges/badge-lines.svg +++ b/packages/developer-portal/src/tests/badges/badge-lines.svg @@ -1 +1 @@ -Coverage:linesCoverage:lines91.2%91.2% \ No newline at end of file +Coverage:linesCoverage:lines89.8%89.8% \ No newline at end of file diff --git a/packages/developer-portal/src/tests/badges/badge-statements.svg b/packages/developer-portal/src/tests/badges/badge-statements.svg index 5c999ee2ea..9b15b3d0ec 100644 --- a/packages/developer-portal/src/tests/badges/badge-statements.svg +++ b/packages/developer-portal/src/tests/badges/badge-statements.svg @@ -1 +1 @@ -Coverage:statementsCoverage:statements90.2%90.2% \ No newline at end of file +Coverage:statementsCoverage:statements88.79%88.79% \ No newline at end of file From ab629ac4ff36a1abab6d3830c6db33e075e83a50 Mon Sep 17 00:00:00 2001 From: Vu Nguyen Date: Mon, 13 Jul 2020 16:32:20 +0700 Subject: [PATCH 4/4] feat: #1917 purge unused code from all remaining pages in dev portal (#2046) --- ...developer-submit-app-successfully.tsx.snap | 77 ------------------- .../developer-submit-app-successfully.tsx | 17 ---- .../__snapshots__/api-docs.test.tsx.snap} | 0 .../__tests__/api-docs.test.tsx} | 2 +- .../pages/{ => api-docs}/api-docs.tsx | 8 +- .../src/components/pages/api-docs/index.ts | 2 + .../app-detail/__tests__/app-detail.test.tsx | 2 +- .../__tests__/app-management.test.tsx | 2 +- .../__test__/authentication.test.tsx | 2 +- .../pages/authentication/authentication.tsx | 4 +- .../__styles__/pricing-tile.tsx | 0 .../__snapshots__/desktop.test.tsx.snap} | 0 .../__tests__/desktop.test.tsx} | 2 +- .../desktop.tsx} | 2 +- .../src/components/pages/desktop/index.ts | 1 + .../pages/developer-desktop/index.ts | 1 - .../developer-submit-app-successfully.tsx | 70 ----------------- ...cy-cloud-integration-section.test.tsx.snap | 0 .../authentication-flow-section.test.tsx.snap | 0 .../developer-edit-app.test.tsx.snap | 0 .../general-information-section.test.tsx.snap | 0 .../marketplace-status-section.test.tsx.snap | 0 .../permission-section.test.tsx.snap | 0 .../redirect-uri-section.test.tsx.snap | 0 .../upload-image-section.test.tsx.snap | 0 .../agency-cloud-integration-section.test.tsx | 0 .../authentication-flow-section.test.tsx | 0 .../__tests__}/developer-edit-app.test.tsx | 0 .../general-information-section.test.tsx | 0 .../marketplace-status-section.test.tsx | 0 .../__tests__}/permission-section.test.tsx | 0 .../__tests__}/redirect-uri-section.test.tsx | 0 .../__tests__}/upload-image-section.test.tsx | 0 .../agency-cloud-integration-section.tsx | 0 .../authentication-flow-section.tsx | 0 .../developer-edit-app.tsx | 0 .../form-schema/form-fields.ts | 0 .../form-schema/validation-schema.ts | 0 .../general-information-section.tsx | 0 .../{developer-edit-app => edit-app}/index.ts | 0 .../marketplace-status-section.tsx | 0 .../permission-section.tsx | 0 .../redirect-uri-section.tsx | 0 .../upload-image-section.tsx | 0 .../__snapshots__/help.test.tsx.snap} | 0 .../__tests__/help.test.tsx} | 12 +-- .../{developer-help.tsx => help/help.tsx} | 4 +- .../src/components/pages/help/index.ts | 2 + .../register-confirm.test.tsx.snap} | 0 .../__tests__/register-confirm.test.tsx} | 0 .../pages/register-confirm/index.ts | 2 + .../register-confirm.tsx | 0 .../__snapshots__/settings.test.tsx.snap | 2 +- .../settings/__tests__/settings.test.tsx | 6 +- .../__snapshots__/swagger.test.tsx.snap} | 0 .../__tests__/swagger.test.tsx} | 2 +- .../src/components/pages/swagger/index.ts | 2 + .../pages/{ => swagger}/swagger.tsx | 7 +- .../pages/webhooks/webhook-test-modal.tsx | 2 +- .../components/pages/webhooks/webhooks.tsx | 2 +- .../__snapshots__/welcome.test.tsx.snap} | 0 .../__tests__/welcome.test.tsx} | 2 +- .../src/components/pages/welcome/index.ts | 2 + .../welcome.tsx} | 6 +- .../ui/__tests__/help-item-list.tsx | 3 +- .../src/components/ui/menu.tsx | 10 +-- .../steps/step-before-you-start.tsx | 5 +- .../developer-portal/src/constants/routes.ts | 18 ++--- .../__tests__/__snapshots__/router.tsx.snap | 14 ++++ .../src/core/private-route-wrapper.tsx | 2 +- packages/developer-portal/src/core/router.tsx | 65 +++++----------- .../src/tests/cypress/hooks/login.ts | 2 +- .../cypress/pages/developer-settings-page.ts | 8 +- .../src/utils/__tests__/auth-route.ts | 8 +- .../developer-portal/src/utils/auth-route.ts | 6 +- .../form/settings-contact-information.ts | 4 +- .../src/utils/route-dispatcher.ts | 6 +- 77 files changed, 112 insertions(+), 284 deletions(-) delete mode 100644 packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-submit-app-successfully.tsx.snap delete mode 100644 packages/developer-portal/src/components/pages/__tests__/developer-submit-app-successfully.tsx rename packages/developer-portal/src/components/pages/{__tests__/__snapshots__/api-docs.tsx.snap => api-docs/__tests__/__snapshots__/api-docs.test.tsx.snap} (100%) rename packages/developer-portal/src/components/pages/{__tests__/api-docs.tsx => api-docs/__tests__/api-docs.test.tsx} (91%) rename packages/developer-portal/src/components/pages/{ => api-docs}/api-docs.tsx (84%) create mode 100644 packages/developer-portal/src/components/pages/api-docs/index.ts rename packages/developer-portal/src/components/pages/{developer-desktop => desktop}/__styles__/pricing-tile.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-desktop/__tests__/__snapshots__/developer-desktop.tsx.snap => desktop/__tests__/__snapshots__/desktop.test.tsx.snap} (100%) rename packages/developer-portal/src/components/pages/{developer-desktop/__tests__/developer-desktop.tsx => desktop/__tests__/desktop.test.tsx} (97%) rename packages/developer-portal/src/components/pages/{developer-desktop/developer-desktop.tsx => desktop/desktop.tsx} (97%) create mode 100644 packages/developer-portal/src/components/pages/desktop/index.ts delete mode 100644 packages/developer-portal/src/components/pages/developer-desktop/index.ts delete mode 100644 packages/developer-portal/src/components/pages/developer-submit-app-successfully.tsx rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/agency-cloud-integration-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/authentication-flow-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/developer-edit-app.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/general-information-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/marketplace-status-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/permission-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/redirect-uri-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/__snapshots__/upload-image-section.test.tsx.snap (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/agency-cloud-integration-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/authentication-flow-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/developer-edit-app.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/general-information-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/marketplace-status-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/permission-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/redirect-uri-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app/__test__ => edit-app/__tests__}/upload-image-section.test.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/agency-cloud-integration-section.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/authentication-flow-section.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/developer-edit-app.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/form-schema/form-fields.ts (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/form-schema/validation-schema.ts (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/general-information-section.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/index.ts (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/marketplace-status-section.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/permission-section.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/redirect-uri-section.tsx (100%) rename packages/developer-portal/src/components/pages/{developer-edit-app => edit-app}/upload-image-section.tsx (100%) rename packages/developer-portal/src/components/pages/{__tests__/__snapshots__/developer-help.test.tsx.snap => help/__tests__/__snapshots__/help.test.tsx.snap} (100%) rename packages/developer-portal/src/components/pages/{__tests__/developer-help.test.tsx => help/__tests__/help.test.tsx} (88%) rename packages/developer-portal/src/components/pages/{developer-help.tsx => help/help.tsx} (97%) create mode 100644 packages/developer-portal/src/components/pages/help/index.ts rename packages/developer-portal/src/components/pages/{__tests__/__snapshots__/register-confirm.tsx.snap => register-confirm/__tests__/__snapshots__/register-confirm.test.tsx.snap} (100%) rename packages/developer-portal/src/components/pages/{__tests__/register-confirm.tsx => register-confirm/__tests__/register-confirm.test.tsx} (100%) create mode 100644 packages/developer-portal/src/components/pages/register-confirm/index.ts rename packages/developer-portal/src/components/pages/{ => register-confirm}/register-confirm.tsx (100%) rename packages/developer-portal/src/components/pages/{__tests__/__snapshots__/swagger.tsx.snap => swagger/__tests__/__snapshots__/swagger.test.tsx.snap} (100%) rename packages/developer-portal/src/components/pages/{__tests__/swagger.tsx => swagger/__tests__/swagger.test.tsx} (98%) create mode 100644 packages/developer-portal/src/components/pages/swagger/index.ts rename packages/developer-portal/src/components/pages/{ => swagger}/swagger.tsx (91%) rename packages/developer-portal/src/components/pages/{__tests__/__snapshots__/developer-welcome.tsx.snap => welcome/__tests__/__snapshots__/welcome.test.tsx.snap} (100%) rename packages/developer-portal/src/components/pages/{__tests__/developer-welcome.tsx => welcome/__tests__/welcome.test.tsx} (98%) create mode 100644 packages/developer-portal/src/components/pages/welcome/index.ts rename packages/developer-portal/src/components/pages/{developer-welcome.tsx => welcome/welcome.tsx} (97%) diff --git a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-submit-app-successfully.tsx.snap b/packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-submit-app-successfully.tsx.snap deleted file mode 100644 index 0284a8937c..0000000000 --- a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-submit-app-successfully.tsx.snap +++ /dev/null @@ -1,77 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DeveloperSubmitAppSuccessfully renders correctly 1`] = ` - - - - - My Apps - - - Submit another app - - - } - isCard={true} - title="Success" - > -

- Your App has now been registered and can be accessed by clicking on ‘My Apps’ below. -

-
-

- You will be directed to the ‘My Apps’ page where you will be able to access the ‘Client ID’ of your App (required for authentication) and or make any changes to your App by clicking ‘Edit Details’. -

-
-

- - Currently, your App is only visible to you - - and will not be available in the Marketplace until you have made it ‘Listed’. When you are ready to do this, click on ‘Edit Detail’ and tick the ‘Is Listed’ check box located in the ‘Marketplace Status’ section. -

-
-

- - Please note: - - Any changes you make now to your App (including making it ‘Listed’) will require approval. These are called ‘Revisions’. All revisions will be sent to our Admin department and whilst your App is being reviewed, you will not be able to make any further changes and the App will be marked as ‘Pending Revision’. -

-
-

- Once you have ‘Listed’ your application, and any revisions have been approved, your app will be live in the Marketplace and available for install by customers. -

-
-

- For any issues or support, please visit the - - ‘Help’ - - page. -

-
-
-
-
-`; diff --git a/packages/developer-portal/src/components/pages/__tests__/developer-submit-app-successfully.tsx b/packages/developer-portal/src/components/pages/__tests__/developer-submit-app-successfully.tsx deleted file mode 100644 index 262bc80660..0000000000 --- a/packages/developer-portal/src/components/pages/__tests__/developer-submit-app-successfully.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react' -import { shallow } from 'enzyme' -import { - DeveloperSubmitAppSuccessfully, - DeveloperSubmitAppSuccessfullyProps, -} from '../developer-submit-app-successfully' - -describe('DeveloperSubmitAppSuccessfully', () => { - it('renders correctly', () => { - const props: DeveloperSubmitAppSuccessfullyProps = { - onGoBackToApps: jest.fn(), - onSubmitAnotherApp: jest.fn(), - } - - expect(shallow()).toMatchSnapshot() - }) -}) diff --git a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/api-docs.tsx.snap b/packages/developer-portal/src/components/pages/api-docs/__tests__/__snapshots__/api-docs.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/__tests__/__snapshots__/api-docs.tsx.snap rename to packages/developer-portal/src/components/pages/api-docs/__tests__/__snapshots__/api-docs.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/__tests__/api-docs.tsx b/packages/developer-portal/src/components/pages/api-docs/__tests__/api-docs.test.tsx similarity index 91% rename from packages/developer-portal/src/components/pages/__tests__/api-docs.tsx rename to packages/developer-portal/src/components/pages/api-docs/__tests__/api-docs.test.tsx index a91dd08edf..6f7a1eeaf7 100644 --- a/packages/developer-portal/src/components/pages/__tests__/api-docs.tsx +++ b/packages/developer-portal/src/components/pages/api-docs/__tests__/api-docs.test.tsx @@ -20,7 +20,7 @@ describe('ApiDocs', () => { describe('parseIframeUrl', () => { it('should run correctly', () => { - const pathname = `${Routes.DEVELOPER_API_DOCS}/platform-glossary` + const pathname = `${Routes.API_DOCS}/platform-glossary` const hash = '#company' const result = parseIframeUrl(pathname, hash) expect(result).toEqual('/platform-glossary#company') diff --git a/packages/developer-portal/src/components/pages/api-docs.tsx b/packages/developer-portal/src/components/pages/api-docs/api-docs.tsx similarity index 84% rename from packages/developer-portal/src/components/pages/api-docs.tsx rename to packages/developer-portal/src/components/pages/api-docs/api-docs.tsx index 3136b8e04f..35f89b33ab 100644 --- a/packages/developer-portal/src/components/pages/api-docs.tsx +++ b/packages/developer-portal/src/components/pages/api-docs/api-docs.tsx @@ -2,13 +2,13 @@ import * as React from 'react' import { useHistory } from 'react-router' import ErrorBoundary from '@/components/hocs/error-boundary' import { UnsupportBrowserPopUp } from '@/components/ui/unsupport-browser-pop-up' -import { IFRAME_URLS } from '../../constants/iframe-urls' -import Routes from '../../constants/routes' import { isIE } from '@/utils/browser' +import Routes from '@/constants/routes' +import { IFRAME_URLS } from '@/constants/iframe-urls' export const parseIframeUrl = (pathname: string, hash: string): string => { - const path = pathname.split(Routes.DEVELOPER_API_DOCS)[1] - return `${path}${hash}` + const documentPagePath = pathname.split(Routes.API_DOCS)[1] + return `${documentPagePath}${hash}` } const ApiDocsPage: React.FC = () => { diff --git a/packages/developer-portal/src/components/pages/api-docs/index.ts b/packages/developer-portal/src/components/pages/api-docs/index.ts new file mode 100644 index 0000000000..d77d2767a5 --- /dev/null +++ b/packages/developer-portal/src/components/pages/api-docs/index.ts @@ -0,0 +1,2 @@ +import APIDocs from './api-docs' +export default APIDocs diff --git a/packages/developer-portal/src/components/pages/app-detail/__tests__/app-detail.test.tsx b/packages/developer-portal/src/components/pages/app-detail/__tests__/app-detail.test.tsx index 69c512b481..513aa3c482 100644 --- a/packages/developer-portal/src/components/pages/app-detail/__tests__/app-detail.test.tsx +++ b/packages/developer-portal/src/components/pages/app-detail/__tests__/app-detail.test.tsx @@ -35,7 +35,7 @@ describe('DeveloperAppDetail', () => { expect( mount( - + , diff --git a/packages/developer-portal/src/components/pages/app-detail/__tests__/app-management.test.tsx b/packages/developer-portal/src/components/pages/app-detail/__tests__/app-management.test.tsx index c9a77ff4f9..f14bd63577 100644 --- a/packages/developer-portal/src/components/pages/app-detail/__tests__/app-management.test.tsx +++ b/packages/developer-portal/src/components/pages/app-detail/__tests__/app-management.test.tsx @@ -43,7 +43,7 @@ describe('ManageApp', () => { expect( mount( - + { it('should run correctly', () => { const fn = onDevelopersButtonClick(history) fn() - expect(history.replace).toBeCalledWith(Routes.DEVELOPER_DESKTOP) + expect(history.replace).toBeCalledWith(Routes.DESKTOP) }) }) }) diff --git a/packages/developer-portal/src/components/pages/authentication/authentication.tsx b/packages/developer-portal/src/components/pages/authentication/authentication.tsx index d5923e3ee8..45f6f93842 100644 --- a/packages/developer-portal/src/components/pages/authentication/authentication.tsx +++ b/packages/developer-portal/src/components/pages/authentication/authentication.tsx @@ -17,7 +17,7 @@ export interface AuthenticationParamTypes { export const onDevelopersButtonClick = (history: History) => { return () => { - history.replace(Routes.DEVELOPER_DESKTOP) + history.replace(Routes.DESKTOP) } } @@ -58,7 +58,7 @@ export const renderClientModal = (history, dispatch) => { please visit the  - Desktop + Desktop  page within the Developers Portal, where you can subscribe to a Developer Edition of Agency Cloud. diff --git a/packages/developer-portal/src/components/pages/developer-desktop/__styles__/pricing-tile.tsx b/packages/developer-portal/src/components/pages/desktop/__styles__/pricing-tile.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-desktop/__styles__/pricing-tile.tsx rename to packages/developer-portal/src/components/pages/desktop/__styles__/pricing-tile.tsx diff --git a/packages/developer-portal/src/components/pages/developer-desktop/__tests__/__snapshots__/developer-desktop.tsx.snap b/packages/developer-portal/src/components/pages/desktop/__tests__/__snapshots__/desktop.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-desktop/__tests__/__snapshots__/developer-desktop.tsx.snap rename to packages/developer-portal/src/components/pages/desktop/__tests__/__snapshots__/desktop.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-desktop/__tests__/developer-desktop.tsx b/packages/developer-portal/src/components/pages/desktop/__tests__/desktop.test.tsx similarity index 97% rename from packages/developer-portal/src/components/pages/developer-desktop/__tests__/developer-desktop.tsx rename to packages/developer-portal/src/components/pages/desktop/__tests__/desktop.test.tsx index 606db34350..7361aa8451 100644 --- a/packages/developer-portal/src/components/pages/developer-desktop/__tests__/developer-desktop.tsx +++ b/packages/developer-portal/src/components/pages/desktop/__tests__/desktop.test.tsx @@ -3,7 +3,7 @@ import { mount } from 'enzyme' import { Provider } from 'react-redux' import configureStore from 'redux-mock-store' import appState from '@/reducers/__stubs__/app-state' -import { DeveloperDesktopPage, handleToggleVisibleModal } from '../developer-desktop' +import { DeveloperDesktopPage, handleToggleVisibleModal } from '../desktop' describe('DeveloperDesktopPage', () => { let store diff --git a/packages/developer-portal/src/components/pages/developer-desktop/developer-desktop.tsx b/packages/developer-portal/src/components/pages/desktop/desktop.tsx similarity index 97% rename from packages/developer-portal/src/components/pages/developer-desktop/developer-desktop.tsx rename to packages/developer-portal/src/components/pages/desktop/desktop.tsx index 99d7ec9b9a..b7d0cdefc5 100644 --- a/packages/developer-portal/src/components/pages/developer-desktop/developer-desktop.tsx +++ b/packages/developer-portal/src/components/pages/desktop/desktop.tsx @@ -31,7 +31,7 @@ export const DeveloperDesktopContentPartOne: React.FC = () => {

To learn more about what’s possible with the Desktop API, please visit the{' '} - + documentation.

diff --git a/packages/developer-portal/src/components/pages/desktop/index.ts b/packages/developer-portal/src/components/pages/desktop/index.ts new file mode 100644 index 0000000000..814a0ba95c --- /dev/null +++ b/packages/developer-portal/src/components/pages/desktop/index.ts @@ -0,0 +1 @@ +export { default } from './desktop' diff --git a/packages/developer-portal/src/components/pages/developer-desktop/index.ts b/packages/developer-portal/src/components/pages/developer-desktop/index.ts deleted file mode 100644 index 645f2fde85..0000000000 --- a/packages/developer-portal/src/components/pages/developer-desktop/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './developer-desktop' diff --git a/packages/developer-portal/src/components/pages/developer-submit-app-successfully.tsx b/packages/developer-portal/src/components/pages/developer-submit-app-successfully.tsx deleted file mode 100644 index 2246537a2e..0000000000 --- a/packages/developer-portal/src/components/pages/developer-submit-app-successfully.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import * as React from 'react' -import { FlexContainerResponsive, Button } from '@reapit/elements' -import CallToAction from '../ui/call-to-action' -import styles from '@/styles/pages/developer-submit-app-successfully.scss?mod' -import { Link } from 'react-router-dom' -import Routes from '@/constants/routes' - -export interface DeveloperSubmitAppSuccessfullyProps { - onGoBackToApps: () => void - onSubmitAnotherApp: () => void -} -export const DeveloperSubmitAppSuccessfully: React.FC = ({ - onGoBackToApps, - onSubmitAnotherApp, -}) => ( - - - - - - - } - > -

Your App has now been registered and can be accessed by clicking on ‘My Apps’ below.

-
-

- You will be directed to the ‘My Apps’ page where you will be able to access the ‘Client - ID’ of your App (required for authentication) and or make any changes to your App by clicking - ‘Edit Details’. -

-
-

- Currently, your App is only visible to you and will not be available in the Marketplace until - you have made it ‘Listed’. When you are ready to do this, click on ‘Edit Detail’ and - tick the ‘Is Listed’ check box located in the ‘Marketplace Status’ section. -

-
-

- Please note: Any changes you make now to your App (including making it ‘Listed’) - will require approval. These are called ‘Revisions’. All revisions will be sent to our Admin - department and whilst your App is being reviewed, you will not be able to make any further changes and the App - will be marked as ‘Pending Revision’. -

-
-

- Once you have ‘Listed’ your application, and any revisions have been approved, your app will be - live in the Marketplace and available for install by customers. -

-
-

- For any issues or support, please visit the ‘Help’ page. -

- -
-
-
-
-) - -export default DeveloperSubmitAppSuccessfully diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/agency-cloud-integration-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/agency-cloud-integration-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/agency-cloud-integration-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/agency-cloud-integration-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/authentication-flow-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/authentication-flow-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/authentication-flow-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/authentication-flow-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/developer-edit-app.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/developer-edit-app.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/developer-edit-app.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/developer-edit-app.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/general-information-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/general-information-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/general-information-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/general-information-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/marketplace-status-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/marketplace-status-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/marketplace-status-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/marketplace-status-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/permission-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/permission-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/permission-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/permission-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/redirect-uri-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/redirect-uri-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/redirect-uri-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/redirect-uri-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/upload-image-section.test.tsx.snap b/packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/upload-image-section.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/__snapshots__/upload-image-section.test.tsx.snap rename to packages/developer-portal/src/components/pages/edit-app/__tests__/__snapshots__/upload-image-section.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/agency-cloud-integration-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/agency-cloud-integration-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/agency-cloud-integration-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/agency-cloud-integration-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/authentication-flow-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/authentication-flow-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/authentication-flow-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/authentication-flow-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/developer-edit-app.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/developer-edit-app.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/developer-edit-app.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/developer-edit-app.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/general-information-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/general-information-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/general-information-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/general-information-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/marketplace-status-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/marketplace-status-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/marketplace-status-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/marketplace-status-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/permission-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/permission-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/permission-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/permission-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/redirect-uri-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/redirect-uri-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/redirect-uri-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/redirect-uri-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/__test__/upload-image-section.test.tsx b/packages/developer-portal/src/components/pages/edit-app/__tests__/upload-image-section.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/__test__/upload-image-section.test.tsx rename to packages/developer-portal/src/components/pages/edit-app/__tests__/upload-image-section.test.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/agency-cloud-integration-section.tsx b/packages/developer-portal/src/components/pages/edit-app/agency-cloud-integration-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/agency-cloud-integration-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/agency-cloud-integration-section.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/authentication-flow-section.tsx b/packages/developer-portal/src/components/pages/edit-app/authentication-flow-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/authentication-flow-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/authentication-flow-section.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/developer-edit-app.tsx b/packages/developer-portal/src/components/pages/edit-app/developer-edit-app.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/developer-edit-app.tsx rename to packages/developer-portal/src/components/pages/edit-app/developer-edit-app.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/form-schema/form-fields.ts b/packages/developer-portal/src/components/pages/edit-app/form-schema/form-fields.ts similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/form-schema/form-fields.ts rename to packages/developer-portal/src/components/pages/edit-app/form-schema/form-fields.ts diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/form-schema/validation-schema.ts b/packages/developer-portal/src/components/pages/edit-app/form-schema/validation-schema.ts similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/form-schema/validation-schema.ts rename to packages/developer-portal/src/components/pages/edit-app/form-schema/validation-schema.ts diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/general-information-section.tsx b/packages/developer-portal/src/components/pages/edit-app/general-information-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/general-information-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/general-information-section.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/index.ts b/packages/developer-portal/src/components/pages/edit-app/index.ts similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/index.ts rename to packages/developer-portal/src/components/pages/edit-app/index.ts diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/marketplace-status-section.tsx b/packages/developer-portal/src/components/pages/edit-app/marketplace-status-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/marketplace-status-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/marketplace-status-section.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/permission-section.tsx b/packages/developer-portal/src/components/pages/edit-app/permission-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/permission-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/permission-section.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/redirect-uri-section.tsx b/packages/developer-portal/src/components/pages/edit-app/redirect-uri-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/redirect-uri-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/redirect-uri-section.tsx diff --git a/packages/developer-portal/src/components/pages/developer-edit-app/upload-image-section.tsx b/packages/developer-portal/src/components/pages/edit-app/upload-image-section.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/developer-edit-app/upload-image-section.tsx rename to packages/developer-portal/src/components/pages/edit-app/upload-image-section.tsx diff --git a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-help.test.tsx.snap b/packages/developer-portal/src/components/pages/help/__tests__/__snapshots__/help.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-help.test.tsx.snap rename to packages/developer-portal/src/components/pages/help/__tests__/__snapshots__/help.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/__tests__/developer-help.test.tsx b/packages/developer-portal/src/components/pages/help/__tests__/help.test.tsx similarity index 88% rename from packages/developer-portal/src/components/pages/__tests__/developer-help.test.tsx rename to packages/developer-portal/src/components/pages/help/__tests__/help.test.tsx index 6a81b87345..5ac1c1e949 100644 --- a/packages/developer-portal/src/components/pages/__tests__/developer-help.test.tsx +++ b/packages/developer-portal/src/components/pages/help/__tests__/help.test.tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import initChatBot from '../../../scripts/chat-bot' +import initChatBot from '../../../../scripts/chat-bot' import { mount } from 'enzyme' import * as ReactRedux from 'react-redux' import { @@ -10,17 +10,17 @@ import { handleFaq, handleViewRoadmap, handleWhatsNew, -} from '../developer-help' +} from '../help' import Routes from '@/constants/routes' import configureStore from 'redux-mock-store' import { history } from '@/core/router' import { HelpLinks } from '@/constants/developer-help-links' -import { mockLoginSession } from '../../../sagas/__tests__/auth' import appState from '@/reducers/__stubs__/app-state' +import { mockLoginSession } from '@/sagas/__tests__/auth' -jest.mock('../../../scripts/chat-bot') +jest.mock('../../../../scripts/chat-bot') -jest.mock('../../../core/router', () => ({ +jest.mock('../../../../core/router', () => ({ history: { push: jest.fn(), }, @@ -53,7 +53,7 @@ describe('handleGotoWelcomeGuide', () => { it('should called with correct props', () => { const spy = jest.spyOn(history, 'push') handleGotoWelcomeGuide() - expect(spy).toHaveBeenCalledWith(Routes.DEVELOPER_WELCOME) + expect(spy).toHaveBeenCalledWith(Routes.WELCOME) }) }) diff --git a/packages/developer-portal/src/components/pages/developer-help.tsx b/packages/developer-portal/src/components/pages/help/help.tsx similarity index 97% rename from packages/developer-portal/src/components/pages/developer-help.tsx rename to packages/developer-portal/src/components/pages/help/help.tsx index 9c0838bd1b..b682fd9761 100644 --- a/packages/developer-portal/src/components/pages/developer-help.tsx +++ b/packages/developer-portal/src/components/pages/help/help.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { useSelector } from 'react-redux' -import initChatBot from '../../scripts/chat-bot' +import initChatBot from '../../../scripts/chat-bot' import { history } from '@/core/router' import { H3 } from '@reapit/elements' import Routes from '@/constants/routes' @@ -17,7 +17,7 @@ import { LoginIdentity } from '@reapit/cognito-auth' import { selectLoginIdentity } from '@/selector/auth' export const handleGotoWelcomeGuide = () => { - history.push(Routes.DEVELOPER_WELCOME) + history.push(Routes.WELCOME) } export const handleReportBug = () => { diff --git a/packages/developer-portal/src/components/pages/help/index.ts b/packages/developer-portal/src/components/pages/help/index.ts new file mode 100644 index 0000000000..ac304f016c --- /dev/null +++ b/packages/developer-portal/src/components/pages/help/index.ts @@ -0,0 +1,2 @@ +import Help from './help' +export default Help diff --git a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/register-confirm.tsx.snap b/packages/developer-portal/src/components/pages/register-confirm/__tests__/__snapshots__/register-confirm.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/__tests__/__snapshots__/register-confirm.tsx.snap rename to packages/developer-portal/src/components/pages/register-confirm/__tests__/__snapshots__/register-confirm.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/__tests__/register-confirm.tsx b/packages/developer-portal/src/components/pages/register-confirm/__tests__/register-confirm.test.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/__tests__/register-confirm.tsx rename to packages/developer-portal/src/components/pages/register-confirm/__tests__/register-confirm.test.tsx diff --git a/packages/developer-portal/src/components/pages/register-confirm/index.ts b/packages/developer-portal/src/components/pages/register-confirm/index.ts new file mode 100644 index 0000000000..d47adffa0a --- /dev/null +++ b/packages/developer-portal/src/components/pages/register-confirm/index.ts @@ -0,0 +1,2 @@ +import RegisterConfirm from './register-confirm' +export default RegisterConfirm diff --git a/packages/developer-portal/src/components/pages/register-confirm.tsx b/packages/developer-portal/src/components/pages/register-confirm/register-confirm.tsx similarity index 100% rename from packages/developer-portal/src/components/pages/register-confirm.tsx rename to packages/developer-portal/src/components/pages/register-confirm/register-confirm.tsx diff --git a/packages/developer-portal/src/components/pages/settings/__tests__/__snapshots__/settings.test.tsx.snap b/packages/developer-portal/src/components/pages/settings/__tests__/__snapshots__/settings.test.tsx.snap index df36c95add..d9e9c6e3ac 100644 --- a/packages/developer-portal/src/components/pages/settings/__tests__/__snapshots__/settings.test.tsx.snap +++ b/packages/developer-portal/src/components/pages/settings/__tests__/__snapshots__/settings.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`DeveloperSettingsPage should match snapshot 1`] = ` +exports[`SettingsPage should match snapshot 1`] = ` { +describe('SettingsPage', () => { it('should match snapshot', () => { const mockStore = configureStore() const store = mockStore(mockState) const wrapper = shallow( - + , ) expect(wrapper).toMatchSnapshot() diff --git a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/swagger.tsx.snap b/packages/developer-portal/src/components/pages/swagger/__tests__/__snapshots__/swagger.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/__tests__/__snapshots__/swagger.tsx.snap rename to packages/developer-portal/src/components/pages/swagger/__tests__/__snapshots__/swagger.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/__tests__/swagger.tsx b/packages/developer-portal/src/components/pages/swagger/__tests__/swagger.test.tsx similarity index 98% rename from packages/developer-portal/src/components/pages/__tests__/swagger.tsx rename to packages/developer-portal/src/components/pages/swagger/__tests__/swagger.test.tsx index eb3cdb1702..45df00d95a 100644 --- a/packages/developer-portal/src/components/pages/__tests__/swagger.tsx +++ b/packages/developer-portal/src/components/pages/swagger/__tests__/swagger.test.tsx @@ -4,7 +4,7 @@ import { getAccessToken } from '@/utils/session' import Swagger, { handleOnComplete, fetchInterceptor, fetchAccessToken, InterceptorParams } from '../swagger' -jest.mock('../../../core/store') +jest.mock('../../../../core/store') jest.mock('@/utils/session') describe('Swagger', () => { diff --git a/packages/developer-portal/src/components/pages/swagger/index.ts b/packages/developer-portal/src/components/pages/swagger/index.ts new file mode 100644 index 0000000000..ead8acfe3b --- /dev/null +++ b/packages/developer-portal/src/components/pages/swagger/index.ts @@ -0,0 +1,2 @@ +import Swagger from './swagger' +export default Swagger diff --git a/packages/developer-portal/src/components/pages/swagger.tsx b/packages/developer-portal/src/components/pages/swagger/swagger.tsx similarity index 91% rename from packages/developer-portal/src/components/pages/swagger.tsx rename to packages/developer-portal/src/components/pages/swagger/swagger.tsx index ebf9f3ab3b..bf291ae309 100644 --- a/packages/developer-portal/src/components/pages/swagger.tsx +++ b/packages/developer-portal/src/components/pages/swagger/swagger.tsx @@ -1,12 +1,11 @@ import * as React from 'react' import SwaggerUI from 'swagger-ui-react' import 'swagger-ui-react/swagger-ui.css' -import '../../styles/vendor/swagger.scss' +import '../../../styles/vendor/swagger.scss' import ErrorBoundary from '@/components/hocs/error-boundary' -import { Loader } from '@reapit/elements' -import { SandboxPopUp } from '../ui/sandbox-pop-up' +import { Loader, StringMap } from '@reapit/elements' import { getAccessToken } from '@/utils/session' -import { StringMap } from '../../types/core' +import { SandboxPopUp } from '@/components/ui/sandbox-pop-up' export type InterceptorParams = { url: string diff --git a/packages/developer-portal/src/components/pages/webhooks/webhook-test-modal.tsx b/packages/developer-portal/src/components/pages/webhooks/webhook-test-modal.tsx index d969ab7eba..89ad188e05 100644 --- a/packages/developer-portal/src/components/pages/webhooks/webhook-test-modal.tsx +++ b/packages/developer-portal/src/components/pages/webhooks/webhook-test-modal.tsx @@ -94,7 +94,7 @@ export const WebhookTestModalBody: React.FunctionComponent diff --git a/packages/developer-portal/src/components/pages/webhooks/webhooks.tsx b/packages/developer-portal/src/components/pages/webhooks/webhooks.tsx index 04570f33f8..60ad121f19 100644 --- a/packages/developer-portal/src/components/pages/webhooks/webhooks.tsx +++ b/packages/developer-portal/src/components/pages/webhooks/webhooks.tsx @@ -202,7 +202,7 @@ export const DeveloperWebhooks = () => { different webhook subscription per topic or per customer. For more information about Webhooks, please see our diff --git a/packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-welcome.tsx.snap b/packages/developer-portal/src/components/pages/welcome/__tests__/__snapshots__/welcome.test.tsx.snap similarity index 100% rename from packages/developer-portal/src/components/pages/__tests__/__snapshots__/developer-welcome.tsx.snap rename to packages/developer-portal/src/components/pages/welcome/__tests__/__snapshots__/welcome.test.tsx.snap diff --git a/packages/developer-portal/src/components/pages/__tests__/developer-welcome.tsx b/packages/developer-portal/src/components/pages/welcome/__tests__/welcome.test.tsx similarity index 98% rename from packages/developer-portal/src/components/pages/__tests__/developer-welcome.tsx rename to packages/developer-portal/src/components/pages/welcome/__tests__/welcome.test.tsx index 5be587fe5d..141b2137be 100644 --- a/packages/developer-portal/src/components/pages/__tests__/developer-welcome.tsx +++ b/packages/developer-portal/src/components/pages/welcome/__tests__/welcome.test.tsx @@ -9,7 +9,7 @@ import { Managing, Support, Welcome, -} from '../developer-welcome' +} from '../welcome' import routes from '@/constants/routes' import { HelpGuide } from '@reapit/elements' diff --git a/packages/developer-portal/src/components/pages/welcome/index.ts b/packages/developer-portal/src/components/pages/welcome/index.ts new file mode 100644 index 0000000000..eaae4b28c0 --- /dev/null +++ b/packages/developer-portal/src/components/pages/welcome/index.ts @@ -0,0 +1,2 @@ +import Welcome from './welcome' +export default Welcome diff --git a/packages/developer-portal/src/components/pages/developer-welcome.tsx b/packages/developer-portal/src/components/pages/welcome/welcome.tsx similarity index 97% rename from packages/developer-portal/src/components/pages/developer-welcome.tsx rename to packages/developer-portal/src/components/pages/welcome/welcome.tsx index e281069575..731e9106ff 100644 --- a/packages/developer-portal/src/components/pages/developer-welcome.tsx +++ b/packages/developer-portal/src/components/pages/welcome/welcome.tsx @@ -48,7 +48,7 @@ export const Documentation = () => {

- + APIs @@ -56,7 +56,7 @@ export const Documentation = () => { Our interactive documentation allows you to easily experiment with our APIs with a ‘Try it now’ function to quickly build requests and inspect responses. To try it yourself and to see what data is available, click{' '} - + here . @@ -156,7 +156,7 @@ export const Support = () => { You are currently logged into our alpha release of Reapit Foundations and we are continuing to update, add additional features and address any issues that may appear. In the meantime, if you would like to request a feature or report a bug, this can be done from the{' '} - + ‘Help’ {' '} section on the left. diff --git a/packages/developer-portal/src/components/ui/__tests__/help-item-list.tsx b/packages/developer-portal/src/components/ui/__tests__/help-item-list.tsx index b2c3780cff..33d70245c9 100644 --- a/packages/developer-portal/src/components/ui/__tests__/help-item-list.tsx +++ b/packages/developer-portal/src/components/ui/__tests__/help-item-list.tsx @@ -3,8 +3,7 @@ import { shallow } from 'enzyme' import toJson from 'enzyme-to-json' import { HelpItemList } from '../help-item-list' - -import { helpItems } from '@/components/pages/developer-help' +import { helpItems } from '@/components/pages/help/help' describe('HelpItemList', () => { it('should match a snapshot', () => { diff --git a/packages/developer-portal/src/components/ui/menu.tsx b/packages/developer-portal/src/components/ui/menu.tsx index fc1f6d1e28..03529a74f9 100644 --- a/packages/developer-portal/src/components/ui/menu.tsx +++ b/packages/developer-portal/src/components/ui/menu.tsx @@ -113,35 +113,35 @@ export const generateMenuConfig = ( { title: 'API', key: 'SWAGGER', - url: Routes.DEVELOPER_SWAGGER, + url: Routes.SWAGGER, type: 'PRIMARY', icon: , }, { title: 'Webhooks', key: 'WEBHOOKS', - url: Routes.DEVELOPER_WEBHOOKS, + url: Routes.WEBHOOKS, type: 'PRIMARY', icon: , }, { title: 'Docs', key: 'API_DOCS', - url: Routes.DEVELOPER_API_DOCS, + url: Routes.API_DOCS, type: 'PRIMARY', icon: , }, { title: 'Desktop', key: 'DESKTOP', - url: Routes.DEVELOPER_DESKTOP, + url: Routes.DESKTOP, type: 'PRIMARY', icon: , }, { title: 'Help', key: 'HELP', - url: Routes.DEVELOPER_HELP, + url: Routes.HELP, type: 'PRIMARY', icon: , }, diff --git a/packages/developer-portal/src/components/ui/submit-app-wizard/steps/step-before-you-start.tsx b/packages/developer-portal/src/components/ui/submit-app-wizard/steps/step-before-you-start.tsx index 54053d2756..e54180f5e1 100644 --- a/packages/developer-portal/src/components/ui/submit-app-wizard/steps/step-before-you-start.tsx +++ b/packages/developer-portal/src/components/ui/submit-app-wizard/steps/step-before-you-start.tsx @@ -5,8 +5,7 @@ import Routes from '@/constants/routes' import { WizardStepComponent, SetWizardStep } from '../types' import { wizzardSteps } from '../constant' -export const onViewDocs = (history: History) => () => - history.push(`${Routes.DEVELOPER_API_DOCS}/developer-portal`) +export const onViewDocs = (history: History) => () => history.push(`${Routes.API_DOCS}/developer-portal`) export const onCreateNewApp = (setWizardStep: SetWizardStep) => () => { setWizardStep(wizzardSteps.INPUT_APP_NAME) @@ -31,7 +30,7 @@ export const StepBeforeYouStart: WizardStepComponent = ({ setWizardStep }) => { <> diff --git a/packages/developer-portal/src/constants/routes.ts b/packages/developer-portal/src/constants/routes.ts index b0482540f6..b76c504697 100644 --- a/packages/developer-portal/src/constants/routes.ts +++ b/packages/developer-portal/src/constants/routes.ts @@ -11,23 +11,23 @@ const Routes = { MY_APPS_PAGINATE: '/client/manage/:page', CLIENT_SETTINGS: '/client/settings', DEVELOPER: '/developer', - DEVELOPER_WELCOME: '/developer/welcome', + WELCOME: '/developer/welcome', APPS: '/developer/apps', - DEVELOPER_APP_DETAIL: '/developer/apps/:appid', - DEVELOPER_SWAGGER: '/developer/swagger', - DEVELOPER_DESKTOP: '/developer/desktop', + APP_DETAIL: '/developer/apps/:appid', + SWAGGER: '/developer/swagger', + DESKTOP: '/developer/desktop', APPS_EDIT: '/developer/apps/:appid/edit', - DEVELOPER_API_DOCS: '/developer/api-docs', + API_DOCS: '/developer/api-docs', ANALYTICS: '/developer/analytics', ANALYTICS_TAB: '/developer/analytics/:activeTab?', - DEVELOPER_RESET_PASSWORD: '/developer/reset-password', - DEVELOPER_WEBHOOKS: '/developer/webhooks', + RESET_PASSWORD: '/developer/reset-password', + WEBHOOKS: '/developer/webhooks', SETTINGS: '/developer/settings/', SETTINGS_ORGANISATION_TAB: '/developer/settings/organisation', SETTINGS_BILLING_TAB: '/developer/settings/billing', SUBMIT_APP: '/developer/submit-app', - DEVELOPER_HELP: '/developer/help', - DEVELOPER_APP_PREVIEW: '/developer/apps/:appId/preview', + HELP: '/developer/help', + APP_PREVIEW: '/developer/apps/:appId/preview', DEVELOPER_EDITION_DOWNLOAD: '/developer/edition-download', CLIENT_HELP: '/client/help', REGISTER: '/register', diff --git a/packages/developer-portal/src/core/__tests__/__snapshots__/router.tsx.snap b/packages/developer-portal/src/core/__tests__/__snapshots__/router.tsx.snap index ba67c6f73e..af4aeec8c0 100644 --- a/packages/developer-portal/src/core/__tests__/__snapshots__/router.tsx.snap +++ b/packages/developer-portal/src/core/__tests__/__snapshots__/router.tsx.snap @@ -302,6 +302,20 @@ exports[`Router should match a snapshot 1`] = ` fetcher={true} path="/developer/settings/" /> + ) const Register = React.lazy(() => catchChunkError(() => import('../components/pages/register'))) const Apps = React.lazy(() => catchChunkError(() => import('../components/pages/apps'))) -const DeveloperAppDetail = React.lazy(() => catchChunkError(() => import('../components/pages/app-detail'))) -const DeveloperEditApp = React.lazy(() => catchChunkError(() => import('../components/pages/developer-edit-app'))) +const AppDetail = React.lazy(() => catchChunkError(() => import('../components/pages/app-detail'))) +const EditApp = React.lazy(() => catchChunkError(() => import('../components/pages/edit-app'))) const AdminDevManagementPage = React.lazy(() => catchChunkError(() => import('../components/pages/admin-dev-management')), ) const ApiDocsPage = React.lazy(() => catchChunkError(() => import('../components/pages/api-docs'))) const SwaggerPage = React.lazy(() => catchChunkError(() => import('../components/pages/swagger'))) -const DeveloperDesktopPage = React.lazy(() => catchChunkError(() => import('../components/pages/developer-desktop'))) -const DeveloperWelcomePage = React.lazy(() => catchChunkError(() => import('../components/pages/developer-welcome'))) -const DeveloperHelpPage = React.lazy(() => catchChunkError(() => import('../components/pages/developer-help'))) +const DesktopPage = React.lazy(() => catchChunkError(() => import('../components/pages/desktop'))) +const WelcomePage = React.lazy(() => catchChunkError(() => import('../components/pages/welcome'))) +const HelpPage = React.lazy(() => catchChunkError(() => import('../components/pages/help'))) const ClientHelpPage = React.lazy(() => catchChunkError(() => import('../components/pages/client-help'))) const AnalyticsPage = React.lazy(() => catchChunkError(() => import('@/components/pages/analytics'))) const AdminAppsPage = React.lazy(() => catchChunkError(() => import('../components/pages/admin-apps'))) const RegisterConfirm = React.lazy(() => catchChunkError(() => import('../components/pages/register-confirm'))) const AdminStats = React.lazy(() => catchChunkError(() => import('../components/pages/admin-stats'))) const WebhooksPage = React.lazy(() => catchChunkError(() => import('../components/pages/webhooks'))) -const SettingsPage = React.lazy(() => catchChunkError(() => import('../components/pages/settings/settings'))) +const SettingsPage = React.lazy(() => catchChunkError(() => import('../components/pages/settings/'))) const SettingsOrganisationTabPage = React.lazy(() => catchChunkError(() => import('../components/pages/settings/settings-organisation-tab')), @@ -45,8 +45,8 @@ const SettingsBillingTabPage = React.lazy(() => catchChunkError(() => import('../components/pages/settings/settings-billing-tab')), ) -const DeveloperAdminBillingPage = React.lazy(() => catchChunkError(() => import('../components/pages/admin-billing'))) -const DeveloperEditionDownloadPage = React.lazy(() => +const AdminBillingPage = React.lazy(() => catchChunkError(() => import('../components/pages/admin-billing'))) +const EditionDownloadPage = React.lazy(() => catchChunkError(() => import('../components/pages/developer-edition-download')), ) @@ -67,7 +67,7 @@ const Router = () => { } /> - + @@ -77,13 +77,7 @@ const Router = () => { path={Routes.AUTHENTICATION_LOGIN_TYPE} component={Authentication} /> - + @@ -91,25 +85,15 @@ const Router = () => { - - - - - - + + + + + + + { fetcher component={SettingsOrganisationTabPage} /> - - + + { userName: developerUserName, password: developerPassword, loginType: 'DEVELOPER', - loginRoute: ROUTES.DEVELOPER_LOGIN, + loginRoute: Routes.LOGIN, beforeLogin: () => { cy.setCookie(`${env}-${COOKIE_DEVELOPER_FIRST_TIME_LOGIN_COMPLETE}`, new Date().toString()) cy.setCookie(`${env}-${COOKIE_DEVELOPER_TERMS_ACCEPTED}`, new Date().toString()) diff --git a/packages/developer-portal/src/tests/cypress/pages/developer-settings-page.ts b/packages/developer-portal/src/tests/cypress/pages/developer-settings-page.ts index 1e2e41d7b8..091e484ed6 100644 --- a/packages/developer-portal/src/tests/cypress/pages/developer-settings-page.ts +++ b/packages/developer-portal/src/tests/cypress/pages/developer-settings-page.ts @@ -1,7 +1,7 @@ import Routes from '@/constants/routes' import api from '../fixtures/routes' -const developerSettingsMetaData = { +const SettingsMetaData = { url: Routes.SETTINGS, selectors: { companyName: 'input[data-test="company-name"]', @@ -13,8 +13,8 @@ const developerSettingsMetaData = { apiRoute: `${api.developers}/**`, } -const developerSettingsAppPage = { - ...developerSettingsMetaData, +const SettingsAppPage = { + ...SettingsMetaData, } -export default developerSettingsAppPage +export default SettingsAppPage diff --git a/packages/developer-portal/src/utils/__tests__/auth-route.ts b/packages/developer-portal/src/utils/__tests__/auth-route.ts index 0bec383fc5..268c1d83f7 100644 --- a/packages/developer-portal/src/utils/__tests__/auth-route.ts +++ b/packages/developer-portal/src/utils/__tests__/auth-route.ts @@ -6,8 +6,8 @@ describe('getDefaultRoute', () => { expect(getDefaultRoute(true)).toEqual(`${window.location.origin}${Routes.APPS}`) }) - it('should return origin url + Routes.DEVELOPER_WELCOME', () => { - expect(getDefaultRoute(false)).toEqual(`${window.location.origin}${Routes.DEVELOPER_WELCOME}`) + it('should return origin url + Routes.WELCOME', () => { + expect(getDefaultRoute(false)).toEqual(`${window.location.origin}${Routes.WELCOME}`) }) }) @@ -20,7 +20,7 @@ describe('getDefaultPathByLoginType', () => { expect(getDefaultPath(false, true)).toEqual(Routes.APPS) }) - it('should return Routes.DEVELOPER_WELCOME', () => { - expect(getDefaultPath(false, false)).toEqual(Routes.DEVELOPER_WELCOME) + it('should return Routes.WELCOME', () => { + expect(getDefaultPath(false, false)).toEqual(Routes.WELCOME) }) }) diff --git a/packages/developer-portal/src/utils/auth-route.ts b/packages/developer-portal/src/utils/auth-route.ts index 7af7b3ea3c..c67b765ea6 100644 --- a/packages/developer-portal/src/utils/auth-route.ts +++ b/packages/developer-portal/src/utils/auth-route.ts @@ -4,14 +4,12 @@ export function getDefaultRoute(isFirtTimeLogin: boolean) { if (window.location.pathname === Routes.DEVELOPER_EDITION_DOWNLOAD) { return `${window.location.origin}${Routes.DEVELOPER_EDITION_DOWNLOAD}` } - return !isFirtTimeLogin - ? `${window.location.origin}${Routes.DEVELOPER_WELCOME}` - : `${window.location.origin}${Routes.APPS}` + return !isFirtTimeLogin ? `${window.location.origin}${Routes.WELCOME}` : `${window.location.origin}${Routes.APPS}` } export function getDefaultPath(isDesktopMode: boolean, isFirtTimeLogin: boolean) { if (isDesktopMode) { return Routes.APPS } - return !isFirtTimeLogin ? Routes.DEVELOPER_WELCOME : Routes.APPS + return !isFirtTimeLogin ? Routes.WELCOME : Routes.APPS } diff --git a/packages/developer-portal/src/utils/form/settings-contact-information.ts b/packages/developer-portal/src/utils/form/settings-contact-information.ts index 72b6cc0ebc..9fda227f0a 100644 --- a/packages/developer-portal/src/utils/form/settings-contact-information.ts +++ b/packages/developer-portal/src/utils/form/settings-contact-information.ts @@ -2,10 +2,10 @@ import { ContactInformationValues } from '@/components/pages/settings/forms/cont import ErrorMessages from '@/constants/error-messages' import { isValidPersonName, isValidTelephone } from '@/utils/validate' -export type DeveloperSettingsContactInformationErrorKeys = Partial +export type SettingsContactInformationErrorKeys = Partial export const validate = (values: ContactInformationValues) => { - let errors: DeveloperSettingsContactInformationErrorKeys = {} + let errors: SettingsContactInformationErrorKeys = {} if (values.telephone && !isValidTelephone(values.telephone)) { errors.telephone = ErrorMessages.FIELD_PHONE_NUMER diff --git a/packages/developer-portal/src/utils/route-dispatcher.ts b/packages/developer-portal/src/utils/route-dispatcher.ts index da49e1802a..5b13d99423 100644 --- a/packages/developer-portal/src/utils/route-dispatcher.ts +++ b/packages/developer-portal/src/utils/route-dispatcher.ts @@ -63,7 +63,7 @@ const routeDispatcher = async (route: RouteValue, params?: StringMap, search?: s } break } - case Routes.DEVELOPER_APP_DETAIL: { + case Routes.APP_DETAIL: { if (id) { const clientId = selectClientId(store.state) const developerId = selectDeveloperId(store.state) || '' @@ -101,10 +101,10 @@ const routeDispatcher = async (route: RouteValue, params?: StringMap, search?: s case Routes.SETTINGS: store.dispatch(requestDeveloperData()) break - case Routes.DEVELOPER_WEBHOOKS: + case Routes.WEBHOOKS: store.dispatch(developerRequestData({ page: 1, appsPerPage: GET_ALL_PAGE_SIZE } as DeveloperRequestParams)) break - case Routes.DEVELOPER_HELP: + case Routes.HELP: // Need the fetcher to have retrieved the login session only. break default: