Skip to content

Permission, Billing account, Review update #1053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,6 @@ The following summarizes the various [apps](#adding-a-new-platform-ui-applicatio
- [Gamification Admin](#gamification-admin)
- [Learn](#learn)
- [Self Service](#self-service)
- [Review](#review)

## Platform App

Expand Down Expand Up @@ -600,10 +599,3 @@ Application that allows customers to submit/start challenges self-service.

[Work README TBD](./src/apps/self-service/README.md)
[Work Routes](./src/apps/self-service/src/self-service.routes.tsx)

## Review

The application that allows managing the review submissions.

[Review README TBD](./src/apps/review/README.md)
[Review Routes](./src/apps/review/src/review-app.routes.tsx)
5 changes: 0 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"@storybook/react": "7.6.10",
"@stripe/react-stripe-js": "1.13.0",
"@stripe/stripe-js": "1.41.0",
"@types/codemirror": "^5.60.15",
"apexcharts": "^3.36.0",
"axios": "^1.7.9",
"browser-cookies": "^1.2.0",
Expand All @@ -44,7 +43,6 @@
"draft-js-export-html": "^1.2.0",
"draft-js-markdown-shortcuts-plugin": "^0.3.0",
"draft-js-plugins-editor": "^2.0.3",
"easymde": "^2.20.0",
"express": "^4.21.2",
"express-fileupload": "^1.4.0",
"express-interceptor": "^1.2.0",
Expand Down Expand Up @@ -94,12 +92,9 @@
"redux-promise": "^0.6.0",
"redux-promise-middleware": "^6.1.3",
"redux-thunk": "^2.4.1",
"rehype-raw": "^7.0.0",
"rehype-stringify": "^10.0.1",
"remark-breaks": "^3.0.2",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1",
"remark-parse": "^11.0.0",
"remove": "^0.1.5",
"sanitize-html": "^2.12.1",
"sass": "^1.79.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const DialogEditUserRoles: FC<Props> = (props: Props) => {
variant='danger'
label='Remove'
onClick={function onClick() {
doRemoveRole(data.id)
doRemoveRole(String(data.id))
}}
disabled={isRemoving[data.id]}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,22 @@ const MobileListView: FC<MobileListViewProps<ReviewSummary>> = props => {
<div className={styles.mobileListViewItemContainer} key={d.legacyChallengeId}>
<div className={styles.rows}>
<div className={styles.row1}>
{/* Title */ propertyElements[1]}
{/* Status */ propertyElements[4]}
{/* Title */ propertyElements[0]}
{/* Status */ propertyElements[2]}
</div>
<div className={styles.row2}>
{/* Legacy ID */ propertyElements[2]}
{/* Legacy ID */ propertyElements[1]}
</div>
<div className={styles.row3}>
{propertyElementLabels[5]}
{/* Open Review Opp' */ propertyElements[5]}
{/* propertyElementLabels[5] */}
{/* Open Review Opp' */ propertyElements[3]}
</div>
<div className={styles.row4}>
{propertyElementLabels[6]}
{/* Review Applications */ propertyElements[6]}
{propertyElementLabels[4]}
{/* Review Applications */ propertyElements[4]}
</div>
<div className={styles.row5}>
{/* Action */ propertyElements[7]}
{/* Action */ propertyElements[5]}
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ const ChallengeTitle: FC<{
const ReviewSummaryList: FC<ReviewListProps> = props => {
const columns = useMemo<TableColumn<ReviewSummary>[]>(
() => [
{
label: 'Challenge type',
propertyName: '',
type: 'text',
},
// Hide the columns temporary, we do not have these data now
// {
// label: 'Challenge type',
// propertyName: '',
// type: 'text',
// },
{
label: 'Challenge Title',
propertyName: 'challengeName',
Expand All @@ -76,11 +77,11 @@ const ReviewSummaryList: FC<ReviewListProps> = props => {
propertyName: 'legacyChallengeId',
type: 'text',
},
{
label: 'Current phase',
propertyName: '',
type: 'text',
},
// {
// label: 'Current phase',
// propertyName: '',
// type: 'text',
// },
{ label: 'Status', propertyName: 'challengeStatus', type: 'text' },
// I think this column is important, and it exits in `admin-app`
// but resp does not have it, so I just comment it here
Expand Down
32 changes: 28 additions & 4 deletions src/apps/admin/src/lib/components/ReviewerList/ReviewerList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FC, useMemo } from 'react'
import { format } from 'date-fns'

import { CheckIcon } from '@heroicons/react/solid'
import { CheckIcon, XIcon } from '@heroicons/react/solid'
import { useWindowSize, WindowSize } from '~/libs/shared'
import {
Button,
Expand All @@ -27,6 +27,7 @@ export interface ReviewerListProps {
approvingReviewerId: number
onPageChange: (page: number) => void
onApproveApplication: (reviewer: Reviewer) => void
onUnapproveApplication: (reviewer: Reviewer) => void
onToggleSort: (sort: Sort) => void
}

Expand All @@ -35,15 +36,22 @@ const ApproveButton: FC<{
openReviews: number
approvingReviewerId: number
onApproveApplication: ReviewerListProps['onApproveApplication']
onUnapproveApplication: ReviewerListProps['onUnapproveApplication']
}> = props => {
const handleApprove = useEventCallback((): void => {
props.onApproveApplication(props.reviewer)
})

const handleRemove = useEventCallback((): void => {
props.onUnapproveApplication(props.reviewer)
})

const isApproving = props.approvingReviewerId === props.reviewer.userId
const isOtherApproving = props.approvingReviewerId > 0
const hideApproveButton
= props.openReviews < 1 || props.reviewer.applicationStatus !== 'Pending'
const showRemoveButton
= props.reviewer.applicationStatus === 'Approved'

return (
<>
Expand All @@ -53,7 +61,19 @@ const ApproveButton: FC<{
className={styles.approvingLoadingSpinner}
/>
) : (
!hideApproveButton && (
hideApproveButton ? (
showRemoveButton && (
<Button
primary
variant='danger'
onClick={handleRemove}
>
<XIcon className='icon icon-fill' />
{' '}
Remove Reviewer
</Button>
)
) : (
<Button
primary
onClick={handleApprove}
Expand Down Expand Up @@ -105,13 +125,15 @@ const Actions: FC<{
openReviews: number
approvingReviewerId: number
onApproveApplication: ReviewerListProps['onApproveApplication']
onUnapproveApplication: ReviewerListProps['onUnapproveApplication']
}> = props => (
<div className={styles.rowActions}>
<ApproveButton
reviewer={props.reviewer}
openReviews={props.openReviews}
approvingReviewerId={props.approvingReviewerId}
onApproveApplication={props.onApproveApplication}
onUnapproveApplication={props.onUnapproveApplication}
/>
</div>
)
Expand Down Expand Up @@ -155,7 +177,7 @@ const ReviewerList: FC<ReviewerListProps> = props => {
type: 'element',
},
{
label: 'Open Review Opp',
label: 'Open Review',
propertyName: '',
renderer: (reviewer: Reviewer) => (
// eslint-disable-next-line jsx-a11y/anchor-is-valid
Expand All @@ -170,7 +192,8 @@ const ReviewerList: FC<ReviewerListProps> = props => {
propertyName: 'reviewsInPast60Days',
type: 'number',
},
{ label: 'Matching Skills', propertyName: '', type: 'text' },
// Hide the columns temporary, we do not have these data now
// { label: 'Matching Skills', propertyName: '', type: 'text' },
{
label: '',
renderer: (reviewer: Reviewer) => (
Expand All @@ -179,6 +202,7 @@ const ReviewerList: FC<ReviewerListProps> = props => {
openReviews={props.openReviews}
approvingReviewerId={props.approvingReviewerId}
onApproveApplication={props.onApproveApplication}
onUnapproveApplication={props.onUnapproveApplication}
/>
),
type: 'action',
Expand Down
11 changes: 9 additions & 2 deletions src/apps/admin/src/lib/components/RolesTable/RolesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const RolesTable: FC<Props> = (props: Props) => {
<Link to={`${data.id}/role-members`}>{data.id}</Link>
</div>
),
type: 'element',
type: 'numberElement', // Change from 'element' to 'numberElement'
},
{
label: 'Role Name',
Expand Down Expand Up @@ -187,6 +187,13 @@ export const RolesTable: FC<Props> = (props: Props) => {
},
],
], [columns])

// Convert id fields to numbers to ensure proper sorting
const processedData = useMemo(() => props.datas.map(role => ({
...role,
id: Number(role.id),
})), [props.datas])

const {
page,
setPage,
Expand All @@ -195,7 +202,7 @@ export const RolesTable: FC<Props> = (props: Props) => {
setSort,
sort,
}: useTableFilterLocalProps<UserRole> = useTableFilterLocal(
props.datas ?? [],
processedData ?? [],
undefined,
{
createdAtString: 'createdAt',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,3 @@
text-transform: uppercase;
white-space: nowrap !important;
}

.blockCellLastValue {
:global(.TableCell_blockCell) {
justify-content: flex-end;
text-align: right;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ export const TableMobile: <T extends { [propertyName: string]: any }>(
[styles.blockCellLabel]:
itemItemColumns.mobileType
=== 'label',
[styles.blockCellLastValue]:
itemItemColumns.mobileType
=== 'last-value',
},
styles.blockCell,
)}
Expand Down
6 changes: 4 additions & 2 deletions src/apps/admin/src/lib/hooks/useManageAddGroupMembers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,14 @@ export function useManageAddGroupMembers(
)
.then(() => {
if (!hasSubmissionErrors) {
// Change the success message based on the membership type
const entityType = membershipType === 'user' ? 'Member' : 'Group'
toast.success(
`${
memberIds.length > 1 ? 'Groups' : 'Group'
memberIds.length > 1 ? `${entityType}s` : entityType
} added successfully`,
{
toastId: 'Add groups',
toastId: `Add ${entityType.toLowerCase()}s`,
},
)
callBack()
Expand Down
1 change: 1 addition & 0 deletions src/apps/admin/src/lib/hooks/useTableFilterBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export function useTableFilterBackend<T>(
fetchDataRef.current.filterCriteria,
() => {
fetchDataRef.current.isLoading = false
window.scrollTo({ left: 0, top: 200 })
},
() => {
fetchDataRef.current.isLoading = false
Expand Down
19 changes: 18 additions & 1 deletion src/apps/admin/src/lib/hooks/useTableFilterLocal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,24 @@ export function useTableFilterLocal<T>(
sortField = mappingSortField[sortField]
}

datas = _.orderBy(datas, [sortField], [sort.direction])
datas = [...datas].sort((a, b) => {
const aValue = (a as Record<string, any>)[sortField]
const bValue = (b as Record<string, any>)[sortField]

// Add special case for id field
if (sortField === 'id') {
return sort.direction === 'asc'
? Number(aValue) - Number(bValue)
: Number(bValue) - Number(aValue)
}

// Existing string comparison logic
return sort.direction === 'asc'
? String(aValue)
.localeCompare(String(bValue))
: String(bValue)
.localeCompare(String(aValue))
})
}

setSortedDatas(datas)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface BillingAccountResource {
id: number
name: string
status: string
mobileType?: 'label' | 'last-value'
}
2 changes: 1 addition & 1 deletion src/apps/admin/src/lib/models/UserRole.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TABLE_DATE_FORMAT } from '../../config/index.config'
* Model for user role info
*/
export interface UserRole {
id: string
id: string | number
roleName: string
createdBy?: string
createdByHandle?: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useRef,
useState,
} from 'react'
import { useParams } from 'react-router-dom'
import { NavigateFunction, useNavigate, useParams } from 'react-router-dom'
import { sortBy } from 'lodash'

import { XIcon } from '@heroicons/react/solid'
Expand Down Expand Up @@ -61,6 +61,7 @@ export const ManageReviewerPage: FC = () => {
const { challengeId = '' }: { challengeId?: string } = useParams<{
challengeId: string
}>()
const navigate: NavigateFunction = useNavigate()
const [filterCriteria, setFilterCriteria]: [
ReviewFilterCriteria,
Dispatch<SetStateAction<ReviewFilterCriteria>>
Expand Down Expand Up @@ -134,6 +135,13 @@ export const ManageReviewerPage: FC = () => {
})
})

const unapprove = useEventCallback((): void => {
// how to get challenge Id?
// Now we use one specific challenge id for testing
const realChallengeId = 'c713e250-ecb4-4192-8717-d607ddda8db4'
navigate(`${rootRoute}/challenge-management/${realChallengeId}/manage-user`)
})

// Init
useEffect(() => {
search()
Expand Down Expand Up @@ -214,6 +222,7 @@ export const ManageReviewerPage: FC = () => {
reviewers={reviewers}
openReviews={openReviews}
onApproveApplication={approve}
onUnapproveApplication={unapprove}
approvingReviewerId={userId}
paging={{
page: filterCriteria.page,
Expand Down Expand Up @@ -519,8 +528,8 @@ const ApproveActionType = {
type ApproveActionType =
| {
type: // | typeof ApproveActionType.APPROVE_INIT
| typeof ApproveActionType.APPROVE_FAILED
| typeof ApproveActionType.APPROVE_DONE
| typeof ApproveActionType.APPROVE_FAILED
| typeof ApproveActionType.APPROVE_DONE
}
| {
type: typeof ApproveActionType.APPROVE_INIT
Expand Down
Loading