@cwellt_software/cwellt-reactjs-lib 1.2.17 → 1.3.0
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 +170 -5
- package/dist/index.css +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.es.js +170 -6
- 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/components/display/text/message/CwMessage.d.ts +3 -2
- package/dist/src/components/display/text/message/CwMessage.d.ts.map +1 -1
- 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 +73 -36
package/dist/index.cjs.js
CHANGED
|
@@ -251,7 +251,7 @@ const CwMessage = props => {
|
|
|
251
251
|
}, props.duration ?? CW_DEFAULT_MESSAGE_DURATION);
|
|
252
252
|
return () => clearTimeout(timer);
|
|
253
253
|
}, [props]);
|
|
254
|
-
return (jsxRuntime.jsxs("div", { className: "cw-message", "data-message-type": Object.keys(exports.CwMessageType).find(key => exports.CwMessageType[key] === props.messageType), children: [props.messageType && jsxRuntime.jsx(CwIcon, { iconId: props.messageType.toString(), size: "large" }), props.message] }));
|
|
254
|
+
return (jsxRuntime.jsxs("div", { className: "cw-message", "data-message-type": Object.keys(exports.CwMessageType).find(key => exports.CwMessageType[key] === props.messageType), onClick: props.onClick, style: props.onClick ? { cursor: "pointer" } : undefined, children: [props.messageType && jsxRuntime.jsx(CwIcon, { iconId: props.messageType.toString(), size: "large" }), props.message] }));
|
|
255
255
|
};
|
|
256
256
|
/**
|
|
257
257
|
* Hook for displaying inline messages within specific components.
|
|
@@ -314,11 +314,11 @@ class CwMessageManager {
|
|
|
314
314
|
document.body.prepend(this.messageWrapper);
|
|
315
315
|
this.root = client.createRoot(this.messageWrapper); // Create a root at the messageWrapper
|
|
316
316
|
}
|
|
317
|
-
showMessage(message, type, duration) {
|
|
317
|
+
showMessage(message, type, duration, onClick) {
|
|
318
318
|
const msg = document.createElement("div");
|
|
319
319
|
this.messageWrapper?.prepend(msg);
|
|
320
320
|
const msgRoot = client.createRoot(msg); // Create a root for the new message
|
|
321
|
-
msgRoot.render(jsxRuntime.jsx(CwMessage, { message: message, messageType: type, duration: duration, onClose: () => this.closeMessage(msgRoot) }));
|
|
321
|
+
msgRoot.render(jsxRuntime.jsx(CwMessage, { message: message, messageType: type, duration: duration, onClick: onClick, onClose: () => this.closeMessage(msgRoot) }));
|
|
322
322
|
}
|
|
323
323
|
closeMessage(msgRoot) {
|
|
324
324
|
msgRoot.unmount(); // Unmount the message root
|
|
@@ -340,8 +340,8 @@ class CwMessageManager {
|
|
|
340
340
|
*
|
|
341
341
|
* @note For inline messages within components, use `CwNote` or `useCwMessage` hook instead
|
|
342
342
|
*/
|
|
343
|
-
function CwDisplayMessage(message, type, duration) {
|
|
344
|
-
CwMessageManager.getInstance().showMessage(message, type, duration);
|
|
343
|
+
function CwDisplayMessage(message, type, duration, onClick) {
|
|
344
|
+
CwMessageManager.getInstance().showMessage(message, type, duration, onClick);
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
/**
|
|
@@ -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;
|