diff --git a/src/components/features/settings/components/WorkspaceSettingsSelector.ts b/src/components/features/settings/components/WorkspaceSettingsSelector.ts new file mode 100644 index 00000000..35ae44cb --- /dev/null +++ b/src/components/features/settings/components/WorkspaceSettingsSelector.ts @@ -0,0 +1,148 @@ +import { Menu, setIcon } from "obsidian"; +import type TaskProgressBarPlugin from "@/index"; +import { WorkspaceData } from "@/experimental/v2/types/workspace"; +import { t } from "@/translations/helper"; +import { TaskProgressBarSettingTab } from "@/setting"; + +export class WorkspaceSettingsSelector { + private containerEl: HTMLElement; + private plugin: TaskProgressBarPlugin; + private settingTab: TaskProgressBarSettingTab; + private currentWorkspaceId: string; + private buttonEl: HTMLElement; + + constructor( + containerEl: HTMLElement, + plugin: TaskProgressBarPlugin, + settingTab: TaskProgressBarSettingTab + ) { + this.containerEl = containerEl; + this.plugin = plugin; + this.settingTab = settingTab; + this.currentWorkspaceId = + plugin.workspaceManager?.getActiveWorkspace().id || ""; + + this.render(); + } + + private render() { + // Create workspace selector container + const selectorContainer = this.containerEl.createDiv({ + cls: "workspace-settings-selector", + }); + + if (!this.plugin.workspaceManager) return; + + const currentWorkspace = + this.plugin.workspaceManager.getActiveWorkspace(); + + this.buttonEl = selectorContainer.createDiv({ + cls: "workspace-settings-selector-button", + }); + + // Workspace icon + const workspaceIcon = this.buttonEl.createDiv({ + cls: "workspace-icon", + }); + setIcon(workspaceIcon, currentWorkspace.icon || "layers"); + + // Workspace name + const workspaceName = this.buttonEl.createSpan({ + cls: "workspace-name", + text: currentWorkspace.name, + }); + + // Dropdown arrow + const dropdownIcon = this.buttonEl.createDiv({ + cls: "workspace-dropdown-icon", + }); + setIcon(dropdownIcon, "chevron-down"); + + // Click handler + this.buttonEl.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + this.showWorkspaceMenu(e); + }); + } + + private showWorkspaceMenu(event: MouseEvent) { + if (!this.plugin.workspaceManager) return; + + const menu = new Menu(); + const workspaces = this.plugin.workspaceManager.getAllWorkspaces(); + const currentWorkspace = + this.plugin.workspaceManager.getActiveWorkspace(); + + // Add workspace items for switching + workspaces.forEach((workspace) => { + menu.addItem((item) => { + item.setTitle(workspace.name) + .setIcon(workspace.icon || "layers") + .onClick(async () => { + await this.switchWorkspace(workspace.id); + }); + + // Mark current workspace with checkmark + if (workspace.id === currentWorkspace.id) { + item.setChecked(true); + } + }); + }); + + // Add separator + menu.addSeparator(); + + // Add "Manage Workspaces..." option to navigate to settings + menu.addItem((item) => { + item.setTitle(t("Manage Workspaces...")) + .setIcon("settings") + .onClick(() => { + // Navigate to workspace settings tab + this.settingTab.switchToTab("workspaces"); + }); + }); + + menu.showAtMouseEvent(event); + } + + private async switchWorkspace(workspaceId: string) { + if (!this.plugin.workspaceManager) return; + + // Switch workspace + await this.plugin.workspaceManager.setActiveWorkspace(workspaceId); + this.currentWorkspaceId = workspaceId; + + // Update button display + this.updateDisplay(); + + // Trigger settings reload to reflect workspace change + await this.plugin.saveSettings(); + this.settingTab.applySettingsUpdate(); + } + + private updateDisplay() { + if (!this.plugin.workspaceManager || !this.buttonEl) return; + + const currentWorkspace = + this.plugin.workspaceManager.getActiveWorkspace(); + + // Update icon + const iconEl = this.buttonEl.querySelector(".workspace-icon"); + if (iconEl) { + iconEl.empty(); + setIcon(iconEl as HTMLElement, currentWorkspace.icon || "layers"); + } + + // Update name + const nameEl = this.buttonEl.querySelector(".workspace-name"); + if (nameEl) { + nameEl.textContent = currentWorkspace.name; + } + } + + public setWorkspace(workspaceId: string) { + this.currentWorkspaceId = workspaceId; + this.updateDisplay(); + } +} \ No newline at end of file diff --git a/src/styles/workspace-settings-selector.css b/src/styles/workspace-settings-selector.css new file mode 100644 index 00000000..cc6d117c --- /dev/null +++ b/src/styles/workspace-settings-selector.css @@ -0,0 +1,130 @@ +/* Workspace Settings Selector Styles */ + +/* Main container for the header bar */ +.tg-settings-header-bar { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 20px; + width: 100%; +} + +/* Container for workspace selector */ +.tg-workspace-selector-container { + flex-shrink: 0; +} + +/* Workspace selector button */ +.workspace-settings-selector { + display: inline-block; +} + +.workspace-settings-selector-button { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px; + background-color: var(--background-modifier-form-field); + border: 1px solid var(--background-modifier-border); + border-radius: 6px; + cursor: pointer; + transition: all 0.15s ease; + min-width: 150px; + height: 34px; /* Match search bar height */ +} + +.workspace-settings-selector-button:hover { + background-color: var(--background-modifier-hover); + border-color: var(--background-modifier-border-hover); +} + +.workspace-settings-selector-button:active { + background-color: var(--background-modifier-active-hover); +} + +/* Workspace icon */ +.workspace-settings-selector-button .workspace-icon { + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + flex-shrink: 0; +} + +.workspace-settings-selector-button .workspace-icon svg { + width: 16px; + height: 16px; + fill: var(--text-muted); +} + +/* Workspace name */ +.workspace-settings-selector-button .workspace-name { + flex: 1; + font-size: 14px; + color: var(--text-normal); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Dropdown arrow icon */ +.workspace-settings-selector-button .workspace-dropdown-icon { + display: flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + flex-shrink: 0; + margin-left: auto; +} + +.workspace-settings-selector-button .workspace-dropdown-icon svg { + width: 12px; + height: 12px; + fill: var(--text-muted); + transition: transform 0.15s ease; +} + +.workspace-settings-selector-button:hover .workspace-dropdown-icon svg { + fill: var(--text-normal); +} + +/* Adjust search container to take remaining space */ +.tg-settings-header-bar .tg-settings-search-container { + flex: 1; + max-width: none; +} + +/* Ensure search input container fills width */ +.tg-settings-header-bar .tg-settings-search-input-container { + width: 100%; +} + +/* Main container adjustments */ +.tg-settings-main-container { + width: 100%; +} + +/* Ensure search results appear below the header bar */ +.tg-settings-main-container .tg-settings-search-results { + margin-top: 8px; +} + +/* Mobile responsive adjustments */ +@media (max-width: 768px) { + .tg-settings-header-bar { + flex-direction: column; + align-items: stretch; + gap: 8px; + } + + .workspace-settings-selector-button { + width: 100%; + min-width: unset; + } + + .tg-settings-header-bar .tg-settings-search-container { + width: 100%; + } +}