diff --git a/package-lock.json b/package-lock.json index 372400f..1e49ca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "anvil", - "version": "0.0.11", + "version": "0.0.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "anvil", - "version": "0.0.11", + "version": "0.0.12", "dependencies": { "@floating-ui/dom": "1.6.8", + "@fontsource/spline-sans-mono": "5.0.20", "axios": "1.7.2", "cheerio": "1.0.0-rc.12" }, @@ -2202,6 +2203,11 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" }, + "node_modules/@fontsource/spline-sans-mono": { + "version": "5.0.20", + "resolved": "https://registry.npmjs.org/@fontsource/spline-sans-mono/-/spline-sans-mono-5.0.20.tgz", + "integrity": "sha512-4u23nOkNK1B6rkmNfiodQaMu9CKtKzrK/lTEAhBuQT08cTm6544uTQSoH8ssylDbdyYZZAWyVA2Mua/TdIuoxQ==" + }, "node_modules/@formatjs/ecma402-abstract": { "version": "1.18.2", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz", diff --git a/package.json b/package.json index 3f3c8e7..79ba940 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "anvil", - "version": "0.0.11", + "version": "0.0.12", "private": true, "scripts": { "dev": "vite dev", @@ -75,6 +75,7 @@ "type": "module", "dependencies": { "@floating-ui/dom": "1.6.8", + "@fontsource/spline-sans-mono": "5.0.20", "axios": "1.7.2", "cheerio": "1.0.0-rc.12" } diff --git a/src/lib/components/molecules/Settings.svelte b/src/lib/components/molecules/Settings.svelte index c915308..173b039 100644 --- a/src/lib/components/molecules/Settings.svelte +++ b/src/lib/components/molecules/Settings.svelte @@ -13,6 +13,7 @@ You should have received a copy of the GNU Affero General Public License along w + +
+
+ {$_('settings.ssh_gpg_keys.headline')} +
+
+
+
+ {$_('settings.ssh_gpg_keys.ssh.headline')} +
+
+ + {#each ssh_keys as key} +
+ + {key.title} + {key.fingerprint} + +
+ {/each} +
+ + + +
+ +
+
+ {$_('settings.ssh_gpg_keys.gpg.headline')} +
+
+ + {#each gpg_keys as key} +
+ + {key.title} + {key.fingerprint} + +
+ {/each} +
+ + + +
+
+
diff --git a/src/lib/i18n/locales/bg.json b/src/lib/i18n/locales/bg.json index 9776dec..e403b4f 100644 --- a/src/lib/i18n/locales/bg.json +++ b/src/lib/i18n/locales/bg.json @@ -228,7 +228,30 @@ } }, "ssh_gpg_keys": { - "label": "" + "gpg": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + }, + "headline": "", + "label": "", + "ssh": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + } } } } diff --git a/src/lib/i18n/locales/de.json b/src/lib/i18n/locales/de.json index e2aa512..e16ce33 100644 --- a/src/lib/i18n/locales/de.json +++ b/src/lib/i18n/locales/de.json @@ -228,7 +228,30 @@ } }, "ssh_gpg_keys": { - "label": "" + "gpg": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + }, + "headline": "", + "label": "", + "ssh": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + } } } } diff --git a/src/lib/i18n/locales/en.json b/src/lib/i18n/locales/en.json index 87086ae..d61f59e 100644 --- a/src/lib/i18n/locales/en.json +++ b/src/lib/i18n/locales/en.json @@ -228,7 +228,30 @@ } }, "ssh_gpg_keys": { - "label": "SSH/GPG Keys" + "gpg": { + "add": "Add GPG key", + "headline": "GPG", + "key": { + "placeholder": "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'." + }, + "remove": "Remove", + "title": { + "placeholder": "Title" + } + }, + "headline": "SSH/GPG Keys", + "label": "SSH/GPG Keys", + "ssh": { + "add": "Add SSH key", + "headline": "SSH", + "key": { + "placeholder": "Begins with 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519', 'sk-ecdsa-sha2-nistp256@openssh.com', or 'sk-ssh-ed25519@openssh.com'" + }, + "remove": "Remove", + "title": { + "placeholder": "Title" + } + } } } } diff --git a/src/lib/i18n/locales/he.json b/src/lib/i18n/locales/he.json index 7a796e8..6724254 100644 --- a/src/lib/i18n/locales/he.json +++ b/src/lib/i18n/locales/he.json @@ -228,7 +228,30 @@ } }, "ssh_gpg_keys": { - "label": "" + "gpg": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + }, + "headline": "", + "label": "", + "ssh": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + } } } } diff --git a/src/lib/i18n/locales/pl.json b/src/lib/i18n/locales/pl.json index b1082b1..5a093ed 100644 --- a/src/lib/i18n/locales/pl.json +++ b/src/lib/i18n/locales/pl.json @@ -228,7 +228,30 @@ } }, "ssh_gpg_keys": { - "label": "" + "gpg": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + }, + "headline": "", + "label": "", + "ssh": { + "add": "", + "headline": "", + "key": { + "placeholder": "" + }, + "remove": "", + "title": { + "placeholder": "" + } + } } } } diff --git a/stories/icons/Key24.stories.ts b/stories/icons/Key24.stories.ts new file mode 100644 index 0000000..4f210eb --- /dev/null +++ b/stories/icons/Key24.stories.ts @@ -0,0 +1,36 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Eric Liu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + */ + +/* + * SPDX-FileCopyrightText: 2020 - 2024 Eric Liu + * SPDX-License-Identifier: MIT + */ + +import type { Meta, StoryObj } from '@storybook/svelte'; +import { Key24 } from 'svelte-octicons'; + +const meta = { + title: 'Icons/Key24', + component: Key24, + tags: ['autodocs'], + argTypes: { + fill: { + control: 'color' + } + } +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Plain: Story = {}; diff --git a/stories/molecules/SetttingsKeys.stories.ts b/stories/molecules/SetttingsKeys.stories.ts new file mode 100644 index 0000000..98f63ff --- /dev/null +++ b/stories/molecules/SetttingsKeys.stories.ts @@ -0,0 +1,26 @@ +/* Stories for SettingsKeys molecule. + * Copyright (C) 2024 André Jaenisch + * SPDX-FileCopyrightText: 2024 André Jaenisch + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this program. If not, see . + */ + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import SettingsKeys from '$lib/components/molecules/SettingsKeys.svelte'; + +const meta = { + title: 'Molecules/SettingsKeys', + component: SettingsKeys, + tags: ['autodocs'] +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Plain: Story = {}; diff --git a/tailwind.config.js b/tailwind.config.js index 49bb458..a54981f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -24,7 +24,20 @@ export default { join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}') ], theme: { - extend: {} + extend: {}, + fontFamily: { + mono: [ + 'ui-monospace', + 'Spline Sans Mono', + 'SFMono-Regular', + 'Menlo', + 'Monaco', + 'Consolas', + 'Liberation Mono', + 'Courier New', + 'monospace' + ] + } }, plugins: [require('@tailwindcss/typography'), forms, skeleton] }; diff --git a/tests/components/molecules/SettingsKeys.test.ts b/tests/components/molecules/SettingsKeys.test.ts new file mode 100644 index 0000000..df80210 --- /dev/null +++ b/tests/components/molecules/SettingsKeys.test.ts @@ -0,0 +1,95 @@ +/* Component test for SettingsKeys molecule. + * Copyright (C) 2024 André Jaenisch + * SPDX-FileCopyrightText: 2024 André Jaenisch + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License along with this program. If not, see . + */ + +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/svelte'; +import { init, locale, register } from 'svelte-i18n'; + +import SettingsKeys from '../../../src/lib/components/molecules/SettingsKeys.svelte'; +import enMessages from '../../../src/lib/i18n/locales/en.json'; + +describe('SettingsKeys.svelte', () => { + beforeEach(() => { + register('en', () => import('../../../src/lib/i18n/locales/en.json')); + init({ fallbackLocale: 'en', initialLocale: 'en' }); + locale.set('en'); + }); + + it('should mount', () => { + // Arrange + // Nothing to prepare + + // Act + const { container } = render(SettingsKeys); + + // Assert + expect(container).toBeTruthy(); + }); + + describe('SSH', () => { + it('should have a way to remove a SSH key', () => { + // Arrange + // Currently those keys are hardcoded + const numberOfKeys = 2 /* SSH */ + 1; /* GPG */ + + // Act + render(SettingsKeys); + + // Assert + expect( + screen.getAllByRole('button', { name: enMessages.settings.ssh_gpg_keys.ssh.remove }) + ).toHaveLength(numberOfKeys); + }); + + it('should have a way to add a SSH key', () => { + // Arrange + // Nothing to prepare + + // Act + render(SettingsKeys); + + // Assert + expect( + screen.getByRole('button', { name: enMessages.settings.ssh_gpg_keys.ssh.add }) + ).toBeInTheDocument(); + }); + }); + + describe('GPG', () => { + it('should have a way to remove a GPG key', () => { + // Arrange + // Currently those keys are hardcoded + const numberOfKeys = 2 /* SSH */ + 1; /* GPG */ + + // Act + render(SettingsKeys); + + // Assert + expect( + screen.getAllByRole('button', { name: enMessages.settings.ssh_gpg_keys.gpg.remove }) + ).toHaveLength(numberOfKeys); + }); + + it('should have a way to add a GPG key', () => { + // Arrange + // Nothing to prepare + + // Act + render(SettingsKeys); + + // Assert + expect( + screen.getByRole('button', { name: enMessages.settings.ssh_gpg_keys.gpg.add }) + ).toBeInTheDocument(); + }); + }); +});