terrier-engine 4.32.0 → 4.32.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.
@@ -1,4 +1,4 @@
1
- // This file was automatically generated on 2024-07-17 13:26:00 -0500, DO NOT EDIT IT MANUALLY!
1
+ // This file was automatically generated on 2024-07-25 17:02:53 -0500, DO NOT EDIT IT MANUALLY!
2
2
 
3
3
  import { Query } from "../queries/queries"
4
4
 
@@ -171,6 +171,7 @@ export type DdDiveRun = {
171
171
  output_data?: object
172
172
  output_file_data?: Attachment | { path: string }
173
173
  status: "initial" | "running" | "success" | "error"
174
+ delivery_mode?: string
174
175
  delivery_recipients?: string[]
175
176
  delivery_data?: object
176
177
  created_by?: DdUser
@@ -194,6 +195,7 @@ export type UnpersistedDdDiveRun = {
194
195
  output_data?: object
195
196
  output_file_data?: Attachment | { path: string }
196
197
  status: "initial" | "running" | "success" | "error"
198
+ delivery_mode?: string
197
199
  delivery_recipients?: string[]
198
200
  delivery_data?: object
199
201
  created_by?: DdUser
@@ -0,0 +1,62 @@
1
+ import {AxisType} from "tuff-plot/axis"
2
+ import {TerrierFormFields} from "../../terrier/forms"
3
+ import {PartTag} from "tuff-core/parts"
4
+ import TerrierPart from "../../terrier/parts/terrier-part"
5
+ import {DbErrors} from "../../terrier/db-client"
6
+ import * as inflection from "inflection"
7
+
8
+
9
+ // let's not worry about a top axis for now
10
+ const axisSides = ['left', 'bottom', 'right'] as const
11
+ export type AxisSide = typeof axisSides[number]
12
+
13
+ export type DivePlotAxisType = AxisType | 'none'
14
+
15
+ export type DivePlotAxis = {
16
+ type: DivePlotAxisType
17
+ title: string
18
+ }
19
+
20
+ const axisTypeOptions = [
21
+ {value: 'none', title: 'None'},
22
+ {value: 'number', title: 'Number'},
23
+ {value: 'time', title: 'Date/Time'},
24
+ {value: 'group', title: 'Grouped Bars'},
25
+ {value: 'stack', title: 'Stacked Bars'},
26
+ ]
27
+
28
+ export class DivePlotAxisFields extends TerrierFormFields<DivePlotAxis> {
29
+
30
+ constructor(part: TerrierPart<any>, axis: DivePlotAxis, readonly side: AxisSide, errors?: DbErrors<DivePlotAxis>) {
31
+ super(part, axis, errors)
32
+ }
33
+
34
+ render(parent: PartTag) {
35
+ parent.div(`.dd-dive-plot-axis-fields.tt-form.shrink.${this.side}`, container => {
36
+ container.div('.side').text(`${inflection.titleize(this.side)} Axis:`)
37
+
38
+ // title
39
+ this.textInput(container, "title", {placeholder: "Title"})
40
+
41
+ // type
42
+ const typeDir = this.side == 'bottom' ? 'row' : 'column'
43
+ container.div(`.tt-flex.wrapped.small-gap.${typeDir}`, flex => {
44
+ axisTypeOptions.forEach(option => {
45
+ if ((this.side == 'bottom' || this.side == 'left') && option.value == 'none') {
46
+ return // don't let them not have a bottom or left axis
47
+ }
48
+ flex.label(".caption-size", label => {
49
+ this.radio(label, 'type', option.value)
50
+ label.span().text(option.title)
51
+ })
52
+ })
53
+ })
54
+ })
55
+ }
56
+ }
57
+
58
+
59
+ const DivePlotAxes = {
60
+ axisSides
61
+ }
62
+ export default DivePlotAxes
@@ -3,12 +3,13 @@ import {ModalPart} from "../../terrier/modals"
3
3
  import {DiveEditorState} from "../dives/dive-editor"
4
4
  import {UnpersistedDdDivePlot} from "../gen/models"
5
5
  import {TerrierFormFields} from "../../terrier/forms"
6
- import {DivePlotTrace} from "./dive-plots"
7
6
  import Messages from "tuff-core/messages"
8
7
  import {Logger} from "tuff-core/logging"
9
8
  import DivePlotList from "./dive-plot-list"
10
9
  import Db from "../dd-db"
11
10
  import DivePlotRenderPart from "./dive-plot-render-part"
11
+ import {DivePlotAxis, DivePlotAxisFields} from "./dive-plot-axes"
12
+ import {DivePlotTrace} from "./dive-plot-trace"
12
13
 
13
14
  const log = new Logger("DivePlotList")
14
15
 
@@ -16,12 +17,13 @@ export type DivePlotEditorState = DiveEditorState & {
16
17
  plot: UnpersistedDdDivePlot
17
18
  }
18
19
 
19
-
20
-
21
20
  export default class DivePlotEditor extends ModalPart<DivePlotEditorState> {
22
21
 
23
22
  plot!: UnpersistedDdDivePlot
24
23
  fields!: TerrierFormFields<UnpersistedDdDivePlot>
24
+ leftAxisFields!: DivePlotAxisFields
25
+ rightAxisFields!: DivePlotAxisFields
26
+ bottomAxisFields!: DivePlotAxisFields
25
27
  traces: DivePlotTrace[] = []
26
28
  renderPart!: DivePlotRenderPart
27
29
  saveKey = Messages.untypedKey()
@@ -39,6 +41,15 @@ export default class DivePlotEditor extends ModalPart<DivePlotEditorState> {
39
41
 
40
42
  this.fields = new TerrierFormFields<UnpersistedDdDivePlot>(this, this.plot)
41
43
 
44
+ // axis fields
45
+ const axes = this.plot.layout.axes || {}
46
+ const leftAxis: DivePlotAxis = axes['left'] || {type: 'number', title: ''}
47
+ this.leftAxisFields = new DivePlotAxisFields(this, leftAxis, 'left')
48
+ const rightAxis: DivePlotAxis = axes['right'] || {type: 'none', title: ''}
49
+ this.rightAxisFields = new DivePlotAxisFields(this, rightAxis, 'right')
50
+ const bottomAxis: DivePlotAxis = axes['bottom'] || {type: 'number', title: ''}
51
+ this.bottomAxisFields = new DivePlotAxisFields(this, bottomAxis, 'bottom')
52
+
42
53
  this.traces = this.plot.traces || []
43
54
 
44
55
  this.renderPart = this.makePart(DivePlotRenderPart, this.state)
@@ -57,12 +68,20 @@ export default class DivePlotEditor extends ModalPart<DivePlotEditorState> {
57
68
 
58
69
  renderContent(parent: PartTag): void {
59
70
  parent.div(".tt-flex.column.padded.gap", mainColumn => {
60
- this.fields.compoundField(mainColumn, field => {
61
- field.label(".required").text("Title")
62
- this.fields.textInput(field, 'title')
71
+
72
+ mainColumn.div(".dd-plot-axes-and-preview.tt-flex.column.gap", axesAndPreview => {
73
+ this.fields.compoundField(axesAndPreview, field => {
74
+ field.label(".required").text("Title")
75
+ this.fields.textInput(field, 'title', {class: 'shrink plot-title'})
76
+ }).class('plot-title-field')
77
+ axesAndPreview.div('.tt-flex.gap', row => {
78
+ this.leftAxisFields.render(row)
79
+ row.part(this.renderPart)
80
+ this.rightAxisFields.render(row)
81
+ })
82
+ this.bottomAxisFields.render(axesAndPreview)
63
83
  })
64
84
 
65
- mainColumn.part(this.renderPart)
66
85
 
67
86
  mainColumn.h3(".glyp-items").text("Traces")
68
87
 
@@ -72,6 +91,13 @@ export default class DivePlotEditor extends ModalPart<DivePlotEditorState> {
72
91
  async save() {
73
92
  const plotData = await this.fields.serialize()
74
93
  const plot = {...this.plot, title: plotData.title}
94
+
95
+ plot.layout.axes = {
96
+ left: await this.leftAxisFields.serialize(),
97
+ bottom: await this.bottomAxisFields.serialize(),
98
+ right: await this.rightAxisFields.serialize()
99
+ }
100
+
75
101
  log.info("Saving plot", plot)
76
102
 
77
103
  const res = await Db().upsert('dd_dive_plot', plot)
@@ -0,0 +1,16 @@
1
+ import {MarkerStyle, TraceStyle, TraceType, YAxisName} from "tuff-plot/trace";
2
+
3
+ /**
4
+ * Similar to the tuff-plot Trace but not strongly typed to the data type since it's dynamically assigned to a query.
5
+ */
6
+ export type DivePlotTrace = {
7
+ id: string
8
+ type: TraceType
9
+ title: string
10
+ query_id: string
11
+ x: string
12
+ y: string
13
+ y_axis: YAxisName
14
+ style?: TraceStyle
15
+ marker?: MarkerStyle
16
+ }
@@ -1,27 +1,19 @@
1
-
2
- import {MarkerStyle, TraceStyle, TraceType, YAxisName} from "tuff-plot/trace"
3
- import {PlotLayout} from "tuff-plot/layout"
4
1
  import {DdDive, DdDivePlot} from "../gen/models"
5
2
  import Db from "../dd-db"
3
+ import {DivePlotAxis} from "./dive-plot-axes"
6
4
 
7
- /**
8
- * Similar to the tuff-plot Trace but not strongly typed to the data type since it's dynamically assigned to a query.
9
- */
10
- export type DivePlotTrace = {
11
- id: string
12
- type: TraceType
13
- title: string
14
- query_id: string
15
- x: string
16
- y: string
17
- y_axis: YAxisName
18
- style?: TraceStyle
19
- marker?: MarkerStyle
20
- }
21
5
 
22
- // maybe we'll add more in the future
23
- export type DivePlotLayout = PlotLayout
6
+ // mimic PlotLayout but with our own types
7
+ export type DivePlotLayout = {
8
+ pad?: number
9
+ axes?: {
10
+ left?: DivePlotAxis
11
+ top?: DivePlotAxis
12
+ right?: DivePlotAxis
13
+ bottom?: DivePlotAxis
14
+ }
24
15
 
16
+ }
25
17
  /**
26
18
  * Get all plots for the given dive.
27
19
  * @param dive
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "files": [
5
5
  "*"
6
6
  ],
7
- "version": "4.32.0",
7
+ "version": "4.32.1",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/Terrier-Tech/terrier-engine"
package/terrier/forms.ts CHANGED
@@ -150,7 +150,7 @@ export class TerrierFormFields<T extends FormPartData> extends FormFields<T> {
150
150
  * @param fun a function that accepts the field as an argument, to actually populate the field
151
151
  */
152
152
  compoundField(parent: PartTag, fun: (field: DivTag) => any) {
153
- parent.div(".tt-compound-field", field => {
153
+ return parent.div(".tt-compound-field", field => {
154
154
  fun(field)
155
155
  })
156
156
  }
@@ -150,8 +150,6 @@ export default abstract class PagePart<TState> extends ContentPart<TState> {
150
150
  if (!this._breadcrumbs.length && !this._title?.length) return
151
151
 
152
152
  parent.h1('.breadcrumbs', h1 => {
153
- const crumbs = Array.from(this._breadcrumbs)
154
-
155
153
  // add a breadcrumb for the page title
156
154
  if (this._title?.length) {
157
155
  const titleCrumb: Action = {
@@ -164,10 +162,10 @@ export default abstract class PagePart<TState> extends ContentPart<TState> {
164
162
  if (this._titleClasses?.length) {
165
163
  titleCrumb.classes = this._titleClasses
166
164
  }
167
- crumbs.push(titleCrumb)
165
+ this.addBreadcrumb(titleCrumb)
168
166
  }
169
167
 
170
- this.app.theme.renderActions(h1, crumbs)
168
+ this.app.theme.renderActions(h1, Array.from(this._breadcrumbs))
171
169
  })
172
170
  }
173
171