feat: Add collapsable snippets (customizable in user profile)
This commit is contained in:
@@ -1397,6 +1397,8 @@
|
|||||||
"fileColorCodingDesc": "Farbcodierung von Dateien nach Typ: Ordner (rot), Dateien (blau), Symlinks (grün)",
|
"fileColorCodingDesc": "Farbcodierung von Dateien nach Typ: Ordner (rot), Dateien (blau), Symlinks (grün)",
|
||||||
"commandAutocomplete": "Befehlsautovervollständigung",
|
"commandAutocomplete": "Befehlsautovervollständigung",
|
||||||
"commandAutocompleteDesc": "Tab-Taste Autovervollständigung für Terminal-Befehle basierend auf Ihrem Befehlsverlauf aktivieren",
|
"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",
|
"currentPassword": "Aktuelles Passwort",
|
||||||
"passwordChangedSuccess": "Passwort erfolgreich geändert! Bitte melden Sie sich erneut an.",
|
"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."
|
"failedToChangePassword": "Passwort konnte nicht geändert werden. Bitte überprüfen Sie Ihr aktuelles Passwort und versuchen Sie es erneut."
|
||||||
|
|||||||
@@ -1586,6 +1586,8 @@
|
|||||||
"fileColorCodingDesc": "Color-code files by type: folders (red), files (blue), symlinks (green)",
|
"fileColorCodingDesc": "Color-code files by type: folders (red), files (blue), symlinks (green)",
|
||||||
"commandAutocomplete": "Command Autocomplete",
|
"commandAutocomplete": "Command Autocomplete",
|
||||||
"commandAutocompleteDesc": "Enable Tab key autocomplete suggestions for terminal commands based on your command history",
|
"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",
|
"currentPassword": "Current Password",
|
||||||
"passwordChangedSuccess": "Password changed successfully! Please log in again.",
|
"passwordChangedSuccess": "Password changed successfully! Please log in again.",
|
||||||
"failedToChangePassword": "Failed to change password. Please check your current password and try again."
|
"failedToChangePassword": "Failed to change password. Please check your current password and try again."
|
||||||
|
|||||||
@@ -1391,6 +1391,8 @@
|
|||||||
"fileColorCodingDesc": "Codage couleur des fichiers par type : dossiers (rouge), fichiers (bleu), liens symboliques (vert)",
|
"fileColorCodingDesc": "Codage couleur des fichiers par type : dossiers (rouge), fichiers (bleu), liens symboliques (vert)",
|
||||||
"commandAutocomplete": "Autocomplétion des commandes",
|
"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",
|
"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",
|
"currentPassword": "Mot de passe actuel",
|
||||||
"passwordChangedSuccess": "Mot de passe modifié avec succès ! Veuillez vous reconnecter.",
|
"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."
|
"failedToChangePassword": "Échec de la modification du mot de passe. Vérifiez votre mot de passe actuel et réessayez."
|
||||||
|
|||||||
@@ -1345,6 +1345,8 @@
|
|||||||
"fileColorCodingDesc": "Codificar arquivos por cores por tipo: pastas (vermelho), arquivos (azul), links simbólicos (verde)",
|
"fileColorCodingDesc": "Codificar arquivos por cores por tipo: pastas (vermelho), arquivos (azul), links simbólicos (verde)",
|
||||||
"commandAutocomplete": "Autocompletar Comandos",
|
"commandAutocomplete": "Autocompletar Comandos",
|
||||||
"commandAutocompleteDesc": "Ativar sugestões de autocompletar com a tecla Tab para comandos do terminal baseado no seu histórico",
|
"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",
|
"currentPassword": "Senha Atual",
|
||||||
"passwordChangedSuccess": "Senha alterada com sucesso! Por favor, faça login novamente.",
|
"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."
|
"failedToChangePassword": "Falha ao alterar a senha. Por favor, verifique sua senha atual e tente novamente."
|
||||||
|
|||||||
@@ -1484,6 +1484,8 @@
|
|||||||
"fileColorCodingDesc": "Цветовая кодировка файлов по типу: папки (красный), файлы (синий), символические ссылки (зелёный)",
|
"fileColorCodingDesc": "Цветовая кодировка файлов по типу: папки (красный), файлы (синий), символические ссылки (зелёный)",
|
||||||
"commandAutocomplete": "Автодополнение команд",
|
"commandAutocomplete": "Автодополнение команд",
|
||||||
"commandAutocompleteDesc": "Включить автодополнение команд терминала клавишей Tab на основе вашей истории команд",
|
"commandAutocompleteDesc": "Включить автодополнение команд терминала клавишей Tab на основе вашей истории команд",
|
||||||
|
"defaultSnippetFoldersCollapsed": "Сворачивать папки сниппетов по умолчанию",
|
||||||
|
"defaultSnippetFoldersCollapsedDesc": "Если включено, все папки сниппетов будут свёрнуты при открытии вкладки сниппетов",
|
||||||
"currentPassword": "Текущий пароль",
|
"currentPassword": "Текущий пароль",
|
||||||
"passwordChangedSuccess": "Пароль успешно изменен! Пожалуйста, войдите снова.",
|
"passwordChangedSuccess": "Пароль успешно изменен! Пожалуйста, войдите снова.",
|
||||||
"failedToChangePassword": "Не удалось изменить пароль. Пожалуйста, проверьте ваш текущий пароль и попробуйте снова."
|
"failedToChangePassword": "Не удалось изменить пароль. Пожалуйста, проверьте ваш текущий пароль и попробуйте снова."
|
||||||
|
|||||||
@@ -1517,6 +1517,8 @@
|
|||||||
"fileColorCodingDesc": "按类型对文件进行颜色编码:文件夹(红色)、文件(蓝色)、符号链接(绿色)",
|
"fileColorCodingDesc": "按类型对文件进行颜色编码:文件夹(红色)、文件(蓝色)、符号链接(绿色)",
|
||||||
"commandAutocomplete": "命令自动补全",
|
"commandAutocomplete": "命令自动补全",
|
||||||
"commandAutocompleteDesc": "启用基于命令历史记录的 Tab 键终端命令自动补全建议",
|
"commandAutocompleteDesc": "启用基于命令历史记录的 Tab 键终端命令自动补全建议",
|
||||||
|
"defaultSnippetFoldersCollapsed": "默认折叠代码片段文件夹",
|
||||||
|
"defaultSnippetFoldersCollapsedDesc": "启用后,打开代码片段标签时所有文件夹将默认折叠",
|
||||||
"currentPassword": "当前密码",
|
"currentPassword": "当前密码",
|
||||||
"passwordChangedSuccess": "密码修改成功!请重新登录。",
|
"passwordChangedSuccess": "密码修改成功!请重新登录。",
|
||||||
"failedToChangePassword": "修改密码失败。请检查您当前的密码并重试。"
|
"failedToChangePassword": "修改密码失败。请检查您当前的密码并重试。"
|
||||||
|
|||||||
@@ -197,9 +197,11 @@ export function SSHToolsSidebar({
|
|||||||
);
|
);
|
||||||
const [draggedSnippet, setDraggedSnippet] = useState<Snippet | null>(null);
|
const [draggedSnippet, setDraggedSnippet] = useState<Snippet | null>(null);
|
||||||
const [dragOverFolder, setDragOverFolder] = useState<string | null>(null);
|
const [dragOverFolder, setDragOverFolder] = useState<string | null>(null);
|
||||||
const [collapsedFolders, setCollapsedFolders] = useState<Set<string>>(
|
const [collapsedFolders, setCollapsedFolders] = useState<Set<string>>(() => {
|
||||||
new Set(),
|
const shouldCollapse =
|
||||||
);
|
localStorage.getItem("defaultSnippetFoldersCollapsed") !== "false";
|
||||||
|
return shouldCollapse ? new Set() : new Set();
|
||||||
|
});
|
||||||
const [showFolderDialog, setShowFolderDialog] = useState(false);
|
const [showFolderDialog, setShowFolderDialog] = useState(false);
|
||||||
const [editingFolder, setEditingFolder] = useState<SnippetFolder | null>(
|
const [editingFolder, setEditingFolder] = useState<SnippetFolder | null>(
|
||||||
null,
|
null,
|
||||||
@@ -351,6 +353,55 @@ export function SSHToolsSidebar({
|
|||||||
}
|
}
|
||||||
}, [isOpen, activeTab]);
|
}, [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) => {
|
const handleMouseDown = (e: React.MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsResizing(true);
|
setIsResizing(true);
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ export function UserProfile({
|
|||||||
const [commandAutocomplete, setCommandAutocomplete] = useState<boolean>(
|
const [commandAutocomplete, setCommandAutocomplete] = useState<boolean>(
|
||||||
localStorage.getItem("commandAutocomplete") !== "false",
|
localStorage.getItem("commandAutocomplete") !== "false",
|
||||||
);
|
);
|
||||||
|
const [defaultSnippetFoldersCollapsed, setDefaultSnippetFoldersCollapsed] =
|
||||||
|
useState<boolean>(
|
||||||
|
localStorage.getItem("defaultSnippetFoldersCollapsed") !== "false",
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUserInfo();
|
fetchUserInfo();
|
||||||
@@ -154,6 +158,12 @@ export function UserProfile({
|
|||||||
localStorage.setItem("commandAutocomplete", enabled.toString());
|
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) => {
|
const handleDeleteAccount = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setDeleteLoading(true);
|
setDeleteLoading(true);
|
||||||
@@ -391,6 +401,25 @@ export function UserProfile({
|
|||||||
</div>
|
</div>
|
||||||
</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="mt-6 pt-6 border-t border-dark-border">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user