Skip to content

Commit 6471e31

Browse files
authored
Merge pull request #1056 from topcoder-platform/diazz-admin-f2f-30376659
Topcoder Admin App - Roles Management Update
2 parents 159d6e2 + 26face4 commit 6471e31

File tree

14 files changed

+248
-137
lines changed

14 files changed

+248
-137
lines changed

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,22 @@ import {
99
useMemo,
1010
useRef,
1111
} from 'react'
12-
import ReactSelect, { components, SingleValue } from 'react-select'
12+
import { components, SingleValue } from 'react-select'
13+
import CreatableReactSelect from 'react-select/creatable'
1314
import classNames from 'classnames'
1415

1516
import { IconOutline, InputWrapper, LoadingSpinner } from '~/libs/ui'
1617

1718
import { SelectOption } from '../../models'
19+
import ReactSelect from '../common/ReactSelectExport'
1820

1921
import styles from './FieldSingleSelect.module.scss'
2022

2123
interface Props {
2224
label?: string
2325
className?: string
2426
placeholder?: string
25-
readonly value?: SelectOption
27+
readonly value?: SelectOption | null
2628
readonly onChange?: (event: SelectOption) => void
2729
readonly disabled?: boolean
2830
readonly dirty?: boolean
@@ -32,6 +34,10 @@ interface Props {
3234
readonly onBlur?: (event: FocusEvent<HTMLInputElement>) => void
3335
readonly options: SelectOption[]
3436
readonly isLoading?: boolean
37+
readonly classNameWrapper?: string
38+
readonly onSearchChange?: (value: string) => void
39+
readonly creatable?: boolean
40+
readonly createLabel?: (inputValue: string) => string
3541
}
3642

3743
// eslint-disable-next-line react/function-component-definition
@@ -60,6 +66,10 @@ export const FieldSingleSelect: FC<Props> = (props: Props) => {
6066
[],
6167
)
6268

69+
const Input = useMemo(() => (
70+
props.creatable ? CreatableReactSelect : ReactSelect
71+
), [props.creatable])
72+
6373
return (
6474
<InputWrapper
6575
{...props}
@@ -72,7 +82,7 @@ export const FieldSingleSelect: FC<Props> = (props: Props) => {
7282
hideInlineErrors={props.hideInlineErrors}
7383
ref={wrapRef as MutableRefObject<HTMLDivElement>}
7484
>
75-
<ReactSelect
85+
<Input
7686
components={asyncSelectComponents}
7787
className={classNames(props.className, styles.select)}
7888
placeholder={props.placeholder ?? 'Enter'}
@@ -88,9 +98,13 @@ export const FieldSingleSelect: FC<Props> = (props: Props) => {
8898
}
8999
}}
90100
value={props.value}
101+
defaultValue={props.value}
91102
isDisabled={props.disabled || props.isLoading}
92103
onBlur={props.onBlur}
93104
options={props.options}
105+
onInputChange={props.onSearchChange}
106+
createOptionPosition='first'
107+
formatCreateLabel={props.createLabel}
94108
/>
95109
{props.isLoading && (
96110
<div className={styles.blockActionLoading}>

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ export const RoleMembersFilters: FC<Props> = props => {
6666
inputControl={register('userHandle')}
6767
disabled={props.isLoading}
6868
/>
69+
<InputText
70+
type='text'
71+
name='email'
72+
label='Email'
73+
placeholder='Enter'
74+
tabIndex={0}
75+
onChange={_.noop}
76+
classNameWrapper={styles.field}
77+
inputControl={register('email')}
78+
disabled={props.isLoading}
79+
/>
6980
</div>
7081

7182
<div className={styles.blockBottom}>

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

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
/**
22
* Role members table.
33
*/
4-
import { FC, useContext, useEffect, useMemo } from 'react'
4+
import { FC, useMemo } from 'react'
55
import _ from 'lodash'
66
import classNames from 'classnames'
77

88
import { useWindowSize, WindowSize } from '~/libs/shared'
99
import { Button, InputCheckbox, Table, TableColumn } from '~/libs/ui'
1010

11-
import { AdminAppContext } from '../../contexts'
1211
import { useTableFilterLocal, useTableFilterLocalProps } from '../../hooks'
13-
import { AdminAppContextType, RoleMemberInfo } from '../../models'
12+
import { RoleMemberInfo } from '../../models'
1413
import { MobileTableColumn } from '../../models/MobileTableColumn.model'
1514
import { Pagination } from '../common/Pagination'
1615
import { TableMobile } from '../common/TableMobile'
@@ -28,8 +27,6 @@ interface Props {
2827
}
2928

3029
export const RoleMembersTable: FC<Props> = (props: Props) => {
31-
const { loadUser, usersMapping, cancelLoadUser }: AdminAppContextType
32-
= useContext(AdminAppContext)
3330
const {
3431
page,
3532
setPage,
@@ -51,27 +48,6 @@ export const RoleMembersTable: FC<Props> = (props: Props) => {
5148
unselectAll,
5249
}: useTableSelectionProps<string> = useTableSelection<string>(datasIds)
5350

54-
useEffect(() => {
55-
// clear queue of currently loading user handles
56-
cancelLoadUser()
57-
// load user handles for members visible on the current page
58-
_.forEach(results, result => {
59-
loadUser(result.id)
60-
})
61-
62-
return () => {
63-
// clear queue of currently loading user handles after exit ui
64-
cancelLoadUser()
65-
}
66-
// eslint-disable-next-line react-hooks/exhaustive-deps
67-
}, [results])
68-
69-
useEffect(() => {
70-
_.forEach(results, result => {
71-
result.handle = usersMapping[result.id]
72-
})
73-
}, [usersMapping, results])
74-
7551
const columns = useMemo<TableColumn<RoleMemberInfo>[]>(
7652
() => [
7753
{
@@ -108,20 +84,12 @@ export const RoleMembersTable: FC<Props> = (props: Props) => {
10884
{
10985
label: 'Handle',
11086
propertyName: 'handle',
111-
renderer: (data: RoleMemberInfo) => {
112-
if (!data.id) {
113-
return <></>
114-
}
115-
116-
return (
117-
<>
118-
{!usersMapping[data.id]
119-
? 'loading...'
120-
: usersMapping[data.id]}
121-
</>
122-
)
123-
},
124-
type: 'element',
87+
type: 'text',
88+
},
89+
{
90+
label: 'Email',
91+
propertyName: 'email',
92+
type: 'text',
12593
},
12694
{
12795
className: styles.blockColumnAction,
@@ -145,7 +113,6 @@ export const RoleMembersTable: FC<Props> = (props: Props) => {
145113
[
146114
isSelectAll,
147115
selectedDatas,
148-
usersMapping,
149116
props.isRemoving,
150117
props.isRemovingBool,
151118
props.doRemoveRoleMember,
@@ -171,12 +138,30 @@ export const RoleMembersTable: FC<Props> = (props: Props) => {
171138
),
172139
type: 'element',
173140
},
141+
], [
142+
{
143+
...columns[3],
144+
className: '',
145+
label: `${columns[3].label as string} label`,
146+
mobileType: 'label',
147+
renderer: () => (
148+
<div>
149+
{columns[3].label as string}
150+
:
151+
</div>
152+
),
153+
type: 'element',
154+
},
155+
{
156+
...columns[3],
157+
mobileType: 'last-value',
158+
},
174159
],
175160
[
176161
{
177-
...columns[3],
162+
...columns[4],
178163
className: classNames(
179-
columns[3].className,
164+
columns[4].className,
180165
styles.blockRightColumn,
181166
),
182167
colSpan: 2,

0 commit comments

Comments
 (0)