[pull] master from cube-js:master - #708
Merged
Merged
Conversation
* feat(cube-cli): list dbt sync history and read one sync's logs `cube dbt` could start and follow a sync, but not look back at one. Two commands complete it: - `cube dbt history <deployment>` lists recent syncs β id, status, trigger, start, duration, branch β paged with `--first`/`--after`. - `cube dbt logs <deployment> <sync-job-id>` prints a sync's phase timeline and the text a failed phase produced, colouring failure entries. A duration is the server's own `durationMs` or an empty cell β never the difference of two stamps written by different processes, which can disagree with it and, for a run that fails moments after starting, be negative. The two `--wait` failure messages now name `cube dbt logs` for the run that failed, which is the difference between a CI step that explains itself and one that only says "dbt sync failed"; both paths build that message through one function instead of two copies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(cube-cli): address dbt history and logs review feedback - Every history cell is read the same way, through one `cell` reader: `status` keeps its single key, now with the reason it is the one field that cannot have a second spelling. - Cells are bounded and single-line, so a value carrying a newline can no longer break the row it sits in, nor an unbounded one the layout. - Server log text is stripped of control characters other than the line breaks and tabs the timeline keeps on purpose. `one_line` was never the guard it looks like: ESC is not whitespace, so a hostile dbt error could have retitled a window or overwritten the lines above it in a CI log. - The raw-entry fallback no longer repeats the timestamp and stage the JSON already carries, and keeps its red when the entry says it is a failure β the entry this build understood least is the last place to drop that signal. - `history`'s "could not read this" warning keys on the sync job id rather than on every cell being blank, which one filled column was enough to defeat. - `human_duration_ms` rejects a float too large to cast, which saturated into a confident five-billion-hour duration instead of passing through. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(cube-cli): filter dbt history, and time each phase in dbt logs Aligns both commands with what the endpoints they call actually publish. - `dbt history` takes `--status` and `--trigger`, sent through unchecked: the two vocabularies are the server's, and a filter this build has not heard of is one the server can still honour, where a list hard-coded here would refuse it. - `dbt logs` drops `--first`/`--after`. One sync's timeline is one page, bounded by the number of phases it ran, so the flags were accepted here and ignored there β a promise of paging that does not exist. - A log line now carries how long its phase took, sharing one bracket with the phase name so a multi-line failure is interrupted by neither. The timings are half of what makes this a timeline rather than a list of remarks. - Fields are read under the names the endpoints publish, and only those: the second spellings were insurance taken out before the shapes were settled, and every one of them was dead. `status` is no longer the odd column out, since no column carries an alias now. A listed run can be CANCELLED or UNKNOWN as well as the two the status endpoint calls terminal. Nothing here acts on a status, so they pass through as they arrived; the docs note that a cancelled run is still a failure to a `--wait` gate, which needs a terminal answer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(cube-cli): refuse an empty dbt history filter, and spell its case out - `--status` and `--trigger` carry a `nonempty_filter` parser, like every other free-text argument in the tree. An empty value is not dropped β `push` sends `status=` β so a CI script whose `$STATUS` did not expand would have listed whatever the server made of an empty filter. - Both vocabularies are the server's and they do not share a case (statuses upper, triggers lower), so the help and the docs now spell that out: a mis-cased value is the one mistake that may come back as an empty table rather than as a complaint, and an empty table reads as an answer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(cube-cli): trim a dbt history filter, unlike a branch name A filter is one word out of a vocabulary the server publishes, and no member of it has a space in it β so ` FAILED` could only ever match nothing, landing in the exact failure this argument's help was written to prevent: an empty table that reads as an answer. `$(jq -r β¦)` and a value read out of a file are the ordinary ways to acquire the padding. The two helpers beside it still return what they were given, because a branch name is the caller's own and `--branch ' x '` can name a branch that exists. A test pins the divergence rather than leaving it to be read as an oversight. Also rewraps the docs paragraph the previous commit left one line too long. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(cube-cli): drop a field the run record does not carry The fixture claimed an `updatedAt` on a listed run. The endpoint deliberately does not publish one β the column behind it is frozen at the launch insert, so a field with that name would never update β and a fixture that carries what the transport does not is the kind of self-consistent wrong stub that green-lights a reader nobody has actually exercised. Nothing read it, so this is fidelity only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
β¦nularity switcher (#11718) * docs(dashboards): document the user-attribute default on the time granularity switcher The controls page documents this setting for filters, parent controls and field switchers; the Time granularity switcher section stopped at the static default, which is now only half the story. Covers what the attribute is matched against (the granularity NAMES, not the localized labels the control renders), what an unusable value does, and where the attribute sits in the precedence order against a URL parameter, a viewer's own pick and a parent control's mapping. * docs(dashboards): scope the granularity attribute-default claims to what the control actually does Review round, all three fair: - The parent-control clause read unconditionally, but an option can leave a child empty β `resolveParentApplications` returns no application for it, so the attribute still seeds the switcher. Scoped, with the third state ("Reset to default", which goes to the SAVED default rather than the viewer's attribute) named as well. - The match target is the switcher's ALLOWED granularities, not the full built-in set; naming that here saves a round trip to the paragraph below. - Nested under "Default granularity" as `####`, so the section's opening "the default above" points at its enclosing heading β the shape the filter's and parent's versions already have. * docs(dashboards): say exactly what Reset to default does to an attribute-seeded switcher Verified against the implementation rather than asserted: `resolveParentApplications` resolves a TIME_GRAIN reset to the child's saved `defaultGrain` and never consults `userAttributeName`, and skips the child entirely when no default is saved β so the attribute value survives that case. Both branches are now pinned by tests in `parent-widget.spec.ts` (cubedevinc/cubejs-enterprise#14627).
β¦ashboard's filters (#11719) * docs(dashboards): say that a chart opened in the workbook keeps the dashboard's filters Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(dashboards): describe the carried filters as they render, in the report's own filter bar Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(dashboards): name the From dashboard cue, and split the two questions the edit bullet answered Review notes: colour was left as the only way to tell a carried filter from a report one, and the chips do carry a "From dashboard" tooltip β so name it and keep the tint as the at-a-glance cue. The second bullet asked "can I change this?" and answered "edit the dashboard control", which is about what viewers get, not about the person in the workbook wanting another value; those are now separate, and the multi-sentence bullets end in full stops. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(dashboards): name the field switcher in the controls list, and keep the third bullet under its lead-in Review nits: the page's controls list predated field switchers and this PR's new paragraph names them, so the omission had become an in-page contradiction; and the third bullet opened on the UI affordance rather than continuing "they are not the report's". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* docs: sync API reference for platform-client v0.6.0 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS9D79N13zEksXB13WeSRa * fix(docs): hoist nullable-field metadata and de-collide SCIM sidebar groups Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS9D79N13zEksXB13WeSRa * fix(docs): scope the nullable-metadata hoist to the exact two-branch shape Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS9D79N13zEksXB13WeSRa * style(docs): trim the hoist function's comment Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WS9D79N13zEksXB13WeSRa --------- Co-authored-by: Claude <noreply@anthropic.com>
* docs(dashboards): a parent control can drive a field switcher
CUB-4269 removes the limitation the Controls page documented in two places:
a field switcher can now be a parent control's child, so it appears in the
Children picker, its mapping row renders its own member picker, and it carries
the same mapping-status indicator the other child controls do.
Also documents `ms_`, the field switcher's own URL parameter. It shipped with
the control (CUB-454/CUB-4159) but the page still said a viewer's choice was
not carried in the link. It travels in a shared link and β unlike `f_` / `tg_`
β not in a scheduled export or a screenshot, whose URLs are rebuilt from a
server-side allowlist that has no entry for it.
* docs(dashboards): resolve the ms_ contradiction the first pass left behind
Review caught that "Sharing the current selection" still carried a bullet
saying a field switcher "has no parameter of its own" β nine lines below the
`ms_` row this branch adds. The page contradicted itself on its most
load-bearing new claim.
That bullet now states what actually happens, keeping the boundary the new Note
draws: the pick travels in a shared link, and does not survive a scheduled
export or a screenshot, whose URLs are rebuilt server-side from an allowlist
with no field-switcher parameter. The bullet above it widens from "filters and
granularities" to every control type, since a parent's children can now include
a switcher.
Also widens the table's explanatory paragraph from "semantic view and dimension"
to "member" and says the right-hand side of `ms_` is an internal name too β and
a measure when the switcher's Field Type is Measure.
And adds the missing `ms_` row to the embedded-dashboard URL table, which the
controls page sends readers to for "the same format" and which still listed
only `f_` and `tg_`.
* docs(dashboards): close the remaining two-of-three control enumerations
Review found the same pattern in three more places, all of which now under-count
the control types:
- the "Sharing the current selection" intro still promised the recipient "the
same filters and granularities", eighteen lines above the `ms_` row;
- the "parameter is ignored" enumeration listed two reject cases where there are
now three β a selected member outside the switcher's Alternatives is dropped
the same way an unlisted granularity is (`dashboard-member-switchers.ts`
drops a URL member that `isSelectable` rejects), and the page already commits
to exactly that behaviour for the attribute path;
- the parent user-attribute example named the two child types it used to have.
On the embed page, the prose quoted `<semantic_view>` / `<dimension>` as
literals, so neither of the `ms_` row's own placeholders was covered by the rule
governing them β it now describes the parts instead β and the setting is named
**Field Type**, as the control spells it, on the page a reader reaches without
that context. Its reject enumeration gains the member case too.
Deliberately not touched: the embed page's section heading (and the link text
mirroring it) still say "filters and granularities". Renaming a published
heading is a wider change than this PR, and its anchor is explicit, so the
wording is a follow-up rather than a correctness gap.
* docs(dashboards): say member, not dimension, where the clause now governs ms_
Follow-through on the reject enumeration this branch just widened. The first
case in that same sentence still said "no matching control for that dimension",
but the clause governs all three parameters now and an `ms_` key is a measure
whenever the switcher's Field Type is Measure β the case the paragraph two above
goes out of its way to spell out. Both pages now say "member", matching the
vocabulary shift already made at the table.
On the embed page, **Alternatives** is also bolded and linked to the field
switcher section, so it reads like its sibling in the same sentence (the
allowed-granularities link) rather than as plain prose β that page is the one a
reader reaches without the controls page's context.
* docs(dashboards): document the field switcher's precedence, and stop saying it twice
Three follow-ups from review, all created by this branch rather than pre-existing:
- The field switcher's **User attribute default** section was the only one of the
three that never said how the attribute interacts with a URL parameter or a
parent control β and before this branch neither applied to it, so the gap is
ours. It now states the whole chain, matching the time granularity twin.
Verified rather than mirrored: `dashboard-member-switchers.ts` seeds
`urlMember ?? attributeMember ?? defaultOption ?? replacedMember`, an unmapped
parent cell emits no application at all (so the attribute's seed stands), and
RESET targets `defaultOption ?? replaced member` without re-resolving the
attribute.
- The field switcher `<Note>` had become a second copy of the Sharing bullet,
which is the fuller version and sits in the section that owns the topic β
`docs-mintlify/CLAUDE.md:267` ("Say it once"). The callout keeps the pointer
and drops the mechanism.
- Re-wrapped the embed paragraph to the file's ~80 columns; taking the earlier
suggestion verbatim had left it ragged with "For" stranded.
* docs(dashboards): name the resolution in the Note, and finish the re-flow
Trimming the Note left it saying an export renders "the control's default
member", where the bullet it defers to says "the default option β or the
recipient's own user attribute where one is set". Inconsistent about the same
mechanism, and read most often by an author who has just turned the attribute
default on two sections above. It now names the resolution instead of one of its
outcomes: those surfaces open on whatever member the control resolves for the
recipient on its own.
The previous re-wrap fixed the first three lines but left "Type** is
**Measure**. For" at 26 columns β the stranded break that was the point of the
report. Closing it needs the following sentence pulled up, past where the
suggestion block reached; the paragraph now flows at ~78 with only the URL line
long, as it already was.
* docs(dashboards): the replaced member is offered too, so ms_ back to it is honoured
Both reject clauses said a member "isn't among the field switcher's
Alternatives", which is narrower than the code: `isSelectable` is
`candidate === member || options.includes(candidate)`, so the replaced member is
selectable as well. `ms_orders.status=status` β the hand-written way to deep-link
back to the original view β is honoured, and both pages told the reader it was
ignored.
The embed page matters more here, since it is about hand-writing the parameter,
but the controls page's sentence sits directly under "you can also write these
parameters by hand", so both are read by someone acting on the rule.
Left as-is: the attribute paragraph's identical shorthand, which is pre-existing
and sits in a passage that is not about authoring a value.
* docs(dashboards): a parent is the third thing an export can resolve a switcher to
The Sharing bullet named the default option and the recipient's attribute, but a
parent control driving the switcher is the path this branch itself added β and
in a server-rendered copy there is no `ms_`, so the parent opens on its own
default (or the recipient's attribute) and drives its children.
Verified both halves in `dashboard-parent.ts`: a plain `defaultOptionId` needs no
mount-time write because `persistSelection` already wrote the mapped member into
the child's own `defaultOption`, and a user-attribute parent pushes on mount
(`applyParentOption(..., { isSeeding: true })`) because no saved child config can
carry a per-viewer value. Either way the switcher shows what the parent maps.
Same over-statement as the Note fixed one commit ago; here the enumeration is
worth keeping since this is the section that owns the topic, so it is extended
rather than replaced.
* docs(dashboards): name the setting in the Reset row, not the outcome
The field switcher's cell said Reset puts it back to "the member it opens on",
which for a viewer with a user-attribute default IS the attribute's member β the
exact resolution the clause added one commit ago says Reset does not perform.
`getSwitcherDefaultMember` returns `defaultOption ?? replaced member` and never
consults the attribute, so the row now names the setting, as its two siblings
already did.
The default-granularity link goes in alongside for symmetry: a reader who needs
"what is the default option" needs the same answer for granularity.
* docs(dashboards): the mapping picker offers the replaced member too
Last instance of the Alternatives narrowing, and here it made the sentence
contradict its own next clause: the picker was described as Alternatives-only
while the following sentence promised "exactly the ones a viewer could pick".
Checked the editor rather than the analogy, as the review asked:
`ParentChildValueControl` builds the row's options with `resolveSwitcherOptions`,
passing `memberName: parsed.memberName`, and that helper PREPENDS the replaced
member (`[memberName, ...configured]`). So the picker does offer it, and
"exactly" was the accurate half.
Also re-read the section as one claim rather than fixing this line alone β
L150 (offered set), L176 (precedence), L193, L225 (Reset), L314 and L317 now
tell the same story. L176's "outranks both" is left as-is deliberately: it
mirrors the time-granularity twin's established phrasing at L132, so changing
only the switcher's copy would introduce a divergence rather than remove one.
* docs(dashboards): drop the export carve-out β CUB-4289 landed
Verified on master rather than taking the report: #14633 merged at 11:10 today
and `ALLOWED_CAPTURE_PARAM_PREFIXES` is now `['f_', 'tg_', 'ms_']`, with
`buildFilterQueryParams` taking `memberSwitcherState` as a required argument and
a `DashboardMemberSwitcherInput` carrying the selection through scheduled runs.
So a field switcher's member now reaches every server-rendered copy, and both
sentences this branch added about it not surviving one are false.
The `<Note>` is deleted rather than inverted: it existed only to record
limitations, and with the last one gone there is no caveat to call out β the
positive statement already lives in the section that owns the topic, so
inverting it here would re-create the duplication removed in 74e5fd3.
The Sharing bullet goes for the same reason: its entire content was the
carve-out, and "Every control's pick, together" already covers all three types.
Deliberately NOT documenting the new export behaviour here β #11723
owns that and describes it more fully (link carries only what the viewer chose;
an export carries every switcher and outranks an attribute; a scheduled export
renders the member stored on the schedule).
β¦st two (#11738) * docs(dashboards): an export carries every control's selection, not just two The Dashboards page told readers that a PNG/PDF snapshot carries "the filter and time-grain selections you currently have applied in your browser". That was exhaustive when it was written and stopped being so when CUB-4289 landed (cubedevinc/cubejs-enterprise#14633): a field switcher's member now reaches every server-rendered copy too, so the sentence enumerated two of the three things that travel and silently excluded the third. Left behind by the two PRs that covered this on the Controls and embedding pages β different file, so neither touched it, and a reader who only ever opens the Dashboards overview would still have concluded their switcher does not survive an export. Scope is deliberately just this sentence. `memberSwitchers`, the API field for the scheduled case, is not hand-documented here because `filters` and `timeGrains` aren't either β those reach readers through the generated management-API reference, and the new field lands there with the next SDK release. * docs(dashboards): scope the export claim to a download you start yourself Review caught that the sentence was over-broad in a way the page then invites the reader to act on. Three paragraphs down it says the same screenshot mechanism powers PNG/PDF attachments on scheduled notifications β so "the selections you currently have applied in your browser are carried into the export" reads as covering the scheduled case, where there is no browser session at all and the attachment renders whatever the notification itself carries. That over-broadness predates this PR: the original sentence made the same claim about filters and time grains. Fixed here rather than left alone, since this PR is what draws attention to the sentence. Also from review: "time granularity switcher" is what controls.mdx calls the second control, so the list now names all three the same way instead of mixing a thing ("time grains") with two control types; and the paragraph is re-wrapped to the file's ~76 columns. * docs(dashboards): don't send readers to a notification setting that has no UI "Renders the selections configured on the notification" promised something a reader can go and find. They can't: the notification card is delivery channel β recipients β attachment format β AI summary, and notifications.mdx documents only PNG vs PDF about the attachment. The capability is real but API-only, and `memberSwitchers` isn't in the checked-in spec yet β so linking the management API would fail them too, three paragraphs above a link to the page that already would. Also fixes the assumption underneath it: the sentence implied a notification always carries selections. Most don't. With none configured `buildDashboardFilterParams` returns `undefined`, the capture URL is left untouched, and the board renders its own defaults β which is the common case and now the one stated first.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? π Please sponsor : )