diff --git a/.vscode/settings.json b/.vscode/settings.json index 95c8a54b8ffd603b64333d85c5ee94d95eb39d70..6c8a184c183b867ca543309a8e2fadf6bf498eca 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,7 +23,6 @@ "javascriptreact", "typescript", "typescriptreact", - } ], "gitlab.instanceUrl": "https://forge.grandlyon.com/web-et-numerique/llle_project/ecolyo", "gitlab.ignoreCertificateErrors": true, diff --git a/app.config.alpha.js b/app.config.alpha.js index 8c15008280eb5d8832a309168b6f4f79d431d6c4..23d023ab4c1ce3a1af1050e2868035172c3b4b22 100644 --- a/app.config.alpha.js +++ b/app.config.alpha.js @@ -25,11 +25,12 @@ const configs = [ require('cozy-scripts/config/webpack.config.progress'), addAnalyzer ? require('cozy-scripts/config/webpack.config.analyzer') : null, // require('cozy-scripts/config/webpack.config.services'), - require('./app.config.services'), // Override the services config + require('./app.config.services.alpha'), // Override the services config require(`cozy-scripts/config/webpack.target.${target}`), ] configs.push(require('./app.config.environment.alpha')) //module.exports = merge.apply(null, configs) +// eslint-disable-next-line prefer-spread module.exports = [merge.apply(null, configs)] // cozy builder expects an array diff --git a/app.config.environment.alpha.js b/app.config.environment.alpha.js index 9f389dacb63de45e0275f6c7d2ca145dcd8f8a68..65e8495114766d3cfb68e796f0e39e09bee65a7d 100644 --- a/app.config.environment.alpha.js +++ b/app.config.environment.alpha.js @@ -13,7 +13,7 @@ module.exports = { new webpack.optimize.OccurrenceOrderPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production'), // to compile on production mode (redux) - 'process.env.IS_ALPHA': JSON.stringify('true'), + __IS_ALPHA__: true, __DEVELOPMENT__: false, __DEVTOOLS__: false, __STACK_ASSETS__: target !== 'mobile', diff --git a/app.config.environment.dev.js b/app.config.environment.dev.js index bdfec3f9ed843c279fa63a57f12beda8bcb45010..86282e3bca1a3c7ba9ed26ce2c08b0f1842ca3f3 100644 --- a/app.config.environment.dev.js +++ b/app.config.environment.dev.js @@ -18,7 +18,7 @@ const stackProvidedLibsConfig = { plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('development'), - 'process.env.IS_ALPHA': JSON.stringify('true'), //set this variable true for dev so tests runs with alpha variable + __IS_ALPHA__: true, __STACK_ASSETS__: true, }), ], diff --git a/app.config.environment.prod.js b/app.config.environment.prod.js new file mode 100644 index 0000000000000000000000000000000000000000..9e5401b8d3c62ff9b25fb0316b460c837d9a0452 --- /dev/null +++ b/app.config.environment.prod.js @@ -0,0 +1,33 @@ +'use strict' + +const webpack = require('webpack') +const TerserPlugin = require('terser-webpack-plugin') + +const { target } = require('cozy-scripts/config/webpack.vars') + +module.exports = { + mode: 'production', + plugins: [ + // use a hash as chunk id to avoid id changes of not changing chunk + new webpack.HashedModuleIdsPlugin(), + new webpack.optimize.OccurrenceOrderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production'), // to compile on production mode (redux) + __IS_ALPHA__: false, + __DEVELOPMENT__: false, + __DEVTOOLS__: false, + __STACK_ASSETS__: target !== 'mobile', + }), + ], + optimization: { + minimizer: [ + new TerserPlugin({ + parallel: true, + //To fix a SAfari 10 bug : https://github.com/zeit/next.js/issues/5630 + terserOptions: { + safari10: true, + }, + }), + ], + }, +} diff --git a/app.config.js b/app.config.js index 766c8fbe90b4b7ed7fa27aa6cfe946c2574e10d0..5bd0f5e6b525699766a85fbd403169d3b0dcc9f7 100644 --- a/app.config.js +++ b/app.config.js @@ -17,7 +17,6 @@ const { const configs = [ require('cozy-scripts/config/webpack.config.base'), require('cozy-scripts/config/webpack.config.chunks'), - //require('cozy-scripts/config/webpack.config.react'), require('./app.config.react'), // Override the react config require('cozy-scripts/config/webpack.config.cozy-ui'), require('cozy-scripts/config/webpack.config.cozy-ui.react'), @@ -28,16 +27,16 @@ const configs = [ require('cozy-scripts/config/webpack.config.manifest'), require('cozy-scripts/config/webpack.config.progress'), addAnalyzer ? require('cozy-scripts/config/webpack.config.analyzer') : null, - // require('cozy-scripts/config/webpack.config.services'), require('./app.config.services'), // Override the services config require(`cozy-scripts/config/webpack.target.${target}`), ] -if (environment === 'production' && process.env.IS_ALPHA !== 'true') { - configs.push(require('cozy-scripts/config/webpack.environment.prod')) +if (environment === 'production') { + configs.push(require('./app.config.environment.prod')) } else { configs.push(require('./app.config.environment.dev')) } //module.exports = merge.apply(null, configs) +// eslint-disable-next-line prefer-spread module.exports = [merge.apply(null, configs)] // cozy builder expects an array diff --git a/app.config.services.alpha.js b/app.config.services.alpha.js new file mode 100644 index 0000000000000000000000000000000000000000..f7edfa4873f55398b17f2550558f30e0709b7faf --- /dev/null +++ b/app.config.services.alpha.js @@ -0,0 +1,100 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +'use strict' + +/** + * This file overrides the default services webpack config. + * This services config enables the use of TypeScript. + * + * @override node_modules/cozy-scripts/config/webpack.config.services.js + */ + +const webpack = require('webpack') +const path = require('path') +const fs = require('fs-extra') +const paths = require('cozy-scripts/utils/paths') +const { + eslintFix, + getFilename, + target, +} = require('cozy-scripts/config/webpack.vars') + +const servicesFolder = paths.appServicesFolder() +const servicesPaths = fs.existsSync(servicesFolder) + ? fs.readdirSync(servicesFolder) + : [] + +const servicesEntries = {} +servicesPaths.forEach(file => { + if (!file.match(/^[^.]*.ts$/)) return + const filename = file.match(/^([^.]*).ts$/)[1] + servicesEntries[filename] = path.resolve(path.join(servicesFolder, file)) +}) + +const config = { + __mergeStrategy: { + smart: false, + strategy: { + plugins: 'replace', + output: 'replace', + entry: 'replace', + optimization: 'replace', + module: 'replace', + externals: 'replace', + }, + }, + entry: servicesEntries, + output: { + path: paths.appServicesBuild(), + filename: `${getFilename(false)}.js`, + }, + target: 'node', + optimization: {}, // reset optimization property + devtool: false, + externals: [], // reset externals property + module: { + rules: [ + { + enforce: 'pre', + test: /\.ts$/, + loader: require.resolve('cozy-scripts/node_modules/eslint-loader'), + exclude: /node_modules/, + options: { + extends: ['cozy-app'], + fix: eslintFix, + emitWarning: true, + }, + }, + { + test: /\.hbs$/, + loader: 'handlebars-loader', + }, + { + test: path.resolve(__dirname, 'node_modules/uglify-js/tools/node.js'), + loader: 'null-loader', + }, + { + test: /\.ts$/, + exclude: /(node_modules|cozy-(bar|client-js))/, + loader: require.resolve('cozy-scripts/node_modules/babel-loader'), + options: { + cacheDirectory: 'cozy-scripts/node_modules/.cache/babel-loader/node', + babelrc: false, + presets: [['cozy-app', { node: true, react: false }]], + }, + }, + ], + }, + plugins: [ + new webpack.DefinePlugin({ + __TARGET__: JSON.stringify('services'), + __IS_ALPHA__: true, + }), + ], +} + +/* We don't build services if no services and if on mobile build */ +const addServicesConfig = + target === 'browser' && Object.keys(servicesEntries).length + +// only for browser target (services are usable only on cozy-stack) +module.exports = addServicesConfig ? { multiple: { services: config } } : {} diff --git a/app.config.services.js b/app.config.services.js index 8dd5d50ea611e49f5cba5d3d13cfc0d13e90c2ab..edc28bebe027e4eff44d83d445c34422023ff0c7 100644 --- a/app.config.services.js +++ b/app.config.services.js @@ -87,6 +87,7 @@ const config = { plugins: [ new webpack.DefinePlugin({ __TARGET__: JSON.stringify('services'), + __IS_ALPHA__: false, }), ], } diff --git a/src/components/Feedback/FeedbackModal.spec.tsx b/src/components/Feedback/FeedbackModal.spec.tsx index a5c818cd01cc8b924fa7582b73d264fef4f9eea9..f57ee8d6214778b932ae38266ffc3fe415697865 100644 --- a/src/components/Feedback/FeedbackModal.spec.tsx +++ b/src/components/Feedback/FeedbackModal.spec.tsx @@ -12,15 +12,6 @@ import { } from '../../../tests/__mocks__/store' import { act } from 'react-dom/test-utils' -const mockSendMail = jest.fn() -jest.mock('services/mail.service', () => { - return jest.fn(() => { - return { - SendMail: mockSendMail, - } - }) -}) - jest.mock('cozy-ui/transpiled/react/I18n', () => { return { useI18n: jest.fn(() => { @@ -31,6 +22,23 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => { } }) +jest.mock('services/environment.service', () => { + return jest.fn(() => { + return { + isProduction: () => true, + } + }) +}) + +const mockSendMail = jest.fn() +jest.mock('services/mail.service', () => { + return jest.fn(() => { + return { + SendMail: mockSendMail, + } + }) +}) + const handleFeedbackModalClose = jest.fn() const mockUseSelector = jest.spyOn(reactRedux, 'useSelector') diff --git a/src/components/Feedback/FeedbackModal.tsx b/src/components/Feedback/FeedbackModal.tsx index f3e7f27337fa313d68bb5a7be54bcf18cbc4b44f..d2db8f2d0b2f8bf3d762f33c4e9e1852872c41ac 100644 --- a/src/components/Feedback/FeedbackModal.tsx +++ b/src/components/Feedback/FeedbackModal.tsx @@ -22,7 +22,7 @@ import MailService from 'services/mail.service' import './feedbackModal.scss' import useExploration from 'components/Hooks/useExploration' import { UserExplorationID } from 'enum/userExploration.enum' -import EnvironementService from 'services/environement.service' +import EnvironmentService from 'services/environment.service' const FEEDBACK_EMAIL = 'ecolyo@grandlyon.com' const browser = detect() @@ -86,7 +86,7 @@ const FeedbackModal: React.FC<FeedbackModalProps> = ({ '\n' + envInfo - const subjectEnv = new EnvironementService().isProduction() + const subjectEnv = new EnvironmentService().isProduction() ? '[Ecolyo]' : '[Ecolyo - alpha]' diff --git a/src/components/Home/ConsumptionView.tsx b/src/components/Home/ConsumptionView.tsx index 0e0836b2431671b9cc8c5de20464f1b61b4fcd82..f207ac8b6f4d643b28d15f041a9925bcaf379d63 100644 --- a/src/components/Home/ConsumptionView.tsx +++ b/src/components/Home/ConsumptionView.tsx @@ -32,7 +32,6 @@ const ConsumptionView: React.FC<ConsumptionViewProps> = ({ fluidType, }: ConsumptionViewProps) => { const client = useClient() - const dispatch = useDispatch() const { currentTimeStep, loading } = useSelector( (state: AppStore) => state.ecolyo.chart diff --git a/src/components/Onboarding/WelcomeModal.spec.tsx b/src/components/Onboarding/WelcomeModal.spec.tsx index a635a8211b4c101641952546e1645a6dba43f968..9be659c49a17cfdd18097956870a6f3a710e9a07 100644 --- a/src/components/Onboarding/WelcomeModal.spec.tsx +++ b/src/components/Onboarding/WelcomeModal.spec.tsx @@ -31,6 +31,13 @@ jest.mock('components/Hooks/userInstanceSettings', () => { }, })) }) +jest.mock('services/environment.service', () => { + return jest.fn(() => { + return { + getPublicURL: () => 'https://ecolyo-agent-rec.grandlyon.com', + } + }) +}) const mockSendMail = jest.fn() jest.mock('services/mail.service', () => { return jest.fn(() => { diff --git a/src/components/Onboarding/WelcomeModal.tsx b/src/components/Onboarding/WelcomeModal.tsx index 24fd01ea791bd0d2e01d9cea4f4bde3d001fa3e4..8db78b491ef92dd9f2c9ce847426e075902e0bf7 100644 --- a/src/components/Onboarding/WelcomeModal.tsx +++ b/src/components/Onboarding/WelcomeModal.tsx @@ -5,7 +5,7 @@ import { useI18n } from 'cozy-ui/transpiled/react/I18n' import { useClient } from 'cozy-client' import { Button, Dialog, IconButton } from '@material-ui/core' import userInstanceSettings from 'components/Hooks/userInstanceSettings' -import EnvironementService from 'services/environement.service' +import EnvironmentService from 'services/environment.service' import MailService from 'services/mail.service' import Icon from 'cozy-ui/transpiled/react/Icon' import CloseIcon from 'assets/icons/ico/close.svg' @@ -31,8 +31,8 @@ const WelcomeModal = ({ open }: WelcomeModalProps) => { if (instanceSettings.public_name !== '') { username = instanceSettings.public_name } - const environementService = new EnvironementService() - const baseUrl = environementService.getPublicURL() + const environmentService = new EnvironmentService() + const baseUrl = environmentService.getPublicURL() const template = welcomeTemplate({ title: 'Bienvenue sur Ecolyo !', username: username, diff --git a/src/services/environement.service.spec.ts b/src/services/environement.service.spec.ts index be29f53368e395d7febcafb438ba89c95ca07988..3ff3841ee62c17f275984abf4c19ce5230eee7ff 100644 --- a/src/services/environement.service.spec.ts +++ b/src/services/environement.service.spec.ts @@ -1,37 +1,23 @@ -import EnvironementService from './environement.service' +import EnvironmentService from './environment.service' describe('Environement service', () => { - const OLD_ENV = process.env - beforeEach(() => { - jest.resetModules() // Most important - it clears the cache - process.env = { ...OLD_ENV } // Make a copy - }) - - afterAll(() => { - process.env = OLD_ENV // Restore old environment - }) - const environementService = new EnvironementService() + const environmentService = new EnvironmentService() describe('isProduction method', () => { - it('should return true', async () => { - process.env.IS_ALPHA = 'toto' - process.env.NODE_ENV = 'production' - const result = environementService.isProduction() + it('should return true and prod url', async () => { + global.__IS_ALPHA__ = false + const result = environmentService.isProduction() expect(result).toEqual(true) + const url = environmentService.getPublicURL() + expect(url).toEqual('https://ecolyo-agent.grandlyon.com') }) - it('should return false, developement case', async () => { - process.env.IS_ALPHA = 'true' - process.env.NODE_ENV = 'development' - const result = environementService.isProduction() - expect(result).toEqual(false) - }) - - it('should return false, alpha case', async () => { - process.env.IS_ALPHA = 'true' - process.env.NODE_ENV = 'production' - const result = environementService.isProduction() + it('should return false and rec url, alpha case', async () => { + global.__IS_ALPHA__ = true + const result = environmentService.isProduction() expect(result).toEqual(false) + const url = environmentService.getPublicURL() + expect(url).toEqual('https://ecolyo-agent-rec.grandlyon.com') }) }) }) diff --git a/src/services/environement.service.ts b/src/services/environment.service.ts similarity index 55% rename from src/services/environement.service.ts rename to src/services/environment.service.ts index 268d437981e02a1e0b9d0868141e441d85c77afa..0fb89f8f4f67c7ba49f64e067885c293c33c708c 100644 --- a/src/services/environement.service.ts +++ b/src/services/environment.service.ts @@ -1,16 +1,21 @@ -export default class EnvironementService { +declare const __IS_ALPHA__: boolean + +export default class EnvironmentService { private isAlpha() { - return process.env.IS_ALPHA + if (__IS_ALPHA__) { + return __IS_ALPHA__ + } + return false } public isProduction() { - if (this.isAlpha() !== 'true') { + if (!this.isAlpha()) { return true } return false } public getPublicURL() { - if (this.isAlpha() !== 'true') { + if (!this.isAlpha()) { return 'https://ecolyo-agent.grandlyon.com' } else { return 'https://ecolyo-agent-rec.grandlyon.com' diff --git a/src/services/partnersInfo.service.spec.ts b/src/services/partnersInfo.service.spec.ts index 2a66339fd07035c71b86c13a0d1d1b0db735388e..f96b94fb40c06389eb8c78807f2974ff1e0914db 100644 --- a/src/services/partnersInfo.service.spec.ts +++ b/src/services/partnersInfo.service.spec.ts @@ -2,6 +2,14 @@ import { PartnersInfo } from 'models/partnersInfo.model' import mockClient from '../../tests/__mocks__/client' import PartnersInfoService from './partnersInfo.service' +jest.mock('services/environment.service', () => { + return jest.fn(() => { + return { + isProduction: () => true, + } + }) +}) + describe('PartnersInfo service', () => { const partnersInfoService = new PartnersInfoService(mockClient) diff --git a/src/services/partnersInfo.service.ts b/src/services/partnersInfo.service.ts index 202629f7b7b783c5b482f1b3e479efdc6f03fdbc..2ac0111891c3454701445aeb4d637e885d8db7ad 100644 --- a/src/services/partnersInfo.service.ts +++ b/src/services/partnersInfo.service.ts @@ -1,6 +1,6 @@ import { Client } from 'cozy-client' import { PartnersInfo } from 'models/partnersInfo.model' -import EnvironementService from './environement.service' +import EnvironmentService from './environment.service' export default class PartnersInfoService { private readonly _client: Client @@ -15,7 +15,7 @@ export default class PartnersInfoService { * Else, throw an error */ public async getPartnersInfo(): Promise<PartnersInfo> { - const env = new EnvironementService() + const env = new EnvironmentService() const remoteUrl = env.isProduction() ? `/remote/org.ecolyo.backoffice.partners.info` : `/remote/org.ecolyo.backoffice.partners.info.rec` diff --git a/src/styles/index.css b/src/styles/index.css index 4db44fc1b7d059b206b42e29696120b6c7b7ff02..049ceff4849fb46ae394e1707c1a164e3ac5db92 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -1147,7 +1147,7 @@ button.btn-profile-back { cursor: pointer; } /* line 15, src/styles/base/_mixins.scss */ button.btn-profile-back span:first-child { - color: #7b7b7b; } + color: #a0a0a0; } /* line 24, src/styles/base/_mixins.scss */ button.btn-profile-back:disabled { cursor: not-allowed; } diff --git a/src/targets/services/aggregatorUsageEvents.ts b/src/targets/services/aggregatorUsageEvents.ts index 3760f051fcc1004e0744d83ca377f2f9796856ad..854e74c7aa9bdedb8883cab8e569f1927bc65343 100644 --- a/src/targets/services/aggregatorUsageEvents.ts +++ b/src/targets/services/aggregatorUsageEvents.ts @@ -12,7 +12,7 @@ import FluidService from 'services/fluid.service' import { FluidState, FluidType } from 'enum/fluid.enum' import { getFluidType } from 'utils/utils' import { TimeStep } from 'enum/timeStep.enum' -import EnvironementService from 'services/environement.service' +import EnvironmentService from 'services/environment.service' import { DaccEvent } from 'enum/dacc.enum' import { UsageEventProperties } from 'enum/usageEventProperties.enum' import ChallengeService from 'services/challenge.service' @@ -49,10 +49,10 @@ const sendIndicator = async ( client: Client ): Promise<boolean> => { try { - const environementService = new EnvironementService() + const environmentService = new EnvironmentService() log( 'info', - environementService.isProduction() + environmentService.isProduction() ? 'Sending data to dacc' : 'Sending data to dacc-dev' ) @@ -62,7 +62,7 @@ const sendIndicator = async ( .getStackClient() .fetchJSON( 'POST', - environementService.isProduction() + environmentService.isProduction() ? '/remote/cc.cozycloud.dacc' : '/remote/cc.cozycloud.dacc.dev', { diff --git a/src/targets/services/consumptionAlert.ts b/src/targets/services/consumptionAlert.ts index 77227394457adc670ec8007e390c31b94c39725f..b34de110bd51705caea590d50adc2844d8fc1379 100644 --- a/src/targets/services/consumptionAlert.ts +++ b/src/targets/services/consumptionAlert.ts @@ -10,7 +10,7 @@ import mjml2html from 'mjml' import { FluidType } from 'enum/fluid.enum' import ConsumptionService from 'services/consumption.service' import { getPreviousMonthName } from 'utils/utils' -import EnvironementService from 'services/environement.service' +import EnvironmentService from 'services/environment.service' const log = logger.namespace('alert') @@ -75,10 +75,10 @@ const consumptionAlert = async ({ client }: ConsumptionAlertProps) => { const mailService = new MailService() const today = DateTime.local().setZone('utc', { keepLocalTime: true }) - const environementService = new EnvironementService() + const environmentService = new EnvironmentService() const template = consumptionLimit({ title: 'Ça déborde !', - baseUrl: environementService.getPublicURL(), + baseUrl: environmentService.getPublicURL(), username: username, clientUrl: `${appLink}/#/consumption/water`, unsubscribeUrl: `${appLink}/#/options`, diff --git a/src/targets/services/monthlyReportNotification.ts b/src/targets/services/monthlyReportNotification.ts index ac208e6e807434041e41accb058402a10724edf3..e6f0e0b3331cfaee35c3b564f03611f11615aa4f 100644 --- a/src/targets/services/monthlyReportNotification.ts +++ b/src/targets/services/monthlyReportNotification.ts @@ -12,7 +12,7 @@ import { FluidType } from 'enum/fluid.enum' import { TimeStep } from 'enum/timeStep.enum' import ConsumptionService from 'services/consumption.service' import { MonthlReport } from 'models/monthlyReport.model' -import EnvironementService from 'services/environement.service' +import EnvironmentService from 'services/environment.service' import { getMonthNameWithPrep, getPreviousMonthName } from 'utils/utils' const log = logger.namespace('report') @@ -138,10 +138,10 @@ const getMonthlyReport = async ( client: Client ): Promise<MonthlReport> => { try { - const environementService = new EnvironementService() + const environmentService = new EnvironmentService() log( 'info', - environementService.isProduction() + environmentService.isProduction() ? 'Fetching data from BO prod' : 'Fetching data from BO rec' ) @@ -150,7 +150,7 @@ const getMonthlyReport = async ( .getStackClient() .fetchJSON( 'GET', - environementService.isProduction() + environmentService.isProduction() ? `/remote/org.ecolyo.backoffice?year=${year}&month=${month}` : `/remote/org.ecolyo.backoffice.rec?year=${year}&month=${month}` ) @@ -260,8 +260,8 @@ const monthlyReportNotification = async ({ .setZone('utc', { keepLocalTime: true }) .minus({ month: 1 }) - const environementService = new EnvironementService() - const baseUrl = environementService.getPublicURL() + const environmentService = new EnvironmentService() + const baseUrl = environmentService.getPublicURL() const template = monthlyReportTemplate({ title: 'Du nouveau dans votre espace Ecolyo !',