-
Notifications
You must be signed in to change notification settings - Fork 16
[PROD RELEASE] - Q2 #1027
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
[PROD RELEASE] - Q2 #1027
Conversation
…loyment-docs PM-462 - update urls
PM-505 Fix default values on onboarding form
PM-505 Fix QA feedback
PM-553: fix breadcrumb url
PM-579 Add copilot request UI
PM-579 Change Restricted route logic
PM-579 Make buttons in form responsive
PM-579 QR feedback on copilot request form
V5 challenge management
@@ -43,6 +74,62 @@ const Table: <T extends { [propertyName: string]: any }>(props: TableProps<T>) = | |||
const [sortedData, setSortedData]: [ReadonlyArray<T>, Dispatch<SetStateAction<ReadonlyArray<T>>>] | |||
= useState<ReadonlyArray<T>>(props.data) | |||
|
|||
useEffect(() => { | |||
if (_.isEmpty(colWidthInput) && colWidthInput) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition _.isEmpty(colWidthInput) && colWidthInput
seems contradictory. If colWidthInput
is empty, it cannot simultaneously be truthy. Consider revising this condition to ensure it behaves as intended.
} | ||
}, 10) | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid disabling ESLint rules inline. Instead, consider refactoring the code to adhere to the rules or configure the rules appropriately in the ESLint configuration file.
} | ||
|
||
screenWidthBkRef.current = screenWidth | ||
// eslint-disable-next-line react-hooks/exhaustive-deps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid disabling ESLint rules inline. Instead, consider refactoring the code to adhere to the rules or configure the rules appropriately in the ESLint configuration file.
const isCurrentlySorted: boolean = isSortable && col.propertyName === sort?.fieldName | ||
const colorClass: string = isCurrentlySorted ? 'black-100' : 'black-60' | ||
const sortableClass: string | undefined = isSortable ? styles.sortable : undefined | ||
const columnId = `column-id-${col.columnId}-` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The columnId
variable is being used as a class name in line 204. Ensure that col.columnId
does not contain any characters that could lead to invalid class names or unintended styling issues.
const isCurrentlySorted: boolean = isSortable && col.propertyName === sort?.fieldName | ||
const colorClass: string = isCurrentlySorted ? 'black-100' : 'black-60' | ||
const sortableClass: string | undefined = isSortable ? styles.sortable : undefined | ||
const columnId = `column-id-${col.columnId}-` | ||
const colWidth = colWidthInput?.[columnId] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The colWidthInput
object is being accessed with columnId
as a key. Ensure that colWidthInput
is properly initialized and contains the expected keys to avoid potential undefined values.
data={sorted} | ||
allRows={sortedData} | ||
onRowClick={props.onRowClick} | ||
columns={props.columns} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The colWidthInput
variable is used here, but it is not clear from the diff if it has been defined or initialized. Ensure that colWidthInput
is properly defined and initialized before use.
<div className={styles['table-wrap']}> | ||
<table className={styles.table}> | ||
<div className={classNames(styles['table-wrap'], props.className)}> | ||
<table ref={tableRef} className={styles.table}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tableRef
is being added as a ref to the table element. Ensure that tableRef
is defined and initialized correctly, and that it is being used appropriately elsewhere in the component.
'TableCell_blockCell', | ||
)} | ||
onClick={onClick} | ||
style={props.style} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using inline styles with style={props.style}
can lead to performance issues and make it harder to maintain the code. Consider using a CSS class instead to apply styles.
}, [props.columns, props.showExpand]) | ||
// get the cells in the row | ||
const cells: Array<JSX.Element> = displayColumns.map((col, colIndex) => { | ||
const columnId = `column-id-${col.columnId}-` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The columnId
variable is constructed with a trailing hyphen (-
). Ensure that this is intentional and that the props.colWidth
object keys are structured to match this format. If not, this could lead to unexpected behavior or undefined values.
// get the cells in the row | ||
const cells: Array<JSX.Element> = displayColumns.map((col, colIndex) => { | ||
const columnId = `column-id-${col.columnId}-` | ||
const colWidth = props.colWidth?.[columnId] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The colWidth
variable is being accessed using a dynamic key. Ensure that props.colWidth
is properly initialized and contains the expected keys to avoid potential runtime errors.
<td colSpan={displayColumns.length}> | ||
<div className={styles.blockExpandContainer}> | ||
{expandColumns.map((col, colIndex) => { | ||
const columnId = `column-id-${col.columnId}-` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable columnId
is constructed using a template string, but it includes a trailing hyphen (-
). Ensure that this is intentional and that it aligns with the expected keys in props.colWidth
.
col.className, | ||
'TableCell_blockExpandValue', | ||
)} | ||
style={colWidth ? { width: `${colWidth}px` } : {}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inline style for width
is conditionally applied based on colWidth
. Consider verifying that colWidth
is always a valid number to prevent potential rendering issues. If colWidth
can be zero or negative, additional validation might be necessary.
|
||
import { Sort } from '../../../../../../apps/gamification-admin/src/game-lib/pagination' | ||
import { IconOutline } from '../../svgs' | ||
import { Button } from '../../button' | ||
|
||
import styles from './TableSort.module.scss' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import statement for styles
is added, but it is not used anywhere in the current diff. Ensure that styles
is utilized in the component or remove the import if it is unnecessary.
|
||
function handleClick(): void { | ||
props.toggleSort(props.propertyName as string) | ||
} | ||
|
||
return ( | ||
<Button | ||
className={props.iconClass} | ||
className={classNames(props.iconClass, 'TableSort', styles.btnSort)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The addition of styles.btnSort
to the className
prop suggests that there is a new style being applied. Ensure that styles.btnSort
is defined and correctly imported in this file to avoid any potential runtime errors.
} | ||
|
||
export function useWindowSize(): WindowSize { | ||
const [windowSize, setWindowSize]: [WindowSize, Dispatch<SetStateAction<WindowSize>>] = useState({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider initializing the windowSize
state with the current window dimensions instead of zeros. This will ensure that the initial state reflects the actual window size, which may prevent unnecessary re-renders.
|
||
// Remove event listener on cleanup | ||
return () => window.removeEventListener('resize', handleResize) | ||
}, [handleResize]) // Empty array ensures that effect is only run on mount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment 'Empty array ensures that effect is only run on mount' is misleading because the dependency array is not empty; it contains handleResize
. Consider updating the comment to accurately reflect the dependency array's contents.
version "11.1.0" | ||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" | ||
integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== | ||
|
||
uuid@^8.3.2: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two different versions of the 'uuid' package specified: '^11.1.0' and '^8.3.2'. Consider consolidating to a single version if possible to avoid potential conflicts or inconsistencies.
fix(PM-1313, PM-1309): project list and made new request form restricted route
authRequired: true, | ||
element: <CopilotsRequestForm />, | ||
id: 'CopilotRequestForm', | ||
rolesRequired: [UserRole.administrator, UserRole.projectManager] as UserRole[], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider checking if the rolesRequired
array is used consistently across the application to ensure that only users with the specified roles can access this route. If this is a new addition, verify that the role-checking logic is implemented correctly in the route handling.
@@ -0,0 +1,572 @@ | |||
import { FC, useContext, useMemo, useState } from 'react' | |||
import { bind, debounce, isEmpty } from 'lodash' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The debounce
function from lodash
is imported but not used in the code. Consider removing it if it's not needed to keep the code clean and maintainable.
InputRadio, InputSelect, InputSelectReact, InputText, InputTextarea } from '~/libs/ui' | ||
import { InputSkillSelector } from '~/libs/shared' | ||
|
||
import { getProjects } from '../../services/projects' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import statement for useProjects
has been removed and replaced with getProjects
. Ensure that the getProjects
function is correctly used in the code, and if useProjects
was used elsewhere, make sure to update those references as well.
const CopilotRequestForm: FC<{}> = () => { | ||
const { profile }: ProfileContextData = useContext(profileContext) | ||
|
||
const [formValues, setFormValues] = useState<any>({}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider specifying a more specific type for formValues
instead of using any
to improve type safety.
|
||
const [formValues, setFormValues] = useState<any>({}) | ||
const [isFormChanged, setIsFormChanged] = useState(false) | ||
const [formErrors, setFormErrors] = useState<any>({}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider specifying a more specific type for formErrors
instead of using any
to improve type safety.
const [isFormChanged, setIsFormChanged] = useState(false) | ||
const [formErrors, setFormErrors] = useState<any>({}) | ||
const [existingCopilot, setExistingCopilot] = useState<string>('') | ||
const [paymentType, setPaymentType] = useState<string>('') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider initializing existingCopilot
with a more descriptive default value or handling the case where it might be an empty string.
const [formErrors, setFormErrors] = useState<any>({}) | ||
const [existingCopilot, setExistingCopilot] = useState<string>('') | ||
const [paymentType, setPaymentType] = useState<string>('') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider initializing paymentType
with a more descriptive default value or handling the case where it might be an empty string.
label: string; | ||
value: string; | ||
}>> { | ||
const response = await getProjects(inputValue) |
There was a problem hiding this comment.
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 the getProjects
call to manage potential API failures gracefully.
setFormErrors(updatedFormErrors) | ||
} | ||
|
||
const debouncedProjectSearch = useMemo(() => debounce((inputValue: string, callback: (options: any[]) => void) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The debounce
function is being used here, but it's not clear if it has been imported from a utility library like lodash. Ensure that debounce
is correctly imported to avoid runtime errors.
setFormErrors(updatedFormErrors) | ||
} | ||
|
||
const debouncedProjectSearch = useMemo(() => debounce((inputValue: string, callback: (options: any[]) => void) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a dependency array to the useMemo
hook if there are any dependencies that should trigger a recalculation of the debounced function. Currently, it is set to an empty array, which means the function will only be created once and never updated.
tabIndex={0} | ||
value={formValues.projectId || ''} | ||
onChange={handleProjectSelect} | ||
loadOptions={debouncedProjectSearch} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The async
prop is not a valid prop for the InputSelectReact
component. If this is intended to be an asynchronous select, ensure that the component supports this functionality or use a compatible component.
value={formValues.projectId || ''} | ||
onChange={handleProjectSelect} | ||
loadOptions={debouncedProjectSearch} | ||
async |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming debouncedProjectSearch
to something more descriptive, such as fetchProjectOptions
, to clarify its purpose in loading options asynchronously.
}) | ||
} | ||
|
||
export const getProjects = (search?: string, filter?: any): Promise<Project[]> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider specifying a more precise type instead of any
for the filter
parameter to improve type safety and maintainability.
} | ||
|
||
export const getProjects = (search?: string, filter?: any): Promise<Project[]> => { | ||
const params = { name: `"${search}"`, ...filter } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that the search
parameter is properly sanitized to prevent potential injection attacks, especially since it is being directly included in the params
object.
|
||
export const getProjects = (search?: string, filter?: any): Promise<Project[]> => { | ||
const params = { name: `"${search}"`, ...filter } | ||
const url = buildUrl(baseUrl, params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verify that the buildUrl
function correctly handles and encodes the params
object to prevent malformed URLs or security vulnerabilities.
@@ -8,6 +8,8 @@ import { | |||
useRef, | |||
} from 'react' | |||
import { find } from 'lodash' | |||
import AsyncCreatable from 'react-select/async-creatable' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider checking if the AsyncCreatable
component is necessary for your use case. If not, it might be better to remove unused imports to keep the code clean.
@@ -8,6 +8,8 @@ import { | |||
useRef, | |||
} from 'react' | |||
import { find } from 'lodash' | |||
import AsyncCreatable from 'react-select/async-creatable' | |||
import AsyncSelect from 'react-select/async' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that AsyncSelect
is used in the component. If it is not used, consider removing it to avoid unnecessary imports.
@@ -31,7 +34,8 @@ interface InputSelectReactProps { | |||
readonly label?: string | |||
readonly name: string | |||
readonly onChange: (event: ChangeEvent<HTMLInputElement>) => void | |||
readonly options: OptionsOrGroups<unknown, GroupBase<unknown>> | |||
readonly onInputChange?: (newValue: string) => void | |||
readonly options?: OptionsOrGroups<unknown, GroupBase<unknown>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion
Making options
optional (options?:
) could lead to potential issues if the component relies on this prop being present. Consider adding validation or default handling within the component to manage cases where options
might be undefined
. This will help prevent runtime errors if the component attempts to access properties of options
without checking for its presence.
@@ -41,6 +45,8 @@ interface InputSelectReactProps { | |||
readonly onBlur?: (event: FocusEvent<HTMLInputElement>) => void | |||
readonly openMenuOnClick?: boolean | |||
readonly openMenuOnFocus?: boolean | |||
readonly async?: boolean | |||
readonly loadOptions?: (inputValue: string, callback: (option: any) => void) => void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider specifying the type for the option
parameter in the loadOptions
callback to improve type safety and clarity.
props.creatable ? CreatableSelect : ReactSelect | ||
), [props.creatable]) | ||
const Input = useMemo(() => { | ||
if (props.async) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a type annotation for the Input
constant to ensure type safety and improve code readability.
@@ -137,7 +152,9 @@ const InputSelectReact: FC<InputSelectReactProps> = props => { | |||
styles.select, | |||
) | |||
} | |||
loadOptions={props.loadOptions} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that loadOptions
is a function and properly handles errors or edge cases when fetching options. Consider adding validation or error handling logic if necessary.
fix(PM-1273): show apply copilot only for projects where user is not a member
startDate: Date, | ||
tzRestrictions: 'yes' | 'no', | ||
createdAt: Date, | ||
members: Array<number>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using number[]
instead of Array<number>
for consistency and readability, as it is more commonly used in TypeScript.
&& copilotApplications | ||
&& copilotApplications.length === 0 | ||
&& opportunity?.status === 'active' | ||
&& !isAlreadyMemberOfTheProject ? applyCopilotOpportunityButton : undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming isAlreadyMemberOfTheProject
to isNotAlreadyMemberOfTheProject
or adjusting the logic to improve readability, as the current negation can be confusing.
Includes work on: