Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Include full query options when generating download/share/preview links, [PR-160](https://github.com/reductstore/web-console/pull/160)
- Fix the inconsistency in the time range selection with an empty end, [PR-162](https://github.com/reductstore/web-console/pull/162)

## 1.12.1 - 2025-11-17

Expand Down
77 changes: 77 additions & 0 deletions src/Views/BucketPanel/EntryDetail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -782,4 +782,81 @@ describe("EntryDetail", () => {
);
});
});

describe("Time Range Input", () => {
beforeEach(async () => {
await act(async () => {
jest.runOnlyPendingTimers();
await waitUntil(
() => wrapper.update().find(".ant-table-row").length > 0,
);
});
});

it("should query with undefined end time when stop field is empty", async () => {
(bucket.query as jest.Mock).mockClear();

const timeInputs = wrapper.find(".timeInputs Input");
const stopInput = timeInputs.at(1);

await act(async () => {
const onChange = stopInput.prop("onChange") as any;
if (onChange) {
onChange({ target: { value: "" } });
}
});
wrapper.update();

const fetchButton = wrapper.find(".fetchButton button").at(0);
await act(async () => {
fetchButton.simulate("click");
jest.runAllTimers();
});

expect(bucket.query).toHaveBeenCalledWith(
"testEntry",
0n,
undefined,
expect.objectContaining({
head: true,
strict: true,
}),
);
});

it("should query with specific end time when stop field has value", async () => {
(bucket.query as jest.Mock).mockClear();

const timeInputs = wrapper.find(".timeInputs Input");
const stopInput = timeInputs.at(1);

const specificTime = "1970-01-01T00:00:01.000Z";
await act(async () => {
const onChange = stopInput.prop("onChange") as any;
if (onChange) {
onChange({ target: { value: specificTime } });
}
});
wrapper.update();

const fetchButton = wrapper.find(".fetchButton button").at(0);
await act(async () => {
fetchButton.simulate("click");
jest.runAllTimers();
});

expect(bucket.query).toHaveBeenCalled();
const [[entry, startTime, endTime, options]] = (bucket.query as jest.Mock)
.mock.calls;

expect(entry).toBe("testEntry");
expect(startTime).toBe(0n);
expect(endTime).toBe(1000000n);

expect(options).toMatchObject({
head: true,
strict: true,
});
});
});
});
29 changes: 14 additions & 15 deletions src/Views/BucketPanel/EntryDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ interface Props {
}

interface RecordQueryContext {
rangeStart?: bigint;
rangeEnd?: bigint;
start?: bigint;
end?: bigint;
options?: QueryOptions;
}

Expand Down Expand Up @@ -226,14 +226,13 @@ export default function EntryDetail(props: Readonly<Props>) {
const bucketInstance = await props.client.getBucket(bucketName);
setBucket(bucketInstance);

const rangeStart = start ?? entryInfo?.oldestRecord;
const rangeEnd = end ?? entryInfo?.latestRecord;

const options = new QueryOptions();
options.head = true;
options.strict = true;

if (whenCondition.trim()) {
const rangeStart = start ?? entryInfo?.oldestRecord;
const rangeEnd = end ?? entryInfo?.latestRecord;
const macroValue = pickEachTInterval(rangeStart, rangeEnd);
const conditionResult = processConditionWithMacros(
whenCondition,
Expand All @@ -258,8 +257,8 @@ export default function EntryDetail(props: Readonly<Props>) {
}

setQueryContext({
rangeStart,
rangeEnd,
start,
end,
options,
});

Expand All @@ -268,8 +267,8 @@ export default function EntryDetail(props: Readonly<Props>) {

for await (const record of bucketInstance.query(
entryName,
rangeStart,
rangeEnd,
start,
end,
options,
)) {
if (abortSignal.aborted) return;
Expand Down Expand Up @@ -315,8 +314,8 @@ export default function EntryDetail(props: Readonly<Props>) {
const expireAt = new Date(Date.now() + 60 * 60 * 1000);
const shareLink = await bucket.createQueryLink(
entryName,
queryContext?.rangeStart,
queryContext?.rangeEnd,
queryContext?.start,
queryContext?.end,
buildLinkQueryOptions(queryContext?.options),
row.tableIndex,
expireAt,
Expand Down Expand Up @@ -353,8 +352,8 @@ export default function EntryDetail(props: Readonly<Props>) {
const bucket = await props.client.getBucket(bucketName);
return bucket.createQueryLink(
entryName,
queryContext?.rangeStart,
queryContext?.rangeEnd,
queryContext?.start,
queryContext?.end,
buildLinkQueryOptions(queryContext?.options),
recordToShare?.tableIndex,
expireAt,
Expand Down Expand Up @@ -871,8 +870,8 @@ export default function EntryDetail(props: Readonly<Props>) {
timestamp={row.timestamp}
bucket={bucket}
apiUrl={props.apiUrl}
queryStart={queryContext?.rangeStart}
queryEnd={queryContext?.rangeEnd}
queryStart={queryContext?.start}
queryEnd={queryContext?.end}
queryOptions={buildLinkQueryOptions(queryContext?.options)}
recordIndex={queryContext ? row.tableIndex : 0}
/>
Expand Down