@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 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;