Make AI sidebar wider when left sidebar is collapsed
This commit is contained in:
@@ -154,6 +154,48 @@ module ApplicationHelper
|
||||
markdown.render(text).html_safe
|
||||
end
|
||||
|
||||
# Determines the starting widths of each panel depending on the user's sidebar preferences
|
||||
def app_sidebar_config(user)
|
||||
left_sidebar_showing = user.show_sidebar?
|
||||
right_sidebar_showing = user.show_ai_sidebar?
|
||||
|
||||
content_max_width = if !left_sidebar_showing && !right_sidebar_showing
|
||||
1024 # 5xl
|
||||
elsif left_sidebar_showing && !right_sidebar_showing
|
||||
896 # 4xl
|
||||
else
|
||||
768 # 3xl
|
||||
end
|
||||
|
||||
left_panel_min_width = 320
|
||||
left_panel_max_width = 320
|
||||
right_panel_min_width = 400
|
||||
right_panel_max_width = 550
|
||||
|
||||
left_panel_width = left_sidebar_showing ? left_panel_min_width : 0
|
||||
right_panel_width = if right_sidebar_showing
|
||||
left_sidebar_showing ? right_panel_min_width : right_panel_max_width
|
||||
else
|
||||
0
|
||||
end
|
||||
|
||||
{
|
||||
left_panel: {
|
||||
is_open: left_sidebar_showing,
|
||||
initial_width: left_panel_width,
|
||||
min_width: left_panel_min_width,
|
||||
max_width: left_panel_max_width
|
||||
},
|
||||
right_panel: {
|
||||
is_open: right_sidebar_showing,
|
||||
initial_width: right_panel_width,
|
||||
min_width: right_panel_min_width,
|
||||
max_width: right_panel_max_width
|
||||
},
|
||||
content_max_width: content_max_width
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
def calculate_total(item, money_method, negate)
|
||||
items = item.reject { |i| i.respond_to?(:entryable) && i.entryable.transfer? }
|
||||
|
||||
@@ -55,7 +55,6 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
#scrollToBottom = () => {
|
||||
console.log("scrolling to bottom");
|
||||
this.messagesTarget.scrollTop = this.messagesTarget.scrollHeight;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,64 +4,67 @@ import { Controller } from "@hotwired/stimulus";
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
userId: String,
|
||||
side: { type: String, default: "left" }, // "left" or "right"
|
||||
config: Object,
|
||||
};
|
||||
|
||||
static targets = ["leftPanel", "rightPanel", "content"];
|
||||
|
||||
toggle(event) {
|
||||
// Determine which sidebar to toggle based on the event or default to the side value
|
||||
const side = event.currentTarget.dataset.side || this.sideValue;
|
||||
|
||||
// Get the appropriate panel based on the side
|
||||
const panel =
|
||||
side === "left" ? this.leftPanelTarget : this.rightPanelTarget;
|
||||
|
||||
// Toggle the sidebar visibility
|
||||
if (side === "left") {
|
||||
panel.classList.toggle("w-0");
|
||||
panel.classList.toggle("opacity-0");
|
||||
panel.classList.toggle("w-80");
|
||||
panel.classList.toggle("opacity-100");
|
||||
} else {
|
||||
// For right panel, use the correct width class
|
||||
panel.classList.toggle("w-0");
|
||||
panel.classList.toggle("opacity-0");
|
||||
panel.classList.toggle("w-[400px]");
|
||||
panel.classList.toggle("opacity-100");
|
||||
}
|
||||
|
||||
// Determine sidebar states
|
||||
const leftSidebarOpen = !this.leftPanelTarget.classList.contains("w-0");
|
||||
const rightSidebarOpen = !this.rightPanelTarget.classList.contains("w-0");
|
||||
|
||||
// Adjust content width based on sidebar states
|
||||
this.adjustContentWidth(leftSidebarOpen, rightSidebarOpen);
|
||||
|
||||
// Save user preference
|
||||
this.saveUserPreference(
|
||||
side,
|
||||
side === "left" ? leftSidebarOpen : rightSidebarOpen,
|
||||
);
|
||||
initialize() {
|
||||
this.leftPanelOpen = this.configValue.left_panel.is_open;
|
||||
this.rightPanelOpen = this.configValue.right_panel.is_open;
|
||||
}
|
||||
|
||||
adjustContentWidth(leftSidebarOpen, rightSidebarOpen) {
|
||||
// Remove all possible width classes first
|
||||
this.contentTarget.classList.remove("max-w-3xl", "max-w-4xl", "max-w-5xl");
|
||||
|
||||
// Apply the appropriate width class based on sidebar states
|
||||
if (leftSidebarOpen && rightSidebarOpen) {
|
||||
this.contentTarget.classList.add("max-w-3xl");
|
||||
} else if (leftSidebarOpen || rightSidebarOpen) {
|
||||
this.contentTarget.classList.add("max-w-4xl");
|
||||
} else {
|
||||
this.contentTarget.classList.add("max-w-5xl");
|
||||
}
|
||||
toggleLeftPanel() {
|
||||
this.leftPanelOpen = !this.leftPanelOpen;
|
||||
this.#updatePanelWidths();
|
||||
this.#persistPreference("show_sidebar", this.leftPanelOpen);
|
||||
}
|
||||
|
||||
saveUserPreference(side, isOpen) {
|
||||
const preferenceField =
|
||||
side === "left" ? "show_sidebar" : "show_ai_sidebar";
|
||||
toggleRightPanel() {
|
||||
this.rightPanelOpen = !this.rightPanelOpen;
|
||||
this.#updatePanelWidths();
|
||||
this.#persistPreference("show_ai_sidebar", this.rightPanelOpen);
|
||||
}
|
||||
|
||||
#updatePanelWidths() {
|
||||
this.contentTarget.style.maxWidth = `${this.#contentMaxWidth()}px`;
|
||||
this.leftPanelTarget.style.width = `${this.#leftPanelWidth()}px`;
|
||||
this.rightPanelTarget.style.width = `${this.#rightPanelWidth()}px`;
|
||||
}
|
||||
|
||||
#leftPanelWidth() {
|
||||
if (this.leftPanelOpen) {
|
||||
return this.configValue.left_panel.min_width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#rightPanelWidth() {
|
||||
if (this.rightPanelOpen) {
|
||||
if (this.leftPanelOpen) {
|
||||
return this.configValue.right_panel.min_width;
|
||||
}
|
||||
|
||||
return this.configValue.right_panel.max_width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#contentMaxWidth() {
|
||||
if (!this.leftPanelOpen && !this.rightPanelOpen) {
|
||||
return 1024;
|
||||
}
|
||||
|
||||
if (this.leftPanelOpen && !this.rightPanelOpen) {
|
||||
return 896;
|
||||
}
|
||||
|
||||
return 768;
|
||||
}
|
||||
|
||||
#persistPreference(field, value) {
|
||||
fetch(`/users/${this.userIdValue}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
@@ -70,7 +73,7 @@ export default class extends Controller {
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
[`user[${preferenceField}]`]: isOpen,
|
||||
[`user[${field}]`]: value,
|
||||
}).toString(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<nav class="flex items-center gap-2 mb-6">
|
||||
<% if sidebar_toggle_enabled %>
|
||||
<button data-action="sidebar#toggle" data-side="left" class="p-2 inline-flex rounded-lg items-center justify-center hover:bg-gray-100 cursor-pointer">
|
||||
<button data-action="sidebar#toggleLeftPanel" class="p-2 inline-flex rounded-lg items-center justify-center hover:bg-gray-100 cursor-pointer">
|
||||
<%= icon("panel-left", color: "gray") %>
|
||||
</button>
|
||||
<% end %>
|
||||
@@ -23,9 +23,11 @@
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto">
|
||||
<button data-action="sidebar#toggle" data-side="right" class="p-2 inline-flex rounded-lg items-center justify-center hover:bg-gray-100 cursor-pointer" title="Toggle AI Assistant">
|
||||
<%= icon("panel-right", color: "gray") %>
|
||||
</button>
|
||||
</div>
|
||||
<% if sidebar_toggle_enabled %>
|
||||
<div class="ml-auto">
|
||||
<button data-action="sidebar#toggleRightPanel" class="p-2 inline-flex rounded-lg items-center justify-center hover:bg-gray-100 cursor-pointer" title="Toggle AI Assistant">
|
||||
<%= icon("panel-right", color: "gray") %>
|
||||
</button>
|
||||
</div>
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<%= yield :head %>
|
||||
</head>
|
||||
|
||||
<body class="h-full antialiased" data-controller="sidebar" data-sidebar-user-id-value="<%= Current.user&.id %>">
|
||||
<body class="h-full antialiased">
|
||||
<div class="fixed z-50 bottom-6 left-24 w-80">
|
||||
<div id="notification-tray" class="space-y-1 w-full">
|
||||
<%= render_flash_notifications %>
|
||||
|
||||
Reference in New Issue
Block a user