Skip to content

Commit

Permalink
Merge pull request #22 from vertex-center/feature/choose-database
Browse files Browse the repository at this point in the history
Data page to configure the default Vertex DBMS
  • Loading branch information
quentinguidee authored Nov 27, 2023
2 parents b6fd6a1 + 47d11a2 commit 6c36ec6
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 18 deletions.
5 changes: 5 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import SqlDatabase from "./apps/Sql/SqlDatabase/SqlDatabase";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import ServiceEditor from "./apps/DevToolsServiceEditor/ServiceEditor/ServiceEditor";
import SettingsDb from "./apps/Settings/SettingsData/SettingsDb";

const queryClient = new QueryClient();

Expand Down Expand Up @@ -164,6 +165,10 @@ function App() {
path="/settings/hardware"
element={<SettingsHardware />}
/>
<Route
path="/settings/database"
element={<SettingsDb />}
/>
<Route
path="/settings/security"
element={<SettingsSecurity />}
Expand Down
5 changes: 5 additions & 0 deletions src/apps/Settings/SettingsApp/SettingsApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export default function SettingsApp() {
icon={<MaterialIcon icon="hard_drive" />}
link={l("/settings/hardware")}
/>
<Sidebar.Item
label="Database"
icon={<MaterialIcon icon="database" />}
link={l("/settings/database")}
/>
<Sidebar.Item
label="Security"
icon={<MaterialIcon icon="key" />}
Expand Down
5 changes: 5 additions & 0 deletions src/apps/Settings/SettingsData/SettingsDb.module.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@use "../../../styles/colors"

.tag
margin-right: 16px
color: colors.$green
172 changes: 172 additions & 0 deletions src/apps/Settings/SettingsData/SettingsDb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import Content from "../../../components/Content/Content";
import {
Button,
Horizontal,
List,
ListActions,
ListDescription,
ListIcon,
ListInfo,
ListItem,
ListTitle,
MaterialIcon,
Paragraph,
Title,
Vertical,
} from "@vertex-center/components";
import { SiPostgresql, SiSqlite } from "@icons-pack/react-simple-icons";
import styles from "./SettingsDb.module.sass";
import Popup from "../../../components/Popup/Popup";
import { Fragment, useState } from "react";
import { useDBMS } from "../hooks/useDBMS";
import Progress, {
ProgressOverlay,
} from "../../../components/Progress/Progress";
import { APIError } from "../../../components/Error/APIError";
import { useDBMSMutation } from "../hooks/useDBMSMutation";
import { useQueryClient } from "@tanstack/react-query";

type DatabaseProps = {
name: string;
icon: JSX.Element;
title: string;
description: string;
installed: boolean;
onMigrate?: (db: string) => void;
hideActions?: boolean;
};

function Db(props: Readonly<DatabaseProps>) {
const {
name,
icon,
title,
description,
installed,
onMigrate,
hideActions,
} = props;

let actions = null;
if (installed) {
actions = (
<Horizontal className={styles.tag} alignItems="center">
<MaterialIcon icon="check" />
Active
</Horizontal>
);
} else if (!hideActions) {
actions = (
<Button
variant="danger"
rightIcon={<MaterialIcon icon="restart_alt" />}
onClick={() => onMigrate(name)}
>
Migrate
</Button>
);
}

return (
<ListItem>
<ListIcon>{icon}</ListIcon>
<ListInfo>
<ListTitle>{title}</ListTitle>
<ListDescription>{description}</ListDescription>
</ListInfo>
<ListActions>{actions}</ListActions>
</ListItem>
);
}

export default function SettingsDb() {
const queryClient = useQueryClient();

const [showPopup, setShowPopup] = useState(false);
const [selectedDB, setSelectedDB] = useState<string>();

const { dbms, isLoadingDbms, errorDbms } = useDBMS();
const { migrate, isMigrating, errorMigrate } = useDBMSMutation({
onMutate: () => {
setShowPopup(false);
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["admin_db_dbms"],
});
},
});

const askMigrate = (db: string) => {
setSelectedDB(db);
setShowPopup(true);
};

const dismissPopup = () => setShowPopup(false);

const askMigrateActions = (
<Fragment>
<Button variant="outlined" onClick={dismissPopup}>
Cancel
</Button>
<Button
variant="danger"
rightIcon={<MaterialIcon icon="restart_alt" />}
onClick={() => migrate(selectedDB)}
>
Migrate
</Button>
</Fragment>
);

return (
<Content>
<Title variant="h2">Database</Title>
<Paragraph>
You can choose between <b>SQLite</b> and <b>Postgres</b> to
store your Vertex data. You don't need to worry about installing
or configuring the database, Vertex will do that for you.
{/*Vertex data can include users, permissions, settings....*/}
</Paragraph>
<ProgressOverlay show={isLoadingDbms} />
<APIError error={errorDbms || errorMigrate} />
<List>
<Db
name="sqlite"
icon={<SiSqlite />}
title="SQLite"
description="Recommended for small setups."
installed={dbms === "sqlite"}
onMigrate={askMigrate}
hideActions={isMigrating || isLoadingDbms}
/>
<Db
name="postgres"
icon={<SiPostgresql />}
title="Postgres"
description="Recommended for larger installations."
installed={dbms === "postgres"}
onMigrate={askMigrate}
hideActions={isMigrating || isLoadingDbms}
/>
</List>
{isMigrating && (
<Vertical gap={12}>
<Paragraph>Migration to {selectedDB} ongoing...</Paragraph>
<Progress infinite />
</Vertical>
)}
<Popup
show={showPopup}
onDismiss={dismissPopup}
title="Migrate database?"
actions={askMigrateActions}
>
<Paragraph>
Are you sure you want to migrate from {dbms} to {selectedDB}
?
</Paragraph>
</Popup>
</Content>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function SettingsNotifications() {
});

useEffect(() => {
setWebhook(settings?.notifications?.webhook);
setWebhook(settings?.webhook);
}, [settings]);

const onWebhookChange = (e: any) => {
Expand All @@ -38,7 +38,7 @@ export default function SettingsNotifications() {
const onSave = () => {
setSaving(true);
api.settings
.patch({ notifications: { webhook } })
.patch({ webhook })
.then(() => setChanged(false))
.catch(console.error)
.finally(() => setSaving(false));
Expand Down
2 changes: 1 addition & 1 deletion src/apps/Settings/SettingsUpdates/SettingsUpdates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default function SettingsUpdates() {
<Paragraph>Enable Beta channel</Paragraph>
<Spacer />
<ToggleButton
value={settings?.updates?.channel === "beta"}
value={settings?.updates_channel === "beta"}
onChange={(beta: boolean) => setChannel(beta)}
disabled={isLoading}
/>
Expand Down
11 changes: 11 additions & 0 deletions src/apps/Settings/hooks/useDBMS.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { api } from "../../../backend/api/backend";

export const useDBMS = () => {
const query = useQuery({
queryKey: ["admin_db_dbms"],
queryFn: api.admin.data.dbms.get,
});
const { data: dbms, isLoading: isLoadingDbms, error: errorDbms } = query;
return { dbms, isLoadingDbms, errorDbms };
};
18 changes: 18 additions & 0 deletions src/apps/Settings/hooks/useDBMSMutation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMutation, UseMutationOptions } from "@tanstack/react-query";
import { api } from "../../../backend/api/backend";

export const useDBMSMutation = (
options: UseMutationOptions<unknown, unknown, string>
) => {
const mutation = useMutation({
mutationKey: ["admin_db_dbms"],
mutationFn: api.admin.data.dbms.migrate,
...options,
});
const {
mutate: migrate,
isLoading: isMigrating,
error: errorMigrate,
} = mutation;
return { migrate, isMigrating, errorMigrate };
};
4 changes: 1 addition & 3 deletions src/apps/Settings/hooks/useSettingsMutation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ export const useSettingsChannelMutation = (
mutationKey: ["settings"],
mutationFn: (beta?: boolean) =>
api.settings.patch({
updates: {
channel: beta ? "beta" : "stable",
},
updates_channel: beta ? "beta" : "stable",
}),
...options,
});
Expand Down
25 changes: 21 additions & 4 deletions src/backend/api/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ const getCPUs = async () => {
};

const getUpdate = async () => {
const { data } = await server.get<Update>("/update");
const { data } = await server.get<Update>("/admin/update");
return data;
};

const installUpdate = async () => {
const { data } = await server.post("/update");
const { data } = await server.post("/admin/update");
return data;
};

Expand All @@ -79,6 +79,23 @@ export const api = {
vxReverseProxy: vxReverseProxyRoutes,
vxServiceEditor: vxServiceEditorRoutes,

admin: {
data: {
dbms: {
get: async () => {
const { data } = await server.get<string>("/admin/db/dbms");
return data;
},
migrate: async (dbms: string) => {
const { data } = await server.post("/admin/db/dbms", {
dbms,
});
return data;
},
},
},
},

apps: {
all: async () => {
const { data } = await server.get<VertexApp[]>("/apps");
Expand Down Expand Up @@ -114,10 +131,10 @@ export const api = {

settings: {
get: async () => {
const { data } = await server.get<Settings>("/settings");
const { data } = await server.get<Settings>("/admin/settings");
return data;
},
patch: (settings: Partial<Settings>) =>
server.patch("/settings", settings),
server.patch("/admin/settings", settings),
},
};
2 changes: 1 addition & 1 deletion src/components/Error/ErrorBox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box, BoxProps, Paragraph } from "@vertex-center/components";

type Props = BoxProps & {
type Props = Omit<BoxProps, "type"> & {
error?: any;
};

Expand Down
9 changes: 2 additions & 7 deletions src/models/settings.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
type Settings = {
notifications?: {
webhook?: string;
};

updates?: {
channel?: string;
};
webhook?: string;
updates_channel?: string;
};

0 comments on commit 6c36ec6

Please sign in to comment.