@cwellt_software/cwellt-reactjs-lib 1.2.17 → 1.3.1
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/index.cjs.js +165 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.es.js +165 -1
- package/dist/src/components/custom/find-crewmember/CwFindCrewmemberComp.d.ts +18 -0
- package/dist/src/components/custom/find-crewmember/CwFindCrewmemberComp.d.ts.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/readme.md +119 -106
package/dist/index.cjs.js
CHANGED
|
@@ -9049,6 +9049,170 @@ const CwFindAirport = ({ handleChange, searchType = "OnlyDatabase", placeHolder
|
|
|
9049
9049
|
}, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeHolder, disabled: disabled, required: required, autoComplete: "off", "aria-expanded": showDropdown, "aria-haspopup": "listbox", role: "combobox", title: tooltipText }), (isLoading || isInitialLoading) && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected airport", variant: "icon", icon: "close", color: "neutral" })) : (jsxRuntime.jsx(CwIcon, { iconId: "control-tower" })) })] })] }), showDropdown && options.length > 0 && (jsxRuntime.jsx("div", { ref: dropdownRef, className: "cw-input-search-dropdown", role: "listbox", children: jsxRuntime.jsx("ul", { children: options.map((option, index) => (jsxRuntime.jsx("li", { className: index === highlightedIndex ? "highlighted" : "", onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
|
|
9050
9050
|
};
|
|
9051
9051
|
|
|
9052
|
+
const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", required = false, cblConfig, className = "", value, disabled = false, initialDisplayText, labelProps, alignProps, width }) => {
|
|
9053
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
9054
|
+
const [options, setOptions] = React.useState([]);
|
|
9055
|
+
const [crewmembers, setCrewmembers] = React.useState([]);
|
|
9056
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
9057
|
+
const [isInitialLoading, setIsInitialLoading] = React.useState(false);
|
|
9058
|
+
const [showDropdown, setShowDropdown] = React.useState(false);
|
|
9059
|
+
const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
|
|
9060
|
+
const [tooltipText, setTooltipText] = React.useState("");
|
|
9061
|
+
const inputRef = React.useRef(null);
|
|
9062
|
+
const dropdownRef = React.useRef(null);
|
|
9063
|
+
const searchTimeoutRef = React.useRef();
|
|
9064
|
+
const getDisplayText = React.useCallback((crew) => {
|
|
9065
|
+
return `${crew.threeLetterCode} - ${crew.lastName} ${crew.firstName}`;
|
|
9066
|
+
}, []);
|
|
9067
|
+
const fetchCrewmemberData = React.useCallback(async (crewmemberId) => {
|
|
9068
|
+
setIsInitialLoading(true);
|
|
9069
|
+
try {
|
|
9070
|
+
const response = await fetch(`${cblConfig}controls/cblFindCrew/cblFindCrew/GetCrewmember?crewmemberId=${crewmemberId}`);
|
|
9071
|
+
const result = await response.json();
|
|
9072
|
+
const display = getDisplayText(result);
|
|
9073
|
+
setCrewmembers([result]);
|
|
9074
|
+
setOptions([{ value: result.id, text: display }]);
|
|
9075
|
+
setInputValue(display);
|
|
9076
|
+
setTooltipText(display);
|
|
9077
|
+
}
|
|
9078
|
+
catch (error) {
|
|
9079
|
+
console.error("Error fetching crewmember data:", error);
|
|
9080
|
+
}
|
|
9081
|
+
finally {
|
|
9082
|
+
setIsInitialLoading(false);
|
|
9083
|
+
}
|
|
9084
|
+
}, [cblConfig, getDisplayText]);
|
|
9085
|
+
const searchCrewmembers = React.useCallback(async (searchText) => {
|
|
9086
|
+
if (searchText.length < 2) {
|
|
9087
|
+
setOptions([]);
|
|
9088
|
+
setCrewmembers([]);
|
|
9089
|
+
setShowDropdown(false);
|
|
9090
|
+
return;
|
|
9091
|
+
}
|
|
9092
|
+
setIsLoading(true);
|
|
9093
|
+
try {
|
|
9094
|
+
const response = await fetch(`${cblConfig}controls/cblFindCrew/cblFindCrew/SearchCrewCodeName?text=${encodeURIComponent(searchText)}`);
|
|
9095
|
+
const results = await response.json();
|
|
9096
|
+
const newOptions = results.map(crew => ({
|
|
9097
|
+
value: crew.id,
|
|
9098
|
+
text: getDisplayText(crew)
|
|
9099
|
+
}));
|
|
9100
|
+
setOptions(newOptions);
|
|
9101
|
+
setCrewmembers(results);
|
|
9102
|
+
setShowDropdown(newOptions.length > 0);
|
|
9103
|
+
setHighlightedIndex(-1);
|
|
9104
|
+
}
|
|
9105
|
+
catch (error) {
|
|
9106
|
+
console.error("Error searching crewmembers:", error);
|
|
9107
|
+
setOptions([]);
|
|
9108
|
+
setCrewmembers([]);
|
|
9109
|
+
setShowDropdown(false);
|
|
9110
|
+
}
|
|
9111
|
+
finally {
|
|
9112
|
+
setIsLoading(false);
|
|
9113
|
+
}
|
|
9114
|
+
}, [cblConfig, getDisplayText]);
|
|
9115
|
+
const debouncedSearch = React.useCallback((searchText) => {
|
|
9116
|
+
if (searchTimeoutRef.current) {
|
|
9117
|
+
window.clearTimeout(searchTimeoutRef.current);
|
|
9118
|
+
}
|
|
9119
|
+
searchTimeoutRef.current = window.setTimeout(() => {
|
|
9120
|
+
searchCrewmembers(searchText);
|
|
9121
|
+
}, 300);
|
|
9122
|
+
}, [searchCrewmembers]);
|
|
9123
|
+
const handleInputChange = (e) => {
|
|
9124
|
+
const newValue = e.target.value;
|
|
9125
|
+
setInputValue(newValue);
|
|
9126
|
+
if (newValue !== inputValue) {
|
|
9127
|
+
debouncedSearch(newValue);
|
|
9128
|
+
}
|
|
9129
|
+
};
|
|
9130
|
+
const handleOptionSelect = (optionValue) => {
|
|
9131
|
+
const selectedCrew = crewmembers.find(c => c.id === optionValue);
|
|
9132
|
+
if (!selectedCrew)
|
|
9133
|
+
return;
|
|
9134
|
+
setShowDropdown(false);
|
|
9135
|
+
const display = getDisplayText(selectedCrew);
|
|
9136
|
+
setInputValue(display);
|
|
9137
|
+
setTooltipText(display);
|
|
9138
|
+
handleChange(optionValue);
|
|
9139
|
+
};
|
|
9140
|
+
const handleKeyDown = (e) => {
|
|
9141
|
+
if (!showDropdown || options.length === 0)
|
|
9142
|
+
return;
|
|
9143
|
+
switch (e.key) {
|
|
9144
|
+
case "ArrowDown":
|
|
9145
|
+
e.preventDefault();
|
|
9146
|
+
setHighlightedIndex(prev => prev < options.length - 1 ? prev + 1 : 0);
|
|
9147
|
+
break;
|
|
9148
|
+
case "ArrowUp":
|
|
9149
|
+
e.preventDefault();
|
|
9150
|
+
setHighlightedIndex(prev => prev > 0 ? prev - 1 : options.length - 1);
|
|
9151
|
+
break;
|
|
9152
|
+
case "Enter":
|
|
9153
|
+
e.preventDefault();
|
|
9154
|
+
if (highlightedIndex >= 0 && highlightedIndex < options.length) {
|
|
9155
|
+
handleOptionSelect(options[highlightedIndex].value);
|
|
9156
|
+
}
|
|
9157
|
+
break;
|
|
9158
|
+
case "Escape":
|
|
9159
|
+
setShowDropdown(false);
|
|
9160
|
+
setHighlightedIndex(-1);
|
|
9161
|
+
break;
|
|
9162
|
+
}
|
|
9163
|
+
};
|
|
9164
|
+
React.useEffect(() => {
|
|
9165
|
+
const handleClickOutside = (event) => {
|
|
9166
|
+
if (dropdownRef.current &&
|
|
9167
|
+
!dropdownRef.current.contains(event.target) &&
|
|
9168
|
+
!inputRef.current?.contains(event.target)) {
|
|
9169
|
+
setShowDropdown(false);
|
|
9170
|
+
setHighlightedIndex(-1);
|
|
9171
|
+
}
|
|
9172
|
+
};
|
|
9173
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
9174
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
9175
|
+
}, []);
|
|
9176
|
+
React.useEffect(() => {
|
|
9177
|
+
if (value && value !== 0 && value !== -1) {
|
|
9178
|
+
if (initialDisplayText) {
|
|
9179
|
+
setInputValue(initialDisplayText);
|
|
9180
|
+
setTooltipText(initialDisplayText);
|
|
9181
|
+
}
|
|
9182
|
+
else {
|
|
9183
|
+
fetchCrewmemberData(value);
|
|
9184
|
+
}
|
|
9185
|
+
}
|
|
9186
|
+
}, [value, fetchCrewmemberData, initialDisplayText]);
|
|
9187
|
+
React.useEffect(() => {
|
|
9188
|
+
if (!value || value === 0 || value === -1) {
|
|
9189
|
+
setInputValue("");
|
|
9190
|
+
setTooltipText("");
|
|
9191
|
+
setOptions([]);
|
|
9192
|
+
setCrewmembers([]);
|
|
9193
|
+
}
|
|
9194
|
+
}, [value]);
|
|
9195
|
+
const handleInputFocus = () => {
|
|
9196
|
+
if (options.length > 0) {
|
|
9197
|
+
setShowDropdown(true);
|
|
9198
|
+
}
|
|
9199
|
+
};
|
|
9200
|
+
const handleClear = () => {
|
|
9201
|
+
setInputValue("");
|
|
9202
|
+
setTooltipText("");
|
|
9203
|
+
setOptions([]);
|
|
9204
|
+
setCrewmembers([]);
|
|
9205
|
+
setShowDropdown(false);
|
|
9206
|
+
handleChange(0);
|
|
9207
|
+
inputRef.current?.focus();
|
|
9208
|
+
};
|
|
9209
|
+
const direction = alignProps?.flexDirection || "row";
|
|
9210
|
+
return (jsxRuntime.jsxs("div", { className: `cw-search-input ${className}`, style: {
|
|
9211
|
+
...(width ? { width } : {}),
|
|
9212
|
+
...(labelProps?.labelWidth ? { '--label-width': labelProps.labelWidth } : {})
|
|
9213
|
+
}, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeHolder, disabled: disabled, required: required, autoComplete: "off", "aria-expanded": showDropdown, "aria-haspopup": "listbox", role: "combobox", title: tooltipText }), (isLoading || isInitialLoading) && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected crewmember", variant: "icon", icon: "close", color: "neutral" })) : (jsxRuntime.jsx(CwIcon, { iconId: "person" })) })] })] }), showDropdown && options.length > 0 && (jsxRuntime.jsx("div", { ref: dropdownRef, className: "cw-input-search-dropdown", role: "listbox", children: jsxRuntime.jsx("ul", { children: options.map((option, index) => (jsxRuntime.jsx("li", { className: index === highlightedIndex ? "highlighted" : "", onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
|
|
9214
|
+
};
|
|
9215
|
+
|
|
9052
9216
|
exports.CblDragAndDrop = CblDragAndDrop;
|
|
9053
9217
|
exports.CwAccordionContainer = CwAccordionContainer;
|
|
9054
9218
|
exports.CwAlign = CwAlign;
|
|
@@ -9079,6 +9243,7 @@ exports.CwExpandable = CwExpandable;
|
|
|
9079
9243
|
exports.CwFileUpload = CwFileUpload;
|
|
9080
9244
|
exports.CwFileUploadMultiple = CwFileUploadMultiple;
|
|
9081
9245
|
exports.CwFindAirport = CwFindAirport;
|
|
9246
|
+
exports.CwFindCrewmember = CwFindCrewmember;
|
|
9082
9247
|
exports.CwGenericTooltip = CwGenericTooltip;
|
|
9083
9248
|
exports.CwHeadingMain = CwHeadingMain;
|
|
9084
9249
|
exports.CwHeadingSecond = CwHeadingSecond;
|