diff --git a/example/app/data/DemoDataSource/recipes/plugins/list/task_list/task.recipe.json b/example/app/data/DemoDataSource/recipes/plugins/list/task_list/task.recipe.json
index 6bd7e28fe..41ccaa3dd 100644
--- a/example/app/data/DemoDataSource/recipes/plugins/list/task_list/task.recipe.json
+++ b/example/app/data/DemoDataSource/recipes/plugins/list/task_list/task.recipe.json
@@ -58,8 +58,7 @@
"selectFromScope": "dmss://DemoDataSource/plugins/list/task_list",
"headers": [
"name",
- "assigned",
- "address"
+ "assigned"
],
"functionality": {
"type": "PLUGINS:dm-core-plugins/list/FunctionalityConfig",
diff --git a/example/src/plugins/table/TestUseListPlugin.tsx b/example/src/plugins/table/TestUseListPlugin.tsx
index 64b422647..7196dee43 100644
--- a/example/src/plugins/table/TestUseListPlugin.tsx
+++ b/example/src/plugins/table/TestUseListPlugin.tsx
@@ -70,7 +70,7 @@ const TestUseListPlugin = (props: IUIPlugin) => {
}}
/>
{attribute && attribute.contained && (
-
+
)}
{dirtyState && }
diff --git a/packages/dm-core-plugins/src/list/ListPlugin.tsx b/packages/dm-core-plugins/src/list/ListPlugin.tsx
index 4eaa26944..1e10c45a9 100644
--- a/packages/dm-core-plugins/src/list/ListPlugin.tsx
+++ b/packages/dm-core-plugins/src/list/ListPlugin.tsx
@@ -71,7 +71,6 @@ export const ListPlugin = (props: IUIPlugin & { config?: TListConfig }) => {
const [showModal, setShowModal] = useState(false)
const [expanded, setExpanded] = useState>({})
- // @ts-ignore
const paginatedRows = useMemo(
() =>
items &&
diff --git a/packages/dm-core/jest.config.js b/packages/dm-core/jest.config.js
index b2e37311e..da633b7a6 100644
--- a/packages/dm-core/jest.config.js
+++ b/packages/dm-core/jest.config.js
@@ -1,6 +1,5 @@
const packageJson = require('./package.json')
const base = require('../../jest.config.base')
-
module.exports = {
...base,
testEnvironment: 'jsdom',
diff --git a/packages/dm-core/src/hooks/useList.test.tsx b/packages/dm-core/src/hooks/useList.test.tsx
index 1e807d273..381e0048c 100644
--- a/packages/dm-core/src/hooks/useList.test.tsx
+++ b/packages/dm-core/src/hooks/useList.test.tsx
@@ -6,26 +6,38 @@ import {
mockAttributeGet,
mockDocumentAdd,
mockDocumentRemove,
- mockGetDocument,
mockGetList,
mockInstantiateEntity,
mockUpdateDocument,
} from '../utils/test-utils-dm-core'
-const attribute = {
- contained: true,
-}
+const setupContained = () => {
+ const attribute = {
+ contained: true,
+ }
-const mockList = [
- {
- name: 'document1',
- description: 'Description1',
- },
- {
- name: 'document2',
- description: 'Description2',
- },
-]
+ const mockList = {
+ 'testDS/1': {
+ '0': [
+ {
+ name: 'document1',
+ description: 'Description1',
+ },
+ {
+ name: 'document2',
+ description: 'Description2',
+ },
+ ],
+ },
+ }
+
+ mockAttributeGet(attribute)
+ const mock = mockGetList(mockList)
+ return {
+ mock,
+ mockList: mockList['testDS/1'][0],
+ }
+}
const wrapper = (props: { children: React.ReactNode }) => (
{props.children}
@@ -36,388 +48,669 @@ afterEach(() => {
jest.clearAllMocks()
})
-test('list items', async () => {
- mockAttributeGet(attribute)
- const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+describe('contained list', () => {
+ test('list items', async () => {
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
})
})
-})
-test('should return error message when fetching lists fails', async () => {
- mockAttributeGet(attribute)
- const mock = mockGetList()
- const { result } = renderHook(() => useList('testDS/-1'), { wrapper })
- await waitFor(() => {
- expect(result.current.items).toEqual([])
- expect(result.current.isLoading).toEqual(false)
- expect(result.current.error).toEqual({
- message: undefined,
- data: 'error',
+ test('should return error message when fetching lists fails', async () => {
+ mockAttributeGet({
+ contained: true,
+ })
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/-1'), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([])
+ expect(result.current.isLoading).toEqual(false)
+ expect(result.current.error).toEqual({
+ message: undefined,
+ data: 'error',
+ })
+ expect(mock).toHaveBeenCalledTimes(1)
})
- expect(mock).toHaveBeenCalledTimes(1)
})
-})
-test('add item and not save', async () => {
- const newEntity = {
- name: 'Document3',
- description: 'Description3',
- }
- mockInstantiateEntity(newEntity)
- mockAttributeGet(attribute)
- const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(async () => await result.current.addItem(false))
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- {
- index: 2,
- isSaved: false,
- reference: null,
- key: expect.any(String),
- data: newEntity,
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+ test('add item and not save', async () => {
+ const newEntity = {
+ name: 'Document3',
+ description: 'Description3',
+ }
+ mockInstantiateEntity(newEntity)
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(async () => await result.current.addItem(false))
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ {
+ index: 2,
+ isSaved: false,
+ reference: null,
+ key: expect.any(String),
+ data: newEntity,
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
})
})
-})
-test('add item and save', async () => {
- const newEntity = {
- name: 'Document3',
- description: 'Description3',
- }
- mockInstantiateEntity(newEntity)
- mockAttributeGet(attribute)
- mockDocumentAdd(newEntity)
- const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(async () => await result.current.addItem())
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- {
- index: 2,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: newEntity,
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+ test('add item and save', async () => {
+ const newEntity = {
+ name: 'Document3',
+ description: 'Description3',
+ }
+ mockInstantiateEntity(newEntity)
+ mockDocumentAdd(newEntity)
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(async () => await result.current.addItem())
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ {
+ index: 2,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: newEntity,
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
})
})
-})
-test('remove item and not save', async () => {
- mockAttributeGet(attribute)
- const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(async () => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+ test('remove item and not save', async () => {
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(async () => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
+ await waitFor(async () => {
+ await result.current.removeItem(result.current.items[0], false)
+ expect(result.current.items).toEqual([
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
})
})
- await waitFor(async () => {
- await result.current.removeItem(result.current.items[0], false)
- expect(result.current.items).toEqual([
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- })
-})
-test('remove item and save', async () => {
- mockAttributeGet(attribute)
- mockDocumentRemove()
- const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(async () => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+ test('remove item and save', async () => {
+ mockDocumentRemove()
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(async () => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
+ await waitFor(async () => {
+ await result.current.removeItem(result.current.items[0])
+ expect(result.current.items).toEqual([
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
})
})
- await waitFor(async () => {
- await result.current.removeItem(result.current.items[0])
- expect(result.current.items).toEqual([
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
+
+ test('move item up', async () => {
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
+ await waitFor(
+ async () => await result.current.moveItem(result.current.items[1], 'up')
+ )
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ ])
+ })
})
-})
-test('move item up', async () => {
- mockAttributeGet(attribute)
- const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+ test('move item down', async () => {
+ const { mock, mockList } = setupContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
+ await waitFor(
+ async () => await result.current.moveItem(result.current.items[0], 'down')
+ )
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ ])
})
})
- await waitFor(
- async () => await result.current.moveItem(result.current.items[1], 'up')
- )
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- ])
+
+ test('save items', async () => {
+ const { mock, mockList } = setupContained()
+ mockUpdateDocument({})
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
+ await waitFor(() =>
+ result.current.updateAttribute(
+ result.current.items[1],
+ 'description',
+ 'new description'
+ )
+ )
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: false,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ })
+ await waitFor(async () => await result.current.save())
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: null,
+ key: expect.any(String),
+ data: mockList[1],
+ },
+ ])
+ })
})
})
-test('move item down', async () => {
+const setupNonContained = () => {
+ const attribute = {
+ contained: false,
+ }
+
+ const mockList = {
+ 'testDS/1': {
+ '0': [
+ {
+ referenceType: 'link',
+ address: '$1',
+ type: 'dmss://system/SIMOS/Reference',
+ },
+ {
+ referenceType: 'link',
+ address: '$2',
+ type: 'dmss://system/SIMOS/Reference',
+ },
+ ],
+ '1': [
+ {
+ name: 'document1',
+ description: 'Description1',
+ },
+ {
+ name: 'document2',
+ description: 'Description2',
+ },
+ ],
+ },
+ }
+
mockAttributeGet(attribute)
const mock = mockGetList(mockList)
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+ return {
+ mock,
+ referenceList: mockList['testDS/1'][0],
+ resolvedList: mockList['testDS/1'][1],
+ }
+}
+
+describe('non contained list with resolve references enabled', () => {
+ test('list items', async () => {
+ const { mock, resolvedList, referenceList } = setupNonContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: referenceList[0],
+ key: expect.any(String),
+ data: resolvedList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: referenceList[1],
+ key: expect.any(String),
+ data: resolvedList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(2)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
+ })
+
+ test('add reference and not save', async () => {
+ const newReference = {
+ referenceType: 'link',
+ address: '$3',
+ type: 'dmss://system/SIMOS/Reference',
+ }
+ const newEntity = {
+ name: 'Document3',
+ description: 'Description3',
+ }
+ mockDocumentAdd(newEntity)
+ const { mock, resolvedList, referenceList } = setupNonContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(
+ async () => await result.current.addReference('$3', newEntity, false)
+ )
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: referenceList[0],
+ key: expect.any(String),
+ data: resolvedList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: referenceList[1],
+ key: expect.any(String),
+ data: resolvedList[1],
+ },
+ {
+ index: 2,
+ isSaved: false,
+ reference: newReference,
+ key: expect.any(String),
+ data: newEntity,
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(2)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
})
})
- await waitFor(
- async () => await result.current.moveItem(result.current.items[0], 'down')
- )
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- ])
+
+ test('add reference and save', async () => {
+ const newReference = {
+ referenceType: 'link',
+ address: '$3',
+ type: 'dmss://system/SIMOS/Reference',
+ }
+ const newEntity = {
+ name: 'Document3',
+ description: 'Description3',
+ }
+ mockDocumentAdd(newEntity)
+ const { mock, resolvedList, referenceList } = setupNonContained()
+ const { result } = renderHook(() => useList('testDS/1'), { wrapper })
+ await waitFor(
+ async () => await result.current.addReference('$3', newEntity)
+ )
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: referenceList[0],
+ key: expect.any(String),
+ data: resolvedList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: referenceList[1],
+ key: expect.any(String),
+ data: resolvedList[1],
+ },
+ {
+ index: 2,
+ isSaved: true,
+ reference: newReference,
+ key: expect.any(String),
+ data: newEntity,
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(2)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
})
})
-test('save items', async () => {
- mockAttributeGet(attribute)
- const mock = mockGetList(mockList)
- mockUpdateDocument({})
- const { result } = renderHook(() => useList('testDS/1'), { wrapper })
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
- expect(mock).toHaveBeenCalledTimes(1)
- expect(mock).toHaveBeenCalledWith({
- address: 'testDS/1',
- depth: 0,
+describe('non contained list with resolve references disabled', () => {
+ test('list items', async () => {
+ const { mock, resolvedList, referenceList } = setupNonContained()
+ const { result } = renderHook(() => useList('testDS/1', false), { wrapper })
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: referenceList[0],
+ key: expect.any(String),
+ data: referenceList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: referenceList[1],
+ key: expect.any(String),
+ data: referenceList[1],
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
})
})
- await waitFor(() =>
- result.current.updateAttribute(
- result.current.items[1],
- 'description',
- 'new description'
+
+ test('add reference and not save', async () => {
+ const newReference = {
+ referenceType: 'link',
+ address: '$3',
+ type: 'dmss://system/SIMOS/Reference',
+ }
+ mockDocumentAdd(newReference)
+ const { mock, resolvedList, referenceList } = setupNonContained()
+ const { result } = renderHook(() => useList('testDS/1', false), { wrapper })
+ await waitFor(
+ async () => await result.current.addReference('$3', newReference, false)
)
- )
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: false,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: referenceList[0],
+ key: expect.any(String),
+ data: referenceList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: referenceList[1],
+ key: expect.any(String),
+ data: referenceList[1],
+ },
+ {
+ index: 2,
+ isSaved: false,
+ reference: newReference,
+ key: expect.any(String),
+ data: newReference,
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
})
- await waitFor(async () => await result.current.save())
- await waitFor(() => {
- expect(result.current.items).toEqual([
- {
- index: 0,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[0],
- },
- {
- index: 1,
- isSaved: true,
- reference: null,
- key: expect.any(String),
- data: mockList[1],
- },
- ])
+
+ test('add reference and save', async () => {
+ const newReference = {
+ referenceType: 'link',
+ address: '$3',
+ type: 'dmss://system/SIMOS/Reference',
+ }
+ mockDocumentAdd(newReference)
+ const { mock, resolvedList, referenceList } = setupNonContained()
+ const { result } = renderHook(() => useList('testDS/1', false), { wrapper })
+ await waitFor(
+ async () => await result.current.addReference('$3', newReference)
+ )
+ await waitFor(() => {
+ expect(result.current.items).toEqual([
+ {
+ index: 0,
+ isSaved: true,
+ reference: referenceList[0],
+ key: expect.any(String),
+ data: referenceList[0],
+ },
+ {
+ index: 1,
+ isSaved: true,
+ reference: referenceList[1],
+ key: expect.any(String),
+ data: referenceList[1],
+ },
+ {
+ index: 2,
+ isSaved: true,
+ reference: newReference,
+ key: expect.any(String),
+ data: newReference,
+ },
+ ])
+ expect(mock).toHaveBeenCalledTimes(1)
+ expect(mock).toHaveBeenCalledWith({
+ address: 'testDS/1',
+ depth: 0,
+ })
+ })
})
})
diff --git a/packages/dm-core/src/hooks/useList.tsx b/packages/dm-core/src/hooks/useList.tsx
index c46eea8b2..37c064a88 100644
--- a/packages/dm-core/src/hooks/useList.tsx
+++ b/packages/dm-core/src/hooks/useList.tsx
@@ -9,7 +9,7 @@ import { v4 as uuidv4 } from 'uuid'
export type TItem = {
key: string
index: number
- data: T
+ data: T | null
reference: TLinkReference | null
isSaved: boolean
}
@@ -18,13 +18,13 @@ interface IUseListReturnType {
items: TItem[]
attribute: TAttribute | null
isLoading: boolean
- addItem: (saveOnAdd?: boolean) => Promise
+ addItem: (saveOnAdd?: boolean) => Promise
updateItem: (itemToUpdate: TItem, newDocument: T) => Promise
removeItem: (itemToDelete: TItem, saveOnRemove?: boolean) => Promise
error: ErrorResponse | null
addReference: (
address: string,
- entity: T,
+ entity: T | null,
saveOnAdd?: boolean
) => Promise
save: () => Promise
@@ -76,69 +76,61 @@ export function useList(
useEffect(() => {
if (!attribute) return
setLoading(true)
-
- const effect = async () => {
- setDirtyState(false)
- dmssAPI
- .documentGet({
- address: idReference,
- depth: 0,
- })
- .then(async (response: AxiosResponse) => {
- if (attribute.contained) {
- if (!Array.isArray(response.data)) {
- throw new Error(
- `Not an array! Got document ${JSON.stringify(response.data)} `
- )
- }
-
- const items = Object.values(response.data).map((data, index) => ({
- key: uuidv4(),
- index: index,
- data: data,
- reference: null,
- isSaved: true,
- }))
- // @ts-ignore
- setItems(items)
- setError(null)
- } else {
- const resolved = resolveReferences
- ? await dmssAPI.documentGet({
- address: idReference,
- depth: 1,
- })
- : []
- const items = Object.values(response.data).map((data, index) => ({
- key: uuidv4(),
- index: index,
- // @ts-ignore
- data: resolveReferences ? resolved.data[index] : data,
- reference: data,
- isSaved: true,
- }))
- // @ts-ignore
- setItems(items)
- setError(null)
+ setDirtyState(false)
+ dmssAPI
+ .documentGet({
+ address: idReference,
+ depth: 0,
+ })
+ .then(async (response: AxiosResponse) => {
+ if (attribute.contained) {
+ if (!Array.isArray(response.data)) {
+ throw new Error(
+ `Not an array! Got document ${JSON.stringify(response.data)} `
+ )
}
- })
- .catch((error: AxiosError) => {
- setError(error.response?.data || { message: error.name, data: error })
- })
- .finally(() => setLoading(false))
- }
-
- effect()
+ const items = Object.values(response.data).map((data, index) => ({
+ key: uuidv4(),
+ index: index,
+ data: data,
+ reference: null,
+ isSaved: true,
+ }))
+ setItems(items)
+ setError(null)
+ } else {
+ const resolved =
+ resolveReferences &&
+ (await dmssAPI.documentGet({
+ address: idReference,
+ depth: 1,
+ }))
+ const resolvedItems = (resolved ? resolved.data : []) as T[]
+ const items = Object.values(response.data).map((data, index) => ({
+ key: uuidv4(),
+ index: index,
+ data: resolveReferences ? resolvedItems[index] : (data as T),
+ reference: data as TLinkReference,
+ isSaved: true,
+ }))
+ setItems(items)
+ setError(null)
+ }
+ })
+ .catch((error: AxiosError) => {
+ setError(error.response?.data || { message: error.name, data: error })
+ })
+ .finally(() => setLoading(false))
}, [attribute, refresh])
const addItem = async (saveOnAdd: boolean = true) => {
if (!attribute) throw new Error('Missing attribute')
- if (!items) throw new Error('Missing items')
if (!attribute.contained)
throw new Error(
"Can't add item to a list that has uncontained items, need to use addReference method instead"
)
setLoading(true)
+ const newKey = uuidv4() as string
try {
const newEntity = await dmssAPI.instantiateEntity({
entity: {
@@ -156,14 +148,13 @@ export function useList(
const newList = [
...items,
{
- key: uuidv4(),
+ key: newKey,
index: items?.length,
- data: newEntity.data,
+ data: newEntity.data as T,
reference: null,
isSaved: saveOnAdd,
},
]
- // @ts-ignore
setItems(newList)
} catch (error) {
if (isAxiosError(error)) {
@@ -173,6 +164,7 @@ export function useList(
} finally {
setLoading(false)
}
+ return newKey
}
const removeItem = async (
@@ -180,7 +172,6 @@ export function useList(
saveOnRemove: boolean = true
) => {
if (!attribute) throw new Error('Missing attribute')
- if (!items) throw new Error('Missing items')
setLoading(true)
const index = items.findIndex(
(item: TItem) => item.key === itemToDelete.key
@@ -208,11 +199,10 @@ export function useList(
const addReference = async (
address: string,
- entity: T,
+ entity: T | null,
saveOnAdd: boolean = true
) => {
if (!attribute) throw new Error('Missing attribute')
- if (!items) throw new Error('Missing items')
if (attribute.contained)
throw new Error(
"Can't add reference to a list that has contained items, need to use addItem method instead"
@@ -233,7 +223,6 @@ export function useList(
} else {
setDirtyState(true)
}
-
const newList = [
...items,
{
@@ -262,7 +251,6 @@ export function useList(
saveOnUpdate: boolean = true
) => {
if (!attribute) throw new Error('Missing attribute')
- if (!items) throw new Error('Missing items')
setLoading(true)
const index = items.findIndex(
(item: TItem) => item.key === itemToUpdate.key
@@ -295,8 +283,6 @@ export function useList(
}
const save = async () => {
- // TODO: Updating data of uncontained items
- if (!items) throw new Error('Missing items')
setLoading(true)
const payload = items.map((item) =>
attribute?.contained ? item.data : item.reference
@@ -326,7 +312,6 @@ export function useList(
attribute: string,
newValue: any
) => {
- if (!items) return
const newList = [...items]
const index = items.findIndex(
(item: TItem) => item.key === itemToUpdate.key
diff --git a/packages/dm-core/src/utils/test-utils-dm-core.tsx b/packages/dm-core/src/utils/test-utils-dm-core.tsx
index 0356737fd..32fd9b261 100644
--- a/packages/dm-core/src/utils/test-utils-dm-core.tsx
+++ b/packages/dm-core/src/utils/test-utils-dm-core.tsx
@@ -18,12 +18,17 @@ export const mockGetDocument = (documents: any) => {
return mock
}
-export const mockGetList = (documents: list | null = null) => {
+export const mockGetList = (documents: dict | null = null) => {
const mock = jest.spyOn(DmssAPI.prototype, 'documentGet')
-
- mock.mockImplementation(() => {
- return documents
- ? Promise.resolve({ data: documents })
+ mock.mockImplementation((parameters) => {
+ const list =
+ parameters['address'] in documents
+ ? documents[parameters['address']][parameters['depth']]
+ : null
+ return list
+ ? Promise.resolve({
+ data: list,
+ })
: Promise.reject('error')
})