-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 3743 - Broken Links - Add cycle link tables (#3791) * 3743 - Add link tables * 3743 - Reorder link types * 3743 - Update link table * 3743 - Update link type * 3743 - Add locations and unique country/link constraint * 3743 - Update link type * 3743 - Broken links - Get all links to visit (#3812) * 3743 - Get Descriptions and ODPs with links * 3743 - Add Link controller -> get all links to visit * 3743 - Broken Links - Add visit cycle links worker (#3813) * 3743 - Add Link -> getMany * 3743 - Add Link -> upsertMany * 3743 - Add visit cycle links worker * 3743 - Close worker connections * 3743 - Fix update props * 3743 - Broken links - Add API endpoints & activity logs (#3823) * 3743 - Add Link api endpoints * 3743 - Add worker activity logs * 3743 - Rename Link to Links * 3743 - Rename Link type folder to Links * 3743 - Rename Link repository folder to Links * 3743 - Rename Link api folder to Links * 3743 - Rename Link controller folder to Links * 3743 - Update tests Links import * 3743 - Update activity log messages * 3743 - Broken Links - Add sockets events and Get verification job status (#3830) * 3743 - Add socket events * 3743 - Add endpoint to get if the verification job is in progress * 3743 Move getActiveVerifyJobs function * 3743 - Add local emit event function * 3743 - Add redux state and actions (#3832) * 3743 - Add admin links route * 3743 - Add translations * 3743 - Add Admin links table * 3743 - Update table with event listeners * Revert "3743 - Update table with event listeners" This reverts commit 66806e7. * Revert "3743 - Add Admin links table" This reverts commit d8f63fc. * Revert "3743 - Add translations" This reverts commit 24bbf33. * Revert "3743 - Add admin links route" This reverts commit 8f71842. * 3743 - Broken Links - UI Table (#3833) * 3743 - Add admin links route * 3743 - Add translations * 3743 - Add Admin links table * 3743 - Update table with event listeners * 3743 - Broken Links - Delete unused links and disable approve button (#3834) * 3743 - Disable approve button when the verify job is running * 3743 - Delete unused links * 3743 - Soft delete unused links * 3743 - Hide deleted links in the UI * 3743 - Remove visits column * 3743 - Update count on links table update * 3743 - Add excludeDeleted default value * 3743 - Remove visits count translation
- Loading branch information
Showing
72 changed files
with
1,715 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import React, { useEffect } from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
|
||
import { ApiEndPoint } from 'meta/api/endpoint' | ||
|
||
import { useAppDispatch } from 'client/store' | ||
import { LinksActions, useIsVerificationInProgress, useLinksChangeListener } from 'client/store/ui/links' | ||
import { useSectionRouteParams } from 'client/hooks/useRouteParams' | ||
import Button from 'client/components/Buttons/Button' | ||
import TablePaginated from 'client/components/TablePaginated' | ||
|
||
import { useColumns } from './hooks/useColumns' | ||
import { useListenLinksVerificationEvents } from './hooks/useListenLinksVerificationEvents' | ||
|
||
const AdminLinks: React.FC = () => { | ||
const columns = useColumns() | ||
const dispatch = useAppDispatch() | ||
const { t } = useTranslation() | ||
const { assessmentName, cycleName } = useSectionRouteParams() | ||
|
||
const handleVerifyLinks = () => { | ||
dispatch(LinksActions.verifyLinks({ assessmentName, cycleName })) | ||
} | ||
|
||
const verifyLinksInProgress = useIsVerificationInProgress(assessmentName, cycleName) | ||
|
||
useLinksChangeListener() | ||
useListenLinksVerificationEvents() | ||
|
||
useEffect(() => { | ||
dispatch(LinksActions.getIsVerificationInProgress({ assessmentName, cycleName })) | ||
}, [assessmentName, cycleName, dispatch]) | ||
|
||
return ( | ||
<> | ||
<div> | ||
<Button disabled={verifyLinksInProgress ?? true} label={t('admin.verifyLinks')} onClick={handleVerifyLinks} /> | ||
</div> | ||
<TablePaginated | ||
columns={columns} | ||
gridTemplateColumns="auto min-content min-content" | ||
path={ApiEndPoint.CycleData.Links.many()} | ||
/> | ||
</> | ||
) | ||
} | ||
|
||
export default AdminLinks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
@import 'src/client/style/partials'; | ||
|
||
.last-status { | ||
&.empty, | ||
&.enotfound, | ||
&.urlParsingError { | ||
color: $ui-destructive; | ||
} | ||
|
||
&.success { | ||
color: $ui-status-accepted; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import './LastStatus.scss' | ||
import React from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
|
||
import classNames from 'classnames' | ||
|
||
import { Link as LinkType, LinkValidationStatusCode } from 'meta/cycleData' | ||
|
||
type Props = { | ||
link: LinkType | ||
} | ||
|
||
const LastStatus: React.FC<Props> = (props) => { | ||
const { link } = props | ||
const { t } = useTranslation() | ||
const code = link.visits?.at(-1).code | ||
|
||
let label = '' | ||
if ([LinkValidationStatusCode.success, LinkValidationStatusCode.empty].includes(code)) { | ||
label = t(`common.${code}`) | ||
} else { | ||
label = t(`admin.${code}`) | ||
} | ||
|
||
return <span className={classNames('last-status', code)}>{label}</span> | ||
} | ||
export default LastStatus |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './LastStatus' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
@import 'src/client/style/partials'; | ||
|
||
.link-cell { | ||
align-items: center; | ||
display: grid; | ||
grid-column-gap: $spacing-xs; | ||
grid-template-columns: repeat(2, auto); | ||
justify-content: space-between; | ||
width: 100%; | ||
} | ||
|
||
.link-cell__badge { | ||
align-items: center; | ||
background-color: $ui-status-accepted; | ||
border-radius: 4px; | ||
color: white; | ||
display: grid; | ||
font-size: $font-xxxxs; | ||
font-weight: 600; | ||
height: 20px; | ||
justify-content: center; | ||
letter-spacing: 0.4px; | ||
line-height: 0; | ||
padding: 0 $spacing-xxs; | ||
text-transform: uppercase; | ||
} | ||
|
||
.link-cell__anchor { | ||
display: block; | ||
overflow: hidden; | ||
text-decoration: none; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
|
||
&:hover { | ||
text-decoration: underline; | ||
} | ||
} | ||
|
||
.link-cell__badge-button-container { | ||
display: flex; | ||
gap: $spacing-xs; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import './Link.scss' | ||
import React from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
|
||
import classNames from 'classnames' | ||
import { Objects } from 'utils/objects' | ||
|
||
import { Link as LinkType } from 'meta/cycleData' | ||
|
||
import { useAppDispatch } from 'client/store' | ||
import { LinksActions, useIsVerificationInProgress } from 'client/store/ui/links' | ||
import { useSectionRouteParams } from 'client/hooks/useRouteParams' | ||
import Button, { ButtonSize, ButtonType } from 'client/components/Buttons/Button' | ||
|
||
type Props = { | ||
link: LinkType | ||
} | ||
|
||
const Link: React.FC<Props> = (props) => { | ||
const { link: linkInfo } = props | ||
const { link } = linkInfo | ||
const { assessmentName, cycleName } = useSectionRouteParams() | ||
const dispatch = useAppDispatch() | ||
const { t } = useTranslation() | ||
|
||
const verifyLinksInProgress = useIsVerificationInProgress(assessmentName, cycleName) | ||
|
||
const approved = linkInfo.props?.approved | ||
const withApprovalBadge = approved ?? false | ||
|
||
const handleUpdateLink = async () => { | ||
const newApproved = Objects.isEmpty(approved) ? true : !approved | ||
const newProps = { ...linkInfo.props, approved: newApproved } | ||
const newLink = { ...linkInfo, props: newProps } | ||
dispatch(LinksActions.updateLink({ assessmentName, cycleName, link: newLink })) | ||
} | ||
|
||
return ( | ||
<div className={classNames('link-cell', { withApprovalBadge })}> | ||
<a className="link-cell__anchor" href={link} rel="noreferrer" target="_blank"> | ||
{link} | ||
</a> | ||
<div className="link-cell__badge-button-container"> | ||
{withApprovalBadge && <div className="link-cell__badge">{t('common.approved')}</div>} | ||
<Button | ||
disabled={verifyLinksInProgress ?? true} | ||
inverse | ||
label={withApprovalBadge ? t('common.disapprove') : t('common.approve')} | ||
onClick={handleUpdateLink} | ||
size={ButtonSize.xs} | ||
type={ButtonType.primary} | ||
/> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export default Link |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './Link' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React, { useMemo } from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
|
||
import { Link as LinkType } from 'meta/cycleData' | ||
|
||
import { Column } from 'client/components/TablePaginated' | ||
import LastStatus from 'client/pages/AdminLinks/LastStatus' | ||
import LinkItem from 'client/pages/AdminLinks/Link' | ||
|
||
const LocationsCount: React.FC<{ link: LinkType }> = (props) => { | ||
const { link } = props | ||
const { locations } = link | ||
|
||
return <span>{locations?.length}</span> | ||
} | ||
|
||
export const useColumns = (): Array<Column<LinkType>> => { | ||
const { t } = useTranslation() | ||
|
||
return useMemo<Array<Column<LinkType>>>(() => { | ||
return [ | ||
{ | ||
component: ({ datum }) => <LinkItem link={datum} />, | ||
header: t('common.link'), | ||
key: 'link', | ||
orderByProperty: 'link', | ||
}, | ||
{ | ||
component: ({ datum }) => <LastStatus link={datum} />, | ||
header: t('admin.lastStatus'), | ||
key: 'lastStatus', | ||
orderByProperty: 'code', | ||
}, | ||
{ | ||
component: ({ datum }) => <LocationsCount link={datum} />, | ||
header: t('admin.locationsCount'), | ||
key: 'locationsCount', | ||
}, | ||
] | ||
}, [t]) | ||
} |
46 changes: 46 additions & 0 deletions
46
src/client/pages/AdminLinks/hooks/useListenLinksVerificationEvents.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { useEffect } from 'react' | ||
|
||
import { WorkerListener } from 'bullmq' | ||
|
||
import { ApiEndPoint } from 'meta/api/endpoint' | ||
import { Sockets } from 'meta/socket' | ||
|
||
import { useAppDispatch } from 'client/store' | ||
import { LinksActions } from 'client/store/ui/links' | ||
import { TablePaginatedActions, useTablePaginatedOrderBy, useTablePaginatedPage } from 'client/store/ui/tablePaginated' | ||
import { useSectionRouteParams } from 'client/hooks/useRouteParams' | ||
import { SocketClient } from 'client/service/socket' | ||
|
||
export const useListenLinksVerificationEvents = (): void => { | ||
const dispatch = useAppDispatch() | ||
const { assessmentName, cycleName } = useSectionRouteParams() | ||
|
||
const linksVerificationEvent = Sockets.getLinksVerificationEvent({ assessmentName, cycleName }) | ||
|
||
const path = ApiEndPoint.CycleData.Links.many() | ||
const page = useTablePaginatedPage(path) | ||
const orderBy = useTablePaginatedOrderBy(path) | ||
|
||
useEffect(() => { | ||
const listener = (args: [{ event: keyof WorkerListener }]): void => { | ||
const [{ event }] = args | ||
if (event === 'active') { | ||
dispatch( | ||
LinksActions.setIsVerificationInProgress({ assessmentName, cycleName, isVerificationInProgress: true }) | ||
) | ||
} else if (event === 'completed' || event === 'failed') { | ||
dispatch( | ||
LinksActions.setIsVerificationInProgress({ assessmentName, cycleName, isVerificationInProgress: false }) | ||
) | ||
const getDataProps = { assessmentName, cycleName, limit: 30, orderBy, page, path } | ||
dispatch(TablePaginatedActions.getData(getDataProps)) | ||
dispatch(TablePaginatedActions.getCount(getDataProps)) | ||
} | ||
} | ||
|
||
SocketClient.on(linksVerificationEvent, listener) | ||
return () => { | ||
SocketClient.off(linksVerificationEvent, listener) | ||
} | ||
}, [assessmentName, cycleName, dispatch, linksVerificationEvent, orderBy, page, path]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './AdminLinks' |
Oops, something went wrong.