mautourco-components 0.2.44 → 0.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/atoms/Inputs/Input/Input.js +1 -1
- package/dist/components/organisms/QuoteHeader/QuoteHeader.d.ts +1 -1
- package/dist/components/organisms/QuoteHeader/QuoteHeader.js +38 -8
- package/dist/components/organisms/Table/Table.css +5 -0
- package/dist/components/organisms/Table/columns/booking-columns.d.ts +2 -2
- package/dist/components/organisms/Table/columns/booking-columns.js +17 -4
- package/dist/components/organisms/Table/columns/index.d.ts +5 -4
- package/dist/components/organisms/Table/columns/quotation-columns.d.ts +3 -2
- package/dist/components/organisms/Table/columns/quotation-columns.js +18 -5
- package/package.json +1 -1
- package/src/components/atoms/Inputs/Input/Input.tsx +1 -1
- package/src/components/organisms/QuoteHeader/QuoteHeader.tsx +45 -9
- package/src/components/organisms/Table/Table.css +5 -0
- package/src/components/organisms/Table/columns/booking-columns.tsx +34 -14
- package/src/components/organisms/Table/columns/quotation-columns.tsx +39 -16
|
@@ -11,6 +11,6 @@ var Input = function (_a) {
|
|
|
11
11
|
disabled: 'input-field--disabled',
|
|
12
12
|
};
|
|
13
13
|
var inputClasses = "".concat(baseClasses, " ").concat(variantClasses[variant], " ").concat(icon ? "input-field--with-icon input-field--icon-".concat(iconPosition) : '', " ").concat(className).trim();
|
|
14
|
-
return (_jsxs("div", { className: "input-wrapper ".concat(icon ? 'input-wrapper--with-icon' : '').trim(), children: [icon && iconPosition === 'leading' && (_jsx("span", { className: "input-icon input-icon--leading", children: _jsx(Icon, { name: icon, size: "sm" }) })), _jsx("input", { id: id, type: type, className: inputClasses, placeholder: placeholder, value: value, disabled: disabled || variant === 'disabled',
|
|
14
|
+
return (_jsxs("div", { className: "input-wrapper ".concat(icon ? 'input-wrapper--with-icon' : '').trim(), children: [icon && iconPosition === 'leading' && (_jsx("span", { className: "input-icon input-icon--leading", children: _jsx(Icon, { name: icon, size: "sm" }) })), _jsx("input", { id: id, type: type, className: inputClasses, placeholder: placeholder, value: value, disabled: disabled || variant === 'disabled', onInput: onChange, onFocus: onFocus, onBlur: onBlur }), icon && iconPosition === 'trailing' && (_jsx("span", { className: "input-icon input-icon--trailing", children: _jsx(Icon, { name: icon, size: "sm" }) }))] }));
|
|
15
15
|
};
|
|
16
16
|
export default Input;
|
|
@@ -8,6 +8,6 @@ export interface QuoteHeaderProps {
|
|
|
8
8
|
/** Callback to create a new quote */
|
|
9
9
|
onNewQuote: () => void;
|
|
10
10
|
onFilterChange?: (filter: FilterType, value: string) => void;
|
|
11
|
-
currentFilter
|
|
11
|
+
currentFilter?: Record<FilterType, string>;
|
|
12
12
|
}
|
|
13
13
|
export declare function QuoteHeader(props: QuoteHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -21,7 +21,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
21
21
|
return t;
|
|
22
22
|
};
|
|
23
23
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
24
|
-
import
|
|
24
|
+
import debounce from 'lodash/debounce';
|
|
25
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
25
26
|
import Button from '../../atoms/Button/Button';
|
|
26
27
|
import DropdownInput from '../../atoms/Inputs/DropdownInput/DropdownInput';
|
|
27
28
|
import Input from '../../atoms/Inputs/Input/Input';
|
|
@@ -45,10 +46,43 @@ var filterConfig = {
|
|
|
45
46
|
export function QuoteHeader(props) {
|
|
46
47
|
var _a;
|
|
47
48
|
var _b = props.current, current = _b === void 0 ? 'quotation' : _b, currentFilter = props.currentFilter, onNavigate = props.onNavigate, onNewQuote = props.onNewQuote, onFilterChange = props.onFilterChange;
|
|
48
|
-
var _c = useState(currentFilter
|
|
49
|
+
var _c = useState(currentFilter || {
|
|
50
|
+
date: '',
|
|
51
|
+
clientType: '',
|
|
52
|
+
fileStatus: '',
|
|
53
|
+
search: '',
|
|
54
|
+
}), currentValue = _c[0], setCurrentValue = _c[1];
|
|
49
55
|
var _d = useState((_a = currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.search) !== null && _a !== void 0 ? _a : ''), searchValue = _d[0], setSearchValue = _d[1];
|
|
56
|
+
// Create a ref to store the debounced function
|
|
57
|
+
var debouncedFilterChangeRef = useRef(debounce(function (value) {
|
|
58
|
+
onFilterChange === null || onFilterChange === void 0 ? void 0 : onFilterChange('search', value);
|
|
59
|
+
setCurrentValue(function (prev) { return (__assign(__assign({}, prev), { search: value })); });
|
|
60
|
+
}, 500));
|
|
61
|
+
// Update the debounced function when onFilterChange changes
|
|
50
62
|
useEffect(function () {
|
|
51
|
-
|
|
63
|
+
// Cancel the previous debounced function
|
|
64
|
+
debouncedFilterChangeRef.current.cancel();
|
|
65
|
+
// Create a new debounced function
|
|
66
|
+
debouncedFilterChangeRef.current = debounce(function (value) {
|
|
67
|
+
onFilterChange === null || onFilterChange === void 0 ? void 0 : onFilterChange('search', value);
|
|
68
|
+
setCurrentValue(function (prev) { return (__assign(__assign({}, prev), { search: value })); });
|
|
69
|
+
}, 500);
|
|
70
|
+
}, [onFilterChange]);
|
|
71
|
+
// Cleanup debounced function on unmount
|
|
72
|
+
useEffect(function () {
|
|
73
|
+
return function () {
|
|
74
|
+
debouncedFilterChangeRef.current.cancel();
|
|
75
|
+
};
|
|
76
|
+
}, []);
|
|
77
|
+
var handleInputChange = useCallback(function (e) {
|
|
78
|
+
var value = e.target.value;
|
|
79
|
+
// Update input value immediately for responsive UI
|
|
80
|
+
setSearchValue(value);
|
|
81
|
+
// Debounce the filter change callback
|
|
82
|
+
debouncedFilterChangeRef.current(value);
|
|
83
|
+
}, []);
|
|
84
|
+
useEffect(function () {
|
|
85
|
+
if (currentFilter && Object.keys(currentFilter).length > 0) {
|
|
52
86
|
var search = currentFilter.search, rest = __rest(currentFilter, ["search"]);
|
|
53
87
|
setCurrentValue(rest);
|
|
54
88
|
setSearchValue(search);
|
|
@@ -58,11 +92,7 @@ export function QuoteHeader(props) {
|
|
|
58
92
|
setSearchValue('');
|
|
59
93
|
}
|
|
60
94
|
}, [currentFilter]);
|
|
61
|
-
return (_jsxs("div", { className: "quote-header", children: [_jsx(Heading, { level: 4, as: "h1", className: "quote-header__title", color: "accent", children: "Quotation & Booking" }), _jsxs("div", { className: "flex gap-4", children: [_jsx(Button, { variant: current === 'quotation' ? 'primary' : 'outline-primary', className: "quote-header__button", onClick: function () { return onNavigate('quotation'); }, children: "Quotation" }), _jsx(Button, { variant: current === 'booking' ? 'primary' : 'outline-primary', className: "quote-header__button", onClick: function () { return onNavigate('booking'); }, children: "Booking" })] }), _jsxs("div", { className: "quote-header__search-container", children: [_jsx(Input, { placeholder: "Search", icon: "search", iconPosition: "leading", className: "quote-header__search", value: searchValue, onChange: function (
|
|
62
|
-
onFilterChange === null || onFilterChange === void 0 ? void 0 : onFilterChange('search', e.target.value);
|
|
63
|
-
setCurrentValue(__assign(__assign({}, currentValue), { search: e.target.value }));
|
|
64
|
-
setSearchValue(e.target.value);
|
|
65
|
-
} }), _jsx(Button, { variant: "primary", leadingIcon: "plus-circle", iconSize: "md", size: "sm", onClick: onNewQuote, children: "New quote" })] }), _jsx("div", { className: "quote-header__filters", children: Object.entries(filterConfig).map(function (_a) {
|
|
95
|
+
return (_jsxs("div", { className: "quote-header", children: [_jsx(Heading, { level: 4, as: "h1", className: "quote-header__title", color: "accent", children: "Quotation & Booking" }), _jsxs("div", { className: "flex gap-4", children: [_jsx(Button, { variant: current === 'quotation' ? 'primary' : 'outline-primary', className: "quote-header__button", onClick: function () { return onNavigate('quotation'); }, children: "Quotation" }), _jsx(Button, { variant: current === 'booking' ? 'primary' : 'outline-primary', className: "quote-header__button", onClick: function () { return onNavigate('booking'); }, children: "Booking" })] }), _jsxs("div", { className: "quote-header__search-container", children: [_jsx(Input, { placeholder: "Search", icon: "search", iconPosition: "leading", className: "quote-header__search", value: searchValue, onChange: handleInputChange }), _jsx(Button, { variant: "primary", leadingIcon: "plus-circle", iconSize: "md", size: "sm", onClick: onNewQuote, children: "New quote" })] }), _jsx("div", { className: "quote-header__filters", children: Object.entries(filterConfig).map(function (_a) {
|
|
66
96
|
var key = _a[0], value = _a[1];
|
|
67
97
|
return (_jsx(DropdownInput, { placeholder: value.placeholder, options: value.options, value: currentValue[key], onSelect: function (value) {
|
|
68
98
|
var _a;
|
|
@@ -2,6 +2,6 @@ import { ActionDropdownType } from '@/src/types/table';
|
|
|
2
2
|
import { BookingListItem } from '@/src/types/table/booking.types';
|
|
3
3
|
import { ColumnType } from '../TableCell';
|
|
4
4
|
export declare const bookingColumns: (params: {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
onAction?: (action: ActionDropdownType) => void;
|
|
6
|
+
keywords?: string;
|
|
7
7
|
}) => ColumnType<BookingListItem>[];
|
|
@@ -6,19 +6,32 @@ import { DateDisplay } from '../../../molecules/DateDisplay/DateDisplay';
|
|
|
6
6
|
import { PaxChips } from '../../../molecules/PaxChips/PaxChips';
|
|
7
7
|
import { actionDropdownData } from '../constant';
|
|
8
8
|
export var bookingColumns = function (_a) {
|
|
9
|
-
var
|
|
9
|
+
var onAction = _a.onAction, _b = _a.keywords, keywords = _b === void 0 ? '' : _b;
|
|
10
10
|
return [
|
|
11
11
|
{
|
|
12
12
|
header: 'Quote nb.',
|
|
13
13
|
key: 'booking_id',
|
|
14
14
|
width: 150,
|
|
15
|
-
cell: function (value) {
|
|
15
|
+
cell: function (value) {
|
|
16
|
+
if (value === void 0) { value = ''; }
|
|
17
|
+
var currentValue = String(value);
|
|
18
|
+
var regex = new RegExp("(".concat(keywords !== null && keywords !== void 0 ? keywords : '', ")"), 'gi');
|
|
19
|
+
if (regex.test(currentValue)) {
|
|
20
|
+
return (_jsx(Text, { variant: "medium", size: "sm", children: _jsx("span", { dangerouslySetInnerHTML: {
|
|
21
|
+
__html: currentValue.replace(regex, "<span class=\"text--highlight\">$1</span>"),
|
|
22
|
+
} }) }));
|
|
23
|
+
}
|
|
24
|
+
return (_jsx(Text, { variant: "medium", size: "sm", children: currentValue }));
|
|
25
|
+
},
|
|
16
26
|
},
|
|
17
27
|
{
|
|
18
28
|
header: 'Client name',
|
|
19
29
|
key: 'agency_name',
|
|
20
30
|
width: 150,
|
|
21
|
-
cell: function (value) {
|
|
31
|
+
cell: function (value) {
|
|
32
|
+
if (value === void 0) { value = ''; }
|
|
33
|
+
return (_jsx(Text, { variant: "medium", size: "sm", children: value }));
|
|
34
|
+
},
|
|
22
35
|
},
|
|
23
36
|
{
|
|
24
37
|
header: 'Type',
|
|
@@ -61,7 +74,7 @@ export var bookingColumns = function (_a) {
|
|
|
61
74
|
key: 'actions',
|
|
62
75
|
width: 232,
|
|
63
76
|
cell: function (_value, raw) {
|
|
64
|
-
return (_jsx("div", { children: _jsxs("div", { className: "flex items-center gap-x-8", children: [_jsxs("div", { className: "flex items-center gap-x-3", children: [_jsx(Button, { variant: "secondary", size: "sm", className: "w-[89px]", children: "Proforma" }), _jsx(Button, { variant: "outline-secondary", size: "sm", className: "w-[89px]", children: "Voucher" })] }), _jsx(ActionDropdown, { data: actionDropdownData(onAction) })] }) }));
|
|
77
|
+
return (_jsx("div", { children: _jsxs("div", { className: "flex items-center gap-x-8", children: [_jsxs("div", { className: "flex items-center gap-x-3", children: [_jsx(Button, { variant: "secondary", size: "sm", className: "w-[89px]", children: "Proforma" }), _jsx(Button, { variant: "outline-secondary", size: "sm", className: "w-[89px]", children: "Voucher" })] }), _jsx(ActionDropdown, { data: actionDropdownData(onAction !== null && onAction !== void 0 ? onAction : (function () { })) })] }) }));
|
|
65
78
|
},
|
|
66
79
|
},
|
|
67
80
|
];
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
declare const columns: {
|
|
2
2
|
quotation: (params: {
|
|
3
|
-
onExpand
|
|
4
|
-
onAction
|
|
3
|
+
onExpand?: (value?: import("../../../..").QuotationListItem) => void;
|
|
4
|
+
onAction?: (data: {
|
|
5
5
|
isChild?: boolean;
|
|
6
6
|
quote: import("../../../..").QuotationListItem;
|
|
7
7
|
}) => (action: import("../../../..").ActionDropdownType) => void;
|
|
8
|
+
keywords?: string;
|
|
8
9
|
}) => import("../TableCell").ColumnType<import("../../../..").QuotationListItem>[];
|
|
9
10
|
detailResume: (params?: {
|
|
10
11
|
onRemove?: (value: import("../../../..").DetailResumeItem, index?: number) => void;
|
|
11
12
|
}) => import("../TableCell").ColumnType<import("../../../..").DetailResumeItem>[];
|
|
12
13
|
booking: (params: {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
onAction?: (action: import("../../../..").ActionDropdownType) => void;
|
|
15
|
+
keywords?: string;
|
|
15
16
|
}) => import("../TableCell").ColumnType<import("../../../../types/table/booking.types").BookingListItem>[];
|
|
16
17
|
bookingCancelService: (params?: {
|
|
17
18
|
onRemove?: (value: import("../../../..").DetailResumeItem, index?: number, childIndex?: number) => void;
|
|
@@ -2,9 +2,10 @@ import { ActionDropdownType } from '@/src/types/table/action-dropdown-type.types
|
|
|
2
2
|
import { QuotationListItem } from '@/src/types/table/quotation.types';
|
|
3
3
|
import { ColumnType } from '../TableCell';
|
|
4
4
|
export declare const quotationColumns: (params: {
|
|
5
|
-
onExpand
|
|
6
|
-
onAction
|
|
5
|
+
onExpand?: (value?: QuotationListItem) => void;
|
|
6
|
+
onAction?: (data: {
|
|
7
7
|
isChild?: boolean;
|
|
8
8
|
quote: QuotationListItem;
|
|
9
9
|
}) => (action: ActionDropdownType) => void;
|
|
10
|
+
keywords?: string;
|
|
10
11
|
}) => ColumnType<QuotationListItem>[];
|
|
@@ -7,20 +7,33 @@ import { DateDisplay } from '../../../molecules/DateDisplay/DateDisplay';
|
|
|
7
7
|
import { cn } from '../../../../lib/utils';
|
|
8
8
|
import { actionDropdownData, chipVariant, clientTypeMap } from '../constant';
|
|
9
9
|
export var quotationColumns = function (_a) {
|
|
10
|
-
var onExpand = _a.onExpand, onAction = _a.onAction;
|
|
10
|
+
var onExpand = _a.onExpand, onAction = _a.onAction, _b = _a.keywords, keywords = _b === void 0 ? '' : _b;
|
|
11
11
|
return [
|
|
12
12
|
{
|
|
13
13
|
header: 'Quote nb.',
|
|
14
14
|
key: 'file_nb',
|
|
15
15
|
width: 150,
|
|
16
|
-
cell: function (value) {
|
|
16
|
+
cell: function (value) {
|
|
17
|
+
if (value === void 0) { value = ''; }
|
|
18
|
+
var currentValue = String(value);
|
|
19
|
+
var regex = new RegExp("(".concat(keywords !== null && keywords !== void 0 ? keywords : '', ")"), 'gi');
|
|
20
|
+
if (regex.test(currentValue)) {
|
|
21
|
+
return (_jsx(Text, { variant: "medium", size: "sm", children: _jsx("span", { dangerouslySetInnerHTML: {
|
|
22
|
+
__html: currentValue.replace(regex, "<span class=\"text--highlight\">$1</span>"),
|
|
23
|
+
} }) }));
|
|
24
|
+
}
|
|
25
|
+
return (_jsx(Text, { variant: "medium", size: "sm", children: currentValue }));
|
|
26
|
+
},
|
|
17
27
|
},
|
|
18
28
|
{
|
|
19
29
|
header: 'Client name',
|
|
20
30
|
key: 'agency_name',
|
|
21
31
|
width: 150,
|
|
22
32
|
cell: function (value, _raw, _index, childIndex) {
|
|
23
|
-
|
|
33
|
+
if (value === void 0) { value = ''; }
|
|
34
|
+
if (childIndex === undefined) {
|
|
35
|
+
return (_jsx(Text, { variant: "medium", size: "sm", children: value }));
|
|
36
|
+
}
|
|
24
37
|
},
|
|
25
38
|
},
|
|
26
39
|
{
|
|
@@ -70,12 +83,12 @@ export var quotationColumns = function (_a) {
|
|
|
70
83
|
key: 'actions',
|
|
71
84
|
width: 232,
|
|
72
85
|
cell: function (_value, raw, _index, childIndex) {
|
|
73
|
-
var _a;
|
|
86
|
+
var _a, _b;
|
|
74
87
|
var hasChildren = raw.children && raw.children.length > 0;
|
|
75
88
|
var isExpanded = (_a = raw.children) === null || _a === void 0 ? void 0 : _a.some(function (child) { return child.visible; });
|
|
76
89
|
var buttonLabel = isExpanded ? 'See less' : 'See more';
|
|
77
90
|
var isOnRequest = raw.status.toLowerCase() === 'on request';
|
|
78
|
-
return (_jsx("div", { children: hasChildren ? (_jsx(Button, { variant: "outline-primary", size: "sm", trailingIcon: "chevron-down", className: cn('table__button', isExpanded && 'table__button-expanded'), onClick: function () { return onExpand(raw); }, children: buttonLabel })) : (_jsxs("div", { className: "flex items-center gap-x-8", children: [_jsx(Button, { variant: isOnRequest ? 'outline-secondary' : 'secondary', size: "sm", className: "table__button", children: isOnRequest ? 'Request to book' : 'Book now' }), _jsx(ActionDropdown, { data: actionDropdownData(onAction({ isChild: childIndex !== undefined, quote: raw })) })] })) }));
|
|
91
|
+
return (_jsx("div", { children: hasChildren ? (_jsx(Button, { variant: "outline-primary", size: "sm", trailingIcon: "chevron-down", className: cn('table__button', isExpanded && 'table__button-expanded'), onClick: function () { return onExpand === null || onExpand === void 0 ? void 0 : onExpand(raw); }, children: buttonLabel })) : (_jsxs("div", { className: "flex items-center gap-x-8", children: [_jsx(Button, { variant: isOnRequest ? 'outline-secondary' : 'secondary', size: "sm", className: "table__button", children: isOnRequest ? 'Request to book' : 'Book now' }), _jsx(ActionDropdown, { data: actionDropdownData((_b = onAction === null || onAction === void 0 ? void 0 : onAction({ isChild: childIndex !== undefined, quote: raw })) !== null && _b !== void 0 ? _b : (function () { })) })] })) }));
|
|
79
92
|
},
|
|
80
93
|
},
|
|
81
94
|
];
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import debounce from 'lodash/debounce';
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
3
|
import Button from '../../atoms/Button/Button';
|
|
3
4
|
import DropdownInput from '../../atoms/Inputs/DropdownInput/DropdownInput';
|
|
4
5
|
import Input from '../../atoms/Inputs/Input/Input';
|
|
@@ -24,7 +25,7 @@ export interface QuoteHeaderProps {
|
|
|
24
25
|
|
|
25
26
|
onFilterChange?: (filter: FilterType, value: string) => void;
|
|
26
27
|
|
|
27
|
-
currentFilter
|
|
28
|
+
currentFilter?: Record<FilterType, string>;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
const filterConfig = {
|
|
@@ -51,12 +52,51 @@ export function QuoteHeader(props: QuoteHeaderProps) {
|
|
|
51
52
|
onFilterChange,
|
|
52
53
|
} = props;
|
|
53
54
|
const [currentValue, setCurrentValue] = useState<Record<FilterType, string>>(
|
|
54
|
-
currentFilter
|
|
55
|
+
currentFilter || {
|
|
56
|
+
date: '',
|
|
57
|
+
clientType: '',
|
|
58
|
+
fileStatus: '',
|
|
59
|
+
search: '',
|
|
60
|
+
}
|
|
55
61
|
);
|
|
56
62
|
const [searchValue, setSearchValue] = useState<string>(currentFilter?.search ?? '');
|
|
57
63
|
|
|
64
|
+
// Create a ref to store the debounced function
|
|
65
|
+
const debouncedFilterChangeRef = useRef(
|
|
66
|
+
debounce((value: string) => {
|
|
67
|
+
onFilterChange?.('search', value);
|
|
68
|
+
setCurrentValue((prev) => ({ ...prev, search: value }));
|
|
69
|
+
}, 500)
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Update the debounced function when onFilterChange changes
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
// Cancel the previous debounced function
|
|
75
|
+
debouncedFilterChangeRef.current.cancel();
|
|
76
|
+
// Create a new debounced function
|
|
77
|
+
debouncedFilterChangeRef.current = debounce((value: string) => {
|
|
78
|
+
onFilterChange?.('search', value);
|
|
79
|
+
setCurrentValue((prev) => ({ ...prev, search: value }));
|
|
80
|
+
}, 500);
|
|
81
|
+
}, [onFilterChange]);
|
|
82
|
+
|
|
83
|
+
// Cleanup debounced function on unmount
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
return () => {
|
|
86
|
+
debouncedFilterChangeRef.current.cancel();
|
|
87
|
+
};
|
|
88
|
+
}, []);
|
|
89
|
+
|
|
90
|
+
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
|
91
|
+
const value = e.target.value;
|
|
92
|
+
// Update input value immediately for responsive UI
|
|
93
|
+
setSearchValue(value);
|
|
94
|
+
// Debounce the filter change callback
|
|
95
|
+
debouncedFilterChangeRef.current(value);
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
58
98
|
useEffect(() => {
|
|
59
|
-
if (Object.keys(currentFilter
|
|
99
|
+
if (currentFilter && Object.keys(currentFilter).length > 0) {
|
|
60
100
|
const { search, ...rest } = currentFilter;
|
|
61
101
|
setCurrentValue(rest as Record<FilterType, string>);
|
|
62
102
|
setSearchValue(search);
|
|
@@ -92,11 +132,7 @@ export function QuoteHeader(props: QuoteHeaderProps) {
|
|
|
92
132
|
iconPosition="leading"
|
|
93
133
|
className="quote-header__search"
|
|
94
134
|
value={searchValue}
|
|
95
|
-
onChange={
|
|
96
|
-
onFilterChange?.('search', e.target.value);
|
|
97
|
-
setCurrentValue({ ...currentValue, search: e.target.value });
|
|
98
|
-
setSearchValue(e.target.value);
|
|
99
|
-
}}
|
|
135
|
+
onChange={handleInputChange}
|
|
100
136
|
/>
|
|
101
137
|
<Button
|
|
102
138
|
variant="primary"
|
|
@@ -9,28 +9,48 @@ import { ColumnType } from '../TableCell';
|
|
|
9
9
|
import { actionDropdownData } from '../constant';
|
|
10
10
|
|
|
11
11
|
export const bookingColumns: (params: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}) => ColumnType<BookingListItem>[] = ({
|
|
12
|
+
onAction?: (action: ActionDropdownType) => void;
|
|
13
|
+
keywords?: string;
|
|
14
|
+
}) => ColumnType<BookingListItem>[] = ({ onAction, keywords = '' }) => [
|
|
15
15
|
{
|
|
16
16
|
header: 'Quote nb.',
|
|
17
17
|
key: 'booking_id',
|
|
18
18
|
width: 150,
|
|
19
|
-
cell: (value) =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
cell: (value = '') => {
|
|
20
|
+
const currentValue = String(value as string);
|
|
21
|
+
const regex = new RegExp(`(${keywords ?? ''})`, 'gi');
|
|
22
|
+
if (regex.test(currentValue)) {
|
|
23
|
+
return (
|
|
24
|
+
<Text variant="medium" size="sm">
|
|
25
|
+
<span
|
|
26
|
+
dangerouslySetInnerHTML={{
|
|
27
|
+
__html: currentValue.replace(
|
|
28
|
+
regex,
|
|
29
|
+
`<span class="text--highlight">$1</span>`
|
|
30
|
+
),
|
|
31
|
+
}}
|
|
32
|
+
/>
|
|
33
|
+
</Text>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return (
|
|
37
|
+
<Text variant="medium" size="sm">
|
|
38
|
+
{currentValue}
|
|
39
|
+
</Text>
|
|
40
|
+
);
|
|
41
|
+
},
|
|
24
42
|
},
|
|
25
43
|
{
|
|
26
44
|
header: 'Client name',
|
|
27
45
|
key: 'agency_name',
|
|
28
46
|
width: 150,
|
|
29
|
-
cell: (value) =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
cell: (value = '') => {
|
|
48
|
+
return (
|
|
49
|
+
<Text variant="medium" size="sm">
|
|
50
|
+
{value as string}
|
|
51
|
+
</Text>
|
|
52
|
+
);
|
|
53
|
+
},
|
|
34
54
|
},
|
|
35
55
|
{
|
|
36
56
|
header: 'Type',
|
|
@@ -92,7 +112,7 @@ export const bookingColumns: (params: {
|
|
|
92
112
|
Voucher
|
|
93
113
|
</Button>
|
|
94
114
|
</div>
|
|
95
|
-
<ActionDropdown data={actionDropdownData(onAction)} />
|
|
115
|
+
<ActionDropdown data={actionDropdownData(onAction ?? (() => {}))} />
|
|
96
116
|
</div>
|
|
97
117
|
</div>
|
|
98
118
|
);
|
|
@@ -10,32 +10,54 @@ import { ColumnType } from '../TableCell';
|
|
|
10
10
|
import { actionDropdownData, chipVariant, clientTypeMap } from '../constant';
|
|
11
11
|
|
|
12
12
|
export const quotationColumns: (params: {
|
|
13
|
-
onExpand
|
|
14
|
-
onAction
|
|
13
|
+
onExpand?: (value?: QuotationListItem) => void;
|
|
14
|
+
onAction?: (data: {
|
|
15
15
|
isChild?: boolean;
|
|
16
16
|
quote: QuotationListItem;
|
|
17
17
|
}) => (action: ActionDropdownType) => void;
|
|
18
|
-
|
|
18
|
+
keywords?: string;
|
|
19
|
+
}) => ColumnType<QuotationListItem>[] = ({ onExpand, onAction, keywords = '' }) => [
|
|
19
20
|
{
|
|
20
21
|
header: 'Quote nb.',
|
|
21
22
|
key: 'file_nb',
|
|
22
23
|
width: 150,
|
|
23
|
-
cell: (value) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
cell: (value = '') => {
|
|
25
|
+
const currentValue = String(value as string);
|
|
26
|
+
const regex = new RegExp(`(${keywords ?? ''})`, 'gi');
|
|
27
|
+
if (regex.test(currentValue)) {
|
|
28
|
+
return (
|
|
29
|
+
<Text variant="medium" size="sm">
|
|
30
|
+
<span
|
|
31
|
+
dangerouslySetInnerHTML={{
|
|
32
|
+
__html: currentValue.replace(
|
|
33
|
+
regex,
|
|
34
|
+
`<span class="text--highlight">$1</span>`
|
|
35
|
+
),
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
38
|
+
</Text>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return (
|
|
42
|
+
<Text variant="medium" size="sm">
|
|
43
|
+
{currentValue}
|
|
44
|
+
</Text>
|
|
45
|
+
);
|
|
46
|
+
},
|
|
28
47
|
},
|
|
29
48
|
{
|
|
30
49
|
header: 'Client name',
|
|
31
50
|
key: 'agency_name',
|
|
32
51
|
width: 150,
|
|
33
|
-
cell: (value, _raw, _index, childIndex) =>
|
|
34
|
-
childIndex === undefined
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
cell: (value = '', _raw, _index, childIndex) => {
|
|
53
|
+
if (childIndex === undefined) {
|
|
54
|
+
return (
|
|
55
|
+
<Text variant="medium" size="sm">
|
|
56
|
+
{value as string}
|
|
57
|
+
</Text>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
39
61
|
},
|
|
40
62
|
{
|
|
41
63
|
header: 'File status',
|
|
@@ -138,7 +160,7 @@ export const quotationColumns: (params: {
|
|
|
138
160
|
size="sm"
|
|
139
161
|
trailingIcon="chevron-down"
|
|
140
162
|
className={cn('table__button', isExpanded && 'table__button-expanded')}
|
|
141
|
-
onClick={() => onExpand(raw)}>
|
|
163
|
+
onClick={() => onExpand?.(raw)}>
|
|
142
164
|
{buttonLabel}
|
|
143
165
|
</Button>
|
|
144
166
|
) : (
|
|
@@ -151,7 +173,8 @@ export const quotationColumns: (params: {
|
|
|
151
173
|
</Button>
|
|
152
174
|
<ActionDropdown
|
|
153
175
|
data={actionDropdownData(
|
|
154
|
-
onAction({ isChild: childIndex !== undefined, quote: raw })
|
|
176
|
+
onAction?.({ isChild: childIndex !== undefined, quote: raw }) ??
|
|
177
|
+
(() => {})
|
|
155
178
|
)}
|
|
156
179
|
/>
|
|
157
180
|
</div>
|