Auto collapse snippet folders #448

Merged
LukeGus merged 4 commits from dev-collapsed-snippets into dev-1.10.0 2025-12-16 20:13:08 +00:00
10 changed files with 102 additions and 10 deletions

View File

@@ -1,8 +1,8 @@
cask "termix" do
version "VERSION_PLACEHOLDER"
sha256 "CHECKSUM_PLACEHOLDER"
version "1.9.0"
sha256 "8fedd242b3cae1ebfd0c391a36f1c246a26ecac258b02478ee8dea2f33cd6d96"
url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_#{version}_dmg.dmg"
url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_dmg.dmg"
name "Termix"
desc "Web-based server management platform with SSH terminal, tunneling, and file editing"
homepage "https://github.com/Termix-SSH/Termix"

View File

@@ -80,16 +80,16 @@ Supported Devices:
- Windows (x64/ia32)
- Portable
- MSI Installer
- Chocolatey Package Manager (coming soon)
- Chocolatey Package Manager
- Linux (x64/ia32)
- Portable
- AppImage
- Deb
- Flatpak (coming soon)
- Flatpak
- macOS (x64/ia32 on v12.0+)
- Apple App Store (coming soon)
- Apple App Store
- DMG
- Homebrew (coming soon)
- Homebrew
- iOS/iPadOS (v15.1+)
- Apple App Store
- ISO

View File

@@ -1397,6 +1397,8 @@
"fileColorCodingDesc": "Farbcodierung von Dateien nach Typ: Ordner (rot), Dateien (blau), Symlinks (grün)",
"commandAutocomplete": "Befehlsautovervollständigung",
"commandAutocompleteDesc": "Tab-Taste Autovervollständigung für Terminal-Befehle basierend auf Ihrem Befehlsverlauf aktivieren",
"defaultSnippetFoldersCollapsed": "Snippet-Ordner standardmäßig einklappen",
"defaultSnippetFoldersCollapsedDesc": "Wenn aktiviert, werden alle Snippet-Ordner beim Öffnen der Snippet-Registerkarte eingeklappt",
"currentPassword": "Aktuelles Passwort",
"passwordChangedSuccess": "Passwort erfolgreich geändert! Bitte melden Sie sich erneut an.",
"failedToChangePassword": "Passwort konnte nicht geändert werden. Bitte überprüfen Sie Ihr aktuelles Passwort und versuchen Sie es erneut."

View File

@@ -1586,6 +1586,8 @@
"fileColorCodingDesc": "Color-code files by type: folders (red), files (blue), symlinks (green)",
"commandAutocomplete": "Command Autocomplete",
"commandAutocompleteDesc": "Enable Tab key autocomplete suggestions for terminal commands based on your command history",
"defaultSnippetFoldersCollapsed": "Collapse Snippet Folders by Default",
"defaultSnippetFoldersCollapsedDesc": "When enabled, all snippet folders will be collapsed when you open the snippets tab",
"currentPassword": "Current Password",
"passwordChangedSuccess": "Password changed successfully! Please log in again.",
"failedToChangePassword": "Failed to change password. Please check your current password and try again."

View File

@@ -1391,6 +1391,8 @@
"fileColorCodingDesc": "Codage couleur des fichiers par type : dossiers (rouge), fichiers (bleu), liens symboliques (vert)",
"commandAutocomplete": "Autocomplétion des commandes",
"commandAutocompleteDesc": "Activer les suggestions d'autocomplétion avec la touche Tab pour les commandes du terminal basées sur votre historique",
"defaultSnippetFoldersCollapsed": "Réduire les dossiers de snippets par défaut",
"defaultSnippetFoldersCollapsedDesc": "Lorsque cette option est activée, tous les dossiers de snippets seront réduits à l'ouverture de l'onglet snippets",
"currentPassword": "Mot de passe actuel",
"passwordChangedSuccess": "Mot de passe modifié avec succès ! Veuillez vous reconnecter.",
"failedToChangePassword": "Échec de la modification du mot de passe. Vérifiez votre mot de passe actuel et réessayez."

View File

@@ -1345,6 +1345,8 @@
"fileColorCodingDesc": "Codificar arquivos por cores por tipo: pastas (vermelho), arquivos (azul), links simbólicos (verde)",
"commandAutocomplete": "Autocompletar Comandos",
"commandAutocompleteDesc": "Ativar sugestões de autocompletar com a tecla Tab para comandos do terminal baseado no seu histórico",
"defaultSnippetFoldersCollapsed": "Recolher Pastas de Snippets por Padrão",
"defaultSnippetFoldersCollapsedDesc": "Quando ativado, todas as pastas de snippets serão recolhidas ao abrir a aba de snippets",
"currentPassword": "Senha Atual",
"passwordChangedSuccess": "Senha alterada com sucesso! Por favor, faça login novamente.",
"failedToChangePassword": "Falha ao alterar a senha. Por favor, verifique sua senha atual e tente novamente."

View File

@@ -1484,6 +1484,8 @@
"fileColorCodingDesc": "Цветовая кодировка файлов по типу: папки (красный), файлы (синий), символические ссылки (зелёный)",
"commandAutocomplete": "Автодополнение команд",
"commandAutocompleteDesc": "Включить автодополнение команд терминала клавишей Tab на основе вашей истории команд",
"defaultSnippetFoldersCollapsed": "Сворачивать папки сниппетов по умолчанию",
"defaultSnippetFoldersCollapsedDesc": "Если включено, все папки сниппетов будут свёрнуты при открытии вкладки сниппетов",
"currentPassword": "Текущий пароль",
"passwordChangedSuccess": "Пароль успешно изменен! Пожалуйста, войдите снова.",
"failedToChangePassword": "Не удалось изменить пароль. Пожалуйста, проверьте ваш текущий пароль и попробуйте снова."

View File

@@ -1517,6 +1517,8 @@
"fileColorCodingDesc": "按类型对文件进行颜色编码:文件夹(红色)、文件(蓝色)、符号链接(绿色)",
"commandAutocomplete": "命令自动补全",
"commandAutocompleteDesc": "启用基于命令历史记录的 Tab 键终端命令自动补全建议",
"defaultSnippetFoldersCollapsed": "默认折叠代码片段文件夹",
"defaultSnippetFoldersCollapsedDesc": "启用后,打开代码片段标签时所有文件夹将默认折叠",
"currentPassword": "当前密码",
"passwordChangedSuccess": "密码修改成功!请重新登录。",
"failedToChangePassword": "修改密码失败。请检查您当前的密码并重试。"

View File

@@ -197,9 +197,11 @@ export function SSHToolsSidebar({
);
const [draggedSnippet, setDraggedSnippet] = useState<Snippet | null>(null);
const [dragOverFolder, setDragOverFolder] = useState<string | null>(null);
const [collapsedFolders, setCollapsedFolders] = useState<Set<string>>(
new Set(),
);
const [collapsedFolders, setCollapsedFolders] = useState<Set<string>>(() => {
const shouldCollapse =
localStorage.getItem("defaultSnippetFoldersCollapsed") !== "false";
return shouldCollapse ? new Set() : new Set();
});
const [showFolderDialog, setShowFolderDialog] = useState(false);
const [editingFolder, setEditingFolder] = useState<SnippetFolder | null>(
null,
@@ -351,6 +353,55 @@ export function SSHToolsSidebar({
}
}, [isOpen, activeTab]);
useEffect(() => {
if (snippetFolders.length > 0) {
const shouldCollapse =
localStorage.getItem("defaultSnippetFoldersCollapsed") !== "false";
if (shouldCollapse) {
const allFolderNames = new Set(snippetFolders.map((f) => f.name));
const uncategorizedSnippets = snippets.filter(
(s) => !s.folder || s.folder === "",
);
if (uncategorizedSnippets.length > 0) {
allFolderNames.add("");
}
setCollapsedFolders(allFolderNames);
} else {
setCollapsedFolders(new Set());
}
}
}, [snippetFolders, snippets]);
useEffect(() => {
const handleSettingChange = () => {
const shouldCollapse =
localStorage.getItem("defaultSnippetFoldersCollapsed") !== "false";
if (shouldCollapse) {
const allFolderNames = new Set(snippetFolders.map((f) => f.name));
const uncategorizedSnippets = snippets.filter(
(s) => !s.folder || s.folder === "",
);
if (uncategorizedSnippets.length > 0) {
allFolderNames.add("");
}
setCollapsedFolders(allFolderNames);
} else {
setCollapsedFolders(new Set());
}
};
window.addEventListener(
"defaultSnippetFoldersCollapsedChanged",
handleSettingChange,
);
return () => {
window.removeEventListener(
"defaultSnippetFoldersCollapsedChanged",
handleSettingChange,
);
};
}, [snippetFolders, snippets]);
const handleMouseDown = (e: React.MouseEvent) => {
e.preventDefault();
setIsResizing(true);

View File

@@ -101,6 +101,10 @@ export function UserProfile({
const [commandAutocomplete, setCommandAutocomplete] = useState<boolean>(
localStorage.getItem("commandAutocomplete") !== "false",
);
const [defaultSnippetFoldersCollapsed, setDefaultSnippetFoldersCollapsed] =
useState<boolean>(
localStorage.getItem("defaultSnippetFoldersCollapsed") !== "false",
);
useEffect(() => {
fetchUserInfo();
@@ -154,6 +158,12 @@ export function UserProfile({
localStorage.setItem("commandAutocomplete", enabled.toString());
};
const handleDefaultSnippetFoldersCollapsedToggle = (enabled: boolean) => {
setDefaultSnippetFoldersCollapsed(enabled);
localStorage.setItem("defaultSnippetFoldersCollapsed", enabled.toString());
window.dispatchEvent(new Event("defaultSnippetFoldersCollapsedChanged"));
};
const handleDeleteAccount = async (e: React.FormEvent) => {
e.preventDefault();
setDeleteLoading(true);
@@ -391,6 +401,25 @@ export function UserProfile({
</div>
</div>
<div className="mt-6 pt-6 border-t border-dark-border">
<div className="flex items-center justify-between">
<div>
<Label className="text-gray-300">
{t("profile.defaultSnippetFoldersCollapsed")}
</Label>
<p className="text-sm text-gray-400 mt-1">
{t("profile.defaultSnippetFoldersCollapsedDesc")}
</p>
</div>
<Switch
checked={defaultSnippetFoldersCollapsed}
onCheckedChange={
handleDefaultSnippetFoldersCollapsedToggle
}
/>
</div>
</div>
<div className="mt-6 pt-6 border-t border-dark-border">
<div className="flex items-center justify-between">
<div>