Skip to content

Commit 580617f

Browse files
authored
Merge pull request #1053 from stevenfrog/permission-update
Permission, Billing account, Review update
2 parents 228b71f + 774a8f5 commit 580617f

File tree

184 files changed

+193
-7659
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+193
-7659
lines changed

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,6 @@ The following summarizes the various [apps](#adding-a-new-platform-ui-applicatio
556556
- [Gamification Admin](#gamification-admin)
557557
- [Learn](#learn)
558558
- [Self Service](#self-service)
559-
- [Review](#review)
560559
561560
## Platform App
562561
@@ -600,10 +599,3 @@ Application that allows customers to submit/start challenges self-service.
600599
601600
[Work README TBD](./src/apps/self-service/README.md)
602601
[Work Routes](./src/apps/self-service/src/self-service.routes.tsx)
603-
604-
## Review
605-
606-
The application that allows managing the review submissions.
607-
608-
[Review README TBD](./src/apps/review/README.md)
609-
[Review Routes](./src/apps/review/src/review-app.routes.tsx)

package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
"@storybook/react": "7.6.10",
2929
"@stripe/react-stripe-js": "1.13.0",
3030
"@stripe/stripe-js": "1.41.0",
31-
"@types/codemirror": "^5.60.15",
3231
"apexcharts": "^3.36.0",
3332
"axios": "^1.7.9",
3433
"browser-cookies": "^1.2.0",
@@ -44,7 +43,6 @@
4443
"draft-js-export-html": "^1.2.0",
4544
"draft-js-markdown-shortcuts-plugin": "^0.3.0",
4645
"draft-js-plugins-editor": "^2.0.3",
47-
"easymde": "^2.20.0",
4846
"express": "^4.21.2",
4947
"express-fileupload": "^1.4.0",
5048
"express-interceptor": "^1.2.0",
@@ -94,12 +92,9 @@
9492
"redux-promise": "^0.6.0",
9593
"redux-promise-middleware": "^6.1.3",
9694
"redux-thunk": "^2.4.1",
97-
"rehype-raw": "^7.0.0",
98-
"rehype-stringify": "^10.0.1",
9995
"remark-breaks": "^3.0.2",
10096
"remark-frontmatter": "^4.0.1",
10197
"remark-gfm": "^3.0.1",
102-
"remark-parse": "^11.0.0",
10398
"remove": "^0.1.5",
10499
"sanitize-html": "^2.12.1",
105100
"sass": "^1.79.0",

src/apps/admin/src/lib/components/DialogEditUserRoles/DialogEditUserRoles.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const DialogEditUserRoles: FC<Props> = (props: Props) => {
100100
variant='danger'
101101
label='Remove'
102102
onClick={function onClick() {
103-
doRemoveRole(data.id)
103+
doRemoveRole(String(data.id))
104104
}}
105105
disabled={isRemoving[data.id]}
106106
/>

src/apps/admin/src/lib/components/ReviewSummaryList/MobileListView/MobileListView.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,22 @@ const MobileListView: FC<MobileListViewProps<ReviewSummary>> = props => {
6767
<div className={styles.mobileListViewItemContainer} key={d.legacyChallengeId}>
6868
<div className={styles.rows}>
6969
<div className={styles.row1}>
70-
{/* Title */ propertyElements[1]}
71-
{/* Status */ propertyElements[4]}
70+
{/* Title */ propertyElements[0]}
71+
{/* Status */ propertyElements[2]}
7272
</div>
7373
<div className={styles.row2}>
74-
{/* Legacy ID */ propertyElements[2]}
74+
{/* Legacy ID */ propertyElements[1]}
7575
</div>
7676
<div className={styles.row3}>
77-
{propertyElementLabels[5]}
78-
{/* Open Review Opp' */ propertyElements[5]}
77+
{/* propertyElementLabels[5] */}
78+
{/* Open Review Opp' */ propertyElements[3]}
7979
</div>
8080
<div className={styles.row4}>
81-
{propertyElementLabels[6]}
82-
{/* Review Applications */ propertyElements[6]}
81+
{propertyElementLabels[4]}
82+
{/* Review Applications */ propertyElements[4]}
8383
</div>
8484
<div className={styles.row5}>
85-
{/* Action */ propertyElements[7]}
85+
{/* Action */ propertyElements[5]}
8686
</div>
8787
</div>
8888
</div>

src/apps/admin/src/lib/components/ReviewSummaryList/ReviewSummaryList.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ const ChallengeTitle: FC<{
5858
const ReviewSummaryList: FC<ReviewListProps> = props => {
5959
const columns = useMemo<TableColumn<ReviewSummary>[]>(
6060
() => [
61-
{
62-
label: 'Challenge type',
63-
propertyName: '',
64-
type: 'text',
65-
},
61+
// Hide the columns temporary, we do not have these data now
62+
// {
63+
// label: 'Challenge type',
64+
// propertyName: '',
65+
// type: 'text',
66+
// },
6667
{
6768
label: 'Challenge Title',
6869
propertyName: 'challengeName',
@@ -76,11 +77,11 @@ const ReviewSummaryList: FC<ReviewListProps> = props => {
7677
propertyName: 'legacyChallengeId',
7778
type: 'text',
7879
},
79-
{
80-
label: 'Current phase',
81-
propertyName: '',
82-
type: 'text',
83-
},
80+
// {
81+
// label: 'Current phase',
82+
// propertyName: '',
83+
// type: 'text',
84+
// },
8485
{ label: 'Status', propertyName: 'challengeStatus', type: 'text' },
8586
// I think this column is important, and it exits in `admin-app`
8687
// but resp does not have it, so I just comment it here

src/apps/admin/src/lib/components/ReviewerList/ReviewerList.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { FC, useMemo } from 'react'
22
import { format } from 'date-fns'
33

4-
import { CheckIcon } from '@heroicons/react/solid'
4+
import { CheckIcon, XIcon } from '@heroicons/react/solid'
55
import { useWindowSize, WindowSize } from '~/libs/shared'
66
import {
77
Button,
@@ -27,6 +27,7 @@ export interface ReviewerListProps {
2727
approvingReviewerId: number
2828
onPageChange: (page: number) => void
2929
onApproveApplication: (reviewer: Reviewer) => void
30+
onUnapproveApplication: (reviewer: Reviewer) => void
3031
onToggleSort: (sort: Sort) => void
3132
}
3233

@@ -35,15 +36,22 @@ const ApproveButton: FC<{
3536
openReviews: number
3637
approvingReviewerId: number
3738
onApproveApplication: ReviewerListProps['onApproveApplication']
39+
onUnapproveApplication: ReviewerListProps['onUnapproveApplication']
3840
}> = props => {
3941
const handleApprove = useEventCallback((): void => {
4042
props.onApproveApplication(props.reviewer)
4143
})
4244

45+
const handleRemove = useEventCallback((): void => {
46+
props.onUnapproveApplication(props.reviewer)
47+
})
48+
4349
const isApproving = props.approvingReviewerId === props.reviewer.userId
4450
const isOtherApproving = props.approvingReviewerId > 0
4551
const hideApproveButton
4652
= props.openReviews < 1 || props.reviewer.applicationStatus !== 'Pending'
53+
const showRemoveButton
54+
= props.reviewer.applicationStatus === 'Approved'
4755

4856
return (
4957
<>
@@ -53,7 +61,19 @@ const ApproveButton: FC<{
5361
className={styles.approvingLoadingSpinner}
5462
/>
5563
) : (
56-
!hideApproveButton && (
64+
hideApproveButton ? (
65+
showRemoveButton && (
66+
<Button
67+
primary
68+
variant='danger'
69+
onClick={handleRemove}
70+
>
71+
<XIcon className='icon icon-fill' />
72+
{' '}
73+
Remove Reviewer
74+
</Button>
75+
)
76+
) : (
5777
<Button
5878
primary
5979
onClick={handleApprove}
@@ -105,13 +125,15 @@ const Actions: FC<{
105125
openReviews: number
106126
approvingReviewerId: number
107127
onApproveApplication: ReviewerListProps['onApproveApplication']
128+
onUnapproveApplication: ReviewerListProps['onUnapproveApplication']
108129
}> = props => (
109130
<div className={styles.rowActions}>
110131
<ApproveButton
111132
reviewer={props.reviewer}
112133
openReviews={props.openReviews}
113134
approvingReviewerId={props.approvingReviewerId}
114135
onApproveApplication={props.onApproveApplication}
136+
onUnapproveApplication={props.onUnapproveApplication}
115137
/>
116138
</div>
117139
)
@@ -155,7 +177,7 @@ const ReviewerList: FC<ReviewerListProps> = props => {
155177
type: 'element',
156178
},
157179
{
158-
label: 'Open Review Opp',
180+
label: 'Open Review',
159181
propertyName: '',
160182
renderer: (reviewer: Reviewer) => (
161183
// eslint-disable-next-line jsx-a11y/anchor-is-valid
@@ -170,7 +192,8 @@ const ReviewerList: FC<ReviewerListProps> = props => {
170192
propertyName: 'reviewsInPast60Days',
171193
type: 'number',
172194
},
173-
{ label: 'Matching Skills', propertyName: '', type: 'text' },
195+
// Hide the columns temporary, we do not have these data now
196+
// { label: 'Matching Skills', propertyName: '', type: 'text' },
174197
{
175198
label: '',
176199
renderer: (reviewer: Reviewer) => (
@@ -179,6 +202,7 @@ const ReviewerList: FC<ReviewerListProps> = props => {
179202
openReviews={props.openReviews}
180203
approvingReviewerId={props.approvingReviewerId}
181204
onApproveApplication={props.onApproveApplication}
205+
onUnapproveApplication={props.onUnapproveApplication}
182206
/>
183207
),
184208
type: 'action',

src/apps/admin/src/lib/components/RolesTable/RolesTable.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const RolesTable: FC<Props> = (props: Props) => {
3434
<Link to={`${data.id}/role-members`}>{data.id}</Link>
3535
</div>
3636
),
37-
type: 'element',
37+
type: 'numberElement', // Change from 'element' to 'numberElement'
3838
},
3939
{
4040
label: 'Role Name',
@@ -187,6 +187,13 @@ export const RolesTable: FC<Props> = (props: Props) => {
187187
},
188188
],
189189
], [columns])
190+
191+
// Convert id fields to numbers to ensure proper sorting
192+
const processedData = useMemo(() => props.datas.map(role => ({
193+
...role,
194+
id: Number(role.id),
195+
})), [props.datas])
196+
190197
const {
191198
page,
192199
setPage,
@@ -195,7 +202,7 @@ export const RolesTable: FC<Props> = (props: Props) => {
195202
setSort,
196203
sort,
197204
}: useTableFilterLocalProps<UserRole> = useTableFilterLocal(
198-
props.datas ?? [],
205+
processedData ?? [],
199206
undefined,
200207
{
201208
createdAtString: 'createdAt',

src/apps/admin/src/lib/components/common/TableMobile/TableMobile.module.scss

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,3 @@
5959
text-transform: uppercase;
6060
white-space: nowrap !important;
6161
}
62-
63-
.blockCellLastValue {
64-
:global(.TableCell_blockCell) {
65-
justify-content: flex-end;
66-
text-align: right;
67-
}
68-
}

src/apps/admin/src/lib/components/common/TableMobile/TableMobile.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ export const TableMobile: <T extends { [propertyName: string]: any }>(
8181
[styles.blockCellLabel]:
8282
itemItemColumns.mobileType
8383
=== 'label',
84-
[styles.blockCellLastValue]:
85-
itemItemColumns.mobileType
86-
=== 'last-value',
8784
},
8885
styles.blockCell,
8986
)}

src/apps/admin/src/lib/hooks/useManageAddGroupMembers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,14 @@ export function useManageAddGroupMembers(
102102
)
103103
.then(() => {
104104
if (!hasSubmissionErrors) {
105+
// Change the success message based on the membership type
106+
const entityType = membershipType === 'user' ? 'Member' : 'Group'
105107
toast.success(
106108
`${
107-
memberIds.length > 1 ? 'Groups' : 'Group'
109+
memberIds.length > 1 ? `${entityType}s` : entityType
108110
} added successfully`,
109111
{
110-
toastId: 'Add groups',
112+
toastId: `Add ${entityType.toLowerCase()}s`,
111113
},
112114
)
113115
callBack()

src/apps/admin/src/lib/hooks/useTableFilterBackend.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export function useTableFilterBackend<T>(
6262
fetchDataRef.current.filterCriteria,
6363
() => {
6464
fetchDataRef.current.isLoading = false
65+
window.scrollTo({ left: 0, top: 200 })
6566
},
6667
() => {
6768
fetchDataRef.current.isLoading = false

src/apps/admin/src/lib/hooks/useTableFilterLocal.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,24 @@ export function useTableFilterLocal<T>(
5454
sortField = mappingSortField[sortField]
5555
}
5656

57-
datas = _.orderBy(datas, [sortField], [sort.direction])
57+
datas = [...datas].sort((a, b) => {
58+
const aValue = (a as Record<string, any>)[sortField]
59+
const bValue = (b as Record<string, any>)[sortField]
60+
61+
// Add special case for id field
62+
if (sortField === 'id') {
63+
return sort.direction === 'asc'
64+
? Number(aValue) - Number(bValue)
65+
: Number(bValue) - Number(aValue)
66+
}
67+
68+
// Existing string comparison logic
69+
return sort.direction === 'asc'
70+
? String(aValue)
71+
.localeCompare(String(bValue))
72+
: String(bValue)
73+
.localeCompare(String(aValue))
74+
})
5875
}
5976

6077
setSortedDatas(datas)

src/apps/admin/src/lib/models/BillingAccountResource.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export interface BillingAccountResource {
55
id: number
66
name: string
77
status: string
8+
mobileType?: 'label' | 'last-value'
89
}

src/apps/admin/src/lib/models/UserRole.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { TABLE_DATE_FORMAT } from '../../config/index.config'
66
* Model for user role info
77
*/
88
export interface UserRole {
9-
id: string
9+
id: string | number
1010
roleName: string
1111
createdBy?: string
1212
createdByHandle?: string

src/apps/admin/src/review-management/ManageReviewerPage/ManageReviewerPage.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
useRef,
88
useState,
99
} from 'react'
10-
import { useParams } from 'react-router-dom'
10+
import { NavigateFunction, useNavigate, useParams } from 'react-router-dom'
1111
import { sortBy } from 'lodash'
1212

1313
import { XIcon } from '@heroicons/react/solid'
@@ -61,6 +61,7 @@ export const ManageReviewerPage: FC = () => {
6161
const { challengeId = '' }: { challengeId?: string } = useParams<{
6262
challengeId: string
6363
}>()
64+
const navigate: NavigateFunction = useNavigate()
6465
const [filterCriteria, setFilterCriteria]: [
6566
ReviewFilterCriteria,
6667
Dispatch<SetStateAction<ReviewFilterCriteria>>
@@ -134,6 +135,13 @@ export const ManageReviewerPage: FC = () => {
134135
})
135136
})
136137

138+
const unapprove = useEventCallback((): void => {
139+
// how to get challenge Id?
140+
// Now we use one specific challenge id for testing
141+
const realChallengeId = 'c713e250-ecb4-4192-8717-d607ddda8db4'
142+
navigate(`${rootRoute}/challenge-management/${realChallengeId}/manage-user`)
143+
})
144+
137145
// Init
138146
useEffect(() => {
139147
search()
@@ -214,6 +222,7 @@ export const ManageReviewerPage: FC = () => {
214222
reviewers={reviewers}
215223
openReviews={openReviews}
216224
onApproveApplication={approve}
225+
onUnapproveApplication={unapprove}
217226
approvingReviewerId={userId}
218227
paging={{
219228
page: filterCriteria.page,
@@ -519,8 +528,8 @@ const ApproveActionType = {
519528
type ApproveActionType =
520529
| {
521530
type: // | typeof ApproveActionType.APPROVE_INIT
522-
| typeof ApproveActionType.APPROVE_FAILED
523-
| typeof ApproveActionType.APPROVE_DONE
531+
| typeof ApproveActionType.APPROVE_FAILED
532+
| typeof ApproveActionType.APPROVE_DONE
524533
}
525534
| {
526535
type: typeof ApproveActionType.APPROVE_INIT

0 commit comments

Comments
 (0)