diff --git a/example/docker-compose.yaml b/example/docker-compose.yaml
index a00456086..f04a4f0cc 100644
--- a/example/docker-compose.yaml
+++ b/example/docker-compose.yaml
@@ -10,8 +10,8 @@ services:
ENVIRONMENT: ${ENVIRONMENT:-local}
RESET_DATA_SOURCE: "off"
SECRET_KEY: sg9aeUM5i1JO4gNN8fQadokJa3_gXQMLBjSGGYcfscs= # Don't reuse this in production...
-# volumes:
-# - ../../data-modelling-storage-service/src:/code/src
+ volumes:
+ - ../../data-modelling-storage-service/src:/code/src
ports:
- '5000:5000'
depends_on:
diff --git a/example/src/ViewPage.tsx b/example/src/ViewPage.tsx
index 76abb78f7..b628ee8dd 100644
--- a/example/src/ViewPage.tsx
+++ b/example/src/ViewPage.tsx
@@ -36,7 +36,13 @@ function ViewPage() {
)
}
- return
+ return (
+
+ )
}
export default ViewPage
diff --git a/example/src/index.tsx b/example/src/index.tsx
index b0f4639ca..2a832dac3 100644
--- a/example/src/index.tsx
+++ b/example/src/index.tsx
@@ -1,5 +1,4 @@
import '@development-framework/dm-core-plugins/dist/main.css'
-import React from 'react'
import 'react-toastify/dist/ReactToastify.min.css'
import './main.css'
@@ -26,7 +25,7 @@ const authConfig = {
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
-
+
{authEnabled ? (
@@ -34,5 +33,5 @@ root.render(
) : (
)}
-
+
)
diff --git a/example/src/plugins/marmo-ui/containers/views/SignalPlot.tsx b/example/src/plugins/marmo-ui/containers/views/SignalPlot.tsx
index ed4f7a678..4228c249d 100644
--- a/example/src/plugins/marmo-ui/containers/views/SignalPlot.tsx
+++ b/example/src/plugins/marmo-ui/containers/views/SignalPlot.tsx
@@ -57,10 +57,12 @@ const ESSPlotPlugin = (props: { document: TGenericObject }) => {
}
const SignalPlot_Component = (props: IUIPlugin) => {
- const { idReference } = props
+ const { idReference, entity } = props
const { document, isLoading, error } = useDocument(
idReference,
- 1
+ 1,
+ true,
+ entity
)
if (isLoading) return
diff --git a/packages/dm-core-plugins/src/form/FormPlugin.tsx b/packages/dm-core-plugins/src/form/FormPlugin.tsx
index f40291e32..579284f85 100644
--- a/packages/dm-core-plugins/src/form/FormPlugin.tsx
+++ b/packages/dm-core-plugins/src/form/FormPlugin.tsx
@@ -9,7 +9,9 @@ import { Form } from './components/Form'
export const FormPlugin = (props: IUIPlugin) => {
const { document, isLoading, updateDocument, error } = useDocument(
props.idReference,
- 0
+ 0,
+ true,
+ props.entity
)
// react-hook-form is unable to rerender when the document is updated.
diff --git a/packages/dm-core-plugins/src/form/components/OpenObjectButton.tsx b/packages/dm-core-plugins/src/form/components/OpenObjectButton.tsx
index 098e9481d..eececd1fa 100644
--- a/packages/dm-core-plugins/src/form/components/OpenObjectButton.tsx
+++ b/packages/dm-core-plugins/src/form/components/OpenObjectButton.tsx
@@ -1,6 +1,7 @@
import {
TInlineRecipeViewConfig,
TReferenceViewConfig,
+ TValidEntity,
TViewConfig,
} from '@development-framework/dm-core'
import { external_link } from '@equinor/eds-icons'
@@ -11,19 +12,22 @@ export const OpenObjectButton = ({
viewId,
viewConfig,
idReference,
+ entity,
}: {
viewId: string
viewConfig: TViewConfig | TReferenceViewConfig | TInlineRecipeViewConfig
idReference?: string
+ entity?: TValidEntity
}) => {
const { onOpen } = useRegistryContext()
+ console.log(entity)
return (
onOpen?.(viewId, viewConfig, idReference)}
+ button-onClick={() => onOpen?.(viewId, viewConfig, entity, idReference)}
icon={external_link}
/>
)
diff --git a/packages/dm-core-plugins/src/form/fields/ArrayField/templates/ArrayComplexTemplate.tsx b/packages/dm-core-plugins/src/form/fields/ArrayField/templates/ArrayComplexTemplate.tsx
index ac30ba76a..865e0ef9e 100644
--- a/packages/dm-core-plugins/src/form/fields/ArrayField/templates/ArrayComplexTemplate.tsx
+++ b/packages/dm-core-plugins/src/form/fields/ArrayField/templates/ArrayComplexTemplate.tsx
@@ -43,6 +43,7 @@ export const ArrayComplexTemplate = (props: TArrayTemplate) => {
onOpen?.(
namePath,
getOpenViewConfig(uiAttribute, namePath),
+ getValues(namePath),
idReference
)
}
@@ -56,6 +57,7 @@ export const ArrayComplexTemplate = (props: TArrayTemplate) => {
)}
{attribute.optional &&
@@ -88,6 +90,7 @@ export const ArrayComplexTemplate = (props: TArrayTemplate) => {
idReference={`${idReference}.${namePath}`}
onOpen={onOpen}
viewConfig={getExpandViewConfig(uiAttribute)}
+ entity={getValues(namePath)}
/>
diff --git a/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelContainedTemplate.tsx b/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelContainedTemplate.tsx
index 7575e7714..8d2ab176e 100644
--- a/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelContainedTemplate.tsx
+++ b/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelContainedTemplate.tsx
@@ -49,6 +49,7 @@ export const ObjectModelContainedTemplate = (
onOpen?.(
namePath,
getOpenViewConfig(uiAttribute, namePath),
+ value,
idReference
)
}
@@ -61,6 +62,7 @@ export const ObjectModelContainedTemplate = (
viewId={namePath}
idReference={idReference}
viewConfig={getOpenViewConfig(uiAttribute, namePath)}
+ entity={value}
/>
)}
{attribute.optional &&
@@ -103,6 +105,7 @@ export const ObjectModelContainedTemplate = (
idReference={`${idReference}.${attribute.name}`}
onOpen={onOpen}
viewConfig={getExpandViewConfig(uiAttribute)}
+ entity={value}
onChange={(data: Record) =>
setValue(
namePath,
diff --git a/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelUncontainedTemplate.tsx b/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelUncontainedTemplate.tsx
index a907aacd8..89597db74 100644
--- a/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelUncontainedTemplate.tsx
+++ b/packages/dm-core-plugins/src/form/fields/ObjectField/templates/ObjectModelUncontainedTemplate.tsx
@@ -58,7 +58,7 @@ export const ObjectModelUncontainedTemplate = (
objectIsNotEmpty={referenceExists}
setIsExpanded={setIsExpanded}
onOpen={() =>
- onOpen?.(namePath, getOpenViewConfig(uiAttribute), address)
+ onOpen?.(namePath, getOpenViewConfig(uiAttribute), value, address)
}
icon={link}
uiAttribute={uiAttribute}
@@ -98,6 +98,7 @@ export const ObjectModelUncontainedTemplate = (
idReference={address ?? ''}
onOpen={onOpen}
viewConfig={getExpandViewConfig(uiAttribute)}
+ entity={value}
/>
diff --git a/packages/dm-core-plugins/src/grid/GridElement.tsx b/packages/dm-core-plugins/src/grid/GridElement.tsx
index e7f86d157..c71ecaa4f 100644
--- a/packages/dm-core-plugins/src/grid/GridElement.tsx
+++ b/packages/dm-core-plugins/src/grid/GridElement.tsx
@@ -1,4 +1,4 @@
-import { ViewCreator } from '@development-framework/dm-core'
+import { TValidEntity, ViewCreator } from '@development-framework/dm-core'
import { Typography } from '@equinor/eds-core-react'
import React from 'react'
import styled from 'styled-components'
@@ -32,11 +32,19 @@ type TGridItemProps = {
showItemBorders: boolean
onSubmit?: (data: any) => void
onChange?: (data: any) => void
+ entity?: TValidEntity
}
export const GridElement = (props: TGridItemProps): React.ReactElement => {
- const { idReference, item, itemBorder, showItemBorders, onSubmit, onChange } =
- props
+ const {
+ idReference,
+ item,
+ itemBorder,
+ showItemBorders,
+ onSubmit,
+ onChange,
+ entity,
+ } = props
return (
{
{item?.title && {item.title}}
void
onChange?: (data: any) => void
+ entity?: TValidEntity
}
export const GridItems = (props: GridItemsProps) => {
@@ -20,10 +22,12 @@ export const GridItems = (props: GridItemsProps) => {
showItemBorders,
onChange,
onSubmit,
+ entity,
} = props
const elements = items.map((item: TGridItem, index) => {
return (
{
- const { config, idReference, type, onSubmit, onChange } = props
+ const { config, idReference, type, onSubmit, onChange, entity } = props
const internalConfig: TGridPluginConfig = {
...defaultConfig,
@@ -54,6 +54,7 @@ export const GridPlugin = (
return (
{
- const { idReference, config: passedConfig, type } = props
+ const {
+ idReference,
+ config: passedConfig,
+ type,
+ entity: passedEntity,
+ } = props
const config: THeaderPluginConfig & { adminRole: string } = {
...defaultHeaderPluginConfig,
...passedConfig,
}
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [anchorEl, setAnchorEl] = useState(null)
- const { document: entity, isLoading } = useDocument(idReference)
+ const { document: entity, isLoading } = useDocument(
+ idReference,
+ 0,
+ true,
+ passedEntity
+ )
const { uiRecipes, isLoading: isBlueprintLoading } = useBlueprint(type)
const { roles, role, dmssAPI, name } = useApplication()
const [aboutOpen, setAboutOpen] = useState(false)
@@ -216,6 +226,7 @@ export default (props: IUIPlugin): React.ReactElement => {
/>
{
- const {
- config,
- idReference,
- }: { config: TJobPluginConfig; idReference: string } = props
+ const { config, idReference, entity } = props
const { dmssAPI } = useApplication()
const { tokenData } = useContext(AuthContext)
const username = tokenData?.preferred_username ?? 'unknown user'
@@ -85,7 +82,7 @@ export const JobCreate = (props: IUIPlugin & { config: TJobPluginConfig }) => {
const { document: jobDocument, updateDocument } = useDocument<
TJob | TRecurringJob
- >(jobTargetAddress, 0, false)
+ >(jobTargetAddress, 0, false, entity)
const {
start,
diff --git a/packages/dm-core-plugins/src/list/ListPlugin.tsx b/packages/dm-core-plugins/src/list/ListPlugin.tsx
index 3ec1c1fe9..173260500 100644
--- a/packages/dm-core-plugins/src/list/ListPlugin.tsx
+++ b/packages/dm-core-plugins/src/list/ListPlugin.tsx
@@ -76,7 +76,7 @@ const defaultConfig: TListConfig = {
}
export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
- const { idReference, config, type, onOpen } = props
+ const { idReference, config, type, onOpen, entity } = props
const internalConfig: TListConfig = {
...defaultConfig,
...config,
@@ -96,7 +96,11 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
moveItem,
reloadData,
updateItem,
- } = useList(idReference, internalConfig.resolveReferences)
+ } = useList(
+ idReference,
+ internalConfig.resolveReferences,
+ entity
+ )
const {
currentItems,
@@ -149,6 +153,7 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
onOpen(
item.key,
view,
+ item.data,
item.idReference,
false,
config.saveExpanded
diff --git a/packages/dm-core-plugins/src/table/Table/Table.tsx b/packages/dm-core-plugins/src/table/Table/Table.tsx
index d8284b624..818c547e9 100644
--- a/packages/dm-core-plugins/src/table/Table/Table.tsx
+++ b/packages/dm-core-plugins/src/table/Table/Table.tsx
@@ -1,6 +1,6 @@
import {
- TGenericObject,
TItem,
+ TValidEntity,
usePagination,
} from '@development-framework/dm-core'
import {
@@ -54,7 +54,7 @@ export function Table(props: TableProps) {
const [tableVariant, setTableVariant] = useState(
config.variant[0].name
)
- const [sortedItems, setSortedItems] = useState[]>([])
+ const [sortedItems, setSortedItems] = useState[]>([])
const [sortColumn, setSortColumn] = useState(undefined)
const [sortDirection, setSortDirection] =
useState('ascending')
@@ -79,7 +79,7 @@ export function Table(props: TableProps) {
}
const handleRemoveItem = async (
- itemToDelete: TItem,
+ itemToDelete: TItem,
saveOnRemove?: boolean | undefined
) => {
setDeletingRow(itemToDelete.key)
@@ -130,7 +130,7 @@ export function Table(props: TableProps) {
setPage(0)
}
- function reorderItems(reorderedItems: TItem[]) {
+ function reorderItems(reorderedItems: TItem[]) {
setItems(reorderedItems)
setDirtyState(true)
}
@@ -196,7 +196,7 @@ export function Table(props: TableProps) {
functionalityConfig={functionalityConfig}
idReference={props.idReference}
index={items.findIndex(
- (it: TItem) => it.key === item.key
+ (it: TItem) => it.key === item.key
)}
item={item}
items={items}
diff --git a/packages/dm-core-plugins/src/table/Table/TableRow/TableCell/TableCell.tsx b/packages/dm-core-plugins/src/table/Table/TableRow/TableCell/TableCell.tsx
index 67d6cdf8b..cd18536aa 100644
--- a/packages/dm-core-plugins/src/table/Table/TableRow/TableCell/TableCell.tsx
+++ b/packages/dm-core-plugins/src/table/Table/TableRow/TableCell/TableCell.tsx
@@ -26,7 +26,7 @@ export function TableCell(props: TableCellProps) {
// TODO: Add more logic for creating better default values.
// If pointing to complex optional object, it has to be created.
- const value = resolvePath(item.data || {}, column?.data, '')
+ const value = resolvePath(item.data || { type: 'unknown' }, column?.data, '')
if (typeof value === 'object') {
throw new Error(
diff --git a/packages/dm-core-plugins/src/table/Table/TableRow/TableRow.tsx b/packages/dm-core-plugins/src/table/Table/TableRow/TableRow.tsx
index d8573695f..1a870b93f 100644
--- a/packages/dm-core-plugins/src/table/Table/TableRow/TableRow.tsx
+++ b/packages/dm-core-plugins/src/table/Table/TableRow/TableRow.tsx
@@ -52,17 +52,17 @@ export function TableRow(props: TableRowProps) {
)
return
}
- const label =
- config.label ||
+ const label = (config.label ||
item.data?.label ||
item.data?.name ||
- `${idReference.split('.').slice(-1)}`
+ `${idReference.split('.').slice(-1)}`) as string
props.onOpen(
item.key,
{
label: config.labelByIndex ? `${label} #${index + 1}` : label,
type: 'ViewConfig',
},
+ item.data ?? undefined,
item.idReference,
false,
(data: any) => handleItemUpdate(item, data)
diff --git a/packages/dm-core-plugins/src/table/Table/types.ts b/packages/dm-core-plugins/src/table/Table/types.ts
index 12d1ac672..89994707d 100644
--- a/packages/dm-core-plugins/src/table/Table/types.ts
+++ b/packages/dm-core-plugins/src/table/Table/types.ts
@@ -1,10 +1,10 @@
import {
IUIPlugin,
- TGenericObject,
TInlineRecipeViewConfig,
TItem,
TOnOpen,
TReferenceViewConfig,
+ TValidEntity,
TViewConfig,
} from '@development-framework/dm-core'
import { TSortableItem, TTemplate } from '../../common'
@@ -64,18 +64,18 @@ export type TableProps = {
) => void
config: TTableConfig
dirtyState: boolean
- items: TItem[]
+ items: TItem[]
isLoading: boolean
reloadData?: () => void
removeItem: (
- itemToDelete: TItem,
+ itemToDelete: TItem,
saveOnRemove?: boolean
) => Promise
- saveTable: (items: TItem[]) => void
- setItems: React.Dispatch[]>>
+ saveTable: (items: TItem[]) => void
+ setItems: React.Dispatch[]>>
updateItem: (
- itemToUpdate: TItem,
- newDocument: TGenericObject,
+ itemToUpdate: TItem,
+ newDocument: TValidEntity,
saveOnUpdate?: boolean
) => Promise
setDirtyState: React.Dispatch>
@@ -100,24 +100,24 @@ export type TableRowProps = {
) => void
config: TTableConfig
removeItem: (
- itemToDelete: TItem,
+ itemToDelete: TItem,
saveOnRemove?: boolean
) => Promise
editMode: boolean
functionalityConfig: TTableFunctionalityConfig
- item: TItem
+ item: TItem
index: number
idReference: string
- items: TItem[]
+ items: TItem[]
onOpen?: TOnOpen
rowsPerPage: number
disableActions: boolean
setDirtyState: React.Dispatch>
- setItems: React.Dispatch[]>>
+ setItems: React.Dispatch[]>>
showActionsCell: boolean
updateItem: (
- itemToUpdate: TItem,
- newDocument: TGenericObject,
+ itemToUpdate: TItem,
+ newDocument: TValidEntity,
saveOnUpdate?: boolean
) => Promise
tableVariant: TableVariantNameEnum
@@ -125,9 +125,9 @@ export type TableRowProps = {
export type TableRowActionsProps = {
editMode: boolean
- item: TItem
+ item: TItem
removeItem: (
- itemToDelete: TItem,
+ itemToDelete: TItem,
saveOnRemove?: boolean
) => Promise
functionalityConfig: TTableFunctionalityConfig
@@ -138,7 +138,7 @@ export type TableCellProps = {
column: TTableColumnConfig
editMode: boolean
isExpanded: boolean
- item: TItem
+ item: TItem
openItemAsTab: () => void
setIsExpanded: React.Dispatch>
updateItem: (
diff --git a/packages/dm-core-plugins/src/table/Table/utils.ts b/packages/dm-core-plugins/src/table/Table/utils.ts
index c3f7d87b5..3e7751f95 100644
--- a/packages/dm-core-plugins/src/table/Table/utils.ts
+++ b/packages/dm-core-plugins/src/table/Table/utils.ts
@@ -1,4 +1,4 @@
-import { TGenericObject, TItem } from '@development-framework/dm-core'
+import { TItem, TValidEntity } from '@development-framework/dm-core'
import { isObject } from 'lodash'
import {
TTableConfig,
@@ -7,14 +7,16 @@ import {
TableVariantNameEnum,
} from './types'
-function setValue(object: TGenericObject, attribute: string, value: any) {
+function setValue(object: TValidEntity, attribute: string, value: any) {
const properties = attribute.split('.')
const lastProperty = properties.pop()
const lastObject = properties.reduce(
+ // @ts-ignore
(a, prop) => (isObject(a) ? a[prop] : null),
object
)
if (isObject(lastObject) && lastProperty) {
+ // @ts-ignore
lastObject[lastProperty] = value
return true
} else {
@@ -23,25 +25,22 @@ function setValue(object: TGenericObject, attribute: string, value: any) {
}
export function updateItemAttribute(
- items: TItem[],
+ items: TItem[],
key: string,
attribute: string,
newValue: string | number | boolean
) {
const itemsCopy = [...items]
const index = itemsCopy.findIndex((item) => item.key === key)
- const itemData = itemsCopy[index].data || {}
+ const itemData = itemsCopy[index].data || { type: 'unknown' }
const success = setValue(itemData, attribute, newValue)
if (success && itemsCopy[index].data) {
- ;(itemsCopy[index].data as TGenericObject) = itemData
+ ;(itemsCopy[index].data as TValidEntity) = itemData
}
return itemsCopy
}
-export function createNewItemObject(
- data: TGenericObject,
- newItemIndex: number
-) {
+export function createNewItemObject(data: TValidEntity, newItemIndex: number) {
const id: string = crypto.randomUUID()
return {
key: id,
@@ -52,9 +51,9 @@ export function createNewItemObject(
}
export function removeItemFromList(
- items: TItem[],
+ items: TItem[],
key: string
-): TItem[] {
+): TItem[] {
const itemIndex = items.findIndex((item) => item.key === key)
const itemsCopy = [...items]
itemsCopy.splice(itemIndex, 1)
@@ -87,7 +86,7 @@ export function dynamicSort(direction: TTableSortDirection, property: string) {
}
export const resolvePath = (
- object: TGenericObject,
+ object: TValidEntity,
path: string,
defaultValue: any
) =>
diff --git a/packages/dm-core-plugins/src/table/TablePlugin.tsx b/packages/dm-core-plugins/src/table/TablePlugin.tsx
index def8e7b8b..a03f9af27 100644
--- a/packages/dm-core-plugins/src/table/TablePlugin.tsx
+++ b/packages/dm-core-plugins/src/table/TablePlugin.tsx
@@ -1,13 +1,13 @@
import {
IUIPlugin,
- TGenericObject,
+ TValidEntity,
useList,
} from '@development-framework/dm-core'
import { TTableConfig, Table } from './Table/Table'
import * as utils from './utils'
export const TablePlugin = (props: IUIPlugin) => {
- const { idReference } = props
+ const { idReference, entity } = props
const config: TTableConfig = utils.mergeConfigs(props.config)
const {
@@ -22,7 +22,7 @@ export const TablePlugin = (props: IUIPlugin) => {
removeItem,
save,
reloadData,
- } = useList(idReference, true)
+ } = useList(idReference, true, entity)
if (error) throw new Error(JSON.stringify(error, null, 2))
diff --git a/packages/dm-core-plugins/src/view_selector/SidebarPlugin.tsx b/packages/dm-core-plugins/src/view_selector/SidebarPlugin.tsx
index 85206af60..36755db96 100644
--- a/packages/dm-core-plugins/src/view_selector/SidebarPlugin.tsx
+++ b/packages/dm-core-plugins/src/view_selector/SidebarPlugin.tsx
@@ -12,7 +12,7 @@ import { useViewSelector } from './useViewSelector'
export const SidebarPlugin = (
props: IUIPlugin & { config?: TViewSelectorConfig }
): React.ReactElement => {
- const { idReference, config, type } = props
+ const { idReference, config, type, entity } = props
const {
addView,
@@ -23,7 +23,7 @@ export const SidebarPlugin = (
formData,
setSelectedViewId,
setFormData,
- } = useViewSelector(idReference, config)
+ } = useViewSelector(idReference, config, entity)
if (error) {
throw new Error(JSON.stringify(error, null, 2))
@@ -47,6 +47,7 @@ export const SidebarPlugin = (
{viewItem.viewConfig ? (
+ entity?: TValidEntity
}): React.ReactElement => {
const { selectedViewId, viewSelectorItems, setFormData, formData, onOpen } =
props
@@ -29,6 +31,7 @@ export const TabsContent = (props: {
{config.viewConfig ? (
{
diff --git a/packages/dm-core-plugins/src/view_selector/TabsPlugin.tsx b/packages/dm-core-plugins/src/view_selector/TabsPlugin.tsx
index 0b5ee0a84..3223ca2fb 100644
--- a/packages/dm-core-plugins/src/view_selector/TabsPlugin.tsx
+++ b/packages/dm-core-plugins/src/view_selector/TabsPlugin.tsx
@@ -8,8 +8,7 @@ import { useViewSelector } from './useViewSelector'
export const TabsPlugin = (
props: IUIPlugin & { config?: TViewSelectorConfig }
): React.ReactElement | null => {
- const { idReference, config, type, onSubmit, onChange } = props
-
+ const { idReference, config, type, onSubmit, onChange, entity } = props
const {
addView,
removeView,
@@ -20,7 +19,7 @@ export const TabsPlugin = (
formData,
setSelectedViewId,
setFormData,
- } = useViewSelector(idReference, config, onSubmit, onChange)
+ } = useViewSelector(idReference, config, entity, onSubmit, onChange)
if (error) {
throw new Error(JSON.stringify(error, null, 2))
@@ -39,6 +38,7 @@ export const TabsPlugin = (
/>
void
onChange?: (data: any) => void
diff --git a/packages/dm-core-plugins/src/view_selector/useViewSelector.tsx b/packages/dm-core-plugins/src/view_selector/useViewSelector.tsx
index ec92dffbe..f3974946d 100644
--- a/packages/dm-core-plugins/src/view_selector/useViewSelector.tsx
+++ b/packages/dm-core-plugins/src/view_selector/useViewSelector.tsx
@@ -4,7 +4,9 @@ import {
TInlineRecipeViewConfig,
TOnOpen,
TReferenceViewConfig,
+ TValidEntity,
TViewConfig,
+ getScopedEntity,
useDocument,
} from '@development-framework/dm-core'
import * as React from 'react'
@@ -27,6 +29,7 @@ interface IUseViewSelector {
export function useViewSelector(
idReference: string,
config: Record,
+ passedEntity?: TValidEntity | undefined,
onSubmit?: (data: any) => void,
onChange?: (data: any) => void
): IUseViewSelector {
@@ -34,7 +37,7 @@ export function useViewSelector(
document: entity,
isLoading,
error,
- } = useDocument(idReference)
+ } = useDocument(idReference, 0, true, passedEntity)
const [selectedViewId, setSelectedViewId] = useState()
const [viewSelectorItems, setViewSelectorItems] = useState([])
const [formData, setFormData] = useState({})
@@ -47,6 +50,7 @@ export function useViewSelector(
const addView: TOnOpen = (
viewId: string,
viewConfig: TViewConfig | TReferenceViewConfig | TInlineRecipeViewConfig,
+ entity?: TValidEntity,
rootId?: string,
isSubItem?: boolean,
onSubmitAdded?: (data: any) => void,
@@ -57,6 +61,7 @@ export function useViewSelector(
)
const newView: TItemData = {
viewId: viewId,
+ entity: entity,
viewConfig: viewConfig,
label: viewConfig.label ?? viewId,
rootEntityId: rootId || idReference,
@@ -101,6 +106,7 @@ export function useViewSelector(
const backupKey: string = viewItem.viewConfig?.scope ?? 'self' // If the view does not have a scope, the scope is 'self'
const viewId = crypto.randomUUID()
newViews.push({
+ entity: getScopedEntity(entity, viewItem.viewConfig?.scope),
viewConfig: viewItem.viewConfig,
subItems: viewItem.subItems,
eds_icon: viewItem.eds_icon,
@@ -117,6 +123,7 @@ export function useViewSelector(
if (!selectedViewId && viewItem.viewConfig) selectedViewId = viewId
if (!selectedViewId) selectedViewId = subViewId
newViews.push({
+ entity: getScopedEntity(entity, viewItem.viewConfig?.scope),
viewConfig: subItem.viewConfig,
subItems: subItem.subItems,
eds_icon: subItem.eds_icon,
@@ -135,6 +142,7 @@ export function useViewSelector(
} else {
// No views where passed. Create default for all complex attributes and "self"
newViews.push({
+ entity: entity,
label: 'self',
viewId: 'self',
eds_icon: 'home',
@@ -155,6 +163,7 @@ export function useViewSelector(
([key, attributeEntity]: [string, any]) => {
if (typeof attributeEntity === 'object') {
newViews.push({
+ entity: getScopedEntity(entity, key),
viewId: key,
label: key,
onSubmit: onSubmit,
diff --git a/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx b/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx
index 845a57a77..23db1831a 100644
--- a/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx
+++ b/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx
@@ -15,7 +15,7 @@ import { ActionButton, ActionsWrapper, CodeContainer } from './styles'
import { YamlPluginProps, defaultConfig } from './types'
export const YamlPlugin = (props: YamlPluginProps) => {
- const { idReference, config: userConfig } = props
+ const { idReference, config: userConfig, entity } = props
const config = { ...defaultConfig, ...userConfig }
const [depth, setDepth] = useState(0)
const [isEditMode, setIsEditMode] = useState(false)
@@ -28,7 +28,7 @@ export const YamlPlugin = (props: YamlPluginProps) => {
const depthPopoverTrigger = useRef(null)
const { document, isLoading, error, setError, updateDocument } =
- useDocument(idReference, depth, false)
+ useDocument(idReference, depth, false, entity)
const asYAML = useMemo(() => YAML.stringify(document), [document])
const asJSON = useMemo(() => JSON.stringify(document, null, 2), [document])
diff --git a/packages/dm-core/src/ApplicationContext.tsx b/packages/dm-core/src/ApplicationContext.tsx
index be0d81b4f..f88920339 100644
--- a/packages/dm-core/src/ApplicationContext.tsx
+++ b/packages/dm-core/src/ApplicationContext.tsx
@@ -17,6 +17,7 @@ import { IUIPlugin, TApplication, TRole, TUiPluginMap } from './types'
import { ErrorGroup } from './utils/ErrorBoundary'
const DEFAULT_ROLE: TRole = {
+ type: 'role',
name: 'anonymous',
authServerRoleName: 'anonymous',
label: 'Anonymous',
@@ -61,6 +62,7 @@ function generateFallbackRoles(roles: string[] | undefined): TRole[] {
name: r,
label: capitalizeFirstLetter(r),
authServerRoleName: r,
+ type: 'role',
}))
}
diff --git a/packages/dm-core/src/components/EntityView.tsx b/packages/dm-core/src/components/EntityView.tsx
index e30b5d359..635101c72 100644
--- a/packages/dm-core/src/components/EntityView.tsx
+++ b/packages/dm-core/src/components/EntityView.tsx
@@ -25,6 +25,7 @@ const MemoizedUiPlugin = memo(function UiPlugin(
export const EntityView = (props: IEntityView): React.ReactElement => {
const {
idReference,
+ entity,
type,
onSubmit,
onOpen,
@@ -99,6 +100,7 @@ export const EntityView = (props: IEntityView): React.ReactElement => {
}}
>
& {
* @param props
*/
export const ViewCreator = (props: TViewCreator): React.ReactElement => {
- const { idReference, viewConfig, onOpen, onSubmit, onChange } = props
+ const { idReference, viewConfig, onOpen, onSubmit, onChange, entity } = props
const { dmssAPI } = useApplication()
const [error, setError] = useState()
@@ -53,7 +53,7 @@ export const ViewCreator = (props: TViewCreator): React.ReactElement => {
() => getTarget(idReference, viewConfig),
[idReference, viewConfig]
)
- const queryKeys = ['attributes', reference, viewConfig.resolve]
+ const queryKeys = ['attributes', reference, viewConfig.resolve ?? false]
const { isPending, data } = useQuery<{
address: string
@@ -69,10 +69,13 @@ export const ViewCreator = (props: TViewCreator): React.ReactElement => {
resolve: props.viewConfig.resolve,
})
.then((response: any) => response.data)
- .catch((error: AxiosError) => setError(error)),
+ .catch((error: AxiosError) => {
+ setError(error)
+ return null
+ }),
})
- if (isPending || !data?.address) return
+ if (isPending) return
if (error)
return (
@@ -80,18 +83,24 @@ export const ViewCreator = (props: TViewCreator): React.ReactElement => {
{error.message})
)
- if (data.attribute === undefined)
+ if (!data || data.attribute === undefined) {
throw new Error('Unable to find type and dimensions for view')
+ }
if (viewConfig === undefined)
throw new Error(
'Cannot create a View without a "viewConfig". Sure the attribute is properly named?'
)
+ if (entity === undefined) {
+ console.log('UNDEFINED ENTITY')
+ console.log(viewConfig.scope)
+ }
if (isInlineRecipeViewConfig(viewConfig)) {
return (
{
{
return (
{
document: T | null
isLoading: boolean
@@ -54,7 +55,8 @@ interface IUseDocumentReturnType {
export function useDocument(
idReference: string,
depth?: number | undefined,
- notify: boolean = true
+ notify: boolean = true,
+ entity?: TValidEntity | undefined
): IUseDocumentReturnType {
const { dmssAPI } = useApplication()
const [errorResponse, setErrorResponse] = useState(null)
@@ -68,8 +70,13 @@ export function useDocument(
staleTime: 5 * 1000,
refetchOnMount: true,
queryKey: queryKeys,
- queryFn: () =>
- dmssAPI
+ queryFn: () => {
+ if (entity && depth === 0) {
+ console.log(`Recived entity for ${idReference}. Will not fetch`)
+ return entity
+ }
+ console.log(`UseDocument did not recieve entity for ${idReference}`)
+ return dmssAPI
.documentGet({
address: idReference,
depth: documentDepth,
@@ -85,7 +92,8 @@ export function useDocument(
setErrorResponse(
error.response?.data || { message: error.name, data: error }
)
- }),
+ })
+ },
})
const mutation = useMutation({
diff --git a/packages/dm-core/src/hooks/useList/useList.tsx b/packages/dm-core/src/hooks/useList/useList.tsx
index f987f1c9b..91bca14c6 100644
--- a/packages/dm-core/src/hooks/useList/useList.tsx
+++ b/packages/dm-core/src/hooks/useList/useList.tsx
@@ -12,7 +12,8 @@ export type { TItem }
export function useList(
idReference: string,
- resolveReferences: boolean = true
+ resolveReferences: boolean = true,
+ entity?: T
): IUseListReturnType {
const [attribute, setAttribute] = useState(null)
const [items, setItems] = useState[]>([])
@@ -39,6 +40,23 @@ export function useList(
if (!attribute) return
setLoading(true)
setDirtyState(false)
+ if (entity) {
+ const items: TItem[] = Object.values(entity).map((data, index) => ({
+ key: crypto.randomUUID() as string,
+ index: index,
+ idReference: `${idReference}${
+ data._id ? `(_id=${data._id})` : `[${index}]`
+ }`,
+ data: data,
+ reference: null,
+ isSaved: true,
+ }))
+ setItems(items)
+ setError(null)
+ setLoading(false)
+ return
+ }
+ console.log(`Did not recive entity for ${idReference}`)
dmssAPI
.documentGet({
address: idReference,
diff --git a/packages/dm-core/src/types.ts b/packages/dm-core/src/types.ts
index 7c09d80bb..b21a5ba51 100644
--- a/packages/dm-core/src/types.ts
+++ b/packages/dm-core/src/types.ts
@@ -10,6 +10,7 @@ export type TDataSource = {
export type TRole = {
name: string
+ type: string
label: string
authServerRoleName: string
}
@@ -173,6 +174,7 @@ export type TPackage = {
export interface IUIPlugin {
type: string
idReference: string
+ entity?: TValidEntity
onSubmit?: (data: any) => void // Listen to submits
onChange?: (data: any) => void // Listen to changes
onOpen?: TOnOpen
@@ -183,6 +185,7 @@ export interface IUIPlugin {
export type TOnOpen = (
viewId: string,
view: TViewConfig | TReferenceViewConfig | TInlineRecipeViewConfig,
+ entity?: TValidEntity,
rootId?: string,
isSubItem?: boolean,
onSubmit?: (data: any) => void,
@@ -221,6 +224,7 @@ export type TUserIdMapping = { userId: string; username: string }
export type TViewConfig = {
type: string
+ entity?: TValidEntity
scope?: string
resolve?: boolean
label?: string
diff --git a/packages/dm-core/src/utils/addressUtilities.ts b/packages/dm-core/src/utils/addressUtilities.ts
index 578443ea7..0f59cb51e 100644
--- a/packages/dm-core/src/utils/addressUtilities.ts
+++ b/packages/dm-core/src/utils/addressUtilities.ts
@@ -1,3 +1,4 @@
+import { TValidEntity } from '../types'
import { splitString } from './stringUtilities'
/**
@@ -126,3 +127,44 @@ export const resolveRelativeAddressSimplified = (
`Invalid format for relative address '${relativeAddress}' at location '${location}'. Check format and update recipes.`
)
}
+
+export function getScopedEntity(
+ entity?: TValidEntity,
+ scope?: string
+): TValidEntity | undefined {
+ if (!entity) {
+ return undefined
+ }
+ if (!scope) return entity
+
+ if (['self', '.'].includes(scope)) return entity
+
+ let subEntity = entity
+ const scopeParts = scope.split('.')
+
+ for (const part of scopeParts) {
+ if (part.endsWith(']')) {
+ const leftBracketIndex = part.indexOf('[')
+ const rightBracketIndex = part.indexOf(']')
+ const beforeBracket = part.slice(0, leftBracketIndex)
+ const listIndex = parseInt(
+ part.slice(leftBracketIndex + 1, rightBracketIndex)
+ )
+ // @ts-ignore
+ subEntity = subEntity[beforeBracket][listIndex]
+ } else {
+ // @ts-ignore
+ subEntity = subEntity[part]
+ }
+ }
+ if (!subEntity) {
+ console.error(
+ `Could not find scoped entity for scope ${scope} in entity ${JSON.stringify(
+ entity
+ )}`
+ )
+ console.error(entity)
+ console.error(scope)
+ }
+ return subEntity
+}