feat: version 2.8.4 -- catalogo de logos de marca oculto tras boton +

El selector de icono generico de Contraseñas queda igual; el catalogo de marcas (simple-icons)
pasa a estar colapsado por defecto detras de un boton "+", y se abre solo si la entrada ya
tenia un logo de marca asignado.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-01 15:12:00 -05:00
parent 79a2e7f6d8
commit de5984b9d6
7 changed files with 40 additions and 16 deletions
+6
View File
@@ -1,5 +1,11 @@
# Changelog - project.linkedcorp.net # Changelog - project.linkedcorp.net
## [2.8.4] - 2026-10-01
### Changed
- El catálogo de logos de marca en "Contraseñas" queda oculto por defecto, con un botón "+" para
desplegarlo — el catálogo genérico de arriba (los íconos originales) no cambia. Si una entrada
ya tiene un logo de marca asignado, el catálogo se abre solo al editarla.
## [2.8.3] - 2026-10-01 ## [2.8.3] - 2026-10-01
### Fixed ### Fixed
- El PIN de "Contraseñas" (acceso y cambio de PIN) ya no usa `type="password"` en el campo — - El PIN de "Contraseñas" (acceso y cambio de PIN) ya no usa `type="password"` en el campo —
+1 -1
View File
@@ -1 +1 @@
2.8.3 2.8.4
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "project-linkedcorp-backend", "name": "project-linkedcorp-backend",
"version": "2.8.3", "version": "2.8.4",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "src/server.js", "main": "src/server.js",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "project-linkedcorp-frontend", "name": "project-linkedcorp-frontend",
"private": true, "private": true,
"version": "2.8.3", "version": "2.8.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+2
View File
@@ -211,6 +211,7 @@ export const messages = {
vault_field_notes: 'Notas', vault_field_notes: 'Notas',
vault_field_icon: 'Ícono', vault_field_icon: 'Ícono',
vault_icon_auto: 'Automático (inicial del nombre)', vault_icon_auto: 'Automático (inicial del nombre)',
vault_icon_more: 'Más íconos (marcas conocidas)',
vault_password_unchanged_hint: 'Dejar en blanco para no cambiarla', vault_password_unchanged_hint: 'Dejar en blanco para no cambiarla',
vault_reveal: 'Revelar', vault_reveal: 'Revelar',
vault_copy: 'Copiar', vault_copy: 'Copiar',
@@ -542,6 +543,7 @@ export const messages = {
vault_field_notes: 'Notes', vault_field_notes: 'Notes',
vault_field_icon: 'Icon', vault_field_icon: 'Icon',
vault_icon_auto: 'Automatic (name initial)', vault_icon_auto: 'Automatic (name initial)',
vault_icon_more: 'More icons (well-known brands)',
vault_password_unchanged_hint: 'Leave blank to keep it unchanged', vault_password_unchanged_hint: 'Leave blank to keep it unchanged',
vault_reveal: 'Reveal', vault_reveal: 'Reveal',
vault_copy: 'Copy', vault_copy: 'Copy',
@@ -81,6 +81,7 @@ export default function ContrasenasPage() {
const [revealedPassword, setRevealedPassword] = useState(null); const [revealedPassword, setRevealedPassword] = useState(null);
const [passwordVisible, setPasswordVisible] = useState(false); const [passwordVisible, setPasswordVisible] = useState(false);
const [creating, setCreating] = useState(false); const [creating, setCreating] = useState(false);
const [showBrandIcons, setShowBrandIcons] = useState(false);
const [changingPin, setChangingPin] = useState(false); const [changingPin, setChangingPin] = useState(false);
const [pinChangeForm, setPinChangeForm] = useState({ current: '', next: '', next2: '' }); const [pinChangeForm, setPinChangeForm] = useState({ current: '', next: '', next2: '' });
@@ -180,6 +181,7 @@ export default function ContrasenasPage() {
setPasswordVisible(false); setPasswordVisible(false);
setEditing(false); setEditing(false);
setCreating(false); setCreating(false);
setShowBrandIcons(!!BRAND_ICONS[entry.icon_key]);
} }
function openCreate() { function openCreate() {
@@ -189,6 +191,7 @@ export default function ContrasenasPage() {
setPasswordVisible(false); setPasswordVisible(false);
setEditing(true); setEditing(true);
setCreating(true); setCreating(true);
setShowBrandIcons(false);
} }
function closePopup() { function closePopup() {
@@ -357,19 +360,30 @@ export default function ContrasenasPage() {
</button> </button>
))} ))}
</div> </div>
<div className="vault-icon-picker vault-icon-picker-brands"> {showBrandIcons ? (
{Object.entries(BRAND_ICONS).map(([key, icon]) => ( <div className="vault-icon-picker vault-icon-picker-brands">
<button {Object.entries(BRAND_ICONS).map(([key, icon]) => (
type="button" <button
key={key} type="button"
className={`vault-icon-option brand ${form.iconKey === key ? 'selected' : ''}`} key={key}
title={icon.title} className={`vault-icon-option brand ${form.iconKey === key ? 'selected' : ''}`}
onClick={() => setForm((f) => ({ ...f, iconKey: key }))} title={icon.title}
> onClick={() => setForm((f) => ({ ...f, iconKey: key }))}
<BrandSvg icon={icon} size={16} /> >
</button> <BrandSvg icon={icon} size={16} />
))} </button>
</div> ))}
</div>
) : (
<button
type="button"
className="vault-icon-option vault-icon-more"
title={t('vault_icon_more')}
onClick={() => setShowBrandIcons(true)}
>
<Plus size={16} />
</button>
)}
</Field> </Field>
)} )}
+2
View File
@@ -396,6 +396,8 @@ table.list-table { width: 100%; border-collapse: collapse; font-size: .8rem; }
.vault-icon-option.selected { border-color: rgb(var(--accent)); background: rgb(var(--accent) / .15); color: rgb(var(--accent)); } .vault-icon-option.selected { border-color: rgb(var(--accent)); background: rgb(var(--accent) / .15); color: rgb(var(--accent)); }
.vault-icon-option.brand, .vault-card-icon.brand { background: #fff; } .vault-icon-option.brand, .vault-card-icon.brand { background: #fff; }
.vault-icon-option.brand.selected { border-color: rgb(var(--accent)); } .vault-icon-option.brand.selected { border-color: rgb(var(--accent)); }
.vault-icon-option.vault-icon-more { border-style: dashed; color: rgb(var(--muted)); }
.vault-icon-option.vault-icon-more:hover { color: rgb(var(--accent)); }
/* --- Overlay de actualizacion (ver UpdaterPanel.jsx) --- /* --- Overlay de actualizacion (ver UpdaterPanel.jsx) ---
Bloquea toda la pantalla (no solo el panel) mientras corre scripts/apply-update.sh, porque el Bloquea toda la pantalla (no solo el panel) mientras corre scripts/apply-update.sh, porque el