Fixed Bucket Events Notifications Page (#2906)
- Added missing ilm & replica supported types - Fixed add screen crash when no arn is selected - Migrated components to mds Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
2
go.mod
2
go.mod
@@ -23,7 +23,7 @@ require (
|
||||
github.com/minio/kes v0.22.3
|
||||
github.com/minio/madmin-go/v3 v3.0.2
|
||||
github.com/minio/mc v0.0.0-20230619193119-5f39522e6902
|
||||
github.com/minio/minio-go/v7 v7.0.55-0.20230525060734-b7836f021bfb
|
||||
github.com/minio/minio-go/v7 v7.0.58-0.20230622175401-7048a16cfbca
|
||||
github.com/minio/pkg v1.7.5
|
||||
github.com/minio/selfupdate v0.6.0
|
||||
github.com/minio/websocket v1.6.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -254,8 +254,8 @@ github.com/minio/mc v0.0.0-20230619193119-5f39522e6902 h1:oNewsjSewAfS4Bly8E0cqQ
|
||||
github.com/minio/mc v0.0.0-20230619193119-5f39522e6902/go.mod h1:DZvNh8trMmDzTcxI2WVQeD2f5yd2UDDk9RYsFxaOMaQ=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.55-0.20230525060734-b7836f021bfb h1:oW9owq24i06IMYrfufzdjLH5S4rcOc9M1f7Cak+Ya5I=
|
||||
github.com/minio/minio-go/v7 v7.0.55-0.20230525060734-b7836f021bfb/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE=
|
||||
github.com/minio/minio-go/v7 v7.0.58-0.20230622175401-7048a16cfbca h1:/cqQl5kUAeTVVfTiJTWN0r4USgUBhjqfwamlnvBqW9k=
|
||||
github.com/minio/minio-go/v7 v7.0.58-0.20230622175401-7048a16cfbca/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE=
|
||||
github.com/minio/mux v1.9.0 h1:dWafQFyEfGhJvK6AwLOt83bIG5bxKxKJnKMCi0XAaoA=
|
||||
github.com/minio/pkg v1.7.5 h1:UOUJjewE5zoaDPlCMJtNx/swc1jT1ZR+IajT7hrLd44=
|
||||
github.com/minio/pkg v1.7.5/go.mod h1:mEfGMTm5Z0b5EGxKNuPwyb5A2d+CC/VlUyRj6RJtIwo=
|
||||
|
||||
@@ -55,6 +55,12 @@ const (
|
||||
|
||||
// NotificationEventTypeGet captures enum value "get"
|
||||
NotificationEventTypeGet NotificationEventType = "get"
|
||||
|
||||
// NotificationEventTypeReplica captures enum value "replica"
|
||||
NotificationEventTypeReplica NotificationEventType = "replica"
|
||||
|
||||
// NotificationEventTypeIlm captures enum value "ilm"
|
||||
NotificationEventTypeIlm NotificationEventType = "ilm"
|
||||
)
|
||||
|
||||
// for schema
|
||||
@@ -62,7 +68,7 @@ var notificationEventTypeEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []NotificationEventType
|
||||
if err := json.Unmarshal([]byte(`["put","delete","get"]`), &res); err != nil {
|
||||
if err := json.Unmarshal([]byte(`["put","delete","get","replica","ilm"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
|
||||
@@ -291,6 +291,8 @@ export enum NotificationEventType {
|
||||
Put = "put",
|
||||
Delete = "delete",
|
||||
Get = "get",
|
||||
Replica = "replica",
|
||||
Ilm = "ilm",
|
||||
}
|
||||
|
||||
export interface NotificationConfig {
|
||||
|
||||
@@ -14,53 +14,28 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { ChangeEvent, useCallback, useEffect, useState } from "react";
|
||||
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { Button, EventSubscriptionIcon } from "mds";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import TableHead from "@mui/material/TableHead";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import Checkbox from "@mui/material/Checkbox";
|
||||
import Table from "@mui/material/Table";
|
||||
import {
|
||||
formFieldStyles,
|
||||
modalStyleUtils,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Button, DataTable, EventSubscriptionIcon, Grid, InputBox } from "mds";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import AutocompleteWrapper from "../../Common/FormComponents/AutocompleteWrapper/AutocompleteWrapper";
|
||||
import { setModalErrorSnackMessage } from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
import { api } from "api";
|
||||
import { NotificationEventType } from "api/consoleApi";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
arnField: {
|
||||
"& div div .MuiOutlinedInput-root": {
|
||||
padding: 0,
|
||||
},
|
||||
},
|
||||
...formFieldStyles,
|
||||
...modalStyleUtils,
|
||||
});
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import AutocompleteWrapper from "../../Common/FormComponents/AutocompleteWrapper/AutocompleteWrapper";
|
||||
import {
|
||||
formFieldStyles,
|
||||
modalBasic,
|
||||
modalStyleUtils,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
interface IAddEventProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
selectedBucket: string;
|
||||
closeModalAndRefresh: () => void;
|
||||
}
|
||||
|
||||
const AddEvent = ({
|
||||
classes,
|
||||
open,
|
||||
selectedBucket,
|
||||
closeModalAndRefresh,
|
||||
@@ -125,28 +100,27 @@ const AddEvent = ({
|
||||
{ label: "PUT - Object Uploaded", value: NotificationEventType.Put },
|
||||
{ label: "GET - Object accessed", value: NotificationEventType.Get },
|
||||
{ label: "DELETE - Object Deleted", value: NotificationEventType.Delete },
|
||||
{
|
||||
label: "REPLICA - Object Replicated",
|
||||
value: NotificationEventType.Replica,
|
||||
},
|
||||
{ label: "ILM - Object Transitioned", value: NotificationEventType.Ilm },
|
||||
];
|
||||
|
||||
const handleClick = (
|
||||
event: React.MouseEvent<unknown> | ChangeEvent<unknown>,
|
||||
name: NotificationEventType
|
||||
) => {
|
||||
const selectedIndex = selectedEvents.indexOf(name);
|
||||
let newSelected: NotificationEventType[] = [];
|
||||
const handleClick = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const targetD = event.target;
|
||||
const value = targetD.value;
|
||||
const checked = targetD.checked;
|
||||
|
||||
if (selectedIndex === -1) {
|
||||
newSelected = newSelected.concat(selectedEvents, name);
|
||||
} else if (selectedIndex === 0) {
|
||||
newSelected = newSelected.concat(selectedEvents.slice(1));
|
||||
} else if (selectedIndex === selectedEvents.length - 1) {
|
||||
newSelected = newSelected.concat(selectedEvents.slice(0, -1));
|
||||
} else if (selectedIndex > 0) {
|
||||
newSelected = newSelected.concat(
|
||||
selectedEvents.slice(0, selectedIndex),
|
||||
selectedEvents.slice(selectedIndex + 1)
|
||||
);
|
||||
let elements: NotificationEventType[] = [...selectedEvents];
|
||||
|
||||
if (checked) {
|
||||
elements.push(value as NotificationEventType);
|
||||
} else {
|
||||
elements = elements.filter((element) => element !== value);
|
||||
}
|
||||
setSelectedEvents(newSelected);
|
||||
|
||||
setSelectedEvents(elements);
|
||||
};
|
||||
|
||||
const arnValues = arnList?.map((arnConstant) => ({
|
||||
@@ -171,11 +145,16 @@ const AddEvent = ({
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
<Grid item xs={12} sx={modalBasic.formScrollable}>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={`${classes.arnField} ${classes.formFieldRow}`}
|
||||
sx={{
|
||||
...formFieldStyles.formFieldRow,
|
||||
"& div div .MuiOutlinedInput-root": {
|
||||
padding: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<AutocompleteWrapper
|
||||
onChange={(value: string) => {
|
||||
@@ -188,8 +167,8 @@ const AddEvent = ({
|
||||
options={arnValues || []}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
<Grid item xs={12} sx={formFieldStyles.formFieldRow}>
|
||||
<InputBox
|
||||
id="prefix-input"
|
||||
name="prefix-input"
|
||||
label="Prefix"
|
||||
@@ -199,8 +178,8 @@ const AddEvent = ({
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
<Grid item xs={12} sx={formFieldStyles.formFieldRow}>
|
||||
<InputBox
|
||||
id="suffix-input"
|
||||
name="suffix-input"
|
||||
label="Suffix"
|
||||
@@ -210,41 +189,19 @@ const AddEvent = ({
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Table size="medium">
|
||||
<TableHead className={classes.minTableHeader}>
|
||||
<TableRow>
|
||||
<TableCell>Select</TableCell>
|
||||
<TableCell>Event</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{events.map((row) => (
|
||||
<TableRow
|
||||
key={`group-${row.value}`}
|
||||
onClick={(event) => handleClick(event, row.value)}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
value={row.value}
|
||||
color="primary"
|
||||
inputProps={{
|
||||
"aria-label": "secondary checkbox",
|
||||
}}
|
||||
onChange={(event) => handleClick(event, row.value)}
|
||||
checked={selectedEvents.includes(row.value)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.wrapCell}>
|
||||
{row.label}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Grid item xs={12} sx={formFieldStyles.formFieldRow}>
|
||||
<DataTable
|
||||
columns={[{ label: "Event", elementKey: "label" }]}
|
||||
idField={"value"}
|
||||
records={events}
|
||||
onSelect={handleClick}
|
||||
selectedItems={selectedEvents}
|
||||
noBackground
|
||||
customPaperHeight={"260px"}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.modalButtonBar}>
|
||||
<Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
|
||||
<Button
|
||||
id={"cancel-add-event"}
|
||||
type="button"
|
||||
@@ -259,7 +216,7 @@ const AddEvent = ({
|
||||
id={"save-event"}
|
||||
type="submit"
|
||||
variant="callAction"
|
||||
disabled={addLoading}
|
||||
disabled={addLoading || arn === "" || selectedEvents.length === 0}
|
||||
label={"Save"}
|
||||
/>
|
||||
</Grid>
|
||||
@@ -269,4 +226,4 @@ const AddEvent = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddEvent);
|
||||
export default AddEvent;
|
||||
|
||||
@@ -15,53 +15,30 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import get from "lodash/get";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { AddIcon, Button, HelpBox, LambdaIcon } from "mds";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import get from "lodash/get";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import {
|
||||
actionsTray,
|
||||
searchField,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
|
||||
|
||||
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
|
||||
import { AddIcon, Button, HelpBox, LambdaIcon, DataTable, Grid } from "mds";
|
||||
import { api } from "api";
|
||||
import { NotificationConfig } from "api/consoleApi";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import { actionsTray } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
hasPermission,
|
||||
SecureComponent,
|
||||
} from "../../../../common/SecureComponent";
|
||||
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
|
||||
|
||||
import withSuspense from "../../Common/Components/withSuspense";
|
||||
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
|
||||
import { selBucketDetailsLoading } from "./bucketDetailsSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
|
||||
import withSuspense from "../../Common/Components/withSuspense";
|
||||
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
|
||||
import { api } from "api";
|
||||
import { NotificationConfig } from "api/consoleApi";
|
||||
import { errorToHandler } from "api/errors";
|
||||
|
||||
const DeleteEvent = withSuspense(React.lazy(() => import("./DeleteEvent")));
|
||||
const AddEvent = withSuspense(React.lazy(() => import("./AddEvent")));
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...searchField,
|
||||
...actionsTray,
|
||||
twHeight: {
|
||||
minHeight: 400,
|
||||
},
|
||||
});
|
||||
|
||||
interface IBucketEventsProps {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const BucketEventsPanel = ({ classes }: IBucketEventsProps) => {
|
||||
const BucketEventsPanel = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const params = useParams();
|
||||
|
||||
@@ -155,7 +132,7 @@ const BucketEventsPanel = ({ classes }: IBucketEventsProps) => {
|
||||
)}
|
||||
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<Grid item xs={12} sx={actionsTray.actionsTray}>
|
||||
<PanelTitle>Events</PanelTitle>
|
||||
<SecureComponent
|
||||
scopes={[
|
||||
@@ -189,7 +166,7 @@ const BucketEventsPanel = ({ classes }: IBucketEventsProps) => {
|
||||
resource={bucketName}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<TableWrapper
|
||||
<DataTable
|
||||
itemActions={tableActions}
|
||||
columns={[
|
||||
{ label: "SQS", elementKey: "arn" },
|
||||
@@ -205,7 +182,7 @@ const BucketEventsPanel = ({ classes }: IBucketEventsProps) => {
|
||||
records={records}
|
||||
entityName="Events"
|
||||
idField="id"
|
||||
customPaperHeight={classes.twHeight}
|
||||
customPaperHeight={"400px"}
|
||||
/>
|
||||
</SecureComponent>
|
||||
</Grid>
|
||||
@@ -242,4 +219,4 @@ const BucketEventsPanel = ({ classes }: IBucketEventsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(BucketEventsPanel);
|
||||
export default BucketEventsPanel;
|
||||
|
||||
@@ -14,11 +14,8 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import React, { Fragment } from "react";
|
||||
import get from "lodash/get";
|
||||
|
||||
import { DialogContentText } from "@mui/material";
|
||||
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import useApi from "../../Common/Hooks/useApi";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
@@ -82,9 +79,7 @@ const DeleteEvent = ({
|
||||
onConfirm={onConfirmDelete}
|
||||
onClose={onClose}
|
||||
confirmationContent={
|
||||
<DialogContentText>
|
||||
Are you sure you want to delete this event?
|
||||
</DialogContentText>
|
||||
<Fragment>Are you sure you want to delete this event?</Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -7433,7 +7433,9 @@ func init() {
|
||||
"enum": [
|
||||
"put",
|
||||
"delete",
|
||||
"get"
|
||||
"get",
|
||||
"replica",
|
||||
"ilm"
|
||||
]
|
||||
},
|
||||
"objectBucketLifecycle": {
|
||||
@@ -16564,7 +16566,9 @@ func init() {
|
||||
"enum": [
|
||||
"put",
|
||||
"delete",
|
||||
"get"
|
||||
"get",
|
||||
"replica",
|
||||
"ilm"
|
||||
]
|
||||
},
|
||||
"objectBucketLifecycle": {
|
||||
|
||||
@@ -73,7 +73,14 @@ func listBucketEvents(client MinioClient, bucketName string) ([]*models.Notifica
|
||||
eventTypePretty = models.NotificationEventTypePut
|
||||
case notification.ObjectRemovedAll:
|
||||
eventTypePretty = models.NotificationEventTypeDelete
|
||||
case notification.ObjectReplicationAll:
|
||||
eventTypePretty = models.NotificationEventTypeReplica
|
||||
case notification.ObjectTransitionAll:
|
||||
eventTypePretty = models.NotificationEventTypeIlm
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, eventTypePretty)
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -4044,6 +4044,8 @@ definitions:
|
||||
- put
|
||||
- delete
|
||||
- get
|
||||
- replica
|
||||
- ilm
|
||||
notificationConfig:
|
||||
type: object
|
||||
required:
|
||||
|
||||
Reference in New Issue
Block a user