mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-02-28 21:25:44 +00:00
Compare commits
10 Commits
embed_imag
...
jamison/hi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e311cac41d | ||
|
|
660b603324 | ||
|
|
78c6ca39b8 | ||
|
|
71a7cf09b3 | ||
|
|
91d30a0156 | ||
|
|
7b30752767 | ||
|
|
4450ecf07c | ||
|
|
0e6b766996 | ||
|
|
12c8cd338b | ||
|
|
ad5688bf65 |
2
.github/workflows/pr-playwright-tests.yml
vendored
2
.github/workflows/pr-playwright-tests.yml
vendored
@@ -603,7 +603,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Download visual diff summaries
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # ratchet:actions/download-artifact@v4
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
|
||||
with:
|
||||
pattern: screenshot-diff-summary-*
|
||||
path: summaries/
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
"""add python tool on default
|
||||
|
||||
Revision ID: 57122d037335
|
||||
Revises: c0c937d5c9e5
|
||||
Create Date: 2026-02-27 10:10:40.124925
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "57122d037335"
|
||||
down_revision = "c0c937d5c9e5"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
PYTHON_TOOL_NAME = "python"
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
|
||||
# Look up the PythonTool id
|
||||
result = conn.execute(
|
||||
sa.text("SELECT id FROM tool WHERE name = :name"),
|
||||
{"name": PYTHON_TOOL_NAME},
|
||||
).fetchone()
|
||||
|
||||
if not result:
|
||||
return
|
||||
|
||||
tool_id = result[0]
|
||||
|
||||
# Attach to the default persona (id=0) if not already attached
|
||||
conn.execute(
|
||||
sa.text(
|
||||
"""
|
||||
INSERT INTO persona__tool (persona_id, tool_id)
|
||||
VALUES (0, :tool_id)
|
||||
ON CONFLICT DO NOTHING
|
||||
"""
|
||||
),
|
||||
{"tool_id": tool_id},
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
|
||||
result = conn.execute(
|
||||
sa.text("SELECT id FROM tool WHERE name = :name"),
|
||||
{"name": PYTHON_TOOL_NAME},
|
||||
).fetchone()
|
||||
|
||||
if not result:
|
||||
return
|
||||
|
||||
conn.execute(
|
||||
sa.text(
|
||||
"""
|
||||
DELETE FROM persona__tool
|
||||
WHERE persona_id = 0 AND tool_id = :tool_id
|
||||
"""
|
||||
),
|
||||
{"tool_id": result[0]},
|
||||
)
|
||||
@@ -32,6 +32,8 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
BASE_URL = "https://api.gong.io"
|
||||
MAX_CALL_DETAILS_ATTEMPTS = 6
|
||||
CALL_DETAILS_DELAY = 30 # in seconds
|
||||
# Gong API limit is 3 calls/sec — stay safely under it
|
||||
MIN_REQUEST_INTERVAL = 0.5 # seconds between requests
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -45,9 +47,13 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
self.continue_on_fail = continue_on_fail
|
||||
self.auth_token_basic: str | None = None
|
||||
self.hide_user_info = hide_user_info
|
||||
self._last_request_time: float = 0.0
|
||||
|
||||
# urllib3 Retry already respects the Retry-After header by default
|
||||
# (respect_retry_after_header=True), so on 429 it will sleep for the
|
||||
# duration Gong specifies before retrying.
|
||||
retry_strategy = Retry(
|
||||
total=5,
|
||||
total=10,
|
||||
backoff_factor=2,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
)
|
||||
@@ -61,8 +67,24 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
url = f"{GongConnector.BASE_URL}{endpoint}"
|
||||
return url
|
||||
|
||||
def _throttled_request(
|
||||
self, method: str, url: str, **kwargs: Any
|
||||
) -> requests.Response:
|
||||
"""Rate-limited request wrapper. Enforces MIN_REQUEST_INTERVAL between
|
||||
calls to stay under Gong's 3 calls/sec limit and avoid triggering 429s."""
|
||||
now = time.monotonic()
|
||||
elapsed = now - self._last_request_time
|
||||
if elapsed < self.MIN_REQUEST_INTERVAL:
|
||||
time.sleep(self.MIN_REQUEST_INTERVAL - elapsed)
|
||||
|
||||
response = self._session.request(method, url, **kwargs)
|
||||
self._last_request_time = time.monotonic()
|
||||
return response
|
||||
|
||||
def _get_workspace_id_map(self) -> dict[str, str]:
|
||||
response = self._session.get(GongConnector.make_url("/v2/workspaces"))
|
||||
response = self._throttled_request(
|
||||
"GET", GongConnector.make_url("/v2/workspaces")
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
workspaces_details = response.json().get("workspaces")
|
||||
@@ -106,8 +128,8 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
del body["filter"]["workspaceId"]
|
||||
|
||||
while True:
|
||||
response = self._session.post(
|
||||
GongConnector.make_url("/v2/calls/transcript"), json=body
|
||||
response = self._throttled_request(
|
||||
"POST", GongConnector.make_url("/v2/calls/transcript"), json=body
|
||||
)
|
||||
# If no calls in the range, just break out
|
||||
if response.status_code == 404:
|
||||
@@ -142,8 +164,8 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
"contentSelector": {"exposedFields": {"parties": True}},
|
||||
}
|
||||
|
||||
response = self._session.post(
|
||||
GongConnector.make_url("/v2/calls/extensive"), json=body
|
||||
response = self._throttled_request(
|
||||
"POST", GongConnector.make_url("/v2/calls/extensive"), json=body
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
@@ -194,7 +216,8 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
# There's a likely race condition in the API where a transcript will have a
|
||||
# call id but the call to v2/calls/extensive will not return all of the id's
|
||||
# retry with exponential backoff has been observed to mitigate this
|
||||
# in ~2 minutes
|
||||
# in ~2 minutes. After max attempts, proceed with whatever we have —
|
||||
# the per-call loop below will skip missing IDs gracefully.
|
||||
current_attempt = 0
|
||||
while True:
|
||||
current_attempt += 1
|
||||
@@ -213,11 +236,14 @@ class GongConnector(LoadConnector, PollConnector):
|
||||
f"missing_call_ids={missing_call_ids}"
|
||||
)
|
||||
if current_attempt >= self.MAX_CALL_DETAILS_ATTEMPTS:
|
||||
raise RuntimeError(
|
||||
f"Attempt count exceeded for _get_call_details_by_ids: "
|
||||
f"missing_call_ids={missing_call_ids} "
|
||||
f"max_attempts={self.MAX_CALL_DETAILS_ATTEMPTS}"
|
||||
logger.error(
|
||||
f"Giving up on missing call id's after "
|
||||
f"{self.MAX_CALL_DETAILS_ATTEMPTS} attempts: "
|
||||
f"missing_call_ids={missing_call_ids} — "
|
||||
f"proceeding with {len(call_details_map)} of "
|
||||
f"{len(transcript_call_ids)} calls"
|
||||
)
|
||||
break
|
||||
|
||||
wait_seconds = self.CALL_DETAILS_DELAY * pow(2, current_attempt - 1)
|
||||
logger.warning(
|
||||
|
||||
@@ -1217,7 +1217,7 @@ websockets==15.0.1
|
||||
# via
|
||||
# fastmcp
|
||||
# google-genai
|
||||
werkzeug==3.1.5
|
||||
werkzeug==3.1.6
|
||||
# via sendgrid
|
||||
wrapt==1.17.3
|
||||
# via
|
||||
|
||||
@@ -72,6 +72,9 @@ def test_cold_startup_default_assistant() -> None:
|
||||
assert (
|
||||
"read_file" in tool_names
|
||||
), "Default assistant should have FileReaderTool attached"
|
||||
assert (
|
||||
"python" in tool_names
|
||||
), "Default assistant should have PythonTool attached"
|
||||
|
||||
# Also verify by display names for clarity
|
||||
assert (
|
||||
@@ -86,8 +89,11 @@ def test_cold_startup_default_assistant() -> None:
|
||||
assert (
|
||||
"File Reader" in tool_display_names
|
||||
), "Default assistant should have File Reader tool"
|
||||
|
||||
# Should have exactly 5 tools
|
||||
assert (
|
||||
len(tool_associations) == 5
|
||||
), f"Default assistant should have exactly 5 tools attached, got {len(tool_associations)}"
|
||||
"Code Interpreter" in tool_display_names
|
||||
), "Default assistant should have Code Interpreter tool"
|
||||
|
||||
# Should have exactly 6 tools
|
||||
assert (
|
||||
len(tool_associations) == 6
|
||||
), f"Default assistant should have exactly 6 tools attached, got {len(tool_associations)}"
|
||||
|
||||
@@ -468,7 +468,7 @@ services:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
@@ -293,7 +293,7 @@ services:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
@@ -298,7 +298,7 @@ services:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
@@ -335,7 +335,7 @@ services:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
@@ -232,7 +232,7 @@ services:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
@@ -520,7 +520,7 @@ services:
|
||||
- minio_data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
@@ -40,6 +40,8 @@ const TRAY_MENU_OPEN_APP_ID: &str = "tray_open_app";
|
||||
const TRAY_MENU_OPEN_CHAT_ID: &str = "tray_open_chat";
|
||||
const TRAY_MENU_SHOW_IN_BAR_ID: &str = "tray_show_in_menu_bar";
|
||||
const TRAY_MENU_QUIT_ID: &str = "tray_quit";
|
||||
const MENU_SHOW_MENU_BAR_ID: &str = "show_menu_bar";
|
||||
const MENU_HIDE_DECORATIONS_ID: &str = "hide_window_decorations";
|
||||
const CHAT_LINK_INTERCEPT_SCRIPT: &str = r##"
|
||||
(() => {
|
||||
if (window.__ONYX_CHAT_LINK_INTERCEPT_INSTALLED__) {
|
||||
@@ -171,25 +173,75 @@ const CHAT_LINK_INTERCEPT_SCRIPT: &str = r##"
|
||||
})();
|
||||
"##;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const MENU_KEY_HANDLER_SCRIPT: &str = r#"
|
||||
(() => {
|
||||
if (window.__ONYX_MENU_KEY_HANDLER__) return;
|
||||
window.__ONYX_MENU_KEY_HANDLER__ = true;
|
||||
|
||||
let altHeld = false;
|
||||
|
||||
function invoke(cmd) {
|
||||
const fn_ =
|
||||
window.__TAURI__?.core?.invoke || window.__TAURI_INTERNALS__?.invoke;
|
||||
if (typeof fn_ === 'function') fn_(cmd);
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Alt') {
|
||||
if (!altHeld) {
|
||||
altHeld = true;
|
||||
invoke('show_menu_bar_temporarily');
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (e.altKey && e.key === 'F1') {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
altHeld = false;
|
||||
invoke('toggle_menu_bar');
|
||||
return;
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.addEventListener('keyup', (e) => {
|
||||
if (e.key === 'Alt' && altHeld) {
|
||||
altHeld = false;
|
||||
invoke('hide_menu_bar_temporary');
|
||||
}
|
||||
}, true);
|
||||
})();
|
||||
"#;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AppConfig {
|
||||
/// The Onyx server URL (default: https://cloud.onyx.app)
|
||||
pub server_url: String,
|
||||
|
||||
/// Optional: Custom window title
|
||||
#[serde(default = "default_window_title")]
|
||||
pub window_title: String,
|
||||
|
||||
#[serde(default = "default_show_menu_bar")]
|
||||
pub show_menu_bar: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub hide_window_decorations: bool,
|
||||
}
|
||||
|
||||
fn default_window_title() -> String {
|
||||
"Onyx".to_string()
|
||||
}
|
||||
|
||||
fn default_show_menu_bar() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Default for AppConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
server_url: DEFAULT_SERVER_URL.to_string(),
|
||||
window_title: default_window_title(),
|
||||
show_menu_bar: true,
|
||||
hide_window_decorations: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,6 +299,7 @@ struct ConfigState {
|
||||
config: RwLock<AppConfig>,
|
||||
config_initialized: RwLock<bool>,
|
||||
app_base_url: RwLock<Option<Url>>,
|
||||
menu_temporarily_visible: RwLock<bool>,
|
||||
}
|
||||
|
||||
fn focus_main_window(app: &AppHandle) {
|
||||
@@ -301,6 +354,7 @@ fn trigger_new_window(app: &AppHandle) {
|
||||
inject_titlebar(window.clone());
|
||||
}
|
||||
|
||||
apply_settings_to_window(&handle, &window);
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
});
|
||||
@@ -577,18 +631,15 @@ async fn new_window(app: AppHandle, state: tauri::State<'_, ConfigState>) -> Res
|
||||
#[cfg(target_os = "linux")]
|
||||
let builder = builder.background_color(tauri::window::Color(0x1a, 0x1a, 0x2e, 0xff));
|
||||
|
||||
let window = builder.build().map_err(|e| e.to_string())?;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let window = builder.build().map_err(|e| e.to_string())?;
|
||||
// Apply vibrancy effect and inject titlebar
|
||||
let _ = apply_vibrancy(&window, NSVisualEffectMaterial::Sidebar, None, None);
|
||||
inject_titlebar(window.clone());
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let _window = builder.build().map_err(|e| e.to_string())?;
|
||||
}
|
||||
apply_settings_to_window(&app, &window);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -624,6 +675,155 @@ async fn start_drag_window(window: tauri::Window) -> Result<(), String> {
|
||||
window.start_dragging().map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Window Settings
|
||||
// ============================================================================
|
||||
|
||||
fn find_check_menu_item(
|
||||
app: &AppHandle,
|
||||
id: &str,
|
||||
) -> Option<CheckMenuItem<tauri::Wry>> {
|
||||
let menu = app.menu()?;
|
||||
for item in menu.items().ok()? {
|
||||
if let Some(submenu) = item.as_submenu() {
|
||||
for sub_item in submenu.items().ok()? {
|
||||
if let Some(check) = sub_item.as_check_menuitem() {
|
||||
if check.id().as_ref() == id {
|
||||
return Some(check.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn apply_settings_to_window(app: &AppHandle, window: &tauri::WebviewWindow) {
|
||||
if cfg!(target_os = "macos") {
|
||||
return;
|
||||
}
|
||||
let state = app.state::<ConfigState>();
|
||||
let config = state.config.read().unwrap();
|
||||
if !config.show_menu_bar {
|
||||
let _ = window.hide_menu();
|
||||
}
|
||||
if config.hide_window_decorations {
|
||||
let _ = window.set_decorations(false);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_menu_bar_toggle(app: &AppHandle) {
|
||||
if cfg!(target_os = "macos") {
|
||||
return;
|
||||
}
|
||||
let state = app.state::<ConfigState>();
|
||||
let show = {
|
||||
let mut config = state.config.write().unwrap();
|
||||
config.show_menu_bar = !config.show_menu_bar;
|
||||
let _ = save_config(&config);
|
||||
config.show_menu_bar
|
||||
};
|
||||
|
||||
*state.menu_temporarily_visible.write().unwrap() = false;
|
||||
|
||||
for (_, window) in app.webview_windows() {
|
||||
if show {
|
||||
let _ = window.show_menu();
|
||||
} else {
|
||||
let _ = window.hide_menu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_decorations_toggle(app: &AppHandle) {
|
||||
if cfg!(target_os = "macos") {
|
||||
return;
|
||||
}
|
||||
let state = app.state::<ConfigState>();
|
||||
let hide = {
|
||||
let mut config = state.config.write().unwrap();
|
||||
config.hide_window_decorations = !config.hide_window_decorations;
|
||||
let _ = save_config(&config);
|
||||
config.hide_window_decorations
|
||||
};
|
||||
|
||||
for (_, window) in app.webview_windows() {
|
||||
let _ = window.set_decorations(!hide);
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn toggle_menu_bar(app: AppHandle) {
|
||||
if cfg!(target_os = "macos") {
|
||||
return;
|
||||
}
|
||||
let state = app.state::<ConfigState>();
|
||||
let new_value = {
|
||||
let mut config = state.config.write().unwrap();
|
||||
config.show_menu_bar = !config.show_menu_bar;
|
||||
let _ = save_config(&config);
|
||||
config.show_menu_bar
|
||||
};
|
||||
|
||||
*state.menu_temporarily_visible.write().unwrap() = false;
|
||||
|
||||
if let Some(check) = find_check_menu_item(&app, MENU_SHOW_MENU_BAR_ID) {
|
||||
let _ = check.set_checked(new_value);
|
||||
}
|
||||
|
||||
for (_, window) in app.webview_windows() {
|
||||
if new_value {
|
||||
let _ = window.show_menu();
|
||||
} else {
|
||||
let _ = window.hide_menu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn show_menu_bar_temporarily(app: AppHandle) {
|
||||
if cfg!(target_os = "macos") {
|
||||
return;
|
||||
}
|
||||
let state = app.state::<ConfigState>();
|
||||
if state.config.read().unwrap().show_menu_bar {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut temp = state.menu_temporarily_visible.write().unwrap();
|
||||
if *temp {
|
||||
return;
|
||||
}
|
||||
*temp = true;
|
||||
drop(temp);
|
||||
|
||||
for (_, window) in app.webview_windows() {
|
||||
let _ = window.show_menu();
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn hide_menu_bar_temporary(app: AppHandle) {
|
||||
if cfg!(target_os = "macos") {
|
||||
return;
|
||||
}
|
||||
let state = app.state::<ConfigState>();
|
||||
let mut temp = state.menu_temporarily_visible.write().unwrap();
|
||||
if !*temp {
|
||||
return;
|
||||
}
|
||||
*temp = false;
|
||||
drop(temp);
|
||||
|
||||
if state.config.read().unwrap().show_menu_bar {
|
||||
return;
|
||||
}
|
||||
|
||||
for (_, window) in app.webview_windows() {
|
||||
let _ = window.hide_menu();
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Menu Setup
|
||||
// ============================================================================
|
||||
@@ -667,6 +867,59 @@ fn setup_app_menu(app: &AppHandle) -> tauri::Result<()> {
|
||||
menu.prepend(&file_menu)?;
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let config = app.state::<ConfigState>();
|
||||
let config_guard = config.config.read().unwrap();
|
||||
|
||||
let show_menu_bar_item = CheckMenuItem::with_id(
|
||||
app,
|
||||
MENU_SHOW_MENU_BAR_ID,
|
||||
"Show Menu Bar",
|
||||
true,
|
||||
config_guard.show_menu_bar,
|
||||
None::<&str>,
|
||||
)?;
|
||||
|
||||
let hide_decorations_item = CheckMenuItem::with_id(
|
||||
app,
|
||||
MENU_HIDE_DECORATIONS_ID,
|
||||
"Hide Window Decorations",
|
||||
true,
|
||||
config_guard.hide_window_decorations,
|
||||
None::<&str>,
|
||||
)?;
|
||||
|
||||
drop(config_guard);
|
||||
|
||||
if let Some(window_menu) = menu
|
||||
.items()?
|
||||
.into_iter()
|
||||
.filter_map(|item| item.as_submenu().cloned())
|
||||
.find(|submenu| submenu.text().ok().as_deref() == Some("Window"))
|
||||
{
|
||||
window_menu.append(&show_menu_bar_item)?;
|
||||
window_menu.append(&hide_decorations_item)?;
|
||||
} else {
|
||||
let window_menu = SubmenuBuilder::new(app, "Window")
|
||||
.item(&show_menu_bar_item)
|
||||
.item(&hide_decorations_item)
|
||||
.build()?;
|
||||
|
||||
let items = menu.items()?;
|
||||
let help_idx = items
|
||||
.iter()
|
||||
.position(|item| {
|
||||
item.as_submenu()
|
||||
.and_then(|s| s.text().ok())
|
||||
.as_deref()
|
||||
== Some("Help")
|
||||
})
|
||||
.unwrap_or(items.len());
|
||||
menu.insert(&window_menu, help_idx)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(help_menu) = menu
|
||||
.get(HELP_SUBMENU_ID)
|
||||
.and_then(|item| item.as_submenu().cloned())
|
||||
@@ -801,6 +1054,7 @@ fn main() {
|
||||
config: RwLock::new(config),
|
||||
config_initialized: RwLock::new(config_initialized),
|
||||
app_base_url: RwLock::new(None),
|
||||
menu_temporarily_visible: RwLock::new(false),
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
get_server_url,
|
||||
@@ -816,13 +1070,18 @@ fn main() {
|
||||
go_forward,
|
||||
new_window,
|
||||
reset_config,
|
||||
start_drag_window
|
||||
start_drag_window,
|
||||
toggle_menu_bar,
|
||||
show_menu_bar_temporarily,
|
||||
hide_menu_bar_temporary
|
||||
])
|
||||
.on_menu_event(|app, event| match event.id().as_ref() {
|
||||
"open_docs" => open_docs(),
|
||||
"new_chat" => trigger_new_chat(app),
|
||||
"new_window" => trigger_new_window(app),
|
||||
"open_settings" => open_settings(app),
|
||||
"show_menu_bar" => handle_menu_bar_toggle(app),
|
||||
"hide_window_decorations" => handle_decorations_toggle(app),
|
||||
_ => {}
|
||||
})
|
||||
.setup(move |app| {
|
||||
@@ -855,6 +1114,8 @@ fn main() {
|
||||
#[cfg(target_os = "macos")]
|
||||
inject_titlebar(window.clone());
|
||||
|
||||
apply_settings_to_window(&app_handle, &window);
|
||||
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
|
||||
@@ -863,7 +1124,27 @@ fn main() {
|
||||
.on_page_load(|webview: &Webview, _payload: &PageLoadPayload| {
|
||||
inject_chat_link_intercept(webview);
|
||||
|
||||
// Re-inject titlebar after every navigation/page load (macOS only)
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let _ = webview.eval(MENU_KEY_HANDLER_SCRIPT);
|
||||
|
||||
let app = webview.app_handle();
|
||||
let state = app.state::<ConfigState>();
|
||||
let config = state.config.read().unwrap();
|
||||
let temp_visible = *state.menu_temporarily_visible.read().unwrap();
|
||||
let label = webview.label().to_string();
|
||||
if !config.show_menu_bar && !temp_visible {
|
||||
if let Some(win) = app.get_webview_window(&label) {
|
||||
let _ = win.hide_menu();
|
||||
}
|
||||
}
|
||||
if config.hide_window_decorations {
|
||||
if let Some(win) = app.get_webview_window(&label) {
|
||||
let _ = win.set_decorations(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let _ = webview.eval(TITLEBAR_SCRIPT);
|
||||
})
|
||||
|
||||
6
uv.lock
generated
6
uv.lock
generated
@@ -8080,14 +8080,14 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "3.1.5"
|
||||
version = "3.1.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markupsafe" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5a/70/1469ef1d3542ae7c2c7b72bd5e3a4e6ee69d7978fa8a3af05a38eca5becf/werkzeug-3.1.5.tar.gz", hash = "sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67", size = 864754, upload-time = "2026-01-08T17:49:23.247Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/61/f1/ee81806690a87dab5f5653c1f146c92bc066d7f4cebc603ef88eb9e13957/werkzeug-3.1.6.tar.gz", hash = "sha256:210c6bede5a420a913956b4791a7f4d6843a43b6fcee4dfa08a65e93007d0d25", size = 864736, upload-time = "2026-02-19T15:17:18.884Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/e4/8d97cca767bcc1be76d16fb76951608305561c6e056811587f36cb1316a8/werkzeug-3.1.5-py3-none-any.whl", hash = "sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc", size = 225025, upload-time = "2026-01-08T17:49:21.859Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/ec/d58832f89ede95652fd01f4f24236af7d32b70cab2196dfcc2d2fd13c5c2/werkzeug-3.1.6-py3-none-any.whl", hash = "sha256:7ddf3357bb9564e407607f988f683d72038551200c704012bb9a4c523d42f131", size = 225166, upload-time = "2026-02-19T15:17:17.475Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -58,7 +58,7 @@ function ContentAction({
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-stretch w-full">
|
||||
<div className={cn("flex-1 min-w-0", padding)}>
|
||||
<div className={cn("flex-1 min-w-0 self-center", padding)}>
|
||||
<Content {...contentProps} />
|
||||
</div>
|
||||
{rightChildren && (
|
||||
|
||||
220
web/package-lock.json
generated
220
web/package-lock.json
generated
@@ -4127,9 +4127,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz",
|
||||
"integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
|
||||
"integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -4140,9 +4140,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz",
|
||||
"integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4153,7 +4153,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.52.5",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4164,9 +4166,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz",
|
||||
"integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4177,9 +4179,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz",
|
||||
"integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4190,9 +4192,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz",
|
||||
"integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4203,9 +4205,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz",
|
||||
"integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
|
||||
"integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -4216,9 +4218,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz",
|
||||
"integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
|
||||
"integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -4229,9 +4231,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4242,9 +4244,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz",
|
||||
"integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4255,9 +4257,22 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-musl": {
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -4268,9 +4283,22 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-musl": {
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -4281,9 +4309,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -4294,9 +4322,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz",
|
||||
"integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -4307,9 +4335,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -4320,9 +4348,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4333,9 +4361,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
|
||||
"integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4345,10 +4373,23 @@
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openbsd-x64": {
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz",
|
||||
"integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4359,9 +4400,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz",
|
||||
"integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -4372,9 +4413,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz",
|
||||
"integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -4385,9 +4426,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz",
|
||||
"integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4398,9 +4439,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.52.5",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz",
|
||||
"integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -14464,7 +14505,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.52.5",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
|
||||
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.8"
|
||||
@@ -14477,28 +14520,31 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.52.5",
|
||||
"@rollup/rollup-android-arm64": "4.52.5",
|
||||
"@rollup/rollup-darwin-arm64": "4.52.5",
|
||||
"@rollup/rollup-darwin-x64": "4.52.5",
|
||||
"@rollup/rollup-freebsd-arm64": "4.52.5",
|
||||
"@rollup/rollup-freebsd-x64": "4.52.5",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.52.5",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.52.5",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.52.5",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.52.5",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.52.5",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.52.5",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.52.5",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.52.5",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.52.5",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.52.5",
|
||||
"@rollup/rollup-linux-x64-musl": "4.52.5",
|
||||
"@rollup/rollup-openharmony-arm64": "4.52.5",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.52.5",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.52.5",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.52.5",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.52.5",
|
||||
"@rollup/rollup-android-arm-eabi": "4.59.0",
|
||||
"@rollup/rollup-android-arm64": "4.59.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.59.0",
|
||||
"@rollup/rollup-darwin-x64": "4.59.0",
|
||||
"@rollup/rollup-freebsd-arm64": "4.59.0",
|
||||
"@rollup/rollup-freebsd-x64": "4.59.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.59.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-loong64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-ppc64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.59.0",
|
||||
"@rollup/rollup-openbsd-x64": "4.59.0",
|
||||
"@rollup/rollup-openharmony-arm64": "4.59.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.59.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.59.0",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.59.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.59.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import * as InputLayouts from "@/layouts/input-layouts";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
import Button from "@/refresh-components/buttons/Button";
|
||||
@@ -372,9 +373,11 @@ function SeatsCard({
|
||||
padding={1}
|
||||
height="auto"
|
||||
>
|
||||
<LineItemLayout
|
||||
<Content
|
||||
title="Update Seats"
|
||||
description="Add or remove seats to reflect your team size."
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
<Button main secondary onClick={handleCancel} disabled={isSubmitting}>
|
||||
Cancel
|
||||
|
||||
@@ -12,6 +12,7 @@ import Tabs from "@/refresh-components/Tabs";
|
||||
import { useFormikContext } from "formik";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import * as InputLayouts from "@/layouts/input-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import CheckboxField from "@/refresh-components/form/LabeledCheckboxField";
|
||||
import InputTextAreaField from "@/refresh-components/form/InputTextAreaField";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
@@ -46,9 +47,11 @@ const TabsField: FC<TabsFieldProps> = ({
|
||||
return (
|
||||
<GeneralLayouts.Section gap={0.5} alignItems="start">
|
||||
{tabField.label && (
|
||||
<InputLayouts.Title
|
||||
<Content
|
||||
title={resolvedLabel ?? ""}
|
||||
description={resolvedDescription}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ import { cn } from "@/lib/utils";
|
||||
import { ThreeDotsLoader } from "@/components/Loading";
|
||||
import { ErrorCallout } from "@/components/ErrorCallout";
|
||||
import { toast } from "@/hooks/useToast";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
import * as SettingsLayouts from "@/layouts/settings-layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
@@ -89,9 +90,11 @@ function GuildDetailContent({
|
||||
)}
|
||||
|
||||
<Card variant={disabled ? "disabled" : "primary"}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
title="Channel Configuration"
|
||||
description="Run !sync-channels in Discord to update the channel list."
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
isRegistered && !channelsLoading && !channelsError ? (
|
||||
<Section
|
||||
@@ -339,9 +342,11 @@ export default function Page({ params }: Props) {
|
||||
<SettingsLayouts.Body>
|
||||
{/* Default Persona Selector */}
|
||||
<Card variant={!guild?.enabled ? "disabled" : "primary"}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
title="Default Agent"
|
||||
description="The agent used by the bot in all channels unless overridden."
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
<InputSelect
|
||||
value={guild?.default_persona_id?.toString() ?? "default"}
|
||||
|
||||
@@ -5,7 +5,7 @@ import useSWR from "swr";
|
||||
import { SvgArrowExchange } from "@opal/icons";
|
||||
import * as SettingsLayouts from "@/layouts/settings-layouts";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
import { LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Content, ContentAction } from "@opal/layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import InputSelect from "@/refresh-components/inputs/InputSelect";
|
||||
import Button from "@/refresh-components/buttons/Button";
|
||||
@@ -72,9 +72,10 @@ function MigrationStatusSection() {
|
||||
<Card>
|
||||
<Text headingH3>Migration Status</Text>
|
||||
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
title="Started"
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
<Text mainUiBody>
|
||||
{hasStarted ? formatTimestamp(data.created_at!) : "Not started"}
|
||||
@@ -82,9 +83,10 @@ function MigrationStatusSection() {
|
||||
}
|
||||
/>
|
||||
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
title="Chunks Migrated"
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
<Text mainUiBody>
|
||||
{progressPercentage !== null
|
||||
@@ -96,9 +98,10 @@ function MigrationStatusSection() {
|
||||
}
|
||||
/>
|
||||
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
title="Completed"
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
<Text mainUiBody>
|
||||
{hasCompleted
|
||||
@@ -174,10 +177,11 @@ function RetrievalSourceSection() {
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<LineItemLayout
|
||||
<Content
|
||||
title="Retrieval Source"
|
||||
description="Controls which document index is used for retrieval."
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
|
||||
<InputSelect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { memo, useState } from "react";
|
||||
import { SvgDownload } from "@opal/icons";
|
||||
import { useState } from "react";
|
||||
import { FiDownload } from "react-icons/fi";
|
||||
import { ImageShape } from "@/app/app/services/streamingModels";
|
||||
import { FullImageModal } from "@/app/app/components/files/images/FullImageModal";
|
||||
import { buildImgUrl } from "@/app/app/components/files/images/utils";
|
||||
@@ -24,22 +24,17 @@ const SHAPE_CLASSES: Record<ImageShape, { container: string; image: string }> =
|
||||
},
|
||||
};
|
||||
|
||||
// Used to stop image flashing as images are loaded and response continues
|
||||
const loadedImages = new Set<string>();
|
||||
|
||||
interface InMessageImageProps {
|
||||
fileId: string;
|
||||
fileName?: string;
|
||||
shape?: ImageShape;
|
||||
}
|
||||
|
||||
export const InMessageImage = memo(function InMessageImage({
|
||||
export function InMessageImage({
|
||||
fileId,
|
||||
fileName,
|
||||
shape = DEFAULT_SHAPE,
|
||||
}: InMessageImageProps) {
|
||||
const [fullImageShowing, setFullImageShowing] = useState(false);
|
||||
const [imageLoaded, setImageLoaded] = useState(loadedImages.has(fileId));
|
||||
const [imageLoaded, setImageLoaded] = useState(false);
|
||||
|
||||
const normalizedShape = SHAPE_CLASSES[shape] ? shape : DEFAULT_SHAPE;
|
||||
const { container: shapeContainerClasses, image: shapeImageClasses } =
|
||||
@@ -54,7 +49,7 @@ export const InMessageImage = memo(function InMessageImage({
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = fileName || `image-${fileId}.png`;
|
||||
a.download = `image-${fileId}.png`; // You can adjust the filename/extension as needed
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
@@ -81,10 +76,7 @@ export const InMessageImage = memo(function InMessageImage({
|
||||
width={1200}
|
||||
height={1200}
|
||||
alt="Chat Message Image"
|
||||
onLoad={() => {
|
||||
loadedImages.add(fileId);
|
||||
setImageLoaded(true);
|
||||
}}
|
||||
onLoad={() => setImageLoaded(true)}
|
||||
className={cn(
|
||||
"object-contain object-left overflow-hidden rounded-lg w-full h-full transition-opacity duration-300 cursor-pointer",
|
||||
shapeImageClasses,
|
||||
@@ -102,7 +94,7 @@ export const InMessageImage = memo(function InMessageImage({
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
icon={SvgDownload}
|
||||
icon={FiDownload}
|
||||
tooltip="Download"
|
||||
onClick={handleDownload}
|
||||
/>
|
||||
@@ -110,4 +102,4 @@ export const InMessageImage = memo(function InMessageImage({
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,21 +1,3 @@
|
||||
const CHAT_FILE_URL_REGEX = /\/api\/chat\/file\/([^/?#]+)/;
|
||||
const IMAGE_EXTENSIONS = /\.(png|jpe?g|gif|webp|svg|bmp|ico|tiff?)$/i;
|
||||
|
||||
export function buildImgUrl(fileId: string) {
|
||||
return `/api/chat/file/${fileId}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `href` points to a chat file and `linkText` ends with an image extension,
|
||||
* returns the file ID. Otherwise returns null.
|
||||
*/
|
||||
export function extractChatImageFileId(
|
||||
href: string | undefined,
|
||||
linkText: string
|
||||
): string | null {
|
||||
if (!href) return null;
|
||||
const match = CHAT_FILE_URL_REGEX.exec(href);
|
||||
if (!match?.[1]) return null;
|
||||
if (!IMAGE_EXTENSIONS.test(linkText)) return null;
|
||||
return match[1];
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@ import {
|
||||
import { extractCodeText, preprocessLaTeX } from "@/app/app/message/codeUtils";
|
||||
import { CodeBlock } from "@/app/app/message/CodeBlock";
|
||||
import { transformLinkUri, cn } from "@/lib/utils";
|
||||
import { InMessageImage } from "@/app/app/components/files/images/InMessageImage";
|
||||
import { extractChatImageFileId } from "@/app/app/components/files/images/utils";
|
||||
|
||||
/**
|
||||
* Processes content for markdown rendering by handling code blocks and LaTeX
|
||||
@@ -60,31 +58,17 @@ export const useMarkdownComponents = (
|
||||
);
|
||||
|
||||
const anchorCallback = useCallback(
|
||||
(props: any) => {
|
||||
const imageFileId = extractChatImageFileId(
|
||||
props.href,
|
||||
String(props.children ?? "")
|
||||
);
|
||||
if (imageFileId) {
|
||||
return (
|
||||
<InMessageImage
|
||||
fileId={imageFileId}
|
||||
fileName={String(props.children ?? "")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<MemoizedAnchor
|
||||
updatePresentingDocument={state?.setPresentingDocument || (() => {})}
|
||||
docs={state?.docs || []}
|
||||
userFiles={state?.userFiles || []}
|
||||
citations={state?.citations}
|
||||
href={props.href}
|
||||
>
|
||||
{props.children}
|
||||
</MemoizedAnchor>
|
||||
);
|
||||
},
|
||||
(props: any) => (
|
||||
<MemoizedAnchor
|
||||
updatePresentingDocument={state?.setPresentingDocument || (() => {})}
|
||||
docs={state?.docs || []}
|
||||
userFiles={state?.userFiles || []}
|
||||
citations={state?.citations}
|
||||
href={props.href}
|
||||
>
|
||||
{props.children}
|
||||
</MemoizedAnchor>
|
||||
),
|
||||
[
|
||||
state?.docs,
|
||||
state?.userFiles,
|
||||
|
||||
@@ -6,7 +6,8 @@ import { Button } from "@opal/components";
|
||||
import Tag from "@/refresh-components/buttons/Tag";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import SimpleTooltip from "@/refresh-components/SimpleTooltip";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
import { formatDurationSeconds } from "@/lib/time";
|
||||
import { noProp } from "@/lib/utils";
|
||||
import MemoriesModal from "@/refresh-components/modals/MemoriesModal";
|
||||
@@ -61,10 +62,12 @@ function MemoryTagWithTooltip({
|
||||
{memoryText}
|
||||
</Text>
|
||||
</div>
|
||||
<LineItemLayout
|
||||
variant="mini"
|
||||
<ContentAction
|
||||
icon={SvgAddLines}
|
||||
title={operationLabel}
|
||||
sizePreset="secondary"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
rightChildren={
|
||||
<Button
|
||||
prominence="tertiary"
|
||||
|
||||
@@ -9,7 +9,8 @@ import type { SharingScope } from "@/app/craft/types/streamingTypes";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Popover from "@/refresh-components/Popover";
|
||||
import Truncated from "@/refresh-components/texts/Truncated";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
|
||||
interface ShareButtonProps {
|
||||
sessionId: string;
|
||||
@@ -133,11 +134,12 @@ export default function ShareButton({
|
||||
: "hover:bg-background-tint-02"
|
||||
)}
|
||||
>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
title={opt.label}
|
||||
description={opt.description}
|
||||
variant="tertiary"
|
||||
reducedPadding
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
paddingVariant="sm"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { useState } from "react";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import Separator from "@/refresh-components/Separator";
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
@@ -99,14 +99,15 @@ export default function ComingSoonConnectors() {
|
||||
const card = (
|
||||
<div key={type} className="opacity-60">
|
||||
<Card variant="secondary">
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={
|
||||
type === ValidSources.Imap
|
||||
? OutlookIcon
|
||||
: sourceMetadata.icon
|
||||
}
|
||||
title={displayName}
|
||||
center
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -118,7 +119,12 @@ export default function ComingSoonConnectors() {
|
||||
card,
|
||||
<div key="onedrive" className="opacity-60">
|
||||
<Card variant="secondary">
|
||||
<LineItemLayout icon={OneDriveIcon} title="OneDrive" center />
|
||||
<Content
|
||||
icon={OneDriveIcon}
|
||||
title="OneDrive"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
/>
|
||||
</Card>
|
||||
</div>,
|
||||
];
|
||||
@@ -130,7 +136,12 @@ export default function ComingSoonConnectors() {
|
||||
card,
|
||||
<div key="box" className="opacity-60">
|
||||
<Card variant="secondary">
|
||||
<LineItemLayout icon={BoxIcon} title="Box" center />
|
||||
<Content
|
||||
icon={BoxIcon}
|
||||
title="Box"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
/>
|
||||
</Card>
|
||||
</div>,
|
||||
];
|
||||
@@ -141,13 +152,23 @@ export default function ComingSoonConnectors() {
|
||||
{/* Enterprise/ERP */}
|
||||
<div className="opacity-60">
|
||||
<Card variant="secondary">
|
||||
<LineItemLayout icon={ServiceNowIcon} title="ServiceNow" center />
|
||||
<Content
|
||||
icon={ServiceNowIcon}
|
||||
title="ServiceNow"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
{/* Project Management */}
|
||||
<div className="opacity-60">
|
||||
<Card variant="secondary">
|
||||
<LineItemLayout icon={TrelloIcon} title="Trello" center />
|
||||
<Content
|
||||
icon={TrelloIcon}
|
||||
title="Trello"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,7 @@ import { useState } from "react";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
import Popover from "@/refresh-components/Popover";
|
||||
import LineItem from "@/refresh-components/buttons/LineItem";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import { getSourceMetadata } from "@/lib/sources";
|
||||
import { SvgMoreHorizontal, SvgPlug, SvgSettings, SvgTrash } from "@opal/icons";
|
||||
@@ -41,15 +40,6 @@ interface ConnectorCardProps {
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
const STATUS_COLORS: Record<ConnectorStatus, string> = {
|
||||
connected: "bg-status-success-05",
|
||||
connected_with_errors: "bg-status-warning-05",
|
||||
indexing: "bg-status-warning-05 animate-pulse",
|
||||
error: "bg-status-error-05",
|
||||
deleting: "bg-status-error-05 animate-pulse",
|
||||
not_connected: "bg-background-neutral-03",
|
||||
};
|
||||
|
||||
function getStatusText(status: ConnectorStatus, docsIndexed: number): string {
|
||||
switch (status) {
|
||||
case "connected":
|
||||
@@ -72,29 +62,6 @@ function getStatusText(status: ConnectorStatus, docsIndexed: number): string {
|
||||
}
|
||||
}
|
||||
|
||||
function StatusDescription({
|
||||
status,
|
||||
docsIndexed,
|
||||
}: {
|
||||
status: ConnectorStatus;
|
||||
docsIndexed: number;
|
||||
}) {
|
||||
return (
|
||||
<Section
|
||||
flexDirection="row"
|
||||
alignItems="center"
|
||||
gap={0.375}
|
||||
width="fit"
|
||||
height="fit"
|
||||
>
|
||||
<div className={cn(STATUS_COLORS[status], "w-2 h-2 rounded-full")} />
|
||||
<Text secondaryBody text03>
|
||||
{getStatusText(status, docsIndexed)}
|
||||
</Text>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ConnectorCard({
|
||||
connectorType,
|
||||
config,
|
||||
@@ -180,17 +147,8 @@ export default function ConnectorCard({
|
||||
const cardVariant =
|
||||
isAlwaysConnected || isConnected ? "primary" : "secondary";
|
||||
|
||||
// Use custom description if provided, otherwise show status
|
||||
const descriptionContent = customDescription ? (
|
||||
<Text secondaryBody text03>
|
||||
{customDescription}
|
||||
</Text>
|
||||
) : (
|
||||
<StatusDescription
|
||||
status={status}
|
||||
docsIndexed={config?.docs_indexed || 0}
|
||||
/>
|
||||
);
|
||||
const descriptionText =
|
||||
customDescription ?? getStatusText(status, config?.docs_indexed || 0);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -198,12 +156,13 @@ export default function ConnectorCard({
|
||||
onClick={handleCardClick}
|
||||
>
|
||||
<Card variant={cardVariant}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={sourceMetadata.icon}
|
||||
title={sourceMetadata.displayName}
|
||||
description={descriptionContent}
|
||||
description={descriptionText}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
rightChildren={rightContent}
|
||||
center
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ConnectorStatus } from "@/lib/types";
|
||||
import { ConnectorTitle } from "@/components/admin/connectors/ConnectorTitle";
|
||||
import * as InputLayouts from "@/layouts/input-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { SvgLock } from "@opal/icons";
|
||||
interface NonSelectableConnectorsProps {
|
||||
@@ -20,7 +20,12 @@ export const NonSelectableConnectors = ({
|
||||
|
||||
return (
|
||||
<div className="mt-6 mb-4">
|
||||
<InputLayouts.Title title={title} description={description} />
|
||||
<Content
|
||||
title={title}
|
||||
description={description}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
|
||||
<div className="p-3 border border-dashed border-border-02 rounded-12 bg-background-neutral-01">
|
||||
<div className="mb-2 flex items-center gap-1.5">
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getSourceMetadata } from "@/lib/sources";
|
||||
import useFederatedOAuthStatus from "@/hooks/useFederatedOAuthStatus";
|
||||
import { SvgLink } from "@opal/icons";
|
||||
import { Card } from "@/refresh-components/cards";
|
||||
import { LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
|
||||
export interface FederatedConnectorOAuthStatus {
|
||||
federated_connector_id: number;
|
||||
@@ -136,10 +136,12 @@ export default function FederatedOAuthModal() {
|
||||
|
||||
return (
|
||||
<Card key={connector.federated_connector_id}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={sourceMetadata.icon}
|
||||
title={sourceMetadata.displayName}
|
||||
description={sourceMetadata.category}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
<Button
|
||||
secondary
|
||||
@@ -149,7 +151,6 @@ export default function FederatedOAuthModal() {
|
||||
Connect
|
||||
</Button>
|
||||
}
|
||||
center
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
import React, { HtmlHTMLAttributes } from "react";
|
||||
import type { IconProps } from "@opal/types";
|
||||
import { WithoutStyles } from "@/types";
|
||||
import { LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
import * as ExpandableCard from "@/layouts/expandable-card-layouts";
|
||||
import { Card } from "@/refresh-components/cards";
|
||||
import Label from "@/refresh-components/form/Label";
|
||||
@@ -119,11 +119,14 @@ function ActionsHeader({
|
||||
<div className="flex flex-col gap-2 pt-4 pb-2">
|
||||
<div className="px-4">
|
||||
<Label name={name}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={Icon}
|
||||
title={title}
|
||||
description={description}
|
||||
sizePreset="section"
|
||||
variant="section"
|
||||
rightChildren={rightChildren}
|
||||
paddingVariant="fit"
|
||||
/>
|
||||
</Label>
|
||||
</div>
|
||||
@@ -237,12 +240,14 @@ function ActionsTool({
|
||||
return (
|
||||
<Card padding={0.75} variant={disabled ? "disabled" : undefined}>
|
||||
<Label name={name} disabled={disabled}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={icon}
|
||||
title={title}
|
||||
description={description}
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
rightChildren={rightChildren}
|
||||
variant="secondary"
|
||||
paddingVariant="fit"
|
||||
/>
|
||||
</Label>
|
||||
</Card>
|
||||
|
||||
@@ -48,7 +48,6 @@ import { PopoverSearchInput } from "@/sections/sidebar/ChatButton";
|
||||
import SimplePopover from "@/refresh-components/SimplePopover";
|
||||
import { Interactive } from "@opal/core";
|
||||
import { Button, OpenButton } from "@opal/components";
|
||||
import { LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { useAppSidebarContext } from "@/providers/AppSidebarProvider";
|
||||
import useScreenSize from "@/hooks/useScreenSize";
|
||||
import {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { cn } from "@/lib/utils";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import Truncated from "@/refresh-components/texts/Truncated";
|
||||
import { WithoutStyles } from "@/types";
|
||||
import { Content } from "@opal/layouts";
|
||||
import { IconProps } from "@opal/types";
|
||||
import React from "react";
|
||||
|
||||
@@ -160,152 +161,6 @@ function Section({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* LineItemLayout - A layout for icon + title + description rows
|
||||
*
|
||||
* Structure:
|
||||
* Flexbox Row [
|
||||
* Grid [
|
||||
* [Icon] [Title ]
|
||||
* [ ] [Description]
|
||||
* ],
|
||||
* rightChildren
|
||||
* ]
|
||||
*
|
||||
* - Icon column auto-sizes to icon width
|
||||
* - Icon vertically centers with title
|
||||
* - Description aligns with title's left edge (both in grid column 2)
|
||||
* - rightChildren is outside the grid, in the outer flexbox
|
||||
*
|
||||
* Variants:
|
||||
* - `primary`: Standard size (20px icon) with emphasized text. The default for prominent list items.
|
||||
* - `secondary`: Compact size (16px icon) with standard text. Use for denser lists or nested items.
|
||||
* - `tertiary`: Compact size (16px icon) with standard text. Use for less prominent items in tight layouts.
|
||||
* - `tertiary-muted`: Compact size (16px icon) with muted text styling. Use for de-emphasized or secondary information.
|
||||
* - `mini`: Smallest size (12px icon) with muted secondary text. Use for metadata labels (e.g., owner, action count).
|
||||
*
|
||||
* @param icon - Optional icon component to display on the left
|
||||
* @param title - The main title text (required)
|
||||
* @param description - Optional description content below the title (string or ReactNode)
|
||||
* @param rightChildren - Optional content to render on the right side
|
||||
* @param variant - Visual variant. Default: "primary"
|
||||
* @param strikethrough - If true, applies line-through style to title. Default: false
|
||||
* @param loading - If true, renders skeleton placeholders instead of content. Default: false
|
||||
* @param center - If true, vertically centers items; otherwise aligns to start. Default: false
|
||||
*/
|
||||
type LineItemLayoutVariant =
|
||||
| "primary"
|
||||
| "secondary"
|
||||
| "tertiary"
|
||||
| "tertiary-muted"
|
||||
| "mini";
|
||||
export interface LineItemLayoutProps {
|
||||
icon?: React.FunctionComponent<IconProps>;
|
||||
title: string;
|
||||
description?: React.ReactNode;
|
||||
middleText?: string;
|
||||
rightChildren?: React.ReactNode;
|
||||
|
||||
variant?: LineItemLayoutVariant;
|
||||
width?: Length;
|
||||
strikethrough?: boolean;
|
||||
loading?: boolean;
|
||||
center?: boolean;
|
||||
reducedPadding?: boolean;
|
||||
}
|
||||
function LineItemLayout({
|
||||
icon: Icon,
|
||||
title,
|
||||
description,
|
||||
middleText,
|
||||
rightChildren,
|
||||
|
||||
variant = "primary",
|
||||
width,
|
||||
strikethrough,
|
||||
loading,
|
||||
center,
|
||||
reducedPadding,
|
||||
}: LineItemLayoutProps) {
|
||||
// Derive styling from variant
|
||||
const isMini = variant === "mini";
|
||||
const isCompact =
|
||||
variant === "secondary" ||
|
||||
variant === "tertiary" ||
|
||||
variant === "tertiary-muted";
|
||||
const isMuted = variant === "tertiary-muted" || isMini;
|
||||
|
||||
// Determine icon size: mini=12px, compact=16px, primary=20px
|
||||
const iconSize = isMini ? 12 : isCompact ? 16 : 20;
|
||||
|
||||
// Determine gap: mini=0.25rem, others=1.5rem
|
||||
const gap = isMini ? 0.25 : 1.5;
|
||||
|
||||
return (
|
||||
<Section
|
||||
flexDirection="row"
|
||||
justifyContent="between"
|
||||
alignItems={center || isMini ? "center" : "start"}
|
||||
gap={gap}
|
||||
width={width}
|
||||
>
|
||||
<div
|
||||
className="line-item-layout"
|
||||
data-variant={variant}
|
||||
data-has-icon={Icon ? "true" : undefined}
|
||||
data-loading={loading ? "true" : undefined}
|
||||
data-strikethrough={strikethrough ? "true" : undefined}
|
||||
data-reduced-padding={reducedPadding ? "true" : undefined}
|
||||
>
|
||||
{/* Row 1: Icon, Title */}
|
||||
{Icon && <Icon size={iconSize} className="line-item-layout-icon" />}
|
||||
{loading ? (
|
||||
<div className="line-item-layout-skeleton-title" />
|
||||
) : (
|
||||
<Truncated
|
||||
mainContentEmphasis={!isCompact && !isMini}
|
||||
secondaryBody={isMini}
|
||||
mainUiAction={variant === "secondary"}
|
||||
text03={isMuted}
|
||||
className="line-item-layout-title"
|
||||
>
|
||||
{title}
|
||||
</Truncated>
|
||||
)}
|
||||
|
||||
{/* Row 2: Description (column 2, or column 1 if no icon) */}
|
||||
{loading && description ? (
|
||||
<div className="line-item-layout-skeleton-description" />
|
||||
) : description ? (
|
||||
<div className="line-item-layout-description">
|
||||
{typeof description === "string" ? (
|
||||
<Text secondaryBody text03>
|
||||
{description}
|
||||
</Text>
|
||||
) : (
|
||||
description
|
||||
)}
|
||||
</div>
|
||||
) : undefined}
|
||||
</div>
|
||||
|
||||
{!loading && middleText && (
|
||||
<div className="flex-1">
|
||||
<Truncated text03 secondaryBody>
|
||||
{middleText}
|
||||
</Truncated>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && rightChildren ? (
|
||||
<div className="line-item-layout-skeleton-right" />
|
||||
) : rightChildren ? (
|
||||
<div className="flex-shrink-0">{rightChildren}</div>
|
||||
) : undefined}
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
export interface AttachmentItemLayoutProps {
|
||||
title: string;
|
||||
description: string;
|
||||
@@ -329,18 +184,29 @@ function AttachmentItemLayout({
|
||||
</div>
|
||||
</Section>
|
||||
</div>
|
||||
<LineItemLayout
|
||||
title={title}
|
||||
description={description}
|
||||
middleText={middleText}
|
||||
rightChildren={
|
||||
rightChildren ? (
|
||||
<div className="px-1">{rightChildren}</div>
|
||||
) : undefined
|
||||
}
|
||||
center
|
||||
variant="secondary"
|
||||
/>
|
||||
<Section
|
||||
flexDirection="row"
|
||||
justifyContent="between"
|
||||
alignItems="center"
|
||||
gap={1.5}
|
||||
>
|
||||
<Content
|
||||
title={title}
|
||||
description={description}
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
{middleText && (
|
||||
<div className="flex-1">
|
||||
<Truncated text03 secondaryBody>
|
||||
{middleText}
|
||||
</Truncated>
|
||||
</div>
|
||||
)}
|
||||
{rightChildren && (
|
||||
<div className="flex-shrink-0 px-1">{rightChildren}</div>
|
||||
)}
|
||||
</Section>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
@@ -413,4 +279,4 @@ function CardItemLayout({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export { Section, LineItemLayout, CardItemLayout, AttachmentItemLayout };
|
||||
export { Section, CardItemLayout, AttachmentItemLayout };
|
||||
|
||||
@@ -4,13 +4,18 @@ import Text from "@/refresh-components/texts/Text";
|
||||
import { SvgXOctagon, SvgAlertCircle } from "@opal/icons";
|
||||
import { useField, useFormikContext } from "formik";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import Label from "@/refresh-components/form/Label";
|
||||
|
||||
interface OrientationLayoutProps extends TitleLayoutProps {
|
||||
interface OrientationLayoutProps {
|
||||
name?: string;
|
||||
disabled?: boolean;
|
||||
nonInteractive?: boolean;
|
||||
children?: React.ReactNode;
|
||||
title: string;
|
||||
description?: string;
|
||||
optional?: boolean;
|
||||
sizePreset?: "main-content" | "main-ui";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,11 +49,20 @@ function VerticalInputLayout({
|
||||
nonInteractive,
|
||||
children,
|
||||
subDescription,
|
||||
...titleLayoutProps
|
||||
title,
|
||||
description,
|
||||
optional,
|
||||
sizePreset = "main-content",
|
||||
}: VerticalLayoutProps) {
|
||||
const content = (
|
||||
<Section gap={0.25} alignItems="start">
|
||||
<TitleLayout {...titleLayoutProps} />
|
||||
<Content
|
||||
title={title}
|
||||
description={description}
|
||||
optional={optional}
|
||||
sizePreset={sizePreset}
|
||||
variant="section"
|
||||
/>
|
||||
{children}
|
||||
{name && <ErrorLayout name={name} />}
|
||||
{subDescription && (
|
||||
@@ -110,7 +124,10 @@ function HorizontalInputLayout({
|
||||
nonInteractive,
|
||||
children,
|
||||
center,
|
||||
...titleLayoutProps
|
||||
title,
|
||||
description,
|
||||
optional,
|
||||
sizePreset = "main-content",
|
||||
}: HorizontalLayoutProps) {
|
||||
const content = (
|
||||
<Section gap={0.25} alignItems="start">
|
||||
@@ -120,7 +137,13 @@ function HorizontalInputLayout({
|
||||
alignItems={center ? "center" : "start"}
|
||||
>
|
||||
<div className="flex flex-col flex-1 self-stretch">
|
||||
<TitleLayout {...titleLayoutProps} />
|
||||
<Content
|
||||
title={title}
|
||||
description={description}
|
||||
optional={optional}
|
||||
sizePreset={sizePreset}
|
||||
variant="section"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col items-end">{children}</div>
|
||||
</Section>
|
||||
@@ -136,80 +159,6 @@ function HorizontalInputLayout({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TitleLayout - A reusable title/description component for form fields
|
||||
*
|
||||
* Renders a title with an optional description and "Optional" indicator.
|
||||
* This is a pure presentational component — it does not render a `<label>`
|
||||
* element. Label semantics are handled by the parent orientation layout
|
||||
* (Vertical/Horizontal) or by the caller.
|
||||
*
|
||||
* Exported as `Title` for convenient usage.
|
||||
*
|
||||
* @param title - The main label text
|
||||
* @param description - Additional helper text shown below the title
|
||||
* @param optional - Whether to show "(Optional)" indicator
|
||||
* @param center - If true, centers the title and description text. Default: false
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* import { Title } from "@/layouts/input-layouts";
|
||||
*
|
||||
* <Title
|
||||
* name="username"
|
||||
* title="Username"
|
||||
* description="Choose a unique username"
|
||||
* optional
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
type TitleLayoutVariants = "primary" | "secondary";
|
||||
export interface TitleLayoutProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
optional?: boolean;
|
||||
center?: boolean;
|
||||
variant?: TitleLayoutVariants;
|
||||
}
|
||||
function TitleLayout({
|
||||
title,
|
||||
description,
|
||||
optional,
|
||||
center,
|
||||
variant = "primary",
|
||||
}: TitleLayoutProps) {
|
||||
return (
|
||||
<Section gap={0} height="fit">
|
||||
<Section
|
||||
flexDirection="row"
|
||||
justifyContent={center ? "center" : "start"}
|
||||
gap={0.25}
|
||||
>
|
||||
<Text
|
||||
mainContentEmphasis={variant === "primary"}
|
||||
mainUiAction={variant === "secondary"}
|
||||
text04
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
{optional && (
|
||||
<Text text03 mainContentMuted>
|
||||
(Optional)
|
||||
</Text>
|
||||
)}
|
||||
</Section>
|
||||
|
||||
{description && (
|
||||
<Section alignItems={center ? "center" : "start"}>
|
||||
<Text secondaryBody text03>
|
||||
{description}
|
||||
</Text>
|
||||
</Section>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ErrorLayout - Displays Formik field validation errors
|
||||
*
|
||||
@@ -280,7 +229,6 @@ function ErrorTextLayout({ children, type = "error" }: ErrorTextLayoutProps) {
|
||||
export {
|
||||
VerticalInputLayout as Vertical,
|
||||
HorizontalInputLayout as Horizontal,
|
||||
TitleLayout as Title,
|
||||
ErrorLayout as Error,
|
||||
ErrorTextLayout,
|
||||
};
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
|
||||
import { SvgEmpty } from "@opal/icons";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
import { LineItemLayout } from "@/layouts/general-layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { Content } from "@opal/layouts";
|
||||
import { IconProps } from "@opal/types";
|
||||
|
||||
export interface EmptyMessageProps {
|
||||
@@ -46,12 +47,18 @@ export default function EmptyMessage({
|
||||
}: EmptyMessageProps) {
|
||||
return (
|
||||
<Card variant="tertiary">
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={Icon}
|
||||
title={title}
|
||||
description={description}
|
||||
variant="tertiary-muted"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
/>
|
||||
{description && (
|
||||
<Text secondaryBody text03>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "@/refresh-components/Collapsible";
|
||||
import { Button } from "@opal/components";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import { Content } from "@opal/layouts";
|
||||
import { SvgFold, SvgExpand } from "@opal/icons";
|
||||
import { WithoutStyles } from "@/types";
|
||||
|
||||
@@ -198,15 +198,13 @@ const Header = React.forwardRef<HTMLDivElement, SimpleCollapsibleHeaderProps>(
|
||||
className="flex flex-row items-center justify-between gap-4 cursor-pointer select-none"
|
||||
{...props}
|
||||
>
|
||||
<div ref={boundingRef} className="flex flex-col w-full">
|
||||
<Text mainContentEmphasis text04>
|
||||
{title}
|
||||
</Text>
|
||||
{description && (
|
||||
<Text secondaryBody text03>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
<div ref={boundingRef} className="w-full">
|
||||
<Content
|
||||
title={title}
|
||||
description={description}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
icon={open ? SvgFold : SvgExpand}
|
||||
@@ -237,7 +235,7 @@ Header.displayName = "SimpleCollapsible.Header";
|
||||
* </SimpleCollapsible>
|
||||
* ```
|
||||
*/
|
||||
const Content = React.forwardRef<
|
||||
const ContentPanel = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
WithoutStyles<React.HTMLAttributes<HTMLDivElement>>
|
||||
>(({ children, ...props }, ref) => {
|
||||
@@ -249,9 +247,9 @@ const Content = React.forwardRef<
|
||||
</CollapsibleContent>
|
||||
);
|
||||
});
|
||||
Content.displayName = "SimpleCollapsible.Content";
|
||||
ContentPanel.displayName = "SimpleCollapsible.Content";
|
||||
|
||||
export default Object.assign(Root, {
|
||||
Header,
|
||||
Content,
|
||||
Content: ContentPanel,
|
||||
});
|
||||
|
||||
@@ -136,8 +136,8 @@ const InputTypeIn = React.forwardRef<HTMLInputElement, InputTypeInProps>(
|
||||
}}
|
||||
>
|
||||
{leftSearchIcon && (
|
||||
<div className="pr-2">
|
||||
<div className="pl-1">
|
||||
<div className="pr-2 pl-1">
|
||||
<div className="pl-[2px]">
|
||||
<SvgSearch className="w-[1rem] h-[1rem] stroke-text-02" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,8 @@ import Button from "@/refresh-components/buttons/Button";
|
||||
import { Button as OpalButton } from "@opal/components";
|
||||
import { SvgProgressCircle, SvgX } from "@opal/icons";
|
||||
import { Card } from "@/refresh-components/cards";
|
||||
import { LineItemLayout, Section } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
|
||||
interface OnboardingHeaderProps {
|
||||
state: OnboardingState;
|
||||
@@ -40,11 +41,15 @@ const OnboardingHeader = React.memo(
|
||||
|
||||
return (
|
||||
<Card padding={0.5} data-label="onboarding-header">
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={(props) => (
|
||||
<SvgProgressCircle value={iconPercentage} {...props} />
|
||||
)}
|
||||
title={STEP_CONFIG[onboardingState.currentStep].title}
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
paddingVariant="sm"
|
||||
rightChildren={
|
||||
stepButtonText ? (
|
||||
<Section flexDirection="row">
|
||||
@@ -70,9 +75,6 @@ const OnboardingHeader = React.memo(
|
||||
/>
|
||||
)
|
||||
}
|
||||
variant="tertiary-muted"
|
||||
reducedPadding
|
||||
center
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,8 @@ import Button from "@/refresh-components/buttons/Button";
|
||||
import { FINAL_SETUP_CONFIG } from "@/refresh-components/onboarding/constants";
|
||||
import { FinalStepItemProps } from "@/refresh-components/onboarding/types";
|
||||
import { SvgExternalLink } from "@opal/icons";
|
||||
import { LineItemLayout, Section } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { ContentAction } from "@opal/layouts";
|
||||
import { Card } from "@/refresh-components/cards";
|
||||
|
||||
const FinalStepItem = React.memo(
|
||||
@@ -23,10 +24,13 @@ const FinalStepItem = React.memo(
|
||||
|
||||
return (
|
||||
<Card padding={0.25} variant="secondary">
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={Icon}
|
||||
title={title}
|
||||
description={description}
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
paddingVariant="sm"
|
||||
rightChildren={
|
||||
<Link href={buttonHref as Route} {...linkProps}>
|
||||
<Button tertiary rightIcon={SvgExternalLink}>
|
||||
@@ -34,8 +38,6 @@ const FinalStepItem = React.memo(
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
reducedPadding
|
||||
variant="tertiary"
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -89,6 +89,7 @@ import AgentKnowledgePane from "@/sections/knowledge/AgentKnowledgePane";
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import { useSettingsContext } from "@/providers/SettingsProvider";
|
||||
import { useUser } from "@/providers/UserProvider";
|
||||
import SimpleLoader from "@/refresh-components/loaders/SimpleLoader";
|
||||
|
||||
interface AgentIconEditorProps {
|
||||
existingAgent?: FullPersona | null;
|
||||
@@ -313,7 +314,11 @@ function MCPServerCard({
|
||||
description={server.description}
|
||||
icon={getActionIcon(server.server_url, server.name)}
|
||||
rightChildren={
|
||||
<GeneralLayouts.Section flexDirection="row" gap={0.5}>
|
||||
<GeneralLayouts.Section
|
||||
flexDirection="row"
|
||||
gap={0.5}
|
||||
alignItems="start"
|
||||
>
|
||||
<EnabledCount
|
||||
enabledCount={enabledCount}
|
||||
totalCount={enabledTools.length}
|
||||
@@ -352,18 +357,9 @@ function MCPServerCard({
|
||||
</ActionsLayouts.Header>
|
||||
{isLoading ? (
|
||||
<ActionsLayouts.Content>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<Card key={index} padding={0.75}>
|
||||
<GeneralLayouts.LineItemLayout
|
||||
// We provide dummy values here.
|
||||
// The `loading` prop will always render a pulsing box instead, so the dummy-values will actually NOT be rendered at all.
|
||||
title="..."
|
||||
description="..."
|
||||
rightChildren={<></>}
|
||||
loading
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
<GeneralLayouts.Section padding={1}>
|
||||
<SimpleLoader />
|
||||
</GeneralLayouts.Section>
|
||||
</ActionsLayouts.Content>
|
||||
) : (
|
||||
enabledTools.length > 0 &&
|
||||
@@ -1168,7 +1164,6 @@ export default function AgentEditorPage({
|
||||
<InputLayouts.Vertical
|
||||
name="agent_avatar"
|
||||
title="Agent Avatar"
|
||||
center
|
||||
>
|
||||
<AgentIconEditor existingAgent={existingAgent} />
|
||||
</InputLayouts.Vertical>
|
||||
|
||||
@@ -3,11 +3,8 @@
|
||||
import { useRef, useCallback, useEffect, useState } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import * as InputLayouts from "@/layouts/input-layouts";
|
||||
import {
|
||||
LineItemLayout,
|
||||
Section,
|
||||
AttachmentItemLayout,
|
||||
} from "@/layouts/general-layouts";
|
||||
import { Section, AttachmentItemLayout } from "@/layouts/general-layouts";
|
||||
import { Content, ContentAction } from "@opal/layouts";
|
||||
import { Formik, Form } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import {
|
||||
@@ -263,7 +260,12 @@ function GeneralSettings() {
|
||||
|
||||
<Section gap={2}>
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Profile" />
|
||||
<Content
|
||||
title="Profile"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Full Name"
|
||||
@@ -319,7 +321,12 @@ function GeneralSettings() {
|
||||
</Section>
|
||||
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Appearance" />
|
||||
<Content
|
||||
title="Appearance"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Color Mode"
|
||||
@@ -424,7 +431,12 @@ function GeneralSettings() {
|
||||
<Separator noPadding />
|
||||
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Danger Zone" />
|
||||
<Content
|
||||
title="Danger Zone"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Delete All Chats"
|
||||
@@ -769,7 +781,12 @@ function ChatPreferencesSettings() {
|
||||
return (
|
||||
<Section gap={2}>
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Chats" />
|
||||
<Content
|
||||
title="Chats"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Default Model"
|
||||
@@ -849,7 +866,12 @@ function ChatPreferencesSettings() {
|
||||
limit={500}
|
||||
/>
|
||||
</InputLayouts.Vertical>
|
||||
<InputLayouts.Title title="Memory" />
|
||||
<Content
|
||||
title="Memory"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Reference Stored Memories"
|
||||
@@ -890,7 +912,12 @@ function ChatPreferencesSettings() {
|
||||
</Section>
|
||||
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Prompt Shortcuts" />
|
||||
<Content
|
||||
title="Prompt Shortcuts"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Use Prompt Shortcuts"
|
||||
@@ -1215,7 +1242,12 @@ function AccountsAccessSettings() {
|
||||
|
||||
<Section gap={2}>
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Accounts" />
|
||||
<Content
|
||||
title="Accounts"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
<Card>
|
||||
<InputLayouts.Horizontal
|
||||
title="Email"
|
||||
@@ -1247,7 +1279,12 @@ function AccountsAccessSettings() {
|
||||
|
||||
{showTokensSection && (
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Access Tokens" />
|
||||
<Content
|
||||
title="Access Tokens"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
{canCreateTokens ? (
|
||||
<Card padding={0.25}>
|
||||
<Section gap={0}>
|
||||
@@ -1363,10 +1400,12 @@ function IndexedConnectorCard({ source, isActive }: IndexedConnectorCardProps) {
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={sourceMetadata.icon}
|
||||
title={sourceMetadata.displayName}
|
||||
description={isActive ? "Connected" : "Paused"}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
@@ -1440,12 +1479,15 @@ function FederatedConnectorCard({
|
||||
)}
|
||||
|
||||
<Card padding={0.5}>
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={sourceMetadata.icon}
|
||||
title={sourceMetadata.displayName}
|
||||
description={
|
||||
connector.has_oauth_token ? "Connected" : "Not connected"
|
||||
}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
paddingVariant="sm"
|
||||
rightChildren={
|
||||
connector.has_oauth_token ? (
|
||||
<OpalButton
|
||||
@@ -1466,7 +1508,6 @@ function FederatedConnectorCard({
|
||||
</Button>
|
||||
) : undefined
|
||||
}
|
||||
reducedPadding
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
@@ -1515,7 +1556,12 @@ function ConnectorsSettings() {
|
||||
return (
|
||||
<Section gap={2}>
|
||||
<Section gap={0.75} justifyContent="start">
|
||||
<InputLayouts.Title title="Connectors" />
|
||||
<Content
|
||||
title="Connectors"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
widthVariant="full"
|
||||
/>
|
||||
{hasConnectors ? (
|
||||
<>
|
||||
{/* Indexed Connectors */}
|
||||
|
||||
@@ -7,7 +7,7 @@ import useSWR from "swr";
|
||||
import { errorHandlingFetcher } from "@/lib/fetcher";
|
||||
import * as SettingsLayouts from "@/layouts/settings-layouts";
|
||||
import * as InputLayouts from "@/layouts/input-layouts";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import Card from "@/refresh-components/cards/Card";
|
||||
import Separator from "@/refresh-components/Separator";
|
||||
import SimpleCollapsible from "@/refresh-components/SimpleCollapsible";
|
||||
@@ -400,7 +400,11 @@ function ChatPreferencesForm() {
|
||||
|
||||
{/* Features */}
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Features" />
|
||||
<Content
|
||||
title="Features"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
<Card>
|
||||
<SimpleTooltip
|
||||
tooltip={
|
||||
@@ -460,7 +464,11 @@ function ChatPreferencesForm() {
|
||||
<Section gap={1.5}>
|
||||
{/* Connectors */}
|
||||
<Section gap={0.75}>
|
||||
<InputLayouts.Title title="Connectors" />
|
||||
<Content
|
||||
title="Connectors"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
|
||||
<Section
|
||||
flexDirection="row"
|
||||
|
||||
@@ -31,7 +31,8 @@ import { useCreateModal } from "@/refresh-components/contexts/ModalContext";
|
||||
import ShareAgentModal from "@/sections/modals/ShareAgentModal";
|
||||
import AgentViewerModal from "@/sections/modals/AgentViewerModal";
|
||||
import { toast } from "@/hooks/useToast";
|
||||
import { LineItemLayout, CardItemLayout } from "@/layouts/general-layouts";
|
||||
import { CardItemLayout } from "@/layouts/general-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import { Interactive } from "@opal/core";
|
||||
import { Card } from "@/refresh-components/cards";
|
||||
|
||||
@@ -193,12 +194,14 @@ export default function AgentCard({ agent }: AgentCardProps) {
|
||||
<div className="bg-background-tint-01 p-1 flex flex-row items-end justify-between w-full">
|
||||
{/* Left side - creator and actions */}
|
||||
<div className="flex flex-col gap-1 py-1 px-2">
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgUser}
|
||||
title={agent.owner?.email || "Onyx"}
|
||||
variant="mini"
|
||||
sizePreset="secondary"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
/>
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgActions}
|
||||
title={
|
||||
agent.tools.length > 0
|
||||
@@ -207,7 +210,9 @@ export default function AgentCard({ agent }: AgentCardProps) {
|
||||
}`
|
||||
: "No Actions"
|
||||
}
|
||||
variant="mini"
|
||||
sizePreset="secondary"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import React, {
|
||||
useEffect,
|
||||
} from "react";
|
||||
import * as GeneralLayouts from "@/layouts/general-layouts";
|
||||
import { Content } from "@opal/layouts";
|
||||
import * as TableLayouts from "@/layouts/table-layouts";
|
||||
import * as InputLayouts from "@/layouts/input-layouts";
|
||||
import { Card } from "@/refresh-components/cards";
|
||||
@@ -318,10 +319,11 @@ function DocumentSetsTableContent({
|
||||
header: "Name",
|
||||
sortable: true,
|
||||
render: (ds) => (
|
||||
<GeneralLayouts.LineItemLayout
|
||||
<Content
|
||||
icon={SvgFolder}
|
||||
title={ds.name}
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -443,10 +445,11 @@ function RecentFilesTableContent({
|
||||
header: "Name",
|
||||
sortable: true,
|
||||
render: (file) => (
|
||||
<GeneralLayouts.LineItemLayout
|
||||
<Content
|
||||
icon={SvgFiles}
|
||||
title={file.name}
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -1135,9 +1138,11 @@ export default function AgentKnowledgePane({
|
||||
|
||||
return (
|
||||
<GeneralLayouts.Section gap={0.5} alignItems="stretch" height="auto">
|
||||
<InputLayouts.Title
|
||||
<Content
|
||||
title="Knowledge"
|
||||
description="Add specific connectors and documents for this agent to use to inform its responses."
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
|
||||
<Card>
|
||||
|
||||
@@ -6,7 +6,8 @@ import type { Route } from "next";
|
||||
import { FullPersona } from "@/app/admin/assistants/interfaces";
|
||||
import { useModal } from "@/refresh-components/contexts/ModalContext";
|
||||
import Modal from "@/refresh-components/Modal";
|
||||
import { Section, LineItemLayout } from "@/layouts/general-layouts";
|
||||
import { Section } from "@/layouts/general-layouts";
|
||||
import { Content, ContentAction } from "@opal/layouts";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import AgentAvatar from "@/refresh-components/avatars/AgentAvatar";
|
||||
import Separator from "@/refresh-components/Separator";
|
||||
@@ -26,7 +27,7 @@ import useMcpServersForAgentEditor from "@/hooks/useMcpServersForAgentEditor";
|
||||
import { getActionIcon } from "@/lib/tools/mcpUtils";
|
||||
import { MCPServer, ToolSnapshot } from "@/lib/tools/interfaces";
|
||||
import EmptyMessage from "@/refresh-components/EmptyMessage";
|
||||
import { Horizontal, Title } from "@/layouts/input-layouts";
|
||||
import { Horizontal } from "@/layouts/input-layouts";
|
||||
import Switch from "@/refresh-components/inputs/Switch";
|
||||
import Button from "@/refresh-components/buttons/Button";
|
||||
import { SEARCH_PARAM_NAMES } from "@/app/app/services/searchParams";
|
||||
@@ -36,10 +37,7 @@ import { formatMmDdYyyy } from "@/lib/dateUtils";
|
||||
import { useProjectsContext } from "@/providers/ProjectsContext";
|
||||
import { FileCard } from "@/sections/cards/FileCard";
|
||||
import DocumentSetCard from "@/sections/cards/DocumentSetCard";
|
||||
import {
|
||||
getLLMProviderOverrideForPersona,
|
||||
getDisplayName,
|
||||
} from "@/lib/llm/utils";
|
||||
import { getDisplayName } from "@/lib/llm/utils";
|
||||
import { useLLMProviders } from "@/lib/hooks/useLLMProviders";
|
||||
import { Interactive } from "@opal/core";
|
||||
|
||||
@@ -60,11 +58,12 @@ function ViewerMCPServerCard({ server, tools }: ViewerMCPServerCardProps) {
|
||||
<ExpandableCard.Root isFolded={folded} onFoldedChange={setFolded}>
|
||||
<ExpandableCard.Header>
|
||||
<div className="p-2">
|
||||
<LineItemLayout
|
||||
<ContentAction
|
||||
icon={serverIcon}
|
||||
title={server.name}
|
||||
description={server.description}
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
rightChildren={
|
||||
<Button
|
||||
internal
|
||||
@@ -74,7 +73,6 @@ function ViewerMCPServerCard({ server, tools }: ViewerMCPServerCardProps) {
|
||||
{folded ? "Expand" : "Fold"}
|
||||
</Button>
|
||||
}
|
||||
center
|
||||
/>
|
||||
</div>
|
||||
</ExpandableCard.Header>
|
||||
@@ -82,10 +80,11 @@ function ViewerMCPServerCard({ server, tools }: ViewerMCPServerCardProps) {
|
||||
<ActionsLayouts.Content>
|
||||
{tools.map((tool) => (
|
||||
<Section key={tool.id} padding={0.25}>
|
||||
<LineItemLayout
|
||||
<Content
|
||||
title={tool.display_name}
|
||||
description={tool.description}
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
</Section>
|
||||
))}
|
||||
@@ -104,12 +103,12 @@ function ViewerOpenApiToolCard({ tool }: { tool: ToolSnapshot }) {
|
||||
<ExpandableCard.Root>
|
||||
<ExpandableCard.Header>
|
||||
<div className="p-2">
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgActions}
|
||||
title={tool.display_name}
|
||||
description={tool.description}
|
||||
variant="secondary"
|
||||
center
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
</div>
|
||||
</ExpandableCard.Header>
|
||||
@@ -258,25 +257,27 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
{/* Metadata */}
|
||||
<Section flexDirection="row" justifyContent="start">
|
||||
{!agent.is_default_persona && (
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgStar}
|
||||
title="Featured"
|
||||
variant="tertiary"
|
||||
width="fit"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
/>
|
||||
)}
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgUser}
|
||||
title={agent.owner?.email ?? "Onyx"}
|
||||
variant="tertiary-muted"
|
||||
width="fit"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
/>
|
||||
{agent.is_public && (
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgOrganization}
|
||||
title="Public to your organization"
|
||||
variant="tertiary-muted"
|
||||
width="fit"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
@@ -287,7 +288,11 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
{/* Knowledge */}
|
||||
<Separator noPadding />
|
||||
<Section gap={0.5} alignItems="start">
|
||||
<Title title="Knowledge" />
|
||||
<Content
|
||||
title="Knowledge"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
{hasKnowledge ? (
|
||||
<Section
|
||||
gap={0.5}
|
||||
@@ -340,10 +345,11 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
<SimpleCollapsible.Content>
|
||||
<Section gap={0.5} alignItems="start">
|
||||
{agent.system_prompt && (
|
||||
<LineItemLayout
|
||||
<Content
|
||||
title="Instructions"
|
||||
description={agent.system_prompt}
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
variant="section"
|
||||
/>
|
||||
)}
|
||||
{defaultModel && (
|
||||
@@ -351,7 +357,7 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
title="Default Model"
|
||||
description="This model will be used by Onyx by default in your chats."
|
||||
nonInteractive
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
>
|
||||
<Text>{defaultModel}</Text>
|
||||
</Horizontal>
|
||||
@@ -361,7 +367,7 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
title="Knowledge Cutoff Date"
|
||||
description="Documents with a last-updated date prior to this will be ignored."
|
||||
nonInteractive
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
>
|
||||
<Text mainUiMono>
|
||||
{formatMmDdYyyy(agent.search_start_date)}
|
||||
@@ -372,7 +378,7 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
title="Overwrite System Prompts"
|
||||
description='Remove the base system prompt which includes useful instructions (e.g. "You can use Markdown tables"). This may affect response quality.'
|
||||
nonInteractive
|
||||
variant="secondary"
|
||||
sizePreset="main-ui"
|
||||
>
|
||||
<Switch disabled checked={agent.replace_base_system_prompt} />
|
||||
</Horizontal>
|
||||
@@ -384,7 +390,12 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
{agent.task_prompt && (
|
||||
<>
|
||||
<Separator noPadding />
|
||||
<Title title="Prompt Reminders" description={agent.task_prompt} />
|
||||
<Content
|
||||
title="Prompt Reminders"
|
||||
description={agent.task_prompt}
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -392,7 +403,11 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
{agent.starter_messages && agent.starter_messages.length > 0 && (
|
||||
<>
|
||||
<Separator noPadding />
|
||||
<Title title="Conversation Starters" />
|
||||
<Content
|
||||
title="Conversation Starters"
|
||||
sizePreset="main-content"
|
||||
variant="section"
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-1 w-full">
|
||||
{agent.starter_messages.map((starter, index) => (
|
||||
<Interactive.Base
|
||||
@@ -401,10 +416,13 @@ export default function AgentViewerModal({ agent }: AgentViewerModalProps) {
|
||||
prominence="tertiary"
|
||||
>
|
||||
<Interactive.Container>
|
||||
<LineItemLayout
|
||||
<Content
|
||||
icon={SvgBubbleText}
|
||||
title={starter.message}
|
||||
variant="tertiary-muted"
|
||||
sizePreset="main-ui"
|
||||
variant="body"
|
||||
prominence="muted"
|
||||
widthVariant="full"
|
||||
/>
|
||||
</Interactive.Container>
|
||||
</Interactive.Base>
|
||||
|
||||
206
widget/package-lock.json
generated
206
widget/package-lock.json
generated
@@ -477,9 +477,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz",
|
||||
"integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
|
||||
"integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -491,9 +491,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz",
|
||||
"integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -505,9 +505,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz",
|
||||
"integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -519,9 +519,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz",
|
||||
"integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -533,9 +533,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz",
|
||||
"integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -547,9 +547,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz",
|
||||
"integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -561,9 +561,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz",
|
||||
"integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
|
||||
"integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -575,9 +575,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz",
|
||||
"integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
|
||||
"integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -589,9 +589,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -603,9 +603,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz",
|
||||
"integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -617,9 +617,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -631,9 +631,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-musl": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz",
|
||||
"integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -645,9 +645,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -659,9 +659,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-musl": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz",
|
||||
"integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -673,9 +673,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -687,9 +687,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz",
|
||||
"integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -701,9 +701,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -715,9 +715,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -729,9 +729,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz",
|
||||
"integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -743,9 +743,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openbsd-x64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz",
|
||||
"integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -757,9 +757,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz",
|
||||
"integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -771,9 +771,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz",
|
||||
"integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -785,9 +785,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz",
|
||||
"integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -799,9 +799,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz",
|
||||
"integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -813,9 +813,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz",
|
||||
"integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1055,9 +1055,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.55.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
|
||||
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
|
||||
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1071,31 +1071,31 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.55.1",
|
||||
"@rollup/rollup-android-arm64": "4.55.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.55.1",
|
||||
"@rollup/rollup-darwin-x64": "4.55.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.55.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.55.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.55.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.55.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.55.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.55.1",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.55.1",
|
||||
"@rollup/rollup-linux-loong64-musl": "4.55.1",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.55.1",
|
||||
"@rollup/rollup-linux-ppc64-musl": "4.55.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.55.1",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.55.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.55.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.55.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.55.1",
|
||||
"@rollup/rollup-openbsd-x64": "4.55.1",
|
||||
"@rollup/rollup-openharmony-arm64": "4.55.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.55.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.55.1",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.55.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.55.1",
|
||||
"@rollup/rollup-android-arm-eabi": "4.59.0",
|
||||
"@rollup/rollup-android-arm64": "4.59.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.59.0",
|
||||
"@rollup/rollup-darwin-x64": "4.59.0",
|
||||
"@rollup/rollup-freebsd-arm64": "4.59.0",
|
||||
"@rollup/rollup-freebsd-x64": "4.59.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.59.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-loong64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-ppc64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.59.0",
|
||||
"@rollup/rollup-openbsd-x64": "4.59.0",
|
||||
"@rollup/rollup-openharmony-arm64": "4.59.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.59.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.59.0",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.59.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.59.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user