terrier-engine 4.7.5 → 4.7.7
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.
|
@@ -12,6 +12,8 @@ import {DiveSettingsModal} from "./dive-settings"
|
|
|
12
12
|
import DdSession from "../dd-session"
|
|
13
13
|
import Messages from "tuff-core/messages"
|
|
14
14
|
import Arrays from "tuff-core/arrays"
|
|
15
|
+
import TerrierPart from "../../terrier/parts/terrier-part"
|
|
16
|
+
import {DiveRunModal} from "./dive-runs"
|
|
15
17
|
|
|
16
18
|
const log = new Logger("DiveList")
|
|
17
19
|
|
|
@@ -20,43 +22,32 @@ const log = new Logger("DiveList")
|
|
|
20
22
|
// List
|
|
21
23
|
////////////////////////////////////////////////////////////////////////////////
|
|
22
24
|
|
|
23
|
-
export
|
|
25
|
+
export type DiveListState = {
|
|
26
|
+
mode: 'editor' | 'readonly' // whether or not to allow editing or simply viewing dives
|
|
27
|
+
}
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Show a list of all dive groups and dives that match the given state.
|
|
31
|
+
*/
|
|
32
|
+
export class DiveListPart extends TerrierPart<DiveListState> {
|
|
33
|
+
|
|
34
|
+
editGroupKey = Messages.typedKey<{ id: string }>()
|
|
35
|
+
newDiveKey = Messages.typedKey<{ group_id: string }>()
|
|
36
|
+
editDiveKey = Messages.typedKey<{ id: string }>()
|
|
37
|
+
runDiveKey = Messages.typedKey<{ id: string }>()
|
|
29
38
|
|
|
30
39
|
session!: DdSession
|
|
31
40
|
result!: DiveListResult
|
|
32
41
|
schema!: SchemaDef
|
|
33
42
|
groupMap: Record<string, DdDiveGroup> = {}
|
|
34
|
-
diveMap: Record<string,DdDive> = {}
|
|
43
|
+
diveMap: Record<string, DdDive> = {}
|
|
44
|
+
|
|
35
45
|
|
|
36
46
|
async init() {
|
|
37
|
-
this.setTitle("Data Dive")
|
|
38
|
-
this.setIcon('glyp-data_dives')
|
|
39
47
|
|
|
40
48
|
this.schema = await Schema.get()
|
|
41
49
|
this.session = await DdSession.get()
|
|
42
50
|
|
|
43
|
-
this.mainContentWidth = 'wide'
|
|
44
|
-
|
|
45
|
-
this.addAction({
|
|
46
|
-
title: "New Group",
|
|
47
|
-
icon: 'glyp-plus_outline',
|
|
48
|
-
click: {key: this.newGroupKey}
|
|
49
|
-
}, 'tertiary')
|
|
50
|
-
|
|
51
|
-
this.onClick(this.newGroupKey, _ => {
|
|
52
|
-
log.info("Showing new dive group model")
|
|
53
|
-
const newGroup = {name: '', group_types: []}
|
|
54
|
-
this.app.showModal(GroupEditorModal, {session: this.session,
|
|
55
|
-
group: newGroup,
|
|
56
|
-
callback: _ => this.reload()
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
51
|
this.onClick(this.editGroupKey, m => {
|
|
61
52
|
log.info(`Edit group ${m.data.id}`)
|
|
62
53
|
const group = this.groupMap[m.data.id]
|
|
@@ -66,8 +57,7 @@ export class DiveListPage extends PagePart<{}> {
|
|
|
66
57
|
group: group as UnpersistedDdDiveGroup,
|
|
67
58
|
callback: _ => this.reload()
|
|
68
59
|
})
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
60
|
+
} else {
|
|
71
61
|
this.alertToast(`No group with id ${m.data.id}`)
|
|
72
62
|
}
|
|
73
63
|
})
|
|
@@ -91,13 +81,22 @@ export class DiveListPage extends PagePart<{}> {
|
|
|
91
81
|
if (dive) {
|
|
92
82
|
log.info(`Editing settings for dive: ${dive.name}`)
|
|
93
83
|
this.app.showModal(DiveSettingsModal, {schema: this.schema, dive, session: this.session})
|
|
84
|
+
} else {
|
|
85
|
+
log.warn(`No dive with id ${m.data.id}`)
|
|
94
86
|
}
|
|
95
|
-
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
this.onClick(this.runDiveKey, m => {
|
|
90
|
+
const dive = this.diveMap[m.data.id] as DdDive
|
|
91
|
+
if (dive) {
|
|
92
|
+
log.info(`Running dive ${dive.name}`)
|
|
93
|
+
this.app.showModal(DiveRunModal, {dive})
|
|
94
|
+
} else {
|
|
96
95
|
log.warn(`No dive with id ${m.data.id}`)
|
|
97
96
|
}
|
|
98
97
|
})
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
this.reload().then()
|
|
101
100
|
}
|
|
102
101
|
|
|
103
102
|
async reload() {
|
|
@@ -109,7 +108,7 @@ export class DiveListPage extends PagePart<{}> {
|
|
|
109
108
|
this.dirty()
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
render(parent: PartTag): any {
|
|
113
112
|
|
|
114
113
|
const groupedDives = Arrays.groupBy(this.result.dives, 'dd_dive_group_id')
|
|
115
114
|
|
|
@@ -122,7 +121,7 @@ export class DiveListPage extends PagePart<{}> {
|
|
|
122
121
|
}
|
|
123
122
|
|
|
124
123
|
renderGroupPanel(parent: PartTag, group: DdDiveGroup, dives: DdDive[]) {
|
|
125
|
-
Fragments.panel(this.theme)
|
|
124
|
+
const panel = Fragments.panel(this.theme)
|
|
126
125
|
.title(group.name)
|
|
127
126
|
.icon((group.icon || 'glyp-data_dives') as IconName)
|
|
128
127
|
.classes('group')
|
|
@@ -132,36 +131,99 @@ export class DiveListPage extends PagePart<{}> {
|
|
|
132
131
|
this.renderDiveRow(content, dive)
|
|
133
132
|
}
|
|
134
133
|
})
|
|
135
|
-
|
|
134
|
+
if (this.state.mode == 'editor') {
|
|
135
|
+
panel.addAction({
|
|
136
136
|
title: "New Dive",
|
|
137
137
|
icon: 'glyp-data_dive',
|
|
138
138
|
click: {key: this.newDiveKey, data: {group_id: group.id}}
|
|
139
139
|
}, 'secondary')
|
|
140
|
-
.addAction({
|
|
140
|
+
panel.addAction({
|
|
141
141
|
icon: 'glyp-settings',
|
|
142
142
|
click: {key: this.editGroupKey, data: {id: group.id}}
|
|
143
143
|
}, 'tertiary')
|
|
144
|
-
|
|
144
|
+
}
|
|
145
|
+
panel.render(parent)
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
renderDiveRow(parent: PartTag, dive: DdDive) {
|
|
148
149
|
parent.div('.dive', row => {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
a
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
if (this.state.mode == 'editor') {
|
|
151
|
+
row.a({href: routes.editor.path({id: dive.id})}, a => {
|
|
152
|
+
if (dive.visibility == 'private') {
|
|
153
|
+
a.i('.glyp-privacy')
|
|
154
|
+
.data({tooltip: "Private Dive"})
|
|
155
|
+
} else {
|
|
156
|
+
a.i('.glyp-data_dive')
|
|
157
|
+
.data({tooltip: "Public Dive"})
|
|
158
|
+
}
|
|
159
|
+
a.span().text(dive.name)
|
|
160
|
+
}).data({tooltip: "Open Editor"})
|
|
161
|
+
row.a('.icon-only', a => {
|
|
162
|
+
a.i('.glyp-settings')
|
|
163
|
+
}).data({tooltip: "Dive Settings"})
|
|
164
|
+
.emitClick(this.editDiveKey, {id: dive.id})
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// readonly mode
|
|
168
|
+
row.a(a => {
|
|
169
|
+
if (dive.visibility == 'private') {
|
|
170
|
+
a.i('.glyp-privacy')
|
|
171
|
+
.data({tooltip: "Private Dive"})
|
|
172
|
+
} else {
|
|
173
|
+
a.i('.glyp-data_dive')
|
|
174
|
+
.data({tooltip: "Public Dive"})
|
|
175
|
+
}
|
|
176
|
+
a.span().text(dive.name)
|
|
177
|
+
})
|
|
178
|
+
.data({tooltip: "Run Dive"})
|
|
179
|
+
.emitClick(this.runDiveKey, {id: dive.id})
|
|
180
|
+
}
|
|
163
181
|
})
|
|
164
182
|
}
|
|
165
183
|
|
|
166
184
|
}
|
|
167
185
|
|
|
186
|
+
|
|
187
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
188
|
+
// Page
|
|
189
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
190
|
+
|
|
191
|
+
export class DiveListPage extends PagePart<{}> {
|
|
192
|
+
|
|
193
|
+
listPart!: DiveListPart
|
|
194
|
+
newGroupKey = Messages.untypedKey()
|
|
195
|
+
|
|
196
|
+
async init() {
|
|
197
|
+
this.setTitle("Data Dive")
|
|
198
|
+
this.setIcon('glyp-data_dives')
|
|
199
|
+
this.mainContentWidth = 'wide'
|
|
200
|
+
|
|
201
|
+
this.listPart = this.makePart(DiveListPart, {mode: 'editor'})
|
|
202
|
+
|
|
203
|
+
this.addAction({
|
|
204
|
+
title: "New Group",
|
|
205
|
+
icon: 'glyp-plus_outline',
|
|
206
|
+
click: {key: this.newGroupKey}
|
|
207
|
+
}, 'tertiary')
|
|
208
|
+
|
|
209
|
+
// we're handling this here instead of in the list part because, as of 9/15/23,
|
|
210
|
+
// attach: 'passive' doesn't seem to work for click handlers,
|
|
211
|
+
// so this handler never got called when it was inside the list part
|
|
212
|
+
this.onClick(this.newGroupKey, _ => {
|
|
213
|
+
log.info("Showing new dive group model")
|
|
214
|
+
const newGroup = {name: '', group_types: []}
|
|
215
|
+
this.app.showModal(GroupEditorModal, {
|
|
216
|
+
session: this.listPart.session,
|
|
217
|
+
group: newGroup,
|
|
218
|
+
callback: _ => this.listPart.reload()
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
renderContent(parent: PartTag): void {
|
|
224
|
+
parent.part(this.listPart)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
@@ -120,9 +120,18 @@ class PreviewPart extends ContentPart<SubEditorState> {
|
|
|
120
120
|
|
|
121
121
|
renderContent(parent: PartTag) {
|
|
122
122
|
if (this.result) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
if (this.result.columns?.length) {
|
|
124
|
+
parent.div('.table-container', col => {
|
|
125
|
+
Queries.renderPreview(col, this.result!)
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// empty query
|
|
130
|
+
parent.div('.dd-hint-container', hintContainer => {
|
|
131
|
+
hintContainer.div('.dd-hint.centered.glyp-columns')
|
|
132
|
+
.text("Select at least one column")
|
|
133
|
+
})
|
|
134
|
+
}
|
|
126
135
|
}
|
|
127
136
|
else {
|
|
128
137
|
parent.a('.tt-button.stretch', a => {
|
package/package.json
CHANGED
package/terrier/fragments.ts
CHANGED
|
@@ -90,11 +90,11 @@ export class PanelFragment extends ContentFragment {
|
|
|
90
90
|
return parent.div(this.prefix, panel => {
|
|
91
91
|
if (this._title?.length) {
|
|
92
92
|
panel.div(`.${noTtPrefix}-header`, header => {
|
|
93
|
-
header.
|
|
93
|
+
header.h3(h3 => {
|
|
94
94
|
if (this._icon) {
|
|
95
|
-
this.theme.renderIcon(
|
|
95
|
+
this.theme.renderIcon(h3, this._icon, 'link')
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
h3.div('.title', {text: this._title})
|
|
98
98
|
})
|
|
99
99
|
this.theme.renderActions(header, this.actions.tertiary)
|
|
100
100
|
})
|