@oneclick.dev/cms-kit 0.0.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/README.md +1 -0
- package/components/ui/apple-emoji/AppleEmoji.vue +32 -0
- package/components/ui/apple-emoji/index.ts +1 -0
- package/components/ui/avatar/Avatar.vue +18 -0
- package/components/ui/avatar/AvatarFallback.vue +23 -0
- package/components/ui/avatar/AvatarImage.vue +16 -0
- package/components/ui/avatar/index.ts +3 -0
- package/components/ui/badge/Badge.vue +39 -0
- package/components/ui/badge/index.ts +1 -0
- package/components/ui/breadcrumb/Breadcrumb.vue +17 -0
- package/components/ui/breadcrumb/BreadcrumbEllipsis.vue +23 -0
- package/components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
- package/components/ui/breadcrumb/BreadcrumbLink.vue +20 -0
- package/components/ui/breadcrumb/BreadcrumbList.vue +17 -0
- package/components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
- package/components/ui/breadcrumb/BreadcrumbSeparator.vue +22 -0
- package/components/ui/breadcrumb/index.ts +7 -0
- package/components/ui/button/Button.vue +39 -0
- package/components/ui/button/index.ts +36 -0
- package/components/ui/calendar/Calendar.vue +63 -0
- package/components/ui/calendar/CalendarCell.vue +25 -0
- package/components/ui/calendar/CalendarCellTrigger.vue +41 -0
- package/components/ui/calendar/CalendarGrid.vue +25 -0
- package/components/ui/calendar/CalendarGridBody.vue +14 -0
- package/components/ui/calendar/CalendarGridHead.vue +15 -0
- package/components/ui/calendar/CalendarGridRow.vue +24 -0
- package/components/ui/calendar/CalendarHeadCell.vue +25 -0
- package/components/ui/calendar/CalendarHeader.vue +25 -0
- package/components/ui/calendar/CalendarHeading.vue +32 -0
- package/components/ui/calendar/CalendarNextButton.vue +34 -0
- package/components/ui/calendar/CalendarPrevButton.vue +34 -0
- package/components/ui/calendar/index.ts +12 -0
- package/components/ui/card/Card.vue +22 -0
- package/components/ui/card/CardAction.vue +17 -0
- package/components/ui/card/CardContent.vue +17 -0
- package/components/ui/card/CardDescription.vue +17 -0
- package/components/ui/card/CardFooter.vue +17 -0
- package/components/ui/card/CardHeader.vue +17 -0
- package/components/ui/card/CardTitle.vue +17 -0
- package/components/ui/card/index.ts +7 -0
- package/components/ui/checkbox/Checkbox.vue +37 -0
- package/components/ui/checkbox/index.ts +1 -0
- package/components/ui/code-editor/CodeEditor.vue +88 -0
- package/components/ui/code-editor/index.ts +1 -0
- package/components/ui/code-editor/interpolationHighlight.ts +39 -0
- package/components/ui/collapsible/Collapsible.vue +19 -0
- package/components/ui/collapsible/CollapsibleContent.vue +14 -0
- package/components/ui/collapsible/CollapsibleTrigger.vue +14 -0
- package/components/ui/collapsible/index.ts +3 -0
- package/components/ui/combobox/Combobox.vue +17 -0
- package/components/ui/combobox/ComboboxAnchor.vue +26 -0
- package/components/ui/combobox/ComboboxEmpty.vue +24 -0
- package/components/ui/combobox/ComboboxGroup.vue +30 -0
- package/components/ui/combobox/ComboboxInput.vue +47 -0
- package/components/ui/combobox/ComboboxItem.vue +27 -0
- package/components/ui/combobox/ComboboxItemIndicator.vue +26 -0
- package/components/ui/combobox/ComboboxList.vue +31 -0
- package/components/ui/combobox/ComboboxSeparator.vue +24 -0
- package/components/ui/combobox/ComboboxTrigger.vue +27 -0
- package/components/ui/combobox/ComboboxViewport.vue +26 -0
- package/components/ui/combobox/index.ts +12 -0
- package/components/ui/command/Command.vue +93 -0
- package/components/ui/command/CommandDialog.vue +31 -0
- package/components/ui/command/CommandEmpty.vue +29 -0
- package/components/ui/command/CommandGroup.vue +47 -0
- package/components/ui/command/CommandInput.vue +41 -0
- package/components/ui/command/CommandItem.vue +79 -0
- package/components/ui/command/CommandList.vue +28 -0
- package/components/ui/command/CommandSeparator.vue +24 -0
- package/components/ui/command/CommandShortcut.vue +17 -0
- package/components/ui/command/index.ts +25 -0
- package/components/ui/context-menu/ContextMenu.vue +18 -0
- package/components/ui/context-menu/ContextMenuCheckboxItem.vue +41 -0
- package/components/ui/context-menu/ContextMenuContent.vue +37 -0
- package/components/ui/context-menu/ContextMenuGroup.vue +14 -0
- package/components/ui/context-menu/ContextMenuItem.vue +42 -0
- package/components/ui/context-menu/ContextMenuLabel.vue +24 -0
- package/components/ui/context-menu/ContextMenuPortal.vue +14 -0
- package/components/ui/context-menu/ContextMenuRadioGroup.vue +22 -0
- package/components/ui/context-menu/ContextMenuRadioItem.vue +41 -0
- package/components/ui/context-menu/ContextMenuSeparator.vue +24 -0
- package/components/ui/context-menu/ContextMenuShortcut.vue +17 -0
- package/components/ui/context-menu/ContextMenuSub.vue +22 -0
- package/components/ui/context-menu/ContextMenuSubContent.vue +36 -0
- package/components/ui/context-menu/ContextMenuSubTrigger.vue +35 -0
- package/components/ui/context-menu/ContextMenuTrigger.vue +16 -0
- package/components/ui/context-menu/index.ts +14 -0
- package/components/ui/custom-dialog/CustomDialog.vue +31 -0
- package/components/ui/custom-dialog/index.ts +1 -0
- package/components/ui/dialog/Dialog.vue +17 -0
- package/components/ui/dialog/DialogClose.vue +14 -0
- package/components/ui/dialog/DialogContent.vue +49 -0
- package/components/ui/dialog/DialogDescription.vue +25 -0
- package/components/ui/dialog/DialogFooter.vue +15 -0
- package/components/ui/dialog/DialogHeader.vue +17 -0
- package/components/ui/dialog/DialogOverlay.vue +23 -0
- package/components/ui/dialog/DialogScrollContent.vue +59 -0
- package/components/ui/dialog/DialogTitle.vue +25 -0
- package/components/ui/dialog/DialogTrigger.vue +14 -0
- package/components/ui/dialog/index.ts +10 -0
- package/components/ui/drawer/Drawer.vue +22 -0
- package/components/ui/drawer/DrawerClose.vue +15 -0
- package/components/ui/drawer/DrawerContent.vue +34 -0
- package/components/ui/drawer/DrawerDescription.vue +24 -0
- package/components/ui/drawer/DrawerFooter.vue +17 -0
- package/components/ui/drawer/DrawerHeader.vue +17 -0
- package/components/ui/drawer/DrawerOverlay.vue +22 -0
- package/components/ui/drawer/DrawerTitle.vue +24 -0
- package/components/ui/drawer/DrawerTrigger.vue +15 -0
- package/components/ui/drawer/index.ts +9 -0
- package/components/ui/dropdown-menu/DropdownMenu.vue +17 -0
- package/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +41 -0
- package/components/ui/dropdown-menu/DropdownMenuContent.vue +39 -0
- package/components/ui/dropdown-menu/DropdownMenuGroup.vue +14 -0
- package/components/ui/dropdown-menu/DropdownMenuItem.vue +30 -0
- package/components/ui/dropdown-menu/DropdownMenuLabel.vue +22 -0
- package/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +22 -0
- package/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +42 -0
- package/components/ui/dropdown-menu/DropdownMenuSeparator.vue +26 -0
- package/components/ui/dropdown-menu/DropdownMenuShortcut.vue +17 -0
- package/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- package/components/ui/dropdown-menu/DropdownMenuSubContent.vue +31 -0
- package/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +30 -0
- package/components/ui/dropdown-menu/DropdownMenuTrigger.vue +16 -0
- package/components/ui/dropdown-menu/index.ts +16 -0
- package/components/ui/emoji-picker/EmojiPicker.vue +71 -0
- package/components/ui/emoji-picker/index.ts +1 -0
- package/components/ui/flow-builder/FlowBuilder.vue +48 -0
- package/components/ui/flow-builder/FlowBuilderSelect.vue +33 -0
- package/components/ui/flow-builder/components/Builder.vue +287 -0
- package/components/ui/flow-builder/components/DropzoneBackground.vue +13 -0
- package/components/ui/flow-builder/components/EdgeEditor.vue +36 -0
- package/components/ui/flow-builder/components/Menu.vue +78 -0
- package/components/ui/flow-builder/components/NodeEditor.vue +181 -0
- package/components/ui/flow-builder/components/edge-editor/DataEdgeEditor.vue +64 -0
- package/components/ui/flow-builder/components/edges/DataEdge.vue +87 -0
- package/components/ui/flow-builder/components/node-editor/ApiRequestEditor.vue +150 -0
- package/components/ui/flow-builder/components/node-editor/ConfettiEditor.vue +23 -0
- package/components/ui/flow-builder/components/node-editor/ConfirmEditor.vue +30 -0
- package/components/ui/flow-builder/components/node-editor/FinishFlowEditor.vue +33 -0
- package/components/ui/flow-builder/components/node-editor/IntegrationActionEditor.vue +50 -0
- package/components/ui/flow-builder/components/node-editor/SetVariableEditor.vue +71 -0
- package/components/ui/flow-builder/components/node-editor/ShowDialogEditor.vue +26 -0
- package/components/ui/flow-builder/components/node-editor/ShowModuleEditor.vue +92 -0
- package/components/ui/flow-builder/components/node-editor/ShowToastEditor.vue +28 -0
- package/components/ui/flow-builder/components/node-editor/TransformDataEditor.vue +27 -0
- package/components/ui/flow-builder/components/node-editor/VisitUrlEditor.vue +31 -0
- package/components/ui/flow-builder/components/nodes/ApiRequestNode.vue +45 -0
- package/components/ui/flow-builder/components/nodes/ConfettiNode.vue +32 -0
- package/components/ui/flow-builder/components/nodes/ConfirmNode.vue +45 -0
- package/components/ui/flow-builder/components/nodes/EmptyNode.vue +26 -0
- package/components/ui/flow-builder/components/nodes/FinishFlowNode.vue +30 -0
- package/components/ui/flow-builder/components/nodes/IntegrationActionNode.vue +52 -0
- package/components/ui/flow-builder/components/nodes/SetVariableNode.vue +34 -0
- package/components/ui/flow-builder/components/nodes/ShowDialogNode.vue +34 -0
- package/components/ui/flow-builder/components/nodes/ShowModuleNode.vue +34 -0
- package/components/ui/flow-builder/components/nodes/ShowToastNode.vue +35 -0
- package/components/ui/flow-builder/components/nodes/StartNode.vue +27 -0
- package/components/ui/flow-builder/components/nodes/TransformDataNode.vue +34 -0
- package/components/ui/flow-builder/components/nodes/VisitUrlNode.vue +34 -0
- package/components/ui/flow-builder/components/toolbars/ApiRequestToolbar.vue +45 -0
- package/components/ui/flow-builder/components/toolbars/ConfirmToolbar.vue +45 -0
- package/components/ui/flow-builder/components/toolbars/DefaultToolbar.vue +42 -0
- package/components/ui/flow-builder/components/toolbars/IntegrationActionToolbar.vue +45 -0
- package/components/ui/flow-builder/components/variables/Widget.vue +137 -0
- package/components/ui/flow-builder/composables/outputRegistry.ts +33 -0
- package/components/ui/flow-builder/composables/taskHandlers.js +185 -0
- package/components/ui/flow-builder/composables/useLayout.js +60 -0
- package/components/ui/flow-builder/composables/useProcessNodeLogic.js +55 -0
- package/components/ui/flow-builder/composables/useRunProcess.js +267 -0
- package/components/ui/flow-builder/index.ts +5 -0
- package/components/ui/flow-builder/types.ts +7 -0
- package/components/ui/form/FormControl.vue +17 -0
- package/components/ui/form/FormDescription.vue +21 -0
- package/components/ui/form/FormItem.vue +22 -0
- package/components/ui/form/FormLabel.vue +25 -0
- package/components/ui/form/FormMessage.vue +22 -0
- package/components/ui/form/index.ts +7 -0
- package/components/ui/form/injectionKeys.ts +4 -0
- package/components/ui/form/useFormField.ts +30 -0
- package/components/ui/form-builder/FormBuilder.vue +45 -0
- package/components/ui/form-builder/FormBuilderSelect.vue +42 -0
- package/components/ui/form-builder/FormDisplayer.vue +39 -0
- package/components/ui/form-builder/components/AdminElementEditor.vue +48 -0
- package/components/ui/form-builder/components/AdminToolbar.vue +60 -0
- package/components/ui/form-builder/components/AdminToolbarView.vue +19 -0
- package/components/ui/form-builder/components/CustomDashboard.vue +312 -0
- package/components/ui/form-builder/components/FormBuilderWrapper.vue +333 -0
- package/components/ui/form-builder/components/admin/Transformer.vue +25 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Button.vue +30 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Checkbox.vue +23 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Label.vue +13 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Radios.vue +85 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Scanner.vue +15 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Select.vue +75 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Text.vue +13 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Textarea.vue +20 -0
- package/components/ui/form-builder/components/admin/element-setting-views/Textfield.vue +20 -0
- package/components/ui/form-builder/components/admin/element-setting-views/index.ts +21 -0
- package/components/ui/form-builder/components/admin/setting-views/ApiActionsView.vue +111 -0
- package/components/ui/form-builder/components/admin/setting-views/NewElementView.vue +200 -0
- package/components/ui/form-builder/components/admin/setting-views/VariablesView.vue +19 -0
- package/components/ui/form-builder/components/admin/setting-views/new-element-view/DraggableElement.vue +107 -0
- package/components/ui/form-builder/components/admin/setting-views/variables-view/ApiActionVariables.vue +27 -0
- package/components/ui/form-builder/components/admin/setting-views/variables-view/RouteQueryParams.vue +47 -0
- package/components/ui/form-builder/components/admin/setting-views/variables-view/Transformers.vue +61 -0
- package/components/ui/form-builder/components/admin/setting-views/variables-view/Variables.vue +74 -0
- package/components/ui/form-builder/components/elements/button/Button.vue +60 -0
- package/components/ui/form-builder/components/elements/button/index.ts +1 -0
- package/components/ui/form-builder/components/elements/checkbox/Checkbox.vue +40 -0
- package/components/ui/form-builder/components/elements/checkbox/index.ts +1 -0
- package/components/ui/form-builder/components/elements/file/File.vue +6 -0
- package/components/ui/form-builder/components/elements/file/index.ts +1 -0
- package/components/ui/form-builder/components/elements/images/Images.vue +28 -0
- package/components/ui/form-builder/components/elements/images/index.ts +1 -0
- package/components/ui/form-builder/components/elements/index.ts +31 -0
- package/components/ui/form-builder/components/elements/items/Items.vue +6 -0
- package/components/ui/form-builder/components/elements/items/index.ts +1 -0
- package/components/ui/form-builder/components/elements/label/Label.vue +20 -0
- package/components/ui/form-builder/components/elements/label/index.ts +1 -0
- package/components/ui/form-builder/components/elements/location/Location.vue +6 -0
- package/components/ui/form-builder/components/elements/location/index.ts +1 -0
- package/components/ui/form-builder/components/elements/radios/Radios.vue +42 -0
- package/components/ui/form-builder/components/elements/radios/index.ts +1 -0
- package/components/ui/form-builder/components/elements/richtext/Richtext.vue +6 -0
- package/components/ui/form-builder/components/elements/richtext/index.ts +1 -0
- package/components/ui/form-builder/components/elements/scanner/Scanner.vue +173 -0
- package/components/ui/form-builder/components/elements/scanner/index.ts +1 -0
- package/components/ui/form-builder/components/elements/select/Select.vue +49 -0
- package/components/ui/form-builder/components/elements/select/index.ts +1 -0
- package/components/ui/form-builder/components/elements/text/Text.vue +20 -0
- package/components/ui/form-builder/components/elements/text/index.ts +1 -0
- package/components/ui/form-builder/components/elements/textarea/Textarea.vue +30 -0
- package/components/ui/form-builder/components/elements/textarea/index.ts +1 -0
- package/components/ui/form-builder/components/elements/textfield/Textfield.vue +30 -0
- package/components/ui/form-builder/components/elements/textfield/index.ts +1 -0
- package/components/ui/form-builder/index.ts +3 -0
- package/components/ui/input/Input.vue +33 -0
- package/components/ui/input/index.ts +1 -0
- package/components/ui/integration-action-builder/IntegrationActionBuilder.vue +193 -0
- package/components/ui/integration-action-builder/InterpolationField.vue +29 -0
- package/components/ui/integration-action-builder/index.ts +1 -0
- package/components/ui/integration-action-builder/integrations/firebase/AddDocument.vue +43 -0
- package/components/ui/integration-action-builder/integrations/firebase/DeleteDocument.vue +6 -0
- package/components/ui/integration-action-builder/integrations/firebase/GetCollections.vue +6 -0
- package/components/ui/integration-action-builder/integrations/firebase/GetDocumentById.vue +6 -0
- package/components/ui/integration-action-builder/integrations/firebase/QueryCollectionGroup.vue +6 -0
- package/components/ui/integration-action-builder/integrations/firebase/QueryFirestore.vue +165 -0
- package/components/ui/integration-action-builder/integrations/firebase/UpdateDocument.vue +6 -0
- package/components/ui/integration-action-builder/integrations/firebase/index.ts +204 -0
- package/components/ui/integration-action-builder/integrations/index.ts +9 -0
- package/components/ui/integration-action-builder/integrations/openai/AddDocument.vue +43 -0
- package/components/ui/integration-action-builder/integrations/openai/GenerateText.vue +40 -0
- package/components/ui/integration-action-builder/integrations/openai/components/ModelSelector.vue +75 -0
- package/components/ui/integration-action-builder/integrations/openai/index.ts +116 -0
- package/components/ui/integration-action-builder/integrations/twilio/MakeCall.vue +40 -0
- package/components/ui/integration-action-builder/integrations/twilio/SendSMS.vue +39 -0
- package/components/ui/integration-action-builder/integrations/twilio/components/ModelSelector.vue +75 -0
- package/components/ui/integration-action-builder/integrations/twilio/index.ts +68 -0
- package/components/ui/integration-icon/IntegrationIcon.vue +18 -0
- package/components/ui/integration-icon/index.ts +1 -0
- package/components/ui/label/Label.vue +28 -0
- package/components/ui/label/index.ts +1 -0
- package/components/ui/lucide-icon-selector/LucideIconPicker.vue +34 -0
- package/components/ui/lucide-icon-selector/LucideIconSelector.vue +55 -0
- package/components/ui/lucide-icon-selector/index.ts +2 -0
- package/components/ui/media-picker/MediaPicker.vue +40 -0
- package/components/ui/media-picker/MediaPickerDialog.vue +306 -0
- package/components/ui/media-picker/MediaPickerItems.vue +342 -0
- package/components/ui/media-picker/index.ts +2 -0
- package/components/ui/media-picker/media-picker-dialog/Dropzone.vue +104 -0
- package/components/ui/media-picker/media-picker-dialog/FileItem.vue +108 -0
- package/components/ui/media-picker/media-picker-dialog/Filters.vue +78 -0
- package/components/ui/menubar/Menubar.vue +36 -0
- package/components/ui/menubar/MenubarCheckboxItem.vue +41 -0
- package/components/ui/menubar/MenubarContent.vue +44 -0
- package/components/ui/menubar/MenubarGroup.vue +14 -0
- package/components/ui/menubar/MenubarItem.vue +37 -0
- package/components/ui/menubar/MenubarLabel.vue +19 -0
- package/components/ui/menubar/MenubarMenu.vue +14 -0
- package/components/ui/menubar/MenubarRadioGroup.vue +22 -0
- package/components/ui/menubar/MenubarRadioItem.vue +41 -0
- package/components/ui/menubar/MenubarSeparator.vue +23 -0
- package/components/ui/menubar/MenubarShortcut.vue +17 -0
- package/components/ui/menubar/MenubarSub.vue +22 -0
- package/components/ui/menubar/MenubarSubContent.vue +39 -0
- package/components/ui/menubar/MenubarSubTrigger.vue +27 -0
- package/components/ui/menubar/MenubarTrigger.vue +30 -0
- package/components/ui/menubar/index.ts +15 -0
- package/components/ui/number-field/NumberField.vue +23 -0
- package/components/ui/number-field/NumberFieldContent.vue +14 -0
- package/components/ui/number-field/NumberFieldDecrement.vue +25 -0
- package/components/ui/number-field/NumberFieldIncrement.vue +25 -0
- package/components/ui/number-field/NumberFieldInput.vue +16 -0
- package/components/ui/number-field/index.ts +5 -0
- package/components/ui/pagination/PaginationEllipsis.vue +22 -0
- package/components/ui/pagination/PaginationFirst.vue +29 -0
- package/components/ui/pagination/PaginationLast.vue +29 -0
- package/components/ui/pagination/PaginationNext.vue +29 -0
- package/components/ui/pagination/PaginationPrev.vue +29 -0
- package/components/ui/pagination/index.ts +10 -0
- package/components/ui/popover/Popover.vue +18 -0
- package/components/ui/popover/PopoverAnchor.vue +15 -0
- package/components/ui/popover/PopoverContent.vue +49 -0
- package/components/ui/popover/PopoverTrigger.vue +14 -0
- package/components/ui/popover/index.ts +4 -0
- package/components/ui/query-builder-dialog/QueryBuilderDialog.vue +389 -0
- package/components/ui/query-builder-dialog/index.ts +1 -0
- package/components/ui/radio-group/RadioGroup.vue +30 -0
- package/components/ui/radio-group/RadioGroupItem.vue +43 -0
- package/components/ui/radio-group/index.ts +2 -0
- package/components/ui/range-calendar/RangeCalendar.vue +57 -0
- package/components/ui/range-calendar/RangeCalendarCell.vue +21 -0
- package/components/ui/range-calendar/RangeCalendarCellTrigger.vue +37 -0
- package/components/ui/range-calendar/RangeCalendarGrid.vue +21 -0
- package/components/ui/range-calendar/RangeCalendarGridBody.vue +11 -0
- package/components/ui/range-calendar/RangeCalendarGridHead.vue +11 -0
- package/components/ui/range-calendar/RangeCalendarGridRow.vue +18 -0
- package/components/ui/range-calendar/RangeCalendarHeadCell.vue +18 -0
- package/components/ui/range-calendar/RangeCalendarHeader.vue +18 -0
- package/components/ui/range-calendar/RangeCalendarHeading.vue +28 -0
- package/components/ui/range-calendar/RangeCalendarNextButton.vue +29 -0
- package/components/ui/range-calendar/RangeCalendarPrevButton.vue +29 -0
- package/components/ui/range-calendar/index.ts +12 -0
- package/components/ui/resizable/ResizableHandle.vue +27 -0
- package/components/ui/resizable/ResizablePanel.vue +18 -0
- package/components/ui/resizable/ResizablePanelGroup.vue +25 -0
- package/components/ui/resizable/index.ts +3 -0
- package/components/ui/ripple-button/RippleButton.vue +97 -0
- package/components/ui/ripple-button/index.ts +1 -0
- package/components/ui/sandbox/Sandbox.vue +35 -0
- package/components/ui/sandbox/index.ts +1 -0
- package/components/ui/scroll-area/ScrollArea.vue +36 -0
- package/components/ui/scroll-area/ScrollBar.vue +34 -0
- package/components/ui/scroll-area/index.ts +2 -0
- package/components/ui/segmented-control/SegmentedControl.vue +121 -0
- package/components/ui/segmented-control/SegmentedControlButton.vue +64 -0
- package/components/ui/segmented-control/index.ts +2 -0
- package/components/ui/select/Select.vue +18 -0
- package/components/ui/select/SelectContent.vue +55 -0
- package/components/ui/select/SelectGroup.vue +14 -0
- package/components/ui/select/SelectItem.vue +45 -0
- package/components/ui/select/SelectItemText.vue +14 -0
- package/components/ui/select/SelectLabel.vue +16 -0
- package/components/ui/select/SelectScrollDownButton.vue +28 -0
- package/components/ui/select/SelectScrollUpButton.vue +28 -0
- package/components/ui/select/SelectSeparator.vue +21 -0
- package/components/ui/select/SelectTrigger.vue +32 -0
- package/components/ui/select/SelectValue.vue +15 -0
- package/components/ui/select/index.ts +11 -0
- package/components/ui/separator/Separator.vue +28 -0
- package/components/ui/separator/index.ts +1 -0
- package/components/ui/sheet/Sheet.vue +17 -0
- package/components/ui/sheet/SheetClose.vue +14 -0
- package/components/ui/sheet/SheetContent.vue +65 -0
- package/components/ui/sheet/SheetDescription.vue +20 -0
- package/components/ui/sheet/SheetFooter.vue +16 -0
- package/components/ui/sheet/SheetHeader.vue +15 -0
- package/components/ui/sheet/SheetOverlay.vue +24 -0
- package/components/ui/sheet/SheetTitle.vue +20 -0
- package/components/ui/sheet/SheetTrigger.vue +14 -0
- package/components/ui/sheet/index.ts +8 -0
- package/components/ui/sidebar/Sidebar.vue +96 -0
- package/components/ui/sidebar/SidebarContent.vue +18 -0
- package/components/ui/sidebar/SidebarFooter.vue +18 -0
- package/components/ui/sidebar/SidebarGroup.vue +18 -0
- package/components/ui/sidebar/SidebarGroupAction.vue +27 -0
- package/components/ui/sidebar/SidebarGroupContent.vue +18 -0
- package/components/ui/sidebar/SidebarGroupLabel.vue +25 -0
- package/components/ui/sidebar/SidebarHeader.vue +18 -0
- package/components/ui/sidebar/SidebarInput.vue +22 -0
- package/components/ui/sidebar/SidebarInset.vue +21 -0
- package/components/ui/sidebar/SidebarMenu.vue +18 -0
- package/components/ui/sidebar/SidebarMenuAction.vue +34 -0
- package/components/ui/sidebar/SidebarMenuBadge.vue +26 -0
- package/components/ui/sidebar/SidebarMenuButton.vue +49 -0
- package/components/ui/sidebar/SidebarMenuButtonChild.vue +34 -0
- package/components/ui/sidebar/SidebarMenuItem.vue +18 -0
- package/components/ui/sidebar/SidebarMenuSkeleton.vue +34 -0
- package/components/ui/sidebar/SidebarMenuSub.vue +22 -0
- package/components/ui/sidebar/SidebarMenuSubButton.vue +36 -0
- package/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
- package/components/ui/sidebar/SidebarProvider.vue +81 -0
- package/components/ui/sidebar/SidebarRail.vue +33 -0
- package/components/ui/sidebar/SidebarSeparator.vue +19 -0
- package/components/ui/sidebar/SidebarTrigger.vue +27 -0
- package/components/ui/sidebar/index.ts +60 -0
- package/components/ui/sidebar/utils.ts +19 -0
- package/components/ui/skeleton/Skeleton.vue +17 -0
- package/components/ui/skeleton/index.ts +1 -0
- package/components/ui/sonner/Sonner.vue +18 -0
- package/components/ui/sonner/index.ts +1 -0
- package/components/ui/spring-calendar/SpringCalendar.vue +110 -0
- package/components/ui/spring-calendar/TextMorph.vue +160 -0
- package/components/ui/spring-calendar/index.ts +2 -0
- package/components/ui/switch/Switch.vue +41 -0
- package/components/ui/switch/index.ts +1 -0
- package/components/ui/table/Table.vue +16 -0
- package/components/ui/table/TableBody.vue +17 -0
- package/components/ui/table/TableCaption.vue +17 -0
- package/components/ui/table/TableCell.vue +22 -0
- package/components/ui/table/TableEmpty.vue +37 -0
- package/components/ui/table/TableFooter.vue +17 -0
- package/components/ui/table/TableHead.vue +17 -0
- package/components/ui/table/TableHeader.vue +17 -0
- package/components/ui/table/TableRow.vue +17 -0
- package/components/ui/table/index.ts +9 -0
- package/components/ui/table/utils.ts +9 -0
- package/components/ui/tabs/Tabs.vue +15 -0
- package/components/ui/tabs/TabsContent.vue +22 -0
- package/components/ui/tabs/TabsList.vue +25 -0
- package/components/ui/tabs/TabsTrigger.vue +29 -0
- package/components/ui/tabs/index.ts +4 -0
- package/components/ui/tailwind-color-picker/TailwindColorPicker.vue +58 -0
- package/components/ui/tailwind-color-picker/index.ts +1 -0
- package/components/ui/textarea/Textarea.vue +28 -0
- package/components/ui/textarea/index.ts +1 -0
- package/components/ui/toggle/Toggle.vue +32 -0
- package/components/ui/toggle/index.ts +27 -0
- package/components/ui/tooltip/Tooltip.vue +17 -0
- package/components/ui/tooltip/TooltipContent.vue +33 -0
- package/components/ui/tooltip/TooltipProvider.vue +13 -0
- package/components/ui/tooltip/TooltipTrigger.vue +14 -0
- package/components/ui/tooltip/index.ts +4 -0
- package/composables/useCms.ts +11 -0
- package/index.ts +10 -0
- package/lib/interpolation.ts +77 -0
- package/lib/utils.ts +24 -0
- package/package.json +52 -0
- package/styles/components/code-editor.css +52 -0
- package/styles/components/flow-builder.css +159 -0
- package/styles/index.css +2 -0
- package/tsconfig.json +19 -0
- package/types/index.ts +41 -0
- package/vite.config.ts +25 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { computed, toRef } from 'vue'
|
|
2
|
+
import { useNodeConnections } from '@vue-flow/core'
|
|
3
|
+
import { ProcessStatus } from './useRunProcess'
|
|
4
|
+
|
|
5
|
+
export function useProcessNodeLogic(props) {
|
|
6
|
+
const sourceConnections = useNodeConnections({ handleType: 'target' })
|
|
7
|
+
const targetConnections = useNodeConnections({ handleType: 'source' })
|
|
8
|
+
|
|
9
|
+
const isStartNode = computed(() => sourceConnections.value.length === 0)
|
|
10
|
+
const isEndNode = computed(() => targetConnections.value.length === 0)
|
|
11
|
+
|
|
12
|
+
const status = toRef(() => props.data.status)
|
|
13
|
+
|
|
14
|
+
const bgColor = computed(() => {
|
|
15
|
+
if (isStartNode.value) return '#2563eb'
|
|
16
|
+
|
|
17
|
+
switch (status.value) {
|
|
18
|
+
case ProcessStatus.ERROR:
|
|
19
|
+
return '#f87171'
|
|
20
|
+
case ProcessStatus.FINISHED:
|
|
21
|
+
return '#42B983'
|
|
22
|
+
case ProcessStatus.CANCELLED:
|
|
23
|
+
return '#fbbf24'
|
|
24
|
+
default:
|
|
25
|
+
return '#4b5563'
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const processLabel = computed(() => {
|
|
30
|
+
if (isStartNode.value) return '📦'
|
|
31
|
+
|
|
32
|
+
switch (status.value) {
|
|
33
|
+
case ProcessStatus.ERROR:
|
|
34
|
+
return '❌'
|
|
35
|
+
case ProcessStatus.SKIPPED:
|
|
36
|
+
return '🚧'
|
|
37
|
+
case ProcessStatus.CANCELLED:
|
|
38
|
+
return '🚫'
|
|
39
|
+
case ProcessStatus.FINISHED:
|
|
40
|
+
return '😎'
|
|
41
|
+
default:
|
|
42
|
+
return '🏠'
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
sourceConnections,
|
|
48
|
+
targetConnections,
|
|
49
|
+
isStartNode,
|
|
50
|
+
isEndNode,
|
|
51
|
+
bgColor,
|
|
52
|
+
processLabel,
|
|
53
|
+
status
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { ref, toRef, toValue } from 'vue'
|
|
2
|
+
import { useVueFlow } from '@vue-flow/core'
|
|
3
|
+
import taskHandlers from './taskHandlers'
|
|
4
|
+
|
|
5
|
+
export const ProcessStatus = {
|
|
6
|
+
ERROR: 'error',
|
|
7
|
+
SKIPPED: 'skipped',
|
|
8
|
+
CANCELLED: 'cancelled',
|
|
9
|
+
FINISHED: 'finished',
|
|
10
|
+
RUNNING: 'running',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Composable to simulate running a process tree.
|
|
15
|
+
*
|
|
16
|
+
* It loops through each node, pretends to run an async process, and updates the node's data indicating whether the process has finished.
|
|
17
|
+
* When one node finishes, the next one starts.
|
|
18
|
+
*
|
|
19
|
+
* When a node has multiple descendants, it will run them in parallel.
|
|
20
|
+
*
|
|
21
|
+
* @param options
|
|
22
|
+
* @param options.graph The graph object containing the nodes and edges.
|
|
23
|
+
* @param options.cancelOnError Whether to cancel the process if an error occurs.
|
|
24
|
+
* @param options.nodes The nodes to run.
|
|
25
|
+
* @param options.edges The edges to run.
|
|
26
|
+
* @param options.variables The variables to run.
|
|
27
|
+
* @param options.computedVariables The computed variables to run.
|
|
28
|
+
* @param options.onFinish The function to call when the process finishes.
|
|
29
|
+
*/
|
|
30
|
+
export function useRunProcess({
|
|
31
|
+
graph: dagreGraph,
|
|
32
|
+
cancelOnError = true,
|
|
33
|
+
nodes = [],
|
|
34
|
+
edges = [],
|
|
35
|
+
variables = [],
|
|
36
|
+
computedVariables = [],
|
|
37
|
+
onFinish
|
|
38
|
+
}) {
|
|
39
|
+
const { updateNodeData, getConnectedEdges, findNode } = useVueFlow()
|
|
40
|
+
const nodeOutputs = new Map()
|
|
41
|
+
|
|
42
|
+
const nodeMap = new Map(nodes.map((node) => [node.id, node]))
|
|
43
|
+
|
|
44
|
+
const graph = toRef(() => toValue(dagreGraph))
|
|
45
|
+
|
|
46
|
+
const isRunning = ref(false)
|
|
47
|
+
|
|
48
|
+
/** Map of running tasks with the node ID as the key and the timeout as the value. */
|
|
49
|
+
const runningTasks = new Map()
|
|
50
|
+
|
|
51
|
+
/** Set of node ids of nodes that have been executed */
|
|
52
|
+
const executedNodes = new Set()
|
|
53
|
+
|
|
54
|
+
/** Set of node ids yet to be executed */
|
|
55
|
+
const upcomingTasks = new Set()
|
|
56
|
+
|
|
57
|
+
/** Local copy of the variables, so we can modify them without affecting the original variables */
|
|
58
|
+
const localVariables = ref(variables ? JSON.parse(JSON.stringify(variables.map(v => ({ ...v, value: Object.keys(v).includes('defaultValue') ? v.defaultValue : v.value ?? null })))) : [])
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Run the process on a node.
|
|
62
|
+
* It will mark the node as running, simulate an async process, and then mark the node as finished or errored.
|
|
63
|
+
*
|
|
64
|
+
* @param nodeId The ID of the node to run.
|
|
65
|
+
* @param isStart Whether this is a starting node.
|
|
66
|
+
*/
|
|
67
|
+
async function runNode(nodeId, isStart = false) {
|
|
68
|
+
if (executedNodes.has(nodeId)) {
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// save the upcoming task in case it gets cancelled before we even start it
|
|
73
|
+
upcomingTasks.add(nodeId)
|
|
74
|
+
|
|
75
|
+
// get all incoming edges to this node
|
|
76
|
+
const incomers = getConnectedEdges(nodeId).filter((connection) => connection.target === nodeId)
|
|
77
|
+
|
|
78
|
+
// wait for edge animations to finish before starting the process
|
|
79
|
+
await Promise.all(incomers.map((incomer) => until(() => !incomer.data?.isAnimating)))
|
|
80
|
+
|
|
81
|
+
// remove the upcoming task since we are about to start it
|
|
82
|
+
upcomingTasks.clear()
|
|
83
|
+
|
|
84
|
+
if (!isRunning.value) {
|
|
85
|
+
// The process was stopped
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// mark the node as executed, so it doesn't run again
|
|
90
|
+
executedNodes.add(nodeId)
|
|
91
|
+
|
|
92
|
+
updateNodeStatus(nodeId, ProcessStatus.RUNNING)
|
|
93
|
+
|
|
94
|
+
// RUN THE TASK
|
|
95
|
+
try {
|
|
96
|
+
// Step 1: Gather input from predecessors
|
|
97
|
+
const predecessors = graph.value.predecessors(nodeId) || []
|
|
98
|
+
const inputFromPredecessors = Object.assign({}, ...predecessors.map((id) => nodeOutputs.get(id) ?? {}))
|
|
99
|
+
const input = {
|
|
100
|
+
...inputFromPredecessors,
|
|
101
|
+
...Object.fromEntries(localVariables.value.map(v => [v.name, v.value]))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Step 2: Find the node and its task handler
|
|
105
|
+
const node = nodeMap?.size > 0 ? nodeMap.get(nodeId) : findNode(nodeId)
|
|
106
|
+
|
|
107
|
+
const taskFn = taskHandlers[node.data.taskType ?? node.type]
|
|
108
|
+
|
|
109
|
+
console.log('Running task:', node.data.taskType, taskFn)
|
|
110
|
+
|
|
111
|
+
// Step 3: Execute the task
|
|
112
|
+
const result = taskFn ? await taskFn(input, { node, graph: graph.value, onFinish, localVariables }) : {}
|
|
113
|
+
|
|
114
|
+
// Step 4: Save output for child nodes
|
|
115
|
+
nodeOutputs.set(nodeId, result)
|
|
116
|
+
updateNodeStatus(nodeId, ProcessStatus.FINISHED)
|
|
117
|
+
|
|
118
|
+
// Step 5: Run children
|
|
119
|
+
const outgoingEdges = edges.filter(edge => edge.source === nodeId)
|
|
120
|
+
|
|
121
|
+
const hasBranching = outgoingEdges.some(edge => edge.sourceHandle)
|
|
122
|
+
|
|
123
|
+
for (const edge of outgoingEdges) {
|
|
124
|
+
const { source, sourceHandle } = edge
|
|
125
|
+
const nodeType = nodeMap.get(source).type
|
|
126
|
+
|
|
127
|
+
const shouldRun =
|
|
128
|
+
(nodeType === 'start') ||
|
|
129
|
+
(nodeType === 'confirm' && sourceHandle === 'success' && result.confirmed === true) ||
|
|
130
|
+
(nodeType === 'confirm' && sourceHandle === 'error' && result.confirmed === false) ||
|
|
131
|
+
(nodeType === 'integration-action' && sourceHandle === 'success' && result.result?.success === true) ||
|
|
132
|
+
(nodeType === 'integration-action' && sourceHandle === 'error' && result.result?.success === false) ||
|
|
133
|
+
(nodeType === 'api-request' && sourceHandle === 'success' && result.result?.success === true) ||
|
|
134
|
+
(nodeType === 'api-request' && sourceHandle === 'error' && result.result?.success === false) ||
|
|
135
|
+
(!['confirm', 'integration-action', 'api-request'].includes(nodeType) && sourceHandle === 'success')
|
|
136
|
+
|
|
137
|
+
console.log('should run', shouldRun, nodeType, sourceHandle, result, hasBranching)
|
|
138
|
+
|
|
139
|
+
if (shouldRun) {
|
|
140
|
+
await runNode(edge.target)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
} catch (err) {
|
|
144
|
+
console.error(`Error in node ${nodeId}:`, err)
|
|
145
|
+
updateNodeStatus(nodeId, ProcessStatus.ERROR)
|
|
146
|
+
|
|
147
|
+
if (toValue(cancelOnError)) {
|
|
148
|
+
await skipDescendants(nodeId)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Run a sequence of nodes.
|
|
155
|
+
* It will start with the nodes that have no predecessors and then run the process on each node in sequence.
|
|
156
|
+
* If a node has multiple descendants, it will run them in parallel.
|
|
157
|
+
* If an error occurs, it will stop the process and mark all descendants as skipped.
|
|
158
|
+
* If cancelOnError is true, it will stop the process if an error occurs.
|
|
159
|
+
* If the process is stopped, it will mark all running nodes as cancelled.
|
|
160
|
+
*
|
|
161
|
+
* @param nodes The nodes to run.
|
|
162
|
+
*/
|
|
163
|
+
async function run(nodes) {
|
|
164
|
+
// if the process is already running, we don't want to start it again
|
|
165
|
+
if (isRunning.value) {
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// reset all nodes to their initial state
|
|
170
|
+
reset(nodes)
|
|
171
|
+
|
|
172
|
+
isRunning.value = true
|
|
173
|
+
|
|
174
|
+
// get all starting nodes (nodes with no predecessors)
|
|
175
|
+
const startingNodes = nodes.filter((node) => graph.value.predecessors(node.id)?.length === 0)
|
|
176
|
+
|
|
177
|
+
// run the process on all starting nodes in parallel
|
|
178
|
+
await Promise.all(startingNodes.map((node) => runNode(node.id, true)))
|
|
179
|
+
|
|
180
|
+
clear()
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Reset all nodes to their initial state.
|
|
185
|
+
*
|
|
186
|
+
* @param nodes The nodes to reset.
|
|
187
|
+
*/
|
|
188
|
+
function reset(nodes) {
|
|
189
|
+
clear()
|
|
190
|
+
|
|
191
|
+
for (const node of nodes) {
|
|
192
|
+
updateNodeStatus(node.id, null)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Skip all descendants of a node.
|
|
198
|
+
*
|
|
199
|
+
* @param nodeId The ID of the node to skip descendants for.
|
|
200
|
+
*/
|
|
201
|
+
async function skipDescendants(nodeId) {
|
|
202
|
+
const children = graph.value.successors(nodeId) || []
|
|
203
|
+
|
|
204
|
+
for (const child of children) {
|
|
205
|
+
updateNodeStatus(child, ProcessStatus.SKIPPED)
|
|
206
|
+
await skipDescendants(child)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Stop the process.
|
|
212
|
+
*
|
|
213
|
+
* It will mark all running nodes as cancelled and skip all upcoming tasks.
|
|
214
|
+
*/
|
|
215
|
+
async function stop() {
|
|
216
|
+
isRunning.value = false
|
|
217
|
+
|
|
218
|
+
for (const nodeId of upcomingTasks) {
|
|
219
|
+
clearTimeout(runningTasks.get(nodeId))
|
|
220
|
+
runningTasks.delete(nodeId)
|
|
221
|
+
updateNodeStatus(nodeId, ProcessStatus.CANCELLED)
|
|
222
|
+
await skipDescendants(nodeId)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
for (const [nodeId, task] of runningTasks) {
|
|
226
|
+
clearTimeout(task)
|
|
227
|
+
runningTasks.delete(nodeId)
|
|
228
|
+
updateNodeStatus(nodeId, ProcessStatus.CANCELLED)
|
|
229
|
+
await skipDescendants(nodeId)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
executedNodes.clear()
|
|
233
|
+
upcomingTasks.clear()
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Clear all running tasks and executed nodes.
|
|
238
|
+
*/
|
|
239
|
+
function clear() {
|
|
240
|
+
isRunning.value = false
|
|
241
|
+
executedNodes.clear()
|
|
242
|
+
runningTasks.clear()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Update the status of a node.
|
|
247
|
+
*
|
|
248
|
+
* @param nodeId The ID of the node to update.
|
|
249
|
+
* @param status The new status of the node.
|
|
250
|
+
*/
|
|
251
|
+
function updateNodeStatus(nodeId, status) {
|
|
252
|
+
updateNodeData(nodeId, { status })
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return { run, stop, reset, isRunning }
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async function until(condition) {
|
|
259
|
+
return new Promise((resolve) => {
|
|
260
|
+
const interval = setInterval(() => {
|
|
261
|
+
if (condition()) {
|
|
262
|
+
clearInterval(interval)
|
|
263
|
+
resolve(true)
|
|
264
|
+
}
|
|
265
|
+
}, 100)
|
|
266
|
+
})
|
|
267
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Slot } from 'reka-ui'
|
|
3
|
+
import { useFormField } from './useFormField'
|
|
4
|
+
|
|
5
|
+
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<Slot
|
|
10
|
+
:id="formItemId"
|
|
11
|
+
data-slot="form-control"
|
|
12
|
+
:aria-describedby="!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`"
|
|
13
|
+
:aria-invalid="!!error"
|
|
14
|
+
>
|
|
15
|
+
<slot />
|
|
16
|
+
</Slot>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { cn } from '../../../lib/utils'
|
|
4
|
+
import { useFormField } from './useFormField'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
class?: HTMLAttributes['class']
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
const { formDescriptionId } = useFormField()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<p
|
|
15
|
+
:id="formDescriptionId"
|
|
16
|
+
data-slot="form-description"
|
|
17
|
+
:class="cn('text-muted-foreground text-sm', props.class)"
|
|
18
|
+
>
|
|
19
|
+
<slot />
|
|
20
|
+
</p>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { cn } from '../../../lib/utils'
|
|
3
|
+
import { useId } from 'reka-ui'
|
|
4
|
+
import { type HTMLAttributes, provide } from 'vue'
|
|
5
|
+
import { FORM_ITEM_INJECTION_KEY } from './injectionKeys'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
class?: HTMLAttributes['class']
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
const id = useId()
|
|
12
|
+
provide(FORM_ITEM_INJECTION_KEY, id)
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<div
|
|
17
|
+
data-slot="form-item"
|
|
18
|
+
:class="cn('grid gap-2', props.class)"
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { LabelProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { cn } from '../../../lib/utils'
|
|
5
|
+
import { Label } from '../label'
|
|
6
|
+
import { useFormField } from './useFormField'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()
|
|
9
|
+
|
|
10
|
+
const { error, formItemId } = useFormField()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<Label
|
|
15
|
+
data-slot="form-label"
|
|
16
|
+
:data-error="!!error"
|
|
17
|
+
:class="cn(
|
|
18
|
+
'data-[error=true]:text-destructive-foreground',
|
|
19
|
+
props.class,
|
|
20
|
+
)"
|
|
21
|
+
:for="formItemId"
|
|
22
|
+
>
|
|
23
|
+
<slot />
|
|
24
|
+
</Label>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { cn } from '../../../lib/utils'
|
|
3
|
+
import { ErrorMessage } from 'vee-validate'
|
|
4
|
+
import { type HTMLAttributes, toValue } from 'vue'
|
|
5
|
+
import { useFormField } from './useFormField'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
class?: HTMLAttributes['class']
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
const { name, formMessageId } = useFormField()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<ErrorMessage
|
|
16
|
+
:id="formMessageId"
|
|
17
|
+
data-slot="form-message"
|
|
18
|
+
as="p"
|
|
19
|
+
:name="toValue(name)"
|
|
20
|
+
:class="cn('text-destructive-foreground text-sm', props.class)"
|
|
21
|
+
/>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as FormControl } from './FormControl.vue'
|
|
2
|
+
export { default as FormDescription } from './FormDescription.vue'
|
|
3
|
+
export { default as FormItem } from './FormItem.vue'
|
|
4
|
+
export { default as FormLabel } from './FormLabel.vue'
|
|
5
|
+
export { default as FormMessage } from './FormMessage.vue'
|
|
6
|
+
export { FORM_ITEM_INJECTION_KEY } from './injectionKeys'
|
|
7
|
+
export { Form, Field as FormField, FieldArray as FormFieldArray } from 'vee-validate'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate'
|
|
2
|
+
import { inject } from 'vue'
|
|
3
|
+
import { FORM_ITEM_INJECTION_KEY } from './injectionKeys'
|
|
4
|
+
|
|
5
|
+
export function useFormField() {
|
|
6
|
+
const fieldContext = inject(FieldContextKey)
|
|
7
|
+
const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY)
|
|
8
|
+
|
|
9
|
+
if (!fieldContext)
|
|
10
|
+
throw new Error('useFormField should be used within <FormField>')
|
|
11
|
+
|
|
12
|
+
const { name } = fieldContext
|
|
13
|
+
const id = fieldItemContext
|
|
14
|
+
|
|
15
|
+
const fieldState = {
|
|
16
|
+
valid: useIsFieldValid(name),
|
|
17
|
+
isDirty: useIsFieldDirty(name),
|
|
18
|
+
isTouched: useIsFieldTouched(name),
|
|
19
|
+
error: useFieldError(name),
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
id,
|
|
24
|
+
name,
|
|
25
|
+
formItemId: `${id}-form-item`,
|
|
26
|
+
formDescriptionId: `${id}-form-item-description`,
|
|
27
|
+
formMessageId: `${id}-form-item-message`,
|
|
28
|
+
...fieldState,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { nextTick, ref, watch } from 'vue'
|
|
3
|
+
import FormBuilderWrapper from './components/FormBuilderWrapper.vue'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
id: number
|
|
7
|
+
config: any
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
const { closeFormBuilder } = useFormBuilder()
|
|
11
|
+
const formBuilder = ref()
|
|
12
|
+
|
|
13
|
+
watch(
|
|
14
|
+
() => props.config,
|
|
15
|
+
async () => {
|
|
16
|
+
await nextTick()
|
|
17
|
+
formBuilder.value?.setState(props.config)
|
|
18
|
+
},
|
|
19
|
+
{ immediate: true }
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const save = () => {
|
|
23
|
+
const data = formBuilder.value.getState()
|
|
24
|
+
console.log("Saving form builder", data)
|
|
25
|
+
closeFormBuilder(props.id, data)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const cancel = () => {
|
|
29
|
+
closeFormBuilder(props.id, false)
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<Teleport to="body">
|
|
35
|
+
<Sheet :open="true" @update:open="cancel">
|
|
36
|
+
<SheetContent side="bottom" class="w-full h-full sm:max-w-full">
|
|
37
|
+
<FormBuilderWrapper ref="formBuilder" />
|
|
38
|
+
<div class="flex justify-end gap-2 p-4">
|
|
39
|
+
<Button variant="outline" @click="cancel">Cancel</Button>
|
|
40
|
+
<Button @click="save">Save</Button>
|
|
41
|
+
</div>
|
|
42
|
+
</SheetContent>
|
|
43
|
+
</Sheet>
|
|
44
|
+
</Teleport>
|
|
45
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useVModel } from '@vueuse/core'
|
|
3
|
+
|
|
4
|
+
const { openFormBuilder } = useFormBuilder()
|
|
5
|
+
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
modelValue: {
|
|
8
|
+
type: Array,
|
|
9
|
+
required: true
|
|
10
|
+
},
|
|
11
|
+
buildText: {
|
|
12
|
+
type: String,
|
|
13
|
+
default: 'Build form'
|
|
14
|
+
},
|
|
15
|
+
editText: {
|
|
16
|
+
type: String,
|
|
17
|
+
default: 'Edit form'
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const emits = defineEmits<{
|
|
22
|
+
(e: 'update:modelValue', payload: any[]): void
|
|
23
|
+
}>()
|
|
24
|
+
|
|
25
|
+
const modelValue = useVModel(props, 'modelValue', emits, {
|
|
26
|
+
passive: true
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const editForm = async () => {
|
|
30
|
+
let config = await openFormBuilder(modelValue.value)
|
|
31
|
+
if (config) {
|
|
32
|
+
emits('update:modelValue', config)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<Button @click="editForm">
|
|
39
|
+
<span v-if="!modelValue || modelValue.length === 0">{{ buildText }}</span>
|
|
40
|
+
<span v-else>{{ editText }}</span>
|
|
41
|
+
</Button>
|
|
42
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import FormBuilderWrapper from './components/FormBuilderWrapper.vue';
|
|
3
|
+
import { ref, nextTick, onMounted } from 'vue'
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
settings: {
|
|
7
|
+
type: Object,
|
|
8
|
+
required: true
|
|
9
|
+
},
|
|
10
|
+
onFinish: {
|
|
11
|
+
type: Function,
|
|
12
|
+
default: () => {}
|
|
13
|
+
},
|
|
14
|
+
variables: {
|
|
15
|
+
type: Array,
|
|
16
|
+
default: () => []
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const form = ref()
|
|
21
|
+
|
|
22
|
+
const loadForm = async () => {
|
|
23
|
+
await nextTick()
|
|
24
|
+
form.value.setState({
|
|
25
|
+
...props.settings,
|
|
26
|
+
layoutRef: {},
|
|
27
|
+
itemRefs: {},
|
|
28
|
+
})
|
|
29
|
+
form.value.fillDefaultValues()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
onMounted(() => {
|
|
33
|
+
loadForm()
|
|
34
|
+
})
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<FormBuilderWrapper ref="form" :isPresentationMode="true" :onFinish="onFinish" :providedVariables="variables" />
|
|
39
|
+
</template>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue';
|
|
3
|
+
import settingViews from './admin/element-setting-views';
|
|
4
|
+
import Transformer from '../components/admin/Transformer.vue'
|
|
5
|
+
|
|
6
|
+
const activeElement = inject('activeElement');
|
|
7
|
+
const state = inject('state');
|
|
8
|
+
|
|
9
|
+
const emit = defineEmits(['removeItem']);
|
|
10
|
+
|
|
11
|
+
function removeItem() {
|
|
12
|
+
emit('removeItem', activeElement.value.i);
|
|
13
|
+
activeElement.value = null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const newName = ref("");
|
|
17
|
+
|
|
18
|
+
watch(activeElement, () => {
|
|
19
|
+
newName.value = activeElement.value.variableName || "";
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
function updateVariableName() {
|
|
23
|
+
let oldName = activeElement.value.variableName;
|
|
24
|
+
activeElement.value.variableName = newName.value;
|
|
25
|
+
|
|
26
|
+
if (state.elementValues[oldName]) {
|
|
27
|
+
state.elementValues[newName.value] = state.elementValues[oldName];
|
|
28
|
+
delete state.elementValues[oldName];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
onMounted(() => {
|
|
33
|
+
newName.value = activeElement.value?.variableName || "";
|
|
34
|
+
})
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<div class="shrink-0 p-2 rounded-xl border bg-card w-[275px] @7xl/custom-dashboard:w-[325px]">
|
|
39
|
+
<Input type="text" placeholder="Variable Name" v-model="newName" @blur="updateVariableName" class="bg-gray-200/25 hover:bg-gray-200/35 dark:bg-muted/25 dark:hover:bg-muted/30 border-transparent hover:border-ring focus:border-ring dark:focus:border-ring shadow-none focus:shadow-xs mb-4" />
|
|
40
|
+
|
|
41
|
+
<component :is="settingViews[activeElement.component]" />
|
|
42
|
+
|
|
43
|
+
<p class="text-sm font-semibold mt-4 mb-2">Visible</p>
|
|
44
|
+
<Transformer v-model="activeElement.visibility" placeholder="true" />
|
|
45
|
+
|
|
46
|
+
<Button variant="destructive" @click="removeItem" class="mt-4">Remove Element</Button>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|