+ + fetchManageData()}> + {(data) => } + +
fetchRecentItems()}> {(data) => } diff --git a/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/ManageData.test.tsx b/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/ManageData.test.tsx new file mode 100644 index 0000000000..7ec4e2fa9d --- /dev/null +++ b/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/ManageData.test.tsx @@ -0,0 +1,95 @@ +import { render } from '@testing-library/react'; + +import { ManagedDataResponse } from '../../../../types'; +import ManagedData from '.'; + +describe('RecentCollections', () => { + const managed_data_stats_multiple_datasets: ManagedDataResponse = { + count: 5, + managed_data_url: '/datasets?q=' + }; + + const managed_data_stats_single_dataset: ManagedDataResponse = { + count: 1, + managed_data_url: '/datasets?q=' + }; + + const managed_data_stats_no_dataset: ManagedDataResponse = { + count: 0, + managed_data_url: '/datasets?q=' + }; + + describe('With results', () => { + it('should render a title', () => { + const { getByRole } = render( + + ); + expect( + getByRole('heading', { + level: 2, + // eslint-disable-next-line quotes + name: "You're the owner or manager of 5 datasets" + }) + ); + }); + it('should render a title in the singular', () => { + const { getByRole } = render( + + ); + expect( + getByRole('heading', { + level: 2, + // eslint-disable-next-line quotes + name: "You're the owner or manager of 1 dataset" + }) + ); + }); + it('should not render at all', () => { + const { queryByRole } = render( + + ); + expect( + queryByRole('heading', { + level: 2, + // eslint-disable-next-line quotes + name: "You're the owner or manager of 0 dataset" + }) + ).not.toBeInTheDocument(); + }); + it('should render a link to the manage data page', () => { + const { getByRole } = render( + + ); + expect( + getByRole('link', { name: 'View and manage your data' }) + ).toHaveAttribute('href', '/datasets?q='); + }); + it('should render a link to helpcentre guidance', () => { + const { getByRole } = render( + + ); + expect( + getByRole('link', { + // eslint-disable-next-line quotes + name: "Learn how to maintain and manage data you're responsible for on Data Workspace" + }) + ).toHaveAttribute( + 'href', + 'https://data-services-help.trade.gov.uk/data-workspace/how-to/data-owner-basics/managing-data-key-tasks-and-responsibilities' + ); + }); + it('should not render a link to helpcentre guidance', () => { + const { queryByRole } = render( + + ); + expect( + queryByRole('link', { + // eslint-disable-next-line quotes + name: "Learn how to maintain and manage data you're responsible for on Data Workspace" + }) + ).not.toBeInTheDocument(); + }); + }); +}); diff --git a/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/ManagedData.stories.tsx b/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/ManagedData.stories.tsx new file mode 100644 index 0000000000..ab96f4b223 --- /dev/null +++ b/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/ManagedData.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import type { ManagedDataProps } from '.'; +import ManagedData from '.'; + +const MultipleDatasets: ManagedDataProps = { + count: 5, + managed_data_url: '/datasets?q=' +}; + +const SingularDataset: ManagedDataProps = { + count: 1, + managed_data_url: '/datasets?q=' +}; + +const NoDatasets: ManagedDataProps = { + count: 0, + managed_data_url: '/datasets?q=' +}; + +const meta = { + title: 'Managed Data', + component: ManagedData +} satisfies Meta; + +type Story = StoryObj; + +export const withMultipleDatasets: Story = { + render: () => +}; + +export const withSingleDatasets: Story = { + render: () => +}; + +export const noDatasets: Story = { + render: () => +}; + +export default meta; diff --git a/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/index.tsx b/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/index.tsx new file mode 100644 index 0000000000..e063dcf19e --- /dev/null +++ b/dataworkspace/dataworkspace/static/js/react/features/home-page/components/ManageData/index.tsx @@ -0,0 +1,47 @@ +import React from 'react'; + +import { typography } from '@govuk-react/lib'; +import Link from '@govuk-react/link'; +import { SectionBreak } from 'govuk-react'; +import styled from 'styled-components'; + +import { Tile } from '../../../../components'; + +export type ManagedDataProps = { + count: number; + managed_data_url: string; +}; + +const StyledParagraph = styled('p')` + ${typography.font({ size: 16 })}; + margin: 0; +`; + +const ManagedData: React.FC> = ({ + managed_data_stats +}) => ( + <> + {managed_data_stats?.count > 0 && ( + 1 ? 's' : ''}`} + > + + View and manage your data + + + + Keeping your data up-to-date helps improve the quality of our data + catalogue.{' '} + + Learn how to maintain and manage data you're responsible for on Data + Workspace + + + + )} + +); + +export default ManagedData; diff --git a/dataworkspace/dataworkspace/static/js/react/services/index.ts b/dataworkspace/dataworkspace/static/js/react/services/index.ts index d1864ce07b..aba46ec717 100644 --- a/dataworkspace/dataworkspace/static/js/react/services/index.ts +++ b/dataworkspace/dataworkspace/static/js/react/services/index.ts @@ -1,6 +1,7 @@ import { API_BASE_URL } from '../constants'; import { transformDataUsageResponse, + transformManageDataResponse, transformRecentCollectionsResponse, transformRecentItemsResponse, transformRecentToolsResponse, @@ -9,6 +10,7 @@ import { import { type DataType, type DataUsageResponse, + type ManagedDataResponse, type TransformedDataUsageResponse, type TransformedYourBookmarksResponse, type TransformedYourRecentCollectionResponse, @@ -44,6 +46,13 @@ export const fetchDataUsage = async (dataType: DataType, id: string) => { ); }; +export const fetchManageData = async () => { + return handleResponse( + `/${API_BASE_URL}/managed_data/stats/`, + transformManageDataResponse + ); +}; + export const fetchRecentCollections = async () => { return handleResponse< YourRecentCollectionResponse, diff --git a/dataworkspace/dataworkspace/static/js/react/transformers.ts b/dataworkspace/dataworkspace/static/js/react/transformers.ts index 717de65a7e..8564db54bc 100644 --- a/dataworkspace/dataworkspace/static/js/react/transformers.ts +++ b/dataworkspace/dataworkspace/static/js/react/transformers.ts @@ -2,6 +2,7 @@ import { DATA_USAGE_KEYS } from './constants'; import type { DataUsageKeys, DataUsageResponse, + ManagedDataResponse, TransformedDataUsageResponse, TransformedYourBookmarksResponse, TransformedYourRecentCollectionResponse, @@ -21,6 +22,12 @@ export const transformDataUsageResponse = ( value: Math.round(response[key as keyof unknown] * 1000) / 1000 })); +export const transformManageDataResponse = ( + response: ManagedDataResponse +): ManagedDataResponse => { + return { count: response.count, managed_data_url: response.managed_data_url }; +}; + export const transformRecentCollectionsResponse = ( response: YourRecentCollectionResponse ): TransformedYourRecentCollectionResponse => diff --git a/dataworkspace/dataworkspace/static/js/react/types/index.d.ts b/dataworkspace/dataworkspace/static/js/react/types/index.d.ts index 2a9bcfb30a..4bab61970f 100644 --- a/dataworkspace/dataworkspace/static/js/react/types/index.d.ts +++ b/dataworkspace/dataworkspace/static/js/react/types/index.d.ts @@ -23,6 +23,11 @@ export type TransformedDataUsageResponse = { value: number; }[]; +export type ManagedDataResponse = { + count: number; + managed_data_url: string; +}; + export type YourRecentCollectionResponse = { results: { name: string;