feat: publish Toolbox 0.17.0 with Colour and Office Tools

This commit is contained in:
2026-09-01 00:54:22 +02:00
parent 01f6c59adf
commit d2d0c9098d
19 changed files with 228 additions and 52 deletions
+22 -1
View File
@@ -48,6 +48,12 @@ describe('portal UI', () => {
expect(
screen.getByTestId('app-card-de.add-ideas.auth-tools')
).toHaveTextContent('OTP & Passkeys');
expect(
screen.getByTestId('app-card-de.add-ideas.colour-tools')
).toHaveTextContent('Colour');
expect(
screen.getByTestId('app-card-de.add-ideas.office-tools')
).toHaveTextContent('Office');
expect(
screen.queryByText(
'Page-level PDF operations performed locally in the browser.'
@@ -416,6 +422,8 @@ describe('portal UI', () => {
'de.add-ideas.svg-tools',
'de.add-ideas.auth-tools',
'de.add-ideas.sudoku-tools',
'de.add-ideas.colour-tools',
'de.add-ideas.office-tools',
],
hidden: [],
theme: 'light',
@@ -436,6 +444,8 @@ describe('portal UI', () => {
screen.getByTestId('app-card-de.add-ideas.svg-tools'),
screen.getByTestId('app-card-de.add-ideas.auth-tools'),
screen.getByTestId('app-card-de.add-ideas.sudoku-tools'),
screen.getByTestId('app-card-de.add-ideas.colour-tools'),
screen.getByTestId('app-card-de.add-ideas.office-tools'),
];
cards.forEach((card, index) => {
const rect = {
@@ -466,7 +476,16 @@ describe('portal UI', () => {
within(tools)
.getAllByRole('heading', { level: 3 })
.map((heading) => heading.textContent)
).toEqual(['XSLT', 'PDF', 'OneNote', 'SVG', 'OTP & Passkeys', 'Sudoku']);
).toEqual([
'XSLT',
'PDF',
'OneNote',
'SVG',
'OTP & Passkeys',
'Sudoku',
'Colour',
'Office',
]);
});
expect(
JSON.parse(localStorage.getItem(PREFERENCES_KEY) ?? '{}').order
@@ -477,6 +496,8 @@ describe('portal UI', () => {
'de.add-ideas.svg-tools',
'de.add-ideas.auth-tools',
'de.add-ideas.sudoku-tools',
'de.add-ideas.colour-tools',
'de.add-ideas.office-tools',
]);
});
+2 -2
View File
@@ -489,9 +489,9 @@ export default function App() {
</span>
</p>
<span>
Portal v0.2.18 ·{' '}
Portal v0.2.19 ·{' '}
<a
href="https://git.add-ideas.de/lotobo/toolbox-portal/src/tag/v0.16.0"
href="https://git.add-ideas.de/lotobo/toolbox-portal/src/tag/v0.17.0"
target="_blank"
rel="noopener noreferrer"
>
+3 -1
View File
@@ -10,7 +10,7 @@ describe('catalogue loading', () => {
const loaded = await loadCatalogue('/toolbox.catalog.json');
expect(loaded.catalogue.name).toBe('add·ideas Toolbox');
expect(loaded.homeUrl).toBe('http://localhost:3000/');
expect(loaded.apps).toHaveLength(6);
expect(loaded.apps).toHaveLength(8);
expect(loaded.apps[0]).toMatchObject({
id: 'de.add-ideas.pdf-tools',
name: 'PDF Workbench',
@@ -43,6 +43,8 @@ describe('catalogue loading', () => {
'de.add-ideas.svg-tools',
'de.add-ideas.auth-tools',
'de.add-ideas.sudoku-tools',
'de.add-ideas.colour-tools',
'de.add-ideas.office-tools',
]);
expect(loaded.unavailable).toHaveLength(1);
expect(loaded.unavailable[0]?.reason).toMatch(/HTTP 404/);
+76
View File
@@ -202,6 +202,76 @@ export const sudokuManifest: ToolboxAppManifest = {
],
};
export const colourManifest: ToolboxAppManifest = {
...sudokuManifest,
id: 'de.add-ideas.colour-tools',
name: 'Colour Tools',
version: '0.1.0',
description:
'Convert, composite, compare and build colours locally in the browser.',
categories: ['graphics', 'design', 'developer'],
tags: ['colour', 'rgba', 'oklch', 'palette', 'gradient', 'contrast'],
requirements: {
secureContext: false,
workers: true,
indexedDb: false,
crossOriginIsolated: false,
topLevelContext: false,
},
privacy: {
processing: 'local',
fileUploads: false,
telemetry: false,
label: 'Colours and images stay in this browser; nothing is uploaded.',
},
source: {
repository: 'https://git.add-ideas.de/lotobo/colour-tools',
license: 'GPL-3.0-or-later',
},
actions: [
{
id: 'source',
label: 'Source',
url: 'https://git.add-ideas.de/lotobo/colour-tools',
},
],
};
export const officeManifest: ToolboxAppManifest = {
...sudokuManifest,
id: 'de.add-ideas.office-tools',
name: 'Office Tools',
version: '0.1.0',
description:
'Open and inspect documents, spreadsheets and presentations locally in the browser.',
categories: ['documents', 'office', 'productivity'],
tags: ['document', 'spreadsheet', 'presentation', 'docx', 'xlsx', 'pptx'],
requirements: {
secureContext: false,
workers: true,
indexedDb: false,
crossOriginIsolated: false,
topLevelContext: false,
},
privacy: {
processing: 'local',
fileUploads: false,
telemetry: false,
label: 'Office files stay in this browser; nothing is uploaded.',
},
source: {
repository: 'https://git.add-ideas.de/lotobo/office-tools',
license: 'GPL-3.0-or-later',
},
actions: [
{
id: 'source',
label: 'Source',
url: 'https://git.add-ideas.de/lotobo/office-tools',
},
],
};
export const catalogue: ToolboxCatalog = {
schemaVersion: 1,
id: 'de.add-ideas.toolbox',
@@ -215,6 +285,8 @@ export const catalogue: ToolboxCatalog = {
{ manifest: './apps/svg/toolbox-app.json', enabled: true },
{ manifest: './apps/auth/toolbox-app.json', enabled: true },
{ manifest: './apps/sudoku/toolbox-app.json', enabled: true },
{ manifest: './apps/colour/toolbox-app.json', enabled: true },
{ manifest: './apps/office/toolbox-app.json', enabled: true },
],
};
@@ -242,6 +314,10 @@ export function catalogueFetch(overrides: Record<string, Response> = {}) {
return Response.json(authManifest);
if (url.pathname.endsWith('/apps/sudoku/toolbox-app.json'))
return Response.json(sudokuManifest);
if (url.pathname.endsWith('/apps/colour/toolbox-app.json'))
return Response.json(colourManifest);
if (url.pathname.endsWith('/apps/office/toolbox-app.json'))
return Response.json(officeManifest);
return new Response('Not found', { status: 404 });
};
}
+24
View File
@@ -63,4 +63,28 @@ describe('compact tool presentation', () => {
expect(shortToolTitle(sudoku)).toBe('Sudoku');
expect(shortToolDescription(sudoku)).toBe('Set, play and solve locally.');
});
it('uses the compact Colour tile copy', () => {
const colour = app(
'de.add-ideas.colour-tools',
'Colour Tools',
'Convert, composite, compare and build colours locally in the browser.'
);
expect(shortToolTitle(colour)).toBe('Colour');
expect(shortToolDescription(colour)).toBe(
'Convert and build colours locally.'
);
});
it('uses the compact Office tile copy', () => {
const office = app(
'de.add-ideas.office-tools',
'Office Tools',
'Open and inspect documents, spreadsheets and presentations locally in the browser.'
);
expect(shortToolTitle(office)).toBe('Office');
expect(shortToolDescription(office)).toBe('Open office files locally.');
});
});
+8
View File
@@ -33,6 +33,14 @@ const PRESENTATION: Record<string, { title: string; description: string }> = {
title: 'Sudoku',
description: 'Set, play and solve locally.',
},
'de.add-ideas.colour-tools': {
title: 'Colour',
description: 'Convert and build colours locally.',
},
'de.add-ideas.office-tools': {
title: 'Office',
description: 'Open office files locally.',
},
};
export function shortToolTitle(app: ResolvedApp): string {