Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Topcoder Admin App - Add Terms Management Final fix#1133

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
suppermancool wants to merge3 commits intofeat/system-admin
base:feat/system-admin
Choose a base branch
Loading
fromdiazz-admin-code-30377360

Conversation

suppermancool
Copy link
Collaborator

}

.dialogLoadingSpinnerContainer {
position: absolute;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive class name for.dialogLoadingSpinnerContainer to clearly indicate its purpose or context within the dialog.

left: 0;

.spinner {
background: none;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The.spinner class currently only setsbackground: none;. If there are additional styles needed for the spinner, consider adding them here for clarity and completeness.

const onSubmit = useCallback(
(data: FormAddTermUser) => {
props.doAddTermUser(
data.handle?.value ?? 0,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider checking ifdata.handle is defined before accessingvalue andlabel to avoid potential runtime errors.

onBlur={controlProps.field.onBlur}
classNameWrapper={styles.inputField}
disabled={props.isAdding}
dirty

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thedirty prop inFieldHandleSelect is set to true, but it is not clear if this prop is necessary or used within the component. Verify if this prop is needed and remove it if it is not used.

placeholder?: string
readonly value?: SelectOption
readonly value?: SelectOption | null

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider updating the type definition forvalue toSelectOption | null in any other related interfaces or components that might be affected by this change to ensure consistency across the codebase.

@@ -16,8 +16,9 @@ import styles from './FieldSingleSelectAsync.module.scss'
interface Props {
label?: string
className?: string
classNameWrapper?: string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider adding a description for the newclassNameWrapper prop in the component's documentation or prop types to clarify its purpose and usage.

align-items: center;
justify-content: center;
height: 64px;
left: $sp-8;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive variable name instead of$sp-8 to improve readability and maintainability.

justify-content: center;
height: 64px;
left: $sp-8;
bottom: $sp-8;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive variable name instead of$sp-8 to improve readability and maintainability.

}

@include ltelg {
left: $sp-4;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive variable name instead of$sp-4 to improve readability and maintainability.


@include ltelg {
left: $sp-4;
bottom: $sp-4;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive variable name instead of$sp-4 to improve readability and maintainability.

*/
const onSubmit = useCallback(
(data: FormAddTerm) => {
const requestBody = _.pickBy(data, _.identity)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider adding error handling for thedoAddTerm anddoUpdateTerm functions to manage potential failures during the term addition or update process.


const agreeabilityTypeId = watch('agreeabilityTypeId')
useEffect(() => {
// check to enable/disable 'Docusign Template ID' and 'URL' fields

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The useEffect dependency array should includegetValues andsetValue to ensure that the effect runs correctly when these functions change.

}, [agreeabilityTypeId])

useEffect(() => {
if (termInfo) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The useEffect dependency array should includereset to ensure that the effect runs correctly when this function changes.

<Button
primary
onClick={function onClick() {
setShowEditor(prev => !prev)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive function name for theonClick handler to improve readability and maintainability.


.fields {
display: flex;
gap: 15px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a variable for thegap value instead of a hardcoded15px to maintain consistency and ease of updates across the stylesheet.


.blockBottom {
display: flex;
gap: 10px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a variable for thegap value instead of a hardcoded10px to maintain consistency and ease of updates across the stylesheet.

.blockBottom {
display: flex;
gap: 10px;
margin-top: 3px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a variable for themargin-top value instead of a hardcoded3px to maintain consistency and ease of updates across the stylesheet.

label='Title'
placeholder='Enter'
tabIndex={0}
onChange={_.noop}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheonChange prop is set to_.noop, which means it does nothing. If this is intentional, consider removing it to avoid confusion.

secondary
onClick={function onClick() {
reset(defaultValues)
setTimeout(() => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThesetTimeout function is used without a delay parameter. If the intention is to executeonSubmit asynchronously, consider specifying a delay or using a different approach to ensure clarity.

color: $blue-110;

&:hover {
color: $blue-110;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The&:hover selector is setting the same color as the default link color. Consider using a different color for hover to provide visual feedback to users.

}

.tableCell {
white-space: break-spaces !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Using!important can make the CSS harder to maintain. Consider refactoring the CSS to avoid using!important if possible.


.tableCell {
white-space: break-spaces !important;
text-align: left !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Using!important can make the CSS harder to maintain. Consider refactoring the CSS to avoid using!important if possible.

totalPages: number
page: number
setPage: Dispatch<SetStateAction<number>>
colWidth: colWidthType | undefined

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider providing a default value forcolWidth to avoid potential undefined behavior.

page: number
setPage: Dispatch<SetStateAction<number>>
colWidth: colWidthType | undefined
setColWidth: Dispatch<SetStateAction<colWidthType>> | undefined

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider providing a default value forsetColWidth to avoid potential undefined behavior.

type: 'element',
},
],
// eslint-disable-next-line react-hooks/exhaustive-deps

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The dependency array foruseMemo is empty, which means the memoized value will never update. Ensure this is intentional, or consider adding dependencies if the columns need to update based on props or state changes.

...column,
className: '',
label: `${column.label as string} label`,
mobileType: 'label',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The label for mobile columns is being suffixed with 'label'. Ensure this is the intended behavior, as it might lead to redundancy in the UI.

.fields {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 15px 30px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using CSS variables or a pre-defined spacing variable for the gap values to maintain consistency across the application.

display: flex;
justify-content: flex-end;
align-items: flex-start;
gap: 15px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using CSS variables or a pre-defined spacing variable for the gap values to maintain consistency across the application.

label='User Id'
placeholder='Enter'
tabIndex={0}
onChange={_.noop}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheonChange handler is set to_.noop, which means it does nothing. If this is intentional, consider removing theonChange prop entirely to avoid confusion.

label='Handle'
placeholder='Enter'
tabIndex={0}
onChange={_.noop}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Similar to the previous comment, theonChange handler is set to_.noop. If no action is needed on change, consider omitting this prop.

onClick={function onClick() {
reset(defaultValues)
setTimeout(() => {
onSubmit(defaultValues)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThesetTimeout function is used without a delay parameter, which defaults to 0. This might be unnecessary if the intention is to executeonSubmit immediately afterreset. Consider removingsetTimeout if no delay is needed.

}

.tableCell {
white-space: break-spaces !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Using!important can make it difficult to override styles in the future. Consider if this is necessary or if the specificity of the selector can be increased instead.


.tableCell {
white-space: break-spaces !important;
text-align: left !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Using!important can make it difficult to override styles in the future. Consider if this is necessary or if the specificity of the selector can be increased instead.

props.forceSelect(item.userId)
})
}
}, [isSelectAll, props.datas])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider addingprops.forceUnSelect andprops.forceSelect to the dependency array oftoggleSelectAll to ensure that the latest versions of these functions are used.

]
}),
[columns],
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider addingprops.isRemovingBool andprops.isRemoving to the dependency array ofcolumnsMobile to ensure that the latest values are used.

// extend body ultra small and override it
font-size: 14px;
line-height: 19px;
line-height: $error-line-height;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Theline-height property is defined twice on this line. Consider removing the redundantline-height: 19px; to avoid confusion and ensure consistency.

const elementRef = useRef<HTMLTextAreaElement>(null)
const easyMDE = useRef<any>(null)

/**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider specifying the type foreasyMDE instead of usingany to improve type safety and maintainability.

},
[],
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThegetState function uses a lot of string manipulation and regular expressions. Consider adding unit tests to ensure its correctness and robustness.

* Handle toggle block
*/
const toggleBlock = useCallback(
(editor: any, type: string, startChars: any, endCharsInput?: any) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThetoggleBlock function is complex and handles multiple cases. Consider breaking it down into smaller functions to improve readability and maintainability.

/**
* Show hint after '@'
*/
const completeAfter = useCallback((cm: CodeMirror.Editor) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThecompleteAfter function directly manipulates the editor content. Ensure that this behavior is well-tested to prevent unexpected side effects.

}, [])

useOnComponentDidMount(() => {
easyMDE.current = new EasyMDE({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheuseOnComponentDidMount hook initializes theEasyMDE editor. Ensure that the dependencies are correctly managed to prevent potential memory leaks or unexpected behavior.

uploadImage: false,
})

easyMDE.current.codemirror.on('change', (cm: CodeMirror.Editor) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider adding error handling for thechange andblur events to gracefully handle any potential issues during these events.

@import '@libs/ui/styles/includes';

.form-input-textarea {
@include font-roboto;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thefont-roboto mixin should be checked to ensure it is correctly imported and available in the context of this file. If it is not defined in the included files, this will cause a compilation error.

border: none;
outline: none;
resize: vertical;
margin-left: calc(-1 * $border);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The use ofcalc(-1 * $border) formargin-left should be verified to ensure that$border is defined and that this calculation results in the intended layout. If$border is not defined or is not a numeric value, this could lead to unexpected behavior.


useEffect(() => {
if (!initValue) {
setInitValue(props.value as string)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThesetInitValue function is called only wheninitValue is falsy, which means it will not update ifprops.value changes after the initial render. Consider whether this behavior is intended or if you need to updateinitValue wheneverprops.value changes.

{...props}
dirty={!!props.dirty}
disabled={!!props.disabled}
label={props.label || props.name}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thelabel prop defaults toprops.name ifprops.label is not provided. Ensure thatprops.name is always a suitable fallback for the label, as it might not always be user-friendly.

@@ -16,14 +16,19 @@
display: flex;
gap: 15px;
justify-content: flex-end;
flex-wrap: wrap;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider ifflex-wrap: wrap; is necessary here. If the container's content is not expected to exceed the container's width, this property might be redundant.


@include ltemd {
grid-template-columns: 1fr;
display: flex;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thedisplay: flex; property is being set within the@include ltemd media query. Ensure that this change is intended, as it overrides thedisplay: grid; property set earlier. This could affect the layout significantly.

@@ -14,7 +14,7 @@
padding: $sp-4;
}

&.isPlatformPage {
&.isPlatformGamificationAdminPage {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The class name change fromisPlatformPage toisPlatformGamificationAdminPage should be verified across the codebase to ensure that all references to this class are updated accordingly. This will prevent any potential styling issues due to mismatched class names.

@@ -1,11 +1,10 @@
import { FC, PropsWithChildren, useContext } from 'react'
import cn from 'classnames'

import { platformRouteId } from '~/apps/admin/src/config/routes.config'
import {gamificationAdminRouteId,platformRouteId, rootRoute } from '~/apps/admin/src/config/routes.config'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The import statement forgamificationAdminRouteId androotRoute has been added, but it's not clear if these are used in the current file. Please ensure that all imported modules are utilized to avoid unnecessary imports.

import { ContentLayout } from '~/libs/ui'
import { routerContext, RouterContextData } from '~/libs/core'
import { platformSkillRouteId } from '~/apps/admin/src/platform/routes.config'
import { AppSubdomain, EnvironmentConfig } from '~/config'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The import statement forAppSubdomain andEnvironmentConfig has been removed. Verify if these are no longer needed in the file, as removing them might affect the functionality if they were used elsewhere in the code.

@@ -39,8 +38,8 @@ export const Layout: FC<LayoutProps> = props => (
</ContentLayout>
)

export const PlatformLayout: FC<LayoutProps> = props => (
<Layout classes={{ mainClass: styles.isPlatformPage }}>
export const PlatformGamificationAdminLayout: FC<LayoutProps> = props => (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The component namePlatformGamificationAdminLayout is quite long and may reduce readability. Consider using a shorter, more concise name if possible.

export constPlatformLayout: FC<LayoutProps> = props => (
<Layout classes={{ mainClass: styles.isPlatformPage }}>
export constPlatformGamificationAdminLayout: FC<LayoutProps> = props => (
<Layout classes={{ mainClass: styles.isPlatformGamificationAdminPage }}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Ensure thatstyles.isPlatformGamificationAdminPage is defined in your styles module. If it is not, this could lead to runtime errors.

const skillManagementRouteId = EnvironmentConfig.SUBDOMAIN === AppSubdomain.admin
? `/${platformRouteId}/${platformSkillRouteId}`
: `/${AppSubdomain.admin}/${platformRouteId}/${platformSkillRouteId}`
const platformBasePath = `${rootRoute}/${platformRouteId}/${gamificationAdminRouteId}`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The variableplatformBasePath is declared but never used in the code. Consider removing it if it's not needed, or ensure it is used appropriately if it is required for functionality.

.startsWith(platformBaseRouteId.toLowerCase())) {
return { Layout:PlatformLayout }
.startsWith(platformBasePath.toLowerCase())) {
return { Layout:PlatformGamificationAdminLayout }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The change fromPlatformLayout toPlatformGamificationAdminLayout should be verified to ensure that it aligns with the intended functionality of the terms management feature. Make sure thatPlatformGamificationAdminLayout provides the necessary layout and components required for the admin interface.

@@ -20,6 +21,7 @@ export const PageWrapper: FC<PropsWithChildren<Props>> = props => (
<PageTitle>{props.pageTitle}</PageTitle>
<PageHeader>
<h3 className={styles.textTitle}>{props.pageTitle}</h3>
{props.pageSubTitle}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider wrappingprops.pageSubTitle in a conditional check to ensure it is not undefined or null before rendering. This will prevent potential rendering issues ifpageSubTitle is not provided.

*/
const doUpdateTerm = useCallback(
(data: Partial<FormAddTerm>, callBack: () => void) => {
setIsAdding(true)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggestion

Consider using a more descriptive variable name instead of reusingisAdding for the update operation. This can help improve code readability and avoid confusion, asisAdding is also used in thedoAddTerm function.

Example

You could introduce a new state variable likeisUpdating for the update operation:

const[isUpdating,setIsUpdating]=useState(false);

And then use it in thedoUpdateTerm function:

setIsUpdating(true);...setIsUpdating(false);

Reasoning

This change will make it clear that the state is specifically related to the update operation, rather than the add operation.

type: TermsActionType.FETCH_TERMS_INIT,
})
let filter = `page=${pagRequest}&perPage=${TABLE_PAGINATION_ITEM_PER_PAGE}`
if (filterCriteria?.searchKey) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider usingconst instead oflet for thefilter variable since it is not reassigned.

let filter = `page=${pagRequest}&perPage=${TABLE_PAGINATION_ITEM_PER_PAGE}`
if (filterCriteria?.searchKey) {
filter += `&title=${filterCriteria?.searchKey}`
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The optional chaining operator?. is used twice onfilterCriteria?.searchKey. The second usage is redundant because iffilterCriteria is undefined, the first check will already prevent accessingsearchKey.

type: TermsActionType.FETCH_TERMS_DONE,
})
success()
window.scrollTo({ left: 0, top: 0 })

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thewindow.scrollTo function is called with an object. Ensure that this behavior is intended and supported across all target browsers.

} from '../models'
import { handleError } from '../utils'
import {
addUserTerm,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider renamingaddUserTerm toaddTermUser for consistency with other function names likeremoveTermUser.

}
| {
type: typeof TermsActionType.FETCH_TERMS_USERS_DONE
payload: {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The payload type here could be more specific. Consider defining a type for the payload to improve type safety and readability.

| typeof TermsActionType.REMOVE_TERMS_USERS_DONE
| typeof TermsActionType.REMOVE_TERMS_USERS_INIT
| typeof TermsActionType.REMOVE_TERMS_USERS_FAILED
payload: number

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The payload type here is a number, which is inconsistent with the other actions that use objects. Consider using a consistent structure for all action payloads.

const requestSuccess = (data: number[], totalPages: number): void => {
dispatch({
payload: {
data: data.map(item => ({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a more descriptive variable name thanitem to improve code readability.

&& filterCriteria?.userId.toString()
.trim()
) {
filter += `&userId=${filterCriteria.userId}`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThetoString().trim() method chain is repeated multiple times. Consider extracting this logic into a utility function to improve code readability and maintainability.


if (filterCriteria?.handle && filterCriteria?.handle.trim()) {
if (
filterCriteria?.userId

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The conditionfilterCriteria?.userId && filterCriteria?.userId.toString().trim() is repeated. Consider extracting this logic into a utility function or variable to avoid repetition.

)

useEffect(() => {
_.forEach(state.datas, termUser => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The dependency array for thisuseEffect is missing some dependencies likeloadUser,setPage, andreloadData. Ensure all dependencies are included to avoid potential bugs.

@@ -99,6 +100,7 @@ export function useTableFilterBackend<T>(

return {
page,
reloadData: doSearchDatas,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The functiondoSearchDatas seems to be used here, but its definition or import is not visible in this diff. Ensure thatdoSearchDatas is correctly defined or imported in the file to avoid runtime errors.

@@ -3,5 +3,13 @@
*/
export interface UserTerm {
id: string
legacyId: number

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using a consistent type for IDs. Ifid is astring, ensurelegacyId andtypeId are alsostring unless there's a specific reason for them to benumber.

title: string
url: string
agreeabilityTypeId: string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheagreeabilityTypeId is astring, buttypeId is anumber. Ensure consistency in ID types unless there's a specific reason for the difference.

> => {
const result = await xhrGetPaginatedAsync<{
result: number[]
}>(`${EnvironmentConfig.API.V5}/terms/${termId}/users?${filter ?? ''}`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The filter parameter is appended directly to the URL without any encoding. Consider usingencodeURIComponent to ensure that the filter string is safely included in the URL.

@@ -20,14 +27,14 @@ import { FormAddSSOLoginData } from '../models/FormAddSSOLoginData.model'
*/
export const getMemberSuggestionsByHandle = async (
handle: string,
): Promise<Array<{ handle: string; userId: number }>> => {
): Promise<Array<MemberInfo>> => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The typeMemberInfo should be defined or imported if not already done. Ensure thatMemberInfo includes the propertieshandle anduserId as expected by the function.

@@ -38,13 +45,13 @@ export const getMemberSuggestionsByHandle = async (
*/
export const getMembersByHandle = async (
handles: string[],
): Promise<Array<{ handle: string }>> => {
): Promise<Array<MemberInfo>> => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The return type of the function has been changed fromArray<{ handle: string }> toArray<MemberInfo>. Ensure that theMemberInfo type is correctly defined and includes all necessary fields such ashandle and any other fields expected from the API response.

*/
export const getProfile = async (handle: string): Promise<MemberInfo> => {
if (!handle) {
return Promise.reject(new Error('Handle must be specified.'))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The check for an empty handle should throw an error instead of returning a rejected promise. Consider usingthrow new Error('Handle must be specified.') for better readability and consistency.

const result = await xhrGetAsync<ApiV3Response<MemberInfo>>(
`${EnvironmentConfig.API.V3}/members/${handle}`,
)
return result.result.content

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider adding error handling for thexhrGetAsync call to manage potential network or API errors gracefully.

* @param units units
* @returns file size
*/
export function humanFileSize(inputBytes: number, units: string[]): string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider adding input validation forinputBytes andunits to ensure they are of expected types and values. For example,inputBytes should be a non-negative number, andunits should be a non-empty array.

*/
export function humanFileSize(inputBytes: number, units: string[]): string {
let bytes = inputBytes
if (Math.abs(bytes) < 1024) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The conditionMath.abs(bytes) < 1024 assumes thatunits has at least one element. Consider adding a check to ensureunits is not empty before accessingunits[0].

u += 1
} while (Math.abs(bytes) >= 1024 && u < units.length)

return `${bytes.toFixed(1)}${units[u]}`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThetoFixed(1) method is used here, which will round the number to one decimal place. Consider whether this level of precision is appropriate for all use cases, or if it should be configurable.

FormUsersFilters,
} from '../models'
import { FormEditUserStatus } from '../models/FormEditUserStatus.model'
import { FormAddRoleMembers } from '../models/FormAddRoleMembers.type'
import { FormAddSSOLoginData } from '../models/FormAddSSOLoginData.model'
import { FormAddTermUser } from '../models/FormAddTermUser.model'

const docusignTypeId

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The variabledocusignTypeId is declared but not initialized properly. Consider usingconst docusignTypeId = EnvironmentConfig.ADMIN.AGREE_FOR_DOCUSIGN_TEMPLATE; to ensure proper initialization.

*/
export const formAddTermUserSchema: Yup.ObjectSchema<FormAddTermUser>
= Yup.object({
handle: Yup.object()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thehandle field is defined as an object, but the error message 'Handle is required.' might be misleading if the object itself is present but one of its properties is missing. Consider specifying which part of the handle is required in the error message.

label: Yup.string()
.required('Label is required.'),
value: Yup.number()
.typeError('Invalid number.')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The error message 'Invalid number.' for thevalue field might not be clear to users. Consider providing more context, such as 'Value must be a valid number.'

docusignTemplateId: Yup.string()
.trim()
.when('agreeabilityTypeId', (agreeabilityTypeId, schema) => {
if (agreeabilityTypeId[0] === docusignTypeId) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider checking ifagreeabilityTypeId is an array before accessing its first element with[0]. This will prevent potential runtime errors ifagreeabilityTypeId is not an array.

.required('Type is required.'),
url: Yup.string()
.trim()
.url('Invalid url.')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Theurl validation should be required if the URL is a mandatory field. Consider changing.optional() to.required('URL is required.') if applicable.

className?: string
}

export const TermsAddPage: FC<Props> = (props: Props) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider using destructuring forprops to directly extractclassName. This can make the code cleaner and more readable. For example:export const TermsAddPage: FC<Props> = ({ className }) => {

}

.removeSelectionButtonContainer {
padding: 20px 0 30px $sp-8;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The padding value20px 0 30px $sp-8 mixes fixed pixel values with a variable$sp-8. Consider using consistent units for padding values to maintain uniformity and scalability.

display: flex;
align-items: center;
justify-content: center;
bottom: 50px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thebottom: 50px; value is a fixed pixel measurement. Consider using a variable or relative unit to ensure responsiveness and adaptability across different screen sizes.

}

export const TermsUsersPage: FC<Props> = (props: Props) => {
const [showDialogAddUser, setShowDialogAddUser] = useState<boolean>()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider initializingshowDialogAddUser with a default value likefalse instead ofundefined to avoid potential issues with undefined state.

export const TermsUsersPage: FC<Props> = (props: Props) => {
const [showDialogAddUser, setShowDialogAddUser] = useState<boolean>()
useAutoScrollTopWhenInit()
const { id = '' }: { id?: string } = useParams<{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The destructuring ofuseParams could be simplified by directly usingconst { id = '' } = useParams(); without specifying the type again, as TypeScript can infer the type from the hook.

icon={PlusIcon}
iconToLeft
label='Add User'
onClick={function onClick() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheonClick function can be simplified by using an arrow function:onClick={() => setShowDialogAddUser(true)}.

variant='danger'
disabled={!hasSelected || isRemovingBool}
size='lg'
onClick={function onClick() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheonClick function can be simplified by using an arrow function:onClick={() => doRemoveTermUsers(selectedDatasArray, unselectAll)}.

{showDialogAddUser && termInfo && (
<DialogAddTermUser
open
setOpen={function setOpen() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThesetOpen function can be simplified by using an arrow function:setOpen={() => { if (!isAdding) setShowDialogAddUser(false); }}.

onBlur={() => setStateHasFocus(false)}
onBlur={() => {
setStateHasFocus(false)
props.onBlur?.()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider adding a check to ensureprops.onBlur is a function before calling it. This can prevent potential runtime errors ifonBlur is not a function. For example, you could usetypeof props.onBlur === 'function' && props.onBlur().

@@ -156,6 +157,7 @@ const InputSelectReact: FC<InputSelectReactProps> = props => {
backspaceRemovesValue
isDisabled={props.disabled}
filterOption={props.filterOption}
isLoading={props.isLoading}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider providing a default value forprops.isLoading to avoid potential issues if the prop is not passed. This can be done by setting a default value in the component's defaultProps or using a default parameter in the function signature.

@@ -10,7 +10,6 @@
outline: none;
resize: vertical;
margin-left: calc(-1 * $border);
overflow: hidden;
padding: $border;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Removingoverflow: hidden; might cause the textarea to display scrollbars if the content exceeds the visible area. Ensure that this change aligns with the intended design and user experience for the textarea component.

@@ -5170,6 +5184,11 @@
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-4.0.7.tgz#400a76809fd08c2bbd9e25f3be06ea38c8e0a1d3"
integrity sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==

"@types/marked@^4.0.7":

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It seems like a new entry for@types/marked@^4.0.7 has been added. Ensure that this addition is intentional and necessary for the project, as it might introduce changes in type definitions that could affect the codebase.

gap: 10px;
}

.fieldAreaContainer {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The new class.fieldAreaContainer is added but not used in this diff. Ensure that it is utilized in the component or remove it if unnecessary.


import styles from './BundledEditor.module.scss'

export const BundledEditor: FC<any> = (props: any) => (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Usingany as the type forprops is not recommended because it defeats the purpose of TypeScript's type checking. Consider defining a specific type or interface for the props thatBundledEditor expects.

@@ -0,0 +1,78 @@
import { FC, FocusEvent, useEffect, useRef, useState } from 'react'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheuseRef hook is imported but not used in the current code. If it's not needed, consider removing it to keep the imports clean.


import { FormInputAutocompleteOption, InputWrapper } from '~/libs/ui'

import { BundledEditor } from './BundledEditor'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The import path for the editor component has changed from./Editor to./BundledEditor. Ensure thatBundledEditor provides the same functionality or intended improvements over the previousEditor component.

const FieldHtmlEditor: FC<FieldHtmlEditorProps> = (
props: FieldHtmlEditorProps,
) => {
const editorRef = useRef<any>(null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Usingany for theeditorRef type can lead to potential type safety issues. Consider specifying a more precise type for the ref, such asReact.RefObject<EditorType> whereEditorType is the expected type of the editor instance.

hideInlineErrors={props.hideInlineErrors}
>
<BundledEditor
onInit={function onInit(_evt: any, editor: any) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider specifying the types for_evt andeditor instead of usingany to improve type safety.

onInit={function onInit(_evt: any, editor: any) {
(editorRef.current = editor)
}}
onChange={function onChange() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

TheonChange function does not use the_evt parameter. Consider removing it if it's not needed.

+ '}',
height: 400,
menubar: false,
plugins: ['table', 'link', 'textcolor', 'contextmenu'],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thesource_view option is not a valid TinyMCE configuration option. Consider removing or correcting it.

import 'tinymce/skins/ui/oxide/skin' // Editor styles
import 'tinymce/skins/content/default/content' // Content styles, including inline UI like fake cursors
import 'tinymce/skins/ui/oxide/content'
import 'tinymce/plugins/table/plugin.min.js'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thetable plugin import has been moved but not commented out. Ensure this change is intentional and that the plugin is still required.

import 'tinymce/skins/content/default/content' // Content styles, including inline UI like fake cursors
import 'tinymce/skins/ui/oxide/content'
import 'tinymce/plugins/table/plugin.min.js'
import 'tinymce/plugins/link/plugin.min.js'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thelink plugin import has been moved but not commented out. Verify if this change is necessary and that the plugin is still needed.

import 'tinymce/skins/ui/oxide/content'
import 'tinymce/plugins/table/plugin.min.js'
import 'tinymce/plugins/link/plugin.min.js'
// import 'tinymce/plugins/advlist/plugin.min.js' // importing the plugin js.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Consider removing the commented-out imports if they are no longer needed to keep the code clean and maintainable.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@github-actionsgithub-actions[bot]github-actions[bot] left review comments

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

1 participant
@suppermancool

[8]ページ先頭

©2009-2025 Movatter.jp