Skip to content

Commit 7d29e7f

Browse files
committed
Updates date-time extensions and UI tweaks.
Updates the Exceptionless.DateTimeExtensions package to version 5.0.0. Adds missing words to cSpell configuration. Improves date-time parsing by enforcing lowercase units, aligning with backend validation. Adjusts UI element dimensions for better responsiveness.
1 parent 45a0167 commit 7d29e7f

File tree

7 files changed

+64
-5
lines changed

7 files changed

+64
-5
lines changed

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"cSpell.words": [
1313
"acacode",
1414
"autodocs",
15+
"axllent",
1516
"circleci",
1617
"classvalidator",
1718
"clsx",
@@ -36,6 +37,7 @@
3637
"legos",
3738
"lucene",
3839
"lucide",
40+
"mailpit",
3941
"nameof",
4042
"navigatetofirstpage",
4143
"oidc",

src/Exceptionless.Web/ClientApp/src/lib/features/projects/components/project-log-level.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,5 +171,5 @@
171171
</DropdownMenu.Content>
172172
</DropdownMenu.Root>
173173
{:else}
174-
<Skeleton class="h-[36px] w-[135px]" />
174+
<Skeleton class="h-9 w-33.75" />
175175
{/if}

src/Exceptionless.Web/ClientApp/src/lib/features/sessions/components/sessions-dashboard-chart.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
}}
8484
>
8585
{#snippet tooltip()}
86-
<Chart.Tooltip class="min-w-[250px]" indicator="line" labelFormatter={(v) => formatDateLabel(v as Date)} />
86+
<Chart.Tooltip class="min-w-62.5" indicator="line" labelFormatter={(v) => formatDateLabel(v as Date)} />
8787
{/snippet}
8888
</AreaChart>
8989
</Chart.Container>

src/Exceptionless.Web/ClientApp/src/lib/features/shared/utils/datemath.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,4 +506,60 @@ describe('DateMath Library', () => {
506506
});
507507
});
508508
});
509+
510+
describe('Elastic date-math unit enforcement (lowercase d)', () => {
511+
it('should accept now-7d as a valid expression', () => {
512+
const result = parseDateMath('now-7d');
513+
expect(result.success).toBe(true);
514+
expect(result.date).toEqual(new Date('2025-09-13T14:30:00Z'));
515+
});
516+
517+
it('should reject now-7D (uppercase D is not a valid Elastic unit)', () => {
518+
const result = parseDateMath('now-7D');
519+
expect(result.success).toBe(false);
520+
});
521+
522+
it('should accept now-1d and resolve correctly', () => {
523+
const result = parseDateMath('now-1d');
524+
expect(result.success).toBe(true);
525+
expect(result.date).toEqual(new Date('2025-09-19T14:30:00Z'));
526+
});
527+
528+
it('should reject now-1D (uppercase D)', () => {
529+
const result = parseDateMath('now-1D');
530+
expect(result.success).toBe(false);
531+
});
532+
533+
it('should parse [now-7d TO now] range correctly', () => {
534+
const range = parseDateMathRange('[now-7d TO now]');
535+
expect(range.start).toEqual(new Date('2025-09-13T14:30:00Z'));
536+
expect(range.end).toEqual(new Date('2025-09-20T14:30:00Z'));
537+
});
538+
539+
it('should fail to parse [now-7D TO now] range (uppercase D)', () => {
540+
const range = parseDateMathRange('[now-7D TO now]');
541+
// Should fall back to default range since uppercase D is invalid
542+
expect(range.start).toEqual(new Date('2012-02-01'));
543+
expect(range.end.getTime()).toBeCloseTo(new Date().getTime(), -3);
544+
});
545+
546+
it('should accept rounding with lowercase d: now/d', () => {
547+
const result = parseDateMath('now/d');
548+
expect(result.success).toBe(true);
549+
});
550+
551+
it('should accept now-1d/d (subtraction + rounding with lowercase d)', () => {
552+
const result = parseDateMath('now-1d/d');
553+
expect(result.success).toBe(true);
554+
expect(result.date).toEqual(new Date('2025-09-19T00:00:00Z'));
555+
});
556+
557+
it('should only accept documented Elastic units: y, M, w, d, h, H, m, s', () => {
558+
const validUnits = ['y', 'M', 'w', 'd', 'h', 'H', 'm', 's'];
559+
validUnits.forEach((unit) => {
560+
const result = parseDateMath(`now-1${unit}`);
561+
expect(result.success).toBe(true);
562+
});
563+
});
564+
});
509565
});

src/Exceptionless.Web/ClientApp/src/lib/features/shared/utils/datemath.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ export const TIME_UNIT_NAMES: Record<TimeUnit, string> = {
3434
* Enhanced to match all backend test cases exactly
3535
*/
3636
const DATE_MATH_REGEX =
37-
/^(?<anchor>now|\*|(?<date>\d{4}-?\d{2}-?\d{2}(?:[T\s](?:\d{1,2}(?::?\d{2}(?::?\d{2})?)?(?:\.\d{1,3})?)?(?:[+-]\d{2}:?\d{2}|Z)?)?)(?:\|\|)?)(?<operations>(?:[+\-/]\d*[yMwdhHms])*)$/i;
37+
/^(?<anchor>now|\*|(?<date>\d{4}-?\d{2}-?\d{2}(?:[T\s](?:\d{1,2}(?::?\d{2}(?::?\d{2})?)?(?:\.\d{1,3})?)?(?:[+-]\d{2}:?\d{2}|Z)?)?)(?:\|\|)?)(?<operations>(?:[+\-/]\d*[yMwdhHms])*)$/;
3838

3939
/** Pre-compiled regex for operation parsing - more strict validation */
40-
const OPERATION_REGEX = /([+\-/])(\d*)([yMwdhHms])/gi;
40+
const OPERATION_REGEX = /([+\-/])(\d*)([yMwdhHms])/g;
4141

4242
/** Result of parsing a date math expression */
4343
export interface DateMathResult {

src/Exceptionless.Web/ClientApp/src/routes/(app)/issues/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@
311311

312312
<EventsDataTable bind:limit={queryParams.limit!} isLoading={clientStatus.isLoading} {rowClick} {rowHref} {table}>
313313
{#snippet footerChildren()}
314-
<div class="h-9 min-w-[140px]">
314+
<div class="h-9 min-w-35">
315315
<TableStacksBulkActionsDropdownMenu {table} />
316316
</div>
317317

src/Exceptionless.Web/Exceptionless.Web.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<PackageReference Include="NEST.JsonNetSerializer" Version="7.17.5" />
2121
<PackageReference Include="OAuth2" Version="0.10.3" />
2222
<PackageReference Include="Scalar.AspNetCore" Version="2.12.40" />
23+
<PackageReference Include="Scalar.AspNetCore" Version="2.12.39" />
2324
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
2425
<PackageReference Include="Serilog.Enrichers.Span" Version="3.1.0" />
2526
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" />

0 commit comments

Comments
 (0)