diff --git a/components/KernDropdown.tsx b/components/KernDropdown.tsx index b1a0541..ab59fcd 100644 --- a/components/KernDropdown.tsx +++ b/components/KernDropdown.tsx @@ -61,7 +61,7 @@ export default function KernDropdown(props: KernDropdownProps) { setDropdownCaptions(prepareOptions); setSearchIndexes(null); } - }, [props.options, searchText, selectedCheckboxes, props.hasSearchBar, props.hasCheckboxes, props.selectedCheckboxes, props.hasSelectAll, props.valuePropertyPath]); + }, [props.options, searchText, props.hasSearchBar, props.hasCheckboxes, props.valuePropertyPath, props.selectedCheckboxes, props.hasSelectAll]); useEffect(() => { if (!props.disabledOptions || !props.options) return; @@ -94,8 +94,7 @@ export default function KernDropdown(props: KernDropdownProps) { return { "maxHeight": `${maxHeight}rem`, "overflowY": "auto" }; }, [props.scrollAfterNOptions]); - function setOptionsWithCheckboxes(options: any[]) { - if (selectedCheckboxes.length > 0) return; + const setOptionsWithCheckboxes = useCallback((options: any[]) => { const newSelectedCheckboxes = options.map((option: any, index: number) => { return { name: option, @@ -110,7 +109,7 @@ export default function KernDropdown(props: KernDropdownProps) { } setSelectedCheckboxes(newSelectedCheckboxes); setDropdownCaptions(newSelectedCheckboxes.map((option: any) => option.name)); - } + }, [props.hasSelectAll, props.selectedCheckboxes]); function toggleDropdown() { if (isDisabled && !props.hasCheckboxes) return; // if the dropdown has checkboxes, it shouldn't be disabled because the user can still select options @@ -118,7 +117,7 @@ export default function KernDropdown(props: KernDropdownProps) { setIsOpen(!isOpen); } - function handleSelectedCheckboxes(option: string, index: number, e: any) { + const handleSelectedCheckboxes = useCallback((option: string, index: number, e: any) => { let newSelectedCheckboxes = [...selectedCheckboxes]; if (option == SELECT_ALL) { newSelectedCheckboxes.forEach((checkbox) => { @@ -136,7 +135,7 @@ export default function KernDropdown(props: KernDropdownProps) { newSelectedCheckboxes = newSelectedCheckboxes.filter((checkbox) => checkbox.name != SELECT_ALL); } props.selectedOption(newSelectedCheckboxes); - } + }, [selectedCheckboxes, props.hasSelectAll]); function handleSelectedCheckboxesThreeStates(index: number) { const optionSave = { ...props.options[index] }; @@ -161,8 +160,7 @@ export default function KernDropdown(props: KernDropdownProps) { setSavedIndex(index); } - - function performActionOnClick(option: string, index: number) { + const performActionOnClick = useCallback((option: string, index: number) => { if (props.hasCheckboxes) { handleSelectedCheckboxes(option, index, { target: { checked: !selectedCheckboxes[index].checked } }); return; @@ -180,8 +178,9 @@ export default function KernDropdown(props: KernDropdownProps) { props.selectedOption(props.options[index]); } setIsOpen(false); + setSelectedCheckboxes([]); } - } + }, [props, selectedCheckboxes, searchIndexes]); return ( @@ -213,7 +212,7 @@ export default function KernDropdown(props: KernDropdownProps) { ) : ( -
+
{props.buttonPrefixIcon} {!props.hasCheckboxesThreeStates && props.buttonName}
@@ -266,7 +265,7 @@ export default function KernDropdown(props: KernDropdownProps) { if (!props.optionsHaveHoverBox) return; setHoverBoxPosition(null); }}> - {props.hasCheckboxes && handleSelectedCheckboxes(option, index, e)} />} {props.hasCheckboxesThreeStates &&
diff --git a/components/kern-table/CellComponents.tsx b/components/kern-table/CellComponents.tsx index 77ec1e4..5dd66c9 100644 --- a/components/kern-table/CellComponents.tsx +++ b/components/kern-table/CellComponents.tsx @@ -345,4 +345,45 @@ function ConfigReleaseNotificationCell({ onClickView, onClickEdit }) {
; } -export { OrganizationAndUsersCell, MaxRowsColsCharsCell, CommentsCell, ExportConsumptionAndDeleteCell, BadgeCell, OrganizationUserCell, DeleteCell, LevelCell, ArchiveReasonCell, ProjectNameTaskCell, CancelTaskCell, IconCell, ConfigCell, EditDeleteOrgButtonCell, ViewStackCell, AbortSessionButtonCell, FeedbackMessageCell, FeedbackMessageTextCell, JumpToConversationCell, RemoteVersionCell, ExternalLinkCell, ModelDateCell, FileSizeCell, StatusModelCell, DeleteModelCell, LabelCell, ViewCell, EvaluationRunStateCell, EvaluationRunDetailsCell, EtlApiTokenCell, EmailCell, EditIntegrationCell, ExpiredTokenCell, LinkCell, ConfigReleaseNotificationCell } \ No newline at end of file +function TruncateAndTooltipCell({ value, hasError = false }) { + return
+ {hasError && } + {value ? {value}} color="invert" hideArrow={true} placement='bottom'> + {value} + : } +
; +} + +function JumpToConversationAndAssignCell({ onClick }) { + const clickArrow = useCallback(() => { + if (onClick) onClick(); + }, [onClick]); + + return
+ + + +
+} + +function TaskStateCell({ value, color }) { + const className = useMemo(() => { + return `inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${color === 'green' + ? 'bg-green-300' + : 'bg-' + color + '-100 text-' + color + '-800'}`; + }, [color]); + + return ( + + + + + {value} + + ); +} + +export { OrganizationAndUsersCell, MaxRowsColsCharsCell, CommentsCell, ExportConsumptionAndDeleteCell, BadgeCell, OrganizationUserCell, DeleteCell, LevelCell, ArchiveReasonCell, ProjectNameTaskCell, CancelTaskCell, IconCell, ConfigCell, EditDeleteOrgButtonCell, ViewStackCell, AbortSessionButtonCell, FeedbackMessageCell, FeedbackMessageTextCell, JumpToConversationCell, RemoteVersionCell, ExternalLinkCell, ModelDateCell, FileSizeCell, StatusModelCell, DeleteModelCell, LabelCell, ViewCell, EvaluationRunStateCell, EvaluationRunDetailsCell, EtlApiTokenCell, EmailCell, EditIntegrationCell, ExpiredTokenCell, LinkCell, ConfigReleaseNotificationCell, TruncateAndTooltipCell, JumpToConversationAndAssignCell, TaskStateCell } \ No newline at end of file diff --git a/components/kern-table/KernTable.tsx b/components/kern-table/KernTable.tsx index ab346cc..3b8657f 100644 --- a/components/kern-table/KernTable.tsx +++ b/components/kern-table/KernTable.tsx @@ -1,6 +1,6 @@ import SortArrows from "@/submodules/react-components/components/kern-table/SortArrows"; import { KernTableProps } from "../../types/kern-table"; -import { AbortSessionButtonCell, ArchiveReasonCell, BadgeCell, CancelTaskCell, CommentsCell, ConfigCell, DeleteModelCell, DeleteCell, EditDeleteOrgButtonCell, EmailCell, EtlApiTokenCell, EvaluationRunDetailsCell, EvaluationRunStateCell, ExportConsumptionAndDeleteCell, ExternalLinkCell, FeedbackMessageCell, FeedbackMessageTextCell, FileSizeCell, IconCell, JumpToConversationCell, LabelCell, LevelCell, MaxRowsColsCharsCell, ModelDateCell, OrganizationAndUsersCell, OrganizationUserCell, ProjectNameTaskCell, RemoteVersionCell, StatusModelCell, ViewCell, ViewStackCell, EditIntegrationCell, ExpiredTokenCell, LinkCell, ConfigReleaseNotificationCell } from "./CellComponents"; +import { AbortSessionButtonCell, ArchiveReasonCell, BadgeCell, CancelTaskCell, CommentsCell, ConfigCell, DeleteModelCell, DeleteCell, EditDeleteOrgButtonCell, EmailCell, EtlApiTokenCell, EvaluationRunDetailsCell, EvaluationRunStateCell, ExportConsumptionAndDeleteCell, ExternalLinkCell, FeedbackMessageCell, FeedbackMessageTextCell, FileSizeCell, IconCell, JumpToConversationCell, LabelCell, LevelCell, MaxRowsColsCharsCell, ModelDateCell, OrganizationAndUsersCell, OrganizationUserCell, ProjectNameTaskCell, RemoteVersionCell, StatusModelCell, ViewCell, ViewStackCell, EditIntegrationCell, ExpiredTokenCell, LinkCell, ConfigReleaseNotificationCell, TruncateAndTooltipCell, JumpToConversationAndAssignCell, TaskStateCell } from "./CellComponents"; import { Fragment, useMemo } from "react"; import KernDropdown from "../KernDropdown"; import { NotApplicableBadge } from "@/submodules/react-components/components/Badges"; @@ -162,6 +162,12 @@ function ComponentMapper(cell: any) { return ; case 'ConfigReleaseNotificationCell': return ; + case 'TruncateAndTooltipCell': + return ; + case 'JumpToConversationAndAssignCell': + return ; + case 'TaskStateCell': + return ; case '@provided@': return cell.jsx ?? ; } diff --git a/types/dropdown.ts b/types/dropdown.ts index cef95d6..0746bce 100644 --- a/types/dropdown.ts +++ b/types/dropdown.ts @@ -44,6 +44,7 @@ import React from "react"; * @positionDropdown {string} - The position of the dropdown * @dropdownAdd {JSX.Element} - array of JSX elements that will be added to the dropdown items * @forceOverwriteOpen {boolean} - forces the dropdown to stay open until set to false/undefined + * @truncateButtonName {boolean} - If the button name should be truncated when it exceeds the button width */ export type KernDropdownProps = { buttonName?: string; @@ -93,6 +94,7 @@ export type KernDropdownProps = { scrollAfterNOptions?: number; dropdownAdd?: JSX.Element[]; forceOverwriteOpen?: boolean; + truncateButtonName?: boolean; } export type AppSelectionDropdownProps = {