Continue frontend building

This commit is contained in:
2025-07-13 12:03:43 +02:00
parent 6faed0dbd4
commit 746f809d28
44 changed files with 2057 additions and 632 deletions

View File

@ -0,0 +1,26 @@
// stores/useAlertsStore.ts
import { defineStore } from 'pinia'
interface Alert {
id: number
message: string
type: 'info' | 'success' | 'warning' | 'error'
}
export const useAlertsStore = defineStore('alerts', {
state: () => ({
alerts: [] as Alert[],
}),
actions: {
showAlert(message: string, type: Alert['type'] = 'info') {
this.alerts.push({
id: Date.now(),
message,
type,
})
},
removeAlert(id: number) {
this.alerts = this.alerts.filter(a => a.id !== id)
},
},
})

View File

@ -0,0 +1,74 @@
import { defineStore } from 'pinia'
import type { SubSystem, Operation } from "@/client";
import { isOperation, isSubSystem } from '@/api/typeguards';
export interface ViewAuditFilters {
subSystem: SubSystem | null
operation: Operation | null
clientName: string | null
secretName: string | null
origin: string | null
}
function withNullValue(value: string | null): string | null {
if (value === '') {
return null
}
return value
}
function subSystemOrNull(value: string | null): SubSystem | null {
if (!value) {
return null
} else if (isSubSystem(value)) {
return value
}
throw "Invalid subsystem value"
}
function operationOrNull(value: string | null): Operation | null {
if (!value) {
return null
} else if (isOperation(value)) {
return value
}
throw "Invalid operation value"
}
export const useAuditFilterState = defineStore('auditFilterState', {
state: () => ({
subSystem: null as SubSystem | null,
operation: null as Operation | null,
clientName: null as string | null,
secretName: null as string | null,
origin: null as string | null,
}),
actions: {
setValues(items: ViewAuditFilters) {
this.subSystem = subSystemOrNull(items['subSystem'])
this.operation = operationOrNull(items['operation'])
this.clientName = withNullValue(items['clientName'])
this.secretName = withNullValue(items['secretName'])
this.origin = withNullValue(items['origin'])
},
reset() {
this.subSystem = null
this.operation = null
this.clientName = null
this.secretName = null
this.origin = null
},
},
getters: {
getFilter: (state) => {
return {
subsystem: state.subSystem,
operation: state.operation,
client_name: state.clientName,
secret_name: state.secretName,
origin: state.origin,
}
}
}
})

View File

@ -2,13 +2,19 @@ import { defineStore } from 'pinia'
import { SshecretObjectType } from '@/api/types'
import type { SshecretObject } from '@/api/types'
import { SshecretAdmin } from '@/client'
import type { ClientQueryResult, Client, SecretView } from '@/client'
import type { ClientQueryResult, Client, SecretView, ClientSecretGroupList, SecretListView, ClientSecretGroup } from '@/client'
export const useTreeState = defineStore('treeState', {
state: () => ({
selected: null as SshecretObject | null,
auditFilter: null as SshecretObject | null,
parent: null as SshecretObject | null,
clients: null as ClientQueryResult | null,
secrets: [] as SecretListView[],
secretGroups: null as ClientSecretGroupList | null,
secretGroupRevision: 0,
clientRevision: 0,
showAudit: false as boolean,
}),
actions: {
selectClient(id: string) {
@ -20,6 +26,9 @@ export const useTreeState = defineStore('treeState', {
this.parent = { objectType: SshecretObjectType.Client, id: parent }
}
},
selectGroup(path: string) {
this.selected = { objectType: SshecretObjectType.SecretGroup, id: path }
},
unselect() {
this.selected = null
},
@ -57,6 +66,23 @@ export const useTreeState = defineStore('treeState', {
return 0
},
async getSecretNames(): Promise<boolean> {
// Get all secret names.
const response = await SshecretAdmin.getSecretNamesApiV1SecretsGet()
if (response.data) {
this.secrets = response.data
return true
}
return false
},
async getSecretGroups(): Promise<boolean> {
const response = await SshecretAdmin.getSecretGroupsApiV1SecretsGroupsGet()
if (response.data) {
this.secretGroups = response.data
return true
}
return false
},
async getClient(id: string | null = null): Promise<Client> {
if (!id && this.selected?.objectType === SshecretObjectType.Client) {
id = this.selected.id
@ -85,7 +111,14 @@ export const useTreeState = defineStore('treeState', {
}
throw "Secret not found"
},
async getSelected(): Promise<Client | SecretView | null> {
async getGroup(path: string): Promise<ClientSecretGroup> {
const response = await SshecretAdmin.getSecretGroupApiV1SecretsGroupsGroupPathGet({ path: { group_path: path } })
if (response.data) {
return response.data
}
throw "Group not found"
},
async getSelected(): Promise<Client | SecretView | ClientSecretGroup | null> {
if (!this.selected) {
return null
}
@ -93,6 +126,8 @@ export const useTreeState = defineStore('treeState', {
return await this.getClient(this.selected.id)
} else if (this.selected.objectType === SshecretObjectType.ClientSecret) {
return await this.getSecret(this.selected.id)
} else if (this.selected.objectType === SshecretObjectType.SecretGroup) {
return await this.getGroup(this.selected.id)
}
else {
throw "Invalid object"
@ -113,7 +148,13 @@ export const useTreeState = defineStore('treeState', {
}
}
return false
}
},
bumpGroupRevision() {
this.secretGroupRevision += 1
},
bumpClientRevision() {
this.clientRevision += 1
},
},
getters: {
clientSelected() {
@ -133,6 +174,12 @@ export const useTreeState = defineStore('treeState', {
return true
}
return false
},
currentGroupPath(): string {
if (this.selected && this.selected.objectType === SshecretObjectType.SecretGroup) {
return this.selected.id
}
return '/'
}
}
})