@@ -61,5 +61,3 @@ function BaseModal({ title, description, buttons }: BaseModalProps) {
);
}
-
-export default BaseModal;
diff --git a/frontend/src/components/modals/confirmation-modals/danger-modal.tsx b/frontend/src/components/modals/confirmation-modals/danger-modal.tsx
index 0f14ff76f4ef..fa6d468d0072 100644
--- a/frontend/src/components/modals/confirmation-modals/danger-modal.tsx
+++ b/frontend/src/components/modals/confirmation-modals/danger-modal.tsx
@@ -1,4 +1,4 @@
-import BaseModal from "./base-modal";
+import { BaseModal } from "./base-modal";
interface DangerModalProps {
title: string;
diff --git a/frontend/src/components/exit-project-confirmation-modal.tsx b/frontend/src/components/modals/exit-project-confirmation-modal.tsx
similarity index 100%
rename from frontend/src/components/exit-project-confirmation-modal.tsx
rename to frontend/src/components/modals/exit-project-confirmation-modal.tsx
diff --git a/frontend/src/components/modals/loading-project.tsx b/frontend/src/components/modals/loading-project.tsx
deleted file mode 100644
index e851656d245e..000000000000
--- a/frontend/src/components/modals/loading-project.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { useTranslation } from "react-i18next";
-import LoadingSpinnerOuter from "#/icons/loading-outer.svg?react";
-import { cn } from "#/utils/utils";
-import { ModalBody } from "./modal-body";
-import { I18nKey } from "#/i18n/declaration";
-
-interface LoadingSpinnerProps {
- size: "small" | "large";
-}
-
-export function LoadingSpinner({ size }: LoadingSpinnerProps) {
- const sizeStyle =
- size === "small" ? "w-[25px] h-[25px]" : "w-[50px] h-[50px]";
-
- return (
-
- );
-}
-
-interface LoadingProjectModalProps {
- message?: string;
-}
-
-function LoadingProjectModal({ message }: LoadingProjectModalProps) {
- const { t } = useTranslation();
-
- return (
-
- );
-}
-
-export default LoadingProjectModal;
diff --git a/frontend/src/components/modals/security/security.tsx b/frontend/src/components/modals/security/security.tsx
index f5001fa9a8f9..ba30bc08c851 100644
--- a/frontend/src/components/modals/security/security.tsx
+++ b/frontend/src/components/modals/security/security.tsx
@@ -1,8 +1,8 @@
import React from "react";
import { useTranslation } from "react-i18next";
import SecurityInvariant from "./invariant/invariant";
-import BaseModal from "../base-modal/base-modal";
import { I18nKey } from "#/i18n/declaration";
+import { BaseModal } from "../base-modal/base-modal";
interface SecurityProps {
isOpen: boolean;
diff --git a/frontend/src/components/settings-form.tsx b/frontend/src/components/modals/settings/settings-form.tsx
similarity index 93%
rename from frontend/src/components/settings-form.tsx
rename to frontend/src/components/modals/settings/settings-form.tsx
index 71db93b5bc80..d5c5d97efcb5 100644
--- a/frontend/src/components/settings-form.tsx
+++ b/frontend/src/components/modals/settings/settings-form.tsx
@@ -7,8 +7,8 @@ import { ModelSelector } from "#/components/modals/settings/model-selector";
import { getDefaultSettings, Settings } from "#/services/settings";
import { ModalBackdrop } from "#/components/modals/modal-backdrop";
import { extractModelAndProvider } from "#/utils/extract-model-and-provider";
-import { ModalButton } from "./ui/buttons/modal-button";
-import { DangerModal } from "./modals/confirmation-modals/danger-modal";
+import { ModalButton } from "../../ui/buttons/modal-button";
+import { DangerModal } from "../confirmation-modals/danger-modal";
import { I18nKey } from "#/i18n/declaration";
import {
extractSettings,
@@ -17,13 +17,13 @@ import {
} from "#/utils/settings-utils";
import { useEndSession } from "#/hooks/use-end-session";
import { useUserPrefs } from "#/context/user-prefs-context";
-import { AdvancedOptionSwitch } from "./ui/inputs/advanced-option-switch";
-import { CustomModelInput } from "./ui/inputs/custom-model-input";
-import { BaseUrlInput } from "./ui/inputs/base-url-input";
-import { AgentInput } from "./ui/inputs/agent-input";
-import { APIKeyInput } from "./ui/inputs/api-key-input";
-import { SecurityAnalyzerInput } from "./ui/inputs/security-analyzers-input";
-import { ConfirmationModeSwitch } from "./ui/inputs/confirmation-mode-switch";
+import { AdvancedOptionSwitch } from "../../ui/inputs/advanced-option-switch";
+import { CustomModelInput } from "../../ui/inputs/custom-model-input";
+import { BaseUrlInput } from "../../ui/inputs/base-url-input";
+import { AgentInput } from "../../ui/inputs/agent-input";
+import { APIKeyInput } from "../../ui/inputs/api-key-input";
+import { SecurityAnalyzerInput } from "../../ui/inputs/security-analyzers-input";
+import { ConfirmationModeSwitch } from "../../ui/inputs/confirmation-mode-switch";
interface SettingsFormProps {
disabled?: boolean;
diff --git a/frontend/src/components/settings-modal.tsx b/frontend/src/components/modals/settings/settings-modal.tsx
similarity index 92%
rename from frontend/src/components/settings-modal.tsx
rename to frontend/src/components/modals/settings/settings-modal.tsx
index 7b3917c8324d..d3702d94c59c 100644
--- a/frontend/src/components/settings-modal.tsx
+++ b/frontend/src/components/modals/settings/settings-modal.tsx
@@ -1,8 +1,8 @@
-import { SettingsForm } from "#/components/settings-form";
-import { LoadingSpinner } from "#/components/modals/loading-project";
+import { SettingsForm } from "#/components/modals/settings/settings-form";
import { ModalBackdrop } from "#/components/modals/modal-backdrop";
import { useUserPrefs } from "#/context/user-prefs-context";
import { useAIConfigOptions } from "#/hooks/query/use-ai-config-options";
+import { LoadingSpinner } from "#/components/ui/loading-spinner";
interface SettingsModalProps {
onClose: () => void;
diff --git a/frontend/src/components/ui/loading-spinner.tsx b/frontend/src/components/ui/loading-spinner.tsx
index ba119cb20c6b..5f19d0fe4de6 100644
--- a/frontend/src/components/ui/loading-spinner.tsx
+++ b/frontend/src/components/ui/loading-spinner.tsx
@@ -1,7 +1,23 @@
-export function LoadingSpinner() {
+import LoadingSpinnerOuter from "#/icons/loading-outer.svg?react";
+import { cn } from "#/utils/utils";
+
+interface LoadingSpinnerProps {
+ size: "small" | "large";
+}
+
+export function LoadingSpinner({ size }: LoadingSpinnerProps) {
+ const sizeStyle =
+ size === "small" ? "w-[25px] h-[25px]" : "w-[50px] h-[50px]";
+
return (
-
-
+
);
}
From cbbe55e09da0c67611a3f5a6ebd78c8825d7aa74 Mon Sep 17 00:00:00 2001
From: amanape <83104063+amanape@users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:21:02 +0400
Subject: [PATCH 12/13] Update README
---
frontend/README.md | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/frontend/README.md b/frontend/README.md
index 7d05e8a9ba3c..65493728aa39 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -9,6 +9,7 @@ This is the frontend of the OpenHands project. It is a React application that pr
- Remix SPA Mode (React + Vite + React Router)
- TypeScript
- Redux
+- TanStack Query
- Tailwind CSS
- i18next
- React Testing Library
@@ -85,7 +86,7 @@ frontend
├── src
│ ├── api # API calls
│ ├── assets
-│ ├── components # Reusable components
+│ ├── components
│ ├── context # Local state management
│ ├── hooks # Custom hooks
│ ├── i18n # Internationalization
@@ -99,6 +100,18 @@ frontend
└── .env.sample # Sample environment variables
```
+#### Components
+
+Components are organized into folders based on their **domain**, **feature**, or **shared functionality**.
+
+```sh
+components
+├── features # Domain-specific components
+├── layout
+├── modals
+└── ui # Shared UI components
+```
+
### Features
- Real-time updates with WebSockets
From b89e1b070c0492a91edecdedadda53cedb0362eb Mon Sep 17 00:00:00 2001
From: amanape <83104063+amanape@users.noreply.github.com>
Date: Thu, 28 Nov 2024 00:06:04 +0400
Subject: [PATCH 13/13] Rename ui to shared and move modals to shared
---
.../modals/base-modal/base-modal.test.tsx | 2 +-
.../modals/settings/model-selector.test.tsx | 2 +-
.../analytics-consent-form-modal.tsx | 8 ++++----
.../components/features/chat/chat-input.tsx | 4 ++--
.../features/chat/chat-interface.tsx | 6 +++---
.../components/features/chat/chat-message.tsx | 2 +-
.../src/components/features/chat/messages.tsx | 2 +-
.../features/controls/agent-control-bar.tsx | 2 +-
.../features/editor/editor-actions.tsx | 2 +-
.../features/feedback/feedback-actions.tsx | 2 +-
.../features/feedback/feedback-form.tsx | 2 +-
.../features/feedback/feedback-modal.tsx | 8 ++++----
.../file-explorer/file-explorer-actions.tsx | 6 +++---
.../features/file-explorer/file-explorer.tsx | 2 +-
.../github-repositories-suggestion-box.tsx | 6 +++---
.../features/images/image-preview.tsx | 2 +-
.../components/features/jupyter/jupyter.tsx | 2 +-
.../features/project-menu/ProjectMenuCard.tsx | 6 +++---
.../components/features/sidebar/sidebar.tsx | 16 +++++++--------
.../features/sidebar/user-avatar.tsx | 2 +-
.../suggestions/suggestion-bubble.tsx | 2 +-
.../features/waitlist/waitlist-modal.tsx | 6 +++---
.../{ui => shared}/action-tooltip.tsx | 0
.../{ui => shared}/buttons/action-button.tsx | 0
.../buttons/all-hands-logo-button.tsx | 0
.../buttons/confirmation-buttons.tsx | 0
.../buttons/continue-button.tsx | 0
.../buttons/copy-to-clipboard-button.tsx | 0
.../{ui => shared}/buttons/docs-button.tsx | 0
.../buttons/editor-action-button.tsx | 0
.../buttons/exit-project-button.tsx | 0
.../buttons/feedback-action-button.tsx | 0
.../{ui => shared}/buttons/icon-button.tsx | 0
.../{ui => shared}/buttons/modal-button.tsx | 0
.../buttons/open-vscode-button.tsx | 0
.../{ui => shared}/buttons/refresh-button.tsx | 0
.../buttons/refresh-icon-button.tsx | 2 +-
.../{ui => shared}/buttons/remove-button.tsx | 0
.../buttons/scroll-to-bottom-button.tsx | 0
.../buttons/settings-button.tsx | 0
.../{ui => shared}/buttons/stop-button.tsx | 0
.../{ui => shared}/buttons/submit-button.tsx | 0
.../buttons/toggle-workspace-icon-button.tsx | 2 +-
.../buttons/upload-icon-button.tsx | 2 +-
.../{ui => shared}/custom-input.tsx | 0
.../components/{ui => shared}/error-toast.tsx | 0
.../{ui => shared}/form-fieldset.tsx | 0
.../{ui => shared}/hero-heading.tsx | 0
.../inputs/advanced-option-switch.tsx | 0
.../{ui => shared}/inputs/agent-input.tsx | 0
.../{ui => shared}/inputs/api-key-input.tsx | 0
.../{ui => shared}/inputs/base-url-input.tsx | 0
.../inputs/confirmation-mode-switch.tsx | 0
.../inputs/custom-model-input.tsx | 0
.../inputs/security-analyzers-input.tsx | 0
.../{ui => shared}/loading-spinner.tsx | 0
.../account-settings-form.tsx | 6 +++---
.../account-settings-modal.tsx | 4 ++--
.../modals/base-modal/base-modal.tsx | 0
.../modals/base-modal/footer-content.tsx | 0
.../modals/base-modal/header-content.tsx | 0
.../modals/confirmation-modals/base-modal.tsx | 2 +-
.../confirmation-modals/danger-modal.tsx | 0
.../modals/connect-to-github-modal.tsx | 4 ++--
.../exit-project-confirmation-modal.tsx | 4 ++--
.../{ => shared}/modals/modal-backdrop.tsx | 0
.../{ => shared}/modals/modal-body.tsx | 0
.../modals/security/invariant/assets/logo.tsx | 0
.../modals/security/invariant/invariant.tsx | 0
.../{ => shared}/modals/security/security.tsx | 0
.../modals/settings/model-selector.tsx | 0
.../modals/settings/settings-form.tsx | 20 +++++++++----------
.../modals/settings/settings-modal.tsx | 6 +++---
.../components/{ui => shared}/task-form.tsx | 0
frontend/src/routes/_oh._index/route.tsx | 4 ++--
frontend/src/routes/_oh.app/route.tsx | 2 +-
frontend/src/utils/display-error-toast.tsx | 2 +-
77 files changed, 76 insertions(+), 76 deletions(-)
rename frontend/src/components/{ui => shared}/action-tooltip.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/action-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/all-hands-logo-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/confirmation-buttons.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/continue-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/copy-to-clipboard-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/docs-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/editor-action-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/exit-project-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/feedback-action-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/icon-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/modal-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/open-vscode-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/refresh-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/refresh-icon-button.tsx (87%)
rename frontend/src/components/{ui => shared}/buttons/remove-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/scroll-to-bottom-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/settings-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/stop-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/submit-button.tsx (100%)
rename frontend/src/components/{ui => shared}/buttons/toggle-workspace-icon-button.tsx (91%)
rename frontend/src/components/{ui => shared}/buttons/upload-icon-button.tsx (87%)
rename frontend/src/components/{ui => shared}/custom-input.tsx (100%)
rename frontend/src/components/{ui => shared}/error-toast.tsx (100%)
rename frontend/src/components/{ui => shared}/form-fieldset.tsx (100%)
rename frontend/src/components/{ui => shared}/hero-heading.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/advanced-option-switch.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/agent-input.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/api-key-input.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/base-url-input.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/confirmation-mode-switch.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/custom-model-input.tsx (100%)
rename frontend/src/components/{ui => shared}/inputs/security-analyzers-input.tsx (100%)
rename frontend/src/components/{ui => shared}/loading-spinner.tsx (100%)
rename frontend/src/components/{ => shared}/modals/account-settings/account-settings-form.tsx (96%)
rename frontend/src/components/{ => shared}/modals/account-settings/account-settings-modal.tsx (81%)
rename frontend/src/components/{ => shared}/modals/base-modal/base-modal.tsx (100%)
rename frontend/src/components/{ => shared}/modals/base-modal/footer-content.tsx (100%)
rename frontend/src/components/{ => shared}/modals/base-modal/header-content.tsx (100%)
rename frontend/src/components/{ => shared}/modals/confirmation-modals/base-modal.tsx (95%)
rename frontend/src/components/{ => shared}/modals/confirmation-modals/danger-modal.tsx (100%)
rename frontend/src/components/{ => shared}/modals/connect-to-github-modal.tsx (95%)
rename frontend/src/components/{ => shared}/modals/exit-project-confirmation-modal.tsx (87%)
rename frontend/src/components/{ => shared}/modals/modal-backdrop.tsx (100%)
rename frontend/src/components/{ => shared}/modals/modal-body.tsx (100%)
rename frontend/src/components/{ => shared}/modals/security/invariant/assets/logo.tsx (100%)
rename frontend/src/components/{ => shared}/modals/security/invariant/invariant.tsx (100%)
rename frontend/src/components/{ => shared}/modals/security/security.tsx (100%)
rename frontend/src/components/{ => shared}/modals/settings/model-selector.tsx (100%)
rename frontend/src/components/{ => shared}/modals/settings/settings-form.tsx (92%)
rename frontend/src/components/{ => shared}/modals/settings/settings-modal.tsx (88%)
rename frontend/src/components/{ui => shared}/task-form.tsx (100%)
diff --git a/frontend/__tests__/components/modals/base-modal/base-modal.test.tsx b/frontend/__tests__/components/modals/base-modal/base-modal.test.tsx
index 6824fd927eed..563cbca6c45a 100644
--- a/frontend/__tests__/components/modals/base-modal/base-modal.test.tsx
+++ b/frontend/__tests__/components/modals/base-modal/base-modal.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, act } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, it, vi, expect } from "vitest";
-import { BaseModal } from "#/components/modals/base-modal/base-modal";
+import { BaseModal } from "#/components/shared/modals/base-modal/base-modal";
describe("BaseModal", () => {
it("should render if the modal is open", () => {
diff --git a/frontend/__tests__/components/modals/settings/model-selector.test.tsx b/frontend/__tests__/components/modals/settings/model-selector.test.tsx
index 2823d988eca7..8da2fec14475 100644
--- a/frontend/__tests__/components/modals/settings/model-selector.test.tsx
+++ b/frontend/__tests__/components/modals/settings/model-selector.test.tsx
@@ -1,7 +1,7 @@
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
-import { ModelSelector } from "#/components/modals/settings/model-selector";
+import { ModelSelector } from "#/components/shared/modals/settings/model-selector";
describe("ModelSelector", () => {
const models = {
diff --git a/frontend/src/components/features/analytics/analytics-consent-form-modal.tsx b/frontend/src/components/features/analytics/analytics-consent-form-modal.tsx
index 0946a2880fc9..02fabd81aedc 100644
--- a/frontend/src/components/features/analytics/analytics-consent-form-modal.tsx
+++ b/frontend/src/components/features/analytics/analytics-consent-form-modal.tsx
@@ -1,10 +1,10 @@
-import { ModalBackdrop } from "../../modals/modal-backdrop";
-import { ModalBody } from "../../modals/modal-body";
-import { ModalButton } from "../../ui/buttons/modal-button";
+import { ModalButton } from "#/components/shared/buttons/modal-button";
import {
BaseModalTitle,
BaseModalDescription,
-} from "../../modals/confirmation-modals/base-modal";
+} from "#/components/shared/modals/confirmation-modals/base-modal";
+import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
+import { ModalBody } from "#/components/shared/modals/modal-body";
import { handleCaptureConsent } from "#/utils/handle-capture-consent";
interface AnalyticsConsentFormModalProps {
diff --git a/frontend/src/components/features/chat/chat-input.tsx b/frontend/src/components/features/chat/chat-input.tsx
index af5be4d8336f..815eb1933720 100644
--- a/frontend/src/components/features/chat/chat-input.tsx
+++ b/frontend/src/components/features/chat/chat-input.tsx
@@ -1,8 +1,8 @@
import React from "react";
import TextareaAutosize from "react-textarea-autosize";
import { cn } from "#/utils/utils";
-import { SubmitButton } from "../../ui/buttons/submit-button";
-import { StopButton } from "../../ui/buttons/stop-button";
+import { SubmitButton } from "#/components/shared/buttons/submit-button";
+import { StopButton } from "#/components/shared/buttons/stop-button";
interface ChatInputProps {
name?: string;
diff --git a/frontend/src/components/features/chat/chat-interface.tsx b/frontend/src/components/features/chat/chat-interface.tsx
index bdc6126b2f56..d87ded048906 100644
--- a/frontend/src/components/features/chat/chat-interface.tsx
+++ b/frontend/src/components/features/chat/chat-interface.tsx
@@ -12,13 +12,13 @@ import { generateAgentStateChangeEvent } from "#/services/agent-state-service";
import { FeedbackModal } from "../feedback/feedback-modal";
import { useScrollToBottom } from "#/hooks/use-scroll-to-bottom";
import { TypingIndicator } from "./typing-indicator";
-import { ContinueButton } from "../../ui/buttons/continue-button";
-import { ScrollToBottomButton } from "../../ui/buttons/scroll-to-bottom-button";
import { useWsClient } from "#/context/ws-client-provider";
import { Messages } from "./messages";
import { ChatSuggestions } from "./chat-suggestions";
import { ActionSuggestions } from "./action-suggestions";
-import { LoadingSpinner } from "#/components/ui/loading-spinner";
+import { ContinueButton } from "#/components/shared/buttons/continue-button";
+import { ScrollToBottomButton } from "#/components/shared/buttons/scroll-to-bottom-button";
+import { LoadingSpinner } from "#/components/shared/loading-spinner";
export function ChatInterface() {
const { send, isLoadingMessages } = useWsClient();
diff --git a/frontend/src/components/features/chat/chat-message.tsx b/frontend/src/components/features/chat/chat-message.tsx
index 96e530e5e527..96d21dfcada9 100644
--- a/frontend/src/components/features/chat/chat-message.tsx
+++ b/frontend/src/components/features/chat/chat-message.tsx
@@ -4,7 +4,7 @@ import remarkGfm from "remark-gfm";
import { code } from "../markdown/code";
import { cn } from "#/utils/utils";
import { ul, ol } from "../markdown/list";
-import { CopyToClipboardButton } from "../../ui/buttons/copy-to-clipboard-button";
+import { CopyToClipboardButton } from "#/components/shared/buttons/copy-to-clipboard-button";
interface ChatMessageProps {
type: "user" | "assistant";
diff --git a/frontend/src/components/features/chat/messages.tsx b/frontend/src/components/features/chat/messages.tsx
index 8307238eac08..0b2f0789620a 100644
--- a/frontend/src/components/features/chat/messages.tsx
+++ b/frontend/src/components/features/chat/messages.tsx
@@ -1,5 +1,5 @@
import { ChatMessage } from "#/components/features/chat/chat-message";
-import { ConfirmationButtons } from "#/components/ui/buttons/confirmation-buttons";
+import { ConfirmationButtons } from "#/components/shared/buttons/confirmation-buttons";
import { ImageCarousel } from "../images/image-carousel";
import { ErrorMessage } from "./error-message";
diff --git a/frontend/src/components/features/controls/agent-control-bar.tsx b/frontend/src/components/features/controls/agent-control-bar.tsx
index cb8e6009327f..dad718533f6e 100644
--- a/frontend/src/components/features/controls/agent-control-bar.tsx
+++ b/frontend/src/components/features/controls/agent-control-bar.tsx
@@ -6,7 +6,7 @@ import { RootState } from "#/store";
import AgentState from "#/types/agent-state";
import { useWsClient } from "#/context/ws-client-provider";
import { IGNORE_TASK_STATE_MAP } from "#/ignore-task-state-map.constant";
-import { ActionButton } from "../../ui/buttons/action-button";
+import { ActionButton } from "#/components/shared/buttons/action-button";
export function AgentControlBar() {
const { send } = useWsClient();
diff --git a/frontend/src/components/features/editor/editor-actions.tsx b/frontend/src/components/features/editor/editor-actions.tsx
index 28e375c58573..1f3accf6252a 100644
--- a/frontend/src/components/features/editor/editor-actions.tsx
+++ b/frontend/src/components/features/editor/editor-actions.tsx
@@ -1,4 +1,4 @@
-import { EditorActionButton } from "../../ui/buttons/editor-action-button";
+import { EditorActionButton } from "#/components/shared/buttons/editor-action-button";
interface EditorActionsProps {
onSave: () => void;
diff --git a/frontend/src/components/features/feedback/feedback-actions.tsx b/frontend/src/components/features/feedback/feedback-actions.tsx
index 386c04c7d734..2293789c201f 100644
--- a/frontend/src/components/features/feedback/feedback-actions.tsx
+++ b/frontend/src/components/features/feedback/feedback-actions.tsx
@@ -1,6 +1,6 @@
import ThumbsUpIcon from "#/icons/thumbs-up.svg?react";
import ThumbDownIcon from "#/icons/thumbs-down.svg?react";
-import { FeedbackActionButton } from "../../ui/buttons/feedback-action-button";
+import { FeedbackActionButton } from "#/components/shared/buttons/feedback-action-button";
interface FeedbackActionsProps {
onPositiveFeedback: () => void;
diff --git a/frontend/src/components/features/feedback/feedback-form.tsx b/frontend/src/components/features/feedback/feedback-form.tsx
index 6e2009c82623..31705a101493 100644
--- a/frontend/src/components/features/feedback/feedback-form.tsx
+++ b/frontend/src/components/features/feedback/feedback-form.tsx
@@ -1,8 +1,8 @@
import React from "react";
import hotToast from "react-hot-toast";
-import { ModalButton } from "../../ui/buttons/modal-button";
import { Feedback } from "#/api/open-hands.types";
import { useSubmitFeedback } from "#/hooks/mutation/use-submit-feedback";
+import { ModalButton } from "#/components/shared/buttons/modal-button";
const FEEDBACK_VERSION = "1.0";
const VIEWER_PAGE = "https://www.all-hands.dev/share";
diff --git a/frontend/src/components/features/feedback/feedback-modal.tsx b/frontend/src/components/features/feedback/feedback-modal.tsx
index 509343e4d544..a3e9d6264f56 100644
--- a/frontend/src/components/features/feedback/feedback-modal.tsx
+++ b/frontend/src/components/features/feedback/feedback-modal.tsx
@@ -1,10 +1,10 @@
-import { FeedbackForm } from "./feedback-form";
import {
BaseModalTitle,
BaseModalDescription,
-} from "../../modals/confirmation-modals/base-modal";
-import { ModalBackdrop } from "../../modals/modal-backdrop";
-import { ModalBody } from "../../modals/modal-body";
+} from "#/components/shared/modals/confirmation-modals/base-modal";
+import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
+import { ModalBody } from "#/components/shared/modals/modal-body";
+import { FeedbackForm } from "./feedback-form";
interface FeedbackModalProps {
onClose: () => void;
diff --git a/frontend/src/components/features/file-explorer/file-explorer-actions.tsx b/frontend/src/components/features/file-explorer/file-explorer-actions.tsx
index 847b8682f2dd..92698b87eabd 100644
--- a/frontend/src/components/features/file-explorer/file-explorer-actions.tsx
+++ b/frontend/src/components/features/file-explorer/file-explorer-actions.tsx
@@ -1,7 +1,7 @@
+import { RefreshIconButton } from "#/components/shared/buttons/refresh-icon-button";
+import { ToggleWorkspaceIconButton } from "#/components/shared/buttons/toggle-workspace-icon-button";
+import { UploadIconButton } from "#/components/shared/buttons/upload-icon-button";
import { cn } from "#/utils/utils";
-import { RefreshIconButton } from "../../ui/buttons/refresh-icon-button";
-import { ToggleWorkspaceIconButton } from "../../ui/buttons/toggle-workspace-icon-button";
-import { UploadIconButton } from "../../ui/buttons/upload-icon-button";
interface ExplorerActionsProps {
onRefresh: () => void;
diff --git a/frontend/src/components/features/file-explorer/file-explorer.tsx b/frontend/src/components/features/file-explorer/file-explorer.tsx
index 47c04c99172d..b033cfb62126 100644
--- a/frontend/src/components/features/file-explorer/file-explorer.tsx
+++ b/frontend/src/components/features/file-explorer/file-explorer.tsx
@@ -13,7 +13,7 @@ import { cn } from "#/utils/utils";
import { Dropzone } from "./dropzone";
import { FileExplorerHeader } from "./file-explorer-header";
import { useVSCodeUrl } from "#/hooks/query/use-vscode-url";
-import { OpenVSCodeButton } from "../../ui/buttons/open-vscode-button";
+import { OpenVSCodeButton } from "#/components/shared/buttons/open-vscode-button";
interface FileExplorerProps {
isOpen: boolean;
diff --git a/frontend/src/components/features/github/github-repositories-suggestion-box.tsx b/frontend/src/components/features/github/github-repositories-suggestion-box.tsx
index f45e408eb53d..f052e1f202f3 100644
--- a/frontend/src/components/features/github/github-repositories-suggestion-box.tsx
+++ b/frontend/src/components/features/github/github-repositories-suggestion-box.tsx
@@ -1,11 +1,11 @@
import React from "react";
import { isGitHubErrorReponse } from "#/api/github";
import { SuggestionBox } from "#/components/features/suggestions/suggestion-box";
-import { ConnectToGitHubModal } from "../../modals/connect-to-github-modal";
-import { ModalBackdrop } from "../../modals/modal-backdrop";
-import { ModalButton } from "../../ui/buttons/modal-button";
import GitHubLogo from "#/assets/branding/github-logo.svg?react";
import { GitHubRepositorySelector } from "./github-repo-selector";
+import { ModalButton } from "#/components/shared/buttons/modal-button";
+import { ConnectToGitHubModal } from "#/components/shared/modals/connect-to-github-modal";
+import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
interface GitHubRepositoriesSuggestionBoxProps {
handleSubmit: () => void;
diff --git a/frontend/src/components/features/images/image-preview.tsx b/frontend/src/components/features/images/image-preview.tsx
index f0fad3282af0..37dc314a4be8 100644
--- a/frontend/src/components/features/images/image-preview.tsx
+++ b/frontend/src/components/features/images/image-preview.tsx
@@ -1,4 +1,4 @@
-import { RemoveButton } from "../../ui/buttons/remove-button";
+import { RemoveButton } from "#/components/shared/buttons/remove-button";
import { Thumbnail } from "./thumbnail";
interface ImagePreviewProps {
diff --git a/frontend/src/components/features/jupyter/jupyter.tsx b/frontend/src/components/features/jupyter/jupyter.tsx
index fef5084d89ce..8ae871c520d0 100644
--- a/frontend/src/components/features/jupyter/jupyter.tsx
+++ b/frontend/src/components/features/jupyter/jupyter.tsx
@@ -3,7 +3,7 @@ import { useSelector } from "react-redux";
import { RootState } from "#/store";
import { useScrollToBottom } from "#/hooks/use-scroll-to-bottom";
import { JupyterCell } from "./jupyter-cell";
-import { ScrollToBottomButton } from "../../ui/buttons/scroll-to-bottom-button";
+import { ScrollToBottomButton } from "#/components/shared/buttons/scroll-to-bottom-button";
interface JupyterEditorProps {
maxWidth: number;
diff --git a/frontend/src/components/features/project-menu/ProjectMenuCard.tsx b/frontend/src/components/features/project-menu/ProjectMenuCard.tsx
index a83388707a0c..159edb9b5610 100644
--- a/frontend/src/components/features/project-menu/ProjectMenuCard.tsx
+++ b/frontend/src/components/features/project-menu/ProjectMenuCard.tsx
@@ -3,16 +3,16 @@ import { useDispatch } from "react-redux";
import toast from "react-hot-toast";
import posthog from "posthog-js";
import EllipsisH from "#/icons/ellipsis-h.svg?react";
-import { ModalBackdrop } from "../../modals/modal-backdrop";
-import { ConnectToGitHubModal } from "../../modals/connect-to-github-modal";
import { addUserMessage } from "#/state/chat-slice";
import { createChatMessage } from "#/services/chat-service";
import { ProjectMenuCardContextMenu } from "./project.menu-card-context-menu";
import { ProjectMenuDetailsPlaceholder } from "./project-menu-details-placeholder";
import { ProjectMenuDetails } from "./project-menu-details";
import { downloadWorkspace } from "#/utils/download-workspace";
-import { LoadingSpinner } from "../../ui/loading-spinner";
import { useWsClient } from "#/context/ws-client-provider";
+import { LoadingSpinner } from "#/components/shared/loading-spinner";
+import { ConnectToGitHubModal } from "#/components/shared/modals/connect-to-github-modal";
+import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
interface ProjectMenuCardProps {
isConnectedToGitHub: boolean;
diff --git a/frontend/src/components/features/sidebar/sidebar.tsx b/frontend/src/components/features/sidebar/sidebar.tsx
index 959ce4bc7db4..f5345b2af2a9 100644
--- a/frontend/src/components/features/sidebar/sidebar.tsx
+++ b/frontend/src/components/features/sidebar/sidebar.tsx
@@ -4,15 +4,15 @@ import { useAuth } from "#/context/auth-context";
import { useUserPrefs } from "#/context/user-prefs-context";
import { useGitHubUser } from "#/hooks/query/use-github-user";
import { useIsAuthed } from "#/hooks/query/use-is-authed";
-import { AllHandsLogoButton } from "#/components/ui/buttons/all-hands-logo-button";
-import { DocsButton } from "#/components/ui/buttons/docs-button";
-import { SettingsButton } from "#/components/ui/buttons/settings-button";
-import { AccountSettingsModal } from "#/components/modals/account-settings/account-settings-modal";
-import { SettingsModal } from "#/components/modals/settings/settings-modal";
import { UserActions } from "./user-actions";
-import { ExitProjectButton } from "../../ui/buttons/exit-project-button";
-import { ExitProjectConfirmationModal } from "#/components/modals/exit-project-confirmation-modal";
-import { LoadingSpinner } from "#/components/ui/loading-spinner";
+import { AllHandsLogoButton } from "#/components/shared/buttons/all-hands-logo-button";
+import { DocsButton } from "#/components/shared/buttons/docs-button";
+import { ExitProjectButton } from "#/components/shared/buttons/exit-project-button";
+import { SettingsButton } from "#/components/shared/buttons/settings-button";
+import { LoadingSpinner } from "#/components/shared/loading-spinner";
+import { AccountSettingsModal } from "#/components/shared/modals/account-settings/account-settings-modal";
+import { ExitProjectConfirmationModal } from "#/components/shared/modals/exit-project-confirmation-modal";
+import { SettingsModal } from "#/components/shared/modals/settings/settings-modal";
export function Sidebar() {
const location = useLocation();
diff --git a/frontend/src/components/features/sidebar/user-avatar.tsx b/frontend/src/components/features/sidebar/user-avatar.tsx
index 5c589860158e..58a4af17386a 100644
--- a/frontend/src/components/features/sidebar/user-avatar.tsx
+++ b/frontend/src/components/features/sidebar/user-avatar.tsx
@@ -1,7 +1,7 @@
+import { LoadingSpinner } from "#/components/shared/loading-spinner";
import DefaultUserAvatar from "#/icons/default-user.svg?react";
import { cn } from "#/utils/utils";
import { Avatar } from "./avatar";
-import { LoadingSpinner } from "../../ui/loading-spinner";
interface UserAvatarProps {
onClick: () => void;
diff --git a/frontend/src/components/features/suggestions/suggestion-bubble.tsx b/frontend/src/components/features/suggestions/suggestion-bubble.tsx
index 611a207ebd8c..5679799c6ed1 100644
--- a/frontend/src/components/features/suggestions/suggestion-bubble.tsx
+++ b/frontend/src/components/features/suggestions/suggestion-bubble.tsx
@@ -1,5 +1,5 @@
+import { RefreshButton } from "#/components/shared/buttons/refresh-button";
import Lightbulb from "#/icons/lightbulb.svg?react";
-import { RefreshButton } from "../../ui/buttons/refresh-button";
interface SuggestionBubbleProps {
suggestion: string;
diff --git a/frontend/src/components/features/waitlist/waitlist-modal.tsx b/frontend/src/components/features/waitlist/waitlist-modal.tsx
index 546697ed6daf..c8ee583fbef0 100644
--- a/frontend/src/components/features/waitlist/waitlist-modal.tsx
+++ b/frontend/src/components/features/waitlist/waitlist-modal.tsx
@@ -1,10 +1,10 @@
+import { ModalBody } from "@nextui-org/react";
import GitHubLogo from "#/assets/branding/github-logo.svg?react";
import AllHandsLogo from "#/assets/branding/all-hands-logo.svg?react";
import { JoinWaitlistAnchor } from "./join-waitlist-anchor";
import { WaitlistMessage } from "./waitlist-message";
-import { ModalBody } from "#/components/modals/modal-body";
-import { ModalBackdrop } from "#/components/modals/modal-backdrop";
-import { ModalButton } from "#/components/ui/buttons/modal-button";
+import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
+import { ModalButton } from "#/components/shared/buttons/modal-button";
interface WaitlistModalProps {
ghToken: string | null;
diff --git a/frontend/src/components/ui/action-tooltip.tsx b/frontend/src/components/shared/action-tooltip.tsx
similarity index 100%
rename from frontend/src/components/ui/action-tooltip.tsx
rename to frontend/src/components/shared/action-tooltip.tsx
diff --git a/frontend/src/components/ui/buttons/action-button.tsx b/frontend/src/components/shared/buttons/action-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/action-button.tsx
rename to frontend/src/components/shared/buttons/action-button.tsx
diff --git a/frontend/src/components/ui/buttons/all-hands-logo-button.tsx b/frontend/src/components/shared/buttons/all-hands-logo-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/all-hands-logo-button.tsx
rename to frontend/src/components/shared/buttons/all-hands-logo-button.tsx
diff --git a/frontend/src/components/ui/buttons/confirmation-buttons.tsx b/frontend/src/components/shared/buttons/confirmation-buttons.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/confirmation-buttons.tsx
rename to frontend/src/components/shared/buttons/confirmation-buttons.tsx
diff --git a/frontend/src/components/ui/buttons/continue-button.tsx b/frontend/src/components/shared/buttons/continue-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/continue-button.tsx
rename to frontend/src/components/shared/buttons/continue-button.tsx
diff --git a/frontend/src/components/ui/buttons/copy-to-clipboard-button.tsx b/frontend/src/components/shared/buttons/copy-to-clipboard-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/copy-to-clipboard-button.tsx
rename to frontend/src/components/shared/buttons/copy-to-clipboard-button.tsx
diff --git a/frontend/src/components/ui/buttons/docs-button.tsx b/frontend/src/components/shared/buttons/docs-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/docs-button.tsx
rename to frontend/src/components/shared/buttons/docs-button.tsx
diff --git a/frontend/src/components/ui/buttons/editor-action-button.tsx b/frontend/src/components/shared/buttons/editor-action-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/editor-action-button.tsx
rename to frontend/src/components/shared/buttons/editor-action-button.tsx
diff --git a/frontend/src/components/ui/buttons/exit-project-button.tsx b/frontend/src/components/shared/buttons/exit-project-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/exit-project-button.tsx
rename to frontend/src/components/shared/buttons/exit-project-button.tsx
diff --git a/frontend/src/components/ui/buttons/feedback-action-button.tsx b/frontend/src/components/shared/buttons/feedback-action-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/feedback-action-button.tsx
rename to frontend/src/components/shared/buttons/feedback-action-button.tsx
diff --git a/frontend/src/components/ui/buttons/icon-button.tsx b/frontend/src/components/shared/buttons/icon-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/icon-button.tsx
rename to frontend/src/components/shared/buttons/icon-button.tsx
diff --git a/frontend/src/components/ui/buttons/modal-button.tsx b/frontend/src/components/shared/buttons/modal-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/modal-button.tsx
rename to frontend/src/components/shared/buttons/modal-button.tsx
diff --git a/frontend/src/components/ui/buttons/open-vscode-button.tsx b/frontend/src/components/shared/buttons/open-vscode-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/open-vscode-button.tsx
rename to frontend/src/components/shared/buttons/open-vscode-button.tsx
diff --git a/frontend/src/components/ui/buttons/refresh-button.tsx b/frontend/src/components/shared/buttons/refresh-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/refresh-button.tsx
rename to frontend/src/components/shared/buttons/refresh-button.tsx
diff --git a/frontend/src/components/ui/buttons/refresh-icon-button.tsx b/frontend/src/components/shared/buttons/refresh-icon-button.tsx
similarity index 87%
rename from frontend/src/components/ui/buttons/refresh-icon-button.tsx
rename to frontend/src/components/shared/buttons/refresh-icon-button.tsx
index c66d344e9fdc..3d0080ba0c60 100644
--- a/frontend/src/components/ui/buttons/refresh-icon-button.tsx
+++ b/frontend/src/components/shared/buttons/refresh-icon-button.tsx
@@ -1,5 +1,5 @@
import { IoIosRefresh } from "react-icons/io";
-import { IconButton } from "#/components/ui/buttons/icon-button";
+import { IconButton } from "./icon-button";
interface RefreshIconButtonProps {
onClick: () => void;
diff --git a/frontend/src/components/ui/buttons/remove-button.tsx b/frontend/src/components/shared/buttons/remove-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/remove-button.tsx
rename to frontend/src/components/shared/buttons/remove-button.tsx
diff --git a/frontend/src/components/ui/buttons/scroll-to-bottom-button.tsx b/frontend/src/components/shared/buttons/scroll-to-bottom-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/scroll-to-bottom-button.tsx
rename to frontend/src/components/shared/buttons/scroll-to-bottom-button.tsx
diff --git a/frontend/src/components/ui/buttons/settings-button.tsx b/frontend/src/components/shared/buttons/settings-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/settings-button.tsx
rename to frontend/src/components/shared/buttons/settings-button.tsx
diff --git a/frontend/src/components/ui/buttons/stop-button.tsx b/frontend/src/components/shared/buttons/stop-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/stop-button.tsx
rename to frontend/src/components/shared/buttons/stop-button.tsx
diff --git a/frontend/src/components/ui/buttons/submit-button.tsx b/frontend/src/components/shared/buttons/submit-button.tsx
similarity index 100%
rename from frontend/src/components/ui/buttons/submit-button.tsx
rename to frontend/src/components/shared/buttons/submit-button.tsx
diff --git a/frontend/src/components/ui/buttons/toggle-workspace-icon-button.tsx b/frontend/src/components/shared/buttons/toggle-workspace-icon-button.tsx
similarity index 91%
rename from frontend/src/components/ui/buttons/toggle-workspace-icon-button.tsx
rename to frontend/src/components/shared/buttons/toggle-workspace-icon-button.tsx
index 038ecb3d3675..5eedd1ae8f1b 100644
--- a/frontend/src/components/ui/buttons/toggle-workspace-icon-button.tsx
+++ b/frontend/src/components/shared/buttons/toggle-workspace-icon-button.tsx
@@ -1,5 +1,5 @@
import { IoIosArrowForward, IoIosArrowBack } from "react-icons/io";
-import { IconButton } from "#/components/ui/buttons/icon-button";
+import { IconButton } from "./icon-button";
interface ToggleWorkspaceIconButtonProps {
onClick: () => void;
diff --git a/frontend/src/components/ui/buttons/upload-icon-button.tsx b/frontend/src/components/shared/buttons/upload-icon-button.tsx
similarity index 87%
rename from frontend/src/components/ui/buttons/upload-icon-button.tsx
rename to frontend/src/components/shared/buttons/upload-icon-button.tsx
index 923e7be1b124..0e8bdeab29d1 100644
--- a/frontend/src/components/ui/buttons/upload-icon-button.tsx
+++ b/frontend/src/components/shared/buttons/upload-icon-button.tsx
@@ -1,5 +1,5 @@
import { IoIosCloudUpload } from "react-icons/io";
-import { IconButton } from "#/components/ui/buttons/icon-button";
+import { IconButton } from "./icon-button";
interface UploadIconButtonProps {
onClick: () => void;
diff --git a/frontend/src/components/ui/custom-input.tsx b/frontend/src/components/shared/custom-input.tsx
similarity index 100%
rename from frontend/src/components/ui/custom-input.tsx
rename to frontend/src/components/shared/custom-input.tsx
diff --git a/frontend/src/components/ui/error-toast.tsx b/frontend/src/components/shared/error-toast.tsx
similarity index 100%
rename from frontend/src/components/ui/error-toast.tsx
rename to frontend/src/components/shared/error-toast.tsx
diff --git a/frontend/src/components/ui/form-fieldset.tsx b/frontend/src/components/shared/form-fieldset.tsx
similarity index 100%
rename from frontend/src/components/ui/form-fieldset.tsx
rename to frontend/src/components/shared/form-fieldset.tsx
diff --git a/frontend/src/components/ui/hero-heading.tsx b/frontend/src/components/shared/hero-heading.tsx
similarity index 100%
rename from frontend/src/components/ui/hero-heading.tsx
rename to frontend/src/components/shared/hero-heading.tsx
diff --git a/frontend/src/components/ui/inputs/advanced-option-switch.tsx b/frontend/src/components/shared/inputs/advanced-option-switch.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/advanced-option-switch.tsx
rename to frontend/src/components/shared/inputs/advanced-option-switch.tsx
diff --git a/frontend/src/components/ui/inputs/agent-input.tsx b/frontend/src/components/shared/inputs/agent-input.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/agent-input.tsx
rename to frontend/src/components/shared/inputs/agent-input.tsx
diff --git a/frontend/src/components/ui/inputs/api-key-input.tsx b/frontend/src/components/shared/inputs/api-key-input.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/api-key-input.tsx
rename to frontend/src/components/shared/inputs/api-key-input.tsx
diff --git a/frontend/src/components/ui/inputs/base-url-input.tsx b/frontend/src/components/shared/inputs/base-url-input.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/base-url-input.tsx
rename to frontend/src/components/shared/inputs/base-url-input.tsx
diff --git a/frontend/src/components/ui/inputs/confirmation-mode-switch.tsx b/frontend/src/components/shared/inputs/confirmation-mode-switch.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/confirmation-mode-switch.tsx
rename to frontend/src/components/shared/inputs/confirmation-mode-switch.tsx
diff --git a/frontend/src/components/ui/inputs/custom-model-input.tsx b/frontend/src/components/shared/inputs/custom-model-input.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/custom-model-input.tsx
rename to frontend/src/components/shared/inputs/custom-model-input.tsx
diff --git a/frontend/src/components/ui/inputs/security-analyzers-input.tsx b/frontend/src/components/shared/inputs/security-analyzers-input.tsx
similarity index 100%
rename from frontend/src/components/ui/inputs/security-analyzers-input.tsx
rename to frontend/src/components/shared/inputs/security-analyzers-input.tsx
diff --git a/frontend/src/components/ui/loading-spinner.tsx b/frontend/src/components/shared/loading-spinner.tsx
similarity index 100%
rename from frontend/src/components/ui/loading-spinner.tsx
rename to frontend/src/components/shared/loading-spinner.tsx
diff --git a/frontend/src/components/modals/account-settings/account-settings-form.tsx b/frontend/src/components/shared/modals/account-settings/account-settings-form.tsx
similarity index 96%
rename from frontend/src/components/modals/account-settings/account-settings-form.tsx
rename to frontend/src/components/shared/modals/account-settings/account-settings-form.tsx
index 92286516df64..3da9b97e2c8d 100644
--- a/frontend/src/components/modals/account-settings/account-settings-form.tsx
+++ b/frontend/src/components/shared/modals/account-settings/account-settings-form.tsx
@@ -5,14 +5,14 @@ import {
BaseModalTitle,
} from "../confirmation-modals/base-modal";
import { ModalBody } from "../modal-body";
-import { ModalButton } from "../../ui/buttons/modal-button";
-import { FormFieldset } from "../../ui/form-fieldset";
-import { CustomInput } from "../../ui/custom-input";
import { AvailableLanguages } from "#/i18n";
import { I18nKey } from "#/i18n/declaration";
import { useAuth } from "#/context/auth-context";
import { useUserPrefs } from "#/context/user-prefs-context";
import { handleCaptureConsent } from "#/utils/handle-capture-consent";
+import { ModalButton } from "../../buttons/modal-button";
+import { CustomInput } from "../../custom-input";
+import { FormFieldset } from "../../form-fieldset";
interface AccountSettingsFormProps {
onClose: () => void;
diff --git a/frontend/src/components/modals/account-settings/account-settings-modal.tsx b/frontend/src/components/shared/modals/account-settings/account-settings-modal.tsx
similarity index 81%
rename from frontend/src/components/modals/account-settings/account-settings-modal.tsx
rename to frontend/src/components/shared/modals/account-settings/account-settings-modal.tsx
index b9ab8c313217..f6bcdb48abfe 100644
--- a/frontend/src/components/modals/account-settings/account-settings-modal.tsx
+++ b/frontend/src/components/shared/modals/account-settings/account-settings-modal.tsx
@@ -1,7 +1,7 @@
-import { AccountSettingsForm } from "#/components/modals/account-settings/account-settings-form";
-import { ModalBackdrop } from "#/components/modals/modal-backdrop";
import { useUserPrefs } from "#/context/user-prefs-context";
import { useGitHubUser } from "#/hooks/query/use-github-user";
+import { ModalBackdrop } from "../modal-backdrop";
+import { AccountSettingsForm } from "./account-settings-form";
interface AccountSettingsModalProps {
onClose: () => void;
diff --git a/frontend/src/components/modals/base-modal/base-modal.tsx b/frontend/src/components/shared/modals/base-modal/base-modal.tsx
similarity index 100%
rename from frontend/src/components/modals/base-modal/base-modal.tsx
rename to frontend/src/components/shared/modals/base-modal/base-modal.tsx
diff --git a/frontend/src/components/modals/base-modal/footer-content.tsx b/frontend/src/components/shared/modals/base-modal/footer-content.tsx
similarity index 100%
rename from frontend/src/components/modals/base-modal/footer-content.tsx
rename to frontend/src/components/shared/modals/base-modal/footer-content.tsx
diff --git a/frontend/src/components/modals/base-modal/header-content.tsx b/frontend/src/components/shared/modals/base-modal/header-content.tsx
similarity index 100%
rename from frontend/src/components/modals/base-modal/header-content.tsx
rename to frontend/src/components/shared/modals/base-modal/header-content.tsx
diff --git a/frontend/src/components/modals/confirmation-modals/base-modal.tsx b/frontend/src/components/shared/modals/confirmation-modals/base-modal.tsx
similarity index 95%
rename from frontend/src/components/modals/confirmation-modals/base-modal.tsx
rename to frontend/src/components/shared/modals/confirmation-modals/base-modal.tsx
index cdd20965240e..2cb79b45c8c0 100644
--- a/frontend/src/components/modals/confirmation-modals/base-modal.tsx
+++ b/frontend/src/components/shared/modals/confirmation-modals/base-modal.tsx
@@ -1,6 +1,6 @@
import React from "react";
-import { ModalButton } from "#/components/ui/buttons/modal-button";
import { ModalBody } from "../modal-body";
+import { ModalButton } from "../../buttons/modal-button";
interface ButtonConfig {
text: string;
diff --git a/frontend/src/components/modals/confirmation-modals/danger-modal.tsx b/frontend/src/components/shared/modals/confirmation-modals/danger-modal.tsx
similarity index 100%
rename from frontend/src/components/modals/confirmation-modals/danger-modal.tsx
rename to frontend/src/components/shared/modals/confirmation-modals/danger-modal.tsx
diff --git a/frontend/src/components/modals/connect-to-github-modal.tsx b/frontend/src/components/shared/modals/connect-to-github-modal.tsx
similarity index 95%
rename from frontend/src/components/modals/connect-to-github-modal.tsx
rename to frontend/src/components/shared/modals/connect-to-github-modal.tsx
index d5fb63817b69..130ca4e19929 100644
--- a/frontend/src/components/modals/connect-to-github-modal.tsx
+++ b/frontend/src/components/shared/modals/connect-to-github-modal.tsx
@@ -1,13 +1,13 @@
import { useTranslation } from "react-i18next";
import { ModalBody } from "./modal-body";
-import { CustomInput } from "../ui/custom-input";
-import { ModalButton } from "../ui/buttons/modal-button";
import {
BaseModalDescription,
BaseModalTitle,
} from "./confirmation-modals/base-modal";
import { I18nKey } from "#/i18n/declaration";
import { useAuth } from "#/context/auth-context";
+import { ModalButton } from "../buttons/modal-button";
+import { CustomInput } from "../custom-input";
interface ConnectToGitHubModalProps {
onClose: () => void;
diff --git a/frontend/src/components/modals/exit-project-confirmation-modal.tsx b/frontend/src/components/shared/modals/exit-project-confirmation-modal.tsx
similarity index 87%
rename from frontend/src/components/modals/exit-project-confirmation-modal.tsx
rename to frontend/src/components/shared/modals/exit-project-confirmation-modal.tsx
index 5d425fd4a6a1..c29477f3e098 100644
--- a/frontend/src/components/modals/exit-project-confirmation-modal.tsx
+++ b/frontend/src/components/shared/modals/exit-project-confirmation-modal.tsx
@@ -1,9 +1,9 @@
import { useDispatch } from "react-redux";
-import { DangerModal } from "#/components/modals/confirmation-modals/danger-modal";
-import { ModalBackdrop } from "#/components/modals/modal-backdrop";
import { useEndSession } from "#/hooks/use-end-session";
import { setCurrentAgentState } from "#/state/agent-slice";
import AgentState from "#/types/agent-state";
+import { DangerModal } from "./confirmation-modals/danger-modal";
+import { ModalBackdrop } from "./modal-backdrop";
interface ExitProjectConfirmationModalProps {
onClose: () => void;
diff --git a/frontend/src/components/modals/modal-backdrop.tsx b/frontend/src/components/shared/modals/modal-backdrop.tsx
similarity index 100%
rename from frontend/src/components/modals/modal-backdrop.tsx
rename to frontend/src/components/shared/modals/modal-backdrop.tsx
diff --git a/frontend/src/components/modals/modal-body.tsx b/frontend/src/components/shared/modals/modal-body.tsx
similarity index 100%
rename from frontend/src/components/modals/modal-body.tsx
rename to frontend/src/components/shared/modals/modal-body.tsx
diff --git a/frontend/src/components/modals/security/invariant/assets/logo.tsx b/frontend/src/components/shared/modals/security/invariant/assets/logo.tsx
similarity index 100%
rename from frontend/src/components/modals/security/invariant/assets/logo.tsx
rename to frontend/src/components/shared/modals/security/invariant/assets/logo.tsx
diff --git a/frontend/src/components/modals/security/invariant/invariant.tsx b/frontend/src/components/shared/modals/security/invariant/invariant.tsx
similarity index 100%
rename from frontend/src/components/modals/security/invariant/invariant.tsx
rename to frontend/src/components/shared/modals/security/invariant/invariant.tsx
diff --git a/frontend/src/components/modals/security/security.tsx b/frontend/src/components/shared/modals/security/security.tsx
similarity index 100%
rename from frontend/src/components/modals/security/security.tsx
rename to frontend/src/components/shared/modals/security/security.tsx
diff --git a/frontend/src/components/modals/settings/model-selector.tsx b/frontend/src/components/shared/modals/settings/model-selector.tsx
similarity index 100%
rename from frontend/src/components/modals/settings/model-selector.tsx
rename to frontend/src/components/shared/modals/settings/model-selector.tsx
diff --git a/frontend/src/components/modals/settings/settings-form.tsx b/frontend/src/components/shared/modals/settings/settings-form.tsx
similarity index 92%
rename from frontend/src/components/modals/settings/settings-form.tsx
rename to frontend/src/components/shared/modals/settings/settings-form.tsx
index d5c5d97efcb5..4b50a85e783b 100644
--- a/frontend/src/components/modals/settings/settings-form.tsx
+++ b/frontend/src/components/shared/modals/settings/settings-form.tsx
@@ -3,11 +3,8 @@ import { useTranslation } from "react-i18next";
import React from "react";
import posthog from "posthog-js";
import { organizeModelsAndProviders } from "#/utils/organize-models-and-providers";
-import { ModelSelector } from "#/components/modals/settings/model-selector";
import { getDefaultSettings, Settings } from "#/services/settings";
-import { ModalBackdrop } from "#/components/modals/modal-backdrop";
import { extractModelAndProvider } from "#/utils/extract-model-and-provider";
-import { ModalButton } from "../../ui/buttons/modal-button";
import { DangerModal } from "../confirmation-modals/danger-modal";
import { I18nKey } from "#/i18n/declaration";
import {
@@ -17,13 +14,16 @@ import {
} from "#/utils/settings-utils";
import { useEndSession } from "#/hooks/use-end-session";
import { useUserPrefs } from "#/context/user-prefs-context";
-import { AdvancedOptionSwitch } from "../../ui/inputs/advanced-option-switch";
-import { CustomModelInput } from "../../ui/inputs/custom-model-input";
-import { BaseUrlInput } from "../../ui/inputs/base-url-input";
-import { AgentInput } from "../../ui/inputs/agent-input";
-import { APIKeyInput } from "../../ui/inputs/api-key-input";
-import { SecurityAnalyzerInput } from "../../ui/inputs/security-analyzers-input";
-import { ConfirmationModeSwitch } from "../../ui/inputs/confirmation-mode-switch";
+import { ModalButton } from "../../buttons/modal-button";
+import { AdvancedOptionSwitch } from "../../inputs/advanced-option-switch";
+import { AgentInput } from "../../inputs/agent-input";
+import { APIKeyInput } from "../../inputs/api-key-input";
+import { BaseUrlInput } from "../../inputs/base-url-input";
+import { ConfirmationModeSwitch } from "../../inputs/confirmation-mode-switch";
+import { CustomModelInput } from "../../inputs/custom-model-input";
+import { SecurityAnalyzerInput } from "../../inputs/security-analyzers-input";
+import { ModalBackdrop } from "../modal-backdrop";
+import { ModelSelector } from "./model-selector";
interface SettingsFormProps {
disabled?: boolean;
diff --git a/frontend/src/components/modals/settings/settings-modal.tsx b/frontend/src/components/shared/modals/settings/settings-modal.tsx
similarity index 88%
rename from frontend/src/components/modals/settings/settings-modal.tsx
rename to frontend/src/components/shared/modals/settings/settings-modal.tsx
index d3702d94c59c..4cd0dd45a719 100644
--- a/frontend/src/components/modals/settings/settings-modal.tsx
+++ b/frontend/src/components/shared/modals/settings/settings-modal.tsx
@@ -1,8 +1,8 @@
-import { SettingsForm } from "#/components/modals/settings/settings-form";
-import { ModalBackdrop } from "#/components/modals/modal-backdrop";
import { useUserPrefs } from "#/context/user-prefs-context";
import { useAIConfigOptions } from "#/hooks/query/use-ai-config-options";
-import { LoadingSpinner } from "#/components/ui/loading-spinner";
+import { LoadingSpinner } from "../../loading-spinner";
+import { ModalBackdrop } from "../modal-backdrop";
+import { SettingsForm } from "./settings-form";
interface SettingsModalProps {
onClose: () => void;
diff --git a/frontend/src/components/ui/task-form.tsx b/frontend/src/components/shared/task-form.tsx
similarity index 100%
rename from frontend/src/components/ui/task-form.tsx
rename to frontend/src/components/shared/task-form.tsx
diff --git a/frontend/src/routes/_oh._index/route.tsx b/frontend/src/routes/_oh._index/route.tsx
index 1687ab7f092b..1c4cb3efba0f 100644
--- a/frontend/src/routes/_oh._index/route.tsx
+++ b/frontend/src/routes/_oh._index/route.tsx
@@ -1,8 +1,6 @@
import { useLocation, useNavigate } from "@remix-run/react";
import React from "react";
import { useDispatch } from "react-redux";
-import { TaskForm } from "../../components/ui/task-form";
-import { HeroHeading } from "../../components/ui/hero-heading";
import { setImportedProjectZip } from "#/state/initial-query-slice";
import { convertZipToBase64 } from "#/utils/convert-zip-to-base64";
import { useUserRepositories } from "#/hooks/query/use-user-repositories";
@@ -12,6 +10,8 @@ import { useConfig } from "#/hooks/query/use-config";
import { useAuth } from "#/context/auth-context";
import { ImportProjectSuggestionBox } from "../../components/features/suggestions/import-project-suggestion-box";
import { GitHubRepositoriesSuggestionBox } from "#/components/features/github/github-repositories-suggestion-box";
+import { HeroHeading } from "#/components/shared/hero-heading";
+import { TaskForm } from "#/components/shared/task-form";
function Home() {
const { token, gitHubToken } = useAuth();
diff --git a/frontend/src/routes/_oh.app/route.tsx b/frontend/src/routes/_oh.app/route.tsx
index 6f307a563011..5d257b169495 100644
--- a/frontend/src/routes/_oh.app/route.tsx
+++ b/frontend/src/routes/_oh.app/route.tsx
@@ -2,7 +2,6 @@ import { useDisclosure } from "@nextui-org/react";
import React from "react";
import { Outlet } from "@remix-run/react";
import { useDispatch, useSelector } from "react-redux";
-import Security from "#/components/modals/security/security";
import { Controls } from "#/components/features/controls/controls";
import { RootState } from "#/store";
import { clearMessages } from "#/state/chat-slice";
@@ -21,6 +20,7 @@ import { useAuth } from "#/context/auth-context";
import { useUserPrefs } from "#/context/user-prefs-context";
import { useConversationConfig } from "#/hooks/query/use-conversation-config";
import { Container } from "#/components/layout/container";
+import Security from "#/components/shared/modals/security/security";
function App() {
const { token, gitHubToken } = useAuth();
diff --git a/frontend/src/utils/display-error-toast.tsx b/frontend/src/utils/display-error-toast.tsx
index 67485eb982c9..d481ccd932fd 100644
--- a/frontend/src/utils/display-error-toast.tsx
+++ b/frontend/src/utils/display-error-toast.tsx
@@ -1,5 +1,5 @@
import toast from "react-hot-toast";
-import { ErrorToast } from "#/components/ui/error-toast";
+import { ErrorToast } from "#/components/shared/error-toast";
export const displayErrorToast = (error: string) =>
toast((t) =>
, {