TP-55185 Revamp UI for CSA (#943)
* TP-55185 Revamp CSA changes done * TP-55185 Revamp CSA type fixes done * TP-55185 fixes done * TP-55185 PR fixes * TP-55185 fixes * TP-55185 CSA changes * TP-55185 Fixes done
This commit is contained in:
committed by
GitHub
parent
45ae7d42a9
commit
870e6f4497
@@ -28,6 +28,7 @@
|
|||||||
"overallPerformanceAgencyManagerPerformanceTable": true,
|
"overallPerformanceAgencyManagerPerformanceTable": true,
|
||||||
"overallPerformanceAgencyPerformanceTable": true,
|
"overallPerformanceAgencyPerformanceTable": true,
|
||||||
"fcmDashboard": true,
|
"fcmDashboard": true,
|
||||||
|
"csaUiRevampEnabled": true
|
||||||
"teleGovernancePerformanceDashboard": true,
|
"teleGovernancePerformanceDashboard": true,
|
||||||
"teleGovernanceAgencyPerformanceTable": true,
|
"teleGovernanceAgencyPerformanceTable": true,
|
||||||
"teleGovernanceAgentPerformanceTable": true,
|
"teleGovernanceAgentPerformanceTable": true,
|
||||||
|
|||||||
30
src/components/FilterDrawer/FilterRenderingEngine.tsx
Normal file
30
src/components/FilterDrawer/FilterRenderingEngine.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import DateTimePickerFilter from './components/DateTimePickerFilter';
|
||||||
|
import { IFilterDrawerSchema, ISelectedOptions } from './types';
|
||||||
|
import { FilterType } from './constants';
|
||||||
|
|
||||||
|
const ComponentMap = {
|
||||||
|
[FilterType.DATE_TIME_PICKER]: DateTimePickerFilter
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IQuestionRenderingEngine {
|
||||||
|
filterType: string;
|
||||||
|
filterKey: string;
|
||||||
|
filterSchema: Record<string, IFilterDrawerSchema>;
|
||||||
|
selectedOptions: ISelectedOptions;
|
||||||
|
setSelectedOptions: (selectedOptions: ISelectedOptions) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FilterRenderingEngine: React.FC<IQuestionRenderingEngine> = props => {
|
||||||
|
const Comp = ComponentMap[props.filterType as FilterType];
|
||||||
|
if (!Comp) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Comp {...props} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterRenderingEngine;
|
||||||
@@ -2,6 +2,7 @@ import styles from './index.module.scss';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { Typography } from '@navi/web-ui/lib/primitives';
|
import { Typography } from '@navi/web-ui/lib/primitives';
|
||||||
import { ILeftPanel } from './types';
|
import { ILeftPanel } from './types';
|
||||||
|
import { DATE_QUERY_PARAMS, FilterKeys } from './constants';
|
||||||
|
|
||||||
const LeftPanel = (props: ILeftPanel) => {
|
const LeftPanel = (props: ILeftPanel) => {
|
||||||
const { filterSchemaMap, filterSchema, selectedFilter, selectedOptions, handleFilterChange } =
|
const { filterSchemaMap, filterSchema, selectedFilter, selectedOptions, handleFilterChange } =
|
||||||
@@ -10,6 +11,7 @@ const LeftPanel = (props: ILeftPanel) => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{filterSchemaMap?.map(filterKey => {
|
{filterSchemaMap?.map(filterKey => {
|
||||||
|
if (DATE_QUERY_PARAMS.includes(filterKey as FilterKeys)) return null;
|
||||||
const { label } = filterSchema?.[filterKey] || {};
|
const { label } = filterSchema?.[filterKey] || {};
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import styles from './index.module.scss';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { addClickstreamEvent } from '@cp/src/service/clickStreamEventService';
|
import { addClickstreamEvent } from '@cp/src/service/clickStreamEventService';
|
||||||
import { IOption, IRightPanel } from './types';
|
import { IOption, IRightPanel } from './types';
|
||||||
|
import SectionedOptions from './SectionedOptions';
|
||||||
|
|
||||||
const RightPanel = (props: IRightPanel) => {
|
const RightPanel = (props: IRightPanel) => {
|
||||||
const { filterSchema, selectedFilter, selectedOptions, setSelectedOptions, tableName } = props;
|
const { filterSchema, selectedFilter, selectedOptions, setSelectedOptions, tableName } = props;
|
||||||
@@ -75,21 +76,33 @@ const RightPanel = (props: IRightPanel) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className={cx(styles.filteredOptions, { [styles.noSearch]: !isSearchEnabled })}>
|
{filteredOptionsData?.length && filteredOptionsData[0]?.filterSectionLabel ? (
|
||||||
{filteredOptionsData?.map(option => (
|
<SectionedOptions
|
||||||
<div className={styles.option} key={option.label}>
|
filteredOptionsData={filteredOptionsData}
|
||||||
<Checkbox
|
filterSchema={filterSchema}
|
||||||
onChange={e => handleCheckboxChange(e, option)}
|
selectedOptions={selectedOptions}
|
||||||
title={option.label as string}
|
selectedFilter={selectedFilter}
|
||||||
defaultChecked={isOptionChecked(
|
handleCheckboxChange={handleCheckboxChange}
|
||||||
option?.value as string,
|
setSelectedOptions={setSelectedOptions}
|
||||||
selectedOptions,
|
isSearchEnabled={isSearchEnabled}
|
||||||
selectedFilter
|
/>
|
||||||
)}
|
) : (
|
||||||
/>
|
<div className={cx(styles.filteredOptions, { [styles.noSearch]: !isSearchEnabled })}>
|
||||||
</div>
|
{filteredOptionsData?.map(option => (
|
||||||
))}
|
<div className={styles.option} key={option.label}>
|
||||||
</div>
|
<Checkbox
|
||||||
|
onChange={e => handleCheckboxChange(e, option)}
|
||||||
|
title={option.label as string}
|
||||||
|
defaultChecked={isOptionChecked(
|
||||||
|
option?.value as string,
|
||||||
|
selectedOptions,
|
||||||
|
selectedFilter
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
61
src/components/FilterDrawer/SectionedOptions.tsx
Normal file
61
src/components/FilterDrawer/SectionedOptions.tsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { getFilterKey, isOptionChecked } from './utils';
|
||||||
|
import { Checkbox, Typography } from '@navi/web-ui/lib/primitives';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
import cx from 'classnames';
|
||||||
|
import { ISectionedOptionValues } from './types';
|
||||||
|
import FilterRenderingEngine from './FilterRenderingEngine';
|
||||||
|
import { FILTERS_WITH_SUBFILTERS, subFilterMapping } from './constants';
|
||||||
|
|
||||||
|
const SectionedOptions = (props: ISectionedOptionValues) => {
|
||||||
|
const {
|
||||||
|
filteredOptionsData,
|
||||||
|
filterSchema,
|
||||||
|
selectedOptions,
|
||||||
|
selectedFilter,
|
||||||
|
handleCheckboxChange,
|
||||||
|
setSelectedOptions,
|
||||||
|
isSearchEnabled
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx(styles.filteredOptions, { [styles.noSearch]: !isSearchEnabled })}>
|
||||||
|
{filteredOptionsData.map(option => {
|
||||||
|
const { filterSectionLabel, filterSectionValue } = option;
|
||||||
|
return (
|
||||||
|
<div key={filterSectionLabel}>
|
||||||
|
<Typography variant="p3" className={styles.filterSectionLabel} as="div">
|
||||||
|
{filterSectionLabel}
|
||||||
|
</Typography>
|
||||||
|
{filterSectionValue.map(option => {
|
||||||
|
const isChecked = isOptionChecked(
|
||||||
|
option?.value as string,
|
||||||
|
selectedOptions,
|
||||||
|
selectedFilter
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div className={styles.option} key={option.label}>
|
||||||
|
<Checkbox
|
||||||
|
onChange={e => handleCheckboxChange(e, option)}
|
||||||
|
title={option.label as string}
|
||||||
|
defaultChecked={isChecked}
|
||||||
|
/>
|
||||||
|
{isChecked && FILTERS_WITH_SUBFILTERS.includes(option?.value) ? (
|
||||||
|
<FilterRenderingEngine
|
||||||
|
filterType={subFilterMapping.get(option?.value)}
|
||||||
|
filterKey={getFilterKey(selectedFilter, option?.value as string)}
|
||||||
|
filterSchema={filterSchema}
|
||||||
|
selectedOptions={selectedOptions}
|
||||||
|
setSelectedOptions={setSelectedOptions}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SectionedOptions;
|
||||||
@@ -10,11 +10,19 @@ import {
|
|||||||
import { getTableQueryParams } from '@cp/src/utils/QueryParamsHelper';
|
import { getTableQueryParams } from '@cp/src/utils/QueryParamsHelper';
|
||||||
import { Button, Typography } from '@navi/web-ui/lib/primitives';
|
import { Button, Typography } from '@navi/web-ui/lib/primitives';
|
||||||
import { ISelectedFilters } from './types';
|
import { ISelectedFilters } from './types';
|
||||||
|
import { DATE_QUERY_PARAMS, DEFAULT_QUERY_PARAM_TABLE_IDENTIFIER, FilterKeys } from './constants';
|
||||||
|
import { getOptionsAndLabels } from './utils';
|
||||||
|
|
||||||
const SelectedFilters = (props: ISelectedFilters) => {
|
const SelectedFilters = (props: ISelectedFilters) => {
|
||||||
const { filterSchemaMap, filterSchema, handleFilterChange, clearAllFilters } = props;
|
const {
|
||||||
|
filterSchemaMap,
|
||||||
|
filterSchema,
|
||||||
|
handleFilterChange,
|
||||||
|
clearAllFilters,
|
||||||
|
queryParamTableIdentifier = DEFAULT_QUERY_PARAM_TABLE_IDENTIFIER
|
||||||
|
} = props;
|
||||||
const CLEAR_ALL_FILTERS_COUNT = 1;
|
const CLEAR_ALL_FILTERS_COUNT = 1;
|
||||||
const queryParams = getTableQueryParams(filterSchema, 'filters');
|
const queryParams = getTableQueryParams(filterSchema, queryParamTableIdentifier);
|
||||||
|
|
||||||
const handleCancelIconClick = (filterKey: string) => {
|
const handleCancelIconClick = (filterKey: string) => {
|
||||||
handleFilterChange(filterKey);
|
handleFilterChange(filterKey);
|
||||||
@@ -23,7 +31,9 @@ const SelectedFilters = (props: ISelectedFilters) => {
|
|||||||
const renderSelectedFilters = useMemo(() => {
|
const renderSelectedFilters = useMemo(() => {
|
||||||
let activeFiltersCount = 0;
|
let activeFiltersCount = 0;
|
||||||
const selectedFilters = filterSchemaMap.map((filterKey: string) => {
|
const selectedFilters = filterSchemaMap.map((filterKey: string) => {
|
||||||
const { options, label } = filterSchema[filterKey] || {};
|
if (DATE_QUERY_PARAMS.includes(filterKey as FilterKeys)) return null;
|
||||||
|
//Checking if the option is of type sectioned filter option
|
||||||
|
const { options, label } = getOptionsAndLabels(filterSchema, filterKey);
|
||||||
const activeFilters = queryParams?.[filterKey];
|
const activeFilters = queryParams?.[filterKey];
|
||||||
const isActiveFilterArray = Array.isArray(activeFilters);
|
const isActiveFilterArray = Array.isArray(activeFilters);
|
||||||
const selectedOptions = isActiveFilterArray
|
const selectedOptions = isActiveFilterArray
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
import DateTimePickerComponent from '../../DateTimePicker/DateTimePickerComponent';
|
||||||
|
import { DATE_TIME_TYPE } from '../../DateTimePicker/constants';
|
||||||
|
import { getCurrentDate, handleOptionChange } from '../utils';
|
||||||
|
import { getTodayDate } from '@cp/src/pages/CaseDetails/constants/communicationHistory.constant';
|
||||||
|
import { IDateTimePickerFilterProps } from '../types';
|
||||||
|
import styles from '../index.module.scss';
|
||||||
|
import { FiltersWithSubfiltersMapping } from '../constants';
|
||||||
|
|
||||||
|
const DateTimePickerFilter = (props: IDateTimePickerFilterProps) => {
|
||||||
|
const { filterKey, filterSchema, selectedOptions, setSelectedOptions } = props;
|
||||||
|
|
||||||
|
const defaultDate = getCurrentDate();
|
||||||
|
let date: string[] = selectedOptions?.[filterKey];
|
||||||
|
if (!date.length) date = defaultDate;
|
||||||
|
|
||||||
|
const handleDateChange = useCallback(
|
||||||
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
handleOptionChange(
|
||||||
|
e,
|
||||||
|
{ label: FiltersWithSubfiltersMapping.PROMISE_TO_PAY, value: e.target.value },
|
||||||
|
filterKey,
|
||||||
|
selectedOptions,
|
||||||
|
filterSchema,
|
||||||
|
setSelectedOptions
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[filterKey, filterSchema, selectedOptions, setSelectedOptions]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DateTimePickerComponent
|
||||||
|
type={DATE_TIME_TYPE.DATE}
|
||||||
|
value={date}
|
||||||
|
onChange={handleDateChange}
|
||||||
|
className={styles.datePicker}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DateTimePickerFilter;
|
||||||
42
src/components/FilterDrawer/constants.ts
Normal file
42
src/components/FilterDrawer/constants.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
export const DEFAULT_QUERY_PARAM_TABLE_IDENTIFIER = 'filters';
|
||||||
|
|
||||||
|
export enum FiltersWithSubfiltersMapping {
|
||||||
|
PROMISE_TO_PAY = 'PROMISE_TO_PAY',
|
||||||
|
REQUESTED_CALLBACK = 'REQUESTED_CALLBACK'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FilterKeys {
|
||||||
|
PROMISE_TO_PAY_TELE_CSA = 'promiseToPayDateTeleCsa',
|
||||||
|
REQUESTED_CALLBACK_TELE_CSA = 'requestedCallbackDateTeleCsa',
|
||||||
|
PROMISE_TO_PAY_FIELD_AGENT = 'promiseToPayDateFieldAgent',
|
||||||
|
TELE_INTERACTION_STATUSES = 'teleInteractionStatuses'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum FilterType {
|
||||||
|
DATE_TIME_PICKER = 'DateTimePickerFilter'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FILTERS_WITH_SUBFILTERS = [
|
||||||
|
FiltersWithSubfiltersMapping.PROMISE_TO_PAY,
|
||||||
|
FiltersWithSubfiltersMapping.REQUESTED_CALLBACK
|
||||||
|
];
|
||||||
|
|
||||||
|
export const subFilterMapping = new Map([
|
||||||
|
[FiltersWithSubfiltersMapping.PROMISE_TO_PAY, FilterType.DATE_TIME_PICKER],
|
||||||
|
[FiltersWithSubfiltersMapping.REQUESTED_CALLBACK, FilterType.DATE_TIME_PICKER]
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const TeleInteractionStatusesFilterKey = new Map([
|
||||||
|
[FiltersWithSubfiltersMapping.PROMISE_TO_PAY, FilterKeys.PROMISE_TO_PAY_TELE_CSA],
|
||||||
|
[FiltersWithSubfiltersMapping.REQUESTED_CALLBACK, FilterKeys.REQUESTED_CALLBACK_TELE_CSA]
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const FieldInteractionStatusesFilterKey = new Map([
|
||||||
|
[FiltersWithSubfiltersMapping.PROMISE_TO_PAY, FilterKeys.PROMISE_TO_PAY_FIELD_AGENT]
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const DATE_QUERY_PARAMS = [
|
||||||
|
FilterKeys.PROMISE_TO_PAY_TELE_CSA,
|
||||||
|
FilterKeys.REQUESTED_CALLBACK_TELE_CSA,
|
||||||
|
FilterKeys.PROMISE_TO_PAY_FIELD_AGENT
|
||||||
|
];
|
||||||
@@ -131,3 +131,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filterSectionLabel {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--blue-cyan);
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
padding: 12px 16px;
|
||||||
|
margin-bottom: 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datePicker {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import LeftPanel from './LeftPanel';
|
|||||||
import RightPanel from './RightPanel';
|
import RightPanel from './RightPanel';
|
||||||
import SelectedFilters from './SelectedFilters';
|
import SelectedFilters from './SelectedFilters';
|
||||||
import { IFilterDrawer } from './types';
|
import { IFilterDrawer } from './types';
|
||||||
|
import { FilterKeys, FiltersWithSubfiltersMapping } from './constants';
|
||||||
|
import { DEFAULT_QUERY_PARAM_TABLE_IDENTIFIER } from './constants';
|
||||||
|
|
||||||
const FilterDrawer = (props: IFilterDrawer) => {
|
const FilterDrawer = (props: IFilterDrawer) => {
|
||||||
const {
|
const {
|
||||||
@@ -31,14 +33,20 @@ const FilterDrawer = (props: IFilterDrawer) => {
|
|||||||
rightContainerClass,
|
rightContainerClass,
|
||||||
selectedFiltersClass,
|
selectedFiltersClass,
|
||||||
onApply,
|
onApply,
|
||||||
tableName
|
tableName,
|
||||||
|
queryParamTableIdentifier = DEFAULT_QUERY_PARAM_TABLE_IDENTIFIER,
|
||||||
|
filterKeys
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const mainParams = readQueryParams();
|
const mainParams = readQueryParams();
|
||||||
const queryParams = getTableQueryParams(filterSchema, 'filters');
|
const queryParams = getTableQueryParams(filterSchema, queryParamTableIdentifier);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const filterSchemaMap = useMemo(() => Object.keys(filterSchema), [filterSchema]);
|
const filterSchemaMap = useMemo(() => {
|
||||||
|
const keys = Object.keys(filterSchema);
|
||||||
|
filterKeys && keys.push(...filterKeys); //Adding keys for subfilters
|
||||||
|
return keys;
|
||||||
|
}, [filterSchema, filterKeys]);
|
||||||
|
|
||||||
const [showFilterDrawer, setShowFilterDrawer] = useState(false);
|
const [showFilterDrawer, setShowFilterDrawer] = useState(false);
|
||||||
const [selectedFilter, setSelectedFilter] = useState('');
|
const [selectedFilter, setSelectedFilter] = useState('');
|
||||||
@@ -68,10 +76,35 @@ const FilterDrawer = (props: IFilterDrawer) => {
|
|||||||
setSelectedFilter(filterKey);
|
setSelectedFilter(filterKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDateChangesInParams = (selectedFilters: Record<string, string[]>) => {
|
||||||
|
if (
|
||||||
|
!selectedFilters?.teleInteractionStatuses?.includes(
|
||||||
|
FiltersWithSubfiltersMapping.PROMISE_TO_PAY
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
selectedFilters.promiseToPayDateTeleCsa = [];
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!selectedFilters?.teleInteractionStatuses?.includes(
|
||||||
|
FiltersWithSubfiltersMapping.REQUESTED_CALLBACK
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
selectedFilters.requestedCallbackDateTeleCsa = [];
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!selectedFilters?.fieldInteractionStatuses?.includes(
|
||||||
|
FiltersWithSubfiltersMapping.PROMISE_TO_PAY
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
selectedFilters.promiseToPayDateFieldAgent = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const applyFilterChangeHandler = (selectedFilters: Record<string, string[]>) => {
|
const applyFilterChangeHandler = (selectedFilters: Record<string, string[]>) => {
|
||||||
|
handleDateChangesInParams(selectedFilters);
|
||||||
const url = createQueryParams({
|
const url = createQueryParams({
|
||||||
...mainParams,
|
...mainParams,
|
||||||
filters: {
|
[queryParamTableIdentifier]: {
|
||||||
...selectedFilters
|
...selectedFilters
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -145,6 +178,7 @@ const FilterDrawer = (props: IFilterDrawer) => {
|
|||||||
filterSchema={filterSchema}
|
filterSchema={filterSchema}
|
||||||
handleFilterChange={clearFilterWithFilterKey}
|
handleFilterChange={clearFilterWithFilterKey}
|
||||||
clearAllFilters={filterCtaHandler}
|
clearAllFilters={filterCtaHandler}
|
||||||
|
queryParamTableIdentifier={queryParamTableIdentifier}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
startAdornment={<FilterIconFilled color="var(--blue-base)" />}
|
startAdornment={<FilterIconFilled color="var(--blue-base)" />}
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
|
import { ChangeEvent } from 'react';
|
||||||
|
|
||||||
export interface IOption {
|
export interface IOption {
|
||||||
label: string;
|
label: string;
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISectionedOption {
|
||||||
|
filterSectionLabel: string;
|
||||||
|
filterSectionValue: IOption[];
|
||||||
|
}
|
||||||
|
|
||||||
export type ISelectedOptions = Record<string, string[]>;
|
export type ISelectedOptions = Record<string, string[]>;
|
||||||
|
|
||||||
export interface IFilterDrawerSchema {
|
export interface IFilterDrawerSchema {
|
||||||
@@ -22,6 +29,8 @@ export interface IFilterDrawer {
|
|||||||
selectedFiltersClass?: string;
|
selectedFiltersClass?: string;
|
||||||
onApply: (selectedFilters: ISelectedOptions) => void;
|
onApply: (selectedFilters: ISelectedOptions) => void;
|
||||||
tableName: string;
|
tableName: string;
|
||||||
|
queryParamTableIdentifier?: string;
|
||||||
|
filterKeys?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILeftPanel {
|
export interface ILeftPanel {
|
||||||
@@ -45,6 +54,7 @@ export interface ISelectedFilters {
|
|||||||
filterSchema: Record<string, IFilterDrawerSchema>;
|
filterSchema: Record<string, IFilterDrawerSchema>;
|
||||||
handleFilterChange: (filterKey: string) => void;
|
handleFilterChange: (filterKey: string) => void;
|
||||||
clearAllFilters: (reset: boolean) => void;
|
clearAllFilters: (reset: boolean) => void;
|
||||||
|
queryParamTableIdentifier?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IResetSelectedOptions {
|
export interface IResetSelectedOptions {
|
||||||
@@ -55,3 +65,20 @@ export interface IResetSelectedOptions {
|
|||||||
queryParams: ISelectedOptions;
|
queryParams: ISelectedOptions;
|
||||||
setSelectedOptions: (selectedOptions: ISelectedOptions) => void;
|
setSelectedOptions: (selectedOptions: ISelectedOptions) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IDateTimePickerFilterProps {
|
||||||
|
filterKey: string;
|
||||||
|
filterSchema: Record<string, IFilterDrawerSchema>;
|
||||||
|
selectedOptions: ISelectedOptions;
|
||||||
|
setSelectedOptions: (selectedOptions: ISelectedOptions) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISectionedOptionValues {
|
||||||
|
filteredOptionsData: IOption[];
|
||||||
|
filterSchema: Record<string, IFilterDrawerSchema>;
|
||||||
|
selectedOptions: ISelectedOptions;
|
||||||
|
selectedFilter: string;
|
||||||
|
handleCheckboxChange: (e: ChangeEvent<HTMLInputElement>, option: IOption) => void;
|
||||||
|
setSelectedOptions: (selectedOptions: ISelectedOptions) => void;
|
||||||
|
isSearchEnabled: boolean;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
import { IFilterDrawerSchema, IOption, IResetSelectedOptions, ISelectedOptions } from './types';
|
import {
|
||||||
|
IFilterDrawerSchema,
|
||||||
|
IOption,
|
||||||
|
IResetSelectedOptions,
|
||||||
|
ISectionedOption,
|
||||||
|
ISelectedOptions
|
||||||
|
} from './types';
|
||||||
|
import {
|
||||||
|
DATE_QUERY_PARAMS,
|
||||||
|
FieldInteractionStatusesFilterKey,
|
||||||
|
FilterKeys,
|
||||||
|
FiltersWithSubfiltersMapping,
|
||||||
|
TeleInteractionStatusesFilterKey
|
||||||
|
} from './constants';
|
||||||
|
import { getTodayDate } from '@cp/src/pages/CaseDetails/constants/communicationHistory.constant';
|
||||||
|
|
||||||
export const removeSpecificOption = (
|
export const removeSpecificOption = (
|
||||||
filterKeyOptionsMap: ISelectedOptions,
|
filterKeyOptionsMap: ISelectedOptions,
|
||||||
@@ -54,6 +68,13 @@ export const handleOptionChange = (
|
|||||||
) => {
|
) => {
|
||||||
const checked = e?.target?.checked;
|
const checked = e?.target?.checked;
|
||||||
let selectedOptionFilterMap = { ...selectedOptions };
|
let selectedOptionFilterMap = { ...selectedOptions };
|
||||||
|
|
||||||
|
if (DATE_QUERY_PARAMS.includes(filterKey as FilterKeys)) {
|
||||||
|
selectedOptionFilterMap[filterKey] = [option.value as string];
|
||||||
|
setSelectedOptions(selectedOptionFilterMap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
if (filterSchema[filterKey].multiSelect) {
|
if (filterSchema[filterKey].multiSelect) {
|
||||||
selectedOptionFilterMap?.[filterKey]?.push(option.value as string);
|
selectedOptionFilterMap?.[filterKey]?.push(option.value as string);
|
||||||
@@ -67,3 +88,28 @@ export const handleOptionChange = (
|
|||||||
}
|
}
|
||||||
setSelectedOptions(selectedOptionFilterMap);
|
setSelectedOptions(selectedOptionFilterMap);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getFilterKey = (selectedFilter: string, selectedOption: string) => {
|
||||||
|
if (selectedFilter === FilterKeys.TELE_INTERACTION_STATUSES) {
|
||||||
|
return TeleInteractionStatusesFilterKey.get(selectedOption as FiltersWithSubfiltersMapping);
|
||||||
|
}
|
||||||
|
return FieldInteractionStatusesFilterKey.get(selectedOption as FiltersWithSubfiltersMapping);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOptionsForSectionedFilters = (options: ISectionedOption[], key: string) => {
|
||||||
|
const filterSectionValues = options.map(option => option.filterSectionValue).flat();
|
||||||
|
return { options: filterSectionValues, label: key };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOptionsAndLabels = (
|
||||||
|
filterSchema: Record<string, IFilterDrawerSchema>,
|
||||||
|
filterKey: string
|
||||||
|
) => {
|
||||||
|
return filterSchema[filterKey].options?.[0]?.filterSectionLabel
|
||||||
|
? getOptionsForSectionedFilters(filterSchema[filterKey].options, filterSchema[filterKey].label)
|
||||||
|
: filterSchema[filterKey] || {};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCurrentDate = () => {
|
||||||
|
return getTodayDate().toISOString().slice(0, 10);
|
||||||
|
};
|
||||||
|
|||||||
@@ -44,7 +44,15 @@ const TableFilters = ({
|
|||||||
onSelectedFiltersApplied,
|
onSelectedFiltersApplied,
|
||||||
onClearSelectedFilters
|
onClearSelectedFilters
|
||||||
}: TableFilterProps) => {
|
}: TableFilterProps) => {
|
||||||
const filterSchema = useSelector((state: RootState) => state.allCases.casesTable.filters.schema);
|
const casesFilterSchema = useSelector(
|
||||||
|
(state: RootState) => state.allCases.casesTable.filters.schema
|
||||||
|
);
|
||||||
|
const {
|
||||||
|
teleInteractionStatuses,
|
||||||
|
fieldInteractionStatuses,
|
||||||
|
allocatedFieldAgent,
|
||||||
|
...filterSchema
|
||||||
|
} = casesFilterSchema;
|
||||||
const filterSchemaMap = Object.keys(filterSchema);
|
const filterSchemaMap = Object.keys(filterSchema);
|
||||||
const queryParams = getTableQueryParams(filterSchema, CASE_TABLE);
|
const queryParams = getTableQueryParams(filterSchema, CASE_TABLE);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ export const fetchAllCases = (
|
|||||||
...searchPageRequest,
|
...searchPageRequest,
|
||||||
aggregationRequest: defaultAgregationRequest
|
aggregationRequest: defaultAgregationRequest
|
||||||
};
|
};
|
||||||
if (payload && !payload.paymentStatus) {
|
|
||||||
|
if (payload && !payload.paymentStatus?.length) {
|
||||||
payload.paymentStatus = ['ALL'];
|
payload.paymentStatus = ['ALL'];
|
||||||
}
|
}
|
||||||
if (updateParams) {
|
if (updateParams) {
|
||||||
|
|||||||
109
src/pages/Cases/components/CaseTableColumnCSA.tsx
Normal file
109
src/pages/Cases/components/CaseTableColumnCSA.tsx
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import { ICellRendererParams } from 'ag-grid-community';
|
||||||
|
import { DEFAULT_COLOR, FeedbackTypesCodeMap } from '../constants/CasesConstants';
|
||||||
|
|
||||||
|
import CasesCustomerName from './CasesCustomerName';
|
||||||
|
import { formatAmount } from 'src/utils/commonUtils';
|
||||||
|
import { ColDefsType } from '@navi/web-ui/lib/components/AgTable/types';
|
||||||
|
import styles from './Cases.module.scss';
|
||||||
|
import TableCellRenderer from '@cp/src/components/TableCellRenderer';
|
||||||
|
import CustomTagWithTime from './CustomTagWithTime';
|
||||||
|
import { DateFormat, dateFormat } from '@cp/src/utils/DateHelper';
|
||||||
|
|
||||||
|
const tooltipContentClass = 'z-[var(--z-index-external-sensei-tooltip)]';
|
||||||
|
export const All_CASES_COLUMN_DEFS_CSA = [
|
||||||
|
{ field: 'customerName', headerName: 'Name', cellRenderer: CasesCustomerName },
|
||||||
|
{ field: 'phoneNumber', width: 160, headerName: 'Phone Number' },
|
||||||
|
{
|
||||||
|
field: 'accountNumber',
|
||||||
|
headerName: 'LAN',
|
||||||
|
minWidth: 145,
|
||||||
|
maxWidth: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'allocatedFieldAgent',
|
||||||
|
headerName: 'Allocated FE',
|
||||||
|
width: 170,
|
||||||
|
serverSortable: true,
|
||||||
|
cellRenderer: (params: ICellRendererParams) => {
|
||||||
|
const { allocatedFieldAgent } = params.data || {};
|
||||||
|
return (
|
||||||
|
<TableCellRenderer
|
||||||
|
value={allocatedFieldAgent}
|
||||||
|
toolTipContent={allocatedFieldAgent}
|
||||||
|
showToolTip
|
||||||
|
tooltipContentClass={tooltipContentClass}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'teleFeedbackType',
|
||||||
|
headerName: 'Tele Feedback',
|
||||||
|
width: 230,
|
||||||
|
serverSortable: true,
|
||||||
|
cellRendererSelector: (params: ICellRendererParams) => {
|
||||||
|
const feedbackType: string = params?.data?.teleFeedbackType;
|
||||||
|
const { color = DEFAULT_COLOR, label = '' } = FeedbackTypesCodeMap[feedbackType] || {};
|
||||||
|
const formattedDate = params?.data?.teleFeedbackTimestamp
|
||||||
|
? dateFormat(
|
||||||
|
new Date(params?.data?.teleFeedbackTimestamp),
|
||||||
|
DateFormat.LONG_DATE_FORMAT_WITH_TIME
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
component: CustomTagWithTime,
|
||||||
|
params: {
|
||||||
|
color,
|
||||||
|
label,
|
||||||
|
variant: 'transparent',
|
||||||
|
labelClass: styles.feedbackTag,
|
||||||
|
time: formattedDate
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'fieldFeedbackType',
|
||||||
|
headerName: 'Field Feedback',
|
||||||
|
width: 230,
|
||||||
|
serverSortable: true,
|
||||||
|
cellRendererSelector: (params: ICellRendererParams) => {
|
||||||
|
const feedbackType: string = params?.data?.fieldFeedbackType;
|
||||||
|
const { color = DEFAULT_COLOR, label = '' } = FeedbackTypesCodeMap[feedbackType] || {};
|
||||||
|
const formattedDate = params?.data?.fieldFeedbackTimestamp
|
||||||
|
? dateFormat(
|
||||||
|
new Date(params?.data?.fieldFeedbackTimestamp),
|
||||||
|
DateFormat.LONG_DATE_FORMAT_WITH_TIME
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
component: CustomTagWithTime,
|
||||||
|
params: {
|
||||||
|
color,
|
||||||
|
label,
|
||||||
|
variant: 'transparent',
|
||||||
|
labelClass: styles.feedbackTag,
|
||||||
|
time: formattedDate
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'outStandingAmount',
|
||||||
|
headerName: 'Outstanding Amount',
|
||||||
|
wrapHeaderText: true,
|
||||||
|
serverSortable: true,
|
||||||
|
width: 140,
|
||||||
|
cellRenderer: (params: ICellRendererParams) => formatAmount(params.value, false)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dpdBucket',
|
||||||
|
headerName: 'DPD Bucket',
|
||||||
|
serverSortable: true,
|
||||||
|
minWidth: 120,
|
||||||
|
maxWidth: 130,
|
||||||
|
wrapHeaderText: true
|
||||||
|
}
|
||||||
|
] as ColDefsType[];
|
||||||
@@ -141,6 +141,7 @@
|
|||||||
|
|
||||||
.feedbackTag {
|
.feedbackTag {
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
.CaseListPage {
|
.CaseListPage {
|
||||||
// position: relative;
|
// position: relative;
|
||||||
@@ -175,3 +176,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.feedbackContainer {
|
||||||
|
display: 'flex';
|
||||||
|
flex-direction: 'column';
|
||||||
|
justify-content: 'center';
|
||||||
|
margin-top: 9px;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedbackTime {
|
||||||
|
color: var(--grayscale-content-3);
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 10px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedFilters {
|
||||||
|
padding: 8px 0px 24px 24px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ import {
|
|||||||
CasesQueryParams,
|
CasesQueryParams,
|
||||||
CASE_TABLE,
|
CASE_TABLE,
|
||||||
defaultAllCasesPageRequest,
|
defaultAllCasesPageRequest,
|
||||||
defaultPageSize
|
defaultPageSize,
|
||||||
|
CSA_TABLE_ROW_HEIGHT
|
||||||
} from '../constants/CasesConstants';
|
} from '../constants/CasesConstants';
|
||||||
import Pagination from '@navi/web-ui/lib/components/Pagination/Pagination';
|
import Pagination from '@navi/web-ui/lib/components/Pagination/Pagination';
|
||||||
import { GridEvent, QueryParams, RowClickEvent } from '../../../components/interfaces';
|
import { GridEvent, QueryParams, RowClickEvent } from '../../../components/interfaces';
|
||||||
@@ -39,11 +40,15 @@ import { addClickstreamEvent } from '../../../service/clickStreamEventService';
|
|||||||
import { CLICKSTREAM_EVENT_NAMES } from '../../../service/clickStream.constant';
|
import { CLICKSTREAM_EVENT_NAMES } from '../../../service/clickStream.constant';
|
||||||
import AnimateWithLottie from '@cp/src/components/AnimationWithLottie';
|
import AnimateWithLottie from '@cp/src/components/AnimationWithLottie';
|
||||||
import eid2024Lottie from '@cp/src/assets/json/eid2024Lottie.json';
|
import eid2024Lottie from '@cp/src/assets/json/eid2024Lottie.json';
|
||||||
|
import { All_CASES_COLUMN_DEFS_CSA } from './CaseTableColumnCSA';
|
||||||
|
import FilterDrawer from '@cp/src/components/FilterDrawer';
|
||||||
|
import { noop } from '@navi/web-ui/lib/utils/common';
|
||||||
|
import { FilterKeys } from '@cp/src/components/FilterDrawer/constants';
|
||||||
|
|
||||||
const columnDefs = All_CASES_COLUMN_DEFS;
|
|
||||||
const Cases = () => {
|
const Cases = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const tableRef = useRef(null);
|
||||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const { [CASE_TABLE]: queryParams } = readQueryParams();
|
const { [CASE_TABLE]: queryParams } = readQueryParams();
|
||||||
@@ -65,6 +70,10 @@ const Cases = () => {
|
|||||||
const { PAGE_SIZE, PAGE_NO, QUERY, SORT_BY_FIELD, SORT_ORDER } = CasesQueryParams;
|
const { PAGE_SIZE, PAGE_NO, QUERY, SORT_BY_FIELD, SORT_ORDER } = CasesQueryParams;
|
||||||
|
|
||||||
const [selectedFiltersApplied, setSelectedFiltersApplied] = React.useState(false);
|
const [selectedFiltersApplied, setSelectedFiltersApplied] = React.useState(false);
|
||||||
|
const csaUiRevampEnabled = useSelector(
|
||||||
|
(store: RootState) => store?.common?.featureFlags?.csaUiRevampEnabled
|
||||||
|
);
|
||||||
|
const columnDefs = csaUiRevampEnabled ? All_CASES_COLUMN_DEFS_CSA : All_CASES_COLUMN_DEFS;
|
||||||
|
|
||||||
const setColumnSorting = () => {
|
const setColumnSorting = () => {
|
||||||
columnDefs.forEach((colDef: ColDefsType) => {
|
columnDefs.forEach((colDef: ColDefsType) => {
|
||||||
@@ -94,6 +103,7 @@ const Cases = () => {
|
|||||||
if (!loading && queryParams?.lastUsed === QUERY) {
|
if (!loading && queryParams?.lastUsed === QUERY) {
|
||||||
searchInputRef?.current?.focus();
|
searchInputRef?.current?.focus();
|
||||||
}
|
}
|
||||||
|
tableRef?.current?.api?.sizeColumnsToFit();
|
||||||
}, [loading]);
|
}, [loading]);
|
||||||
|
|
||||||
const updateQueryParamsAndNavigate = (
|
const updateQueryParamsAndNavigate = (
|
||||||
@@ -170,7 +180,8 @@ const Cases = () => {
|
|||||||
|
|
||||||
const handleSortChange = (column: ColDefsType) => {
|
const handleSortChange = (column: ColDefsType) => {
|
||||||
if (column) {
|
if (column) {
|
||||||
const { field, serverSort } = column;
|
const { field, serverSort, serverSortable } = column;
|
||||||
|
if (!serverSortable) return;
|
||||||
if (field) {
|
if (field) {
|
||||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.LH_CaseList_SortSuccess, {
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.LH_CaseList_SortSuccess, {
|
||||||
sortBy: field,
|
sortBy: field,
|
||||||
@@ -214,6 +225,14 @@ const Cases = () => {
|
|||||||
col.sortable = false;
|
col.sortable = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { interactionStatuses, assignedAtFilters, ...csaFilterSchema } = allCasesFilterSchema;
|
||||||
|
const csaFilterKeys = [
|
||||||
|
FilterKeys.PROMISE_TO_PAY_TELE_CSA,
|
||||||
|
FilterKeys.REQUESTED_CALLBACK_TELE_CSA,
|
||||||
|
FilterKeys.PROMISE_TO_PAY_FIELD_AGENT
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.CaseListPage}>
|
<div className={styles.CaseListPage}>
|
||||||
<GridContainer key={location.search} className={cx(styles.cases, 'allCasesTable')}>
|
<GridContainer key={location.search} className={cx(styles.cases, 'allCasesTable')}>
|
||||||
@@ -231,13 +250,24 @@ const Cases = () => {
|
|||||||
<AnimateWithLottie animationData={eid2024Lottie} />
|
<AnimateWithLottie animationData={eid2024Lottie} />
|
||||||
) : null}
|
) : null}
|
||||||
<div className={styles.cases__filters}>
|
<div className={styles.cases__filters}>
|
||||||
<TableFilters
|
{csaUiRevampEnabled ? (
|
||||||
// filterSchema={allCasesFilterSchema}
|
<FilterDrawer
|
||||||
handlerFilterChange={handlerFilterChange}
|
filterButtonTitle="Filters"
|
||||||
handlerFilterClear={handleClearAllFilters}
|
filterSchema={csaFilterSchema}
|
||||||
onSelectedFiltersApplied={() => setSelectedFiltersApplied(true)}
|
selectedFiltersClass={styles.selectedFilters}
|
||||||
onClearSelectedFilters={() => setSelectedFiltersApplied(false)}
|
onApply={noop}
|
||||||
/>
|
tableName={CASE_TABLE}
|
||||||
|
queryParamTableIdentifier={CASE_TABLE}
|
||||||
|
filterKeys={csaFilterKeys}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<TableFilters
|
||||||
|
handlerFilterChange={handlerFilterChange}
|
||||||
|
handlerFilterClear={handleClearAllFilters}
|
||||||
|
onSelectedFiltersApplied={() => setSelectedFiltersApplied(true)}
|
||||||
|
onClearSelectedFilters={() => setSelectedFiltersApplied(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<SearchBarInput
|
<SearchBarInput
|
||||||
containerClassName={styles.searchInputContainer}
|
containerClassName={styles.searchInputContainer}
|
||||||
className={styles.searchInput}
|
className={styles.searchInput}
|
||||||
@@ -252,6 +282,7 @@ const Cases = () => {
|
|||||||
</div>
|
</div>
|
||||||
<GridColumn md={12} className={styles.cases__table}>
|
<GridColumn md={12} className={styles.cases__table}>
|
||||||
<AgTable
|
<AgTable
|
||||||
|
ref={tableRef}
|
||||||
className="AllCasesTable"
|
className="AllCasesTable"
|
||||||
defaultColDef={{
|
defaultColDef={{
|
||||||
suppressMovable: true,
|
suppressMovable: true,
|
||||||
@@ -278,9 +309,9 @@ const Cases = () => {
|
|||||||
onGridReady={onCasesGridReady}
|
onGridReady={onCasesGridReady}
|
||||||
onRowClicked={onCasesRowClicked}
|
onRowClicked={onCasesRowClicked}
|
||||||
rowClass={'cursor-pointer'}
|
rowClass={'cursor-pointer'}
|
||||||
|
rowHeight={csaUiRevampEnabled ? CSA_TABLE_ROW_HEIGHT : undefined}
|
||||||
/>
|
/>
|
||||||
</GridColumn>
|
</GridColumn>
|
||||||
{/* {loading && <div className={styles['overlay']} />} */}
|
|
||||||
<Loader show={loading} className={'overlay'} animate={false} />
|
<Loader show={loading} className={'overlay'} animate={false} />
|
||||||
</GridContainer>
|
</GridContainer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
21
src/pages/Cases/components/CustomTagWithTime.tsx
Normal file
21
src/pages/Cases/components/CustomTagWithTime.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Tag from '@navi/web-ui/lib/primitives/Tag';
|
||||||
|
import styles from './Cases.module.scss';
|
||||||
|
import { Typography } from '@navi/web-ui/lib/primitives';
|
||||||
|
import { ICustomTagProps } from '../constants/CasesInterfaces';
|
||||||
|
|
||||||
|
const CustomTagWithTime: React.FC<ICustomTagProps> = props => {
|
||||||
|
const { label, color, variant, labelClass, time } = props;
|
||||||
|
return (
|
||||||
|
<div className={styles.feedbackContainer}>
|
||||||
|
<Tag label={label} color={color} variant={variant} labelClass={labelClass} />
|
||||||
|
{time && (
|
||||||
|
<Typography variant="h4" className={styles.feedbackTime}>
|
||||||
|
{time}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CustomTagWithTime;
|
||||||
@@ -2,6 +2,9 @@ import { TagColors } from '@navi/web-ui/lib/primitives/Tag/types';
|
|||||||
import { AlertTypesProps, AllCasesPageRequest } from './CasesInterfaces';
|
import { AlertTypesProps, AllCasesPageRequest } from './CasesInterfaces';
|
||||||
|
|
||||||
export const CASE_TABLE = 'casesTable';
|
export const CASE_TABLE = 'casesTable';
|
||||||
|
export const CSA_TABLE_ROW_HEIGHT = 80;
|
||||||
|
export const DEFAULT_DATE = '01 Jan, 1970 | 05:30 am';
|
||||||
|
export const DEFAULT_COLOR = 'var(--navi-color-green-bg)';
|
||||||
|
|
||||||
export const FEEDBACK_TYPES_OPTIONS = [
|
export const FEEDBACK_TYPES_OPTIONS = [
|
||||||
{ value: 'NOT_CONTACTED', label: 'Not Contacted' },
|
{ value: 'NOT_CONTACTED', label: 'Not Contacted' },
|
||||||
@@ -86,7 +89,7 @@ export const defaultAllCasesPageRequest: AllCasesPageRequest = {
|
|||||||
interactionStatuses: [],
|
interactionStatuses: [],
|
||||||
dpdBuckets: [],
|
dpdBuckets: [],
|
||||||
posAmountRanges: [],
|
posAmountRanges: [],
|
||||||
paymentStatus: ['ALL']
|
paymentStatus: []
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultAllCasesRequestFields = {
|
export const defaultAllCasesRequestFields = {
|
||||||
@@ -177,7 +180,11 @@ export const FeedbackTypesCodeMap = {
|
|||||||
PROMISE_TO_PAY_LATER: { color: 'green', label: 'Promise to pay later' },
|
PROMISE_TO_PAY_LATER: { color: 'green', label: 'Promise to pay later' },
|
||||||
OUT_OF_NETWORK: { color: 'red', label: 'Out of network' },
|
OUT_OF_NETWORK: { color: 'red', label: 'Out of network' },
|
||||||
NOT_AVAILABLE: { color: 'blue', label: 'Not Available' },
|
NOT_AVAILABLE: { color: 'blue', label: 'Not Available' },
|
||||||
MISSED_CALL: { color: 'blue', label: 'Missed Call' }
|
MISSED_CALL: { color: 'blue', label: 'Missed Call' },
|
||||||
|
PAID_ON_CALL: { color: 'yellow', label: 'Paid on call' },
|
||||||
|
PTP_FROM_FRIENDS_OR_FAMILY: { color: 'green', label: 'PTP from friends and family' },
|
||||||
|
REQUESTED_VISIT: { color: 'green', label: 'Requested visit' },
|
||||||
|
FRAUD: { color: 'red', label: 'Fraud' }
|
||||||
} as { [key: string]: CodeMap };
|
} as { [key: string]: CodeMap };
|
||||||
|
|
||||||
export const CasesDetailsFeedbackTypesCodeMap = {
|
export const CasesDetailsFeedbackTypesCodeMap = {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IPagination, ITableData, PageRequest } from '../../../components/interfaces';
|
import { IPagination, ITableData, PageRequest } from '../../../components/interfaces';
|
||||||
import { TagColors } from '@navi/web-ui/lib/primitives/Tag/types';
|
import { TagColors, TagVariants } from '@navi/web-ui/lib/primitives/Tag/types';
|
||||||
|
|
||||||
export interface ICasesState extends ITableData {
|
export interface ICasesState extends ITableData {
|
||||||
casesData: AllCasesSummary[] | null;
|
casesData: AllCasesSummary[] | null;
|
||||||
@@ -85,3 +85,11 @@ export interface AllCasesApiResponseData {
|
|||||||
data: AllCasesSummary[];
|
data: AllCasesSummary[];
|
||||||
pages: IPagination;
|
pages: IPagination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ICustomTagProps {
|
||||||
|
label: string;
|
||||||
|
color: TagColors;
|
||||||
|
variant: TagVariants;
|
||||||
|
labelClass: string;
|
||||||
|
time: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,27 +21,49 @@ const initialState = {
|
|||||||
paymentStatus: {
|
paymentStatus: {
|
||||||
options: PAYMENT_STATUS_OPTIONS,
|
options: PAYMENT_STATUS_OPTIONS,
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
label: 'Payment Status'
|
label: 'Payment Status',
|
||||||
|
key: 'paymentStatus'
|
||||||
},
|
},
|
||||||
interactionStatuses: {
|
interactionStatuses: {
|
||||||
options: FEEDBACK_TYPES_OPTIONS,
|
options: FEEDBACK_TYPES_OPTIONS,
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
label: 'Feedback'
|
label: 'Feedback'
|
||||||
},
|
},
|
||||||
|
teleInteractionStatuses: {
|
||||||
|
options: [],
|
||||||
|
multiSelect: true,
|
||||||
|
label: 'Tele Feedback',
|
||||||
|
key: 'teleInteractionStatuses'
|
||||||
|
},
|
||||||
|
fieldInteractionStatuses: {
|
||||||
|
options: [],
|
||||||
|
multiSelect: true,
|
||||||
|
label: 'Field Feedback',
|
||||||
|
key: 'fieldInteractionStatuses'
|
||||||
|
},
|
||||||
|
allocatedFieldAgent: {
|
||||||
|
options: [],
|
||||||
|
multiSelect: true,
|
||||||
|
label: 'Allocated FE',
|
||||||
|
key: 'allocatedFieldAgent'
|
||||||
|
},
|
||||||
dpdDuringAllocationFilters: {
|
dpdDuringAllocationFilters: {
|
||||||
options: DPD_BUCKETS_OPTIONS,
|
options: DPD_BUCKETS_OPTIONS,
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
label: 'DPD During Allocation'
|
label: 'DPD During Allocation',
|
||||||
|
key: 'dpdDuringAllocationFilters'
|
||||||
},
|
},
|
||||||
assignedAtFilters: {
|
assignedAtFilters: {
|
||||||
options: DATE_OF_ALLOCATION,
|
options: DATE_OF_ALLOCATION,
|
||||||
multiSelect: false,
|
multiSelect: false,
|
||||||
label: 'Allocation Date'
|
label: 'Allocation Date',
|
||||||
|
key: 'assignedAtFilters'
|
||||||
},
|
},
|
||||||
states: {
|
states: {
|
||||||
options: [],
|
options: [],
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
label: 'State of Customers'
|
label: 'State of Customers',
|
||||||
|
key: 'states'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -93,10 +115,25 @@ const casesSlice = createSlice({
|
|||||||
staticFilters.dpdDuringAllocationFilters;
|
staticFilters.dpdDuringAllocationFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (staticFilters?.teleInteractionStatuses) {
|
||||||
|
state.casesTable.filters.schema.teleInteractionStatuses.options =
|
||||||
|
staticFilters?.teleInteractionStatuses;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (staticFilters?.fieldInteractionStatuses) {
|
||||||
|
state.casesTable.filters.schema.fieldInteractionStatuses.options =
|
||||||
|
staticFilters?.fieldInteractionStatuses;
|
||||||
|
}
|
||||||
|
|
||||||
if (dynamicFilters?.stateFilters) {
|
if (dynamicFilters?.stateFilters) {
|
||||||
state.casesTable.filters.schema.states.options = dynamicFilters.stateFilters;
|
state.casesTable.filters.schema.states.options = dynamicFilters.stateFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dynamicFilters?.allocatedFieldAgentFilters) {
|
||||||
|
state.casesTable.filters.schema.allocatedFieldAgent.options =
|
||||||
|
dynamicFilters?.allocatedFieldAgentFilters;
|
||||||
|
}
|
||||||
|
|
||||||
state.casesTable.casesData = caseSummaryPaginatedResponse?.data;
|
state.casesTable.casesData = caseSummaryPaginatedResponse?.data;
|
||||||
|
|
||||||
state.casesTable.pagination = {
|
state.casesTable.pagination = {
|
||||||
|
|||||||
Reference in New Issue
Block a user