-
Notifications
You must be signed in to change notification settings - Fork 3
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
Moving inboxsearchcomposerV2 #46
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThe updates involve significant changes across various React components and configuration files within a project. Key changes include version updates for dependencies, the introduction of new components like Changes
Recent Review DetailsConfiguration used: CodeRabbit UI Files selected for processing (39)
Files not reviewed due to errors (1)
Files skipped from review due to trivial changes (5)
Additional comments not posted (60)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
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.
Actionable comments posted: 22
@@ -1,6 +1,6 @@ | |||
import React, { useEffect, useReducer, useState, useMemo } from "react"; | |||
import React, { useEffect, useReducer, useState,useMemo } from "react"; |
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 removing unused imports to keep the code clean.
if (Object.keys(state.searchForm)?.length >= 0) { | ||
const result = { ..._.get(apiDetails, apiDetails?.searchFormJsonPath, {}), ...state.searchForm } | ||
Object.keys(result).forEach(key => { | ||
if (!result[key]) delete result[key] | ||
}); | ||
_.set(apiDetails, apiDetails?.searchFormJsonPath, result) | ||
} | ||
if (Object.keys(state.filterForm)?.length >= 0) { | ||
const result = { ..._.get(apiDetails, apiDetails?.filterFormJsonPath, {}), ...state.filterForm } | ||
Object.keys(result).forEach(key => { | ||
if (!result[key] || result[key]?.length===0) delete result[key] | ||
}); | ||
_.set(apiDetails, apiDetails?.filterFormJsonPath, result) | ||
} | ||
|
||
if(Object.keys(state.tableForm)?.length >= 0) { | ||
_.set(apiDetails, apiDetails?.tableFormJsonPath, { ..._.get(apiDetails, apiDetails?.tableFormJsonPath, {}),...state.tableForm }) | ||
} |
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.
Optimize the handling of form data in state updates to avoid potential performance issues with large data sets.
const updatedReqCriteria = Digit?.Customizations?.[apiDetails?.masterName]?.[apiDetails?.moduleName]?.preProcess ? Digit?.Customizations?.[apiDetails?.masterName]?.[apiDetails?.moduleName]?.preProcess(requestCriteria,configs.additionalDetails) : requestCriteria | ||
|
||
if(configs.customHookName){ | ||
var { isLoading, data, revalidate,isFetching,refetch,error } = eval(`Digit.Hooks.${configs.customHookName}(updatedReqCriteria)`); | ||
} | ||
if (Object.keys(state.filterForm)?.length >= 0) { | ||
const result = { ..._.get(apiDetails, apiDetails?.filterFormJsonPath, {}), ...state.filterForm }; | ||
Object.keys(result).forEach((key) => { | ||
if (!result[key] || result[key]?.length === 0) delete result[key]; | ||
}); | ||
_.set(apiDetails, apiDetails?.filterFormJsonPath, result); | ||
else { | ||
var { isLoading, data, revalidate,isFetching,error } = Digit.Hooks.useCustomAPIHook(updatedReqCriteria); | ||
|
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 handling errors from the custom hook more robustly, especially in production environments.
@@ -1,346 +1,368 @@ | |||
import React from "react"; | |||
import React from 'react'; |
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.
Use consistent import quotes.
Please ensure that all import statements use single quotes for consistency as per the project's coding standards.
t={t} | ||
setValue={setValue} | ||
onSelect={setValue} | ||
config={config} | ||
data={formData} | ||
formData={formData} | ||
register={register} | ||
errors={errors} | ||
props={props} | ||
setError={setError} | ||
clearErrors={clearErrors} | ||
onBlur={props.onBlur} | ||
control={control} | ||
getValues={getValues} | ||
responseData={data} | ||
populators={populators} | ||
/> | ||
)} | ||
name={config?.key} | ||
control={control} | ||
/> | ||
); | ||
}} | ||
/> | ||
); | ||
case "dateRange": | ||
return ( | ||
<Controller | ||
render={(props) => ( | ||
<DateRangeNew | ||
t={t} | ||
values={formData?.[populators?.name]?.range} | ||
name={populators?.name} | ||
onFilterChange={props.onChange} | ||
inputRef={props.ref} | ||
errorStyle={errors?.[populators?.name]} | ||
/> | ||
)} | ||
rules={{ required: isMandatory, ...populators.validation }} | ||
defaultValue={formData?.[populators?.name]} | ||
name={populators?.name} | ||
control={control} | ||
/> | ||
); | ||
|
||
case "component": | ||
return ( | ||
<Controller | ||
render={(props) => ( | ||
<Component | ||
userType={"employee"} | ||
t={t} | ||
setValue={setValue} | ||
onSelect={setValue} | ||
config={config} | ||
data={formData} | ||
formData={formData} | ||
register={register} | ||
errors={errors} | ||
props={props} | ||
setError={setError} | ||
clearErrors={clearErrors} | ||
onBlur={props.onBlur} | ||
control={control} | ||
getValues={getValues} | ||
responseData={data} | ||
/> | ||
)} | ||
name={config?.key} | ||
control={control} | ||
/> | ||
); | ||
|
||
default: | ||
return populators?.dependency !== false ? populators : null; | ||
} | ||
}; | ||
|
||
return ( | ||
<React.Fragment> | ||
{fields?.map((item, index) => { | ||
return ( | ||
<LabelFieldPair key={index} style={{ display: "flex", flexDirection: "column" ,alignItems:"flex-start"}}> | ||
{item.label && ( | ||
<CardLabel style={{ ...props.labelStyle, marginBottom: "0.4rem" }}> | ||
{t(item.label)} | ||
{item?.isMandatory ? " * " : null} | ||
</CardLabel> | ||
)} | ||
|
||
{fieldSelector(item.type, item.populators, item.isMandatory, item?.disable, item?.component, item)} | ||
|
||
{item?.populators?.name && errors && errors[item?.populators?.name] && Object.keys(errors[item?.populators?.name]).length ? ( | ||
<CardLabelError style={{ fontSize: "12px", marginTop: "-20px" }}>{t(item?.populators?.error)}</CardLabelError> | ||
) : null} | ||
|
||
default: | ||
return populators?.dependency !== false ? populators : null; | ||
} | ||
}; |
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.
Refactor fieldSelector
for maintainability.
The fieldSelector
function is quite lengthy and handles many cases, which can make it difficult to maintain and extend. Consider breaking it down into smaller, more manageable functions, each handling a specific field type. This will improve readability and maintainability.
- const fieldSelector = (type, populators, isMandatory, disable = false, component, config) => {
+ const handleTextInput = (type, populators, isMandatory, disable, component, config) => {
+ // Logic for text input
+ }
+ const handleTextArea = (type, populators, isMandatory, disable, component, config) => {
+ // Logic for textarea
+ }
+ const fieldSelector = (type, populators, isMandatory, disable = false, component, config) => {
+ switch (type) {
+ case "text":
+ case "number":
+ case "password":
+ case "time":
+ return handleTextInput(type, populators, isMandatory, disable, component, config);
+ case "textarea":
+ return handleTextArea(type, populators, isMandatory, disable, component, config);
+ // other cases
+ }
+ }
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const fieldSelector = (type, populators, isMandatory, disable = false, component, config) => { | |
const Component = typeof component === "string" ? Digit.ComponentRegistryService.getComponent(component) : component; | |
let customValidations = config?.additionalValidation ? Digit?.Customizations?.[apiDetails?.masterName]?.[apiDetails?.moduleName]?.additionalValidations(config?.additionalValidation?.type, formData, config?.additionalValidation?.keys) : null | |
const customRules = customValidations ? { validate: customValidations} : {} | |
switch (type) { | |
case "date": | |
case "text": | |
case "number": | |
case "password": | |
case "time": | |
return ( | |
<Controller | |
defaultValue={formData?.[populators.name]} | |
render={({ onChange, ref, value }) => ( | |
<TextInput | |
value={formData?.[populators.name]} | |
type={type} | |
name={populators.name} | |
onChange={onChange} | |
inputRef={ref} | |
errorStyle={errors?.[populators.name]} | |
max={populators.max} | |
disable={disable} | |
style={type === "date" ? { paddingRight: "3px" } : populators?.style ? {...populators?.style} : {}} | |
maxlength={populators?.validation?.maxlength} | |
minlength={populators?.validation?.minlength} | |
/> | |
)} | |
name={populators.name} | |
rules={{required: isMandatory, ...populators.validation, ...customRules }} | |
control={control} | |
/> | |
); | |
case "textarea": | |
return ( | |
<Controller | |
defaultValue={formData?.[populators.name]} | |
render={({ onChange, ref, value }) => ( | |
<TextArea | |
className="field" | |
value={formData?.[populators.name]} | |
type={type} | |
name={populators.name} | |
onChange={onChange} | |
inputRef={ref} | |
disable={disable} | |
errorStyle={errors?.[populators.name]} | |
/> | |
)} | |
name={populators.name} | |
rules={{ required: isMandatory, ...populators.validation }} | |
control={control} | |
/> | |
)} | |
name={populators?.name} | |
rules={{ required: isMandatory, ...populators.validation, ...customRules }} | |
control={control} | |
/> | |
); | |
case "textarea": | |
return ( | |
<Controller | |
defaultValue={formData?.[populators?.name]} | |
render={({ onChange, ref, value }) => ( | |
<TextArea | |
className="field" | |
value={formData?.[populators?.name]} | |
type={type} | |
); | |
case "mobileNumber": | |
return ( | |
<Controller | |
render={(props) => ( | |
<MobileNumber | |
inputRef={props.ref} | |
className="field fullWidth" | |
onChange={props.onChange} | |
value={props.value} | |
disable={disable} | |
{...props} | |
errorStyle={errors?.[populators.name]} | |
/> | |
)} | |
defaultValue={populators.defaultValue} | |
name={populators?.name} | |
onChange={onChange} | |
inputRef={ref} | |
disabled={disable} | |
errorStyle={errors?.[populators?.name]} | |
/> | |
)} | |
name={populators?.name} | |
rules={{ required: isMandatory, ...populators.validation }} | |
control={control} | |
/> | |
); | |
case "mobileNumber": | |
return ( | |
<Controller | |
render={(props) => ( | |
<MobileNumber | |
inputRef={props.ref} | |
className="field fullWidth" | |
onChange={props.onChange} | |
value={props.value} | |
disable={disable} | |
{...props} | |
errorStyle={errors?.[populators?.name]} | |
rules={{ required: isMandatory, ...populators.validation }} | |
control={control} | |
/> | |
)} | |
defaultValue={populators.defaultValue} | |
name={populators?.name} | |
rules={{ required: isMandatory, ...populators.validation }} | |
control={control} | |
/> | |
); | |
case "multiupload": | |
return ( | |
<Controller | |
name={`${populators?.name}`} | |
control={control} | |
rules={{ required: false }} | |
render={({ onChange, ref, value = [] }) => { | |
function getFileStoreData(filesData) { | |
const numberOfFiles = filesData.length; | |
let finalDocumentData = []; | |
if (numberOfFiles > 0) { | |
filesData.forEach((value) => { | |
finalDocumentData.push({ | |
fileName: value?.[0], | |
fileStoreId: value?.[1]?.fileStoreId?.fileStoreId, | |
documentType: value?.[1]?.file?.type, | |
}); | |
}); | |
} | |
onChange(numberOfFiles > 0 ? filesData : []); | |
} | |
); | |
case "multiupload": | |
return ( | |
<Controller | |
name={`${populators.name}`} | |
control={control} | |
rules={{ required: false }} | |
render={({ onChange, ref, value = [] }) => { | |
function getFileStoreData(filesData) { | |
const numberOfFiles = filesData.length; | |
let finalDocumentData = []; | |
if (numberOfFiles > 0) { | |
filesData.forEach((value) => { | |
finalDocumentData.push({ | |
fileName: value?.[0], | |
fileStoreId: value?.[1]?.fileStoreId?.fileStoreId, | |
documentType: value?.[1]?.file?.type, | |
}); | |
}); | |
} | |
onChange(numberOfFiles>0?filesData:[]); | |
} | |
return ( | |
<MultiUploadWrapper | |
t={t} | |
module="works" | |
tenantId={Digit.ULBService.getCurrentTenantId()} | |
getFormState={getFileStoreData} | |
showHintBelow={populators?.showHintBelow ? true : false} | |
setuploadedstate={value} | |
allowedFileTypesRegex={populators.allowedFileTypes} | |
allowedMaxSizeInMB={populators.allowedMaxSizeInMB} | |
hintText={populators.hintText} | |
maxFilesAllowed={populators.maxFilesAllowed} | |
extraStyleName={{ padding: "0.5rem" }} | |
customClass={populators?.customClass} | |
/> | |
); | |
}} | |
/> | |
); | |
case "custom": | |
return ( | |
<Controller | |
render={(props) => populators.component({ ...props, setValue }, populators.customProps)} | |
defaultValue={populators.defaultValue} | |
name={populators?.name} | |
control={control} | |
/> | |
); | |
case "radio": | |
case "dropdown": | |
return ( | |
<Controller | |
render={(props) => ( | |
<CustomDropdown | |
t={t} | |
label={config?.label} | |
type={type} | |
onBlur={props.onBlur} | |
value={props.value} | |
inputRef={props.ref} | |
onChange={props.onChange} | |
config={populators} | |
disable={config?.disable} | |
errorStyle={errors?.[populators.name]} | |
mdmsv2={populators.mdmsv2 ? populators.mdmsv2 : false } | |
props={props} | |
/> | |
)} | |
rules={{ required: isMandatory, ...populators.validation }} | |
defaultValue={formData?.[populators.name]} | |
name={populators?.name} | |
control={control} | |
/> | |
); | |
case "multiselectdropdown": | |
return ( | |
<MultiUploadWrapper | |
t={t} | |
module="works" | |
tenantId={Digit.ULBService.getCurrentTenantId()} | |
getFormState={getFileStoreData} | |
showHintBelow={populators?.showHintBelow ? true : false} | |
setuploadedstate={value} | |
allowedFileTypesRegex={populators.allowedFileTypes} | |
allowedMaxSizeInMB={populators.allowedMaxSizeInMB} | |
hintText={populators.hintText} | |
maxFilesAllowed={populators.maxFilesAllowed} | |
extraStyleName={{ padding: "0.5rem" }} | |
customClass={populators?.customClass} | |
<Controller | |
name={`${populators.name}`} | |
control={control} | |
defaultValue={formData?.[populators.name]} | |
rules={{ required: populators?.isMandatory }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<MultiSelectDropdown | |
options={populators?.options} | |
optionsKey={populators?.optionsKey} | |
props={props} | |
isPropsNeeded={true} | |
onSelect={(e) => { | |
props.onChange(e?.map(row=>{return row?.[1] ? row[1] : null}).filter(e=>e)) | |
}} | |
selected={props?.value} | |
defaultLabel={t(populators?.defaultText)} | |
defaultUnit={t(populators?.selectedText)} | |
config={populators} | |
/> | |
</div> | |
); | |
}} | |
/> | |
); | |
}} | |
/> | |
); | |
case "custom": | |
return ( | |
<Controller | |
render={(props) => populators.component({ ...props, setValue }, populators.customProps)} | |
defaultValue={populators.defaultValue} | |
name={populators?.name} | |
control={control} | |
/> | |
); | |
case "radio": | |
case "dropdown": | |
return ( | |
<Controller | |
render={(props) => ( | |
<CustomDropdown | |
t={t} | |
label={config?.label} | |
type={type} | |
onBlur={props.onBlur} | |
value={props.value} | |
inputRef={props.ref} | |
onChange={props.onChange} | |
config={populators} | |
disable={config?.disable} | |
errorStyle={errors?.[populators?.name]} | |
/> | |
)} | |
rules={{ required: isMandatory, ...populators.validation }} | |
defaultValue={formData?.[populators?.name]} | |
name={populators?.name} | |
control={control} | |
/> | |
); | |
case "multiselectdropdown": | |
return ( | |
<Controller | |
name={`${populators?.name}`} | |
control={control} | |
defaultValue={formData?.[populators?.name]} | |
rules={{ required: populators?.isMandatory }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<MultiSelectDropdown | |
options={populators?.options} | |
optionsKey={populators?.optionsKey} | |
props={props} | |
isPropsNeeded={true} | |
onSelect={(e) => { | |
props.onChange( | |
e | |
?.map((row) => { | |
return row?.[1] ? row[1] : null; | |
}) | |
.filter((e) => e) | |
case "locationdropdown": | |
return ( | |
<Controller | |
name={`${populators.name}`} | |
control={control} | |
defaultValue={formData?.[populators.name]} | |
rules={{ required: populators?.isMandatory, ...populators.validation }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<LocationDropdownWrapper | |
props={props} | |
populators={populators} | |
formData={formData} | |
inputRef={props.ref} | |
errors={errors} | |
setValue={setValue} | |
/> | |
</div> | |
); | |
}} | |
selected={props?.value} | |
defaultLabel={t(populators?.defaultText)} | |
defaultUnit={t(populators?.selectedText)} | |
config={populators} | |
/> | |
</div> | |
); | |
}} | |
/> | |
); | |
case "locationdropdown": | |
return ( | |
<Controller | |
name={`${populators?.name}`} | |
control={control} | |
defaultValue={formData?.[populators?.name]} | |
rules={{ required: populators?.isMandatory, ...populators.validation }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" ,width:"100%"}}> | |
<LocationDropdownWrapper | |
props={props} | |
populators={populators} | |
formData={formData} | |
inputRef={props.ref} | |
errors={errors} | |
setValue={setValue} | |
); | |
case "apidropdown": | |
return ( | |
<Controller | |
name={`${populators.name}`} | |
control={control} | |
defaultValue={formData?.[populators.name]} | |
rules={{ required: populators?.isMandatory, ...populators.validation }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<ApiDropdown | |
props={props} | |
populators={populators} | |
formData={formData} | |
inputRef={props.ref} | |
errors={errors} | |
/> | |
</div> | |
); | |
}} | |
/> | |
</div> | |
); | |
}} | |
/> | |
); | |
case "apidropdown": | |
return ( | |
<Controller | |
name={`${populators?.name}`} | |
control={control} | |
defaultValue={formData?.[populators?.name]} | |
rules={{ required: populators?.isMandatory, ...populators.validation }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<ApiDropdown props={props} populators={populators} formData={formData} inputRef={props.ref} errors={errors} /> | |
</div> | |
); | |
}} | |
/> | |
); | |
case "workflowstatesfilter": | |
return ( | |
<Controller | |
name={`${populators?.name}`} | |
control={control} | |
defaultValue={formData?.[populators?.name]} | |
rules={{ required: populators?.isMandatory }} | |
render={(props) => { | |
); | |
case "apicheckboxes": | |
return ( | |
<Controller | |
name={`${populators.name}`} | |
control={control} | |
defaultValue={formData?.[populators.name]} | |
rules={{ required: populators?.isMandatory, ...populators.validation }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<ApiCheckboxes | |
props={props} | |
populators={populators} | |
formData={formData} | |
inputRef={props.ref} | |
errors={errors} | |
/> | |
</div> | |
); | |
}} | |
/> | |
); | |
case "workflowstatesfilter": | |
return ( | |
<Controller | |
name={`${populators.name}`} | |
control={control} | |
defaultValue={formData?.[populators.name]} | |
rules={{ required: populators?.isMandatory }} | |
render={(props) => { | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<WorkflowStatusFilter | |
inboxResponse={data} | |
props={props} | |
populators={populators} | |
t={t} | |
formData={formData} | |
/> | |
</div> | |
); | |
}} | |
/> | |
); | |
case "dateRange": | |
return ( | |
<Controller | |
render={(props) => ( | |
<DateRangeNew | |
t={t} | |
values={formData?.[populators.name]?.range} | |
name={populators.name} | |
onFilterChange={props.onChange} | |
inputRef={props.ref} | |
errorStyle={errors?.[populators.name]} | |
populators={populators} | |
/> | |
)} | |
rules={{ required: isMandatory, ...populators.validation }} | |
defaultValue={formData?.[populators.name]} | |
name={populators?.name} | |
control={control} | |
/> | |
); | |
case "component": | |
return ( | |
<div style={{ display: "grid", gridAutoFlow: "row" }}> | |
<WorkflowStatusFilter inboxResponse={data} props={props} populators={populators} t={t} formData={formData} /> | |
</div> | |
<Controller | |
render={(props) => ( | |
<Component | |
userType={"employee"} | |
t={t} | |
setValue={setValue} | |
onSelect={setValue} | |
config={config} | |
data={formData} | |
formData={formData} | |
register={register} | |
errors={errors} | |
props={props} | |
setError={setError} | |
clearErrors={clearErrors} | |
onBlur={props.onBlur} | |
control={control} | |
getValues={getValues} | |
responseData={data} | |
populators={populators} | |
/> | |
)} | |
name={config?.key} | |
control={control} | |
/> | |
); | |
}} | |
/> | |
); | |
case "dateRange": | |
return ( | |
<Controller | |
render={(props) => ( | |
<DateRangeNew | |
t={t} | |
values={formData?.[populators?.name]?.range} | |
name={populators?.name} | |
onFilterChange={props.onChange} | |
inputRef={props.ref} | |
errorStyle={errors?.[populators?.name]} | |
/> | |
)} | |
rules={{ required: isMandatory, ...populators.validation }} | |
defaultValue={formData?.[populators?.name]} | |
name={populators?.name} | |
control={control} | |
/> | |
); | |
case "component": | |
return ( | |
<Controller | |
render={(props) => ( | |
<Component | |
userType={"employee"} | |
t={t} | |
setValue={setValue} | |
onSelect={setValue} | |
config={config} | |
data={formData} | |
formData={formData} | |
register={register} | |
errors={errors} | |
props={props} | |
setError={setError} | |
clearErrors={clearErrors} | |
onBlur={props.onBlur} | |
control={control} | |
getValues={getValues} | |
responseData={data} | |
/> | |
)} | |
name={config?.key} | |
control={control} | |
/> | |
); | |
default: | |
return populators?.dependency !== false ? populators : null; | |
} | |
}; | |
return ( | |
<React.Fragment> | |
{fields?.map((item, index) => { | |
return ( | |
<LabelFieldPair key={index} style={{ display: "flex", flexDirection: "column" ,alignItems:"flex-start"}}> | |
{item.label && ( | |
<CardLabel style={{ ...props.labelStyle, marginBottom: "0.4rem" }}> | |
{t(item.label)} | |
{item?.isMandatory ? " * " : null} | |
</CardLabel> | |
)} | |
{fieldSelector(item.type, item.populators, item.isMandatory, item?.disable, item?.component, item)} | |
{item?.populators?.name && errors && errors[item?.populators?.name] && Object.keys(errors[item?.populators?.name]).length ? ( | |
<CardLabelError style={{ fontSize: "12px", marginTop: "-20px" }}>{t(item?.populators?.error)}</CardLabelError> | |
) : null} | |
default: | |
return populators?.dependency !== false ? populators : null; | |
} | |
}; | |
const handleTextInput = (type, populators, isMandatory, disable, component, config) => { | |
// Logic for text input | |
} | |
const handleTextArea = (type, populators, isMandatory, disable, component, config) => { | |
// Logic for textarea | |
} | |
const fieldSelector = (type, populators, isMandatory, disable = false, component, config) => { | |
switch (type) { | |
case "text": | |
case "number": | |
case "password": | |
case "time": | |
return handleTextInput(type, populators, isMandatory, disable, component, config); | |
case "textarea": | |
return handleTextArea(type, populators, isMandatory, disable, component, config); | |
// other cases | |
} | |
} |
<div className={`multi-select-dropdown-wrap ${disable ? "disabled" : ""}`} ref={dropdownRef}> | ||
<div className={`master${active ? `-active` : ``} ${disable ? "disabled" : ""}`}> | ||
<input className="cursorPointer" type="text" onKeyDown={keyChange} onFocus={() => setActive(true)} value={searchQuery} onChange={onSearch} placeholder={t(placeholder)} /> | ||
<div className="label"></div> | ||
<p>{alreadyQueuedSelectedState.length > 0 ? `${isSurvey ? alreadyQueuedSelectedState?.filter((ob) => ob?.i18nKey !== undefined).length : alreadyQueuedSelectedState.length} ${defaultUnit}` : defaultLabel}</p> | ||
<ArrowDown disable={disable} /> | ||
</div> | ||
{config?.isDropdownWithChip ? ( | ||
<div className="digit-tag-container"> | ||
{alreadyQueuedSelectedState.length > 0 && | ||
alreadyQueuedSelectedState.map((value, index) => { | ||
if (!value.propsData[1]?.options) { | ||
const translatedText = t(value.code); | ||
const replacedText = replaceDotWithColon(translatedText); | ||
return ( | ||
<RemoveableTag | ||
key={index} | ||
text={replacedText.length > 64 ? `${replacedText.slice(0, 64)}...` : replacedText} | ||
onClick={ | ||
variant === "treemultiselect" | ||
? () => onSelectToAddToQueue([value]) | ||
: isPropsNeeded | ||
? (e) => onSelectToAddToQueue(e, value, props) | ||
: (e) => onSelectToAddToQueue(e, value) | ||
} | ||
className="multiselectdropdown-tag" | ||
/> | ||
); | ||
} | ||
return null; | ||
})} | ||
{alreadyQueuedSelectedState.length > 0 && ( | ||
<Button | ||
label={t(config?.clearLabel ? config?.clearLabel : "Clear All")} | ||
onClick={handleClearAll} | ||
variation="" | ||
style={{ | ||
height: "2rem", | ||
minWidth: "4.188rem", | ||
minHeight: "2rem", | ||
padding: "0.5rem", | ||
justifyContent: "center", | ||
alignItems: "center", | ||
borderRadius: "3.125rem", | ||
border: "1px solid #F47738", | ||
background: "#FAFAFA", | ||
}} | ||
textStyles={{ height: "auto", fontSize: "0.875rem", fontWeight: "400", width: "100%", lineHeight: "16px", color: "#F47738" }} | ||
/> | ||
)} | ||
</div> | ||
) : null} | ||
{active ? | ||
( | ||
<div className="server" id="jk-dropdown-unique" style={ServerStyle ? ServerStyle : {}}> | ||
<Menu /> | ||
</div> | ||
) : null | ||
} |
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 main return block of the component is complex and includes inline conditional logic. Simplify this by breaking down into smaller components or using more descriptive helper functions.
{showHint && <p className="cell-text">{t(props?.hintText)}</p>} | ||
<div className={`upload-file ${user_type === "employee" ? "" : "upload-file-max-width"} ${props.disabled ? " disabled" : ""}`} style={extraStyles?.uploadFile ? extraStyles?.uploadFile : {}}> |
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 rendering logic in the return statement is complex and includes multiple conditional renderings. Consider simplifying this by breaking it down into smaller components or using more descriptive helper functions.
<div className="options-card date-range" style={{ overflow: "visible", width: "unset"}}> | ||
<DateRange | ||
className="pickerShadow" | ||
focusedRange={focusedRange} | ||
ranges={[selectionRange]} | ||
rangeColors={["#F47738"]} | ||
onChange={handleSelect} | ||
onRangeFocusChange={setFocusedRange} | ||
retainEndDateOnFirstSelection={true} | ||
showSelectionPreview={true} | ||
staticRanges={staticRanges} | ||
inputRanges={[]} | ||
weekStartsOn={1} | ||
maxDate={populators?.maxDate} | ||
minDate={populators?.minDate} | ||
startDatePlaceholder={t("EVENTS_START_DATE_LABEL")} | ||
endDatePlaceholder={t("EVENTS_END_DATE_LABEL")} | ||
/> | ||
</div> |
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 rendering logic for the modal component is complex and includes inline conditional logic. Consider simplifying this by breaking it down into smaller components or using more descriptive helper functions.
const renderHeader = () => { | ||
switch (uiConfig?.typeMobile) { | ||
case "filter": { | ||
return ( | ||
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | ||
<span className="header" style={{ display: "flex" }}> | ||
<span className="icon" style={{ marginRight: "12px", marginTop: "5px", paddingBottom: "3px" }}><FilterIcon /></span> | ||
<span style={{ fontSize: "1.5rem", fontWeight: "700", marginRight: "12px" }}>{t(`${uiConfig?.headerLabel || "TQM_INBOX_SORTBY"}`)}</span> | ||
<span className="clear-search refresh-icon-container" onClick={clearSearch}><RefreshIcon /></span> | ||
</span> | ||
<span onClick={onClose}> | ||
<CloseSvg /> | ||
</span> | ||
</div> | ||
); | ||
} | ||
case "sort": { | ||
return ( | ||
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | ||
<span className="header" style={{ display: "flex" }}> | ||
<span className="icon" style={{ marginRight: "12px", marginTop: "5px", paddingBottom: "3px" }}><SortSvg /></span> | ||
<span style={{ fontSize: "1.5rem", fontWeight: "700", marginRight: "12px" }}>{t(`${uiConfig?.headerLabel || "TQM_INBOX_SORTBY"}`)}</span> | ||
<span className="clear-search refresh-icon-container" onClick={clearSearch}><RefreshIcon /></span> | ||
</span> | ||
<span onClick={onClose}> | ||
<CloseSvg /> | ||
</span> | ||
</div> | ||
); | ||
} | ||
case "search": { | ||
return ( | ||
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | ||
<span className="header" style={{ display: "flex" }}> | ||
<span className="icon" style={{ marginRight: "12px", marginTop: "5px" }}><SearchIcon /></span> | ||
<span style={{ fontSize: "large" }}>{t(`${uiConfig?.headerLabel || "TQM_INBOX_SORTBY"}`)}</span> | ||
</span> | ||
<span onClick={onClose}> | ||
<CloseSvg /> | ||
</span> | ||
</div> | ||
); | ||
} |
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 renderHeader
function includes complex conditional rendering based on the uiConfig.typeMobile
. Consider refactoring this to simplify the logic and improve readability.
- switch (uiConfig?.typeMobile) {
+ const headerDetails = getHeaderDetails(uiConfig?.typeMobile);
+ return (
+ <div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}>
+ <span className="header" style={{ display: "flex" }}>
+ <span className="icon" style={{ marginRight: "12px", marginTop: "5px", paddingBottom: "3px" }}>{headerDetails.icon}</span>
+ <span style={{ fontSize: "1.5rem", fontWeight: "700", marginRight: "12px" }}>{t(headerDetails.label)}</span>
+ <span className="clear-search refresh-icon-container" onClick={clearSearch}><RefreshIcon /></span>
+ </span>
+ <span onClick={onClose}>
+ <CloseSvg />
+ </span>
+ </div>
+ );
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const renderHeader = () => { | |
switch (uiConfig?.typeMobile) { | |
case "filter": { | |
return ( | |
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | |
<span className="header" style={{ display: "flex" }}> | |
<span className="icon" style={{ marginRight: "12px", marginTop: "5px", paddingBottom: "3px" }}><FilterIcon /></span> | |
<span style={{ fontSize: "1.5rem", fontWeight: "700", marginRight: "12px" }}>{t(`${uiConfig?.headerLabel || "TQM_INBOX_SORTBY"}`)}</span> | |
<span className="clear-search refresh-icon-container" onClick={clearSearch}><RefreshIcon /></span> | |
</span> | |
<span onClick={onClose}> | |
<CloseSvg /> | |
</span> | |
</div> | |
); | |
} | |
case "sort": { | |
return ( | |
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | |
<span className="header" style={{ display: "flex" }}> | |
<span className="icon" style={{ marginRight: "12px", marginTop: "5px", paddingBottom: "3px" }}><SortSvg /></span> | |
<span style={{ fontSize: "1.5rem", fontWeight: "700", marginRight: "12px" }}>{t(`${uiConfig?.headerLabel || "TQM_INBOX_SORTBY"}`)}</span> | |
<span className="clear-search refresh-icon-container" onClick={clearSearch}><RefreshIcon /></span> | |
</span> | |
<span onClick={onClose}> | |
<CloseSvg /> | |
</span> | |
</div> | |
); | |
} | |
case "search": { | |
return ( | |
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | |
<span className="header" style={{ display: "flex" }}> | |
<span className="icon" style={{ marginRight: "12px", marginTop: "5px" }}><SearchIcon /></span> | |
<span style={{ fontSize: "large" }}>{t(`${uiConfig?.headerLabel || "TQM_INBOX_SORTBY"}`)}</span> | |
</span> | |
<span onClick={onClose}> | |
<CloseSvg /> | |
</span> | |
</div> | |
); | |
} | |
const renderHeader = () => { | |
const headerDetails = getHeaderDetails(uiConfig?.typeMobile); | |
return ( | |
<div className="popup-label" style={{ display: "flex", paddingBottom: "20px" }}> | |
<span className="header" style={{ display: "flex" }}> | |
<span className="icon" style={{ marginRight: "12px", marginTop: "5px", paddingBottom: "3px" }}>{headerDetails.icon}</span> | |
<span style={{ fontSize: "1.5rem", fontWeight: "700", marginRight: "12px" }}>{t(headerDetails.label)}</span> | |
<span className="clear-search refresh-icon-container" onClick={clearSearch}><RefreshIcon /></span> | |
</span> | |
<span onClick={onClose}> | |
<CloseSvg /> | |
</span> | |
</div> | |
); | |
} |
: {} | ||
} | ||
> | ||
<span className={customTableWrapperClassName}> | ||
{tableTopComponent ? tableTopComponent : null} | ||
<table | ||
className={className} | ||
{...getTableProps()} | ||
style={styles} | ||
ref={tableRef} | ||
> | ||
<thead> | ||
{headerGroups.map((headerGroup) => ( | ||
<tr {...headerGroup.getHeaderGroupProps()}> | ||
{showAutoSerialNo && ( | ||
<th style={{ verticalAlign: 'top' }}> | ||
{showAutoSerialNo && typeof showAutoSerialNo == 'string' | ||
? t(showAutoSerialNo) | ||
: t('TB_SNO')} | ||
</th> | ||
)} | ||
{headerGroup.headers.map((column) => ( | ||
<th | ||
{...column.getHeaderProps(column.getSortByToggleProps())} | ||
style={{ verticalAlign: 'top' }} | ||
> | ||
{column.render('Header')} | ||
<span> | ||
{column.isSorted ? ( | ||
column.isSortedDesc ? ( | ||
<SortDown /> | ||
) : ( | ||
<SortUp /> | ||
) | ||
) : ( | ||
'' | ||
)} | ||
</span> | ||
</th> | ||
))} | ||
</tr> | ||
); | ||
})} | ||
</tbody> | ||
</table> | ||
</span> | ||
{isPaginationRequired && ( | ||
<div className="pagination dss-white-pre"> | ||
{`${t("CS_COMMON_ROWS_PER_PAGE")} :`} | ||
<select | ||
className="cp" | ||
value={manualPagination ? pageSizeLimit : pageSize} | ||
style={{ marginRight: "15px" }} | ||
onChange={manualPagination ? onPageSizeChange : (e) => setPageSize(Number(e.target.value))} | ||
))} | ||
</thead> | ||
<tbody {...getTableBodyProps()}> | ||
{page.map((row, i) => { | ||
// rows.slice(0, 10).map((row, i) => { | ||
prepareRow(row); | ||
return ( | ||
<tr {...row.getRowProps()}> | ||
{showAutoSerialNo && <td>{i + 1}</td>} | ||
{row.cells.map((cell) => { | ||
return ( | ||
<td | ||
// style={{ padding: "20px 18px", fontSize: "16px", borderTop: "1px solid grey", textAlign: "left", verticalAlign: "middle" }} | ||
{...cell.getCellProps([ | ||
// { | ||
// className: cell.column.className, | ||
// style: cell.column.style, | ||
// }, | ||
// getColumnProps(cell.column), | ||
getCellProps(cell), | ||
])} | ||
> | ||
{cell.attachment_link ? ( | ||
<a | ||
style={{ color: '#1D70B8' }} | ||
href={cell.attachment_link} | ||
> | ||
{cell.render('Cell')} | ||
</a> | ||
) : ( | ||
<React.Fragment> | ||
{' '} | ||
{cell.render('Cell')}{' '} | ||
</React.Fragment> | ||
)} | ||
</td> | ||
); | ||
})} | ||
</tr> | ||
); | ||
})} | ||
</tbody> | ||
</table> | ||
</span> | ||
</div> | ||
{isPaginationRequired && ( |
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 rendering logic for the table and pagination controls is complex and includes multiple conditional renderings. Consider simplifying this by breaking it down into smaller components or using more descriptive helper functions.
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.
Also make sure you export newly added components, and update versions properly. Also assuming you've copy pasted components code from develop branch of digit properly @hridya-egov.
@@ -1,6 +1,7 @@ | |||
import React, { useEffect, useMemo } from "react"; | |||
import { useTranslation } from "react-i18next"; | |||
import {InboxSearchComposer, Loader, Button ,AddFilled} from "@egovernments/digit-ui-components"; | |||
import {Loader, Button ,AddFilled} from "@egovernments/digit-ui-components"; |
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.
Check import
@@ -68,7 +69,7 @@ const ProjectSearch = () => { | |||
)} | |||
</div> | |||
<div className="inbox-search-wrapper"> | |||
<InboxSearchComposer configs={configs}></InboxSearchComposer> | |||
<InboxSearchComposerV2 configs={configs}></InboxSearchComposerV2> |
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.
Browsersession is required in v2
@@ -1,6 +1,7 @@ | |||
import React from "react"; | |||
import { useTranslation } from "react-i18next"; | |||
import { Header, Loader,InboxSearchComposer} from "@egovernments/digit-ui-components"; | |||
import { Header, Loader} from "@egovernments/digit-ui-components"; | |||
import InboxSearchComposerV2 from "../../../../../../ui-components/src/hoc/InboxSearchComposerV2"; |
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.
Import here
@@ -25,7 +26,7 @@ const ProjectSearchAndInboxComponent = () => { | |||
<React.Fragment> | |||
<Header styles={{ fontSize: "32px" }}>{t(configs?.label)}</Header> | |||
<div className="inbox-search-wrapper"> | |||
<InboxSearchComposer configs={configs}></InboxSearchComposer> | |||
<InboxSearchComposerV2 configs={configs}></InboxSearchComposerV2> |
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.
Browser session?
Summary by CodeRabbit
New Features
HorizontalNavV2
for enhanced horizontal navigation.RemovableTagNew
andMobileSearchResultsV1
components for improved UI interaction.ApiCheckboxes
component that fetches and displays checkboxes dynamically based on API data.Enhancements
SearchComponent
,MultiSelectDropdown
, andUploadFile
components with enhanced functionality and user interaction.InboxSearchComposerV2
with better search and filtering capabilities.MobileSearchComponent
.Bug Fixes
MultiUploadWrapper
andWorkflowStatusFilter
components for better stability and performance.Documentation
index.html
for global configuration.Refactor
CheckBox
,Table
, andSubmitBar
to improve performance and maintainability.Style