@equinor/echo-cli 1.0.3-beta-0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +355 -354
  2. package/lib/__test__/utils/merg.test.d.ts +1 -0
  3. package/lib/__test__/utils/merg.test.js +29 -0
  4. package/lib/__test__/utils/merg.test.js.map +1 -0
  5. package/lib/config/common/buildAndCopyEchoHostForProd.d.ts +16 -0
  6. package/lib/config/common/buildAndCopyEchoHostForProd.js +38 -0
  7. package/lib/config/common/buildAndCopyEchoHostForProd.js.map +1 -0
  8. package/lib/config/common/echoManifest.d.ts +3 -0
  9. package/lib/config/common/echoManifest.js +45 -0
  10. package/lib/config/common/echoManifest.js.map +1 -0
  11. package/lib/config/common/echoModuleConfig.d.ts +31 -0
  12. package/lib/config/common/echoModuleConfig.js +34 -0
  13. package/lib/config/common/echoModuleConfig.js.map +1 -0
  14. package/lib/config/common/echoModuleId.d.ts +5 -0
  15. package/lib/config/common/echoModuleId.js +15 -0
  16. package/lib/config/common/echoModuleId.js.map +1 -0
  17. package/lib/config/common/extensions.d.ts +1 -0
  18. package/lib/config/common/extensions.js +2 -0
  19. package/lib/config/common/extensions.js.map +1 -0
  20. package/lib/config/common/getCurrentIndexFile.d.ts +2 -0
  21. package/lib/config/common/getCurrentIndexFile.js +11 -0
  22. package/lib/config/common/getCurrentIndexFile.js.map +1 -0
  23. package/lib/config/common/getPackageJson.d.ts +1 -0
  24. package/lib/config/common/getPackageJson.js +7 -0
  25. package/lib/config/common/getPackageJson.js.map +1 -0
  26. package/lib/config/common/https.d.ts +6 -0
  27. package/lib/config/common/https.js +16 -0
  28. package/lib/config/common/https.js.map +1 -0
  29. package/lib/config/common/initOptions.d.ts +26 -0
  30. package/lib/config/common/initOptions.js +32 -0
  31. package/lib/config/common/initOptions.js.map +1 -0
  32. package/lib/config/common/ssl.d.ts +7 -0
  33. package/lib/config/common/ssl.js +76 -0
  34. package/lib/config/common/ssl.js.map +1 -0
  35. package/lib/config/common/updateEnv.d.ts +6 -0
  36. package/lib/config/common/updateEnv.js +16 -0
  37. package/lib/config/common/updateEnv.js.map +1 -0
  38. package/lib/config/webpack/config.d.ts +3 -0
  39. package/lib/config/webpack/config.js +36 -0
  40. package/lib/config/webpack/config.js.map +1 -0
  41. package/lib/config/webpack/configBuilders/devServer.d.ts +8 -0
  42. package/lib/config/webpack/configBuilders/devServer.js +60 -0
  43. package/lib/config/webpack/configBuilders/devServer.js.map +1 -0
  44. package/lib/config/webpack/configBuilders/entry.d.ts +12 -0
  45. package/lib/config/webpack/configBuilders/entry.js +13 -0
  46. package/lib/config/webpack/configBuilders/entry.js.map +1 -0
  47. package/lib/config/webpack/configBuilders/module.d.ts +8 -0
  48. package/lib/config/webpack/configBuilders/module.js +124 -0
  49. package/lib/config/webpack/configBuilders/module.js.map +1 -0
  50. package/lib/config/webpack/configBuilders/optimization.d.ts +7 -0
  51. package/lib/config/webpack/configBuilders/optimization.js +30 -0
  52. package/lib/config/webpack/configBuilders/optimization.js.map +1 -0
  53. package/lib/config/webpack/configBuilders/output.d.ts +12 -0
  54. package/lib/config/webpack/configBuilders/output.js +20 -0
  55. package/lib/config/webpack/configBuilders/output.js.map +1 -0
  56. package/lib/config/webpack/configBuilders/plugins.d.ts +10 -0
  57. package/lib/config/webpack/configBuilders/plugins.js +29 -0
  58. package/lib/config/webpack/configBuilders/plugins.js.map +1 -0
  59. package/lib/config/webpack/echoWebpackModule.d.ts +2 -0
  60. package/lib/config/webpack/echoWebpackModule.js +47 -0
  61. package/lib/config/webpack/echoWebpackModule.js.map +1 -0
  62. package/lib/config/webpack/server.d.ts +3 -0
  63. package/lib/config/webpack/server.js +22 -0
  64. package/lib/config/webpack/server.js.map +1 -0
  65. package/lib/const/common.d.ts +6 -0
  66. package/lib/const/common.js +15 -0
  67. package/lib/const/common.js.map +1 -0
  68. package/lib/echo-build-dev-host.d.ts +6 -0
  69. package/lib/echo-build-dev-host.js +19 -0
  70. package/lib/echo-build-dev-host.js.map +1 -0
  71. package/lib/echo-build.d.ts +34 -0
  72. package/lib/echo-build.js +83 -0
  73. package/lib/echo-build.js.map +1 -0
  74. package/lib/echo-create.d.ts +16 -0
  75. package/lib/echo-create.js +35 -0
  76. package/lib/echo-create.js.map +1 -0
  77. package/lib/echo-dev-host/.env +29 -0
  78. package/lib/echo-dev-host/README.md +121 -0
  79. package/lib/echo-dev-host/babel.config.js +11 -0
  80. package/lib/echo-dev-host/env.sh +51 -0
  81. package/lib/echo-dev-host/jest.config.js +21 -0
  82. package/lib/echo-dev-host/package-lock.json +12555 -0
  83. package/lib/echo-dev-host/package.json +80 -0
  84. package/lib/echo-dev-host/public/env-config.js +17 -0
  85. package/lib/echo-dev-host/public/index.css +60 -0
  86. package/lib/echo-dev-host/public/index.html +21 -0
  87. package/lib/echo-dev-host/src/api/api-plants.ts +23 -0
  88. package/lib/echo-dev-host/src/app.css +12 -0
  89. package/lib/echo-dev-host/src/app.tsx +43 -0
  90. package/lib/echo-dev-host/src/components/Home/Home.tsx +23 -0
  91. package/lib/echo-dev-host/src/components/Home/home.module.css +38 -0
  92. package/lib/echo-dev-host/src/components/dummySearchPanel/DummySearchPanel.tsx +28 -0
  93. package/lib/echo-dev-host/src/components/dummySearchPanel/dummySearchPanel.module.css +13 -0
  94. package/lib/echo-dev-host/src/components/legend.tsx +3 -0
  95. package/lib/echo-dev-host/src/images/frontpage-brand-placeholder.jpg +0 -0
  96. package/lib/echo-dev-host/src/index.tsx +91 -0
  97. package/lib/echo-dev-host/src/setupTests.ts +25 -0
  98. package/lib/echo-dev-host/src/utils/plants.test.ts +33 -0
  99. package/lib/echo-dev-host/src/utils/plants.ts +12 -0
  100. package/lib/echo-dev-host/src/utils/setupSkipAuth.ts +43 -0
  101. package/lib/echo-dev-host/tsconfig.json +21 -0
  102. package/lib/echo-dev-host/webpack.config.js +145 -0
  103. package/lib/echo-manifest.d.ts +6 -0
  104. package/lib/echo-manifest.js +13 -0
  105. package/lib/echo-manifest.js.map +1 -0
  106. package/lib/tools/buildScripts/buildAndCopyDevHost.d.ts +29 -0
  107. package/lib/tools/buildScripts/buildAndCopyDevHost.js +135 -0
  108. package/lib/tools/buildScripts/buildAndCopyDevHost.js.map +1 -0
  109. package/lib/tools/buildScripts/webpackBuilds.d.ts +3 -0
  110. package/lib/tools/buildScripts/webpackBuilds.js +87 -0
  111. package/lib/tools/buildScripts/webpackBuilds.js.map +1 -0
  112. package/lib/tools/create/copyFile.d.ts +2 -0
  113. package/lib/tools/create/copyFile.js +16 -0
  114. package/lib/tools/create/copyFile.js.map +1 -0
  115. package/lib/tools/create/createProject.d.ts +2 -0
  116. package/lib/tools/create/createProject.js +83 -0
  117. package/lib/tools/create/createProject.js.map +1 -0
  118. package/lib/tools/create/createSetTargetDirectory.d.ts +1 -0
  119. package/lib/tools/create/createSetTargetDirectory.js +12 -0
  120. package/lib/tools/create/createSetTargetDirectory.js.map +1 -0
  121. package/lib/tools/create/getAppTemplateName.d.ts +1 -0
  122. package/lib/tools/create/getAppTemplateName.js +22 -0
  123. package/lib/tools/create/getAppTemplateName.js.map +1 -0
  124. package/lib/tools/create/gitInit.d.ts +1 -0
  125. package/lib/tools/create/gitInit.js +19 -0
  126. package/lib/tools/create/gitInit.js.map +1 -0
  127. package/lib/tools/create/promptOptions.d.ts +2 -0
  128. package/lib/tools/create/promptOptions.js +88 -0
  129. package/lib/tools/create/promptOptions.js.map +1 -0
  130. package/lib/tools/create/updatePackageConfig.d.ts +2 -0
  131. package/lib/tools/create/updatePackageConfig.js +28 -0
  132. package/lib/tools/create/updatePackageConfig.js.map +1 -0
  133. package/lib/tools/create/updateReadme.d.ts +2 -0
  134. package/lib/tools/create/updateReadme.js +23 -0
  135. package/lib/tools/create/updateReadme.js.map +1 -0
  136. package/lib/types/createTypes.d.ts +23 -0
  137. package/lib/types/createTypes.js +2 -0
  138. package/lib/types/createTypes.js.map +1 -0
  139. package/lib/types/types.d.ts +4 -0
  140. package/lib/types/types.js +2 -0
  141. package/lib/types/types.js.map +1 -0
  142. package/lib/update-echo-libs.d.ts +9 -0
  143. package/lib/update-echo-libs.js +188 -0
  144. package/lib/update-echo-libs.js.map +1 -0
  145. package/lib/utils/findConsumerAppPackageJson.d.ts +11 -0
  146. package/lib/utils/findConsumerAppPackageJson.js +55 -0
  147. package/lib/utils/findConsumerAppPackageJson.js.map +1 -0
  148. package/lib/utils/findTopLevelNodeModulesWithCli.d.ts +12 -0
  149. package/lib/utils/findTopLevelNodeModulesWithCli.js +28 -0
  150. package/lib/utils/findTopLevelNodeModulesWithCli.js.map +1 -0
  151. package/lib/utils/getFile.d.ts +34 -0
  152. package/lib/utils/getFile.js +72 -0
  153. package/lib/utils/getFile.js.map +1 -0
  154. package/lib/utils/getFilePath.d.ts +1 -0
  155. package/lib/utils/getFilePath.js +22 -0
  156. package/lib/utils/getFilePath.js.map +1 -0
  157. package/lib/utils/getLatestPkgVersion.d.ts +14 -0
  158. package/lib/utils/getLatestPkgVersion.js +30 -0
  159. package/lib/utils/getLatestPkgVersion.js.map +1 -0
  160. package/lib/utils/logo.d.ts +1 -0
  161. package/lib/utils/logo.js +12 -0
  162. package/lib/utils/logo.js.map +1 -0
  163. package/lib/utils/merge.d.ts +1 -0
  164. package/lib/utils/merge.js +8 -0
  165. package/lib/utils/merge.js.map +1 -0
  166. package/lib/utils/printEchoLibsVersions.d.ts +23 -0
  167. package/lib/utils/printEchoLibsVersions.js +162 -0
  168. package/lib/utils/printEchoLibsVersions.js.map +1 -0
  169. package/lib/utils/timer.d.ts +0 -0
  170. package/lib/utils/timer.js +2 -0
  171. package/lib/utils/timer.js.map +1 -0
  172. package/package.json +110 -110
  173. package/templates/echoAppTemplate/.gitattributes +3 -3
  174. package/templates/echoAppTemplate/package.json +35 -35
  175. package/templates/echoAppTemplate/readme.md +41 -41
  176. package/templates/echoAppTemplate/tsconfig.json +25 -25
  177. package/templates/echoAppTemplateTutorial/.gitattributes +3 -3
  178. package/templates/echoAppTemplateTutorial/package.json +36 -36
  179. package/templates/echoAppTemplateTutorial/readme.md +41 -41
  180. package/templates/echoAppTemplateTutorial/tsconfig.json +25 -25
  181. package/templates/echoLibraryTemplate/package.json +35 -35
  182. package/templates/echoLibraryTemplate/public/index.html +21 -21
  183. package/templates/echoLibraryTemplate/readme.md +1 -1
  184. package/templates/echoPluginTemplate/package.json +35 -35
  185. package/templates/echoPluginTemplate/public/index.html +21 -21
  186. package/templates/echoPluginTemplate/readme.md +1 -1
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@equinor/echo-dev-host",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "webpack serve --mode development --env development --open --hot",
8
+ "build-client": "webpack --env development --env=cli=true",
9
+ "build": "webpack --mode development",
10
+ "echo-update": "echo-update",
11
+ "echo-update-version": "echo-update -v",
12
+ "echo-update-next": "echo-update -c",
13
+ "echo-update-all": "echo-update -a",
14
+ "echo-test": "jest",
15
+ "lint": "eslint --ext .js,.jsx,.ts,.tsx src --color",
16
+ "test-wo-install": "jest --watchAll",
17
+ "test": "npm ci & jest --watchAll",
18
+ "test-coverage": "npm ci & jest --coverage --watchAll",
19
+ "unlink-echo-search": "node unlink-echo-search.js"
20
+ },
21
+ "author": "",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@equinor/echo-base": "1.3.0",
25
+ "@equinor/echo-components": "1.3.0",
26
+ "@equinor/echo-core": "1.3.0",
27
+ "@equinor/echo-framework": "1.3.0",
28
+ "@equinor/echo-scripts": "0.1.5",
29
+ "@equinor/echo-search": "1.3.0",
30
+ "@equinor/echo-utils": "1.3.0",
31
+ "@equinor/eds-core-react": "0.43.0",
32
+ "@equinor/eds-icons": "0.22.0",
33
+ "@equinor/eds-utils": "0.8.7",
34
+ "@microsoft/signalr": "9.0.6",
35
+ "@svgr/webpack": "8.1.0",
36
+ "@tanstack/react-query": "5.90.2",
37
+ "classnames": "2.5.1",
38
+ "fs-extra": "11.3.0",
39
+ "history": "5.3.0",
40
+ "immer": "10.1.3",
41
+ "lodash": "4.17.21",
42
+ "react": "18.3.1",
43
+ "react-dom": "18.3.1",
44
+ "react-router-dom": "5.3.4",
45
+ "react-sortablejs": "6.1.4",
46
+ "sortablejs": "1.15.6",
47
+ "styled-components": "6.1.19",
48
+ "zustand": "4.5.7"
49
+ },
50
+ "devDependencies": {
51
+ "@babel/core": "7.28.4",
52
+ "@babel/plugin-transform-runtime": "7.27.1",
53
+ "@babel/polyfill": "7.12.1",
54
+ "@babel/preset-env": "7.27.2",
55
+ "@babel/preset-react": "7.27.1",
56
+ "@babel/preset-typescript": "7.27.1",
57
+ "@equinor/echo-update": "1.3.3",
58
+ "@types/jest": "30.0.0",
59
+ "@types/node": "24.3.0",
60
+ "@types/react": "18.3.12",
61
+ "@types/react-dom": "18.3.1",
62
+ "@types/react-router-dom": "5.3.3",
63
+ "@types/webpack-env": "1.18.8",
64
+ "babel-loader": "10.0.0",
65
+ "copy-webpack-plugin": "13.0.0",
66
+ "css-loader": "7.1.2",
67
+ "dotenv-webpack": "8.1.0",
68
+ "file-loader": "6.2.0",
69
+ "html-webpack-plugin": "5.6.3",
70
+ "jest": "30.2.0",
71
+ "style-loader": "4.0.0",
72
+ "ts-jest": "29.4.5",
73
+ "ts-loader": "9.5.2",
74
+ "typescript": "5.9.3",
75
+ "webpack": "5.102.1",
76
+ "webpack-cli": "6.0.1",
77
+ "webpack-dev-server": "5.2.1",
78
+ "webpackbar": "7.0.0"
79
+ }
80
+ }
@@ -0,0 +1,17 @@
1
+ window._env_ = {
2
+ HTTPS: "true",
3
+ GENERATE_SOURCEMAP: "true",
4
+ INLINE_RUNTIME_CHUNK: "false",
5
+ WEBSITE_HOSTNAME: "localhost:3000;",
6
+ REACT_APP_DEFAULT_CACHE_LOCATION: "localstorage",
7
+ REACT_APP_API_URL: "https://dt-echopedia-api-dev.azurewebsites.net",
8
+ REACT_APP_WEB_URL: "https://dt-echopedia-web-dev.azurewebsites.net",
9
+ REACT_APP_WEB_PROD_URL: "https://echo.equinor.com",
10
+ REACT_APP_AZURE_AD_TENNANT: "StatoilSRM.onmicrosoft.com",
11
+ REACT_APP_AZURE_AD_TENNANT_ID: "3aa4a235-b6e2-48d5-9195-7fcf05b459b0",
12
+ REACT_APP_AZURE_AD_CLIENT_ID: "751d2504-0b66-4b78-9807-4b60525a14c6",
13
+ REACT_APP_API_CLIENT_ID: "aef35d97-53d4-4fd0-adaf-c5a514b38436",
14
+ REACT_APP_APPINSIGHTS_CONNECTION_STRING: "InstrumentationKey=e5299075-a00d-4012-96f9-42861e8d8a9e;IngestionEndpoint=https://northeurope-3.in.applicationinsights.azure.com/;LiveEndpoint=https://northeurope.livediagnostics.monitor.azure.com/;ApplicationId=a9b64222-d4a9-42e6-a615-7428fe1a26af",
15
+ REACT_APP_AZURE_BUILD_NUMBER: "0.8.dev.9",
16
+ REACT_APP_LOGGER_ACTIVE: "false",
17
+ }
@@ -0,0 +1,60 @@
1
+ body {
2
+ overflow: hidden;
3
+ margin: 0;
4
+ }
5
+
6
+ .highlightedText {
7
+ background: yellow;
8
+ color: black;
9
+ padding: 0;
10
+ }
11
+
12
+ #rootloading {
13
+ display: flex;
14
+ flex-direction: column;
15
+ color: #ff1243;
16
+ justify-content: center;
17
+ align-items: center;
18
+ text-align: center;
19
+ position: absolute;
20
+ width: 100%;
21
+ height: 100%;
22
+ }
23
+
24
+ .loaderContainer {
25
+ margin: 8px auto;
26
+ display: flex;
27
+ flex-direction: column;
28
+ padding-top: 0;
29
+ }
30
+
31
+ .productLogo {
32
+ flex: 1;
33
+ margin-bottom: 4rem;
34
+ text-align: left;
35
+ }
36
+
37
+ .productLogoImg {
38
+ display: inline-block;
39
+ vertical-align: baseline;
40
+ width: 122px;
41
+ animation: fadeIn 0.5s;
42
+ }
43
+
44
+ .equinorLogo {
45
+ margin: 0 auto;
46
+ display: inline-block;
47
+ vertical-align: baseline;
48
+ width: 64px;
49
+ height: 64px;
50
+ animation: fadeIn 0.5s;
51
+ }
52
+
53
+ @keyframes fadeIn {
54
+ 0% {
55
+ opacity: 0;
56
+ }
57
+ 100% {
58
+ opacity: 1;
59
+ }
60
+ }
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <script type="application/javascript" src="./env-config.js"></script>
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"
10
+ />
11
+ <link href="./index.css" rel="stylesheet" />
12
+ <link rel="stylesheet" href="https://cdn.eds.equinor.com/font/equinor-font.css" />
13
+ <link rel="preconnect" href="https://login.microsoftonline.com" />
14
+ <link rel="preconnect" href="https://dc.services.visualstudio.com" />
15
+ <link rel="preconnect" href="https://cdn.eds.equinor.com" />
16
+ <title>Echo | Development</title>
17
+ </head>
18
+ <body>
19
+ <div id="root"></div>
20
+ </body>
21
+ </html>
@@ -0,0 +1,23 @@
1
+ import { EchoEnv, Plant, request, setPlantsData } from '@equinor/echo-core';
2
+
3
+ async function getPlantsFromApi(): Promise<Plant[] | undefined> {
4
+ const url = `${EchoEnv.env().REACT_APP_API_URL}/plants`;
5
+ return request<Plant[]>({
6
+ url,
7
+ cache: {
8
+ timeInSeconds: 4 * 60 * 60 // 4 hours
9
+ }
10
+ });
11
+ }
12
+
13
+ export async function getCorePlants(): Promise<void> {
14
+ try {
15
+ const apiPlants = (await getPlantsFromApi()) ?? [];
16
+
17
+ if (apiPlants && apiPlants.length > 0) {
18
+ setPlantsData({ plants: apiPlants });
19
+ }
20
+ } catch (ex) {
21
+ console.error(ex);
22
+ }
23
+ }
@@ -0,0 +1,12 @@
1
+ /* Applied in echo application by bootstrap so it should exist here to */
2
+ *,
3
+ :after,
4
+ :before {
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ #root {
9
+ height: 100%;
10
+ overflow: hidden;
11
+ width: 100%;
12
+ }
@@ -0,0 +1,43 @@
1
+ import { EchoEnv, useInitial } from '@equinor/echo-core';
2
+ import { displayToast, EchoContent, EchoEventHandler, EchoRoutes, Toasters } from '@equinor/echo-framework';
3
+ import { Syncer } from '@equinor/echo-search';
4
+ import React from 'react';
5
+ import { Redirect as TypedRedirect, Route as TypedRoute, Switch as TypedSwitch } from 'react-router-dom';
6
+ import { getCorePlants } from './api/api-plants';
7
+ import './app.css';
8
+ import { Home } from './components/Home/Home';
9
+ import { Legend } from './components/legend';
10
+
11
+ export const EchoApp: React.FC = () => {
12
+ useInitial(async () => {
13
+ await Syncer.configuration.setApiBaseUrl(EchoEnv.env().REACT_APP_API_URL);
14
+ fireAndForget(getCorePlants, {
15
+ userFriendlyErrorMessage: '[echo-dev-host][app.tsx] Failed to load plants data',
16
+ displayToast: true
17
+ });
18
+ });
19
+
20
+ return (
21
+ <EchoEventHandler>
22
+ <EchoContent Legend={Legend} isOnboardingCompleted={true}>
23
+ <TypedSwitch>
24
+ <EchoRoutes homeComponent={Home} />
25
+ <TypedRoute render={(): JSX.Element => <TypedRedirect to="/" />} />
26
+ </TypedSwitch>
27
+ <Toasters />
28
+ </EchoContent>
29
+ </EchoEventHandler>
30
+ );
31
+ };
32
+
33
+ function fireAndForget(
34
+ asyncFunc: () => Promise<void>,
35
+ options: { userFriendlyErrorMessage: string; displayToast?: boolean }
36
+ ): void {
37
+ asyncFunc().catch((error) => {
38
+ console.error(error, options.userFriendlyErrorMessage);
39
+ if (options.displayToast) {
40
+ displayToast({ message: options.userFriendlyErrorMessage });
41
+ }
42
+ });
43
+ }
@@ -0,0 +1,23 @@
1
+ import { AppLinks, EchoLogo, Footer, PlantSelector } from '@equinor/echo-framework';
2
+ import React from 'react';
3
+ import placeholderHomeImage from '../../images/frontpage-brand-placeholder.jpg';
4
+ import style from './home.module.css';
5
+
6
+ export const Home: React.FC = () => {
7
+ return (
8
+ <main className={style.home}>
9
+ <div className={style.plantSelector}>
10
+ <div>
11
+ <EchoLogo />
12
+ </div>
13
+
14
+ <PlantSelector />
15
+ </div>
16
+ <AppLinks />
17
+ <div className={style.brandSliderContainer}>
18
+ <img src={placeholderHomeImage} alt="Application Echo on tablet" />
19
+ </div>
20
+ <Footer />
21
+ </main>
22
+ );
23
+ };
@@ -0,0 +1,38 @@
1
+ .home {
2
+ display: grid;
3
+ grid-template-rows: 30% 100px auto 56px;
4
+ gap: 1rem;
5
+ height: 100%;
6
+ width: 100%;
7
+ }
8
+
9
+ .plantSelector {
10
+ display: flex;
11
+ justify-content: center;
12
+ align-items: baseline;
13
+ align-self: center;
14
+ flex-flow: wrap;
15
+ }
16
+
17
+ .heading {
18
+ padding-left: 18px;
19
+ }
20
+
21
+ .brandSliderContainer {
22
+ display: flex;
23
+ flex: 1 1;
24
+ flex-flow: column-reverse;
25
+ margin: 0;
26
+ width: 100%;
27
+ overflow: hidden;
28
+ object-fit: cover;
29
+ }
30
+
31
+ .appBar {
32
+ margin: 0 auto 48px;
33
+ display: flex;
34
+ flex-wrap: wrap;
35
+ justify-content: center;
36
+ align-items: flex-start;
37
+ }
38
+
@@ -0,0 +1,28 @@
1
+ import { ECHO_CORE_SEARCH, Panel, PanelType } from '@equinor/echo-core';
2
+ import React from 'react';
3
+ import style from './dummySearchPanel.module.css';
4
+
5
+ const DummySearchMenu: React.FC = () => {
6
+ return (
7
+ <div className={style.wrapper}>
8
+ <div className={style.panel}>
9
+ <h3>SearchMenu</h3>
10
+ <p>
11
+ You're running your echo app in <b>echo-dev-host</b>, a host application for echo apps / modules.
12
+ </p>
13
+ <p>
14
+ <b>echo-dev-host</b> is a bare-bones version of the original app, echopediaWeb. The purpose of it is
15
+ to help echo teams to develop their app independently from echopediaWeb itself.
16
+ </p>
17
+ </div>
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export const dummySearchPanel: Panel = {
23
+ component: DummySearchMenu,
24
+ panelType: PanelType.left,
25
+ key: ECHO_CORE_SEARCH,
26
+ icon: 'search',
27
+ label: 'Search'
28
+ };
@@ -0,0 +1,13 @@
1
+ .panel {
2
+ padding: var(--small);
3
+ }
4
+
5
+ .wrapper {
6
+ display: flex;
7
+ flex-direction: column;
8
+ margin: 10px;
9
+ }
10
+
11
+ .close {
12
+ align-self: end;
13
+ }
@@ -0,0 +1,3 @@
1
+ export const Legend: React.FC = () => {
2
+ return null;
3
+ };
@@ -0,0 +1,91 @@
1
+ import { LoadingModuleOptions } from '@equinor/echo-base';
2
+ import '@equinor/echo-components/style-reset.css';
3
+ import EchoCore, { createEchoAppModuleApi, EventHubProvider, queryClient } from '@equinor/echo-core';
4
+ import { mainMenu, Mediator } from '@equinor/echo-framework';
5
+ import { Icon } from '@equinor/eds-core-react';
6
+ import * as Icons from '@equinor/eds-icons';
7
+ import React from 'react';
8
+ import { initForE2ETests } from './utils/setupSkipAuth';
9
+
10
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
11
+ import { createRoot } from 'react-dom/client';
12
+ import { BrowserRouter } from 'react-router-dom';
13
+ import { EchoApp } from './app';
14
+ import { dummySearchPanel } from './components/dummySearchPanel/DummySearchPanel';
15
+
16
+ const useEdsIcon = (): void => {
17
+ Icon.add({
18
+ ...Icons
19
+ });
20
+ };
21
+
22
+ const Echo: React.FC = (): JSX.Element => {
23
+ /* Needed to skip authentication when running e2e tests*/
24
+ initForE2ETests();
25
+
26
+ const isAuthenticated = EchoCore.useEchoSetup({
27
+ leftPanels: [dummySearchPanel],
28
+ rightPanel: mainMenu
29
+ });
30
+ useEdsIcon();
31
+ const moduleOptions: LoadingModuleOptions = {
32
+ createApi: createEchoAppModuleApi(),
33
+ dependencies: {
34
+ react: require('react'),
35
+ 'react-dom': require('react-dom'),
36
+ 'react-router-dom': require('react-router-dom'),
37
+ '@equinor/echo-core': require('@equinor/echo-core'),
38
+ '@equinor/echo-framework': require('@equinor/echo-framework'),
39
+ '@equinor/echo-utils': require('@equinor/echo-utils'),
40
+ '@equinor/echo-components': require('@equinor/echo-components'),
41
+ '@equinor/echo-base': require('@equinor/echo-base'),
42
+ '@equinor/echo-search': require('@equinor/echo-search'),
43
+ '@equinor/eds-core-react': require('@equinor/eds-core-react'),
44
+ '@equinor/eds-icons': require('@equinor/eds-icons'),
45
+ 'styled-components': require('styled-components'),
46
+ classnames: require('classnames'),
47
+ lodash: require('lodash'),
48
+ zustand: require('zustand')
49
+ },
50
+ fetchModules: () => {
51
+ return new Promise((resolve) => {
52
+ fetch('/echoModuleManifest.json').then((response) => {
53
+ response.json().then((manifests) => {
54
+ manifests.forEach((manifest) => {
55
+ manifest.fileUri = `/index.js`;
56
+ });
57
+ resolve(manifests);
58
+ });
59
+ });
60
+ });
61
+ }
62
+ };
63
+ return (
64
+ <>
65
+ {isAuthenticated && (
66
+ <EchoCore.AuthProviderComponent>
67
+ {/*
68
+ Need to cast queryClient to QueryClient because of the following error:
69
+ TS2352: Conversion of type 'import("Equinor\\EchopediaWeb\\node_modules\\@tanstack\\query-core\\build\\modern\\hydration-CwYEwyQI").b' to type 'import("Equinor\\EchopediaWeb\\node_modules\\@tanstack\\query-core\\build\\modern\\hydration-BlEK5ylC").b' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
70
+ Property '#private' in type 'QueryClient' refers to a different member that cannot be accessed from within type 'QueryClient'.
71
+ Based on my research we used the same version of react-query in echopediaWeb and echo-client.
72
+ */}
73
+ <QueryClientProvider client={queryClient as unknown as QueryClient}>
74
+ <EventHubProvider>
75
+ <Mediator options={moduleOptions} />
76
+ <BrowserRouter>
77
+ <EchoApp />
78
+ </BrowserRouter>
79
+ </EventHubProvider>
80
+ </QueryClientProvider>
81
+ </EchoCore.AuthProviderComponent>
82
+ )}
83
+ </>
84
+ );
85
+ };
86
+
87
+ if (!(window !== window.parent && !window.opener)) {
88
+ const container = document.getElementById('root') as HTMLElement;
89
+ const root = createRoot(container);
90
+ root.render(<Echo />);
91
+ }
@@ -0,0 +1,25 @@
1
+ export {};
2
+ // Should remove this error: BrowserAuthError: crypto_nonexistent: The crypto object or function is not available. Detail:Browser crypto or msCrypto object not available.
3
+ const mGetRandomValues = jest.fn().mockReturnValueOnce(new Uint32Array(10));
4
+ Object.defineProperty(window, 'crypto', {
5
+ value: { getRandomValues: mGetRandomValues }
6
+ });
7
+
8
+ jest.mock('@equinor/echo-core', () => {
9
+ return {
10
+ __esModule: true,
11
+ ...jest.requireActual('@equinor/echo-core'),
12
+ storage: {
13
+ getItem: jest.fn(),
14
+ setItem: jest.fn()
15
+ },
16
+ EchoEnv: {
17
+ env: jest.fn().mockImplementation(() => {
18
+ return {
19
+ REACT_APP_AZURE_AD_CLIENT_ID: '',
20
+ REACT_APP_API_URL: 'non-mono-base-api-url'
21
+ };
22
+ })
23
+ }
24
+ };
25
+ });
@@ -0,0 +1,33 @@
1
+ import { Plant } from '@equinor/echo-core';
2
+ import { checkIsPlantsListUpdated } from './plants';
3
+
4
+ describe('checkIsPlantsListUpdated', () => {
5
+ const originalPlant: Plant = {
6
+ instCode: 'JSV',
7
+ hasTr2000: true,
8
+ description: 'A description',
9
+ sapPlantId: '',
10
+ proCoSysPlantId: ''
11
+ };
12
+ const updatedPlant: Plant = { ...originalPlant, description: 'A changed description' };
13
+ it('should return false if lists are identical', () => {
14
+ // given
15
+ const apiPlants = [originalPlant];
16
+ const localStoragePlants = [originalPlant];
17
+
18
+ // when
19
+ const result = checkIsPlantsListUpdated(apiPlants, localStoragePlants);
20
+
21
+ expect(result).toBe(false);
22
+ });
23
+ it('should return true if lists are not identical', () => {
24
+ // given
25
+ const apiPlants = [updatedPlant];
26
+ const localStoragePlants = [originalPlant];
27
+
28
+ // when
29
+ const result = checkIsPlantsListUpdated(apiPlants, localStoragePlants);
30
+
31
+ expect(result).toBe(true);
32
+ });
33
+ });
@@ -0,0 +1,12 @@
1
+ import { Plant } from '@equinor/echo-core';
2
+ import EchoUtils from '@equinor/echo-utils';
3
+
4
+ const { arraysIsEqual } = EchoUtils.Utils;
5
+
6
+ export const checkIsPlantsListUpdated = (apiPlants: Plant[], localStoragePlants: Plant[]): boolean => {
7
+ if (!localStoragePlants || localStoragePlants.length === 0 || !arraysIsEqual([...localStoragePlants], apiPlants)) {
8
+ return true;
9
+ } else {
10
+ return false;
11
+ }
12
+ };
@@ -0,0 +1,43 @@
1
+ import EchoCore, { AuthenticationResult } from '@equinor/echo-core';
2
+ import { getDeepLinkParams } from '@equinor/echo-utils';
3
+
4
+ export function initForE2ETests() {
5
+ const { skipAuth } = getDeepLinkParams(['skipAuth']);
6
+ if (skipAuth?.toLowerCase() === 'true') {
7
+ setupSkipAuth();
8
+ }
9
+ }
10
+
11
+ const setAuthentication = () => {
12
+ EchoCore.EchoAuthProvider.isAuthenticated = true;
13
+ EchoCore.EchoAuthProvider.userProperties = {
14
+ account: {
15
+ homeAccountId: 'homeAccountId',
16
+ environment: 'testingEnvironment',
17
+ tenantId: 'tenantId',
18
+ username: 'tester',
19
+ localAccountId: 'tester123'
20
+ }
21
+ };
22
+ };
23
+
24
+ export function setupSkipAuth() {
25
+ EchoCore.EchoAuthProvider.isAuthenticated = true;
26
+ EchoCore.EchoAuthProvider.handleLogin = async (logRequest?: (...args: unknown[]) => void): Promise<void> => {
27
+ setAuthentication();
28
+ return Promise.resolve(undefined);
29
+ };
30
+ EchoCore.EchoAuthProvider.ssoSilentOrRedirectToAuthenticate = async () => {
31
+ setAuthentication();
32
+ return Promise.resolve(undefined);
33
+ };
34
+ EchoCore.EchoAuthProvider.aquireTokenSilentOrRedirectToAuthenticate =
35
+ async (): Promise<AuthenticationResult | null> => {
36
+ setAuthentication();
37
+ return null;
38
+ };
39
+ EchoCore.EchoAuthProvider.login = async () => {
40
+ setAuthentication();
41
+ return Promise.resolve();
42
+ };
43
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "jsx": "react-jsx",
5
+ "lib": ["dom", "dom.iterable", "esnext"],
6
+ "allowSyntheticDefaultImports": true,
7
+ "esModuleInterop": true,
8
+ "module": "commonjs",
9
+ "outDir": "./build/",
10
+ "preserveConstEnums": true,
11
+ "removeComments": true,
12
+ "sourceMap": true,
13
+ "noImplicitAny": false,
14
+ "allowJs": true,
15
+ "skipLibCheck": true,
16
+ "target": "es5",
17
+ "resolveJsonModule": true,
18
+ "types": ["@equinor/echo-scripts", "@types/node", "@types/webpack-env", "@types/jest"]
19
+ },
20
+ "include": ["src"]
21
+ }