mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-11-03 17:13:33 +00:00
Permissions polish for restricted users
This commit is contained in:
@@ -2,9 +2,10 @@ import { IconDotsVertical, IconEdit, IconTrash } from "@tabler/icons-react";
|
||||
import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||
import { useMemo } from "react";
|
||||
import type { AccessList } from "src/api/backend";
|
||||
import { EmptyData, GravatarFormatter, ValueWithDateFormatter } from "src/components";
|
||||
import { EmptyData, GravatarFormatter, HasPermission, ValueWithDateFormatter } from "src/components";
|
||||
import { TableLayout } from "src/components/Table/TableLayout";
|
||||
import { intl, T } from "src/locale";
|
||||
import { ACCESS_LISTS, MANAGE } from "src/modules/Permissions";
|
||||
|
||||
interface Props {
|
||||
data: AccessList[];
|
||||
@@ -84,18 +85,20 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete,
|
||||
<IconEdit size={16} />
|
||||
<T id="action.edit" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
<HasPermission section={ACCESS_LISTS} permission={MANAGE} hideError>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
</HasPermission>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
@@ -130,6 +133,7 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete,
|
||||
onNew={onNew}
|
||||
isFiltered={isFiltered}
|
||||
color="cyan"
|
||||
permissionSection={ACCESS_LISTS}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -2,10 +2,11 @@ import { IconHelp, IconSearch } from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import Alert from "react-bootstrap/Alert";
|
||||
import { deleteAccessList } from "src/api/backend";
|
||||
import { Button, LoadingPage } from "src/components";
|
||||
import { Button, HasPermission, LoadingPage } from "src/components";
|
||||
import { useAccessLists } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import { showAccessListModal, showDeleteConfirmModal, showHelpModal } from "src/modals";
|
||||
import { ACCESS_LISTS, MANAGE } from "src/modules/Permissions";
|
||||
import { showObjectSuccess } from "src/notifications";
|
||||
import Table from "./Table";
|
||||
|
||||
@@ -67,11 +68,17 @@ export default function TableWrapper() {
|
||||
<Button size="sm" onClick={() => showHelpModal("AccessLists", "cyan")}>
|
||||
<IconHelp size={20} />
|
||||
</Button>
|
||||
{data?.length ? (
|
||||
<Button size="sm" className="btn-cyan" onClick={() => showAccessListModal("new")}>
|
||||
<T id="object.add" tData={{ object: "access-list" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
<HasPermission section={ACCESS_LISTS} permission={MANAGE} hideError>
|
||||
{data?.length ? (
|
||||
<Button
|
||||
size="sm"
|
||||
className="btn-cyan"
|
||||
onClick={() => showAccessListModal("new")}
|
||||
>
|
||||
<T id="object.add" tData={{ object: "access-list" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
</HasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { ACCESS_LISTS, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const Access = () => {
|
||||
return (
|
||||
<HasPermission permission="accessLists" type="view" pageLoading loadingNoLogo>
|
||||
<HasPermission section={ACCESS_LISTS} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { ADMIN, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const AuditLog = () => {
|
||||
return (
|
||||
<HasPermission permission="admin" type="manage" pageLoading loadingNoLogo>
|
||||
<HasPermission section={ADMIN} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -8,10 +8,12 @@ import {
|
||||
DomainsFormatter,
|
||||
EmptyData,
|
||||
GravatarFormatter,
|
||||
HasPermission,
|
||||
} from "src/components";
|
||||
import { TableLayout } from "src/components/Table/TableLayout";
|
||||
import { intl, T } from "src/locale";
|
||||
import { showCustomCertificateModal, showDNSCertificateModal, showHTTPCertificateModal } from "src/modals";
|
||||
import { CERTIFICATES, MANAGE } from "src/modules/Permissions";
|
||||
|
||||
interface Props {
|
||||
data: Certificate[];
|
||||
@@ -125,29 +127,31 @@ export default function Table({ data, isFetching, onDelete, onRenew, onDownload,
|
||||
<IconRefresh size={16} />
|
||||
<T id="action.renew" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDownload?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconDownload size={16} />
|
||||
<T id="action.download" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
<HasPermission section={CERTIFICATES} permission={MANAGE} hideError>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDownload?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconDownload size={16} />
|
||||
<T id="action.download" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
</HasPermission>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
@@ -223,6 +227,7 @@ export default function Table({ data, isFetching, onDelete, onRenew, onDownload,
|
||||
isFiltered={isFiltered}
|
||||
color="pink"
|
||||
customAddBtn={customAddBtn}
|
||||
permissionSection={CERTIFICATES}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { IconHelp, IconSearch } from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import Alert from "react-bootstrap/Alert";
|
||||
import { deleteCertificate, downloadCertificate } from "src/api/backend";
|
||||
import { Button, LoadingPage } from "src/components";
|
||||
import { Button, HasPermission, LoadingPage } from "src/components";
|
||||
import { useCertificates } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import {
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
showHTTPCertificateModal,
|
||||
showRenewCertificateModal,
|
||||
} from "src/modals";
|
||||
import { CERTIFICATES, MANAGE } from "src/modules/Permissions";
|
||||
import { showError, showObjectSuccess } from "src/notifications";
|
||||
import Table from "./Table";
|
||||
|
||||
@@ -70,7 +71,6 @@ export default function TableWrapper() {
|
||||
<T id="certificates" />
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="col-md-auto col-sm-12">
|
||||
<div className="ms-auto d-flex flex-wrap btn-list">
|
||||
{data?.length ? (
|
||||
@@ -90,50 +90,52 @@ export default function TableWrapper() {
|
||||
<Button size="sm" onClick={() => showHelpModal("Certificates", "pink")}>
|
||||
<IconHelp size={20} />
|
||||
</Button>
|
||||
{data?.length ? (
|
||||
<div className="dropdown">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm dropdown-toggle btn-pink mt-1"
|
||||
data-bs-toggle="dropdown"
|
||||
>
|
||||
<T id="object.add" tData={{ object: "certificate" }} />
|
||||
</button>
|
||||
<div className="dropdown-menu">
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showHTTPCertificateModal();
|
||||
}}
|
||||
<HasPermission section={CERTIFICATES} permission={MANAGE} hideError>
|
||||
{data?.length ? (
|
||||
<div className="dropdown">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm dropdown-toggle btn-pink mt-1"
|
||||
data-bs-toggle="dropdown"
|
||||
>
|
||||
<T id="lets-encrypt-via-http" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showDNSCertificateModal();
|
||||
}}
|
||||
>
|
||||
<T id="lets-encrypt-via-dns" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showCustomCertificateModal();
|
||||
}}
|
||||
>
|
||||
<T id="certificates.custom" />
|
||||
</a>
|
||||
<T id="object.add" tData={{ object: "certificate" }} />
|
||||
</button>
|
||||
<div className="dropdown-menu">
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showHTTPCertificateModal();
|
||||
}}
|
||||
>
|
||||
<T id="lets-encrypt-via-http" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showDNSCertificateModal();
|
||||
}}
|
||||
>
|
||||
<T id="lets-encrypt-via-dns" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
showCustomCertificateModal();
|
||||
}}
|
||||
>
|
||||
<T id="certificates.custom" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
) : null}
|
||||
</HasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { CERTIFICATES, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const Certificates = () => {
|
||||
return (
|
||||
<HasPermission permission="certificates" type="view" pageLoading loadingNoLogo>
|
||||
<HasPermission section={CERTIFICATES} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { HasPermission } from "src/components";
|
||||
import { useHostReport } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import { DEAD_HOSTS, PROXY_HOSTS, REDIRECTION_HOSTS, STREAMS, VIEW } from "src/modules/Permissions";
|
||||
|
||||
const Dashboard = () => {
|
||||
const { data: hostReport } = useHostReport();
|
||||
@@ -16,7 +17,7 @@ const Dashboard = () => {
|
||||
<div className="row row-deck row-cards">
|
||||
<div className="col-12 my-4">
|
||||
<div className="row row-cards">
|
||||
<HasPermission permission="proxyHosts" type="view" hideError>
|
||||
<HasPermission section={PROXY_HOSTS} permission={VIEW} hideError>
|
||||
<div className="col-sm-6 col-lg-3">
|
||||
<a
|
||||
href="/nginx/proxy"
|
||||
@@ -43,7 +44,7 @@ const Dashboard = () => {
|
||||
</a>
|
||||
</div>
|
||||
</HasPermission>
|
||||
<HasPermission permission="redirectionHosts" type="view" hideError>
|
||||
<HasPermission section={REDIRECTION_HOSTS} permission={VIEW} hideError>
|
||||
<div className="col-sm-6 col-lg-3">
|
||||
<a
|
||||
href="/nginx/redirection"
|
||||
@@ -71,7 +72,7 @@ const Dashboard = () => {
|
||||
</a>
|
||||
</div>
|
||||
</HasPermission>
|
||||
<HasPermission permission="streams" type="view" hideError>
|
||||
<HasPermission section={STREAMS} permission={VIEW} hideError>
|
||||
<div className="col-sm-6 col-lg-3">
|
||||
<a
|
||||
href="/nginx/stream"
|
||||
@@ -96,7 +97,7 @@ const Dashboard = () => {
|
||||
</a>
|
||||
</div>
|
||||
</HasPermission>
|
||||
<HasPermission permission="deadHosts" type="view" hideError>
|
||||
<HasPermission section={DEAD_HOSTS} permission={VIEW} hideError>
|
||||
<div className="col-sm-6 col-lg-3">
|
||||
<a
|
||||
href="/nginx/404"
|
||||
|
||||
@@ -7,10 +7,12 @@ import {
|
||||
DomainsFormatter,
|
||||
EmptyData,
|
||||
GravatarFormatter,
|
||||
HasPermission,
|
||||
TrueFalseFormatter,
|
||||
} from "src/components";
|
||||
import { TableLayout } from "src/components/Table/TableLayout";
|
||||
import { intl, T } from "src/locale";
|
||||
import { DEAD_HOSTS, MANAGE } from "src/modules/Permissions";
|
||||
|
||||
interface Props {
|
||||
data: DeadHost[];
|
||||
@@ -89,29 +91,31 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
||||
<IconEdit size={16} />
|
||||
<T id="action.edit" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
<HasPermission section={DEAD_HOSTS} permission={MANAGE} hideError>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
</HasPermission>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
@@ -146,6 +150,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
||||
onNew={onNew}
|
||||
isFiltered={isFiltered}
|
||||
color="red"
|
||||
permissionSection={DEAD_HOSTS}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -3,10 +3,11 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import Alert from "react-bootstrap/Alert";
|
||||
import { deleteDeadHost, toggleDeadHost } from "src/api/backend";
|
||||
import { Button, LoadingPage } from "src/components";
|
||||
import { Button, HasPermission, LoadingPage } from "src/components";
|
||||
import { useDeadHosts } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import { showDeadHostModal, showDeleteConfirmModal, showHelpModal } from "src/modals";
|
||||
import { DEAD_HOSTS, MANAGE } from "src/modules/Permissions";
|
||||
import { showObjectSuccess } from "src/notifications";
|
||||
import Table from "./Table";
|
||||
|
||||
@@ -76,11 +77,13 @@ export default function TableWrapper() {
|
||||
<Button size="sm" onClick={() => showHelpModal("DeadHosts", "red")}>
|
||||
<IconHelp size={20} />
|
||||
</Button>
|
||||
{data?.length ? (
|
||||
<Button size="sm" className="btn-red" onClick={() => showDeadHostModal("new")}>
|
||||
<T id="object.add" tData={{ object: "dead-host" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
<HasPermission section={DEAD_HOSTS} permission={MANAGE} hideError>
|
||||
{data?.length ? (
|
||||
<Button size="sm" className="btn-red" onClick={() => showDeadHostModal("new")}>
|
||||
<T id="object.add" tData={{ object: "dead-host" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
</HasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { DEAD_HOSTS, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const DeadHosts = () => {
|
||||
return (
|
||||
<HasPermission permission="deadHosts" type="view" pageLoading loadingNoLogo>
|
||||
<HasPermission section={DEAD_HOSTS} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -8,10 +8,12 @@ import {
|
||||
DomainsFormatter,
|
||||
EmptyData,
|
||||
GravatarFormatter,
|
||||
HasPermission,
|
||||
TrueFalseFormatter,
|
||||
} from "src/components";
|
||||
import { TableLayout } from "src/components/Table/TableLayout";
|
||||
import { intl, T } from "src/locale";
|
||||
import { MANAGE, PROXY_HOSTS } from "src/modules/Permissions";
|
||||
|
||||
interface Props {
|
||||
data: ProxyHost[];
|
||||
@@ -105,29 +107,31 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
||||
<IconEdit size={16} />
|
||||
<T id="action.edit" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
<HasPermission section={PROXY_HOSTS} permission={MANAGE} hideError>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
</HasPermission>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
@@ -162,6 +166,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
||||
onNew={onNew}
|
||||
isFiltered={isFiltered}
|
||||
color="lime"
|
||||
permissionSection={PROXY_HOSTS}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -3,10 +3,11 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import Alert from "react-bootstrap/Alert";
|
||||
import { deleteProxyHost, toggleProxyHost } from "src/api/backend";
|
||||
import { Button, LoadingPage } from "src/components";
|
||||
import { Button, HasPermission, LoadingPage } from "src/components";
|
||||
import { useProxyHosts } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import { showDeleteConfirmModal, showHelpModal, showProxyHostModal } from "src/modals";
|
||||
import { MANAGE, PROXY_HOSTS } from "src/modules/Permissions";
|
||||
import { showObjectSuccess } from "src/notifications";
|
||||
import Table from "./Table";
|
||||
|
||||
@@ -59,7 +60,6 @@ export default function TableWrapper() {
|
||||
<T id="proxy-hosts" />
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="col-md-auto col-sm-12">
|
||||
<div className="ms-auto d-flex flex-wrap btn-list">
|
||||
{data?.length ? (
|
||||
@@ -79,11 +79,17 @@ export default function TableWrapper() {
|
||||
<Button size="sm" onClick={() => showHelpModal("ProxyHosts", "lime")}>
|
||||
<IconHelp size={20} />
|
||||
</Button>
|
||||
{data?.length ? (
|
||||
<Button size="sm" className="btn-lime" onClick={() => showProxyHostModal("new")}>
|
||||
<T id="object.add" tData={{ object: "proxy-host" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
<HasPermission section={PROXY_HOSTS} permission={MANAGE} hideError>
|
||||
{data?.length ? (
|
||||
<Button
|
||||
size="sm"
|
||||
className="btn-lime"
|
||||
onClick={() => showProxyHostModal("new")}
|
||||
>
|
||||
<T id="object.add" tData={{ object: "proxy-host" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
</HasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { PROXY_HOSTS, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const ProxyHosts = () => {
|
||||
return (
|
||||
<HasPermission permission="proxyHosts" type="view" pageLoading loadingNoLogo>
|
||||
<HasPermission section={PROXY_HOSTS} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -7,10 +7,12 @@ import {
|
||||
DomainsFormatter,
|
||||
EmptyData,
|
||||
GravatarFormatter,
|
||||
HasPermission,
|
||||
TrueFalseFormatter,
|
||||
} from "src/components";
|
||||
import { TableLayout } from "src/components/Table/TableLayout";
|
||||
import { intl, T } from "src/locale";
|
||||
import { MANAGE, REDIRECTION_HOSTS } from "src/modules/Permissions";
|
||||
|
||||
interface Props {
|
||||
data: RedirectionHost[];
|
||||
@@ -110,29 +112,31 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
||||
<IconEdit size={16} />
|
||||
<T id="action.edit" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
<HasPermission section={REDIRECTION_HOSTS} permission={MANAGE} hideError>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id={info.row.original.enabled ? "action.disable" : "action.enable"} />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
</HasPermission>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
@@ -167,6 +171,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
||||
onNew={onNew}
|
||||
isFiltered={isFiltered}
|
||||
color="yellow"
|
||||
permissionSection={REDIRECTION_HOSTS}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -3,10 +3,11 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import Alert from "react-bootstrap/Alert";
|
||||
import { deleteRedirectionHost, toggleRedirectionHost } from "src/api/backend";
|
||||
import { Button, LoadingPage } from "src/components";
|
||||
import { Button, HasPermission, LoadingPage } from "src/components";
|
||||
import { useRedirectionHosts } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import { showDeleteConfirmModal, showHelpModal, showRedirectionHostModal } from "src/modals";
|
||||
import { MANAGE, REDIRECTION_HOSTS } from "src/modules/Permissions";
|
||||
import { showObjectSuccess } from "src/notifications";
|
||||
import Table from "./Table";
|
||||
|
||||
@@ -59,7 +60,6 @@ export default function TableWrapper() {
|
||||
<T id="redirection-hosts" />
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="col-md-auto col-sm-12">
|
||||
<div className="ms-auto d-flex flex-wrap btn-list">
|
||||
{data?.length ? (
|
||||
@@ -79,15 +79,17 @@ export default function TableWrapper() {
|
||||
<Button size="sm" onClick={() => showHelpModal("RedirectionHosts", "yellow")}>
|
||||
<IconHelp size={20} />
|
||||
</Button>
|
||||
{data?.length ? (
|
||||
<Button
|
||||
size="sm"
|
||||
className="btn-yellow"
|
||||
onClick={() => showRedirectionHostModal("new")}
|
||||
>
|
||||
<T id="object.add" tData={{ object: "redirection-host" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
<HasPermission section={REDIRECTION_HOSTS} permission={MANAGE} hideError>
|
||||
{data?.length ? (
|
||||
<Button
|
||||
size="sm"
|
||||
className="btn-yellow"
|
||||
onClick={() => showRedirectionHostModal("new")}
|
||||
>
|
||||
<T id="object.add" tData={{ object: "redirection-host" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
</HasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { REDIRECTION_HOSTS, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const RedirectionHosts = () => {
|
||||
return (
|
||||
<HasPermission permission="redirectionHosts" type="view" pageLoading loadingNoLogo>
|
||||
<HasPermission section={REDIRECTION_HOSTS} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -6,11 +6,13 @@ import {
|
||||
CertificateFormatter,
|
||||
EmptyData,
|
||||
GravatarFormatter,
|
||||
HasPermission,
|
||||
TrueFalseFormatter,
|
||||
ValueWithDateFormatter,
|
||||
} from "src/components";
|
||||
import { TableLayout } from "src/components/Table/TableLayout";
|
||||
import { intl, T } from "src/locale";
|
||||
import { MANAGE, STREAMS } from "src/modules/Permissions";
|
||||
|
||||
interface Props {
|
||||
data: Stream[];
|
||||
@@ -118,29 +120,31 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete,
|
||||
<IconEdit size={16} />
|
||||
<T id="action.edit" />
|
||||
</a>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id="action.disable" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
<HasPermission section={STREAMS} permission={MANAGE} hideError>
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDisableToggle?.(info.row.original.id, !info.row.original.enabled);
|
||||
}}
|
||||
>
|
||||
<IconPower size={16} />
|
||||
<T id="action.disable" />
|
||||
</a>
|
||||
<div className="dropdown-divider" />
|
||||
<a
|
||||
className="dropdown-item"
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
onDelete?.(info.row.original.id);
|
||||
}}
|
||||
>
|
||||
<IconTrash size={16} />
|
||||
<T id="action.delete" />
|
||||
</a>
|
||||
</HasPermission>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
@@ -175,6 +179,7 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete,
|
||||
onNew={onNew}
|
||||
isFiltered={isFiltered}
|
||||
color="blue"
|
||||
permissionSection={STREAMS}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -3,10 +3,11 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import Alert from "react-bootstrap/Alert";
|
||||
import { deleteStream, toggleStream } from "src/api/backend";
|
||||
import { Button, LoadingPage } from "src/components";
|
||||
import { Button, HasPermission, LoadingPage } from "src/components";
|
||||
import { useStreams } from "src/hooks";
|
||||
import { T } from "src/locale";
|
||||
import { showDeleteConfirmModal, showHelpModal, showStreamModal } from "src/modals";
|
||||
import { MANAGE, STREAMS } from "src/modules/Permissions";
|
||||
import { showObjectSuccess } from "src/notifications";
|
||||
import Table from "./Table";
|
||||
|
||||
@@ -61,7 +62,6 @@ export default function TableWrapper() {
|
||||
<T id="streams" />
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="col-md-auto col-sm-12">
|
||||
<div className="ms-auto d-flex flex-wrap btn-list">
|
||||
{data?.length ? (
|
||||
@@ -81,11 +81,13 @@ export default function TableWrapper() {
|
||||
<Button size="sm" onClick={() => showHelpModal("Streams", "blue")}>
|
||||
<IconHelp size={20} />
|
||||
</Button>
|
||||
{data?.length ? (
|
||||
<Button size="sm" className="btn-blue" onClick={() => showStreamModal("new")}>
|
||||
<T id="object.add" tData={{ object: "stream" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
<HasPermission section={STREAMS} permission={MANAGE} hideError>
|
||||
{data?.length ? (
|
||||
<Button size="sm" className="btn-blue" onClick={() => showStreamModal("new")}>
|
||||
<T id="object.add" tData={{ object: "stream" }} />
|
||||
</Button>
|
||||
) : null}
|
||||
</HasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { STREAMS, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const Streams = () => {
|
||||
return (
|
||||
<HasPermission permission="streams" type="view" pageLoading loadingNoLogo>
|
||||
<HasPermission section={STREAMS} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { ADMIN, VIEW } from "src/modules/Permissions";
|
||||
import Layout from "./Layout";
|
||||
|
||||
const Settings = () => {
|
||||
return (
|
||||
<HasPermission permission="admin" type="manage" pageLoading loadingNoLogo>
|
||||
<HasPermission section={ADMIN} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<Layout />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HasPermission } from "src/components";
|
||||
import { ADMIN, VIEW } from "src/modules/Permissions";
|
||||
import TableWrapper from "./TableWrapper";
|
||||
|
||||
const Users = () => {
|
||||
return (
|
||||
<HasPermission permission="admin" type="manage" pageLoading loadingNoLogo>
|
||||
<HasPermission section={ADMIN} permission={VIEW} pageLoading loadingNoLogo>
|
||||
<TableWrapper />
|
||||
</HasPermission>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user