diff --git a/package-lock.json b/package-lock.json
index 0d4333e14..a6873cfc9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -49,7 +49,7 @@
"slate-history": "^0.100.0",
"slate-hyperscript": "^0.100.0",
"slate-react": "^0.100.0",
- "terraso-client-shared": "github:techmatters/terraso-client-shared#5e56086",
+ "terraso-client-shared": "github:techmatters/terraso-client-shared#d577669",
"use-debounce": "^9.0.4",
"uuid": "^9.0.1",
"web-vitals": "^3.5.0",
@@ -27391,20 +27391,20 @@
},
"node_modules/terraso-backend": {
"version": "0.1.0",
- "resolved": "git+ssh://git@github.com/techmatters/terraso-backend.git#4929e5f4599cebc2f107873dd0075885c4df5e46"
+ "resolved": "git+ssh://git@github.com/techmatters/terraso-backend.git#3d323b5d204a8a7d33579cde27d4498c5b307ecb"
},
"node_modules/terraso-client-shared": {
"version": "0.1.0",
- "resolved": "git+ssh://git@github.com/techmatters/terraso-client-shared.git#b86117e3735b2d8b2f85ffdb68547eb9738b9f77",
- "integrity": "sha512-33236wvHVdvHmd6R0icNzt1PWtVhqZq8nkRguDfhq5bYrH8H3MCKf1umcsJQHJ+Y4csYw6VlFSHKrIzbayIrZw==",
+ "resolved": "git+ssh://git@github.com/techmatters/terraso-client-shared.git#8ca7559da49aafeaaf78ccccfa54e2aaf89dd1b4",
+ "integrity": "sha512-ZOa8+yzrfIn+nwdlhBMxDS9p6OTqfAodvCgj3wJvSifKsUyoq056+H7mGmKmcjJjrLJOzPYNrv4X4BhcnwvfcQ==",
"dependencies": {
- "@reduxjs/toolkit": "^1.9.6",
+ "@reduxjs/toolkit": "^1.9.7",
"jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"react": "^18.2.0",
- "react-redux": "^8.1.2",
- "terraso-backend": "github:techmatters/terraso-backend#4929e5f",
- "uuid": "^9.0.0"
+ "react-redux": "^8.1.3",
+ "terraso-backend": "github:techmatters/terraso-backend#3d323b5",
+ "uuid": "^9.0.1"
}
},
"node_modules/terser": {
diff --git a/package.json b/package.json
index d508b240b..7449624c0 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"slate-history": "^0.100.0",
"slate-hyperscript": "^0.100.0",
"slate-react": "^0.100.0",
- "terraso-client-shared": "github:techmatters/terraso-client-shared#5e56086",
+ "terraso-client-shared": "github:techmatters/terraso-client-shared#d577669",
"use-debounce": "^9.0.4",
"uuid": "^9.0.1",
"web-vitals": "^3.5.0",
diff --git a/src/group/components/GroupSharedDataUpload.js b/src/group/components/GroupSharedDataUpload.js
index 29e78d8e8..baff96190 100644
--- a/src/group/components/GroupSharedDataUpload.js
+++ b/src/group/components/GroupSharedDataUpload.js
@@ -79,9 +79,12 @@ const GroupSharedDataUpload = () => {
-
+
diff --git a/src/group/components/GroupSharedDataUploadFiles.test.js b/src/group/components/GroupSharedDataUploadFiles.test.js
index da4338ad9..9e408f23f 100644
--- a/src/group/components/GroupSharedDataUploadFiles.test.js
+++ b/src/group/components/GroupSharedDataUploadFiles.test.js
@@ -215,6 +215,10 @@ test('GroupSharedDataUpload: Complete Success', async () => {
await waitFor(() => expect(uploadButton).not.toHaveAttribute('disabled'));
await act(async () => fireEvent.click(uploadButton));
expect(navigate.mock.calls[0]).toEqual(['/groups/slug-1']);
+
+ const saveCall = terrasoApi.request.mock.calls[0];
+ expect(saveCall[0].body.get('target_type')).toBe('group');
+ expect(saveCall[0].body.get('target_slug')).toBe('slug-1');
});
test('GroupSharedDataUpload: PDF Success', async () => {
diff --git a/src/group/components/GroupView.test.js b/src/group/components/GroupView.test.js
index a02762582..95d74ea69 100644
--- a/src/group/components/GroupView.test.js
+++ b/src/group/components/GroupView.test.js
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
-import { render, screen } from 'tests/utils';
+import { render, screen, within } from 'tests/utils';
import React from 'react';
import { useParams } from 'react-router-dom';
import * as terrasoApi from 'terraso-client-shared/terrasoApi/api';
@@ -98,6 +98,29 @@ test('GroupView: Display data', async () => {
},
})),
};
+ const accountMembership = {
+ id: 'user-id',
+ userRole: 'MEMBER',
+ membershipStatus: 'APPROVED',
+ };
+ const sharedResources = {
+ edges: Array(6)
+ .fill(0)
+ .map((item, index) => ({
+ node: {
+ source: {
+ id: `de-${index}`,
+ createdAt: '2022-05-20T16:25:21.536679+00:00',
+ name: `Data Entry ${index}`,
+ createdBy: { id: 'user-id', firstName: 'First', lastName: 'Last' },
+ description: `Description ${index}`,
+ size: 3456,
+ entryType: 'FILE',
+ visualizations: { edges: [] },
+ },
+ },
+ })),
+ };
terrasoApi.requestGraphQL.mockReturnValue(
Promise.resolve({
groups: {
@@ -109,6 +132,8 @@ test('GroupView: Display data', async () => {
website: 'https://www.group.org',
email: 'email@email.com',
memberships,
+ accountMembership,
+ sharedResources,
},
},
],
@@ -135,6 +160,17 @@ test('GroupView: Display data', async () => {
).toBeInTheDocument();
expect(screen.getByText(/\+2/i)).toBeInTheDocument();
expect(
- screen.getByRole('button', { name: 'Join Group' })
+ screen.getByRole('button', { name: 'Leave: Group name' })
+ ).toBeInTheDocument();
+
+ // Shared Data
+ const sharedDataRegion = within(
+ screen.getByRole('region', { name: 'Shared files and Links' })
+ );
+ expect(
+ sharedDataRegion.getByRole('heading', { name: 'Shared files and Links' })
).toBeInTheDocument();
+ const entriesList = within(sharedDataRegion.getByRole('list'));
+ const items = entriesList.getAllByRole('listitem');
+ expect(items.length).toBe(6);
});
diff --git a/src/group/groupFragments.ts b/src/group/groupFragments.ts
index 66d7e6cec..1a5723fb1 100644
--- a/src/group/groupFragments.ts
+++ b/src/group/groupFragments.ts
@@ -35,13 +35,17 @@ export const groupsListFields = /* GraphQL */ `
}
`;
-export const dataEntries = /* GraphQL */ `
- fragment dataEntries on GroupNode {
- dataEntries(resourceType_In: $resourceTypes) {
+export const groupDataEntries = /* GraphQL */ `
+ fragment groupDataEntries on GroupNode {
+ sharedResources {
edges {
node {
- ...dataEntry
- ...dataEntryVisualizations
+ source {
+ ... on DataEntryNode {
+ ...dataEntry
+ ...dataEntryVisualizations
+ }
+ }
}
}
}
diff --git a/src/group/groupService.ts b/src/group/groupService.ts
index 19bd1f1e9..a5f1ce769 100644
--- a/src/group/groupService.ts
+++ b/src/group/groupService.ts
@@ -23,6 +23,8 @@ import {
import * as terrasoApi from 'terraso-client-shared/terrasoApi/api';
import { graphql } from 'terrasoApi/shared/graphqlSchema';
+import { extractDataEntries } from 'sharedData/sharedDataUtils';
+
import type { Group } from './groupSlice';
export const fetchGroupToUpdate = (slug: string) => {
@@ -54,18 +56,22 @@ export const fetchGroupToView = async (slug: string) => {
...groupMembersInfo
...groupMembersPending
...accountMembership
+ ...groupDataEntries
}
}
}
}
`);
return terrasoApi
- .requestGraphQL(query, { slug })
+ .requestGraphQL(query, {
+ slug,
+ })
.then(resp => resp.groups?.edges.at(0)?.node || Promise.reject('not_found'))
.then(group => ({
..._.omit(['memberships', 'membershipsCount'], group),
membersInfo: extractMembersInfo(group),
accountMembership: extractAccountMembership(group),
+ dataEntries: extractDataEntries(group),
}));
};
diff --git a/src/group/groupSlice.ts b/src/group/groupSlice.ts
index 2b5f2402a..33ad9e79f 100644
--- a/src/group/groupSlice.ts
+++ b/src/group/groupSlice.ts
@@ -25,6 +25,7 @@ import type { Message } from 'terraso-client-shared/notifications/notificationsS
import { createAsyncThunk } from 'terraso-client-shared/store/utils';
import * as groupService from 'group/groupService';
+import { setList } from 'sharedData/sharedDataSlice';
export type Group = {
slug: string;
@@ -45,6 +46,7 @@ export const fetchGroupView = createAsyncThunk(
async (slug: string, user, { dispatch }) => {
const group = await groupService.fetchGroupToView(slug);
dispatch(setMemberships(getMemberships([group])));
+ dispatch(setList(group.dataEntries));
return group;
}
);
diff --git a/src/landscape/components/LandscapeSharedDataUpload.js b/src/landscape/components/LandscapeSharedDataUpload.js
index 243032a0a..f7f56d2f9 100644
--- a/src/landscape/components/LandscapeSharedDataUpload.js
+++ b/src/landscape/components/LandscapeSharedDataUpload.js
@@ -15,7 +15,6 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import React, { useCallback, useEffect, useMemo } from 'react';
-import _ from 'lodash/fp';
import { usePermissionRedirect } from 'permissions';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -85,11 +84,14 @@ const LandscapeSharedDataUpload = () => {
name: landscape.name,
})}
/>
-
+
diff --git a/src/landscape/components/LandscapeSharedDataUploadLinks.test.js b/src/landscape/components/LandscapeSharedDataUploadLinks.test.js
index bdb6f8c6b..9f20b87d8 100644
--- a/src/landscape/components/LandscapeSharedDataUploadLinks.test.js
+++ b/src/landscape/components/LandscapeSharedDataUploadLinks.test.js
@@ -255,4 +255,17 @@ test('LandscapeSharedDataUpload: Complete Success', async () => {
search: 'scrollTo=shared-data-card-title',
},
]);
+ expect(terrasoApi.requestGraphQL).toHaveBeenCalledTimes(3);
+ const saveCall = terrasoApi.requestGraphQL.mock.calls[2];
+ expect(saveCall[1]).toStrictEqual({
+ input: {
+ description: '',
+ entryType: 'link',
+ targetType: 'landscape',
+ targetSlug: 'slug-1',
+ name: 'name 1',
+ resourceType: 'link',
+ url: 'https://test1.com',
+ },
+ });
});
diff --git a/src/landscape/components/LandscapeSharedDataVisualization.js b/src/landscape/components/LandscapeSharedDataVisualization.js
index 918bfe184..bdafc4a46 100644
--- a/src/landscape/components/LandscapeSharedDataVisualization.js
+++ b/src/landscape/components/LandscapeSharedDataVisualization.js
@@ -58,10 +58,9 @@ const LandscapeSharedDataVisualization = () => {
}
return (
-
+
navigate(`/landscapes/${landscapeSlug}`)}
/>
diff --git a/src/landscape/components/LandscapeSharedDataVisualization.test.js b/src/landscape/components/LandscapeSharedDataVisualization.test.js
index 41e3443e4..7f56934fc 100644
--- a/src/landscape/components/LandscapeSharedDataVisualization.test.js
+++ b/src/landscape/components/LandscapeSharedDataVisualization.test.js
@@ -256,4 +256,13 @@ test('LandscapeSharedDataVisualization: Display visualization', async () => {
expect(domElement.querySelector('p').textContent).toEqual(
'Custom Label: val11'
);
+
+ // Validate api call input to fetch visualization config
+ // It should contain the owner slug and type
+ const fetchCall = terrasoApi.requestGraphQL.mock.calls[3];
+ expect(fetchCall[1]).toStrictEqual({
+ configSlug: 'config-slug',
+ ownerSlug: 'jose-landscape-deafult-test-4',
+ ownerType: 'landscape',
+ });
});
diff --git a/src/landscape/components/LandscapeSharedDataVisualizationConfig.js b/src/landscape/components/LandscapeSharedDataVisualizationConfig.js
index 232ea2cc3..47d095ad1 100644
--- a/src/landscape/components/LandscapeSharedDataVisualizationConfig.js
+++ b/src/landscape/components/LandscapeSharedDataVisualizationConfig.js
@@ -71,7 +71,7 @@ const LandscapeSharedDataVisualizationConfig = () => {
return (
-
+
},
});
}
- if (trimmedQuery.startsWith('query group')) {
+ if (trimmedQuery.startsWith('query dataEntries')) {
return Promise.resolve({
- groups: {
+ dataEntries: {
edges: [
{
node: {
- dataEntries: {
- edges: [
- {
- node: {
- createdAt: '2022-05-17T23:32:50.606587+00:00',
- createdBy: {
- id: 'dc695d00-d6b4-45b2-ab8d-f48206d998da',
- lastName: 'Buitrón',
- firstName: 'José',
- },
- description: '',
- id: 'f00c5564-cf93-471a-94c2-b930cbb0a4f8',
- name: 'File 1',
- resourceType: 'text/csv',
- size: 3565,
- url: 'https://file-url',
- visualizations: { edges: [] },
- },
- },
- ],
+ createdAt: '2022-05-17T23:32:50.606587+00:00',
+ createdBy: {
+ id: 'dc695d00-d6b4-45b2-ab8d-f48206d998da',
+ lastName: 'Buitrón',
+ firstName: 'José',
},
+ description: '',
+ id: 'f00c5564-cf93-471a-94c2-b930cbb0a4f8',
+ name: 'File 1',
+ resourceType: 'text/csv',
+ size: 3565,
+ url: 'https://file-url',
+ visualizations: { edges: [] },
},
},
],
@@ -327,6 +319,14 @@ test('LandscapeSharedDataVisualizationConfig: Create visualization', async () =>
await testAnnotateStep();
await testPreviewStep(map, events);
+ // Fetch data entries validation
+ const fetchCall = terrasoApi.requestGraphQL.mock.calls[3];
+ expect(fetchCall[1]).toStrictEqual({
+ resourceTypes: ['csv', 'xls', 'xlsx'],
+ slug: 'landscape-slug',
+ type: 'landscape',
+ });
+
// Save
await act(async () =>
fireEvent.click(screen.getByRole('button', { name: 'Publish' }))
@@ -335,7 +335,8 @@ test('LandscapeSharedDataVisualizationConfig: Create visualization', async () =>
const saveCall = terrasoApi.requestGraphQL.mock.calls[4];
expect(saveCall[1]).toStrictEqual({
input: {
- groupId: '6a625efb-4ec8-45e8-ad6a-eb052cc3fe65',
+ ownerId: 'e9a65bef-4ef1-4058-bba3-fc73b53eb779',
+ ownerType: 'landscape',
title: 'Test Title',
configuration: JSON.stringify({
datasetConfig: {
diff --git a/src/landscape/components/LandscapeView.test.js b/src/landscape/components/LandscapeView.test.js
index a1434ad39..0ca7feef0 100644
--- a/src/landscape/components/LandscapeView.test.js
+++ b/src/landscape/components/LandscapeView.test.js
@@ -108,19 +108,21 @@ const baseViewTest = async (userRole = 'MEMBER') => {
membershipStatus: 'APPROVED',
};
- const dataEntries = {
+ const sharedResources = {
edges: Array(6)
.fill(0)
.map((item, index) => ({
node: {
- id: `de-${index}`,
- createdAt: '2022-05-20T16:25:21.536679+00:00',
- name: `Data Entry ${index}`,
- createdBy: { id: 'user-id', firstName: 'First', lastName: 'Last' },
- description: `Description ${index}`,
- size: 3456,
- entryType: 'FILE',
- visualizations: { edges: [] },
+ source: {
+ id: `de-${index}`,
+ createdAt: '2022-05-20T16:25:21.536679+00:00',
+ name: `Data Entry ${index}`,
+ createdBy: { id: 'user-id', firstName: 'First', lastName: 'Last' },
+ description: `Description ${index}`,
+ size: 3456,
+ entryType: 'FILE',
+ visualizations: { edges: [] },
+ },
},
})),
};
@@ -141,6 +143,7 @@ const baseViewTest = async (userRole = 'MEMBER') => {
accountMembership,
membershipsCount: 6,
},
+ sharedResources,
},
},
],
@@ -161,17 +164,7 @@ const baseViewTest = async (userRole = 'MEMBER') => {
memberships,
accountMembership,
},
- },
- },
- ],
- },
- })
- .mockResolvedValueOnce({
- groups: {
- edges: [
- {
- node: {
- dataEntries,
+ sharedResources,
},
},
],
@@ -310,7 +303,7 @@ test('LandscapeView: Update Shared Data', async () => {
})
)
);
- const saveCall = terrasoApi.requestGraphQL.mock.calls[3];
+ const saveCall = terrasoApi.requestGraphQL.mock.calls[2];
expect(saveCall[1].input).toEqual({
id: 'de-3',
diff --git a/src/landscape/landscapeFragments.js b/src/landscape/landscapeFragments.js
index c9d292f57..a998e7232 100644
--- a/src/landscape/landscapeFragments.js
+++ b/src/landscape/landscapeFragments.js
@@ -116,3 +116,20 @@ export const defaultGroupWithMembersSample = /* GraphQL */ `
}
}
`;
+
+export const landscapeDataEntries = /* GraphQL */ `
+ fragment landscapeDataEntries on LandscapeNode {
+ sharedResources {
+ edges {
+ node {
+ source {
+ ... on DataEntryNode {
+ ...dataEntry
+ ...dataEntryVisualizations
+ }
+ }
+ }
+ }
+ }
+ }
+`;
diff --git a/src/landscape/landscapeService.js b/src/landscape/landscapeService.js
index f79784227..246a85149 100644
--- a/src/landscape/landscapeService.js
+++ b/src/landscape/landscapeService.js
@@ -24,6 +24,7 @@ import { graphql } from 'terrasoApi/shared/graphqlSchema';
import { countryNameForCode } from 'common/countries';
import * as gisService from 'gis/gisService';
+import { extractDataEntries } from 'sharedData/sharedDataUtils';
import { extractTerms } from 'taxonomies/taxonomiesUtils';
import { ALL_PARTNERSHIP_STATUS } from './landscapeConstants';
@@ -149,6 +150,7 @@ export const fetchLandscapeToView = slug => {
...landscapeFields
...landscapePartnershipField
...defaultGroupWithMembersSample
+ ...landscapeDataEntries
areaPolygon
}
}
@@ -156,7 +158,9 @@ export const fetchLandscapeToView = slug => {
}
`);
return terrasoApi
- .requestGraphQL(query, { slug })
+ .requestGraphQL(query, {
+ slug,
+ })
.then(_.get('landscapes.edges[0].node'))
.then(landscape => landscape || Promise.reject('not_found'))
.then(landscape => ({
@@ -170,6 +174,7 @@ export const fetchLandscapeToView = slug => {
: null,
partnershipStatus: ALL_PARTNERSHIP_STATUS[landscape.partnershipStatus],
partnership: extractPartnership(landscape),
+ dataEntries: extractDataEntries(landscape),
}))
.then(landscape => {
if (landscape.areaPolygon || !landscape.location) {
diff --git a/src/landscape/landscapeService.test.ts b/src/landscape/landscapeService.test.ts
index 692a4675e..e62cae446 100644
--- a/src/landscape/landscapeService.test.ts
+++ b/src/landscape/landscapeService.test.ts
@@ -43,6 +43,7 @@ test('LandscapeService: Fetch landscape with missing fields', async () => {
description: 'Landscape description',
website: 'https://www.landscape.org',
areaPolygon: null,
+ dataEntries: undefined,
defaultGroup: {
membersInfo: {
accountMembership: undefined,
diff --git a/src/landscape/landscapeSlice.js b/src/landscape/landscapeSlice.js
index f8450a958..8240d04c6 100644
--- a/src/landscape/landscapeSlice.js
+++ b/src/landscape/landscapeSlice.js
@@ -21,6 +21,7 @@ import * as membershipsUtils from 'terraso-client-shared/memberships/memberships
import { createAsyncThunk } from 'terraso-client-shared/store/utils';
import * as landscapeService from 'landscape/landscapeService';
+import { setList } from 'sharedData/sharedDataSlice';
const initialState = {
list: {
@@ -82,6 +83,7 @@ export const fetchLandscapeView = createAsyncThunk(
currentUser
);
dispatch(setMemberships(getMemberships([landscape])));
+ dispatch(setList(landscape.dataEntries));
return landscape;
}
);
diff --git a/src/permissions/rules.js b/src/permissions/rules.js
index fea53fc96..5e7ca0cb5 100644
--- a/src/permissions/rules.js
+++ b/src/permissions/rules.js
@@ -66,9 +66,10 @@ const isAllowedToDeleteSharedData = ({ resource, user }) => {
};
const isAllowedToDeleteVisualization = ({
- resource: { group, visualizationConfig },
+ resource: { owner, visualizationConfig },
user,
}) => {
+ const group = owner.defaultGroup || owner;
const isManager = hasRole({ group, role: ROLE_MANAGER });
const isOwner =
_.get('createdBy.id', visualizationConfig) === _.get('id', user);
diff --git a/src/sharedData/components/SharedDataCard.js b/src/sharedData/components/SharedDataCard.js
index 865db59f6..9161a3401 100644
--- a/src/sharedData/components/SharedDataCard.js
+++ b/src/sharedData/components/SharedDataCard.js
@@ -14,12 +14,11 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
-import React, { useCallback } from 'react';
+import React from 'react';
import _ from 'lodash/fp';
import { usePermission } from 'permissions';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
-import { useFetchData } from 'terraso-client-shared/store/utils';
import {
Button,
Card,
@@ -33,7 +32,6 @@ import {
import List from 'common/components/List';
import { ScrollTo } from 'navigation/scrollTo';
import { useGroupContext } from 'group/groupContext';
-import { fetchGroupSharedData } from 'sharedData/sharedDataSlice';
import SharedDataEntryFile from './SharedDataEntryFile';
import SharedDataEntryLink from './SharedDataEntryLink';
@@ -48,13 +46,6 @@ const SharedFilesCard = props => {
const { data: sharedFiles, fetching } = useSelector(_.get('sharedData.list'));
const hasFiles = !_.isEmpty(sharedFiles);
- useFetchData(
- useCallback(
- () => (allowed ? fetchGroupSharedData({ slug: group.slug }) : null),
- [group.slug, allowed]
- )
- );
-
if (!allowed) {
return null;
}
diff --git a/src/sharedData/components/SharedDataUpload/index.js b/src/sharedData/components/SharedDataUpload/index.js
index e98b74b64..94de342e7 100644
--- a/src/sharedData/components/SharedDataUpload/index.js
+++ b/src/sharedData/components/SharedDataUpload/index.js
@@ -51,7 +51,7 @@ const SharedDataUpload = props => {
const { trackEvent } = useAnalytics();
const { owner, entityType } = useGroupContext();
- const { groupSlug, onCancel, onCompleteSuccess } = props;
+ const { targetInput, onCancel, onCompleteSuccess } = props;
const [section, setSection] = useState('files');
@@ -103,10 +103,10 @@ const SharedDataUpload = props => {
const onSave = useCallback(() => {
setShowSummary(false);
const linksPromises = toUpload.links.map(link =>
- dispatch(addSharedDataLink({ groupSlug, link }))
+ dispatch(addSharedDataLink({ ...targetInput, link }))
);
const filesPromises = toUpload.files.map(file =>
- dispatch(uploadSharedDataFile({ groupSlug, file }))
+ dispatch(uploadSharedDataFile({ ...targetInput, file }))
);
const allPromises = [...filesPromises, ...linksPromises];
@@ -134,7 +134,7 @@ const SharedDataUpload = props => {
});
setShowSummary(true);
});
- }, [entityType, owner.slug, toUpload, groupSlug, dispatch, trackEvent]);
+ }, [entityType, owner.slug, toUpload, targetInput, dispatch, trackEvent]);
const hasBlockingErrors = useMemo(
() =>
diff --git a/src/sharedData/sharedDataService.js b/src/sharedData/sharedDataService.js
index 5de08bca0..a68f39c9e 100644
--- a/src/sharedData/sharedDataService.js
+++ b/src/sharedData/sharedDataService.js
@@ -18,18 +18,23 @@ import _ from 'lodash/fp';
import * as terrasoApi from 'terraso-client-shared/terrasoApi/api';
import { graphql } from 'terrasoApi/shared/graphqlSchema';
-import { extractDataEntry, extractGroupDataEntries } from 'group/groupUtils';
+import { extractDataEntry } from './sharedDataUtils';
import { SHARED_DATA_ACCEPTED_EXTENSIONS } from 'config';
const ALL_RESOURCE_TYPES = [...SHARED_DATA_ACCEPTED_EXTENSIONS, 'link'];
-export const uploadSharedDataFile = async ({ groupSlug, file }) => {
+export const uploadSharedDataFile = async ({
+ targetType,
+ targetSlug,
+ file,
+}) => {
const path = '/shared-data/upload/';
const body = new FormData();
const filename = `${file.name}${file.resourceType}`;
- body.append('groups', groupSlug);
+ body.append('target_type', targetType);
+ body.append('target_slug', targetSlug);
body.append('name', file.name);
if (file.description) {
body.append('description', file.description);
@@ -61,7 +66,7 @@ export const deleteSharedData = ({ dataEntry }) => {
});
};
-export const addSharedDataLink = ({ groupSlug, link }) => {
+export const addSharedDataLink = ({ targetType, targetSlug, link }) => {
const query = graphql(`
mutation addDataEntry($input: DataEntryAddMutationInput!) {
addDataEntry(input: $input) {
@@ -80,7 +85,8 @@ export const addSharedDataLink = ({ groupSlug, link }) => {
..._.pick(['name', 'url', 'description'], link),
entryType: 'link',
resourceType: 'link',
- groupSlug,
+ targetType,
+ targetSlug,
},
})
.then(_.get('addDataEntry.dataEntry'));
@@ -112,31 +118,45 @@ export const updateSharedData = ({ dataEntry }) => {
.then(extractDataEntry);
};
-export const fetchGroupSharedData = ({
- slug,
+export const fetchSharedData = ({
+ targetSlug,
+ targetType,
resourceTypes = ALL_RESOURCE_TYPES,
}) => {
const query = graphql(`
- query group($slug: String!, $resourceTypes: [String]!) {
- groups(slug: $slug) {
+ query dataEntries(
+ $slug: String!
+ $type: String!
+ $resourceTypes: [String]!
+ ) {
+ dataEntries(
+ sharedResources_Target_Slug: $slug
+ sharedResources_TargetContentType: $type
+ resourceType_In: $resourceTypes
+ ) {
edges {
node {
- ...dataEntries
+ ...dataEntry
+ ...dataEntryVisualizations
}
}
}
}
`);
return terrasoApi
- .requestGraphQL(query, { slug, resourceTypes })
- .then(_.get('groups.edges[0].node'))
- .then(group => group || Promise.reject('not_found'))
- .then(group => extractGroupDataEntries(group));
+ .requestGraphQL(query, {
+ slug: targetSlug,
+ type: targetType,
+ resourceTypes,
+ })
+ .then(_.get('dataEntries.edges'))
+ .then(edges => edges.map(edge => extractDataEntry(edge.node)));
};
export const addVisualizationConfig = ({
title,
- group,
+ ownerId,
+ ownerType,
selectedFile,
visualizationConfig,
}) => {
@@ -161,7 +181,8 @@ export const addVisualizationConfig = ({
title,
configuration,
dataEntryId: selectedFile.id,
- groupId: group.id,
+ ownerId,
+ ownerType,
},
})
.then(response => ({
@@ -185,11 +206,20 @@ export const deleteVisualizationConfig = config => {
});
};
-export const fetchVisualizationConfig = ({ groupSlug, configSlug }) => {
+export const fetchVisualizationConfig = ({
+ ownerSlug,
+ ownerType,
+ configSlug,
+}) => {
const query = graphql(`
- query fetchVisualizationConfig($groupSlug: String!, $configSlug: String!) {
+ query fetchVisualizationConfig(
+ $ownerSlug: String!
+ $ownerType: String!
+ $configSlug: String!
+ ) {
visualizationConfigs(
- dataEntry_Groups_Slug: $groupSlug
+ dataEntry_SharedResources_Target_Slug: $ownerSlug
+ dataEntry_SharedResources_TargetContentType: $ownerType
slug: $configSlug
) {
edges {
@@ -204,7 +234,7 @@ export const fetchVisualizationConfig = ({ groupSlug, configSlug }) => {
}
`);
return terrasoApi
- .requestGraphQL(query, { groupSlug, configSlug })
+ .requestGraphQL(query, { ownerSlug, ownerType, configSlug })
.then(_.get('visualizationConfigs.edges[0].node'))
.then(
visualizationConfig => visualizationConfig || Promise.reject('not_found')
diff --git a/src/sharedData/sharedDataSlice.js b/src/sharedData/sharedDataSlice.js
index 3c1870146..3f697702d 100644
--- a/src/sharedData/sharedDataSlice.js
+++ b/src/sharedData/sharedDataSlice.js
@@ -74,9 +74,9 @@ export const updateSharedData = createAsyncThunk(
params: { name: dataEntry.name },
})
);
-export const fetchGroupSharedData = createAsyncThunk(
- 'sharedData/fetchGroupSharedData',
- sharedDataService.fetchGroupSharedData
+export const fetchSharedData = createAsyncThunk(
+ 'sharedData/fetchSharedData',
+ sharedDataService.fetchSharedData
);
export const addVisualizationConfig = createAsyncThunk(
@@ -124,6 +124,13 @@ const sharedDataSlice = createSlice({
...state,
processing: _.omit(action.payload, state.processing),
}),
+ setList: (state, action) => ({
+ ...state,
+ list: {
+ data: action.payload,
+ fetching: false,
+ },
+ }),
},
extraReducers: builder => {
@@ -219,7 +226,7 @@ const sharedDataSlice = createSlice({
)
);
- builder.addCase(fetchGroupSharedData.pending, (state, action) => ({
+ builder.addCase(fetchSharedData.pending, (state, action) => ({
...state,
list: {
fetching: true,
@@ -227,7 +234,7 @@ const sharedDataSlice = createSlice({
},
}));
- builder.addCase(fetchGroupSharedData.fulfilled, (state, action) => ({
+ builder.addCase(fetchSharedData.fulfilled, (state, action) => ({
...state,
list: {
fetching: false,
@@ -278,6 +285,7 @@ const sharedDataSlice = createSlice({
},
});
-export const { resetUploads, resetProcessing } = sharedDataSlice.actions;
+export const { resetUploads, resetProcessing, setList } =
+ sharedDataSlice.actions;
export default sharedDataSlice.reducer;
diff --git a/src/group/groupUtils.ts b/src/sharedData/sharedDataUtils.js
similarity index 61%
rename from src/group/groupUtils.ts
rename to src/sharedData/sharedDataUtils.js
index d533b627a..0cd316907 100644
--- a/src/group/groupUtils.ts
+++ b/src/sharedData/sharedDataUtils.js
@@ -14,18 +14,13 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
-import {
- DataEntriesFragment,
- DataEntryFragment,
- DataEntryVisualizationsFragment,
-} from 'terrasoApi/shared/graphqlSchema/graphql';
-export const extractDataEntry = (
- dataEntry: DataEntryFragment & DataEntryVisualizationsFragment
-) => ({
+export const extractDataEntry = dataEntry => ({
...dataEntry,
- visualizations: dataEntry.visualizations?.edges?.map(edge => edge.node),
+ visualizations: dataEntry?.visualizations?.edges?.map(edge => edge.node),
});
-export const extractGroupDataEntries = (group: DataEntriesFragment) =>
- group.dataEntries.edges.map(edge => extractDataEntry(edge.node));
+export const extractDataEntries = parent =>
+ parent.sharedResources?.edges
+ .map(edge => edge.node.source)
+ .map(dataEntry => extractDataEntry(dataEntry));
diff --git a/src/sharedData/visualization/components/VisualizationConfigForm/PreviewStep.js b/src/sharedData/visualization/components/VisualizationConfigForm/PreviewStep.js
index a7415f963..3e5fa35cf 100644
--- a/src/sharedData/visualization/components/VisualizationConfigForm/PreviewStep.js
+++ b/src/sharedData/visualization/components/VisualizationConfigForm/PreviewStep.js
@@ -44,7 +44,7 @@ const PreviewStep = props => {
const [viewportConfig, setViewportConfig] = useState(
visualizationConfig.viewportConfig
);
- const { owner, entityTypeLocalized, group } = useGroupContext();
+ const { owner, entityTypeLocalized, entityType } = useGroupContext();
useEffect(() => {
setViewportConfig(visualizationConfig.viewportConfig);
@@ -88,7 +88,8 @@ const PreviewStep = props => {
title: _.get('annotateConfig.mapTitle', completeConfig),
visualizationConfig: filteredConfig,
selectedFile,
- group,
+ ownerId: owner.id,
+ ownerType: entityType,
})
).then(data => {
const success = _.get('meta.requestStatus', data) === 'fulfilled';
@@ -106,9 +107,10 @@ const PreviewStep = props => {
});
}, [
dispatch,
- group,
onSaved,
owner.name,
+ owner.id,
+ entityType,
selectedFile,
trackEvent,
viewportConfig,
diff --git a/src/sharedData/visualization/components/VisualizationConfigForm/SelectDataFileStep.js b/src/sharedData/visualization/components/VisualizationConfigForm/SelectDataFileStep.js
index e49bfe7d2..0de9732a6 100644
--- a/src/sharedData/visualization/components/VisualizationConfigForm/SelectDataFileStep.js
+++ b/src/sharedData/visualization/components/VisualizationConfigForm/SelectDataFileStep.js
@@ -36,7 +36,7 @@ import PageLoader from 'layout/PageLoader';
import { formatDate } from 'localization/utils';
import { useGroupContext } from 'group/groupContext';
import SharedFileIcon from 'sharedData/components/SharedFileIcon';
-import { fetchGroupSharedData } from 'sharedData/sharedDataSlice';
+import { fetchSharedData } from 'sharedData/sharedDataSlice';
import { useVisualizationContext } from 'sharedData/visualization/visualizationContext';
const ACCEPTED_RESOURCE_TYPES = ['csv', 'xls', 'xlsx'];
@@ -50,7 +50,7 @@ const SelectDataFileStep = props => {
const { i18n, t } = useTranslation();
const { visualizationConfig } = useVisualizationContext();
const { onNext, onBack } = props;
- const { group } = useGroupContext();
+ const { owner, entityType } = useGroupContext();
const { data: sharedFiles, fetching } = useSelector(_.get('sharedData.list'));
const [selected, setSelected] = useState();
@@ -62,12 +62,13 @@ const SelectDataFileStep = props => {
useEffect(() => {
dispatch(
- fetchGroupSharedData({
- slug: group.slug,
+ fetchSharedData({
+ targetSlug: owner.slug,
+ targetType: entityType,
resourceTypes: ACCEPTED_RESOURCE_TYPES,
})
);
- }, [dispatch, group.slug]);
+ }, [dispatch, owner.slug, entityType]);
// If there are no files to map, go back to the landscape/group index page.
useEffect(() => {
diff --git a/src/sharedData/visualization/components/VisualizationWrapper.js b/src/sharedData/visualization/components/VisualizationWrapper.js
index 1971787c9..05ad6f619 100644
--- a/src/sharedData/visualization/components/VisualizationWrapper.js
+++ b/src/sharedData/visualization/components/VisualizationWrapper.js
@@ -60,16 +60,22 @@ const VisualizationWrapper = props => {
const dispatch = useDispatch();
const { i18n, t } = useTranslation();
const { downloadFile } = useSharedData();
- const { groupSlug, configSlug, onDeleted } = props;
+ const { configSlug, onDeleted } = props;
const { data, fetching, deleting } = useSelector(
state => state.sharedData.visualizationConfig
);
- const { group, owner, entityType } = useGroupContext();
+ const { owner, entityType } = useGroupContext();
const [imagePrinter, setImagePrinter] = useState();
useEffect(() => {
- dispatch(fetchVisualizationConfig({ groupSlug, configSlug }));
- }, [dispatch, groupSlug, configSlug]);
+ dispatch(
+ fetchVisualizationConfig({
+ ownerSlug: owner.slug,
+ ownerType: entityType,
+ configSlug,
+ })
+ );
+ }, [dispatch, owner.slug, entityType, configSlug]);
const visualizationConfig = useMemo(
() =>
@@ -133,7 +139,7 @@ const VisualizationWrapper = props => {