mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 22:39:46 +00:00
fix editing records and patch mocks
This commit is contained in:
@@ -65,7 +65,7 @@ import { TunnelData, WgServer } from 'src/app/services/patch-db/data-model'
|
|||||||
@for (device of devices(); track $index) {
|
@for (device of devices(); track $index) {
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ device.name }}</td>
|
<td>{{ device.name }}</td>
|
||||||
<td>{{ device.subnetName }}</td>
|
<td>{{ device.subnet.name }}</td>
|
||||||
<td>{{ device.ip }}</td>
|
<td>{{ device.ip }}</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
@@ -82,7 +82,7 @@ import { TunnelData, WgServer } from 'src/app/services/patch-db/data-model'
|
|||||||
tuiOption
|
tuiOption
|
||||||
iconStart="@tui.pencil"
|
iconStart="@tui.pencil"
|
||||||
new
|
new
|
||||||
(click)="onEdit(device.name)"
|
(click)="onEdit(device)"
|
||||||
>
|
>
|
||||||
Rename
|
Rename
|
||||||
</button>
|
</button>
|
||||||
@@ -156,7 +156,11 @@ import { TunnelData, WgServer } from 'src/app/services/patch-db/data-model'
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<footer><button tuiButton (click)="onSave()">Save</button></footer>
|
<footer>
|
||||||
|
<button tuiButton (click)="onSave()" [disabled]="form.invalid">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
</form>
|
</form>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template [(tuiDialog)]="config">
|
<ng-template [(tuiDialog)]="config">
|
||||||
@@ -252,8 +256,10 @@ export default class Devices {
|
|||||||
protected readonly devices = computed(() =>
|
protected readonly devices = computed(() =>
|
||||||
this.subnets().flatMap(subnet =>
|
this.subnets().flatMap(subnet =>
|
||||||
Object.entries(subnet.clients).map(([ip, { name }]) => ({
|
Object.entries(subnet.clients).map(([ip, { name }]) => ({
|
||||||
subnet: subnet.range,
|
subnet: {
|
||||||
subnetName: subnet.name,
|
name: subnet.name,
|
||||||
|
range: subnet.range,
|
||||||
|
},
|
||||||
ip,
|
ip,
|
||||||
name,
|
name,
|
||||||
})),
|
})),
|
||||||
@@ -269,7 +275,7 @@ export default class Devices {
|
|||||||
protected readonly mobile = inject(TUI_IS_MOBILE)
|
protected readonly mobile = inject(TUI_IS_MOBILE)
|
||||||
protected readonly form = inject(NonNullableFormBuilder).group({
|
protected readonly form = inject(NonNullableFormBuilder).group({
|
||||||
name: ['', Validators.required],
|
name: ['', Validators.required],
|
||||||
subnet: [{} as MappedSubnet, Validators.required],
|
subnet: [{} as MappedDevice['subnet'], Validators.required],
|
||||||
ip: ['', Validators.required],
|
ip: ['', Validators.required],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -279,9 +285,9 @@ export default class Devices {
|
|||||||
this.dialog.set(true)
|
this.dialog.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onEdit(name: string): void {
|
protected onEdit(device: MappedDevice): void {
|
||||||
this.editing.set(true)
|
this.editing.set(true)
|
||||||
this.form.reset({ name })
|
this.form.reset(device)
|
||||||
this.dialog.set(true)
|
this.dialog.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +325,10 @@ export default class Devices {
|
|||||||
.subscribe(async () => {
|
.subscribe(async () => {
|
||||||
const loader = this.loading.open().subscribe()
|
const loader = this.loading.open().subscribe()
|
||||||
try {
|
try {
|
||||||
await this.api.deleteDevice({ subnet: device.subnet, ip: device.ip })
|
await this.api.deleteDevice({
|
||||||
|
subnet: device.subnet.range,
|
||||||
|
ip: device.ip,
|
||||||
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -337,8 +346,10 @@ type MappedSubnet = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MappedDevice = {
|
type MappedDevice = {
|
||||||
subnet: string
|
subnet: {
|
||||||
subnetName: string
|
name: string
|
||||||
|
range: string
|
||||||
|
}
|
||||||
ip: string
|
ip: string
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ import { TunnelData } from 'src/app/services/patch-db/data-model'
|
|||||||
tuiOption
|
tuiOption
|
||||||
iconStart="@tui.pencil"
|
iconStart="@tui.pencil"
|
||||||
new
|
new
|
||||||
(click)="onEdit(subnet.name)"
|
(click)="onEdit(subnet)"
|
||||||
>
|
>
|
||||||
Rename
|
Rename
|
||||||
</button>
|
</button>
|
||||||
@@ -102,7 +102,11 @@ import { TunnelData } from 'src/app/services/patch-db/data-model'
|
|||||||
[error]="[] | tuiFieldError | async"
|
[error]="[] | tuiFieldError | async"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
<footer><button tuiButton (click)="onSave()">Save</button></footer>
|
<footer>
|
||||||
|
<button tuiButton (click)="onSave()" [disabled]="form.invalid">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</footer>
|
||||||
</form>
|
</form>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
`,
|
`,
|
||||||
@@ -130,7 +134,7 @@ export default class Subnets {
|
|||||||
protected readonly dialog = signal(false)
|
protected readonly dialog = signal(false)
|
||||||
protected readonly editing = signal(false)
|
protected readonly editing = signal(false)
|
||||||
|
|
||||||
protected readonly subnets = toSignal(
|
protected readonly subnets = toSignal<MappedSubnet[], []>(
|
||||||
this.patch.watch$('wg', 'subnets').pipe(
|
this.patch.watch$('wg', 'subnets').pipe(
|
||||||
map(s =>
|
map(s =>
|
||||||
Object.entries(s).map(([range, info]) => ({
|
Object.entries(s).map(([range, info]) => ({
|
||||||
@@ -165,9 +169,9 @@ export default class Subnets {
|
|||||||
this.dialog.set(true)
|
this.dialog.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onEdit(name: string): void {
|
protected onEdit(subnet: MappedSubnet): void {
|
||||||
this.editing.set(true)
|
this.editing.set(true)
|
||||||
this.form.reset({ name })
|
this.form.reset({ subnet: subnet.range, name: subnet.name })
|
||||||
this.dialog.set(true)
|
this.dialog.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,3 +216,9 @@ export default class Subnets {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MappedSubnet = {
|
||||||
|
range: string
|
||||||
|
name: string
|
||||||
|
hasClients: boolean
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
openWebsocket$<T>(guid: string): WebSocketSubject<T> {
|
openWebsocket$<T>(guid: string): WebSocketSubject<T> {
|
||||||
return this.mockWsSource$.pipe(
|
return this.mockWsSource$.pipe(
|
||||||
tap(v => console.log('MOCK WS', v)),
|
|
||||||
shareReplay({ bufferSize: 1, refCount: true }),
|
shareReplay({ bufferSize: 1, refCount: true }),
|
||||||
) as WebSocketSubject<T>
|
) as WebSocketSubject<T>
|
||||||
}
|
}
|
||||||
@@ -80,7 +79,7 @@ export class MockApiService extends ApiService {
|
|||||||
const patch: AddOperation<WgSubnet>[] = [
|
const patch: AddOperation<WgSubnet>[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.ADD,
|
op: PatchOp.ADD,
|
||||||
path: `/wg/subnets/${params.subnet}`,
|
path: `/wg/subnets/${replaceSlashes(params.subnet)}`,
|
||||||
value: { name: params.name, clients: {} },
|
value: { name: params.name, clients: {} },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -95,7 +94,7 @@ export class MockApiService extends ApiService {
|
|||||||
const patch: ReplaceOperation<string>[] = [
|
const patch: ReplaceOperation<string>[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: `/wg/subnets/${params.subnet}/name`,
|
path: `/wg/subnets/${replaceSlashes(params.subnet)}/name`,
|
||||||
value: params.name,
|
value: params.name,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -110,7 +109,7 @@ export class MockApiService extends ApiService {
|
|||||||
const patch: RemoveOperation[] = [
|
const patch: RemoveOperation[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REMOVE,
|
op: PatchOp.REMOVE,
|
||||||
path: `/wg/subnets/${params.subnet}`,
|
path: `/wg/subnets/${replaceSlashes(params.subnet)}`,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
this.mockRevision(patch)
|
this.mockRevision(patch)
|
||||||
@@ -124,7 +123,7 @@ export class MockApiService extends ApiService {
|
|||||||
const patch: AddOperation<WgClient>[] = [
|
const patch: AddOperation<WgClient>[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.ADD,
|
op: PatchOp.ADD,
|
||||||
path: `/wg/subnets/${params.subnet}/clients/${params.ip}`,
|
path: `/wg/subnets/${replaceSlashes(params.subnet)}/clients/${params.ip}`,
|
||||||
value: { name: params.name },
|
value: { name: params.name },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -139,7 +138,7 @@ export class MockApiService extends ApiService {
|
|||||||
const patch: ReplaceOperation<string>[] = [
|
const patch: ReplaceOperation<string>[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: `/wg/subnets/${params.subnet}/clients/${params.ip}/name`,
|
path: `/wg/subnets/${replaceSlashes(params.subnet)}/clients/${params.ip}/name`,
|
||||||
value: params.name,
|
value: params.name,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -154,7 +153,7 @@ export class MockApiService extends ApiService {
|
|||||||
const patch: RemoveOperation[] = [
|
const patch: RemoveOperation[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REMOVE,
|
op: PatchOp.REMOVE,
|
||||||
path: `/wg/subnets/${params.subnet}/clients/${params.ip}`,
|
path: `/wg/subnets/${replaceSlashes(params.subnet)}/clients/${params.ip}`,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
this.mockRevision(patch)
|
this.mockRevision(patch)
|
||||||
@@ -199,3 +198,7 @@ export class MockApiService extends ApiService {
|
|||||||
this.mockWsSource$.next(revision)
|
this.mockWsSource$.next(revision)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceSlashes(val: string) {
|
||||||
|
return val.replace(new RegExp('/', 'g'), '~1')
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user