feat(monorepo): restructure web components and update configurations
CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 27s
CI / web (push) Successful in 38s
CI / go (push) Successful in 2m36s
CI / bird2 (push) Successful in 15s
CI / release (push) Failing after 3m7s
CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 27s
CI / web (push) Successful in 38s
CI / go (push) Successful in 2m36s
CI / bird2 (push) Successful in 15s
CI / release (push) Failing after 3m7s
Refactored the project structure to support a monorepo setup, moving the web application to `apps/web/` and updating related configurations. Adjusted pre-commit hooks to use `pnpm` for linting and formatting. Updated CI workflows to reflect the new directory structure and dependencies. Removed legacy files and configurations from the previous `web/` directory, streamlining the project for better maintainability and clarity.
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<script lang="ts">
|
||||
import { apiMutate } from '$lib/api/client.js';
|
||||
import type { BgpCommunity, DomainEntry, DomainEntryCreate } from '$lib/api/types.js';
|
||||
import {
|
||||
communityLabel,
|
||||
communityOptionLabel,
|
||||
fromNullableSelect,
|
||||
NONE_OPTION,
|
||||
nullableSelectValue
|
||||
} from '$lib/components/modules/module-helpers.js';
|
||||
import { Button } from '@evobgp/ui/components/button/index.js';
|
||||
import { Input } from '@evobgp/ui/components/input/index.js';
|
||||
import { Label } from '@evobgp/ui/components/label/index.js';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogFooter
|
||||
} from '@evobgp/ui/components/dialog/index.js';
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger
|
||||
} from '@evobgp/ui/components/select/index.js';
|
||||
import { notify, notifyApiError } from '$lib/ui/app/toast.js';
|
||||
|
||||
type Props = {
|
||||
open: boolean;
|
||||
moduleId: string;
|
||||
edit: DomainEntry | null;
|
||||
communities: BgpCommunity[];
|
||||
onSaved: () => void | Promise<void>;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
let { open = $bindable(), moduleId, edit, communities, onSaved, onClose }: Props = $props();
|
||||
|
||||
let saving = $state(false);
|
||||
let form = $state<DomainEntryCreate>({ fqdn: '', community_id: null });
|
||||
let initKey = $state('');
|
||||
|
||||
function resetForm() {
|
||||
form = edit
|
||||
? { fqdn: edit.fqdn, community_id: edit.community_id }
|
||||
: { fqdn: '', community_id: null };
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if (!open) {
|
||||
initKey = '';
|
||||
return;
|
||||
}
|
||||
const nextKey = edit?.id ?? 'new';
|
||||
if (nextKey !== initKey) {
|
||||
initKey = nextKey;
|
||||
resetForm();
|
||||
}
|
||||
});
|
||||
|
||||
async function save() {
|
||||
saving = true;
|
||||
try {
|
||||
if (edit) {
|
||||
await apiMutate(`/v1/modules/${moduleId}/domain-entries/${edit.id}`, 'PATCH', form);
|
||||
notify.success('Домен обновлён');
|
||||
} else {
|
||||
await apiMutate(`/v1/modules/${moduleId}/domain-entries`, 'POST', form);
|
||||
notify.success('Домен добавлен');
|
||||
}
|
||||
open = false;
|
||||
await onSaved();
|
||||
} catch (e) {
|
||||
notifyApiError(e);
|
||||
} finally {
|
||||
saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleOpenChange(next: boolean) {
|
||||
open = next;
|
||||
if (!next) onClose();
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog bind:open onOpenChange={handleOpenChange}>
|
||||
<DialogContent class="sm:max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{edit ? 'Редактировать домен' : 'Новый домен'}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div class="space-y-4 py-2">
|
||||
<div class="space-y-1.5">
|
||||
<Label for="dom-fqdn">FQDN</Label>
|
||||
<Input id="dom-fqdn" placeholder="example.com" bind:value={form.fqdn} />
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<Label for="dom-comm">Community</Label>
|
||||
<Select
|
||||
type="single"
|
||||
value={nullableSelectValue(form.community_id)}
|
||||
onValueChange={(v) => {
|
||||
form.community_id = fromNullableSelect(v);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger id="dom-comm" class="w-full">
|
||||
{form.community_id ? communityLabel(form.community_id, communities) : 'Не выбрано'}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={NONE_OPTION}>Не выбрано</SelectItem>
|
||||
{#each communities as c (c.id)}
|
||||
<SelectItem value={c.id}>{communityOptionLabel(c)}</SelectItem>
|
||||
{/each}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onclick={() => handleOpenChange(false)}>Отмена</Button>
|
||||
<Button onclick={save} disabled={saving}>
|
||||
{saving ? 'Сохранение…' : edit ? 'Сохранить' : 'Добавить'}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
Reference in New Issue
Block a user