From 3efc4d7fa53594d281f442df38403b745533798c Mon Sep 17 00:00:00 2001 From: Allan Eising Date: Tue, 15 Jul 2025 16:53:37 +0200 Subject: [PATCH] Deletions, group moves and validation --- packages/sshecret-frontend/TODO.org | 29 ++++++-- packages/sshecret-frontend/src/App.vue | 15 +--- .../src/components/audit/AuditTable.vue | 1 - .../src/components/clients/ClientForm.vue | 23 ++++-- .../src/components/common/AlertToast.vue | 36 ++++++++++ .../src/components/common/ShowAlerts.vue | 11 +++ .../src/components/secrets/GroupMoveTree.vue | 12 +++- .../components/secrets/MoveSecretGroup.vue | 58 +++++++++++++++ .../src/components/secrets/SecretDetail.vue | 36 ++++++++-- .../src/store/useAlertsStore.ts | 27 ++++++- .../src/views/secrets/SecretDetailView.vue | 72 +++++++++++++++---- 11 files changed, 268 insertions(+), 52 deletions(-) create mode 100644 packages/sshecret-frontend/src/components/common/AlertToast.vue create mode 100644 packages/sshecret-frontend/src/components/common/ShowAlerts.vue create mode 100644 packages/sshecret-frontend/src/components/secrets/MoveSecretGroup.vue diff --git a/packages/sshecret-frontend/TODO.org b/packages/sshecret-frontend/TODO.org index 339071e..15a8e83 100644 --- a/packages/sshecret-frontend/TODO.org +++ b/packages/sshecret-frontend/TODO.org @@ -7,7 +7,7 @@ So, this is the steps I need to take. * DONE Write a typescript API client. I suppose this can be rendered from OpenAPI? -* Install the required libraries +* DONE Install the required libraries + [X] Flowbite + [X] Shoelace + [X] tailwind @@ -15,9 +15,26 @@ I suppose this can be rendered from OpenAPI? I've set up flowbite-vue here. https://flowbite-vue.com/pages/getting-started * DONE Set up base page -* Set up login page (basic) -+ [ ] Create an authentication state store -+ [ ] Use the rendered API to send login details, and receive tokens -+ [ ] Consider adding a refresh token thing to the API +* DONE Set up login page (basic) ++ [X] Create an authentication state store ++ [X] Use the rendered API to send login details, and receive tokens ++ [X] Consider adding a refresh token thing to the API -* Create the master/detail page +* DONE Create the master/detail page + +* Views +** Secret View ++ [X] Add dropdown ++ [X] Implement delete ++ [X] Implement move + +* Navigation +** DONE Implement hard links ++ All selections can be done to the state, + except the tab selection + +* Error handling ++ [X] Check styling on sl-alert ++ [X] Ensure that its z-index is above any popups ++ [X] Refine field-based validation in ClientForm for other fields ++ [ ] Implement validation in SecretForm diff --git a/packages/sshecret-frontend/src/App.vue b/packages/sshecret-frontend/src/App.vue index f87236f..ac15c85 100644 --- a/packages/sshecret-frontend/src/App.vue +++ b/packages/sshecret-frontend/src/App.vue @@ -1,21 +1,10 @@ diff --git a/packages/sshecret-frontend/src/components/audit/AuditTable.vue b/packages/sshecret-frontend/src/components/audit/AuditTable.vue index 5ad45cd..500ffef 100644 --- a/packages/sshecret-frontend/src/components/audit/AuditTable.vue +++ b/packages/sshecret-frontend/src/components/audit/AuditTable.vue @@ -208,7 +208,6 @@ const props = defineProps() const shouldPaginate = toRef(() => props.paginate ?? true) const auditFilter = toRef(() => props.auditFilter) -console.log(auditFilter.value) const auditList = ref([]) const auditEntries = computed(() => auditList.value?.results) const totalEntries = computed(() => auditList.value?.total) diff --git a/packages/sshecret-frontend/src/components/clients/ClientForm.vue b/packages/sshecret-frontend/src/components/clients/ClientForm.vue index 058d2fe..7b6668a 100644 --- a/packages/sshecret-frontend/src/components/clients/ClientForm.vue +++ b/packages/sshecret-frontend/src/components/clients/ClientForm.vue @@ -80,10 +80,7 @@ const name = ref('') const description = ref('') const sourcePrefix = ref('') const policies = ref(['0.0.0.0/0', '::/0']) -// This key is only here during testing. -const publicKey = ref( - 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC737Yj7mbuBLDNbAuNGqhFF4Cvzd/ROq/QeQX0QIcPyZOoUtpXc7R/JIrdL6DXkPYXpN/IrUFoSeJQjV9Le+ewVxYELUPVhF0/nQhpBNE1Rjx2PRtJlfmywG5VRStgPQ+DSTDtgm4L0wPpnJiH3udkq/JFMHEYrVAF40QqNmR7AqYo1ZfEFk8YcQGb/S29JxWigq0qoJyufFENmSGNmabjqPAWJEf/oshMPaxwlDfTdmjeUWkPtsm10gi98XCwtnVCAVYZdVKeLSNpQCKUYVYWlycpahNczaITY9lehcMtux79uXTk2d4difra1Q4guw8oorUp1eRn/Al0BPeRb7x9WdgRs8wVY1kPD2796CTAQMkeBrOzGxwzwWhTf1XOuHG/wB5O2QSbcC6aMW9KAFmcCF+AOMb8Mv2Y5D7l/gbp938qTyZJ8ivP1/fy/88CWr+mrv5yP4HOZmNCyC9nMlAvrS/Kkg0tFU+NHFkDsmWpT3oar+VvGzkImEF6ip6Mzk8= testkey', -) +const publicKey = ref('') const nameField = ref() const sourceField = ref() @@ -169,15 +166,27 @@ function validatePublicKey() { setFieldValidation(publicKeyField, '') } +function resetValidation() { + setFieldValidation(nameField, '') + setFieldValidation(sourceField, '') + setFieldValidation(publicKeyField, '') +} + watch( () => props.errors, (errors) => { + resetValidation() const nameErrors = errors.filter((e) => e.loc.includes('name')) + const sourceErrors = errors.filter((e) => e.loc.includes('source')) + const publicKeyError = errors.filter((e) => e.loc.includes('public_key')) if (nameErrors.length > 0) { - console.log(nameErrors) setFieldValidation(nameField, nameErrors[0].msg) - } else { - setFieldValidation(nameField, '') + } + if (sourceErrors.length > 0) { + setFieldValidation(sourceField, sourceErrors[0].msg) + } + if (publicKeyError.length > 0) { + setFieldValidation(publicKeyField, publicKeyErrors[0].msg) } }, ) diff --git a/packages/sshecret-frontend/src/components/common/AlertToast.vue b/packages/sshecret-frontend/src/components/common/AlertToast.vue new file mode 100644 index 0000000..1747940 --- /dev/null +++ b/packages/sshecret-frontend/src/components/common/AlertToast.vue @@ -0,0 +1,36 @@ + + + + diff --git a/packages/sshecret-frontend/src/components/common/ShowAlerts.vue b/packages/sshecret-frontend/src/components/common/ShowAlerts.vue new file mode 100644 index 0000000..338b01a --- /dev/null +++ b/packages/sshecret-frontend/src/components/common/ShowAlerts.vue @@ -0,0 +1,11 @@ + + diff --git a/packages/sshecret-frontend/src/components/secrets/GroupMoveTree.vue b/packages/sshecret-frontend/src/components/secrets/GroupMoveTree.vue index a8c5349..ea64574 100644 --- a/packages/sshecret-frontend/src/components/secrets/GroupMoveTree.vue +++ b/packages/sshecret-frontend/src/components/secrets/GroupMoveTree.vue @@ -16,9 +16,12 @@ Cancel diff --git a/packages/sshecret-frontend/src/components/secrets/SecretDetail.vue b/packages/sshecret-frontend/src/components/secrets/SecretDetail.vue index b4db438..e4c4fdb 100644 --- a/packages/sshecret-frontend/src/components/secrets/SecretDetail.vue +++ b/packages/sshecret-frontend/src/components/secrets/SecretDetail.vue @@ -100,12 +100,25 @@ > {{ secret.group.path }}
- + Move
+ +
+ Not in any group +
+ + + Add to group + +
+
@@ -179,6 +192,13 @@ Delete + + +