Skip to content
Merged
Show file tree
Hide file tree
Changes from 106 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
ab502a2
Add route to moderation queue
mazursasha1990 Oct 11, 2024
8235d29
Add route to moderation queue
mazursasha1990 Oct 11, 2024
af8bbb6
Add filters components for moderation queue page
mazursasha1990 Oct 11, 2024
b384e66
Add actions for record type options
mazursasha1990 Oct 14, 2024
4c7f799
Add reducers for record type options
mazursasha1990 Oct 14, 2024
ecc286d
Use fetchRecordTypes and fetchCountries in the DashboardModerationQue…
mazursasha1990 Oct 14, 2024
1141614
Use recordTypesOptions from the state
mazursasha1990 Oct 14, 2024
b978501
Add actions for fetching match status options options
mazursasha1990 Oct 15, 2024
0f56d47
Add reducers for match status options options
mazursasha1990 Oct 15, 2024
aed78ac
Use fetchMatchStatusOptions in the DashboardModerationQueue component
mazursasha1990 Oct 15, 2024
8105f02
Use matchStatusesOptions from the state
mazursasha1990 Oct 15, 2024
42e502b
Use options for moderation queue filters from constant values
mazursasha1990 Oct 18, 2024
ac86145
Remove actions and reducers for the moderation queue filters
mazursasha1990 Oct 18, 2024
9c129ab
Revert changes in filterOptions.js
mazursasha1990 Oct 18, 2024
221e46c
Add DashboardModerationQueueReducer
mazursasha1990 Oct 18, 2024
43819a4
Add actions for the moderation queue
mazursasha1990 Oct 18, 2024
4e7b318
Add moderationEventsPropType
mazursasha1990 Oct 18, 2024
99d34f7
Correct moderationEventsPropType
mazursasha1990 Oct 18, 2024
b4cca62
Change name import CLAIM_DECISION_EMPTY to EMPTY_PLACEHOLDER
mazursasha1990 Oct 18, 2024
649278f
Add className prop to the moderation queue page filters
mazursasha1990 Oct 18, 2024
b3c1ddb
Change value in the RECORD_TYPES_OPTIONS
mazursasha1990 Oct 18, 2024
83f3995
Add width for the DownloadFacilityClaimsButton
mazursasha1990 Oct 18, 2024
7670d7b
Introduce DatePicker component
mazursasha1990 Oct 21, 2024
4b3503b
Introduce DownloadExcelButton component
mazursasha1990 Oct 22, 2024
ce7de07
Add actions for downloading moderation events
mazursasha1990 Oct 22, 2024
362ed95
Add util functions used by actions for downloading moderation events
mazursasha1990 Oct 22, 2024
f831dae
Add reducers for downloading moderation events
mazursasha1990 Oct 22, 2024
b249c7e
Make DashboardDownloadDataButton as reusable
mazursasha1990 Oct 22, 2024
10a1cbc
Use DashboardDownloadDataButton in the DashboardClaims component inst…
mazursasha1990 Oct 22, 2024
5c2836b
Addapt filters to updated specifications
mazursasha1990 Oct 22, 2024
01185d0
Modify mocked data acording to the updated specifications
mazursasha1990 Oct 22, 2024
b55c867
Remove DownloadFacilityClaimsButton.jsx as redundant
mazursasha1990 Oct 22, 2024
c1575b1
Add default prop type for filter options
mazursasha1990 Oct 22, 2024
7ec2320
Add reducers for sourceTypes and moderationStatuses filter values
mazursasha1990 Oct 22, 2024
a6fb212
Refactor SourceTypeFilter
mazursasha1990 Oct 22, 2024
d90e78e
Refactor ModerationStatusFilter
mazursasha1990 Oct 22, 2024
2475d4a
Add defaultProps for the downloadError value in the DashboardDownload…
mazursasha1990 Oct 22, 2024
5ac81bf
Add updateSourceTypeFilter and updateModerationStatusFilter actions
mazursasha1990 Oct 22, 2024
a7d96a9
Organize colors based on their general color family
mazursasha1990 Oct 23, 2024
1e8eeac
Add createOptionsFromConstants function to the util.js
mazursasha1990 Oct 23, 2024
94fe475
Modify creation of options for the SourceType and ModerationStatus f…
mazursasha1990 Oct 23, 2024
1914a99
Add dinamic value for the background color of the selected value
mazursasha1990 Oct 23, 2024
2ba44f8
Refactor main components
mazursasha1990 Oct 23, 2024
6022be9
Add ROWS_PER_PAGE_OPTIONS and DEFAULT_ROWS_PER_PAGE constants to esca…
mazursasha1990 Oct 23, 2024
61060cf
Merge branch 'main' into OSDEV-1120-create-new-moderation-queue-page
mazursasha1990 Oct 23, 2024
2261ed3
Refactor DashboardModerationQueueListTableHeader component
mazursasha1990 Oct 23, 2024
cda55cb
Refactor DashboardModerationQueueListTable component
mazursasha1990 Oct 23, 2024
65fdeeb
Refactor DashboardModerationQueue component
mazursasha1990 Oct 23, 2024
982be9d
Add tests for the DashboardDownloadDataButton component
mazursasha1990 Oct 24, 2024
bfeffd4
Add tests for the DashboardDownloadDataButton component
mazursasha1990 Oct 24, 2024
907ea26
Add tests for the DatePicker component
mazursasha1990 Oct 25, 2024
bd10501
Modify formatDate util function
mazursasha1990 Oct 25, 2024
4af82da
Add tests for the DashboardModerationQueueListTable component
mazursasha1990 Oct 25, 2024
436368a
Add tests for the DashboardModerationQueueListTableHeader component
mazursasha1990 Oct 25, 2024
ed92d86
Fix linter error
mazursasha1990 Oct 25, 2024
394ac20
Fix error in tests
mazursasha1990 Oct 25, 2024
7264882
Fix sonar duplicated lines error
mazursasha1990 Oct 25, 2024
0386537
Fix sonar duplicated lines error
mazursasha1990 Oct 25, 2024
92d6676
Fix sonar duplicated lines error
mazursasha1990 Oct 25, 2024
d61a592
Merge branch 'main' into OSDEV-1120-create-new-moderation-queue-page
mazursasha1990 Oct 25, 2024
7d213cc
Fix linter error
mazursasha1990 Oct 25, 2024
6de9c36
Fix test for the DownloadExcelButton component
mazursasha1990 Oct 25, 2024
eaee0b4
Fix linter error
mazursasha1990 Oct 25, 2024
5a68fb6
Remove link to Moderation Queue from the Dashboard
mazursasha1990 Oct 25, 2024
799df0f
Use formatDate util function in the DashboardModerationQueueListTable…
mazursasha1990 Oct 28, 2024
bf669ae
Add release notes
mazursasha1990 Oct 28, 2024
8b28c22
Use formatDate util function in the formatFacilityClaimsDataForXLSX a…
mazursasha1990 Oct 28, 2024
4c65786
Add TODO comment to the dashboardModerationQueue.js
mazursasha1990 Oct 28, 2024
852e994
Added prop types for the moderationStatuses and sourceTypes
mazursasha1990 Oct 28, 2024
5305ea1
Restrict the order prop to specific values in the DashboardModeration…
mazursasha1990 Oct 28, 2024
8208b71
Modify test for the DashboardModerationQueueListTable component
mazursasha1990 Oct 29, 2024
7f4c3a7
Rename downloadError to downloadClaimsError in the DashboardClaims co…
mazursasha1990 Oct 29, 2024
c7fe2cb
Rename downloadError to downloadEventsError in the DashboardModeratio…
mazursasha1990 Oct 29, 2024
cbc7053
Change prop types for error and downloadEventsError to string
mazursasha1990 Oct 29, 2024
44d9fe1
Change default prop type for events to empty array
mazursasha1990 Oct 29, 2024
b2a9eaa
Add aria-label to the TableSortLabel
mazursasha1990 Oct 29, 2024
78a09ba
Fix warning about missing prop validation for handleDownload in the D…
mazursasha1990 Oct 29, 2024
8b7e2cd
Update release notes
mazursasha1990 Oct 29, 2024
10fec52
Merge branch 'main' into OSDEV-1120-create-new-moderation-queue-page
mazursasha1990 Oct 29, 2024
7ac79a5
Fix warning about missing prop validation for handleDownload in the D…
mazursasha1990 Oct 29, 2024
c1e4f1f
Create DATE_FORMATS constant and use it in the changed files
mazursasha1990 Oct 29, 2024
69855cf
Remove unused import of 'func' in the DashboardDownloadDataButton.tes…
mazursasha1990 Oct 29, 2024
2b614e9
Fix linter error
mazursasha1990 Oct 29, 2024
82b8192
Add kunk to the ticket in the TODO comment
mazursasha1990 Oct 29, 2024
0b2ee75
Add date validation to prevent invalid ranges
mazursasha1990 Oct 29, 2024
525fa63
Merge branch 'main' into OSDEV-1120-create-new-moderation-queue-page
mazursasha1990 Oct 29, 2024
c22616e
added screen with dummy data
Nov 1, 2024
ed14fed
code refactoring, added actions and reducer
Nov 5, 2024
2e398f3
merged main
Nov 5, 2024
ab245e8
added react tests, passed moderation id from params to method
Nov 6, 2024
141772e
added task description
Nov 7, 2024
eb7a996
Merge branch 'main' into OSDEV-1116-implement-contribution-record-page
Nov 7, 2024
e5ce87d
removed routing with flag
Nov 7, 2024
237a285
commented routing
Nov 7, 2024
ea5e6e9
removed unneseccary comment
Nov 7, 2024
1d8047a
aded changes for coderabbit comments
Nov 8, 2024
247a5a2
changes according comments
Nov 8, 2024
0046606
added Object.freeze for styles, added butto attr for row and changed…
Nov 8, 2024
2aa5763
fixed tests
Nov 8, 2024
a54c11b
replaced colors with const vars
Nov 9, 2024
ef71a57
changed moderation id, fixed propTypes
Nov 11, 2024
bc3f471
changed mod event prop type
Nov 11, 2024
5ec2510
fixed structure of List component
Nov 11, 2024
bd5e551
added NOSONAR justification for ignoring specific code
Nov 11, 2024
464f282
changed mocked data
Nov 11, 2024
60f4429
renamed vars similar to Moderation Queue, changed mock data to avoid …
Nov 11, 2024
b020d50
revert changes in Olek file
Nov 11, 2024
2e1aa5b
Update .editorconfig
Innavin369 Nov 11, 2024
efbb55e
reverted changes in test file
Nov 12, 2024
ad54324
added tests for avaliable data, fixes
Nov 12, 2024
7bc8773
Merge branch 'main' into OSDEV-1116-implement-contribution-record-page
Nov 12, 2024
483e00c
fixed linter
Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
* [OSDEV-1335](https://opensupplyhub.atlassian.net/browse/OSDEV-1335) - Fixed the assertion in the test for the `country.rb` filter of the "production locations" Logstash pipeline. The main issue was with the evaluation of statements in the Ruby block. Since only the last statement is evaluated in a Ruby block, all the checks were grouped into one chain of logical statements and returned as a `result` variable at the end.

### What's new
* [OSDEV-1116](https://opensupplyhub.atlassian.net/browse/OSDEV-1116) - A new Contribution Record Page has been developed to enable quick identification and moderation of contributions. This page includes two main sections: Moderation Event Data and Potential Matches, along with a set of buttons designed to facilitate the moderation process.
* [OSDEV-1120](https://opensupplyhub.atlassian.net/browse/OSDEV-1120) - A new Moderation Queue Dashboard page has been introduced, featuring three essential components:
* Moderation Events Table: Allows users to view and manage moderation events more effectively.
* Filtering Options: Multiple filter fields enable users to customize the displayed events based on different criteria, making it easier to find specific events.
Expand Down
163 changes: 163 additions & 0 deletions src/react/src/__tests__/components/DashboardContributionRecord.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React from 'react';
import DashboardContributionRecord from '../../components/Dashboard/DashboardContributionRecord';
import renderWithProviders from '../../util/testUtils/renderWithProviders';
import { waitFor } from '@testing-library/react';

describe('DashboardContributionRecord component', () => {
const routeProps = {
match: {
params: {
moderationID: '1',
},
},
};
const defaultProps = {
event: {},
potentialMatches: [],
fetchEventError: null,
fetchPotentialMatchError: null,
};

const renderComponent = (props = {}) => renderWithProviders(
<DashboardContributionRecord {...defaultProps} {...routeProps} {...props}/>
);

beforeEach(() => {
jest.clearAllMocks();
});

test('should render the CreateButton', () => {
const {getByText} = renderComponent();

expect(getByText('Create New Location')).toBeInTheDocument();
});

test('should render the RejectButton', () => {
const {getByText} = renderComponent();

expect(getByText('Reject Contribution')).toBeInTheDocument();
});

test('should render the ClaimButton', () => {
const {getByText} = renderComponent();

expect(getByText('Go to Claim')).toBeInTheDocument();
});

test('should disable button when eventFetching is true', () => {
const {getByRole} = renderComponent({ eventFetching: true });
const createButton = getByRole('button', { name: /Create New Location/i });
const rejectButton = getByRole('button', { name: /Reject Contribution/i });
const claimButton = getByRole('button', { name: /Go to Claim/i });

expect(createButton).toBeDisabled();
expect(rejectButton).toBeDisabled();
expect(claimButton).toBeDisabled();
});

test('should enable button when fetching is false', async () => {
const {getByRole} = renderComponent({eventFetching: false});
const createButton = getByRole('button', { name: /Create New Location/i });
const rejectButton = getByRole('button', { name: /Reject Contribution/i });
const claimButton = getByRole('button', { name: /Go to Claim/i });

await waitFor(() => {
expect(createButton).not.toBeDisabled();
expect(rejectButton).not.toBeDisabled();
expect(claimButton).not.toBeDisabled();
});

});

test('renders the "No potential matches found" block if no potential matches', () => {
const {getByText} = renderComponent();

expect(getByText('No potential matches found')).toBeInTheDocument();
});

test('renders the loading spinner', () => {
const {getByRole} = renderComponent({ eventFetching: true });

expect(getByRole('progressbar')).toBeInTheDocument();
});

test('should render event data when provided', async () => {
const event = {
moderation_id: 14,
created_at: '2024-11-17T11:33:20.287Z',
updated_at: '2024-12-18T21:30:20.187Z',
os_id: 'CN2021250D1DTU7',
cleaned_data: {
name: 'Eco Friendly Plastics Test',
address: '764 Main St, Manhattan, NY - USA',
country: {
name: 'Germany',
alpha_2: 'DE',
alpha_3: 'DEU',
numeric: '286',
},
},
contributor_id: 0,
contributor_name: 'Green Solutions Corp Test',
request_type: 'CREATE',
source: 'API',
moderation_status: 'PENDING',
moderation_decision_date: null,
claim_id: 0,
};
const { container } = renderComponent({ event });

await waitFor(() => {
const preElement = container.querySelector("pre");
expect(preElement).toBeInTheDocument();
});
});


test('should render potential matches when available', async () => {
const potentialMatches = [
{
os_id: 'CN2031250H1DTN7',
name: 'Test name INC Test',
address: '495 Main St, Manhattan, NY - US',
sector: ['Apparel'],
parent_company: 'ASI GLOBAL LIMITED',
product_type: ['Accessories'],
location_type: [],
processing_type: ['Final Product Assembly'],
number_of_workers: {
min: 0,
max: 0,
},
coordinates: {
lat: 0,
lng: 0,
},
local_name: '',
description: '',
business_url: '',
minimum_order_quantity: '',
average_lead_time: '',
percent_female_workers: 0,
affiliations: [],
certifications_standards_regulations: [],
historical_os_id: [],
country: {
name: 'Germany',
alpha_2: 'DE',
alpha_3: 'DEU',
numeric: '276',
},
claim_status: 'unclaimed',
},
];
const {getByText}= renderComponent({potentialMatches});

await waitFor(() => {
expect(getByText('Name: Test name INC NEW')).toBeInTheDocument();
expect(getByText('Address: 1523 Main St, Manhattan, NY - USA')).toBeInTheDocument();
expect(getByText('Claimed Status: unclaimed')).toBeInTheDocument();
expect(getByText('Potential Matches (1)')).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ describe('DashboardModerationQueueListTable component', () => {
source: 'API',
},
];

const paginatedModerationEvents = [
...sampleModerationEvents,
{
Expand Down Expand Up @@ -150,7 +149,7 @@ describe('DashboardModerationQueueListTable component', () => {

expect(getByText(/1-5 of 6/)).toBeInTheDocument();
expect(getByText(/rows per page/i)).toBeInTheDocument();

fireEvent.click(getByText('5'));
fireEvent.click(getByText('10'));
expect(getByText(/1-6 of 6/)).toBeInTheDocument();
Expand All @@ -172,4 +171,4 @@ describe('DashboardModerationQueueListTable component', () => {
const { getByText } = renderComponent({ events: [] });
expect(getByText(/0-0 of 0/)).toBeInTheDocument();
});
});
});
132 changes: 132 additions & 0 deletions src/react/src/actions/dashboardContributionRecord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { createAction } from 'redux-act';
import { logErrorAndDispatchFailure } from '../util/util';

export const startFetchingSingleModerationEvent = createAction(
'START_FETCHING_SINGLE_MODERATION_EVENT',
);
export const failFetchingSingleModerationEvent = createAction(
'FAIL_FETCHING_SINGLE_MODERATION_EVENT',
);
export const completeFetchingSingleModerationEvent = createAction(
'COMPLETE_FETCHING_SINGLE_MODERATION_EVENT',
);
export const startFetchingPotentialMatches = createAction(
'START_FETCHING_POTENTIAL_MATCHES',
);
export const failFetchingPotentialMatches = createAction(
'FAIL_FETCHING_POTENTIAL_MATCHES',
);
export const completeFetchingPotentialMatches = createAction(
'COMPLETE_FETCHING_POTENTIAL_MATCHES',
);
export const cleanupContributionRecord = createAction(
'CLEANUP_CONTRIBUTION_RECORD',
);

// TODO: Remove mock data and replace with actual API call as part of https://opensupplyhub.atlassian.net/browse/OSDEV-1347
const eventMockData = {
moderation_id: 12,
created_at: '2024-06-13T15:30:20.287Z',
updated_at: '2024-09-20T11:35:20.287Z',
os_id: 'FN2071250D1DTN7',
cleaned_data: {
name: 'Eco Test Friendly Plastics',
address: '4999 Main St, Manhattan, NY - USA',
country: {
name: 'Germany',
alpha_2: 'DE',
alpha_3: 'DEU',
numeric: '276',
},
},
contributor_id: 0,
contributor_name: 'Green Test Solutions Corp',
request_type: 'CREATE',
source: 'API',
moderation_status: 'PENDING',
moderation_decision_date: null,
claim_id: 0,
};
// TODO: Remove mock data and replace with actual API call as part of /v1/production-locations endpoint
const potentialMatchesMockData = [
{
os_id: 'CY2021280D1DTN7',
name: 'Test name INC NEW',
address: '1523 Main St, Manhattan, NY - USA',
sector: ['Apparel'],
parent_company: 'ASI TEST GLOBAL LIMITED',
product_type: ['Accessories'],
location_type: [],
processing_type: ['Product Assembly'],
number_of_workers: {
min: 0,
max: 0,
},
coordinates: {
lat: 0,
lng: 0,
},
local_name: '',
description: '',
business_url: '',
minimum_order_quantity: '',
average_lead_time: '',
percent_female_workers: 0,
affiliations: [],
certifications_standards_regulations: [],
historical_os_id: [],
country: {
name: 'Germany',
alpha_2: 'DE',
alpha_3: 'DEU',
numeric: '276',
},
claim_status: 'unclaimed',
},
];

// eslint-disable-next-line no-unused-vars
export function fetchSingleModerationEvent(moderationID) {
return async dispatch => {
dispatch(startFetchingSingleModerationEvent());
// TODO: Replace the mock implementation with an actual API call as part of https://opensupplyhub.atlassian.net/browse/OSDEV-1347
return new Promise(resolve => {
setTimeout(() => resolve({ data: eventMockData }), 1000);
})
.then(({ data }) =>
dispatch(completeFetchingSingleModerationEvent(data)),
)
.catch(err =>
dispatch(
logErrorAndDispatchFailure(
err,
'An error prevented fetching moderation event',
failFetchingSingleModerationEvent,
),
),
);
};
}

export function fetchPotentialMatches() {
return async dispatch => {
dispatch(startFetchingPotentialMatches());

// TODO: Replace the mock implementation with an actual API call as part of /v1/production-locations endpoint
return new Promise(resolve => {
setTimeout(() => resolve({ data: potentialMatchesMockData }), 1000);
})
.then(({ data }) =>
dispatch(completeFetchingPotentialMatches(data)),
)
.catch(err =>
dispatch(
logErrorAndDispatchFailure(
err,
'An error prevented fetching potential matches',
failFetchingPotentialMatches,
),
),
);
};
}
15 changes: 15 additions & 0 deletions src/react/src/components/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import DashboardApiBlock from './DashboardApiBlock';
import DashboardLinkToOsId from './DashboardLinkToOsId';
import DashboardGeocoder from './DashboardGeocoder';
import DashboardModerationQueue from './Dashboard/DashboardModerationQueue';
import DashboardContributionRecord from './Dashboard/DashboardContributionRecord';
import FeatureFlag from './FeatureFlag';
import RouteNotFound from './RouteNotFound';

Expand All @@ -38,6 +39,7 @@ import {
dashboardGeocoderRoute,
dashboardLinkOsIdRoute,
dashboardModerationQueueRoute,
dashboardContributionRecordRoute,
} from '../util/constants';

import AppGrid from './AppGrid';
Expand Down Expand Up @@ -95,6 +97,7 @@ function Dashboard({ userWithAccessHasSignedIn, fetchingSessionSignIn }) {
</FeatureFlag>
<Link to={dashboardDeleteFacilityRoute}>Delete a Facility</Link>
<Link to={dashboardMergeFacilitiesRoute}>Merge Two Facilities</Link>
{/* <Link to={dashboardModerationQueueRoute}>Moderation Queue</Link> */}
<Link to={dashboardAdjustFacilityMatchesRoute}>
Adjust Facility Matches
</Link>
Expand Down Expand Up @@ -222,6 +225,13 @@ function Dashboard({ userWithAccessHasSignedIn, fetchingSessionSignIn }) {
'Moderation Queue',
)}
/>
<Route
exact
path={dashboardContributionRecordRoute}
render={makeClickableDashboardLinkFn(
'Contribution Record',
)}
/>
</Switch>
}
>
Expand Down Expand Up @@ -256,6 +266,11 @@ function Dashboard({ userWithAccessHasSignedIn, fetchingSessionSignIn }) {
path={dashboardModerationQueueRoute}
component={DashboardModerationQueue}
/>
<Route
exact
path={dashboardContributionRecordRoute}
component={DashboardContributionRecord}
/>
<Route
exact
path={dashboardClaimsDetailsRoute}
Expand Down
Loading