mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-04-07 02:53:38 +00:00
173 lines
6.9 KiB
TypeScript
173 lines
6.9 KiB
TypeScript
import React, { useState } from "react";
|
|
import { Button, Menu, MenuItem, Box, Tooltip, IconButton, Divider, TextField, InputAdornment } from "@mui/material";
|
|
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
|
import InventoryIcon from "@mui/icons-material/Inventory";
|
|
import AddIcon from "@mui/icons-material/Add";
|
|
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
|
import DownloadIcon from "@mui/icons-material/Download";
|
|
import ReplayIcon from "@mui/icons-material/Replay";
|
|
import DeleteIcon from "@mui/icons-material/Delete";
|
|
import VpnKeyIcon from "@mui/icons-material/VpnKey";
|
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
|
import FileDownloadIcon from "@mui/icons-material/FileDownload";
|
|
import SearchIcon from "@mui/icons-material/Search";
|
|
import ClearIcon from "@mui/icons-material/Clear";
|
|
import AutoRefreshControl from "components/common/AutoRefreshControl";
|
|
import type { AutoRefreshInterval } from "api/types/AutoRefreshInterval";
|
|
import type { BuildStatus } from "api/types/BuildStatus";
|
|
import { StatusColors } from "theme/status/StatusColors";
|
|
|
|
export interface AutoRefreshProps {
|
|
intervals: AutoRefreshInterval[];
|
|
enabled: boolean;
|
|
currentInterval: number;
|
|
onToggle: (enabled: boolean) => void;
|
|
onIntervalChange: (interval: number) => void;
|
|
}
|
|
|
|
export interface ToolbarActions {
|
|
onDashboardClick: () => void;
|
|
onAddClick: () => void;
|
|
onUpdateClick: () => void;
|
|
onRefreshDbClick: () => void;
|
|
onRebuildClick: () => void;
|
|
onRemoveClick: () => void;
|
|
onKeyImportClick: () => void;
|
|
onReloadClick: () => void;
|
|
onExportClick: () => void;
|
|
}
|
|
|
|
interface PackageTableToolbarProps {
|
|
hasSelection: boolean;
|
|
isAuthorized: boolean;
|
|
repoStatus?: BuildStatus;
|
|
searchText: string;
|
|
onSearchChange: (text: string) => void;
|
|
autoRefresh: AutoRefreshProps;
|
|
actions: ToolbarActions;
|
|
}
|
|
|
|
export default function PackageTableToolbar({
|
|
hasSelection,
|
|
isAuthorized,
|
|
repoStatus,
|
|
searchText,
|
|
onSearchChange,
|
|
autoRefresh,
|
|
actions,
|
|
}: PackageTableToolbarProps): React.JSX.Element {
|
|
const [packagesAnchorEl, setPackagesAnchorEl] = useState<null | HTMLElement>(null);
|
|
|
|
return (
|
|
<Box sx={{ display: "flex", gap: 1, mb: 1, flexWrap: "wrap", alignItems: "center" }}>
|
|
<Tooltip title="System health">
|
|
<IconButton
|
|
aria-label="System health"
|
|
onClick={actions.onDashboardClick}
|
|
sx={{
|
|
borderColor: repoStatus ? StatusColors[repoStatus] : undefined,
|
|
borderWidth: 1,
|
|
borderStyle: "solid",
|
|
color: repoStatus ? StatusColors[repoStatus] : undefined,
|
|
}}
|
|
>
|
|
<InfoOutlinedIcon />
|
|
</IconButton>
|
|
</Tooltip>
|
|
|
|
{isAuthorized && (
|
|
<>
|
|
<Button
|
|
variant="contained"
|
|
startIcon={<InventoryIcon />}
|
|
onClick={(e) => setPackagesAnchorEl(e.currentTarget)}
|
|
>
|
|
packages
|
|
</Button>
|
|
<Menu
|
|
anchorEl={packagesAnchorEl}
|
|
open={Boolean(packagesAnchorEl)}
|
|
onClose={() => setPackagesAnchorEl(null)}
|
|
>
|
|
<MenuItem onClick={() => {
|
|
setPackagesAnchorEl(null); actions.onAddClick();
|
|
}}>
|
|
<AddIcon fontSize="small" sx={{ mr: 1 }} /> add
|
|
</MenuItem>
|
|
<MenuItem onClick={() => {
|
|
setPackagesAnchorEl(null); actions.onUpdateClick();
|
|
}}>
|
|
<PlayArrowIcon fontSize="small" sx={{ mr: 1 }} /> update
|
|
</MenuItem>
|
|
<MenuItem onClick={() => {
|
|
setPackagesAnchorEl(null); actions.onRefreshDbClick();
|
|
}}>
|
|
<DownloadIcon fontSize="small" sx={{ mr: 1 }} /> update pacman databases
|
|
</MenuItem>
|
|
<MenuItem onClick={() => {
|
|
setPackagesAnchorEl(null); actions.onRebuildClick();
|
|
}}>
|
|
<ReplayIcon fontSize="small" sx={{ mr: 1 }} /> rebuild
|
|
</MenuItem>
|
|
<Divider />
|
|
<MenuItem onClick={() => {
|
|
setPackagesAnchorEl(null); actions.onRemoveClick();
|
|
}} disabled={!hasSelection}>
|
|
<DeleteIcon fontSize="small" sx={{ mr: 1 }} /> remove
|
|
</MenuItem>
|
|
</Menu>
|
|
|
|
<Button variant="contained" color="info" startIcon={<VpnKeyIcon />} onClick={actions.onKeyImportClick}>
|
|
import key
|
|
</Button>
|
|
</>
|
|
)}
|
|
|
|
<Button variant="outlined" color="secondary" startIcon={<RefreshIcon />} onClick={actions.onReloadClick}>
|
|
reload
|
|
</Button>
|
|
|
|
<AutoRefreshControl
|
|
intervals={autoRefresh.intervals}
|
|
enabled={autoRefresh.enabled}
|
|
currentInterval={autoRefresh.currentInterval}
|
|
onToggle={autoRefresh.onToggle}
|
|
onIntervalChange={autoRefresh.onIntervalChange}
|
|
/>
|
|
|
|
<Box sx={{ flexGrow: 1 }} />
|
|
|
|
<TextField
|
|
size="small"
|
|
aria-label="Search packages"
|
|
placeholder="search packages..."
|
|
value={searchText}
|
|
onChange={(e) => onSearchChange(e.target.value)}
|
|
slotProps={{
|
|
input: {
|
|
startAdornment: (
|
|
<InputAdornment position="start">
|
|
<SearchIcon fontSize="small" />
|
|
</InputAdornment>
|
|
),
|
|
endAdornment: searchText ? (
|
|
<InputAdornment position="end">
|
|
<IconButton size="small" aria-label="Clear search" onClick={() => onSearchChange("")}>
|
|
<ClearIcon fontSize="small" />
|
|
</IconButton>
|
|
</InputAdornment>
|
|
) : undefined,
|
|
},
|
|
}}
|
|
sx={{ minWidth: 200 }}
|
|
/>
|
|
|
|
<Tooltip title="Export CSV">
|
|
<IconButton size="small" aria-label="Export CSV" onClick={actions.onExportClick}>
|
|
<FileDownloadIcon fontSize="small" />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</Box>
|
|
);
|
|
}
|