Skip to content

Commit ab5bfb1

Browse files
authored
Add delete tags (#216)
* Add delete tags * Add changelog * Add test * fmt * fmt
1 parent 7972c35 commit ab5bfb1

5 files changed

Lines changed: 68 additions & 33 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
## 1.15.1 - 2026-06-19
11+
12+
### Fixed
13+
14+
- Show "Deleting" status badge for entries during bulk deletion until server completes, [PR-216](https://github.com/reductstore/web-console/pull/216)
15+
1016
## 1.15.0 - 2026-06-16
1117

1218
### Added
@@ -352,7 +358,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
352358

353359
- Initial Release
354360

355-
[Unreleased]: https://github.com/reductstore/web-console/compare/v1.15.0...HEAD
361+
[Unreleased]: https://github.com/reductstore/web-console/compare/v1.15.1...HEAD
362+
[1.15.1]: https://github.com/reductstore/web-console/compare/v1.15.0...v1.15.1
356363
[1.15.0]: https://github.com/reductstore/web-console/compare/v1.14.2...v1.15.0
357364
[1.14.2]: https://github.com/reductstore/web-console/compare/v1.14.1...v1.14.2
358365
[1.14.1]: https://github.com/reductstore/web-console/compare/v1.14.0...v1.14.1

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "web-console",
3-
"version": "1.15.0",
3+
"version": "1.15.1",
44
"type": "module",
55
"private": true,
66
"devDependencies": {

src/Views/BucketPanel/BucketDetail.test.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from "react";
22
import { render, fireEvent, waitFor } from "@testing-library/react";
33
import { mockJSDOM } from "../../Helpers/TestHelpers";
4-
import { Bucket, BucketInfo, Client, EntryInfo } from "reduct-js";
4+
import { Bucket, BucketInfo, Client, EntryInfo, Status } from "reduct-js";
55
import BucketDetail from "./BucketDetail";
66
import { MemoryRouter } from "react-router-dom";
77
import { act } from "react";
@@ -136,4 +136,31 @@ describe("BucketDetail", () => {
136136
// The table should still render (filtered)
137137
expect(container.querySelector(".entriesTable")).not.toBeNull();
138138
});
139+
140+
it("should show deleting badge for entries with DELETING status", async () => {
141+
bucket.getEntryList = vi.fn().mockResolvedValue([
142+
{
143+
name: "deleting-entry",
144+
blockCount: 1n,
145+
recordCount: 1n,
146+
size: 512n,
147+
oldestRecord: 0n,
148+
latestRecord: 10000n,
149+
status: Status.DELETING,
150+
} as EntryInfo,
151+
]);
152+
153+
const { container } = render(
154+
<MemoryRouter>
155+
<BucketDetail client={client} />
156+
</MemoryRouter>,
157+
);
158+
159+
await waitFor(() => {
160+
expect(container.querySelector(".entriesTable")).not.toBeNull();
161+
});
162+
163+
const row = container.querySelector(".ant-table-row");
164+
expect(row?.textContent).toContain("Deleting");
165+
});
139166
});

src/Views/BucketPanel/BucketDetail.tsx

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
Divider,
1717
Flex,
1818
Input,
19+
Tag,
1920
Tooltip,
2021
Typography,
2122
message,
@@ -30,6 +31,7 @@ import {
3031
EditOutlined,
3132
ExpandAltOutlined,
3233
LineChartOutlined,
34+
LoadingOutlined,
3335
NodeCollapseOutlined,
3436
NodeExpandOutlined,
3537
PartitionOutlined,
@@ -316,33 +318,19 @@ export default function BucketDetail(props: Readonly<Props>) {
316318
} = useBulkDelete({
317319
onDelete: async (entryName) => {
318320
if (!info) throw new Error("No bucket info");
319-
const prefix = `${entryName}/`;
321+
const bucket: Bucket = await props.client.getBucket(info.name);
322+
await bucket.removeEntry(entryName);
323+
},
324+
onStart: (keys) => {
320325
setEntries((prev) =>
321326
prev.map((entry) =>
322-
entry.name === entryName || entry.name.startsWith(prefix)
327+
keys.some(
328+
(key) => entry.name === key || entry.name.startsWith(`${key}/`),
329+
)
323330
? { ...entry, status: Status.DELETING }
324331
: entry,
325332
),
326333
);
327-
try {
328-
const bucket: Bucket = await props.client.getBucket(info.name);
329-
await bucket.removeEntry(entryName);
330-
setEntries((prev) =>
331-
prev.filter(
332-
(entry) =>
333-
entry.name !== entryName && !entry.name.startsWith(prefix),
334-
),
335-
);
336-
} catch (err) {
337-
setEntries((prev) =>
338-
prev.map((entry) =>
339-
entry.name === entryName || entry.name.startsWith(prefix)
340-
? { ...entry, status: Status.READY }
341-
: entry,
342-
),
343-
);
344-
throw err;
345-
}
346334
},
347335
onSuccess: () => {
348336
setIsBulkDeleteOpen(false);
@@ -462,7 +450,20 @@ export default function BucketDetail(props: Readonly<Props>) {
462450
{row.name}
463451
</Typography.Link>
464452
) : (
465-
<Typography.Text>{row.name}</Typography.Text>
453+
<Typography.Text
454+
style={isDeleting ? { color: "#bfbfbf" } : undefined}
455+
>
456+
{row.name}
457+
</Typography.Text>
458+
)}
459+
{isDeleting && (
460+
<Tag
461+
color="processing"
462+
icon={<LoadingOutlined spin />}
463+
style={{ marginLeft: 4 }}
464+
>
465+
Deleting
466+
</Tag>
466467
)}
467468
{!row.ownEntryName &&
468469
row.children &&

0 commit comments

Comments
 (0)