diff --git a/example/src/App.tsx b/example/src/App.tsx
index 7608a3a74..e38b7183f 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -1,20 +1,21 @@
import {
- ApplicationContext,
+ AuthContext,
+ DMApplicationProvider,
+ DmssAPI,
EntityView,
- FSTreeProvider,
- Loading,
- RoleProvider,
+ ErrorResponse,
TApplication,
- useDocument,
} from '@development-framework/dm-core'
import '@development-framework/dm-core/dist/main.css'
import { Button, Card, Icon, Typography } from '@equinor/eds-core-react'
import { refresh } from '@equinor/eds-icons'
import './main.css'
+import { AxiosError } from 'axios'
+import { useContext, useEffect, useState } from 'react'
import { RouterProvider, createBrowserRouter } from 'react-router-dom'
import ViewPage from './ViewPage'
-
+import plugins from './plugins'
const appNotReadyPage = () => (
(idReference)
+ const [application, setApplication] = useState
()
+ const [error, setError] = useState()
+ const [isLoading, setIsLoading] = useState(true)
+ const { token } = useContext(AuthContext)
- if (isLoading) return
+ useEffect(() => {
+ setIsLoading(true)
+ const dmssAPI = new DmssAPI(token, import.meta.env.VITE_DMSS_URL)
+ dmssAPI
+ .documentGet({ address: idReference })
+ .then((response: any) => {
+ setApplication(response.data)
+ setError(null)
+ })
+ .catch((error: AxiosError) => {
+ console.error(error)
+ setError(error.response?.data || { message: error.name, data: error })
+ })
+ .finally(() => setIsLoading(false))
+ }, [])
- if (error || !application) {
+ if (isLoading) return <>>
+ if (error || !application || !application.type) {
console.error(error)
return appNotReadyPage()
}
+
const router = createBrowserRouter([
{
path: '/',
@@ -98,15 +114,19 @@ function App() {
),
},
])
+ const enableBlueprintCache =
+ import.meta.env.VITE_BLUEPRINT_CACHE_ENABLED === '1' || true
return (
-
-
-
-
-
-
-
+
+
+
)
}
diff --git a/example/src/index.tsx b/example/src/index.tsx
index 11b73e02a..23c6ecc05 100644
--- a/example/src/index.tsx
+++ b/example/src/index.tsx
@@ -1,19 +1,9 @@
-import {
- DMJobProvider,
- DMSSProvider,
- UiPluginProvider,
-} from '@development-framework/dm-core'
import React from 'react'
-import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.min.css'
import ReactDOM from 'react-dom/client'
import { AuthProvider } from 'react-oauth2-code-pkce'
import App from './App'
-import plugins from './plugins'
-
-const fullCurrentURL = () =>
- `${window.location.pathname}${window.location.search}${window.location.hash}`
const authEnabled = import.meta.env.VITE_AUTH_ENABLED === '1'
const authConfig = {
@@ -31,34 +21,16 @@ const authConfig = {
}/oauth2/logout`,
}
-const Content = () => {
- const enableBlueprintCache =
- import.meta.env.VITE_BLUEPRINT_CACHE_ENABLED === '1' || true
- return (
-
-
-
-
-
-
-
-
- )
-}
-
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
{authEnabled ? (
-
+
) : (
-
+
)}
)
diff --git a/packages/dm-core-plugins/src/blueprint-hierarchy/BlueprintHierarchyPlugin.tsx b/packages/dm-core-plugins/src/blueprint-hierarchy/BlueprintHierarchyPlugin.tsx
index 9a2c45604..51a6230dc 100644
--- a/packages/dm-core-plugins/src/blueprint-hierarchy/BlueprintHierarchyPlugin.tsx
+++ b/packages/dm-core-plugins/src/blueprint-hierarchy/BlueprintHierarchyPlugin.tsx
@@ -4,7 +4,7 @@ import {
DmssAPI,
IUIPlugin,
Loading,
- useDMSS,
+ useApplication,
useDocument,
} from '@development-framework/dm-core'
import MermaidWrapper from './MermaidWrapper'
@@ -74,7 +74,7 @@ function useExplorer(dmssAPI: DmssAPI) {
export const BlueprintHierarchyPlugin = (props: IUIPlugin) => {
const { idReference } = props
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const explorer = useExplorer(dmssAPI)
const [chart, setChart] = useState(undefined)
diff --git a/packages/dm-core-plugins/src/blueprint-hierarchy/loader.tsx b/packages/dm-core-plugins/src/blueprint-hierarchy/loader.tsx
index ab6b6b6af..306bad35b 100644
--- a/packages/dm-core-plugins/src/blueprint-hierarchy/loader.tsx
+++ b/packages/dm-core-plugins/src/blueprint-hierarchy/loader.tsx
@@ -1,4 +1,4 @@
-import { useDMSS } from '@development-framework/dm-core'
+import { useApplication } from '@development-framework/dm-core'
import { IBlueprintType, TAttributeType } from './types'
export class Node {
@@ -58,7 +58,7 @@ const nonPrimitiveAttributes = (blueprint: IBlueprintType): TAttributeType[] =>
)
const search = async (query: any) => {
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const response = await dmssAPI.search({
dataSources: ['WorkflowDS'],
diff --git a/packages/dm-core-plugins/src/data-grid/DataGridPlugin.tsx b/packages/dm-core-plugins/src/data-grid/DataGridPlugin.tsx
index 820af43a1..c7e4d289b 100644
--- a/packages/dm-core-plugins/src/data-grid/DataGridPlugin.tsx
+++ b/packages/dm-core-plugins/src/data-grid/DataGridPlugin.tsx
@@ -3,8 +3,8 @@ import {
Stack,
TAttribute,
TGenericObject,
+ useApplication,
useBlueprint,
- useDMSS,
useDocument,
} from '@development-framework/dm-core'
import { Button, Icon, Tooltip } from '@equinor/eds-core-react'
@@ -17,7 +17,7 @@ import { getFunctionalityVariables, reverseData } from './utils'
export function DataGridPlugin(props: IUIPlugin) {
const { idReference, config: userConfig, type, onChange } = props
const config: DataGridConfig = { ...defaultConfig, ...userConfig }
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const [data, setData] = useState()
const [initialData, setInitialData] = useState()
const [loading, setLoading] = useState(false)
diff --git a/packages/dm-core-plugins/src/explorer/ExplorerPlugin.tsx b/packages/dm-core-plugins/src/explorer/ExplorerPlugin.tsx
index 75855f7c8..49d83606e 100644
--- a/packages/dm-core-plugins/src/explorer/ExplorerPlugin.tsx
+++ b/packages/dm-core-plugins/src/explorer/ExplorerPlugin.tsx
@@ -1,22 +1,17 @@
import {
EBlueprint,
EntityView,
- FSTreeContext,
- Tree,
TreeNode,
TreeView,
+ useApplication,
} from '@development-framework/dm-core'
import { Progress } from '@equinor/eds-core-react'
-import { useContext, useState } from 'react'
+import { useState } from 'react'
import Sidebar from './components/Sidebar'
import NodeRightClickMenu from './components/context-menu/NodeRightClickMenu'
export default () => {
- const { treeNodes, loading } = useContext<{
- tree: null | Tree
- treeNodes: TreeNode[]
- loading: boolean
- }>(FSTreeContext)
+ const { treeNodes, loading } = useApplication()
const [selectedType, setSelectedType] = useState()
const [selectedEntity, setSelectedEntity] = useState()
const [nodeDimensions, setNodeDimensions] = useState(
diff --git a/packages/dm-core-plugins/src/explorer/components/dialogs/DeleteDialog.tsx b/packages/dm-core-plugins/src/explorer/components/dialogs/DeleteDialog.tsx
index f27bf0745..8c2753517 100644
--- a/packages/dm-core-plugins/src/explorer/components/dialogs/DeleteDialog.tsx
+++ b/packages/dm-core-plugins/src/explorer/components/dialogs/DeleteDialog.tsx
@@ -2,7 +2,7 @@ import {
Dialog,
ErrorResponse,
TreeNode,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { Button, Progress } from '@equinor/eds-core-react'
import { AxiosError } from 'axios'
@@ -22,7 +22,7 @@ type TProps = {
const DeleteDialog = (props: TProps) => {
const { setDialogId, node } = props
const [loading, setLoading] = useState(false)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const handleDelete = () => {
setLoading(true)
diff --git a/packages/dm-core-plugins/src/explorer/components/dialogs/NewEntityDialog.tsx b/packages/dm-core-plugins/src/explorer/components/dialogs/NewEntityDialog.tsx
index 88c5f9dce..0189f2b36 100644
--- a/packages/dm-core-plugins/src/explorer/components/dialogs/NewEntityDialog.tsx
+++ b/packages/dm-core-plugins/src/explorer/components/dialogs/NewEntityDialog.tsx
@@ -1,16 +1,15 @@
import {
- ApplicationContext,
BlueprintPicker,
Dialog,
ErrorResponse,
TAttribute,
TBlueprint,
TreeNode,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { Button, Progress, TextField } from '@equinor/eds-core-react'
import { AxiosError } from 'axios'
-import { useContext, useEffect, useState } from 'react'
+import { useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { EDialog } from '../../types'
import {
@@ -30,9 +29,7 @@ const NewEntityDialog = (props: TProps) => {
const [blueprint, setBlueprint] = useState()
const [newName, setNewName] = useState('')
const [loading, setLoading] = useState(false)
- const dmssAPI = useDMSS()
-
- const { name } = useContext(ApplicationContext)
+ const { dmssAPI, name } = useApplication()
useEffect(() => {
if (!blueprintName) return
diff --git a/packages/dm-core-plugins/src/explorer/components/dialogs/NewFolderDialog.tsx b/packages/dm-core-plugins/src/explorer/components/dialogs/NewFolderDialog.tsx
index 4ef5fcdac..51bda68fe 100644
--- a/packages/dm-core-plugins/src/explorer/components/dialogs/NewFolderDialog.tsx
+++ b/packages/dm-core-plugins/src/explorer/components/dialogs/NewFolderDialog.tsx
@@ -3,7 +3,7 @@ import {
ErrorResponse,
INPUT_FIELD_WIDTH,
TreeNode,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { Button, Progress, TextField } from '@equinor/eds-core-react'
import { AxiosError } from 'axios'
@@ -26,7 +26,7 @@ const NewFolderDialog = (props: TProps) => {
const { setDialogId, node, setNodeOpen, isRoot } = props
const [folderName, setFolderName] = useState('')
const [loading, setLoading] = useState(false)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const handleCreate = () => {
const newFolder = {
diff --git a/packages/dm-core-plugins/src/file/DownloadFileButton.tsx b/packages/dm-core-plugins/src/file/DownloadFileButton.tsx
index 4ada2b696..67d673fdf 100644
--- a/packages/dm-core-plugins/src/file/DownloadFileButton.tsx
+++ b/packages/dm-core-plugins/src/file/DownloadFileButton.tsx
@@ -2,7 +2,7 @@ import {
ErrorResponse,
Loading,
TFileEntity,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { Button } from '@equinor/eds-core-react'
import { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
@@ -20,7 +20,7 @@ export const DownloadFileButton = (props: DownloadButtonProps) => {
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => {
setError(null)
diff --git a/packages/dm-core-plugins/src/file/UploadFileButton.tsx b/packages/dm-core-plugins/src/file/UploadFileButton.tsx
index 6b9efdf7d..0bd13a510 100644
--- a/packages/dm-core-plugins/src/file/UploadFileButton.tsx
+++ b/packages/dm-core-plugins/src/file/UploadFileButton.tsx
@@ -1,4 +1,7 @@
-import { TStorageReference, useDMSS } from '@development-framework/dm-core'
+import {
+ TStorageReference,
+ useApplication,
+} from '@development-framework/dm-core'
import { Button, Progress } from '@equinor/eds-core-react'
import { AxiosError } from 'axios'
import { ChangeEvent, useEffect, useRef, useState } from 'react'
@@ -14,7 +17,7 @@ export const UploadFileButton = (props: UploadButtonProps) => {
const textInput = useRef(null)
const [error, setError] = useState()
const [loading, setLoading] = useState(false)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => setError(undefined))
diff --git a/packages/dm-core-plugins/src/form/components/AddObjectButton.tsx b/packages/dm-core-plugins/src/form/components/AddObjectButton.tsx
index 752986185..841622ba3 100644
--- a/packages/dm-core-plugins/src/form/components/AddObjectButton.tsx
+++ b/packages/dm-core-plugins/src/form/components/AddObjectButton.tsx
@@ -1,4 +1,4 @@
-import { ErrorResponse, useDMSS } from '@development-framework/dm-core'
+import { ErrorResponse, useApplication } from '@development-framework/dm-core'
import { AxiosError, AxiosResponse } from 'axios'
import { useFormContext } from 'react-hook-form'
import { useRegistryContext } from '../context/RegistryContext'
@@ -12,7 +12,7 @@ const AddObject = (props: {
}) => {
const { type, namePath, defaultValue, onAdd } = props
const { setValue } = useFormContext()
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const { idReference } = useRegistryContext()
const handleAdd = () => {
if (!defaultValue) {
diff --git a/packages/dm-core-plugins/src/form/components/AddObjectBySearchButton.tsx b/packages/dm-core-plugins/src/form/components/AddObjectBySearchButton.tsx
index a718c74d7..d9cf3d584 100644
--- a/packages/dm-core-plugins/src/form/components/AddObjectBySearchButton.tsx
+++ b/packages/dm-core-plugins/src/form/components/AddObjectBySearchButton.tsx
@@ -1,8 +1,4 @@
-import {
- useApplication,
- useDMSS,
- useSearch,
-} from '@development-framework/dm-core'
+import { useApplication, useSearch } from '@development-framework/dm-core'
import { EdsProvider, Menu } from '@equinor/eds-core-react'
import { add } from '@equinor/eds-icons'
import { useState } from 'react'
@@ -19,17 +15,16 @@ const AddObjectBySearchButton = (props: {
}) => {
const { type, namePath, onAdd } = props
const { setValue } = useFormContext()
- const dmssAPI = useDMSS()
+ const { dmssAPI, visibleDataSources } = useApplication()
const { idReference } = useRegistryContext()
const [isOpen, setIsOpen] = useState(false)
const [anchorEl, setAnchorEl] = useState(null)
- const application = useApplication()
const [searchResult] = useSearch(
{
type: 'dmss://system/SIMOS/Blueprint',
extends: [type],
},
- application.dataSources
+ visibleDataSources
)
const openMenu = () => {
diff --git a/packages/dm-core-plugins/src/form/components/AddStorageUncontained.tsx b/packages/dm-core-plugins/src/form/components/AddStorageUncontained.tsx
index 0330e8ced..dab0f96a3 100644
--- a/packages/dm-core-plugins/src/form/components/AddStorageUncontained.tsx
+++ b/packages/dm-core-plugins/src/form/components/AddStorageUncontained.tsx
@@ -1,4 +1,4 @@
-import { splitAddress, useDMSS } from '@development-framework/dm-core'
+import { splitAddress, useApplication } from '@development-framework/dm-core'
import { AxiosResponse } from 'axios'
import { useFormContext } from 'react-hook-form'
import { useRegistryContext } from '../context/RegistryContext'
@@ -19,7 +19,7 @@ const AddStorageUncontained = (props: {
const { idReference } = useRegistryContext()
const { setValue } = useFormContext()
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const addDocument = () => {
const options = {
shouldDirty: true,
diff --git a/packages/dm-core-plugins/src/form/components/Form.test.tsx b/packages/dm-core-plugins/src/form/components/Form.test.tsx
index b881e80aa..55bacfb6f 100644
--- a/packages/dm-core-plugins/src/form/components/Form.test.tsx
+++ b/packages/dm-core-plugins/src/form/components/Form.test.tsx
@@ -37,7 +37,7 @@ describe('Form', () => {
expect(container.querySelector(`input[id="bar"]`)).toBeTruthy()
expect(container.querySelector(`input[id="baz"]`)).toBeNull()
// Should only call get blueprint once
- expect(mock).toHaveBeenCalledWith({ typeRef: 'Root' })
+ expect(mock).toHaveBeenCalledWith({ typeRef: 'Root', context: 'test' })
expect(mock).toHaveBeenCalledTimes(1)
})
})
@@ -134,7 +134,7 @@ describe('Form', () => {
await waitFor(() => {
expect(container.querySelector(`input[id="foo"]`)).toBeTruthy()
// Should only call get blueprint once
- expect(mock).toHaveBeenCalledWith({ typeRef: 'Root' })
+ expect(mock).toHaveBeenCalledWith({ typeRef: 'Root', context: 'test' })
expect(mock).toHaveBeenCalledTimes(1)
})
})
diff --git a/packages/dm-core-plugins/src/form/components/Form.tsx b/packages/dm-core-plugins/src/form/components/Form.tsx
index a6ffa2b86..7827a44a2 100644
--- a/packages/dm-core-plugins/src/form/components/Form.tsx
+++ b/packages/dm-core-plugins/src/form/components/Form.tsx
@@ -1,15 +1,14 @@
-import { useContext, useState } from 'react'
+import { useState } from 'react'
import {
- ApplicationContext,
EBlueprint,
Loading,
TAttribute,
TGenericObject,
TUiRecipe,
findRecipe,
+ useApplication,
useBlueprint,
- useDMSS,
} from '@development-framework/dm-core'
import { Button, EdsProvider, Icon } from '@equinor/eds-core-react'
import { undo } from '@equinor/eds-icons'
@@ -36,8 +35,7 @@ export const defaultConfig: TFormConfig = {
export const Form = (props: TFormProps) => {
const { type, formData, onSubmit, idReference, onOpen } = props
const { blueprint, storageRecipes, isLoading, error } = useBlueprint(type)
- const dmssAPI = useDMSS()
- const { name } = useContext(ApplicationContext)
+ const { dmssAPI, name } = useApplication()
const [reloadCounter, setReloadCounter] = useState(0)
const showSubmitButton = props.showSubmitButton ?? true
// Every react hook form controller needs to have a unique name
diff --git a/packages/dm-core-plugins/src/form/components/RemoveObjectButton.tsx b/packages/dm-core-plugins/src/form/components/RemoveObjectButton.tsx
index 3c7f9f01b..a1962a315 100644
--- a/packages/dm-core-plugins/src/form/components/RemoveObjectButton.tsx
+++ b/packages/dm-core-plugins/src/form/components/RemoveObjectButton.tsx
@@ -1,7 +1,7 @@
import {
DeleteHardButton,
ErrorResponse,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { AxiosError } from 'axios'
import { useFormContext } from 'react-hook-form'
@@ -19,7 +19,7 @@ const RemoveObject = (props: {
props
const { unregister } = useFormContext()
const { idReference } = useRegistryContext()
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const onClick = () => {
dmssAPI
diff --git a/packages/dm-core-plugins/src/form/components/SelectReference.tsx b/packages/dm-core-plugins/src/form/components/SelectReference.tsx
index 24b470549..eb7fb9709 100644
--- a/packages/dm-core-plugins/src/form/components/SelectReference.tsx
+++ b/packages/dm-core-plugins/src/form/components/SelectReference.tsx
@@ -4,7 +4,7 @@ import {
ErrorResponse,
TEntityPickerReturn,
TLinkReference,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { AxiosError } from 'axios/index'
import { useState } from 'react'
@@ -19,7 +19,7 @@ export const SelectReference = (props: {
}) => {
const [showModal, setShowModal] = useState(false)
const { setValue, watch } = useFormContext()
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const { idReference } = useRegistryContext()
const value = watch(props.namePath)
diff --git a/packages/dm-core-plugins/src/form/fields/BinaryField.tsx b/packages/dm-core-plugins/src/form/fields/BinaryField.tsx
index fc5a86b0a..67aecb617 100644
--- a/packages/dm-core-plugins/src/form/fields/BinaryField.tsx
+++ b/packages/dm-core-plugins/src/form/fields/BinaryField.tsx
@@ -2,7 +2,7 @@ import {
ErrorResponse,
TGenericObject,
splitAddress,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { Button, Label } from '@equinor/eds-core-react'
import { AxiosError, AxiosResponse } from 'axios'
@@ -29,7 +29,7 @@ const DownloadBinary = (props: {
initialValue: TGenericObject & { address: string }
}) => {
const { namePath, initialValue, displayLabel } = props
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const [data_source_id, blob_id] = getTarget(initialValue)
const handleDownload = () => {
diff --git a/packages/dm-core-plugins/src/form/test-utils.tsx b/packages/dm-core-plugins/src/form/test-utils.tsx
index 5eb82392e..ac51445fd 100644
--- a/packages/dm-core-plugins/src/form/test-utils.tsx
+++ b/packages/dm-core-plugins/src/form/test-utils.tsx
@@ -1,8 +1,7 @@
import {
- DMSSProvider,
+ DMApplicationProvider,
DmssAPI,
TUiPluginMap,
- UiPluginProvider,
} from '@development-framework/dm-core'
import React from 'react'
import { FormPlugin } from './FormPlugin'
@@ -42,7 +41,12 @@ const plugins = {
} as TUiPluginMap
export const wrapper = (props: { children: React.ReactNode }) => (
-
- {props.children}
-
+
+ {props.children}
+
)
diff --git a/packages/dm-core-plugins/src/header/HeaderPlugin.tsx b/packages/dm-core-plugins/src/header/HeaderPlugin.tsx
index b6454bb84..bc25961f9 100644
--- a/packages/dm-core-plugins/src/header/HeaderPlugin.tsx
+++ b/packages/dm-core-plugins/src/header/HeaderPlugin.tsx
@@ -4,9 +4,9 @@ import {
TApplication,
TGenericObject,
TUiRecipe,
+ useApplication,
useBlueprint,
useDocument,
- useUiPlugins,
} from '@development-framework/dm-core'
import { Icon, TopBar } from '@equinor/eds-core-react'
import React, { useEffect, useState } from 'react'
@@ -74,7 +74,7 @@ export default (props: IUIPlugin): React.ReactElement => {
const { uiRecipes, isLoading: isBlueprintLoading } = useBlueprint(type)
const [aboutOpen, setAboutOpen] = useState(false)
const [visibleUserInfo, setVisibleUserInfo] = useState(false)
- const { getUiPlugin } = useUiPlugins()
+ const { getUiPlugin } = useApplication()
const [selectedRecipe, setSelectedRecipe] = useState({
component: () => ,
config: {},
diff --git a/packages/dm-core-plugins/src/header/components/UserInfoDialog.tsx b/packages/dm-core-plugins/src/header/components/UserInfoDialog.tsx
index 2a30b1e58..5d75237da 100644
--- a/packages/dm-core-plugins/src/header/components/UserInfoDialog.tsx
+++ b/packages/dm-core-plugins/src/header/components/UserInfoDialog.tsx
@@ -1,9 +1,8 @@
import {
Dialog,
- RoleContext,
TApplication,
TRole,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { Button, Icon, Radio, Typography } from '@equinor/eds-core-react'
import { close } from '@equinor/eds-icons'
@@ -51,8 +50,7 @@ export const UserInfoDialog = (props: UserInfoDialogProps) => {
const { isOpen, setIsOpen } = props
const [apiKey, setAPIKey] = useState(null)
const { tokenData, token, logOut } = useContext(AuthContext)
- const dmssAPI = useDMSS()
- const { role, setRole, roles } = useContext(RoleContext)
+ const { dmssAPI, role, setRole, roles } = useApplication()
const [selectedRole, setSelectedRole] = useState(role)
return (
diff --git a/packages/dm-core-plugins/src/job/JobControl.tsx b/packages/dm-core-plugins/src/job/JobControl.tsx
index 66c2b2369..04f88b4be 100644
--- a/packages/dm-core-plugins/src/job/JobControl.tsx
+++ b/packages/dm-core-plugins/src/job/JobControl.tsx
@@ -11,7 +11,7 @@ import {
TSchedule,
TTemplate,
TemplateMenu,
- useDMSS,
+ useApplication,
useDocument,
useJob,
} from '@development-framework/dm-core'
@@ -47,7 +47,7 @@ const defaultConfig: TJobControlConfig = {
export const JobControl = (props: IUIPlugin) => {
const { idReference, config } = props
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const { tokenData }: IAuthContext = useContext(AuthContext)
const internalConfig: TJobControlConfig = { ...defaultConfig, ...config }
diff --git a/packages/dm-core-plugins/src/job/JobCreate.tsx b/packages/dm-core-plugins/src/job/JobCreate.tsx
index 988718bcc..002d9e6b6 100644
--- a/packages/dm-core-plugins/src/job/JobCreate.tsx
+++ b/packages/dm-core-plugins/src/job/JobCreate.tsx
@@ -1,4 +1,7 @@
-import { resolveRelativeAddressSimplified } from '@development-framework/dm-core'
+import {
+ resolveRelativeAddressSimplified,
+ useApplication,
+} from '@development-framework/dm-core'
import { useContext, useMemo } from 'react'
import { AuthContext } from 'react-oauth2-code-pkce'
@@ -12,7 +15,6 @@ import {
TSchedule,
TTemplate,
TemplateMenu,
- useDMSS,
useDocument,
useJob,
} from '@development-framework/dm-core'
@@ -54,7 +56,7 @@ export const JobCreate = (props: IUIPlugin & { config: TJobPluginConfig }) => {
config,
idReference,
}: { config: TJobPluginConfig; idReference: string } = props
- const dmssApi = useDMSS()
+ const { dmssAPI } = useApplication()
const { tokenData } = useContext(AuthContext)
const username = tokenData?.preferred_username ?? 'unknown user'
@@ -109,7 +111,7 @@ export const JobCreate = (props: IUIPlugin & { config: TJobPluginConfig }) => {
}
// Get template
- dmssApi
+ dmssAPI
.documentGet({
address: templateAddress,
})
@@ -137,7 +139,7 @@ export const JobCreate = (props: IUIPlugin & { config: TJobPluginConfig }) => {
updateDocument(newJob, false).then(() => start())
} else {
// Add template to job container
- dmssApi
+ dmssAPI
.documentAdd({
address: jobTargetAddress,
document: JSON.stringify(newJob),
diff --git a/packages/dm-core-plugins/src/mediaViewer/MediaViewerPlugin.tsx b/packages/dm-core-plugins/src/mediaViewer/MediaViewerPlugin.tsx
index 65c85be6e..8ae4c6ef9 100644
--- a/packages/dm-core-plugins/src/mediaViewer/MediaViewerPlugin.tsx
+++ b/packages/dm-core-plugins/src/mediaViewer/MediaViewerPlugin.tsx
@@ -5,7 +5,7 @@ import {
MediaContent,
mimeTypes,
splitAddress,
- useDMSS,
+ useApplication,
useDocument,
} from '@development-framework/dm-core'
import { AxiosRequestConfig } from 'axios'
@@ -39,7 +39,7 @@ export const MediaViewerPlugin = (
const { idReference, config } = props
const [blobUrl, setBlobUrl] = useState()
const [contentType, setContentType] = useState('')
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const {
document,
isLoading,
diff --git a/packages/dm-core-plugins/src/pdf/PDFViewer.tsx b/packages/dm-core-plugins/src/pdf/PDFViewer.tsx
index f5f74255a..bf99c0bea 100644
--- a/packages/dm-core-plugins/src/pdf/PDFViewer.tsx
+++ b/packages/dm-core-plugins/src/pdf/PDFViewer.tsx
@@ -4,7 +4,7 @@ import {
Loading,
TGenericObject,
formatBytes,
- useDMSS,
+ useApplication,
} from '@development-framework/dm-core'
import { AxiosError } from 'axios'
import { useEffect, useState } from 'react'
@@ -40,7 +40,7 @@ export const ViewerPDFPlugin = (props: {
const [blobUrl, setBlobUrl] = useState('')
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => {
setError(null)
diff --git a/packages/dm-core-plugins/src/role_filter/RoleFilterPlugin.tsx b/packages/dm-core-plugins/src/role_filter/RoleFilterPlugin.tsx
index 07ed4a1a8..75d1f56bd 100644
--- a/packages/dm-core-plugins/src/role_filter/RoleFilterPlugin.tsx
+++ b/packages/dm-core-plugins/src/role_filter/RoleFilterPlugin.tsx
@@ -1,11 +1,11 @@
import {
IUIPlugin,
- RoleContext,
ViewCreator,
+ useApplication,
} from '@development-framework/dm-core'
import { Banner, Icon } from '@equinor/eds-core-react'
import { thumbs_down } from '@equinor/eds-icons'
-import React, { useContext, useEffect, useState } from 'react'
+import React, { useEffect, useState } from 'react'
type FilteredView = {
type: string
@@ -22,7 +22,7 @@ export const RoleFilterPlugin = (props: IUIPlugin): React.ReactElement => {
)
const [openViewConfigs, setOpenViewConfigs] = useState([])
const [allowedRoles, setAllowedRoles] = useState([])
- const { role } = useContext(RoleContext)
+ const { role } = useApplication()
useEffect(() => {
let roles: string[] = []
diff --git a/packages/dm-core/src/ApplicationContext.tsx b/packages/dm-core/src/ApplicationContext.tsx
new file mode 100644
index 000000000..4e316a855
--- /dev/null
+++ b/packages/dm-core/src/ApplicationContext.tsx
@@ -0,0 +1,166 @@
+import React, {
+ Dispatch,
+ ReactNode,
+ SetStateAction,
+ useContext,
+ useEffect,
+ useState,
+} from 'react'
+import { AuthContext } from 'react-oauth2-code-pkce'
+import { ToastContainer } from 'react-toastify'
+import { Tree, TreeNode } from './domain/Tree'
+import { DmJobAPI } from './services'
+import DmssAPI from './services/api/DmssAPI'
+import { IUIPlugin, TApplication, TRole, TUiPluginMap } from './types'
+import { ErrorGroup } from './utils/ErrorBoundary'
+
+const DEFAULT_ROLE: TRole = {
+ name: 'anonymous',
+ authServerRoleName: 'anonymous',
+ label: 'Anonymous',
+}
+export const ApplicationContext = React.createContext<
+ | {
+ name: string
+ dmssAPI: DmssAPI
+ dmJobApi: DmJobAPI
+ getUiPlugin: (
+ pluginName: string
+ ) => (props: IUIPlugin) => React.ReactElement
+ visibleDataSources: string[]
+ role: TRole
+ setRole: Dispatch>
+ roles: TRole[]
+ tree: null | Tree
+ treeNodes: TreeNode[]
+ loading: boolean
+ }
+ | undefined
+>(undefined)
+
+function capitalizeFirstLetter(v: string): string {
+ return v.charAt(0).toUpperCase() + v.slice(1)
+}
+
+function findFirstCommonRole(appRoles: TRole[], actualRoles: string[]): TRole {
+ const matchingRole = appRoles.find((r: TRole) =>
+ actualRoles.includes(r.authServerRoleName)
+ )
+ return matchingRole ?? appRoles[0]
+}
+
+function generateFallbackRoles(roles: string[] | undefined): TRole[] {
+ if (!roles) {
+ console.warn('No roles has been configured for the application')
+ return [DEFAULT_ROLE]
+ }
+ return roles.map((r) => ({
+ name: r,
+ label: capitalizeFirstLetter(r),
+ authServerRoleName: r,
+ }))
+}
+
+export const DMApplicationProvider = (props: {
+ children: ReactNode
+ application: TApplication
+ dmJobPath: string
+ dmssBasePath?: string
+ enableBlueprintCache: boolean
+ plugins: TUiPluginMap
+}) => {
+ const [role, setRole] = useState(DEFAULT_ROLE)
+ const [roles, setRoles] = useState(props.application.roles || [])
+ const [loading, setLoading] = useState(true)
+ const [treeNodes, setTreeNodes] = useState([])
+ const { token, tokenData } = useContext(AuthContext)
+ const dmJobApi = new DmJobAPI(token, props.dmJobPath)
+
+ const dmssAPIOriginal = new DmssAPI(token, props.dmssBasePath)
+ const dmssAPI = new DmssAPI(token, props.dmssBasePath)
+ const tree: Tree = new Tree(dmssAPI, (t: Tree) => setTreeNodes([...t]))
+
+ // @ts-ignore
+ dmssAPI.blueprintGet = async (requestParameters, options) => {
+ const cacheKey = `${requestParameters.typeRef}${requestParameters.context}`
+ const cachedValue = window.sessionStorage.getItem(cacheKey)
+ if (!cachedValue) {
+ return dmssAPIOriginal
+ .blueprintGet(requestParameters)
+ .then((response) => {
+ if (props.enableBlueprintCache)
+ window.sessionStorage.setItem(
+ cacheKey,
+ JSON.stringify(response.data)
+ )
+ return response
+ })
+ }
+ return {
+ data: JSON.parse(cachedValue),
+ status: 200,
+ statusText: 'ok',
+ }
+ }
+
+ function getUiPlugin(
+ pluginName: string
+ ): (props: IUIPlugin) => React.ReactElement {
+ const plugin = props.plugins[pluginName]?.component
+ if (!plugin)
+ return () => (
+ Did not find the plugin: {pluginName}
+ )
+ return plugin
+ }
+
+ useEffect(() => {
+ let newRoles = props.application.roles || []
+ if (tokenData) {
+ newRoles = newRoles.filter((role) =>
+ tokenData.roles.includes(role.authServerRoleName)
+ )
+ }
+ if (props.application.roles && !props.application.roles.length) {
+ // No roles is configured in application. Generate from roles in token
+ newRoles = generateFallbackRoles(tokenData?.roles)
+ }
+ setRoles(newRoles)
+ setRole(findFirstCommonRole(newRoles, tokenData?.roles ?? [])) // Default select the first role that exists in tokenData
+ }, [tokenData])
+
+ useEffect(() => {
+ setLoading(true)
+ tree
+ .initFromDataSources(props.application.dataSources)
+ .finally(() => setLoading(false))
+ }, [])
+
+ return (
+
+ {props.children}
+
+
+ )
+}
+export const useApplication = () => {
+ const context = useContext(ApplicationContext)
+ if (context === undefined) {
+ throw new Error('useApplication must be used within a ApplicationProvider')
+ }
+ return context
+}
diff --git a/packages/dm-core/src/components/AccessControl/AccessControlListComponent.tsx b/packages/dm-core/src/components/AccessControl/AccessControlListComponent.tsx
index d68220c8d..0c8a32d47 100644
--- a/packages/dm-core/src/components/AccessControl/AccessControlListComponent.tsx
+++ b/packages/dm-core/src/components/AccessControl/AccessControlListComponent.tsx
@@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react'
import { AxiosError, AxiosResponse } from 'axios'
import { toast } from 'react-toastify'
-import { useDMSS } from '../../context/DMSSContext'
+import { useApplication } from '../../ApplicationContext'
import { useLocalStorage } from '../../hooks/useLocalStorage'
import { AccessControlList, AccessLevel } from '../../services'
import { TUserIdMapping } from '../../types'
@@ -29,7 +29,7 @@ export const AccessControlListComponent = (props: {
const [loadingACLDocument, setLoadingACLDocument] = useState(false)
const [tokenWithReadAccess, setTokenWithReadAccess] = useState('')
const [refreshToken] = useLocalStorage('ROCP_refreshToken', '')
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const [documentACL, setDocumentACL] = useState({
owner: '',
diff --git a/packages/dm-core/src/components/CopyLinkDialog.tsx b/packages/dm-core/src/components/CopyLinkDialog.tsx
index 6486a5f99..fe9e3d1ab 100644
--- a/packages/dm-core/src/components/CopyLinkDialog.tsx
+++ b/packages/dm-core/src/components/CopyLinkDialog.tsx
@@ -21,7 +21,7 @@ import {
TLinkReference,
TValidEntity,
truncatePathString,
- useDMSS,
+ useApplication,
useDocument,
} from '../index'
import { setMetaInDocument } from '../utils/setMetaInDocument'
@@ -85,12 +85,9 @@ export const CopyLinkDialog = (props: TProps) => {
useState(false)
const [showLinkTargetDialog, setShowLinkTargetDialog] =
useState(false)
- const { document, isLoading: documentIsLoading } = useDocument(
- idReference,
- 9
- )
+ const { document } = useDocument(idReference, 9)
const [isLoading, setIsLoading] = useState(false)
- const dmss = useDMSS()
+ const { dmssAPI } = useApplication()
const copyEntityToDestination = async (): Promise<
Promise | Promise
@@ -114,14 +111,14 @@ export const CopyLinkDialog = (props: TProps) => {
if (wrapper) {
const wrapperEntity: TValidEntity =
// TODO: Handle relative/unresolved addresses? Perhaps in blueprint upload?
- (await dmss.instantiateEntity({ entity: { type: wrapper } }))
+ (await dmssAPI.instantiateEntity({ entity: { type: wrapper } }))
.data as TValidEntity
wrapperEntity[wrapperAttribute] = newDocument
wrapperEntity._meta_ = newDocument._meta_
newDocument = wrapperEntity
}
- return dmss
+ return dmssAPI
.documentAdd({
address: selectedDestination.address,
document: JSON.stringify(newDocument),
@@ -152,7 +149,7 @@ export const CopyLinkDialog = (props: TProps) => {
referenceType: 'link',
type: EBlueprint.REFERENCE,
}
- dmss
+ dmssAPI
.documentAdd({
address: selectedLinkTarget.address,
document: JSON.stringify(linkReference),
diff --git a/packages/dm-core/src/components/NewEntityButton.tsx b/packages/dm-core/src/components/NewEntityButton.tsx
index f95c11769..f15b967c4 100644
--- a/packages/dm-core/src/components/NewEntityButton.tsx
+++ b/packages/dm-core/src/components/NewEntityButton.tsx
@@ -2,7 +2,7 @@ import { Button, Input, Label, Progress } from '@equinor/eds-core-react'
import { AxiosError, AxiosResponse } from 'axios'
import React, { useEffect, useState } from 'react'
import { toast } from 'react-toastify'
-import { useDMSS } from '../context/DMSSContext'
+import { useApplication } from '../ApplicationContext'
import { TGenericObject, TReference } from '../types'
import { INPUT_FIELD_WIDTH } from '../utils/variables'
import { Dialog } from './Dialog'
@@ -33,7 +33,7 @@ export function NewEntityButton(props: {
>(undefined)
const [typeToCreate, setTypeToCreate] = useState(type || '')
const [loading, setLoading] = useState(false)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => setTypeToCreate(type || ''), [type])
useEffect(() => {
diff --git a/packages/dm-core/src/components/Pickers/BlueprintPicker.tsx b/packages/dm-core/src/components/Pickers/BlueprintPicker.tsx
index f5f3f2070..de0121335 100644
--- a/packages/dm-core/src/components/Pickers/BlueprintPicker.tsx
+++ b/packages/dm-core/src/components/Pickers/BlueprintPicker.tsx
@@ -1,4 +1,4 @@
-import { useContext, useState } from 'react'
+import { useState } from 'react'
import { toast } from 'react-toastify'
import { EBlueprint } from '../../Enums'
import {
@@ -17,7 +17,7 @@ import {
} from '@equinor/eds-core-react'
import { Variants } from '@equinor/eds-core-react/dist/types/components/types'
import { add } from '@equinor/eds-icons'
-import { FSTreeContext } from '../../context/FileSystemTreeContext'
+import { useApplication } from '../../ApplicationContext'
import { TreeNode } from '../../domain/Tree'
import { truncatePathString } from '../../utils/truncatePathString'
import { Dialog } from '../Dialog'
@@ -71,7 +71,7 @@ export const BlueprintPicker = (props: TBlueprintPickerProps) => {
...props,
}
const [showModal, setShowModal] = useState(false)
- const { treeNodes, loading } = useContext(FSTreeContext)
+ const { treeNodes, loading } = useApplication()
return (
diff --git a/packages/dm-core/src/components/Pickers/DestinationPicker.tsx b/packages/dm-core/src/components/Pickers/DestinationPicker.tsx
index 870119c5a..55d567ec9 100644
--- a/packages/dm-core/src/components/Pickers/DestinationPicker.tsx
+++ b/packages/dm-core/src/components/Pickers/DestinationPicker.tsx
@@ -1,4 +1,4 @@
-import { useContext, useEffect, useState } from 'react'
+import { useEffect, useState } from 'react'
import { EBlueprint } from '../../Enums'
import {
PATH_INPUT_FIELD_WIDTH,
@@ -15,7 +15,7 @@ import {
Tooltip,
} from '@equinor/eds-core-react'
import styled from 'styled-components'
-import { ApplicationContext } from '../../context/ApplicationContext'
+import { useApplication } from '../../ApplicationContext'
import { Tree, TreeNode } from '../../domain/Tree'
import { truncatePathString } from '../../utils/truncatePathString'
import { Dialog } from '../Dialog'
@@ -30,12 +30,12 @@ type TDestinationPickerProps = {
export const DestinationPicker = (props: TDestinationPickerProps) => {
const { onChange, formData, disabled, scope, label } = props
- const appConfig = useContext(ApplicationContext)
+ const { visibleDataSources, dmssAPI } = useApplication()
const [showModal, setShowModal] = useState
(false)
const [loading, setLoading] = useState(true)
const [treeNodes, setTreeNodes] = useState([])
- const tree: Tree = new Tree((t: Tree) => setTreeNodes([...t]))
+ const tree: Tree = new Tree(dmssAPI, (t: Tree) => setTreeNodes([...t]))
useEffect(() => {
setLoading(true)
@@ -43,7 +43,7 @@ export const DestinationPicker = (props: TDestinationPickerProps) => {
tree.initFromPath(scope).finally(() => setLoading(false))
} else {
tree
- .initFromDataSources(appConfig.visibleDataSources)
+ .initFromDataSources(visibleDataSources)
.finally(() => setLoading(false))
}
}, [scope])
diff --git a/packages/dm-core/src/components/Pickers/EntityPickerDialog.tsx b/packages/dm-core/src/components/Pickers/EntityPickerDialog.tsx
index 91b0c063e..0495250d9 100644
--- a/packages/dm-core/src/components/Pickers/EntityPickerDialog.tsx
+++ b/packages/dm-core/src/components/Pickers/EntityPickerDialog.tsx
@@ -1,4 +1,4 @@
-import { ChangeEvent, useContext, useEffect, useState } from 'react'
+import { ChangeEvent, useEffect, useState } from 'react'
import {
Button,
@@ -8,8 +8,8 @@ import {
} from '@equinor/eds-core-react'
import { toast } from 'react-toastify'
import styled from 'styled-components'
+import { useApplication } from '../../ApplicationContext'
import { EBlueprint } from '../../Enums'
-import { ApplicationContext } from '../../context/ApplicationContext'
import { Tree, TreeNode } from '../../domain/Tree'
import { TValidEntity } from '../../types'
import { truncatePathString } from '../../utils/truncatePathString'
@@ -136,20 +136,21 @@ export const EntityPickerDialog = (
multiple = false,
hideInvalidTypes = false,
} = props
- const appConfig = useContext(ApplicationContext)
+ const { dmssAPI, visibleDataSources } = useApplication()
const [loading, setLoading] = useState(true)
const [treeNodes, setTreeNodes] = useState([])
- const tree: Tree = new Tree((t: Tree) => setTreeNodes([...t]))
+ const tree: Tree = new Tree(dmssAPI, (t: Tree) => setTreeNodes([...t]))
const [selectedNodes, setSelectedNodes] = useState([])
useEffect(() => {
setLoading(true)
if (scope) {
+ 2
tree.initFromPath(scope).finally(() => setLoading(false))
} else {
tree
- .initFromDataSources(appConfig.visibleDataSources)
+ .initFromDataSources(visibleDataSources)
.finally(() => setLoading(false))
}
}, [scope])
diff --git a/packages/dm-core/src/components/Pickers/JobHandlerPicker.tsx b/packages/dm-core/src/components/Pickers/JobHandlerPicker.tsx
index 7a2a2be12..ba2bccefc 100644
--- a/packages/dm-core/src/components/Pickers/JobHandlerPicker.tsx
+++ b/packages/dm-core/src/components/Pickers/JobHandlerPicker.tsx
@@ -1,6 +1,6 @@
import { ChangeEvent } from 'react'
-import { useDMSS } from '../../context/DMSSContext'
-import { useSearch } from '../../hooks/useSearch'
+import { useApplication } from '../../ApplicationContext'
+import { useSearch } from '../../hooks'
import { Select } from '../Select'
export const JobHandlerPicker = (props: {
@@ -9,7 +9,7 @@ export const JobHandlerPicker = (props: {
}) => {
const { onChange, formData } = props
const blueprintName = formData.split('/').pop()
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const [searchResult] = useSearch(
{
type: 'dmss://system/SIMOS/Blueprint',
diff --git a/packages/dm-core/src/components/UploadFileButton.tsx b/packages/dm-core/src/components/UploadFileButton.tsx
index 5525b8e32..d3a31f499 100644
--- a/packages/dm-core/src/components/UploadFileButton.tsx
+++ b/packages/dm-core/src/components/UploadFileButton.tsx
@@ -2,7 +2,7 @@ import { Button, Progress } from '@equinor/eds-core-react'
import { AxiosError, AxiosResponse } from 'axios'
import { ChangeEvent, useEffect, useRef, useState } from 'react'
import { toast } from 'react-toastify'
-import { useDMSS } from '../context/DMSSContext'
+import { useApplication } from '../ApplicationContext'
import { TGenericObject, TReference, TValidEntity } from '../types'
import { getKey } from '../utils/objectUtilities'
@@ -21,7 +21,7 @@ export function UploadFileButton(props: {
const textInput = useRef(null)
const [error, setError] = useState()
const [loading, setLoading] = useState(false)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => setError(undefined), [formData])
diff --git a/packages/dm-core/src/components/ViewCreator/InlineRecipeView.tsx b/packages/dm-core/src/components/ViewCreator/InlineRecipeView.tsx
index 5466c76d4..47697b7cc 100644
--- a/packages/dm-core/src/components/ViewCreator/InlineRecipeView.tsx
+++ b/packages/dm-core/src/components/ViewCreator/InlineRecipeView.tsx
@@ -1,4 +1,4 @@
-import { ErrorBoundary, IUIPlugin, useUiPlugins } from '../../index'
+import { ErrorBoundary, IUIPlugin, useApplication } from '../../index'
import { TInlineRecipeViewConfig } from '../../types'
type TInlineRecipeViewProps = IUIPlugin & {
@@ -7,7 +7,7 @@ type TInlineRecipeViewProps = IUIPlugin & {
export const InlineRecipeView = (props: TInlineRecipeViewProps) => {
const { idReference, type, viewConfig, onOpen, onSubmit, onChange } = props
- const { getUiPlugin } = useUiPlugins()
+ const { getUiPlugin } = useApplication()
const UiPlugin = getUiPlugin(viewConfig.recipe.plugin)
return (
diff --git a/packages/dm-core/src/components/ViewCreator/ViewCreator.tsx b/packages/dm-core/src/components/ViewCreator/ViewCreator.tsx
index 68ce59418..92ebab793 100644
--- a/packages/dm-core/src/components/ViewCreator/ViewCreator.tsx
+++ b/packages/dm-core/src/components/ViewCreator/ViewCreator.tsx
@@ -1,7 +1,7 @@
import { Typography } from '@equinor/eds-core-react'
import { AxiosResponse } from 'axios'
import React, { useEffect, useState } from 'react'
-import { EntityView, Loading, TAttribute, useDMSS } from '../../index'
+import { EntityView, Loading, TAttribute, useApplication } from '../../index'
import {
IUIPlugin,
TInlineRecipeViewConfig,
@@ -39,7 +39,7 @@ type TViewCreator = Omit & {
*/
export const ViewCreator = (props: TViewCreator): React.ReactElement => {
const { idReference, viewConfig, onOpen, onSubmit, onChange } = props
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState()
const [attribute, setAttribute] = useState()
diff --git a/packages/dm-core/src/context/ApplicationContext.tsx b/packages/dm-core/src/context/ApplicationContext.tsx
deleted file mode 100644
index f1b26f973..000000000
--- a/packages/dm-core/src/context/ApplicationContext.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React, { useContext } from 'react'
-export const ApplicationContext = React.createContext({})
-
-export const useApplication = () => {
- const context = useContext(ApplicationContext)
- if (context === undefined) {
- throw new Error('useApplication must be used within a ApplicationProvider')
- }
- return context
-}
diff --git a/packages/dm-core/src/context/DMJobContext.tsx b/packages/dm-core/src/context/DMJobContext.tsx
deleted file mode 100644
index a1e4ad434..000000000
--- a/packages/dm-core/src/context/DMJobContext.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { ReactNode, createContext, useContext } from 'react'
-import { AuthContext } from 'react-oauth2-code-pkce'
-import { DmJobAPI } from '../services'
-
-const DMJobContext = createContext(undefined)
-
-export const DMJobProvider = (props: {
- children: ReactNode
- dmJobPath?: string
-}) => {
- const { token } = useContext(AuthContext)
- if (!props.dmJobPath)
- throw new Error('DMJobProvider is missing a job api url')
- const dmJobApi = new DmJobAPI(token, props.dmJobPath)
- return (
-
- {props.children}
-
- )
-}
-
-export const useDmJob = () => {
- const context = useContext(DMJobContext)
- if (!context) throw new Error('useDmJob must be used within a DMJobProvider')
- return context
-}
diff --git a/packages/dm-core/src/context/DMSSContext.tsx b/packages/dm-core/src/context/DMSSContext.tsx
deleted file mode 100644
index a37b828b4..000000000
--- a/packages/dm-core/src/context/DMSSContext.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { ReactNode, createContext, useContext } from 'react'
-import { AuthContext } from 'react-oauth2-code-pkce'
-import DmssAPI from '../services/api/DmssAPI'
-
-const DMSSContext = createContext(undefined)
-
-export const DMSSProvider = (props: {
- children: ReactNode
- dmssBasePath?: string
- enableBlueprintCache?: boolean
-}) => {
- const { token } = useContext(AuthContext)
- const dmssAPIOriginal = new DmssAPI(token, props.dmssBasePath)
- const dmssAPI = new DmssAPI(token, props.dmssBasePath)
-
- // @ts-ignore
- dmssAPI.blueprintGet = async (requestParameters, options) => {
- const cacheKey = `${requestParameters.typeRef}${requestParameters.context}`
- const cachedValue = window.sessionStorage.getItem(cacheKey)
- if (!cachedValue) {
- return dmssAPIOriginal
- .blueprintGet(requestParameters)
- .then((response) => {
- if (props.enableBlueprintCache)
- window.sessionStorage.setItem(
- cacheKey,
- JSON.stringify(response.data)
- )
- return response
- })
- }
- return {
- data: JSON.parse(cachedValue),
- status: 200,
- statusText: 'ok',
- }
- }
-
- return (
-
- {props.children}
-
- )
-}
-
-export const useDMSS = () => {
- const context = useContext(DMSSContext)
- if (context === undefined) {
- throw new Error('useDMSS must be used within a DMSSProvider')
- }
- return context
-}
diff --git a/packages/dm-core/src/context/FileSystemTreeContext.tsx b/packages/dm-core/src/context/FileSystemTreeContext.tsx
deleted file mode 100644
index c55718127..000000000
--- a/packages/dm-core/src/context/FileSystemTreeContext.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { ReactNode, createContext, useEffect, useState } from 'react'
-import { Tree, TreeNode } from '../domain/Tree'
-
-export const FSTreeContext = createContext<{
- tree: null | Tree
- treeNodes: TreeNode[]
- loading: boolean
-}>({
- tree: null,
- treeNodes: [],
- loading: false,
-})
-
-export const FSTreeProvider = (props: {
- children: ReactNode
- visibleDataSources: string[]
-}) => {
- const { children, visibleDataSources } = props
- const [loading, setLoading] = useState(true)
- const [treeNodes, setTreeNodes] = useState([])
- const tree: Tree = new Tree((t: Tree) => setTreeNodes([...t]))
-
- useEffect(() => {
- setLoading(true)
- tree
- .initFromDataSources(visibleDataSources)
- .finally(() => setLoading(false))
- }, [])
-
- return (
-
- {children}
-
- )
-}
diff --git a/packages/dm-core/src/context/RoleContext.tsx b/packages/dm-core/src/context/RoleContext.tsx
deleted file mode 100644
index 5ec8cb02a..000000000
--- a/packages/dm-core/src/context/RoleContext.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import {
- Dispatch,
- ReactNode,
- SetStateAction,
- createContext,
- useContext,
- useEffect,
- useState,
-} from 'react'
-import { AuthContext } from 'react-oauth2-code-pkce'
-import { TRole } from '../types'
-
-const DEFAULT_ROLE: TRole = {
- name: 'anonymous',
- authServerRoleName: 'anonymous',
- label: 'Anonymous',
-}
-export const RoleContext = createContext<{
- role: TRole
- setRole: Dispatch>
- roles: TRole[]
-}>({
- role: DEFAULT_ROLE,
- // @ts-ignore
- setRole: () => {
- throw new Error('RoleContex was accessed before the provider registered.')
- },
- roles: [],
-})
-
-function capitalizeFirstLetter(v: string): string {
- return v.charAt(0).toUpperCase() + v.slice(1)
-}
-
-function findFirstCommonRole(appRoles: TRole[], actualRoles: string[]): TRole {
- const matchingRole = appRoles.find((r: TRole) =>
- actualRoles.includes(r.authServerRoleName)
- )
- return matchingRole ?? appRoles[0]
-}
-
-function generateFallbackRoles(roles: string[] | undefined): TRole[] {
- if (!roles) {
- console.warn('No roles has been configured for the application')
- return [DEFAULT_ROLE]
- }
- return roles.map((r) => ({
- name: r,
- label: capitalizeFirstLetter(r),
- authServerRoleName: r,
- }))
-}
-
-export const RoleProvider = (props: {
- children: ReactNode
- roles: TRole[]
-}) => {
- const { children, roles: passedRoles } = props
- const [role, setRole] = useState(DEFAULT_ROLE)
- const [roles, setRoles] = useState(passedRoles)
- const { tokenData } = useContext(AuthContext)
-
- useEffect(() => {
- let newRoles = passedRoles
- if (tokenData) {
- newRoles = newRoles.filter((role) =>
- tokenData.roles.includes(role.authServerRoleName)
- )
- }
- if (passedRoles && !passedRoles.length) {
- // No roles is configured in application. Generate from roles in token
- newRoles = generateFallbackRoles(tokenData?.roles)
- }
- setRoles(newRoles)
- setRole(findFirstCommonRole(newRoles, tokenData?.roles ?? [])) // Default select the first role that exists in tokenData
- }, [tokenData])
-
- return (
-
- {children}
-
- )
-}
diff --git a/packages/dm-core/src/context/UiPluginContext.tsx b/packages/dm-core/src/context/UiPluginContext.tsx
deleted file mode 100644
index d2a50c513..000000000
--- a/packages/dm-core/src/context/UiPluginContext.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React, { createContext, useContext } from 'react'
-import { IUIPlugin, TUiPluginMap } from '../types'
-import { ErrorGroup } from '../utils/ErrorBoundary'
-
-type TUiPluginContext = {
- plugins: TUiPluginMap
- getUiPlugin: (pluginName: string) => (props: IUIPlugin) => React.ReactElement
-}
-
-const UiPluginContext = createContext(undefined)
-
-export const useUiPlugins = () => {
- const context = useContext(UiPluginContext)
- if (context === undefined) {
- throw new Error('useUiPlugins must be used within a UiPluginProvider')
- }
- return context
-}
-
-export const UiPluginProvider = ({
- pluginsToLoad: plugins,
- children,
-}: {
- pluginsToLoad: TUiPluginMap
- children: any
-}) => {
- function getUiPlugin(
- pluginName: string
- ): (props: IUIPlugin) => React.ReactElement {
- const plugin = plugins[pluginName]?.component
- if (!plugin)
- return () => (
- Did not find the plugin: {pluginName}
- )
- return plugin
- }
-
- return (
-
- {children}
-
- )
-}
diff --git a/packages/dm-core/src/domain/Tree.ts b/packages/dm-core/src/domain/Tree.ts
index f04ac0b47..37c48d7cd 100644
--- a/packages/dm-core/src/domain/Tree.ts
+++ b/packages/dm-core/src/domain/Tree.ts
@@ -1,6 +1,5 @@
import { AxiosResponse } from 'axios'
import { EBlueprint } from '../Enums'
-import { useDMSS } from '../context/DMSSContext'
import { DmssAPI } from '../services'
import { TAttribute, TBlueprint, TPackage } from '../types'
import { splitAddress } from '../utils/addressUtilities'
@@ -275,8 +274,8 @@ export class Tree {
dmssApi: DmssAPI
updateCallback: (t: Tree) => void
- constructor(updateCallback: (t: Tree) => void) {
- this.dmssApi = useDMSS()
+ constructor(dmssAPI: DmssAPI, updateCallback: (t: Tree) => void) {
+ this.dmssApi = dmssAPI
this.updateCallback = updateCallback
}
@@ -293,6 +292,7 @@ export class Tree {
}
async initFromDataSources(dataSources?: string[]) {
+ if (!dataSources) return
// Add the dataSources as the top-level nodes
const allDataSources = await this.dmssApi
.dataSourceGetAll()
diff --git a/packages/dm-core/src/hooks/useBlueprint.tsx b/packages/dm-core/src/hooks/useBlueprint.tsx
index 992c4f253..540b7c4cd 100644
--- a/packages/dm-core/src/hooks/useBlueprint.tsx
+++ b/packages/dm-core/src/hooks/useBlueprint.tsx
@@ -1,8 +1,7 @@
import { AxiosError } from 'axios'
-import { useContext, useEffect, useState } from 'react'
+import { useEffect, useState } from 'react'
import { TBlueprint, TStorageRecipe, TUiRecipe } from 'src/types'
-import { ApplicationContext } from '../context/ApplicationContext'
-import { useDMSS } from '../context/DMSSContext'
+import { useApplication } from '../ApplicationContext'
import { ErrorResponse } from '../services'
interface IUseBlueprint {
@@ -43,8 +42,7 @@ export const useBlueprint = (typeRef: string): IUseBlueprint => {
const [initialUiRecipe, setInitialUiRecipe] = useState()
const [isLoading, setLoading] = useState(true)
const [error, setError] = useState(null)
- const { name } = useContext(ApplicationContext)
- const dmssAPI = useDMSS()
+ const { dmssAPI, name } = useApplication()
useEffect(() => {
dmssAPI
diff --git a/packages/dm-core/src/hooks/useDocument.test.tsx b/packages/dm-core/src/hooks/useDocument.test.tsx
index 3504bdc1a..afe4d2415 100644
--- a/packages/dm-core/src/hooks/useDocument.test.tsx
+++ b/packages/dm-core/src/hooks/useDocument.test.tsx
@@ -1,8 +1,8 @@
import { renderHook, waitFor } from '@testing-library/react'
import { useDocument } from './useDocument'
import React from 'react'
-import { DMSSProvider } from '../context/DMSSContext'
import { mockGetDocument } from '../utils/test-utils-dm-core'
+import { DMApplicationProvider } from "../ApplicationContext";
const mockDocument = [
{
@@ -12,8 +12,15 @@ const mockDocument = [
]
const wrapper = (props: { children: React.ReactNode }) => (
- {props.children}
-)
+
+ {props.children}
+
+ )
describe('useDocumentHook', () => {
afterEach(() => {
diff --git a/packages/dm-core/src/hooks/useDocument.tsx b/packages/dm-core/src/hooks/useDocument.tsx
index 3fdc74e7f..b3d985de6 100644
--- a/packages/dm-core/src/hooks/useDocument.tsx
+++ b/packages/dm-core/src/hooks/useDocument.tsx
@@ -1,9 +1,9 @@
import { AxiosError } from 'axios'
import { useEffect, useState } from 'react'
-import { useDMSS } from '../context/DMSSContext'
import { ErrorResponse } from '../services'
import { toast } from 'react-toastify'
+import { useApplication } from '../ApplicationContext'
interface IUseDocumentReturnType {
document: T | null
@@ -56,7 +56,7 @@ export function useDocument(
const [document, setDocument] = useState(null)
const [isLoading, setLoading] = useState(true)
const [error, setError] = useState(null)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => {
setLoading(true)
diff --git a/packages/dm-core/src/hooks/useJob.tsx b/packages/dm-core/src/hooks/useJob.tsx
index b53cf6b61..25c28b03b 100644
--- a/packages/dm-core/src/hooks/useJob.tsx
+++ b/packages/dm-core/src/hooks/useJob.tsx
@@ -1,7 +1,6 @@
import { AxiosError, AxiosResponse } from 'axios'
import { useEffect, useState } from 'react'
-import { useDmJob } from '../context/DMJobContext'
-import { useDMSS } from '../context/DMSSContext'
+import { useApplication } from '../ApplicationContext'
import {
DeleteJobResponse,
ErrorResponse,
@@ -82,8 +81,8 @@ export function useJob(entityId?: string, jobId?: string): IUseJob {
const [status, setStatus] = useState(JobStatus.NotStarted)
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState()
- const dmJobApi = useDmJob()
- const dmssAPI = useDMSS()
+ const { dmJobApi } = useApplication()
+ const { dmssAPI } = useApplication()
let statusIntervalId: NodeJS.Timeout
diff --git a/packages/dm-core/src/hooks/useList/useList.test.tsx b/packages/dm-core/src/hooks/useList/useList.test.tsx
index 21440dfdd..935aebdaa 100644
--- a/packages/dm-core/src/hooks/useList/useList.test.tsx
+++ b/packages/dm-core/src/hooks/useList/useList.test.tsx
@@ -1,7 +1,6 @@
import { cleanup, renderHook, waitFor } from '@testing-library/react'
import { useList } from './useList'
import React from 'react'
-import { DMSSProvider } from '../../context/DMSSContext'
import {
mockAttributeGet,
mockDocumentAdd,
@@ -10,6 +9,7 @@ import {
mockInstantiateEntity,
mockUpdateDocument,
} from '../../utils/test-utils-dm-core'
+import { DMApplicationProvider } from "../../ApplicationContext";
const setupContained = () => {
const attribute = {
@@ -40,8 +40,16 @@ const setupContained = () => {
}
const wrapper = (props: { children: React.ReactNode }) => (
- {props.children}
-)
+
+ {props.children}
+
+ )
afterEach(() => {
cleanup()
diff --git a/packages/dm-core/src/hooks/useList/useList.tsx b/packages/dm-core/src/hooks/useList/useList.tsx
index e4a26930b..f987f1c9b 100644
--- a/packages/dm-core/src/hooks/useList/useList.tsx
+++ b/packages/dm-core/src/hooks/useList/useList.tsx
@@ -1,7 +1,7 @@
import { AxiosError, AxiosResponse, isAxiosError } from 'axios'
import { useEffect, useState } from 'react'
+import { useApplication } from '../../ApplicationContext'
import { EBlueprint } from '../../Enums'
-import { useDMSS } from '../../context/DMSSContext'
import { ErrorResponse } from '../../services'
import { TAttribute, TGenericObject, TLinkReference } from '../../types'
import { resolveRelativeAddressSimplified } from '../../utils/addressUtilities'
@@ -20,7 +20,7 @@ export function useList(
const [error, setError] = useState(null)
const [dirtyState, setDirtyState] = useState(false)
const [refresh, reloadData] = useState()
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => {
dmssAPI
diff --git a/packages/dm-core/src/hooks/useRecipe.tsx b/packages/dm-core/src/hooks/useRecipe.tsx
index 71c2af5d0..8680e8ed2 100644
--- a/packages/dm-core/src/hooks/useRecipe.tsx
+++ b/packages/dm-core/src/hooks/useRecipe.tsx
@@ -1,13 +1,6 @@
import { AxiosError } from 'axios'
-import { useContext, useEffect, useState } from 'react'
-import {
- ApplicationContext,
- ErrorResponse,
- IUIPlugin,
- TUiRecipe,
- useDMSS,
- useUiPlugins,
-} from '../index'
+import { useEffect, useState } from 'react'
+import { ErrorResponse, IUIPlugin, TUiRecipe, useApplication } from '../index'
export const findRecipe = (
recipes: TUiRecipe[],
@@ -92,7 +85,7 @@ export const useRecipe = (
recipeName?: string,
dimensions: string = ''
): IUseRecipe => {
- const { getUiPlugin } = useUiPlugins()
+ const { getUiPlugin } = useApplication()
const [foundRecipe, setFoundRecipe] = useState()
const [findRecipeError, setFindRecipeError] = useState(
null
@@ -100,8 +93,7 @@ export const useRecipe = (
const [isLoading, setLoading] = useState(true)
const [error, setError] = useState(null)
- const dmssAPI = useDMSS()
- const { name } = useContext(ApplicationContext)
+ const { dmssAPI, name } = useApplication()
useEffect(() => {
setLoading(true)
diff --git a/packages/dm-core/src/hooks/useSearch.tsx b/packages/dm-core/src/hooks/useSearch.tsx
index 703747d04..b6eb53e57 100644
--- a/packages/dm-core/src/hooks/useSearch.tsx
+++ b/packages/dm-core/src/hooks/useSearch.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
-import { useDMSS } from '../context/DMSSContext'
+import { useApplication } from '../ApplicationContext'
export function useSearch(
body: any,
@@ -9,7 +9,7 @@ export function useSearch(
const [searchResult, setSearchResult] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [hasError, setHasError] = useState(false)
- const dmssAPI = useDMSS()
+ const { dmssAPI } = useApplication()
useEffect(() => {
setIsLoading(true)
diff --git a/packages/dm-core/src/index.tsx b/packages/dm-core/src/index.tsx
index dd8b130f4..a59996b31 100644
--- a/packages/dm-core/src/index.tsx
+++ b/packages/dm-core/src/index.tsx
@@ -6,12 +6,7 @@ export { AuthContext, AuthProvider } from 'react-oauth2-code-pkce'
export * from './Enums'
export * from './components'
export { colors } from './colors'
-export * from './context/ApplicationContext'
-export * from './context/DMSSContext'
-export * from './context/DMJobContext'
-export * from './context/FileSystemTreeContext'
-export * from './context/UiPluginContext'
-export * from './context/RoleContext'
+export * from './ApplicationContext'
export * from './domain/Tree'
export * from './services'
export * from './services/api/configs/gen-job/models'