@malloy-publisher/server 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/assets/{EnvironmentPage-D6kQraU3.js → EnvironmentPage-CMNz23OH.js} +1 -1
- package/dist/app/assets/{HomePage-BZbuE5jv.js → HomePage-CIFBQm1O.js} +1 -1
- package/dist/app/assets/{LightMode-BxZdPcNr.js → LightMode-230hA2MG.js} +1 -1
- package/dist/app/assets/{MainPage-DrczCw4J.js → MainPage-DBgaP8G6.js} +2 -2
- package/dist/app/assets/{MaterializationsPage-BFLHLEuk.js → MaterializationsPage-B5tdbpRJ.js} +1 -1
- package/dist/app/assets/ModelPage-A6Kd1_wx.js +2 -0
- package/dist/app/assets/{PackagePage-DHsVf_mP.js → PackagePage-JUM3EcgJ.js} +1 -1
- package/dist/app/assets/RenderedResult-mDE-4u8S.es-s0zwv__L.js +116 -0
- package/dist/app/assets/{RouteError-CHq8ubhy.js → RouteError-BJAZkbpg.js} +1 -1
- package/dist/app/assets/{ThemeEditorPage-B2y8Y64Y.js → ThemeEditorPage-a0QNervK.js} +1 -1
- package/dist/app/assets/index-B5_U5YBb.js +1 -0
- package/dist/app/assets/index-BR3mOYNn.js +1322 -0
- package/dist/app/assets/{index-By-g8wiC.js → index-CNMFq7Ua.js} +1 -1
- package/dist/app/assets/index-CRAwrhYM.js +2 -0
- package/dist/app/assets/index-DplzDOL2.js +453 -0
- package/dist/app/assets/index-JaIfCAcq.js +443 -0
- package/dist/app/assets/index.es-CB4dOn75.js +106 -0
- package/dist/app/index.html +1 -1
- package/dist/server.mjs +52 -47
- package/package.json +1 -1
- package/dist/app/assets/ModelPage-CFnfQ6BL.js +0 -1
- package/dist/app/assets/index-BVv6KQ93.js +0 -557
- package/dist/app/assets/index-Bqrhk3ff.js +0 -2
- package/dist/app/assets/index-CawCwLK3.js +0 -1774
package/dist/server.mjs
CHANGED
|
@@ -320380,14 +320380,18 @@ Scanned at a glance is a dashboard; read top to bottom is a notebook.
|
|
|
320380
320380
|
2. **PICK THE VIEWS TO SHOW.** A dashboard is \`## artifact { tiles=[…] }\` naming existing views, so
|
|
320381
320381
|
this is the design step: which views, how wide each sits, what each is called. There is one form,
|
|
320382
320382
|
so there is no form to choose.
|
|
320383
|
-
3. **DECLARE THE GIVENS** the dashboard will filter by, in the
|
|
320384
|
-
|
|
320385
|
-
|
|
320383
|
+
3. **DECLARE THE GIVENS** the dashboard will filter by, in the dashboard file itself, with their
|
|
320384
|
+
control tags: see "Filter controls" below for the syntax and what each tag renders as. That is
|
|
320385
|
+
the convention because the dashboard builder edits the dashboard file and nothing else, so a
|
|
320386
|
+
filter it can add, change or remove is a declaration in that file. Bind them on the tiles (step
|
|
320387
|
+
4). Reuse the package's \`givens.malloy\` only for a control several surfaces genuinely share, and
|
|
320388
|
+
then import it whole, knowing the builder can bind those givens but not edit them.
|
|
320386
320389
|
4. **COMPOSE THE FILE** for \`dashboards/\`, following the template below, but do not save it yet.
|
|
320387
|
-
|
|
320388
|
-
|
|
320389
|
-
|
|
320390
|
-
|
|
320390
|
+
Name the sources you need: \`import { order_items, products } from '../storefront.malloy'\`.
|
|
320391
|
+
Each tile binds its controls with a refinement, \`view: t is v + { where: category ~ $CATEGORY }\`,
|
|
320392
|
+
one clause per given it answers to; a \`filter<...>\` binds with \`~\`, a plain \`date\` or \`number\`
|
|
320393
|
+
given is a value and binds with \`>=\`, \`<=\` or \`=\`. Only the givens some tile references become
|
|
320394
|
+
controls, so a declaration nothing binds shows nothing. Then import every
|
|
320391
320395
|
source or query any referenced given names in a \`suggest\`. Both are per-file, and getting the
|
|
320392
320396
|
suggest wrong does not error: the control still looks like a picker but has no options, and says
|
|
320393
320397
|
so underneath, "Could not load the options for this control". The package warnings name it too. **A \`suggest\` naming a \`query=\` needs that
|
|
@@ -320422,33 +320426,31 @@ out by Publisher into the grid \`# dashboard { columns=N }\` names.
|
|
|
320422
320426
|
\`\`\`malloy
|
|
320423
320427
|
##! experimental.givens
|
|
320424
320428
|
## artifact { title="Storefront overview" tiles=["overview -> kpis", "overview -> revenue_trend", "overview -> revenue_by_state"] } dashboard { columns=12 }
|
|
320425
|
-
import {
|
|
320426
|
-
|
|
320427
|
-
|
|
320429
|
+
import { order_items, products } from '../storefront.malloy'
|
|
320430
|
+
|
|
320431
|
+
// The controls, declared here: the tags are each one's control contract.
|
|
320432
|
+
# label="Category" control=select suggest { source=products dimension=category }
|
|
320433
|
+
given: CATEGORY :: filter<string> is f''
|
|
320434
|
+
# label="Ordered since"
|
|
320435
|
+
given: SINCE :: date is @2023-01-01
|
|
320428
320436
|
|
|
320429
320437
|
// Layout goes on the VIEW, and a thin re-declaration is the place to put it: the
|
|
320430
|
-
// modelled view keeps its chart tag,
|
|
320431
|
-
|
|
320438
|
+
// modelled view keeps its chart tag, this decides how wide it sits here, and the
|
|
320439
|
+
// \`+ { where: ... }\` says which controls the tile answers to.
|
|
320440
|
+
source: overview is order_items extend {
|
|
320432
320441
|
# colspan=12
|
|
320433
320442
|
# label="Key figures"
|
|
320434
320443
|
# big_value
|
|
320435
|
-
view: kpis is {
|
|
320436
|
-
aggregate:
|
|
320437
|
-
# label="Revenue"
|
|
320438
|
-
# currency
|
|
320439
|
-
total_sales
|
|
320440
|
-
# label="Orders"
|
|
320441
|
-
order_count
|
|
320442
|
-
}
|
|
320444
|
+
view: kpis is key_figures + { where: category ~ $CATEGORY, where: created_at >= $SINCE }
|
|
320443
320445
|
|
|
320444
320446
|
# colspan=8
|
|
320445
320447
|
# break
|
|
320446
320448
|
# label="Revenue by month"
|
|
320447
|
-
view: revenue_trend is sales_by_month
|
|
320449
|
+
view: revenue_trend is sales_by_month + { where: category ~ $CATEGORY, where: created_at >= $SINCE }
|
|
320448
320450
|
|
|
320449
320451
|
# colspan=4
|
|
320450
320452
|
# label="Revenue by state"
|
|
320451
|
-
view: revenue_by_state is sales_by_state
|
|
320453
|
+
view: revenue_by_state is sales_by_state + { where: category ~ $CATEGORY, where: created_at >= $SINCE }
|
|
320452
320454
|
}
|
|
320453
320455
|
\`\`\`
|
|
320454
320456
|
|
|
@@ -320461,8 +320463,8 @@ Three things the form costs, so you are not surprised by them:
|
|
|
320461
320463
|
- **A tile expression is a string in an annotation, so the compiler never checks it.** Rename a view
|
|
320462
320464
|
and the file still compiles; the tile fails at package load. Read the lint (step 6).
|
|
320463
320465
|
- **No per-parent-row grouping.** There is no parent query to repeat a grid over.
|
|
320464
|
-
- **Filtering lives
|
|
320465
|
-
|
|
320466
|
+
- **Filtering lives on the tiles**, not on the page: each view's \`+ { where: ... }\` names the
|
|
320467
|
+
controls it answers to. Below is why, and the one thing that does not work.
|
|
320466
320468
|
|
|
320467
320469
|
### Also served: \`# artifact\` on a \`query:\`
|
|
320468
320470
|
|
|
@@ -320522,23 +320524,24 @@ object", so a dashboard has no description as a result.
|
|
|
320522
320524
|
|
|
320523
320525
|
### Where the filtering goes
|
|
320524
320526
|
|
|
320525
|
-
A dashboard has no query, so
|
|
320526
|
-
|
|
320527
|
-
|
|
320528
|
-
|
|
320529
|
-
|
|
320530
|
-
|
|
320531
|
-
|
|
320532
|
-
|
|
320533
|
-
|
|
320534
|
-
|
|
320535
|
-
|
|
320536
|
-
|
|
320537
|
-
|
|
320538
|
-
|
|
320539
|
-
|
|
320540
|
-
|
|
320541
|
-
|
|
320527
|
+
A dashboard has no query, so its filtering lives on the views it names: a \`+ { where: field ~ $GIVEN }\`
|
|
320528
|
+
refinement on each tile, one clause per control the tile answers to. A tile without the clause does
|
|
320529
|
+
not move when the control does, which is how a page keeps one tile fixed while the rest filter. The
|
|
320530
|
+
givens those clauses read are declared in the same file (step 3).
|
|
320531
|
+
|
|
320532
|
+
**Binding is per declaration, not per name.** Measured: a dashboard declaring its own \`CATEGORY\`
|
|
320533
|
+
over a source whose model-level \`where:\` reads the model's \`CATEGORY\` compiles, shows the control,
|
|
320534
|
+
and filters nothing when it moves, because the two declarations only share a name. So do not mix
|
|
320535
|
+
the two designs on one given. The other design still works on its own: a source with the givens
|
|
320536
|
+
already applied in an untagged \`dashboards/_shared.malloy\`, reading \`import '../givens.malloy'\`,
|
|
320537
|
+
which discovery treats as a shared include rather than a dashboard. Then the dashboard imports both
|
|
320538
|
+
and the controls render for the givens its tiles reach. A given the dashboard imports but nothing
|
|
320539
|
+
references gets no control, silently, at reload 200 with no warning. Save the include before you
|
|
320540
|
+
compile the dashboard that imports it, since an importer compiled against a sibling that is not on
|
|
320541
|
+
disk fails with an \`import-error\`. The builder can bind such a control but not add, change or
|
|
320542
|
+
remove it, since it never edits imports or model files.
|
|
320543
|
+
|
|
320544
|
+
Note \`SINCE\` is a \`date\` rather than a \`filter<>\`, so it compares with \`>=\` rather than \`~\`.
|
|
320542
320545
|
|
|
320543
320546
|
**\`# dashboard { columns=N }\` is the one spelling of the grid width**, on both forms, beside the
|
|
320544
320547
|
artifact tag. Anything else inside the artifact tag is a package warning naming it, which is what you
|
|
@@ -320620,9 +320623,10 @@ rows.
|
|
|
320620
320623
|
- **The filename is the dashboard's name:** its URL slug, its listing name, and its \`# drill\`
|
|
320621
320624
|
target. The query inside can be called anything, and sometimes must be (a query named \`regions\`
|
|
320622
320625
|
collides with an imported \`regions\` source).
|
|
320623
|
-
- **
|
|
320624
|
-
|
|
320625
|
-
|
|
320626
|
+
- **A given has to be in the dashboard file's scope to be bindable**: declared there (the
|
|
320627
|
+
convention) or imported. Malloy's given namespace is per-file. A given the file cannot see gets
|
|
320628
|
+
no control and cannot be sent to it, even when a \`where:\` that references it lives up an import
|
|
320629
|
+
chain. And a given declared here does not drive a \`where:\` in the model: bind on the tiles.
|
|
320626
320630
|
- **A suggest's source or query has to resolve in the dashboard file too.** \`suggest { source=products … }\`
|
|
320627
320631
|
means the dashboard imports \`products\`.
|
|
320628
320632
|
- **A model-level \`##\` tag must be on one line.** Wrapping one always breaks it, but how you find
|
|
@@ -320641,9 +320645,10 @@ choosing them.
|
|
|
320641
320645
|
|
|
320642
320646
|
## Filter controls
|
|
320643
320647
|
|
|
320644
|
-
Controls come from the \`given:\` declarations the
|
|
320645
|
-
|
|
320646
|
-
|
|
320648
|
+
Controls come from the \`given:\` declarations the tiles reference. Declare them in the dashboard
|
|
320649
|
+
file, which is what the builder edits; a package \`givens.malloy\` is for controls the data app and
|
|
320650
|
+
notebooks share, and a dashboard importing it whole gets the same controls but cannot edit them.
|
|
320651
|
+
The tags on the declaration are the control contract:
|
|
320647
320652
|
|
|
320648
320653
|
\`\`\`malloy
|
|
320649
320654
|
##! experimental.givens
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{D as g,r as j,a0 as u,j as a,J as s,a1 as N,a2 as d,a3 as y,H as f,Q as k,a4 as b,a5 as F,a6 as U,T as l,a7 as c,a8 as x}from"./index-BVv6KQ93.js";function v(e,n){const t=g();return j.useCallback((o,i)=>{const r=new URLSearchParams(o.givens).toString(),m=encodeURIComponent(e),p=encodeURIComponent(n),h=encodeURIComponent(o.dashboard);t(`/${m}/${p}/dashboards/${h}`+(r?`?${r}`:""),i)},[t,e,n])}function W({environmentName:e,packageName:n,dashboardName:t}){const{params:o,onGivensChange:i}=u(),r=v(e,n);return a.jsx(s,{sx:{p:3,maxWidth:1600,mx:"auto"},children:a.jsx(N,{resourceUri:d({environmentName:e,packageName:n}),dashboard:t,givens:o,onGivensChange:i,onNavigate:r,maxResultSize:1024*1024})})}function P({environmentName:e,packageName:n,notebookPath:t}){const{params:o,onGivensChange:i}=u(),r=v(e,n),m=g();return a.jsx(s,{sx:{p:3,maxWidth:1200,mx:"auto"},children:a.jsx(y,{resourceUri:d({environmentName:e,packageName:n,modelPath:t}),maxResultSize:1024*1024,givens:o,onGivensChange:i,onNavigate:m,onDrillNavigate:r})})}function C(){const e=f(),n=e["*"],{server:t}=k();if(!e.environmentName)return a.jsx("div",{children:a.jsx("h2",{children:"Missing environment name"})});if(!e.packageName)return a.jsx("div",{children:a.jsx("h2",{children:"Missing package name"})});const o={p:3,maxWidth:1200,mx:"auto"};if(n?.startsWith("dashboards/")&&!n.endsWith(".malloy")&&!n.endsWith(".malloynb"))return a.jsx(W,{environmentName:e.environmentName,packageName:e.packageName,dashboardName:n.slice(11)});if(n?.startsWith("data-apps/")&&!n.endsWith(".malloy")&&!n.endsWith(".malloynb")){const p=n.slice(10),h=d({environmentName:e.environmentName,packageName:e.packageName,modelPath:p});return a.jsx(b,{resourceUri:h})}const i=d({environmentName:e.environmentName,packageName:e.packageName,modelPath:n});if(n?.endsWith(".malloy"))return a.jsx(s,{sx:o,children:a.jsx(F,{resourceUri:i,runOnDemand:!0,maxResultSize:512*1024})});if(n?.endsWith(".malloynb"))return a.jsx(P,{environmentName:e.environmentName,packageName:e.packageName,notebookPath:n});const r=/\.[^./]+$/.test(n??""),m=U({server:t,environmentName:e.environmentName,packageName:e.packageName,path:n??""});return a.jsxs(s,{sx:o,children:[a.jsx(l,{variant:"h6",sx:{fontWeight:600},children:"Nothing to open at this path"}),a.jsxs(l,{variant:"body2",color:"text.secondary",sx:{mt:1},children:[a.jsx(s,{component:"span",sx:{fontFamily:c},children:n})," ","does not name a"," ",a.jsx(s,{component:"span",sx:{fontFamily:c},children:".malloy"})," ","or"," ",a.jsx(s,{component:"span",sx:{fontFamily:c},children:".malloynb"})," ","file in package"," ",a.jsx(s,{component:"span",sx:{fontFamily:c},children:e.packageName}),". This address opens"," ",a.jsx(s,{component:"span",sx:{fontFamily:c},children:".malloy"})," ","and"," ",a.jsx(s,{component:"span",sx:{fontFamily:c},children:".malloynb"})," ","files."]}),r&&a.jsxs(l,{variant:"body2",color:"text.secondary",sx:{mt:1},children:["A file from the package's"," ",a.jsx(s,{component:"span",sx:{fontFamily:c},children:"public/"})," ","directory is served at ",a.jsx(x,{href:m,children:m}),"."]}),a.jsxs(l,{variant:"body2",color:"text.secondary",sx:{mt:1},children:[a.jsxs(x,{href:`/${encodeURIComponent(e.environmentName)}/${encodeURIComponent(e.packageName)}`,children:["Back to ",e.packageName]})," ","lists this package's models, notebooks, and data apps."]})]})}export{C as default};
|