691 lines
22 KiB
TypeScript
691 lines
22 KiB
TypeScript
import {
|
|
Checkbox,
|
|
FormControlLabel,
|
|
Paper,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableRow,
|
|
Tooltip,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import React from "react";
|
|
import { NWFilter } from "../../api/NWFilterApi";
|
|
import { NetworkInfo } from "../../api/NetworksApi";
|
|
import { ServerApi } from "../../api/ServerApi";
|
|
import { APIToken, TokenRight } from "../../api/TokensApi";
|
|
import { VMInfo } from "../../api/VMApi";
|
|
|
|
export function TokenRightsEditor(p: {
|
|
token: APIToken;
|
|
editable: boolean;
|
|
onChange?: () => void;
|
|
vms: VMInfo[];
|
|
networks: NetworkInfo[];
|
|
nwFilters: NWFilter[];
|
|
tokens: APIToken[];
|
|
}): React.ReactElement {
|
|
return (
|
|
<>
|
|
{/* Virtual machines */}
|
|
<RightsSection label="Virtual machines">
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "POST", path: "/api/vm/create" }}
|
|
label="Create a new virtual machine"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/list" }}
|
|
label="Get list of virtual machines"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vnc" }}
|
|
label="Establish VNC connection"
|
|
/>
|
|
</RightsSection>
|
|
|
|
<RightsSection label="VM configuration management">
|
|
<Table size="small">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>VM name</TableCell>
|
|
<TableCell align="center">Get definition</TableCell>
|
|
<TableCell align="center">Update</TableCell>
|
|
<TableCell align="center">Delete</TableCell>
|
|
<TableCell align="center">Get XML definition</TableCell>
|
|
<TableCell align="center">Get autostart</TableCell>
|
|
<TableCell align="center">Set autostart</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{/* All VM operations */}
|
|
<TableRow hover>
|
|
<TableCell>
|
|
<i>All</i>
|
|
</TableCell>
|
|
<CellRight {...p} right={{ verb: "GET", path: "/api/vm/*" }} />
|
|
<CellRight {...p} right={{ verb: "PUT", path: "/api/vm/*" }} />
|
|
<CellRight {...p} right={{ verb: "DELETE", path: "/api/vm/*" }} />
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/src" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/autostart" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: "/api/vm/*/autostart" }}
|
|
/>
|
|
</TableRow>
|
|
|
|
{/* Per VM operations */}
|
|
{p.vms.map((v, n) => (
|
|
<TableRow hover key={n}>
|
|
<TableCell>{v.name}</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: `/api/vm/${v.uuid}` }}
|
|
parent={{ verb: "PUT", path: "/api/vm/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: `/api/vm/${v.uuid}` }}
|
|
parent={{ verb: "DELETE", path: "/api/vm/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/src` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/src" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/autostart` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/autostart" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: `/api/vm/${v.uuid}/autostart` }}
|
|
parent={{ verb: "PUT", path: "/api/vm/*/autostart" }}
|
|
/>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</RightsSection>
|
|
|
|
<RightsSection label="VM maintenance">
|
|
<Table size="small">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>VM name</TableCell>
|
|
<TableCell align="center">Get state</TableCell>
|
|
<TableCell align="center">Start</TableCell>
|
|
<TableCell align="center">Shutdown</TableCell>
|
|
<TableCell align="center">Kill</TableCell>
|
|
<TableCell align="center">Reset</TableCell>
|
|
<TableCell align="center">Suspend</TableCell>
|
|
<TableCell align="center">Resume</TableCell>
|
|
<TableCell align="center">Screenshot</TableCell>
|
|
<TableCell align="center">VNC token</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{/* All VM operations */}
|
|
<TableRow hover>
|
|
<TableCell>
|
|
<i>All</i>
|
|
</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/state" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/start" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/shutdown" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/kill" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/reset" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/suspend" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/resume" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/screenshot" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/vm/*/vnc" }}
|
|
/>
|
|
</TableRow>
|
|
|
|
{/* Per VM operations */}
|
|
{p.vms.map((v, n) => (
|
|
<TableRow hover key={n}>
|
|
<TableCell>{v.name}</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/state` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/state" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/start` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/start" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/shutdown` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/shutdown" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/kill` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/kill" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/reset` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/reset" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/suspend` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/suspend" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/resume` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/resume" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/screenshot` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/screenshot" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/vm/${v.uuid}/vnc` }}
|
|
parent={{ verb: "GET", path: "/api/vm/*/vnc" }}
|
|
/>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</RightsSection>
|
|
|
|
{/* Networks */}
|
|
<RightsSection label="Networks">
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "POST", path: "/api/network/create" }}
|
|
label="Create a new network"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/list" }}
|
|
label="Get list of networks"
|
|
/>
|
|
</RightsSection>
|
|
|
|
{/* Networks management */}
|
|
<RightsSection label="Networks management">
|
|
<Table size="small">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Network name</TableCell>
|
|
<TableCell align="center">Get definition</TableCell>
|
|
<TableCell align="center">Update</TableCell>
|
|
<TableCell align="center">Delete</TableCell>
|
|
<TableCell align="center">Get XML definition</TableCell>
|
|
<TableCell align="center">Get autostart</TableCell>
|
|
<TableCell align="center">Set autostart</TableCell>
|
|
<TableCell align="center">Get status</TableCell>
|
|
<TableCell align="center">Start</TableCell>
|
|
<TableCell align="center">Stop</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{/* All networks operations */}
|
|
<TableRow hover>
|
|
<TableCell>
|
|
<i>All</i>
|
|
</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: "/api/network/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: "/api/network/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/*/src" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/*/autostart" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: "/api/network/*/autostart" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/*/status" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/*/start" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/network/*/stop" }}
|
|
/>
|
|
</TableRow>
|
|
|
|
{/* Per network operations */}
|
|
{p.networks.map((v, n) => (
|
|
<TableRow hover key={n}>
|
|
<TableCell>{v.name}</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/network/${v.uuid}` }}
|
|
parent={{ verb: "GET", path: "/api/network/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: `/api/network/${v.uuid}` }}
|
|
parent={{ verb: "PUT", path: "/api/network/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: `/api/network/${v.uuid}` }}
|
|
parent={{ verb: "DELETE", path: "/api/network/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/network/${v.uuid}/src` }}
|
|
parent={{ verb: "GET", path: "/api/network/*/src" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{
|
|
verb: "GET",
|
|
path: `/api/network/${v.uuid}/autostart`,
|
|
}}
|
|
parent={{ verb: "GET", path: "/api/network/*/autostart" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{
|
|
verb: "PUT",
|
|
path: `/api/network/${v.uuid}/autostart`,
|
|
}}
|
|
parent={{ verb: "PUT", path: "/api/network/*/autostart" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{
|
|
verb: "GET",
|
|
path: `/api/network/${v.uuid}/status`,
|
|
}}
|
|
parent={{ verb: "GET", path: "/api/network/*/status" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{
|
|
verb: "GET",
|
|
path: `/api/network/${v.uuid}/start`,
|
|
}}
|
|
parent={{ verb: "GET", path: "/api/network/*/start" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{
|
|
verb: "GET",
|
|
path: `/api/network/${v.uuid}/stop`,
|
|
}}
|
|
parent={{ verb: "GET", path: "/api/network/*/stop" }}
|
|
/>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</RightsSection>
|
|
|
|
{/* Network filters */}
|
|
<RightsSection label="Network filters">
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "POST", path: "/api/nwfilter/create" }}
|
|
label="Create a new network filter"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/nwfilter/list" }}
|
|
label="Get list of network filters"
|
|
/>
|
|
</RightsSection>
|
|
|
|
{/* Networks filters management */}
|
|
<RightsSection label="Networks filters management">
|
|
<Table size="small">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Network filter name</TableCell>
|
|
<TableCell align="center">Get definition</TableCell>
|
|
<TableCell align="center">Update</TableCell>
|
|
<TableCell align="center">Delete</TableCell>
|
|
<TableCell align="center">Get XML definition</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{/* All networks filters operations */}
|
|
<TableRow hover>
|
|
<TableCell>
|
|
<i>All</i>
|
|
</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/nwfilter/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: "/api/nwfilter/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: "/api/nwfilter/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/nwfilter/*/src" }}
|
|
/>
|
|
</TableRow>
|
|
|
|
{/* Per network filter operations */}
|
|
{p.nwFilters.map((v, n) => (
|
|
<TableRow hover key={n}>
|
|
<TableCell>{v.name}</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/nwfilter/${v.uuid}` }}
|
|
parent={{ verb: "GET", path: "/api/nwfilter/*" }}
|
|
/>
|
|
{ServerApi.Config.builtin_nwfilter_rules.includes(v.name!) ? (
|
|
<TableCell></TableCell>
|
|
) : (
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: `/api/nwfilter/${v.uuid}` }}
|
|
parent={{ verb: "PUT", path: "/api/nwfilter/*" }}
|
|
/>
|
|
)}
|
|
{ServerApi.Config.builtin_nwfilter_rules.includes(v.name!) ? (
|
|
<TableCell></TableCell>
|
|
) : (
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: `/api/nwfilter/${v.uuid}` }}
|
|
parent={{ verb: "DELETE", path: "/api/nwfilter/*" }}
|
|
/>
|
|
)}
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/nwfilter/${v.uuid}/src` }}
|
|
parent={{ verb: "GET", path: "/api/nwfilter/*/src" }}
|
|
/>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</RightsSection>
|
|
|
|
{/* API tokens */}
|
|
<RightsSection label="API tokens">
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "POST", path: "/api/token/create" }}
|
|
label="Create a new API token"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/token/list" }}
|
|
label="Get list of API tokens"
|
|
/>
|
|
</RightsSection>
|
|
|
|
{/* API tokens management */}
|
|
<RightsSection label="API tokens management">
|
|
<Table size="small">
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>API token name</TableCell>
|
|
<TableCell align="center">Get</TableCell>
|
|
<TableCell align="center">Update</TableCell>
|
|
<TableCell align="center">Delete</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{/* All API tokens operations */}
|
|
<TableRow hover>
|
|
<TableCell>
|
|
<i>All</i>
|
|
</TableCell>
|
|
<CellRight {...p} right={{ verb: "GET", path: "/api/token/*" }} />
|
|
<CellRight {...p} right={{ verb: "PUT", path: "/api/token/*" }} />
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: "/api/token/*" }}
|
|
/>
|
|
</TableRow>
|
|
|
|
{/* Per API token operations */}
|
|
{p.tokens.map((v, n) => (
|
|
<TableRow hover key={n}>
|
|
<TableCell>{v.name}</TableCell>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "GET", path: `/api/token/${v.id}` }}
|
|
parent={{ verb: "GET", path: "/api/token/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "PUT", path: `/api/token/${v.id}` }}
|
|
parent={{ verb: "PUT", path: "/api/token/*" }}
|
|
/>
|
|
<CellRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: `/api/token/${v.id}` }}
|
|
parent={{ verb: "DELETE", path: "/api/token/*" }}
|
|
/>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</RightsSection>
|
|
|
|
{/* ISO files */}
|
|
<RightsSection label="ISO files">
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "POST", path: "/api/iso/upload" }}
|
|
label="Upload a new ISO file"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "POST", path: "/api/iso/upload_from_url" }}
|
|
label="Upload a new ISO file from a given URL"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/iso/list" }}
|
|
label="Get the list of ISO files"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/iso/*" }}
|
|
label="Download ISO files"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "DELETE", path: "/api/iso/*" }}
|
|
label="Delete ISO files"
|
|
/>
|
|
</RightsSection>
|
|
|
|
{/* Server general information */}
|
|
<RightsSection label="Server">
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/server/static_config" }}
|
|
label="Get static server configuration"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/server/info" }}
|
|
label="Get server information"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/server/network_hook_status" }}
|
|
label="Get network hook status"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/server/number_vcpus" }}
|
|
label="Get number of vCPU"
|
|
/>
|
|
<RouteRight
|
|
{...p}
|
|
right={{ verb: "GET", path: "/api/server/networks" }}
|
|
label="Get list of network cards"
|
|
/>
|
|
</RightsSection>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function RightsSection(
|
|
p: React.PropsWithChildren<{ label: string }>
|
|
): React.ReactElement {
|
|
return (
|
|
<Paper style={{ padding: "20px", margin: "10px" }}>
|
|
<Typography variant="h5">{p.label}</Typography>
|
|
{p.children}
|
|
</Paper>
|
|
);
|
|
}
|
|
|
|
interface RightOpts {
|
|
right: TokenRight;
|
|
label?: string;
|
|
editable: boolean;
|
|
token: APIToken;
|
|
onChange?: () => void;
|
|
parent?: TokenRight;
|
|
}
|
|
|
|
function CellRight(p: RightOpts): React.ReactElement {
|
|
return (
|
|
<TableCell align="center">
|
|
<RouteRight {...p} />
|
|
</TableCell>
|
|
);
|
|
}
|
|
|
|
function RouteRight(p: RightOpts): React.ReactElement {
|
|
const rightIndex = p.token.rights.findIndex(
|
|
(r) => r.verb === p.right.verb && r.path === p.right.path
|
|
);
|
|
const activated = rightIndex !== -1;
|
|
|
|
const parentActivated =
|
|
!!p.parent &&
|
|
p.token.rights.findIndex(
|
|
(r) => r.verb === p.parent?.verb && r.path === p.parent?.path
|
|
) !== -1;
|
|
|
|
const toggle = (a: boolean) => {
|
|
if (a) {
|
|
p.token.rights.push(p.right);
|
|
} else {
|
|
p.token.rights.splice(rightIndex, 1);
|
|
}
|
|
p.onChange?.();
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Tooltip
|
|
title={`${p.right.verb} ${p.right.path}`}
|
|
arrow
|
|
placement="left"
|
|
slotProps={{
|
|
popper: {
|
|
modifiers: [
|
|
{
|
|
name: "offset",
|
|
options: {
|
|
offset: [0, -14],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}}
|
|
>
|
|
{p.label ? (
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={activated || parentActivated}
|
|
disabled={!p.editable || parentActivated}
|
|
onChange={(_e, a) => toggle(a)}
|
|
/>
|
|
}
|
|
label={p.label}
|
|
/>
|
|
) : (
|
|
<span>
|
|
<Checkbox
|
|
checked={activated || parentActivated}
|
|
disabled={!p.editable || parentActivated}
|
|
onChange={(_e, a) => toggle(a)}
|
|
/>
|
|
</span>
|
|
)}
|
|
</Tooltip>
|
|
</div>
|
|
);
|
|
}
|