@equinor/fusion-framework-dev-portal 1.1.4 → 1.2.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/fusion-framework-dev-portal",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "module": "./dist/main.js",
@@ -25,7 +25,7 @@
25
25
  "@equinor/fusion-react-side-sheet": "1.3.11",
26
26
  "@equinor/fusion-react-styles": "^0.6.4",
27
27
  "@equinor/fusion-wc-chip": "^1.2.2",
28
- "@equinor/fusion-wc-person": "^3.1.8",
28
+ "@equinor/fusion-wc-person": "^3.2.4",
29
29
  "@material-ui/styles": "^4.11.5",
30
30
  "@types/dotenv": "^8.2.3",
31
31
  "@types/react": "^18.2.50",
@@ -39,22 +39,23 @@
39
39
  "styled-components": "^6.0.7",
40
40
  "tsx": "^4.19.3",
41
41
  "typescript": "^5.8.2",
42
- "vite": "^7.1.5",
43
- "@equinor/fusion-framework": "^7.3.20",
44
- "@equinor/fusion-framework-app": "^10.0.0",
45
- "@equinor/fusion-framework-module-app": "^7.0.1",
46
- "@equinor/fusion-framework-dev-server": "^1.1.3",
47
- "@equinor/fusion-framework-module-bookmark": "^3.0.1",
48
- "@equinor/fusion-framework-module-feature-flag": "^1.1.24",
49
- "@equinor/fusion-framework-module-context": "^7.0.0",
50
- "@equinor/fusion-framework-module-services": "^7.1.2",
51
- "@equinor/fusion-framework-module-navigation": "^6.0.0",
52
- "@equinor/fusion-framework-react": "^7.4.18",
53
- "@equinor/fusion-framework-react-components-people-provider": "^1.5.23",
54
- "@equinor/fusion-framework-react-module-bookmark": "^5.0.1",
55
- "@equinor/fusion-framework-react-components-bookmark": "^1.1.0",
56
- "@equinor/fusion-query": "^5.2.14",
57
- "@equinor/fusion-observable": "^8.5.4"
42
+ "vite": "^7.1.9",
43
+ "@equinor/fusion-framework": "7.4.0",
44
+ "@equinor/fusion-framework-dev-server": "1.1.4",
45
+ "@equinor/fusion-framework-app": "10.1.0",
46
+ "@equinor/fusion-framework-module-app": "7.0.2",
47
+ "@equinor/fusion-framework-module-bookmark": "3.0.2",
48
+ "@equinor/fusion-framework-module-context": "7.0.1",
49
+ "@equinor/fusion-framework-module-services": "7.1.2",
50
+ "@equinor/fusion-framework-module-navigation": "6.0.0",
51
+ "@equinor/fusion-framework-module-feature-flag": "1.1.24",
52
+ "@equinor/fusion-framework-module-telemetry": "4.2.0",
53
+ "@equinor/fusion-framework-react": "7.4.18",
54
+ "@equinor/fusion-framework-react-components-bookmark": "1.1.1",
55
+ "@equinor/fusion-framework-react-components-people-provider": "1.5.24",
56
+ "@equinor/fusion-observable": "8.5.5",
57
+ "@equinor/fusion-query": "6.0.0",
58
+ "@equinor/fusion-framework-react-module-bookmark": "5.0.1"
58
59
  },
59
60
  "scripts": {
60
61
  "start": "tsx dev-server.ts",
package/src/AppLoader.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useEffect, useMemo, useRef, useState } from 'react';
1
+ import { useEffect, useId, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Subscription } from 'rxjs';
4
4
  import { last } from 'rxjs/operators';
@@ -26,6 +26,7 @@ export const AppLoader = (props: { readonly appKey: string }) => {
26
26
 
27
27
  /** reference of application section/container */
28
28
  const ref = useRef<HTMLElement>(null);
29
+ const applicationContentId = useId();
29
30
 
30
31
  const [loading, setLoading] = useState<boolean>(false);
31
32
  const [error, setError] = useState<Error | undefined>();
@@ -112,7 +113,7 @@ export const AppLoader = (props: { readonly appKey: string }) => {
112
113
  }
113
114
 
114
115
  return (
115
- <section id="application-content" ref={ref} style={{ display: 'contents' }}>
116
+ <section id={applicationContentId} ref={ref} style={{ display: 'contents' }}>
116
117
  {loading && <EquinorLoader text="Loading Application" />}
117
118
  </section>
118
119
  );
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useMemo } from 'react';
1
+ import { useCallback, useEffect, useId, useMemo } from 'react';
2
2
  import {
3
3
  ContextProvider,
4
4
  ContextSearch,
@@ -14,6 +14,7 @@ import { useContextResolver } from './useContextResolver';
14
14
  * @returns JSX element
15
15
  */
16
16
  export const ContextSelector = (props: ContextSearchProps): JSX.Element | null => {
17
+ const contextSelectorId = useId();
17
18
  const {
18
19
  resolver,
19
20
  provider,
@@ -53,7 +54,7 @@ export const ContextSelector = (props: ContextSearchProps): JSX.Element | null =
53
54
  <div style={{ flex: 1, maxWidth: '480px' }}>
54
55
  <ContextProvider resolver={resolver}>
55
56
  <ContextSearch
56
- id="context-selector-cli-header"
57
+ id={contextSelectorId}
57
58
  placeholder={props.placeholder ?? 'Search for context'}
58
59
  initialText={props.initialText ?? 'Start typing to search'}
59
60
  dropdownHeight={props.dropdownHeight ?? '300px'}
@@ -1,58 +1,64 @@
1
+ import { useId } from 'react';
1
2
  import type { SVGProps } from 'react';
2
3
 
3
4
  type FusionLogoProps = Omit<SVGProps<SVGSVGElement>, 'viewBox'> & {
4
5
  readonly scale?: number;
5
6
  };
6
7
 
7
- export const FusionLogo = ({ scale = 1, style }: FusionLogoProps) => (
8
- <svg viewBox="0 0 50 35" style={{ height: '1em', ...style, transform: `scale(${scale})` }}>
9
- <title>Fusion Logo</title>
10
- <path
11
- d="M0 2V23.1776L7.05405 16.1235V7.05405H16.1235L23.1776 0H2C0.895431 0 0 0.89543 0 2Z"
12
- transform="translate(50 17.5) scale(0.92727 1.06779) rotate(135)"
13
- fill="url(#paint0_linear)"
14
- />
15
- <path
16
- d="M0 2V23.1776L7.05405 16.1235V7.05405H16.1235L23.1776 0H2C0.895431 0 0 0.89543 0 2Z"
17
- transform="translate(0 17.5) scale(0.92727 1.06779) rotate(-45)"
18
- fill="url(#paint1_linear)"
19
- />
20
- <path
21
- d="M9.61965 36.6972L2.60087 29.6784L1.96135 22.3809L8.42623 22.9069L9.61965 36.6972Z"
22
- transform="translate(33.8887 34.9863) scale(0.92727 -1.06779) rotate(45)"
23
- fill="#990025"
24
- />
25
- <path
26
- d="M7.05434 7.05434L0 0L1.21096 13.8183L7.68846 14.3818L7.05434 7.05434Z"
27
- transform="translate(33.8887 34.9863) scale(0.92727 -1.06779) rotate(45)"
28
- fill="#990025"
29
- />
30
- <path
31
- d="M0 0L2.49398 29.5715L9.61965 36.6972L7.01878 7.01878L0 0Z"
32
- transform="translate(33.8887 0.015625) scale(0.92727 1.06779) rotate(45)"
33
- fill="#FF1243"
34
- />
35
- <defs>
36
- <linearGradient
37
- id="paint0_linear"
38
- x2="1"
39
- gradientUnits="userSpaceOnUse"
40
- gradientTransform="matrix(-13.5478 9.01983 -12.9578 -13.5478 18.0677 6.77391)"
41
- >
42
- <stop offset="0.508287" stopColor="#DC002E" />
43
- <stop offset="0.508387" stopColor="#FF1243" />
44
- </linearGradient>
45
- <linearGradient
46
- id="paint1_linear"
47
- x2="1"
48
- gradientUnits="userSpaceOnUse"
49
- gradientTransform="matrix(-13.5478 9.01983 -12.9578 -13.5478 18.0677 6.77391)"
50
- >
51
- <stop offset="0.508287" stopColor="#DC002E" />
52
- <stop offset="0.508387" stopColor="#FF1243" />
53
- </linearGradient>
54
- </defs>
55
- </svg>
56
- );
8
+ export const FusionLogo = ({ scale = 1, style }: FusionLogoProps) => {
9
+ const paint0Id = useId();
10
+ const paint1Id = useId();
11
+
12
+ return (
13
+ <svg viewBox="0 0 50 35" style={{ height: '1em', ...style, transform: `scale(${scale})` }}>
14
+ <title>Fusion Logo</title>
15
+ <path
16
+ d="M0 2V23.1776L7.05405 16.1235V7.05405H16.1235L23.1776 0H2C0.895431 0 0 0.89543 0 2Z"
17
+ transform="translate(50 17.5) scale(0.92727 1.06779) rotate(135)"
18
+ fill={`url(#${paint0Id})`}
19
+ />
20
+ <path
21
+ d="M0 2V23.1776L7.05405 16.1235V7.05405H16.1235L23.1776 0H2C0.895431 0 0 0.89543 0 2Z"
22
+ transform="translate(0 17.5) scale(0.92727 1.06779) rotate(-45)"
23
+ fill={`url(#${paint1Id})`}
24
+ />
25
+ <path
26
+ d="M9.61965 36.6972L2.60087 29.6784L1.96135 22.3809L8.42623 22.9069L9.61965 36.6972Z"
27
+ transform="translate(33.8887 34.9863) scale(0.92727 -1.06779) rotate(45)"
28
+ fill="#990025"
29
+ />
30
+ <path
31
+ d="M7.05434 7.05434L0 0L1.21096 13.8183L7.68846 14.3818L7.05434 7.05434Z"
32
+ transform="translate(33.8887 34.9863) scale(0.92727 -1.06779) rotate(45)"
33
+ fill="#990025"
34
+ />
35
+ <path
36
+ d="M0 0L2.49398 29.5715L9.61965 36.6972L7.01878 7.01878L0 0Z"
37
+ transform="translate(33.8887 0.015625) scale(0.92727 1.06779) rotate(45)"
38
+ fill="#FF1243"
39
+ />
40
+ <defs>
41
+ <linearGradient
42
+ id={paint0Id}
43
+ x2="1"
44
+ gradientUnits="userSpaceOnUse"
45
+ gradientTransform="matrix(-13.5478 9.01983 -12.9578 -13.5478 18.0677 6.77391)"
46
+ >
47
+ <stop offset="0.508287" stopColor="#DC002E" />
48
+ <stop offset="0.508387" stopColor="#FF1243" />
49
+ </linearGradient>
50
+ <linearGradient
51
+ id={paint1Id}
52
+ x2="1"
53
+ gradientUnits="userSpaceOnUse"
54
+ gradientTransform="matrix(-13.5478 9.01983 -12.9578 -13.5478 18.0677 6.77391)"
55
+ >
56
+ <stop offset="0.508287" stopColor="#DC002E" />
57
+ <stop offset="0.508387" stopColor="#FF1243" />
58
+ </linearGradient>
59
+ </defs>
60
+ </svg>
61
+ );
62
+ };
57
63
 
58
64
  export default FusionLogo;
package/src/Header.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useCallback, useState } from 'react';
1
+ import { useCallback, useId, useState } from 'react';
2
2
  import { ContextSelector } from './ContextSelector';
3
3
  import { FusionLogo } from './FusionLogo';
4
4
 
@@ -35,6 +35,7 @@ const Styled = {
35
35
 
36
36
  export const Header = () => {
37
37
  const currentUser = useCurrentUser();
38
+ const topBarId = useId();
38
39
  const [isPersonSheetOpen, setIsPersonSheetOpen] = useState(false);
39
40
 
40
41
  const [isBookmarkOpen, setIsBookmarkOpen] = useState(false);
@@ -58,7 +59,7 @@ export const Header = () => {
58
59
  currentUser ? { id: currentUser.localAccountId, name: currentUser.name } : undefined
59
60
  }
60
61
  >
61
- <TopBar id="cli-top-bar" sticky={false} style={{ padding: '0 1em', height: 48 }}>
62
+ <TopBar id={topBarId} sticky={false} style={{ padding: '0 1em', height: 48 }}>
62
63
  <TopBar.Header>
63
64
  <Styled.Title>
64
65
  <FusionLogo />
package/src/config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { enableAppModule } from '@equinor/fusion-framework-module-app';
2
2
  import { enableBookmark } from '@equinor/fusion-framework-react-module-bookmark';
3
- import type { FrameworkConfigurator, Fusion } from '@equinor/fusion-framework';
3
+ import type { FrameworkConfigurator } from '@equinor/fusion-framework';
4
4
  import { enableNavigation } from '@equinor/fusion-framework-module-navigation';
5
5
  import { enableServices } from '@equinor/fusion-framework-module-services';
6
6
  import { enableFeatureFlagging } from '@equinor/fusion-framework-module-feature-flag';
@@ -9,14 +9,52 @@ import {
9
9
  createUrlPlugin,
10
10
  } from '@equinor/fusion-framework-module-feature-flag/plugins';
11
11
 
12
+ import { enableTelemetry } from '@equinor/fusion-framework-module-telemetry';
13
+ import { version } from './version';
14
+
15
+ /**
16
+ * Configures the Fusion Dev Portal with all required modules and features
17
+ *
18
+ * This function sets up the complete framework configuration including:
19
+ * - Telemetry tracking for portal analytics
20
+ * - Core app functionality and navigation
21
+ * - Bookmark management system
22
+ * - Feature flagging for development features
23
+ * - Service integrations
24
+ *
25
+ * @param config - The framework configurator instance to extend with portal features
26
+ */
12
27
  export const configure = async (config: FrameworkConfigurator) => {
28
+ // Enable telemetry tracking for portal usage analytics and monitoring
29
+ enableTelemetry(config, {
30
+ attachConfiguratorEvents: true,
31
+ configure: (builder, ref) => {
32
+ // Set metadata identifying this as portal telemetry with version info
33
+ builder.setMetadata(() => ({
34
+ fusion: {
35
+ type: 'portal-telemetry',
36
+ portal: {
37
+ version,
38
+ name: 'Fusion Dev Portal',
39
+ },
40
+ },
41
+ }));
42
+ // Scope telemetry events to portal-specific tracking
43
+ builder.setDefaultScope(['portal']);
44
+ // Inherit parent telemetry configuration for consistent tracking
45
+ builder.setParent(ref.telemetry);
46
+ },
47
+ });
48
+
13
49
  enableAppModule(config);
14
50
 
15
51
  enableNavigation(config);
16
52
 
17
53
  enableServices(config);
18
54
 
55
+ // Configure bookmark functionality with CLI as the source system
19
56
  enableBookmark(config, (builder) => {
57
+ // Identify bookmarks created in dev portal as coming from CLI system
20
58
  builder.setSourceSystem({
21
59
  subSystem: 'CLI',
22
60
  identifier: 'fusion-cli',
@@ -24,8 +62,9 @@ export const configure = async (config: FrameworkConfigurator) => {
24
62
  });
25
63
  });
26
64
 
27
- /* Adds demo portal features to cli */
65
+ // Configure feature flags for development and demo purposes
28
66
  enableFeatureFlagging(config, (builder) => {
67
+ // Add local storage plugin for persistent feature flag storage
29
68
  builder.addPlugin(
30
69
  createLocalStoragePlugin([
31
70
  {
@@ -40,16 +79,16 @@ export const configure = async (config: FrameworkConfigurator) => {
40
79
  },
41
80
  ]),
42
81
  );
82
+ // Add URL plugin to allow enabling debug features via query parameters
43
83
  builder.addPlugin(createUrlPlugin(['fusionDebug']));
44
84
  });
45
85
 
46
- config.onConfigured(() => {
47
- console.log('framework config done');
48
- });
49
-
86
+ // Expose framework modules globally for development debugging and inspection
50
87
  config.onInitialized(async (modules) => {
51
- console.debug('📒 subscribing to all events');
52
- window.Fusion = { modules } as Fusion; // expose Fusion instance
88
+ // NOTE: TypeScript ignore needed due to window object extension
89
+ // This provides developer access to all initialized modules via window.Fusion
90
+ // @ts-ignore
91
+ window.Fusion = { modules };
53
92
  });
54
93
  };
55
94
 
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '1.1.4';
2
+ export const version = '1.2.0';
package/tsconfig.json CHANGED
@@ -14,6 +14,9 @@
14
14
  {
15
15
  "path": "../utils/query"
16
16
  },
17
+ {
18
+ "path": "../modules/telemetry"
19
+ },
17
20
  {
18
21
  "path": "../modules/http"
19
22
  },