feat(resources): render anonymous volume names readably in the volume browser (#1429)

Anonymous Docker volumes carry a raw 64-character hex name, which is correct
data but unreadable in the volume browser crumb, sheet title, and table row.

Detect 64-hex names and show a short prefix (e.g. 079dfda49f2c…) in the table
cell and sheet title, with the full name available on hover and an "anonymous"
chip so the truncation is self-explanatory. The volume browser sheet adds a
band that keeps the full hash visible and copyable. Named volumes still display
in full. The name is passed verbatim to the API; only the rendered label changes.
This commit is contained in:
Anso
2026-06-24 19:05:40 -04:00
committed by GitHub
parent 2c70e11485
commit 401980ffa3
8 changed files with 232 additions and 32 deletions
@@ -0,0 +1,34 @@
import { describe, it, expect } from 'vitest';
import { isAnonymousVolumeName, shortVolumeLabel } from '../volumeName';
const ANON = '079dfda49f2c483f80f1d4f6b1865be55af54a0298507a0e588aae551134ba62';
describe('isAnonymousVolumeName', () => {
it('treats a 64 lowercase hex name as anonymous', () => {
expect(isAnonymousVolumeName(ANON)).toBe(true);
});
it('treats a friendly named volume as not anonymous', () => {
expect(isAnonymousVolumeName('app_pgdata')).toBe(false);
});
it('rejects names that are not exactly 64 chars', () => {
expect(isAnonymousVolumeName(ANON.slice(0, 63))).toBe(false);
expect(isAnonymousVolumeName(ANON + 'a')).toBe(false);
});
it('rejects uppercase hex and non-hex characters', () => {
expect(isAnonymousVolumeName(ANON.toUpperCase())).toBe(false);
expect(isAnonymousVolumeName('z'.repeat(64))).toBe(false);
});
});
describe('shortVolumeLabel', () => {
it('truncates an anonymous name to a 12-char prefix plus an ellipsis', () => {
expect(shortVolumeLabel(ANON)).toBe('079dfda49f2c…');
});
it('returns a named volume verbatim', () => {
expect(shortVolumeLabel('app_pgdata')).toBe('app_pgdata');
});
});
+25
View File
@@ -0,0 +1,25 @@
// Helpers for rendering Docker volume names readably in the Resources Hub.
//
// A standard Docker anonymous volume name is exactly 64 lowercase hex characters
// (the same shape as a SHA-256 digest). Named volumes are arbitrary strings.
//
// Note: a user who deliberately names a volume with 64 lowercase hex characters
// is also treated as anonymous for display only. Nothing is lost: the full name
// stays available via the title tooltip (and the copy button in the volume
// browser sheet), and it is always passed verbatim to the API.
const ANON_VOLUME_RE = /^[0-9a-f]{64}$/;
/** True when the name looks like an anonymous Docker volume (64 lowercase hex chars). */
export function isAnonymousVolumeName(name: string): boolean {
return ANON_VOLUME_RE.test(name);
}
/**
* A short, readable label for a volume name. Anonymous names are truncated to a
* 12-character prefix with an ellipsis (e.g. `079dfda49f2c…`); named volumes are
* returned verbatim so friendly names keep displaying in full.
*/
export function shortVolumeLabel(name: string): string {
return isAnonymousVolumeName(name) ? `${name.slice(0, 12)}` : name;
}