Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rill-time frontend integration #6371

Closed
wants to merge 29 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a55bf2d
Add rilltime package
AdityaHegde Dec 23, 2024
2aa5ca3
Use rilltime in queries
AdityaHegde Dec 23, 2024
3f165ed
Add API to resolve time ranges
AdityaHegde Dec 23, 2024
3bbb615
Add absolute date/time support
AdityaHegde Dec 23, 2024
a947e7f
Adding basic +/- support to anchors
AdityaHegde Dec 24, 2024
6d51ab9
Adding mapping for old rill-<> format
AdityaHegde Dec 30, 2024
6162f08
Merge branch 'main' into adityahegde/rill-time-syntax-backend
AdityaHegde Dec 31, 2024
8914b52
Add the nearly parser
AdityaHegde Dec 31, 2024
15eeaaa
Update SuperPill
AdityaHegde Jan 1, 2025
54460f2
Avoid usage of time-control-store
AdityaHegde Jan 2, 2025
da5e3fb
Merge branch 'main' into adityahegde/rill-time-syntax-backend
AdityaHegde Jan 6, 2025
34c287f
Support 2024-03-01-7d, 2024-03-01 @-2d
AdityaHegde Jan 7, 2025
9f89121
Merge branch 'main' into adityahegde/rill-time-syntax-backend
AdityaHegde Jan 7, 2025
7cf5de0
Fix merge issue
AdityaHegde Jan 7, 2025
0daed8b
Merge branch 'adityahegde/rill-time-syntax-backend' into adityahegde/…
AdityaHegde Jan 7, 2025
f91c240
Add more variant support
AdityaHegde Jan 8, 2025
330aabe
Review comments #1
AdityaHegde Jan 8, 2025
3b5dd34
Remove unit param in metricssql time functions
AdityaHegde Jan 9, 2025
9233683
Review comments pass 2
AdityaHegde Jan 9, 2025
ca73407
Merge branch 'main' into adityahegde/rill-time-syntax-backend
AdityaHegde Jan 9, 2025
d6718bf
Merge branch 'adityahegde/rill-time-syntax-backend' into adityahegde/…
AdityaHegde Jan 9, 2025
94f9506
Add support for arithematic
AdityaHegde Jan 9, 2025
e9029c2
More PR comments
AdityaHegde Jan 10, 2025
c0f8eb4
Fix ISO duration and some edge cases
AdityaHegde Jan 13, 2025
1fbb43a
Merge branch 'main' into adityahegde/rill-time-syntax-backend
AdityaHegde Jan 13, 2025
43b7da2
Add watermark as separate param
AdityaHegde Jan 14, 2025
f012780
Merge branch 'adityahegde/rill-time-syntax-backend' into adityahegde/…
AdityaHegde Jan 14, 2025
0fb74d4
Fix API usages
AdityaHegde Jan 14, 2025
dd818df
Merge branch 'main' into adityahegde/rill-time-syntax-frontend
AdityaHegde Jan 22, 2025
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
Prev Previous commit
Next Next commit
Add more variant support
AdityaHegde committed Jan 8, 2025
commit f91c240be40266da330a492b9ddb3b8980421787
Original file line number Diff line number Diff line change
@@ -6,31 +6,46 @@ export enum RillTimeType {
}

export class RillTime {
public timeRange: string;
public readonly isComplete: boolean;
public readonly end: RillTimeModifier;
public readonly end: RillTimeAnchor;
public readonly type: RillTimeType;

public constructor(
public readonly start: RillTimeModifier,
end: RillTimeModifier,
public readonly start: RillTimeAnchor,
end: RillTimeAnchor,
public readonly timeRangeGrain: RillTimeRangeGrain | undefined,
public readonly modifier: RillTimeRangeModifier | undefined,
) {
this.type = start.getType();

this.end = end ?? RillTimeModifier.now();
this.end = end ?? RillTimeAnchor.now();
this.isComplete =
this.end.type === RillTimeModifierType.Custom ||
this.end.type === RillTimeAnchorType.Custom ||
this.end.truncate !== undefined;
}

public getLabel() {
if (this.type === RillTimeType.Unknown || !!this.modifier) {
return this.timeRange;
}

const start = capitalizeFirstChar(this.start.getLabel());
const completeSuffix = ", " + (this.isComplete ? "complete" : "incomplete");
return `${start}${completeSuffix}`;
if (
this.end &&
this.end.type === RillTimeAnchorType.Custom &&
this.end.grain &&
this.end.grain.count < 0
) {
return this.timeRange;
}

if (this.isComplete) return start;
return `${start}, incomplete`;
}
}

export enum RillTimeModifierType {
export enum RillTimeAnchorType {
Now = "Now",
Earliest = "Earliest",
Latest = "Latest",
@@ -49,25 +64,25 @@ const GrainToUnit = {
Y: "year",
};
export const InvalidTime = "Invalid";
export class RillTimeModifier {
export class RillTimeAnchor {
public truncate: RillTimeGrain | undefined = undefined;

public constructor(
public readonly type: RillTimeModifierType,
public readonly type: RillTimeAnchorType,
public readonly grain: RillTimeGrain | undefined = undefined,
) {}

public static now() {
return new RillTimeModifier(RillTimeModifierType.Now);
return new RillTimeAnchor(RillTimeAnchorType.Now);
}
public static earliest() {
return new RillTimeModifier(RillTimeModifierType.Earliest);
return new RillTimeAnchor(RillTimeAnchorType.Earliest);
}
public static latest() {
return new RillTimeModifier(RillTimeModifierType.Latest);
return new RillTimeAnchor(RillTimeAnchorType.Latest);
}
public static custom(grain: RillTimeGrain) {
return new RillTimeModifier(RillTimeModifierType.Custom, grain);
return new RillTimeAnchor(RillTimeAnchorType.Custom, grain);
}

public withTruncate(truncate: RillTimeGrain) {
@@ -78,7 +93,7 @@ export class RillTimeModifier {
public getLabel() {
const grain = this.grain ?? this.truncate;
if (!grain) {
return RillTimeModifierType.Earliest.toString();
return RillTimeAnchorType.Earliest.toString();
}

const unit = GrainToUnit[grain.grain];
@@ -123,9 +138,8 @@ export type RillTimeRangeGrain = {
};

export type RillTimeRangeModifier = {
timeRangeGrain: RillTimeRangeGrain | undefined;
timeZone: string | undefined;
at: RillTimeModifier | undefined;
at: RillTimeAnchor | undefined;
};

function capitalizeFirstChar(str: string): string {
Original file line number Diff line number Diff line change
@@ -3,10 +3,12 @@ import grammar from "./rill-time.cjs";
import nearley from "nearley";

const compiledGrammar = nearley.Grammar.fromCompiled(grammar);
export function parseRillTime(rillTime: string): RillTime {
export function parseRillTime(rillTimeRange: string): RillTime {
const parser = new nearley.Parser(compiledGrammar);
parser.feed(rillTime);
return parser.results[0];
parser.feed(rillTimeRange);
const rt = parser.results[0] as RillTime;
rt.timeRange = rillTimeRange;
return rt;
}

export function validateRillTime(rillTime: string): Error | undefined {
Original file line number Diff line number Diff line change
@@ -3,17 +3,17 @@
function id(x) { return x[0]; }

import {
RillTimeModifier,
RillTimeAnchor,
RillTime,
} from "./RillTime.ts"
let Lexer = undefined;
let ParserRules = [
{"name": "_$ebnf$1", "symbols": []},
{"name": "_$ebnf$1", "symbols": ["_$ebnf$1", "wschar"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "_", "symbols": ["_$ebnf$1"], "postprocess": function(d) {return null;}},

Check failure on line 13 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "__$ebnf$1", "symbols": ["wschar"]},
{"name": "__$ebnf$1", "symbols": ["__$ebnf$1", "wschar"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "__", "symbols": ["__$ebnf$1"], "postprocess": function(d) {return null;}},

Check failure on line 16 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "wschar", "symbols": [/[ \t\n\v\f]/], "postprocess": id},
{"name": "unsigned_int$ebnf$1", "symbols": [/[0-9]/]},
{"name": "unsigned_int$ebnf$1", "symbols": ["unsigned_int$ebnf$1", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
@@ -25,7 +25,7 @@
{"name": "int$ebnf$1$subexpression$1", "symbols": [{"literal":"-"}]},
{"name": "int$ebnf$1$subexpression$1", "symbols": [{"literal":"+"}]},
{"name": "int$ebnf$1", "symbols": ["int$ebnf$1$subexpression$1"], "postprocess": id},
{"name": "int$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 28 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "int$ebnf$2", "symbols": [/[0-9]/]},
{"name": "int$ebnf$2", "symbols": ["int$ebnf$2", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "int", "symbols": ["int$ebnf$1", "int$ebnf$2"], "postprocess":
@@ -43,7 +43,7 @@
{"name": "unsigned_decimal$ebnf$2$subexpression$1$ebnf$1", "symbols": ["unsigned_decimal$ebnf$2$subexpression$1$ebnf$1", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "unsigned_decimal$ebnf$2$subexpression$1", "symbols": [{"literal":"."}, "unsigned_decimal$ebnf$2$subexpression$1$ebnf$1"]},
{"name": "unsigned_decimal$ebnf$2", "symbols": ["unsigned_decimal$ebnf$2$subexpression$1"], "postprocess": id},
{"name": "unsigned_decimal$ebnf$2", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 46 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "unsigned_decimal", "symbols": ["unsigned_decimal$ebnf$1", "unsigned_decimal$ebnf$2"], "postprocess":
function(d) {
return parseFloat(
@@ -53,14 +53,14 @@
}
},
{"name": "decimal$ebnf$1", "symbols": [{"literal":"-"}], "postprocess": id},
{"name": "decimal$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 56 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "decimal$ebnf$2", "symbols": [/[0-9]/]},
{"name": "decimal$ebnf$2", "symbols": ["decimal$ebnf$2", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "decimal$ebnf$3$subexpression$1$ebnf$1", "symbols": [/[0-9]/]},
{"name": "decimal$ebnf$3$subexpression$1$ebnf$1", "symbols": ["decimal$ebnf$3$subexpression$1$ebnf$1", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "decimal$ebnf$3$subexpression$1", "symbols": [{"literal":"."}, "decimal$ebnf$3$subexpression$1$ebnf$1"]},
{"name": "decimal$ebnf$3", "symbols": ["decimal$ebnf$3$subexpression$1"], "postprocess": id},
{"name": "decimal$ebnf$3", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 63 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "decimal", "symbols": ["decimal$ebnf$1", "decimal$ebnf$2", "decimal$ebnf$3"], "postprocess":
function(d) {
return parseFloat(
@@ -76,21 +76,21 @@
}
},
{"name": "jsonfloat$ebnf$1", "symbols": [{"literal":"-"}], "postprocess": id},
{"name": "jsonfloat$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 79 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "jsonfloat$ebnf$2", "symbols": [/[0-9]/]},
{"name": "jsonfloat$ebnf$2", "symbols": ["jsonfloat$ebnf$2", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "jsonfloat$ebnf$3$subexpression$1$ebnf$1", "symbols": [/[0-9]/]},
{"name": "jsonfloat$ebnf$3$subexpression$1$ebnf$1", "symbols": ["jsonfloat$ebnf$3$subexpression$1$ebnf$1", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "jsonfloat$ebnf$3$subexpression$1", "symbols": [{"literal":"."}, "jsonfloat$ebnf$3$subexpression$1$ebnf$1"]},
{"name": "jsonfloat$ebnf$3", "symbols": ["jsonfloat$ebnf$3$subexpression$1"], "postprocess": id},
{"name": "jsonfloat$ebnf$3", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 86 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "jsonfloat$ebnf$4$subexpression$1$ebnf$1", "symbols": [/[+-]/], "postprocess": id},
{"name": "jsonfloat$ebnf$4$subexpression$1$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 88 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "jsonfloat$ebnf$4$subexpression$1$ebnf$2", "symbols": [/[0-9]/]},
{"name": "jsonfloat$ebnf$4$subexpression$1$ebnf$2", "symbols": ["jsonfloat$ebnf$4$subexpression$1$ebnf$2", /[0-9]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "jsonfloat$ebnf$4$subexpression$1", "symbols": [/[eE]/, "jsonfloat$ebnf$4$subexpression$1$ebnf$1", "jsonfloat$ebnf$4$subexpression$1$ebnf$2"]},
{"name": "jsonfloat$ebnf$4", "symbols": ["jsonfloat$ebnf$4$subexpression$1"], "postprocess": id},
{"name": "jsonfloat$ebnf$4", "symbols": [], "postprocess": function(d) {return null;}},

Check failure on line 93 in web-common/src/features/dashboards/url-state/time-ranges/rill-time.cjs

GitHub Actions / build

'd' is defined but never used. Allowed unused args must match /^_/u
{"name": "jsonfloat", "symbols": ["jsonfloat$ebnf$1", "jsonfloat$ebnf$2", "jsonfloat$ebnf$3", "jsonfloat$ebnf$4"], "postprocess":
function(d) {
return parseFloat(
@@ -126,32 +126,32 @@
return d.join("");
}
},
{"name": "rill_time", "symbols": ["time_mod", "_", {"literal":","}, "_", "time_mod", "_", {"literal":":"}, "_", "modifiers"], "postprocess": ([start, , , , end, , , , modifiers]) => new RillTime(start, end, modifiers)},
{"name": "rill_time", "symbols": ["time_mod", "_", {"literal":","}, "_", "time_mod"], "postprocess": ([start, , , , end]) => new RillTime(start, end)},
{"name": "rill_time", "symbols": ["time_mod", "_", {"literal":":"}, "_", "modifiers"], "postprocess": ([start, , , , modifiers]) => new RillTime(start, undefined, modifiers)},
{"name": "rill_time", "symbols": ["time_mod"], "postprocess": ([start]) => new RillTime(start)},
{"name": "time_mod", "symbols": ["time_mod_offset"], "postprocess": id},
{"name": "time_mod", "symbols": ["time_mod_offset", "_", {"literal":"/"}, "_", "grain"], "postprocess": ([mod, , , , truncate]) => mod.withTruncate(truncate)},
{"name": "time_mod_offset$string$1", "symbols": [{"literal":"n"}, {"literal":"o"}, {"literal":"w"}], "postprocess": function joiner(d) {return d.join('');}},
{"name": "time_mod_offset", "symbols": ["time_mod_offset$string$1"], "postprocess": () => RillTimeModifier.now()},
{"name": "time_mod_offset$string$2", "symbols": [{"literal":"e"}, {"literal":"a"}, {"literal":"r"}, {"literal":"l"}, {"literal":"i"}, {"literal":"e"}, {"literal":"s"}, {"literal":"t"}], "postprocess": function joiner(d) {return d.join('');}},
{"name": "time_mod_offset", "symbols": ["time_mod_offset$string$2"], "postprocess": () => RillTimeModifier.earliest()},
{"name": "time_mod_offset$string$3", "symbols": [{"literal":"l"}, {"literal":"a"}, {"literal":"t"}, {"literal":"e"}, {"literal":"s"}, {"literal":"t"}], "postprocess": function joiner(d) {return d.join('');}},
{"name": "time_mod_offset", "symbols": ["time_mod_offset$string$3"], "postprocess": () => RillTimeModifier.latest()},
{"name": "time_mod_offset", "symbols": ["grain_modifier"], "postprocess": ([grain]) => RillTimeModifier.custom(grain)},
{"name": "modifiers", "symbols": ["range_grain_modifier"], "postprocess": ([timeRangeGrain]) => ({ timeRangeGrain })},
{"name": "modifiers", "symbols": ["range_grain_modifier", "_", "at_modifiers"], "postprocess": ([timeRangeGrain, , atModifiers]) => ({ timeRangeGrain, ...atModifiers })},
{"name": "modifiers", "symbols": ["at_modifiers"], "postprocess": id},
{"name": "at_modifiers", "symbols": [{"literal":"@"}, "_", "grain_modifier"], "postprocess": ([, , grain]) => ({ grain })},
{"name": "at_modifiers", "symbols": [{"literal":"@"}, "_", "timezone_modifier"], "postprocess": ([, , timeZone]) => ({ timeZone })},
{"name": "at_modifiers", "symbols": [{"literal":"@"}, "_", "grain_modifier", "_", "timezone_modifier"], "postprocess": ([, , timeZone]) => ({ timeZone })},
{"name": "grain_modifier", "symbols": ["grain"], "postprocess": ([grain]) => ({ count: 0, grain })},
{"name": "grain_modifier", "symbols": ["int", "grain"], "postprocess": ([count, grain]) => ({ count, grain })},
{"name": "timezone_modifier$ebnf$1", "symbols": [/[a-zA-Z]/]},
{"name": "timezone_modifier$ebnf$1", "symbols": ["timezone_modifier$ebnf$1", /[a-zA-Z]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "timezone_modifier", "symbols": [{"literal":"{"}, "_", "timezone_modifier$ebnf$1", "_", {"literal":"}"}], "postprocess": ([, , tz]) => tz},
{"name": "rill_time", "symbols": ["time_anchor_part"], "postprocess": ([{ start, end }]) => new RillTime(start, end)},
{"name": "rill_time", "symbols": ["time_anchor_part", "_", "grain_and_at_part"], "postprocess": ([{ start, end }, , { grain, modifier }]) => new RillTime(start, end, grain, modifier)},
{"name": "time_anchor_part", "symbols": ["time_anchor", "_", {"literal":","}, "_", "time_anchor"], "postprocess": ([start, , , , end]) => ({ start, end })},
{"name": "time_anchor_part", "symbols": ["time_anchor"], "postprocess": ([start]) => ({ start })},
{"name": "time_anchor", "symbols": ["time_anchor_offset"], "postprocess": id},
{"name": "time_anchor", "symbols": ["time_anchor_offset", "_", {"literal":"/"}, "_", "grain"], "postprocess": ([mod, , , , truncate]) => mod.withTruncate(truncate)},
{"name": "time_anchor_offset$string$1", "symbols": [{"literal":"n"}, {"literal":"o"}, {"literal":"w"}], "postprocess": function joiner(d) {return d.join('');}},
{"name": "time_anchor_offset", "symbols": ["time_anchor_offset$string$1"], "postprocess": () => RillTimeAnchor.now()},
{"name": "time_anchor_offset$string$2", "symbols": [{"literal":"e"}, {"literal":"a"}, {"literal":"r"}, {"literal":"l"}, {"literal":"i"}, {"literal":"e"}, {"literal":"s"}, {"literal":"t"}], "postprocess": function joiner(d) {return d.join('');}},
{"name": "time_anchor_offset", "symbols": ["time_anchor_offset$string$2"], "postprocess": () => RillTimeAnchor.earliest()},
{"name": "time_anchor_offset$string$3", "symbols": [{"literal":"l"}, {"literal":"a"}, {"literal":"t"}, {"literal":"e"}, {"literal":"s"}, {"literal":"t"}], "postprocess": function joiner(d) {return d.join('');}},
{"name": "time_anchor_offset", "symbols": ["time_anchor_offset$string$3"], "postprocess": () => RillTimeAnchor.latest()},
{"name": "time_anchor_offset", "symbols": ["grain_modifier"], "postprocess": ([grain]) => RillTimeAnchor.custom(grain)},
{"name": "grain_and_at_part", "symbols": [{"literal":":"}, "_", "range_grain_modifier", "_", {"literal":"@"}, "_", "at_modifiers"], "postprocess": ([, , grain, , , , modifier]) => ({ grain, modifier })},
{"name": "grain_and_at_part", "symbols": [{"literal":":"}, "_", "range_grain_modifier"], "postprocess": ([, , grain]) => ({ grain })},
{"name": "grain_and_at_part", "symbols": [{"literal":"@"}, "_", "at_modifiers"], "postprocess": ([, , modifier]) => ({ modifier })},
{"name": "range_grain_modifier", "symbols": ["grain"], "postprocess": ([grain]) => ({ grain, isComplete: false })},
{"name": "range_grain_modifier", "symbols": [{"literal":"|"}, "_", "grain", "_", {"literal":"|"}], "postprocess": ([, ,grain]) => ({ grain, isComplete: true })},
{"name": "at_modifiers", "symbols": ["grain_modifier"], "postprocess": ([grain]) => ({ at: RillTimeAnchor.custom(grain) })},
{"name": "at_modifiers", "symbols": ["timezone_modifier"], "postprocess": ([timeZone]) => ({ timeZone })},
{"name": "at_modifiers", "symbols": ["grain_modifier", "_", "timezone_modifier"], "postprocess": ([grain, , timeZone]) => ({ at: RillTimeAnchor.custom(grain), timeZone })},
{"name": "grain_modifier", "symbols": ["grain"], "postprocess": ([grain]) => ({ count: 0, grain })},
{"name": "grain_modifier", "symbols": ["int", "grain"], "postprocess": ([count, grain]) => ({ count, grain })},
{"name": "timezone_modifier$ebnf$1", "symbols": [/[^}]/]},
{"name": "timezone_modifier$ebnf$1", "symbols": ["timezone_modifier$ebnf$1", /[^}]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
{"name": "timezone_modifier", "symbols": [{"literal":"{"}, "_", "timezone_modifier$ebnf$1", "_", {"literal":"}"}], "postprocess": ([, , tz]) => tz.join("")},
{"name": "grain", "symbols": [/[smhdDWQMY]/], "postprocess": id}
];
let ParserStart = "rill_time";
Original file line number Diff line number Diff line change
@@ -5,38 +5,39 @@

@{%
import {
RillTimeModifier,
RillTimeAnchor,
RillTime,
} from "./RillTime.ts"
%}

rill_time => time_mod _ "," _ time_mod _ ":" _ modifiers {% ([start, , , , end, , , , modifiers]) => new RillTime(start, end, modifiers) %}
| time_mod _ "," _ time_mod {% ([start, , , , end]) => new RillTime(start, end) %}
| time_mod _ ":" _ modifiers {% ([start, , , , modifiers]) => new RillTime(start, undefined, modifiers) %}
| time_mod {% ([start]) => new RillTime(start) %}
rill_time => time_anchor_part {% ([{ start, end }]) => new RillTime(start, end) %}
| time_anchor_part _ grain_and_at_part {% ([{ start, end }, , { grain, modifier }]) => new RillTime(start, end, grain, modifier) %}

time_mod => time_mod_offset {% id %}
| time_mod_offset _ "/" _ grain {% ([mod, , , , truncate]) => mod.withTruncate(truncate) %}
time_anchor_part => time_anchor _ "," _ time_anchor {% ([start, , , , end]) => ({ start, end }) %}
| time_anchor {% ([start]) => ({ start }) %}

time_mod_offset => "now" {% () => RillTimeModifier.now() %}
| "earliest" {% () => RillTimeModifier.earliest() %}
| "latest" {% () => RillTimeModifier.latest() %}
| grain_modifier {% ([grain]) => RillTimeModifier.custom(grain) %}
time_anchor => time_anchor_offset {% id %}
| time_anchor_offset _ "/" _ grain {% ([mod, , , , truncate]) => mod.withTruncate(truncate) %}

modifiers => range_grain_modifier {% ([timeRangeGrain]) => ({ timeRangeGrain }) %}
| range_grain_modifier _ at_modifiers {% ([timeRangeGrain, , atModifiers]) => ({ timeRangeGrain, ...atModifiers }) %}
| at_modifiers {% id %}
time_anchor_offset => "now" {% () => RillTimeAnchor.now() %}
| "earliest" {% () => RillTimeAnchor.earliest() %}
| "latest" {% () => RillTimeAnchor.latest() %}
| grain_modifier {% ([grain]) => RillTimeAnchor.custom(grain) %}

at_modifiers => "@" _ grain_modifier {% ([, , grain]) => ({ grain }) %}
| "@" _ timezone_modifier {% ([, , timeZone]) => ({ timeZone }) %}
| "@" _ grain_modifier _ timezone_modifier {% ([, , timeZone]) => ({ timeZone }) %}
grain_and_at_part => ":" _ range_grain_modifier _ "@" _ at_modifiers {% ([, , grain, , , , modifier]) => ({ grain, modifier }) %}
| ":" _ range_grain_modifier {% ([, , grain]) => ({ grain }) %}
| "@" _ at_modifiers {% ([, , modifier]) => ({ modifier }) %}

range_grain_modifier => grain {% ([grain]) => ({ grain, isComplete: false }) %}
| "|" _ grain _ "|" {% ([, ,grain]) => ({ grain, isComplete: true }) %}

at_modifiers => grain_modifier {% ([grain]) => ({ at: RillTimeAnchor.custom(grain) }) %}
| timezone_modifier {% ([timeZone]) => ({ timeZone }) %}
| grain_modifier _ timezone_modifier {% ([grain, , timeZone]) => ({ at: RillTimeAnchor.custom(grain), timeZone }) %}

grain_modifier => grain {% ([grain]) => ({ count: 0, grain }) %}
| int grain {% ([count, grain]) => ({ count, grain }) %}

timezone_modifier => "{" _ [a-zA-Z]:+ _ "}" {% ([, , tz]) => tz %}

range_grain_modifier => grain {% ([grain]) => ({ grain, isComplete: false }) %}
| "|" _ grain _ "|" {% ([, ,grain]) => ({ grain, isComplete: true }) %}
timezone_modifier => "{" _ [^}]:+ _ "}" {% ([, , tz]) => tz.join("") %}

grain => [smhdDWQMY] {% id %}
Original file line number Diff line number Diff line change
@@ -5,51 +5,51 @@ import nearley from "nearley";

describe("rill time", () => {
describe("positive cases", () => {
const Cases = [
{
rillTime: "m : |s|",
label: "Minute to date, incomplete",
},
{
rillTime: "-5m : |m|",
label: "Last 5 minutes, incomplete",
},
{
rillTime: "-5m, 0m : |m|",
label: "Last 5 minutes, complete",
},
{
rillTime: "-7d, 0d : |h|",
label: "Last 7 days, complete",
},
{
rillTime: "-6d, now : |h|",
label: "Last 7 days, incomplete",
},
{
rillTime: "-6d, now : h",
label: "Last 7 days, incomplete",
},
{
rillTime: "d : h",
label: "Today, incomplete",
},
const Cases: [rillTime: string, label: string][] = [
["m : |s|", "Minute to date, incomplete"],
["-5m : |m|", "Last 5 minutes, incomplete"],
["-5m, 0m : |m|", "Last 5 minutes"],
["-7d, 0d : |h|", "Last 7 days"],
["-7d, now/d : |h|", "Last 7 days"],
["-6d, now : |h|", "Last 7 days, incomplete"],
["-6d, now : h", "Last 7 days, incomplete"],
["d : h", "Today, incomplete"],

// TODO: correct label for the below
["-7d, -5d : h", "-7d, -5d : h"],
["-2d, now/d : h @ -5d", "-2d, now/d : h @ -5d"],
["-2d, now/d @ -5d", "-2d, now/d @ -5d"],

[
"-7d, now/d : h @ {Asia/Kathmandu}",
"-7d, now/d : h @ {Asia/Kathmandu}",
],
[
"-7d, now/d : |h| @ {Asia/Kathmandu}",
"-7d, now/d : |h| @ {Asia/Kathmandu}",
],
[
"-7d, now/d : |h| @ -5d {Asia/Kathmandu}",
"-7d, now/d : |h| @ -5d {Asia/Kathmandu}",
],

// TODO: should these be something different when end is latest vs now?
["-7d, latest/d : |h|", "Last 7 days"],
["-6d, latest : |h|", "Last 6 days, incomplete"],
["-6d, latest : h", "Last 6 days, incomplete"],
];

const compiledGrammar = nearley.Grammar.fromCompiled(grammar);
for (const { rillTime, label } of Cases) {
for (const [rillTime, label] of Cases) {
it(rillTime, () => {
const parser = new nearley.Parser(compiledGrammar);
parser.feed(rillTime);
// assert that there is only match. this ensures unambiguous grammar.
expect(parser.results).length(1);

const rt = parseRillTime(rillTime);
expect(
rt.getLabel({
completeness: true,
}),
).toEqual(label);
console.log(rt);
expect(rt.getLabel()).toEqual(label);
});
}
});

Unchanged files with check annotations Beta

name: string,
timeRanges: V1TimeRange[],
): DashboardTimeControls | undefined {
const tr = timeRanges.find((tr) => tr.rillTime === name);

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/proto.spec.ts > toProto/fromProto > backwards compatibility for time controls

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ Module.getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ src/features/dashboards/proto-state/proto.spec.ts:45:7

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset dashboard store > from filters

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset dashboard store > from time range

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset dashboard store > from dimension table

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset dashboard store > from time dimension details

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset dashboard store > from pivot

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset partial dashboard store > to filters

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset partial dashboard store > to time range

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset partial dashboard store > to dimension table

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5

Check failure on line 460 in web-common/src/features/dashboards/time-controls/time-control-store.ts

GitHub Actions / build

src/features/dashboards/proto-state/sparse-proto.spec.ts > sparse proto > should reset partial dashboard store > to time dimension details

TypeError: Cannot read properties of undefined (reading 'find') ❯ Module.findTimeRange src/features/dashboards/time-controls/time-control-store.ts:460:25 ❯ fromTimeRangeUrlParam src/features/dashboards/url-state/convertPresetToExploreState.ts:229:26 ❯ fromTimeRangesParams src/features/dashboards/url-state/convertPresetToExploreState.ts:140:45 ❯ Module.convertPresetToExploreState src/features/dashboards/url-state/convertPresetToExploreState.ts:109:5 ❯ getInitExploreStateForTest src/features/dashboards/stores/test-data/helpers.ts:69:35 ❯ initAdBidsInStore src/features/dashboards/stores/test-data/helpers.ts:41:5 ❯ Module.resetDashboardStore src/features/dashboards/stores/test-data/helpers.ts:34:3 ❯ src/features/dashboards/proto-state/sparse-proto.spec.ts:92:5
if (!tr) return undefined;
return {
name: name as TimeRangePreset,