diff --git a/src/pages/Secrets/KeyValue/KeyValueSecret.tsx b/src/pages/Secrets/KeyValue/KeyValueSecret.tsx
index ff47038..7d1e511 100644
--- a/src/pages/Secrets/KeyValue/KeyValueSecret.tsx
+++ b/src/pages/Secrets/KeyValue/KeyValueSecret.tsx
@@ -1,9 +1,9 @@
+import { Component, JSX, render } from "preact";
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
import { Page } from "../../../types/Page";
import { SecretTitleElement } from "../SecretTitleElement";
import { getCapabilities } from "../../../api/sys/getCapabilities";
import { getSecret } from "../../../api/kv/getSecret";
-import { Component, JSX, render } from "preact";
import { sortedObjectMap } from "../../../utils";
import { undeleteSecret } from "../../../api/kv/undeleteSecret";
import Prism from "prismjs";
@@ -80,15 +80,14 @@ export class KeyValueSecretPage extends Page {
// On kv-v2, secrets can be deleted temporarily with the ability to restore
// Do not show any buttons when the secret is deleted.
- let secretIsDeleted = secretInfo == null && this.state.secretMountType == "kv-v2";
+ const secretIsDeleted = secretInfo == null && this.state.secretMountType == "kv-v2";
render(
{
// Delete Button
- !secretIsDeleted &&
- caps.includes("delete") && (
+ !secretIsDeleted && caps.includes("delete") && (
)
}
- {
- !secretIsDeleted &&
- caps.includes("update") && this.state.secretVersion == null && (
-
- )}
- {
- !secretIsDeleted &&
- this.state.secretMountType == "kv-v2" && (
-
- )}
+ {!secretIsDeleted && caps.includes("update") && this.state.secretVersion == null && (
+
+ )}
+ {!secretIsDeleted && this.state.secretMountType == "kv-v2" && (
+
+ )}
- {!secretIsDeleted &&
-
- }
+ {!secretIsDeleted &&
}
- {secretIsDeleted &&
+ {secretIsDeleted && (
<>
{i18next.t("kv_secret_deleted_text")}
,
this.router.pageContentElement,
);
diff --git a/src/pages/Secrets/KeyValue/KeyValueView.tsx b/src/pages/Secrets/KeyValue/KeyValueView.tsx
index f4b550d..7d1b3e7 100644
--- a/src/pages/Secrets/KeyValue/KeyValueView.tsx
+++ b/src/pages/Secrets/KeyValue/KeyValueView.tsx
@@ -1,11 +1,101 @@
+import { Component, JSX, render } from "preact";
import { DoesNotExistError } from "../../../types/internalErrors";
import { Page } from "../../../types/Page";
import { SecretTitleElement } from "../SecretTitleElement";
import { getSecrets } from "../../../api/kv/getSecrets";
-import { render } from "preact";
import { setErrorText } from "../../../pageUtils";
import i18next from "i18next";
+export type KVKeysListProps = {
+ page: Page;
+};
+
+type KVKeysListState =
+ | {
+ dataLoaded: false;
+ }
+ | {
+ dataLoaded: true;
+ keys: string[];
+ };
+
+export class KVKeysList extends Component {
+ constructor() {
+ super();
+ this.state = {
+ dataLoaded: false,
+ };
+ }
+
+ loadData(): void {
+ void getSecrets(
+ this.props.page.state.baseMount,
+ this.props.page.state.secretMountType,
+ this.props.page.state.secretPath,
+ )
+ .then((keys) => {
+ this.setState({
+ dataLoaded: true,
+ keys: keys,
+ });
+ })
+ .catch((e: Error) => {
+ // getSecrets also 404's on no keys so dont go all the way back.
+ if (e == DoesNotExistError) {
+ if (this.props.page.state.secretPath.length != 0) {
+ void this.props.page.goBack();
+ return;
+ } else {
+ this.setState({
+ dataLoaded: true,
+ keys: null,
+ });
+ }
+ } else {
+ setErrorText(e.message);
+ }
+ });
+ return;
+ }
+
+ componentDidMount(): void {
+ if (!this.state.dataLoaded) {
+ this.loadData();
+ }
+ }
+
+ render(): JSX.Element {
+ if (!this.state.dataLoaded) {
+ return {i18next.t("content_loading")}
;
+ }
+ if (this.state.keys == null) {
+ return {i18next.t("kv_view_none_here_text")}
;
+ }
+ return (
+
+ );
+ }
+}
+
export class KeyValueViewPage extends Page {
constructor() {
super();
@@ -34,59 +124,10 @@ export class KeyValueViewPage extends Page {
{this.state.secretMountType == "cubbyhole" && {i18next.t("kv_view_cubbyhole_text")}
}
-
+
>,
this.router.pageContentElement,
);
-
- let res: string[];
-
- try {
- res = await getSecrets(
- this.state.baseMount,
- this.state.secretMountType,
- this.state.secretPath,
- );
- } catch (e: unknown) {
- const error = e as Error;
- if (error == DoesNotExistError) {
- // getSecrets also 404's on no keys so dont go all the way back.
- if (this.state.secretPath.length != 0) {
- return this.goBack();
- } else {
- render(
- {i18next.t("kv_view_none_here_text")}
,
- document.querySelector("#secretsList"),
- );
- }
- } else {
- setErrorText(error.message);
- return;
- }
- }
-
- render(
- ,
- document.querySelector("#secretsList"),
- );
}
async renderPageTitle(): Promise {