feat: add board access settings (#249)

* wip: add board access settings

* wip: add user access control

* wip: add user access control

* feat: add user access control

* refactor: move away from mantine-modal-manager

* fix: ci issues and failing tests

* fix: lint issue

* fix: format issue

* fix: deepsource issues

* chore: address pull request feedback
This commit is contained in:
Meier Lukas
2024-03-20 20:30:58 +01:00
committed by GitHub
parent 4753bc7162
commit 361700b239
59 changed files with 1763 additions and 1338 deletions

View File

@@ -4,6 +4,7 @@ import { useCallback } from "react";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useConfirmModal } from "@homarr/modals";
import {
showErrorNotification,
showSuccessNotification,
@@ -12,7 +13,6 @@ import { useScopedI18n } from "@homarr/translation/client";
import { ActionIcon, IconTrash } from "@homarr/ui";
import { revalidatePathAction } from "../../../revalidatePathAction";
import { modalEvents } from "../../modals";
interface AppDeleteButtonProps {
app: RouterOutputs["app"]["all"][number];
@@ -20,10 +20,11 @@ interface AppDeleteButtonProps {
export const AppDeleteButton = ({ app }: AppDeleteButtonProps) => {
const t = useScopedI18n("app.page.delete");
const { openConfirmModal } = useConfirmModal();
const { mutate, isPending } = clientApi.app.delete.useMutation();
const onClick = useCallback(() => {
modalEvents.openConfirmModal({
openConfirmModal({
title: t("title"),
children: t("message", app),
onConfirm: () => {
@@ -47,7 +48,7 @@ export const AppDeleteButton = ({ app }: AppDeleteButtonProps) => {
);
},
});
}, [app, mutate, t]);
}, [app, mutate, t, openConfirmModal]);
return (
<ActionIcon

View File

@@ -3,6 +3,7 @@
import { useRouter } from "next/navigation";
import { clientApi } from "@homarr/api/client";
import { useConfirmModal } from "@homarr/modals";
import {
showErrorNotification,
showSuccessNotification,
@@ -11,7 +12,6 @@ import { useScopedI18n } from "@homarr/translation/client";
import { ActionIcon, IconTrash } from "@homarr/ui";
import { revalidatePathAction } from "../../../revalidatePathAction";
import { modalEvents } from "../../modals";
interface DeleteIntegrationActionButtonProps {
count: number;
@@ -24,6 +24,7 @@ export const DeleteIntegrationActionButton = ({
}: DeleteIntegrationActionButtonProps) => {
const t = useScopedI18n("integration.page.delete");
const router = useRouter();
const { openConfirmModal } = useConfirmModal();
const { mutateAsync, isPending } = clientApi.integration.delete.useMutation();
return (
@@ -32,7 +33,7 @@ export const DeleteIntegrationActionButton = ({
variant="subtle"
color="red"
onClick={() => {
modalEvents.openConfirmModal({
openConfirmModal({
title: t("title"),
children: t("message", integration),
onConfirm: () => {

View File

@@ -10,6 +10,7 @@ import {
getDefaultSecretKinds,
} from "@homarr/definitions";
import { useForm, zodResolver } from "@homarr/form";
import { useConfirmModal } from "@homarr/modals";
import {
showErrorNotification,
showSuccessNotification,
@@ -19,7 +20,6 @@ import { Button, Fieldset, Group, Stack, TextInput } from "@homarr/ui";
import type { z } from "@homarr/validation";
import { validation } from "@homarr/validation";
import { modalEvents } from "~/app/[locale]/modals";
import { SecretCard } from "../../_integration-secret-card";
import { IntegrationSecretInput } from "../../_integration-secret-inputs";
import {
@@ -35,9 +35,10 @@ interface EditIntegrationForm {
export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
const t = useI18n();
const { openConfirmModal } = useConfirmModal();
const secretsKinds =
getAllSecretKindOptions(integration.kind).find((x) =>
integration.secrets.every((y) => x.includes(y.kind)),
getAllSecretKindOptions(integration.kind).find((secretKinds) =>
integration.secrets.every((secret) => secretKinds.includes(secret.kind)),
) ?? getDefaultSecretKinds(integration.kind);
const initialFormValues = {
name: integration.name,
@@ -99,7 +100,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
};
return (
<form onSubmit={form.onSubmit((v) => void handleSubmit(v))}>
<form onSubmit={form.onSubmit((values) => void handleSubmit(values))}>
<Stack>
<TestConnectionNoticeAlert />
@@ -128,7 +129,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
) {
return res(true);
}
modalEvents.openConfirmModal({
openConfirmModal({
title: t("integration.secrets.reset.title"),
children: t("integration.secrets.reset.message"),
onCancel: () => res(false),

View File

@@ -33,7 +33,7 @@ export const IntegrationCreateDropdownContent = () => {
leftSection={<IconSearch stroke={1.5} size={20} />}
placeholder={t("integration.page.list.search")}
value={search}
onChange={(e) => setSearch(e.target.value)}
onChange={(event) => setSearch(event.target.value)}
/>
{filteredKinds.length > 0 ? (