From edb75928e523ca3b8ae12ca7a46c275922c79060 Mon Sep 17 00:00:00 2001 From: Jules Belveze <32683010+JulesBelveze@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:59:27 +0200 Subject: [PATCH] [front] - chore: upgrade `Checkbox` (#8005) * [front/components] - refactor: standardize checkbox component integration - Replace string literals for checkbox states with a structured CheckboxStatus object to improve code clarity and consistency - Update Checkbox component usage across various components to align with the new CheckboxStatus implementation [front/package] - fix: update @dust-tt/sparkle dependency to latest version - Ensure compatibility with new CheckboxStatus structure by updating the @dust-tt/sparkle dependency to the latest RC version - Include updates to related checkbox components from @radix-ui/react-checkbox to maintain alignment with dependency changes * [front] - refactor: replace PokeCheckbox with Checkbox from sparkle library - PokeCheckbox has been replaced with Checkbox across different components for consistency - Import of PokeCheckbox has been removed as it's no longer used * [front/components/poke/plans] - refactor: reorder imports in createPlan component - Adjust the order of component imports to follow convention [misc] - remove: delete obsolete checkbox component - Remove the PokeCheckbox component as it's no longer in use * [front] - fix: correct event handler for Checkbox component in form - Replace `onChange` with `onCheckedChange` to correctly handle state changes when checkboxes are toggled in the editing plan form * [front] - fix: ensure proper state update on selection change in tree - Replace direct state manipulation with controlled component behavior when a tree item is checked - Resolve issue with partial selection state not updating correctly upon user interaction * [front] - refactor: streamline checkbox component interface and usage - Replaced individual checked and onChange props with defaultChecked and onCheckedChange for Checkbox components across various modules - Simplified getCheckedState function in ContentNodeTree.tsx by returning a string state instead of an object with boolean flags - Adjusted logic handling the checked state of tree items to accommodate the new return type of getCheckedState function - Ensured consistent behavior of checkbox components and their interaction within the application's various features * [front/components] - refactor: standardize checkbox checked state representation - Replace the mixed usage of "checked", "unchecked", and "partial" string literals with booleans and a "partial" string where necessary - Simplify the logic in various components to work with the standardized state representation [front] - fix: correct spacing in import statement in createPlan.tsx - Ensure consistent code style by fixing the spacing between imported components [front] - devops: update @dust-tt/sparkle package to version 0.2.266-rc-2 - Bump the version of @dust-tt/sparkle to incorporate the latest changes and fixes in the project dependencies * [front] - fix: use controlled component pattern for checkboxes - Changed Checkbox components from uncontrolled to controlled by using the `checked` prop instead of `defaultChecked` - Ensures the Checkbox components properly react to state changes for consistent user experience across the application * [front] - feature: upgrade @dust-tt/sparkle to version 0.2.267 - Update the @dust-tt/sparkle package from a release candidate to the stable version - Resolve package-lock.json to point to the new version with updated integrity checksums --------- Co-authored-by: Jules --- front/components/ContentNodeTree.tsx | 17 +- .../assistant/conversation/SidebarMenu.tsx | 11 +- .../assistant_builder/ActionsScreen.tsx | 5 +- .../vaults/VaultSelector.tsx | 5 +- .../DataSourceViewSelector.tsx | 4 +- front/components/poke/plans/createPlan.tsx | 5 +- front/components/poke/plans/form.tsx | 6 +- front/components/poke/plugins/PluginForm.tsx | 4 +- front/components/poke/shadcn/ui/checkbox.tsx | 28 --- front/package-lock.json | 207 ++++++++++++++++-- front/package.json | 2 +- 11 files changed, 216 insertions(+), 78 deletions(-) delete mode 100644 front/components/poke/shadcn/ui/checkbox.tsx diff --git a/front/components/ContentNodeTree.tsx b/front/components/ContentNodeTree.tsx index e67ade111a3e..74b8b8a5c524 100644 --- a/front/components/ContentNodeTree.tsx +++ b/front/components/ContentNodeTree.tsx @@ -122,18 +122,18 @@ function ContentNodeTreeChildren({ const getCheckedState = useCallback( (node: BaseContentNode) => { if (!selectedNodes) { - return "unchecked"; + return false; } // If the parent is selected, the node is considered selected. if (parentIsSelected) { - return "checked"; + return true; } // Check if there is a local state for this node. const localState = selectedNodes[node.internalId]; if (localState?.isSelected) { - return "checked"; + return true; } const internalPartiallySelectedId = Object.values(selectedNodes) @@ -144,7 +144,7 @@ function ContentNodeTreeChildren({ } // Return false if no custom function is provided. - return "unchecked"; + return false; }, [parentIsSelected, selectedNodes] ); @@ -165,7 +165,6 @@ function ContentNodeTreeChildren({ {filteredNodes.map((n, i) => { const checkedState = getCheckedState(n); - return ( { + onCheckedChange: (v) => { if (setSelectedNodes) { if (checkedState === "partial") { // Handle clicking on partial : unselect all selected children @@ -190,9 +189,9 @@ function ContentNodeTreeChildren({ setSelectedNodes((prev) => ({ ...prev, [n.internalId]: { - isSelected: checked, + isSelected: !!v, node: n, - parents: checked ? parentIds : [], + parents: v ? parentIds : [], }, })); } @@ -253,7 +252,7 @@ function ContentNodeTreeChildren({ depth={depth + 1} parentId={n.internalId} parentIds={[n.internalId, ...parentIds]} - parentIsSelected={getCheckedState(n) === "checked"} + parentIsSelected={getCheckedState(n) === true} /> )} /> diff --git a/front/components/assistant/conversation/SidebarMenu.tsx b/front/components/assistant/conversation/SidebarMenu.tsx index 2bc19136ca72..e89ebc6cc67e 100644 --- a/front/components/assistant/conversation/SidebarMenu.tsx +++ b/front/components/assistant/conversation/SidebarMenu.tsx @@ -298,13 +298,10 @@ export function AssistantSidebarMenu({ owner }: AssistantSidebarMenuProps) { isMultiSelect ? () => ( + checked={selectedConversations.includes( + c + )} + onCheckedChange={() => toggleConversationSelection(c) } /> diff --git a/front/components/assistant_builder/ActionsScreen.tsx b/front/components/assistant_builder/ActionsScreen.tsx index 87bd78cbbecf..b4179c344884 100644 --- a/front/components/assistant_builder/ActionsScreen.tsx +++ b/front/components/assistant_builder/ActionsScreen.tsx @@ -1094,9 +1094,8 @@ function Capabilities({ return (
diff --git a/front/components/assistant_builder/vaults/VaultSelector.tsx b/front/components/assistant_builder/vaults/VaultSelector.tsx index 00eec3dbdd9c..9f952e3491e0 100644 --- a/front/components/assistant_builder/vaults/VaultSelector.tsx +++ b/front/components/assistant_builder/vaults/VaultSelector.tsx @@ -63,9 +63,8 @@ export function VaultSelector({ }} > { + checked={isChecked} + onCheckedChange={() => { if (!isDisabled) { setSelectedVault(isChecked ? "" : vault.sId); } diff --git a/front/components/data_source_view/DataSourceViewSelector.tsx b/front/components/data_source_view/DataSourceViewSelector.tsx index 69cfb2834d7f..a0a4338b6db7 100644 --- a/front/components/data_source_view/DataSourceViewSelector.tsx +++ b/front/components/data_source_view/DataSourceViewSelector.tsx @@ -391,10 +391,10 @@ export function DataSourceViewSelector({ const isPartiallyChecked = internalIds.length > 0; const checkedStatus = selectionConfiguration.isSelectAll - ? "checked" + ? true : isPartiallyChecked ? "partial" - : "unchecked"; + : false; const isTableView = viewType === "tables"; diff --git a/front/components/poke/plans/createPlan.tsx b/front/components/poke/plans/createPlan.tsx index 9902b4bd8276..d1860d81b0fa 100644 --- a/front/components/poke/plans/createPlan.tsx +++ b/front/components/poke/plans/createPlan.tsx @@ -1,5 +1,5 @@ -import { Spinner } from "@dust-tt/sparkle"; import { Input } from "@dust-tt/sparkle"; +import { Checkbox, Spinner } from "@dust-tt/sparkle"; import type { CreatePlanFormType, WorkspaceType } from "@dust-tt/types"; import { CreatePlanFormSchema, removeNulls } from "@dust-tt/types"; import { ioTsResolver } from "@hookform/resolvers/io-ts"; @@ -10,7 +10,6 @@ import { useForm } from "react-hook-form"; import PokeNavbar from "@app/components/poke/PokeNavbar"; import { PokeButton } from "@app/components/poke/shadcn/ui/button"; -import { PokeCheckbox } from "@app/components/poke/shadcn/ui/checkbox"; import { PokeForm, PokeFormControl, @@ -283,7 +282,7 @@ function CheckboxField({ {title ?? name} - diff --git a/front/components/poke/plans/form.tsx b/front/components/poke/plans/form.tsx index 5ab7a2324148..ce70ba0d2393 100644 --- a/front/components/poke/plans/form.tsx +++ b/front/components/poke/plans/form.tsx @@ -334,12 +334,12 @@ export const Field: React.FC = ({ case "boolean": const fieldValue = editingPlan && isEditing ? editingPlan[fieldName] : plan[fieldName]; - const checkedStatus = fieldValue ? "checked" : "unchecked"; + const isChecked = !!fieldValue; return ( { + checked={isChecked} + onCheckedChange={(x) => { if (!editingPlan) { return; } diff --git a/front/components/poke/plugins/PluginForm.tsx b/front/components/poke/plugins/PluginForm.tsx index 785274da705d..583666a2180d 100644 --- a/front/components/poke/plugins/PluginForm.tsx +++ b/front/components/poke/plugins/PluginForm.tsx @@ -1,4 +1,5 @@ import { Input } from "@dust-tt/sparkle"; +import { Checkbox } from "@dust-tt/sparkle"; import { createIoTsCodecFromArgs } from "@dust-tt/types"; import { ioTsResolver } from "@hookform/resolvers/io-ts"; import type * as t from "io-ts"; @@ -6,7 +7,6 @@ import { useMemo } from "react"; import { useForm } from "react-hook-form"; import { PokeButton } from "@app/components/poke/shadcn/ui/button"; -import { PokeCheckbox } from "@app/components/poke/shadcn/ui/checkbox"; import { PokeForm, PokeFormControl, @@ -97,7 +97,7 @@ export function PluginForm({ manifest, onSubmit }: PluginFormProps) { /> )} {arg.type === "boolean" && ( - diff --git a/front/components/poke/shadcn/ui/checkbox.tsx b/front/components/poke/shadcn/ui/checkbox.tsx deleted file mode 100644 index db690a0e1b58..000000000000 --- a/front/components/poke/shadcn/ui/checkbox.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; -import { Check } from "lucide-react"; -import * as React from "react"; - -import { cn } from "@app/components/poke/shadcn/lib/utils"; - -const PokeCheckbox = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - - -)); -PokeCheckbox.displayName = CheckboxPrimitive.Root.displayName; - -export { PokeCheckbox }; diff --git a/front/package-lock.json b/front/package-lock.json index 3477fc92de6c..a67566e13ac5 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -10,7 +10,7 @@ "@amplitude/analytics-node": "^1.3.5", "@auth0/nextjs-auth0": "^3.5.0", "@dust-tt/client": "file:../sdks/js", - "@dust-tt/sparkle": "^0.2.265", + "@dust-tt/sparkle": "^0.2.267", "@dust-tt/types": "file:../types", "@headlessui/react": "^1.7.7", "@heroicons/react": "^2.0.11", @@ -11819,13 +11819,14 @@ "link": true }, "node_modules/@dust-tt/sparkle": { - "version": "0.2.265", - "resolved": "https://registry.npmjs.org/@dust-tt/sparkle/-/sparkle-0.2.265.tgz", - "integrity": "sha512-iHUv/b0T9rk7SplYrluNJqEvR9RwqaAfCLpsby+Czhoy7HGGE+BkKLFiw9w7elCT8DDRXgWNxdbHTU8twnEa9w==", + "version": "0.2.267", + "resolved": "https://registry.npmjs.org/@dust-tt/sparkle/-/sparkle-0.2.267.tgz", + "integrity": "sha512-ujci24r6lPKauK869kcQ+IuSEfyzzUcpGBcbZFzDziTgBy8vSCI8A5LoyNrd9XS6m+giv1sC8Bw2TS0zrma5gw==", "dependencies": { "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", "@headlessui/react": "^1.7.19", + "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-popover": "^1.1.2", @@ -11833,6 +11834,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.3", "@tanstack/react-table": "^8.13.0", + "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "emoji-mart": "^5.5.2", "lottie-react": "^2.4.0", @@ -15365,24 +15367,102 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.0.4", - "license": "MIT", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.2.tgz", + "integrity": "sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-use-size": "1.0.1" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-presence": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", + "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -15393,6 +15473,99 @@ } } }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-collection": { "version": "1.0.3", "license": "MIT", diff --git a/front/package.json b/front/package.json index fa58968a6444..6439ac241e94 100644 --- a/front/package.json +++ b/front/package.json @@ -23,7 +23,7 @@ "@amplitude/analytics-node": "^1.3.5", "@auth0/nextjs-auth0": "^3.5.0", "@dust-tt/client": "file:../sdks/js", - "@dust-tt/sparkle": "^0.2.265", + "@dust-tt/sparkle": "^0.2.267", "@dust-tt/types": "file:../types", "@headlessui/react": "^1.7.7", "@heroicons/react": "^2.0.11",