Fixed Object Version selector visibility in Add Lifecycle Rule modal (#2769)
- Fixed Object Version selector visibility in Add Lifecycle Rule modal - Changed definition in swagger file to match camelCase standard - Added a playwright test case to avoid this issue in the future Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -36,17 +36,17 @@ import (
|
||||
// swagger:model bucketVersioningResponse
|
||||
type BucketVersioningResponse struct {
|
||||
|
||||
// exclude folders
|
||||
ExcludeFolders bool `json:"ExcludeFolders,omitempty"`
|
||||
|
||||
// excluded prefixes
|
||||
ExcludedPrefixes []*BucketVersioningResponseExcludedPrefixesItems0 `json:"ExcludedPrefixes"`
|
||||
|
||||
// m f a delete
|
||||
MFADelete string `json:"MFADelete,omitempty"`
|
||||
|
||||
// exclude folders
|
||||
ExcludeFolders bool `json:"excludeFolders,omitempty"`
|
||||
|
||||
// excluded prefixes
|
||||
ExcludedPrefixes []*BucketVersioningResponseExcludedPrefixesItems0 `json:"excludedPrefixes"`
|
||||
|
||||
// status
|
||||
Status string `json:"Status,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket versioning response
|
||||
@@ -76,9 +76,9 @@ func (m *BucketVersioningResponse) validateExcludedPrefixes(formats strfmt.Regis
|
||||
if m.ExcludedPrefixes[i] != nil {
|
||||
if err := m.ExcludedPrefixes[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("ExcludedPrefixes" + "." + strconv.Itoa(i))
|
||||
return ve.ValidateName("excludedPrefixes" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("ExcludedPrefixes" + "." + strconv.Itoa(i))
|
||||
return ce.ValidateName("excludedPrefixes" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -110,9 +110,9 @@ func (m *BucketVersioningResponse) contextValidateExcludedPrefixes(ctx context.C
|
||||
if m.ExcludedPrefixes[i] != nil {
|
||||
if err := m.ExcludedPrefixes[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("ExcludedPrefixes" + "." + strconv.Itoa(i))
|
||||
return ve.ValidateName("excludedPrefixes" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("ExcludedPrefixes" + "." + strconv.Itoa(i))
|
||||
return ce.ValidateName("excludedPrefixes" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func (m *BucketVersioningResponse) UnmarshalBinary(b []byte) error {
|
||||
type BucketVersioningResponseExcludedPrefixesItems0 struct {
|
||||
|
||||
// prefix
|
||||
Prefix string `json:"Prefix,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this bucket versioning response excluded prefixes items0
|
||||
|
||||
52
portal-ui/e2e/lifecycle.spec.ts
Normal file
52
portal-ui/e2e/lifecycle.spec.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2023 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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 { expect } from "@playwright/test";
|
||||
import { test } from "./fixtures/baseFixture";
|
||||
import { minioadminFile } from "./consts";
|
||||
|
||||
test.use({ storageState: minioadminFile });
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("http://localhost:5005/buckets");
|
||||
});
|
||||
|
||||
test("Test if Object Version selector is present in Lifecycle rule modal", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator("#create-bucket").click();
|
||||
await page.getByLabel("Bucket Name*").click();
|
||||
await page.getByLabel("Bucket Name*").fill("versioned-bucket");
|
||||
await page.locator("#versioned").check();
|
||||
await page.getByRole("button", { name: "Create Bucket" }).click();
|
||||
await page.locator("#manageBucket-versioned-bucket").click();
|
||||
await page.getByRole("tab", { name: "Lifecycle" }).click();
|
||||
await page.getByRole("button", { name: "Add Lifecycle Rule" }).click();
|
||||
await expect(await page.locator("#object_version")).toBeTruthy();
|
||||
});
|
||||
|
||||
test("Test if Object Version selector is not present when bucket is not versioned", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator("#create-bucket").click();
|
||||
await page.getByLabel("Bucket Name*").click();
|
||||
await page.getByLabel("Bucket Name*").fill("non-versioned-bucket");
|
||||
await page.getByRole("button", { name: "Create Bucket" }).click();
|
||||
await page.locator("#manageBucket-non-versioned-bucket").click();
|
||||
await page.getByRole("tab", { name: "Lifecycle" }).click();
|
||||
await page.getByRole("button", { name: "Add Lifecycle Rule" }).click();
|
||||
await expect(await page.locator("#object_version").count()).toEqual(0);
|
||||
});
|
||||
@@ -791,12 +791,12 @@ export interface ListRemoteBucketsResponse {
|
||||
}
|
||||
|
||||
export interface BucketVersioningResponse {
|
||||
Status?: string;
|
||||
status?: string;
|
||||
MFADelete?: string;
|
||||
ExcludedPrefixes?: {
|
||||
Prefix?: string;
|
||||
excludedPrefixes?: {
|
||||
prefix?: string;
|
||||
}[];
|
||||
ExcludeFolders?: boolean;
|
||||
excludeFolders?: boolean;
|
||||
}
|
||||
|
||||
export interface SetBucketVersioning {
|
||||
|
||||
@@ -49,10 +49,10 @@ import {
|
||||
spacingUtils,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import InputUnitMenu from "../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
|
||||
import { BucketVersioning } from "../types";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import { selDistSet, setModalErrorSnackMessage } from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
import { BucketVersioningInfo, ITiersDropDown } from "../types";
|
||||
|
||||
interface IReplicationModal {
|
||||
open: boolean;
|
||||
@@ -61,11 +61,6 @@ interface IReplicationModal {
|
||||
bucketName: string;
|
||||
}
|
||||
|
||||
export interface ITiersDropDown {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
formFieldRowFilter: {
|
||||
@@ -88,7 +83,8 @@ const AddLifecycleModal = ({
|
||||
const [loadingTiers, setLoadingTiers] = useState<boolean>(true);
|
||||
const [tiersList, setTiersList] = useState<ITiersDropDown[]>([]);
|
||||
const [addLoading, setAddLoading] = useState(false);
|
||||
const [isVersioned, setIsVersioned] = useState<boolean>(false);
|
||||
const [versioningInfo, setVersioningInfo] =
|
||||
useState<BucketVersioningInfo | null>(null);
|
||||
const [prefix, setPrefix] = useState("");
|
||||
const [tags, setTags] = useState<string>("");
|
||||
const [storageClass, setStorageClass] = useState("");
|
||||
@@ -146,8 +142,8 @@ const AddLifecycleModal = ({
|
||||
if (loadingVersioning && distributedSetup) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/buckets/${bucketName}/versioning`)
|
||||
.then((res: BucketVersioning) => {
|
||||
setIsVersioned(res.is_versioned);
|
||||
.then((res: BucketVersioningInfo) => {
|
||||
setVersioningInfo(res);
|
||||
setLoadingVersioning(false);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
@@ -258,7 +254,7 @@ const AddLifecycleModal = ({
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
{isVersioned && (
|
||||
{versioningInfo?.status === "Enabled" && (
|
||||
<Grid item xs={12}>
|
||||
<SelectWrapper
|
||||
value={targetVersion}
|
||||
|
||||
@@ -372,7 +372,7 @@ const BucketSummary = ({ classes }: IBucketSummaryProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
let versioningStatus = versioningInfo?.Status;
|
||||
let versioningStatus = versioningInfo?.status;
|
||||
let versioningText = "Unversioned (Default)";
|
||||
if (versioningStatus === "Enabled") {
|
||||
versioningText = "Versioned";
|
||||
@@ -604,7 +604,7 @@ const BucketSummary = ({ classes }: IBucketSummaryProps) => {
|
||||
isLoading={loadingVersioning}
|
||||
/>
|
||||
|
||||
{versioningInfo?.Status === "Enabled" ? (
|
||||
{versioningInfo?.status === "Enabled" ? (
|
||||
<VersioningInfo versioningState={versioningInfo} />
|
||||
) : null}
|
||||
</Box>
|
||||
|
||||
@@ -36,9 +36,8 @@ import {
|
||||
spacingUtils,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
import { LifeCycleItem } from "../types";
|
||||
import { ITiersDropDown, LifeCycleItem } from "../types";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import { ITiersDropDown } from "./AddLifecycleModal";
|
||||
import {
|
||||
ITierElement,
|
||||
ITierResponse,
|
||||
|
||||
@@ -40,7 +40,7 @@ const EnableVersioningModal = ({
|
||||
selectedBucket,
|
||||
versioningInfo = {},
|
||||
}: IVersioningEventProps) => {
|
||||
const isVersioningEnabled = versioningInfo.Status === "Enabled";
|
||||
const isVersioningEnabled = versioningInfo.status === "Enabled";
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const [versioningLoading, setVersioningLoading] = useState<boolean>(false);
|
||||
|
||||
@@ -40,12 +40,11 @@ import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapp
|
||||
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
|
||||
import { ITiersDropDown } from "../BucketDetails/AddLifecycleModal";
|
||||
import {
|
||||
ITierElement,
|
||||
ITierResponse,
|
||||
} from "../../Configurations/TiersConfiguration/types";
|
||||
import { MultiBucketResult } from "../types";
|
||||
import { ITiersDropDown, MultiBucketResult } from "../types";
|
||||
import { setModalErrorSnackMessage } from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ const DeleteObject = ({
|
||||
};
|
||||
|
||||
const isVersionedDelete =
|
||||
versioning?.Status === "Enabled" || versioning?.Status === "Suspended";
|
||||
versioning?.status === "Enabled" || versioning?.status === "Suspended";
|
||||
|
||||
return (
|
||||
<ConfirmDialog
|
||||
|
||||
@@ -122,7 +122,7 @@ const DeleteObject = ({
|
||||
)}
|
||||
? <br />
|
||||
<br />
|
||||
{isVersionedMode(versioningInfo?.Status) &&
|
||||
{isVersionedMode(versioningInfo?.status) &&
|
||||
selectedVersion === "" && (
|
||||
<Fragment>
|
||||
<FormSwitchWrapper
|
||||
|
||||
@@ -18,10 +18,10 @@ const VersioningInfo = ({
|
||||
}}
|
||||
>
|
||||
<Box sx={{ fontWeight: "medium", display: "flex", gap: 2 }}>
|
||||
{versioningState.ExcludeFolders ? (
|
||||
{versioningState.excludeFolders ? (
|
||||
<LabelWithIcon
|
||||
icon={
|
||||
versioningState.ExcludeFolders ? (
|
||||
versioningState.excludeFolders ? (
|
||||
<EnabledIcon style={{ color: "green" }} />
|
||||
) : (
|
||||
<DisabledIcon />
|
||||
@@ -35,7 +35,7 @@ const VersioningInfo = ({
|
||||
/>
|
||||
) : null}
|
||||
</Box>
|
||||
{versioningState.ExcludedPrefixes?.length ? (
|
||||
{versioningState.excludedPrefixes?.length ? (
|
||||
<Box
|
||||
sx={{
|
||||
fontWeight: "medium",
|
||||
@@ -57,7 +57,7 @@ const VersioningInfo = ({
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
{versioningState.ExcludedPrefixes?.map((it) => (
|
||||
{versioningState.excludedPrefixes?.map((it) => (
|
||||
<div>
|
||||
<strong>{it.Prefix}</strong>
|
||||
</div>
|
||||
|
||||
@@ -52,15 +52,11 @@ export interface ArnList {
|
||||
arns: string[];
|
||||
}
|
||||
|
||||
export interface BucketVersioning {
|
||||
is_versioned: boolean;
|
||||
}
|
||||
|
||||
export interface BucketVersioningInfo {
|
||||
ExcludeFolders?: boolean;
|
||||
ExcludedPrefixes?: Record<"Prefix", string>[];
|
||||
excludeFolders?: boolean;
|
||||
excludedPrefixes?: Record<"Prefix", string>[];
|
||||
MFADelete?: string;
|
||||
Status?: "Enabled" | "Suspended" | "";
|
||||
status?: "Enabled" | "Suspended" | "";
|
||||
}
|
||||
|
||||
export interface BucketObjectLocking {
|
||||
@@ -147,3 +143,8 @@ export interface MultiBucketResult {
|
||||
export interface MultiBucketResult {
|
||||
results: MultiBucketResult[];
|
||||
}
|
||||
|
||||
export interface ITiersDropDown {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
@@ -5948,24 +5948,24 @@ func init() {
|
||||
"bucketVersioningResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ExcludeFolders": {
|
||||
"MFADelete": {
|
||||
"type": "string"
|
||||
},
|
||||
"excludeFolders": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ExcludedPrefixes": {
|
||||
"excludedPrefixes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Prefix": {
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"MFADelete": {
|
||||
"type": "string"
|
||||
},
|
||||
"Status": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -14384,7 +14384,7 @@ func init() {
|
||||
"BucketVersioningResponseExcludedPrefixesItems0": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Prefix": {
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
@@ -15084,19 +15084,19 @@ func init() {
|
||||
"bucketVersioningResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ExcludeFolders": {
|
||||
"MFADelete": {
|
||||
"type": "string"
|
||||
},
|
||||
"excludeFolders": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ExcludedPrefixes": {
|
||||
"excludedPrefixes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/BucketVersioningResponseExcludedPrefixesItems0"
|
||||
}
|
||||
},
|
||||
"MFADelete": {
|
||||
"type": "string"
|
||||
},
|
||||
"Status": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4944,18 +4944,18 @@ definitions:
|
||||
bucketVersioningResponse:
|
||||
type: object
|
||||
properties:
|
||||
Status:
|
||||
status:
|
||||
type: string
|
||||
MFADelete:
|
||||
type: string
|
||||
ExcludedPrefixes:
|
||||
excludedPrefixes:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
Prefix:
|
||||
prefix:
|
||||
type: string
|
||||
ExcludeFolders:
|
||||
excludeFolders:
|
||||
type: boolean
|
||||
|
||||
setBucketVersioning:
|
||||
|
||||
Reference in New Issue
Block a user