terrier-engine 4.52.3 → 4.52.5
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/data-dive/dives/dive-editor.ts +1 -10
- package/package.json +1 -1
- package/terrier/gen/hub-icons.ts +10 -2
- package/terrier/images/icons/step_demo.svg +1 -0
- package/terrier/images/optimized/icon-step_demo.svg +1 -0
- package/terrier/images/raw/icon-step_demo.svg +10 -0
- package/terrier/plugins/load-on-scroll-plugin.ts +1 -1
- package/terrier/tabs.ts +39 -28
|
@@ -49,8 +49,6 @@ export default class DiveEditor extends ContentPart<DiveEditorState> {
|
|
|
49
49
|
static readonly diveChangedKey = Messages.untypedKey()
|
|
50
50
|
|
|
51
51
|
queries = new Map<string, Query>()
|
|
52
|
-
// Array of map keys to give the queries a sort order.
|
|
53
|
-
queryOrder = new Array<string>()
|
|
54
52
|
|
|
55
53
|
async init() {
|
|
56
54
|
this.queryTabs = this.makePart(TabContainerPart, { side: 'top', reorderable: true })
|
|
@@ -82,7 +80,6 @@ export default class DiveEditor extends ContentPart<DiveEditorState> {
|
|
|
82
80
|
this.queries = new Map()
|
|
83
81
|
for (const query of this.state.dive.query_data?.queries || []) {
|
|
84
82
|
this.queries.set(query.id, query)
|
|
85
|
-
this.queryOrder.push(query.id)
|
|
86
83
|
this.addQueryTab(query)
|
|
87
84
|
}
|
|
88
85
|
|
|
@@ -92,12 +89,6 @@ export default class DiveEditor extends ContentPart<DiveEditorState> {
|
|
|
92
89
|
this.queryTabs.updateTab({ key: query.id, title: query.name })
|
|
93
90
|
})
|
|
94
91
|
|
|
95
|
-
// Reorder queries in the list when the tab sort order is updated.
|
|
96
|
-
this.listenMessage(this.queryTabs.tabsModifiedKey, m => {
|
|
97
|
-
const { newOrder } = m.data
|
|
98
|
-
this.queryOrder = newOrder
|
|
99
|
-
})
|
|
100
|
-
|
|
101
92
|
this.onClick(this.newQueryKey, _ => {
|
|
102
93
|
this.app.showModal(NewQueryModal, { editor: this as DiveEditor, schema: this.state.schema })
|
|
103
94
|
})
|
|
@@ -188,7 +179,7 @@ export default class DiveEditor extends ContentPart<DiveEditorState> {
|
|
|
188
179
|
|
|
189
180
|
return {
|
|
190
181
|
...this.state.dive,
|
|
191
|
-
query_data: { queries: this.
|
|
182
|
+
query_data: { queries: this.queryTabs.getTabOrder().map(id => queries.get(id)!) }
|
|
192
183
|
}
|
|
193
184
|
}
|
|
194
185
|
|
package/package.json
CHANGED
package/terrier/gen/hub-icons.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// This file was automatically generated on
|
|
1
|
+
// This file was automatically generated on 2025-05-30 09:45:22 -0500, DO NOT EDIT IT MANUALLY!
|
|
2
2
|
|
|
3
3
|
import {ColorName} from "../theme"
|
|
4
4
|
import {PartTag} from "tuff-core/parts"
|
|
@@ -341,6 +341,10 @@ import StatusRaw from '../images/icons/status.svg?raw'
|
|
|
341
341
|
// @ts-ignore
|
|
342
342
|
import StatusSrc from '../images/icons/status.svg'
|
|
343
343
|
// @ts-ignore
|
|
344
|
+
import StepDemoRaw from '../images/icons/step_demo.svg?raw'
|
|
345
|
+
// @ts-ignore
|
|
346
|
+
import StepDemoSrc from '../images/icons/step_demo.svg'
|
|
347
|
+
// @ts-ignore
|
|
344
348
|
import StepDeployRaw from '../images/icons/step_deploy.svg?raw'
|
|
345
349
|
// @ts-ignore
|
|
346
350
|
import StepDeploySrc from '../images/icons/step_deploy.svg'
|
|
@@ -754,6 +758,10 @@ export const IconDefs: Record<HubIconName,{ raw: string, src: string }> = {
|
|
|
754
758
|
raw: StatusRaw,
|
|
755
759
|
src: StatusSrc,
|
|
756
760
|
},
|
|
761
|
+
"hub-step_demo": {
|
|
762
|
+
raw: StepDemoRaw,
|
|
763
|
+
src: StepDemoSrc,
|
|
764
|
+
},
|
|
757
765
|
"hub-step_deploy": {
|
|
758
766
|
raw: StepDeployRaw,
|
|
759
767
|
src: StepDeploySrc,
|
|
@@ -833,7 +841,7 @@ export const IconDefs: Record<HubIconName,{ raw: string, src: string }> = {
|
|
|
833
841
|
}
|
|
834
842
|
|
|
835
843
|
const Names = [
|
|
836
|
-
'hub-active', 'hub-admin', 'hub-archive', 'hub-arrow_down', 'hub-arrow_left', 'hub-arrow_right', 'hub-arrow_up', 'hub-assign', 'hub-attachment', 'hub-back', 'hub-badge', 'hub-board', 'hub-bookmark', 'hub-bookmark_add', 'hub-bookmark_remove', 'hub-bookmarked', 'hub-bookmarks', 'hub-branch', 'hub-bug', 'hub-calculator', 'hub-checkmark', 'hub-close', 'hub-clypboard', 'hub-comment', 'hub-complete', 'hub-dashboard', 'hub-data_pull', 'hub-data_update', 'hub-database', 'hub-day', 'hub-delete', 'hub-documentation', 'hub-edit', 'hub-existing_child', 'hub-existing_parent', 'hub-feature', 'hub-flex', 'hub-forward', 'hub-github', 'hub-history', 'hub-home', 'hub-image', 'hub-inbox', 'hub-info', 'hub-internal', 'hub-issue', 'hub-lane', 'hub-lane_asap', 'hub-lane_days', 'hub-lane_hours', 'hub-lane_weeks', 'hub-lanes_board', 'hub-level_complete', 'hub-level_highway', 'hub-level_on_ramp', 'hub-level_parking', 'hub-link', 'hub-list_view', 'hub-metrics', 'hub-minus', 'hub-new_child', 'hub-new_parent', 'hub-night', 'hub-origin', 'hub-pending', 'hub-plot', 'hub-plus', 'hub-post', 'hub-posts', 'hub-pr_closed', 'hub-pr_merged', 'hub-pr_open', 'hub-prioritized', 'hub-project', 'hub-question', 'hub-reaction', 'hub-recent', 'hub-refresh', 'hub-related_posts', 'hub-releases', 'hub-request', 'hub-settings', 'hub-split_view', 'hub-status', 'hub-step_deploy', 'hub-step_develop', 'hub-step_investigate', 'hub-step_review', 'hub-step_test', 'hub-steps', 'hub-steps_board', 'hub-subscribe', 'hub-support', 'hub-team', 'hub-terrier', 'hub-thumbs_up', 'hub-type', 'hub-unprioritized', 'hub-upload', 'hub-user', 'hub-users', 'hub-website', 'hub-week'
|
|
844
|
+
'hub-active', 'hub-admin', 'hub-archive', 'hub-arrow_down', 'hub-arrow_left', 'hub-arrow_right', 'hub-arrow_up', 'hub-assign', 'hub-attachment', 'hub-back', 'hub-badge', 'hub-board', 'hub-bookmark', 'hub-bookmark_add', 'hub-bookmark_remove', 'hub-bookmarked', 'hub-bookmarks', 'hub-branch', 'hub-bug', 'hub-calculator', 'hub-checkmark', 'hub-close', 'hub-clypboard', 'hub-comment', 'hub-complete', 'hub-dashboard', 'hub-data_pull', 'hub-data_update', 'hub-database', 'hub-day', 'hub-delete', 'hub-documentation', 'hub-edit', 'hub-existing_child', 'hub-existing_parent', 'hub-feature', 'hub-flex', 'hub-forward', 'hub-github', 'hub-history', 'hub-home', 'hub-image', 'hub-inbox', 'hub-info', 'hub-internal', 'hub-issue', 'hub-lane', 'hub-lane_asap', 'hub-lane_days', 'hub-lane_hours', 'hub-lane_weeks', 'hub-lanes_board', 'hub-level_complete', 'hub-level_highway', 'hub-level_on_ramp', 'hub-level_parking', 'hub-link', 'hub-list_view', 'hub-metrics', 'hub-minus', 'hub-new_child', 'hub-new_parent', 'hub-night', 'hub-origin', 'hub-pending', 'hub-plot', 'hub-plus', 'hub-post', 'hub-posts', 'hub-pr_closed', 'hub-pr_merged', 'hub-pr_open', 'hub-prioritized', 'hub-project', 'hub-question', 'hub-reaction', 'hub-recent', 'hub-refresh', 'hub-related_posts', 'hub-releases', 'hub-request', 'hub-settings', 'hub-split_view', 'hub-status', 'hub-step_demo', 'hub-step_deploy', 'hub-step_develop', 'hub-step_investigate', 'hub-step_review', 'hub-step_test', 'hub-steps', 'hub-steps_board', 'hub-subscribe', 'hub-support', 'hub-team', 'hub-terrier', 'hub-thumbs_up', 'hub-type', 'hub-unprioritized', 'hub-upload', 'hub-user', 'hub-users', 'hub-website', 'hub-week'
|
|
837
845
|
] as const
|
|
838
846
|
|
|
839
847
|
export type HubIconName = typeof Names[number]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="currentColor" fill-rule="evenodd"><path fill-opacity="0.33" stroke="currentColor" stroke-linejoin="round" stroke-width="2" d="M5 7h22v14H5z"/><path d="M14 21h4v3h-4z"/><rect width="8" height="2" x="12" y="24" rx="1"/><path d="M13 9.902v8.196a.5.5 0 0 0 .765.424l6.557-4.098a.5.5 0 0 0 0-.848l-6.557-4.098a.5.5 0 0 0-.765.424Z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="#000" fill-rule="evenodd"><path fill-opacity=".25" stroke="#000" stroke-linejoin="round" stroke-width="2" d="M5 7h22v14H5z"/><path d="M14 21h4v3h-4z"/><rect width="8" height="2" x="12" y="24" rx="1"/><path d="M13 9.902v8.196a.5.5 0 0 0 .765.424l6.557-4.098a.5.5 0 0 0 0-.848l-6.557-4.098a.5.5 0 0 0-.765.424Z"/></g></svg>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<title>icon-step_demo</title>
|
|
4
|
+
<g id="icon-step_demo" stroke="none" fill="none" fill-rule="evenodd">
|
|
5
|
+
<rect id="Rectangle" stroke="#000000" stroke-width="2" fill-opacity="0.25" fill="#000000" stroke-linejoin="round" x="5" y="7" width="22" height="14"></rect>
|
|
6
|
+
<rect id="Rectangle" fill="#000000" x="14" y="21" width="4" height="3"></rect>
|
|
7
|
+
<rect id="Rectangle" fill="#000000" x="12" y="24" width="8" height="2" rx="1"></rect>
|
|
8
|
+
<path d="M13,9.90212382 L13,18.0978762 C13,18.3740186 13.2238576,18.5978762 13.5,18.5978762 C13.5937099,18.5978762 13.6855337,18.5715415 13.7649995,18.5218753 L20.3216014,14.4239992 C20.5557696,14.277644 20.6269562,13.9691688 20.480601,13.7350005 C20.4403607,13.670616 20.3859859,13.6162412 20.3216014,13.5760008 L13.7649995,9.47812467 C13.5308312,9.3317695 13.222356,9.40295609 13.0760008,9.63712435 C13.0263347,9.71659015 13,9.80841396 13,9.90212382 Z" id="Path" fill="#000000"></path>
|
|
9
|
+
</g>
|
|
10
|
+
</svg>
|
|
@@ -21,7 +21,7 @@ export type LoadOnScrollOptions<TState> = {
|
|
|
21
21
|
loadNextStates: (existingStates: TState[]) => Promise<TState[] | undefined>
|
|
22
22
|
// The root element whose viewport is scrolling. If not provided, the document viewport is used.
|
|
23
23
|
// Usually not required, but if using intersectThreshold on a scrollable element, might be necessary.
|
|
24
|
-
intersectRootSelector
|
|
24
|
+
intersectRootSelector?: string
|
|
25
25
|
// Percentage of the last item in the collection that must be visible before the next state is loaded.
|
|
26
26
|
// If not provided, a default value of 25% is used. Must be between 0 and 1.
|
|
27
27
|
intersectThreshold?: number
|
package/terrier/tabs.ts
CHANGED
|
@@ -38,10 +38,11 @@ export type TabContainerState = {
|
|
|
38
38
|
|
|
39
39
|
export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
40
40
|
|
|
41
|
-
private tabs =
|
|
41
|
+
private tabs = new Map as Map<string, TabDefinition>
|
|
42
|
+
private tabOrder = [] as string[]
|
|
42
43
|
changeTabKey = Messages.typedKey<{ tabKey: string }>()
|
|
43
44
|
changeSideKey = Messages.typedKey<{ side: TabSide }>()
|
|
44
|
-
tabsModifiedKey = Messages.
|
|
45
|
+
tabsModifiedKey = Messages.untypedKey()
|
|
45
46
|
|
|
46
47
|
async init() {
|
|
47
48
|
this.state = Object.assign({ reorderable: false }, this.state)
|
|
@@ -59,22 +60,29 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
59
60
|
|
|
60
61
|
if (this.state.reorderable) {
|
|
61
62
|
this.makePlugin(SortablePlugin, {
|
|
62
|
-
zoneClass:
|
|
63
|
+
zoneClass: `tablist-${this.id}`,
|
|
63
64
|
targetClass: 'tab',
|
|
64
|
-
onSorted: (
|
|
65
|
-
this.
|
|
65
|
+
onSorted: () => {
|
|
66
|
+
// Get only our tab container, as other tab contains may exist inside this one.
|
|
67
|
+
const ourTabList = this.element?.getElementsByClassName(`tablist-${this.id}`)[0]
|
|
68
|
+
const tabElements = Array.from(ourTabList?.getElementsByClassName('tab') || []) as HTMLElement[]
|
|
69
|
+
this.tabOrder = tabElements.map(tabElement => tabElement.dataset?.key!)
|
|
70
|
+
this.#onTabsModified()
|
|
71
|
+
this.dirty()
|
|
66
72
|
}
|
|
67
73
|
})
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
|
|
71
|
-
onTabsModified(
|
|
72
|
-
|
|
73
|
-
Array.from(this.element?.querySelectorAll('.tt-tab-list') ?? [])
|
|
74
|
-
const newOrder = tabElements.map(tabElement => tabElement.dataset.key)
|
|
75
|
-
this.emitMessage(this.tabsModifiedKey, { newOrder })
|
|
77
|
+
#onTabsModified() {
|
|
78
|
+
this.emitMessage(this.tabsModifiedKey, null)
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Gets the current tab order as an array of keys.
|
|
83
|
+
*/
|
|
84
|
+
getTabOrder = () => [...this.tabOrder]
|
|
85
|
+
|
|
78
86
|
/**
|
|
79
87
|
* Adds or overwrites an existing tab.
|
|
80
88
|
* @param tab initial parameters for the tab
|
|
@@ -86,13 +94,15 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
86
94
|
constructor: { new(p: PartParent, id: string, state: PartStateType): PartType; },
|
|
87
95
|
state: InferredPartStateType
|
|
88
96
|
): PartType {
|
|
89
|
-
const existingTab = this.tabs
|
|
90
|
-
this.tabs[tab.key] = Object.assign(existingTab, {
|
|
91
|
-
state: 'enabled',
|
|
92
|
-
}, tab)
|
|
93
|
-
this.onTabsModified()
|
|
97
|
+
const existingTab = this.tabs.get(tab.key) ?? {}
|
|
94
98
|
const part = this.makePart(constructor, state)
|
|
95
|
-
|
|
99
|
+
this.tabs.set(tab.key, Object.assign(existingTab, {
|
|
100
|
+
state: 'enabled',
|
|
101
|
+
part
|
|
102
|
+
}, tab))
|
|
103
|
+
if (!this.tabOrder.includes(tab.key))
|
|
104
|
+
this.tabOrder.push(tab.key)
|
|
105
|
+
this.#onTabsModified()
|
|
96
106
|
this.dirty()
|
|
97
107
|
return part
|
|
98
108
|
}
|
|
@@ -102,7 +112,7 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
102
112
|
* @param tab
|
|
103
113
|
*/
|
|
104
114
|
updateTab(tab: TabParams): void {
|
|
105
|
-
const existingTab = this.tabs
|
|
115
|
+
const existingTab = this.tabs.get(tab.key)
|
|
106
116
|
if (!existingTab) throw `Tab with key '${tab.key}' does not exist!`
|
|
107
117
|
Object.assign(existingTab, tab)
|
|
108
118
|
this.dirty()
|
|
@@ -113,13 +123,14 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
113
123
|
* @param key
|
|
114
124
|
*/
|
|
115
125
|
removeTab(key: string) {
|
|
116
|
-
const tab = this.tabs
|
|
126
|
+
const tab = this.tabs.get(key)
|
|
117
127
|
if (!tab) return log.warn(`No tab ${key} to remove!`)
|
|
118
128
|
|
|
119
129
|
log.info(`Removing tab ${key}`, tab)
|
|
120
|
-
|
|
130
|
+
this.tabs.delete(key)
|
|
131
|
+
this.tabOrder.splice(this.tabOrder.indexOf(key), 1)
|
|
121
132
|
this.removeChild(tab.part)
|
|
122
|
-
this
|
|
133
|
+
this.#onTabsModified()
|
|
123
134
|
this.state.currentTab = undefined
|
|
124
135
|
this.dirty()
|
|
125
136
|
}
|
|
@@ -129,10 +140,10 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
129
140
|
* @param tabKey
|
|
130
141
|
*/
|
|
131
142
|
showTab(tabKey: string) {
|
|
132
|
-
if (!
|
|
143
|
+
if (!this.tabs.has(tabKey)) {
|
|
133
144
|
throw `Unknown tab key ${tabKey}`
|
|
134
145
|
}
|
|
135
|
-
if (this.tabs
|
|
146
|
+
if (this.tabs.get(tabKey)?.state != 'enabled') return // tab exists but is not enabled
|
|
136
147
|
if (this.state.currentTab === tabKey) return // tab is already selected
|
|
137
148
|
|
|
138
149
|
this.state.currentTab = tabKey
|
|
@@ -143,7 +154,7 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
143
154
|
* Gets the current tab key.
|
|
144
155
|
*/
|
|
145
156
|
get currentTagKey(): string | undefined {
|
|
146
|
-
return this.state.currentTab ||
|
|
157
|
+
return this.state.currentTab || this.tabOrder[0]
|
|
147
158
|
}
|
|
148
159
|
|
|
149
160
|
|
|
@@ -161,20 +172,20 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
161
172
|
this.dirty()
|
|
162
173
|
}
|
|
163
174
|
|
|
164
|
-
|
|
165
|
-
|
|
166
175
|
render(parent: PartTag) {
|
|
167
176
|
let currentTabKey = this.state.currentTab
|
|
168
177
|
if (!currentTabKey) {
|
|
169
178
|
log.debug("no current tab specified, selecting first enabled tab")
|
|
170
|
-
currentTabKey =
|
|
179
|
+
currentTabKey = this.tabs.values().find(t => t.state == 'enabled')?.key
|
|
171
180
|
}
|
|
172
181
|
parent.div('tt-tab-container', this.state.side, container => {
|
|
173
182
|
container.div('.tt-flex.tt-tab-list', tabList => {
|
|
183
|
+
tabList.class(`tablist-${this.id}`)
|
|
174
184
|
if (this._beforeActions.length) {
|
|
175
185
|
this.theme.renderActions(tabList, this._beforeActions, { defaultClass: 'action' })
|
|
176
186
|
}
|
|
177
|
-
for (const
|
|
187
|
+
for (const tabKey of this.tabOrder) {
|
|
188
|
+
const tab = this.tabs.get(tabKey)!
|
|
178
189
|
if (tab.state == 'hidden') continue
|
|
179
190
|
|
|
180
191
|
tabList.a('.tab', a => {
|
|
@@ -195,7 +206,7 @@ export class TabContainerPart extends TerrierPart<TabContainerState> {
|
|
|
195
206
|
})
|
|
196
207
|
|
|
197
208
|
if (currentTabKey) {
|
|
198
|
-
const currentTab = this.tabs
|
|
209
|
+
const currentTab = this.tabs.get(currentTabKey)!
|
|
199
210
|
container.div('.tt-tab-content', panel => {
|
|
200
211
|
if (currentTab.classes?.length) panel.class(...currentTab.classes)
|
|
201
212
|
panel.part(currentTab.part as StatelessPart)
|