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.
@@ -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.queryOrder.map(id => queries.get(id)!) }
182
+ query_data: { queries: this.queryTabs.getTabOrder().map(id => queries.get(id)!) }
192
183
  }
193
184
  }
194
185
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "files": [
5
5
  "*"
6
6
  ],
7
- "version": "4.52.3",
7
+ "version": "4.52.5",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/Terrier-Tech/terrier-engine"
@@ -1,4 +1,4 @@
1
- // This file was automatically generated on 2024-10-30 08:24:15 -0500, DO NOT EDIT IT MANUALLY!
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: string
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 = {} as Record<string, TabDefinition>
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.typedKey<{ newOrder: string[] }>()
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: 'tt-tab-list',
63
+ zoneClass: `tablist-${this.id}`,
63
64
  targetClass: 'tab',
64
- onSorted: (_, evt) => {
65
- this.onTabsModified(evt.toChildren)
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(tabElementsMaybe?: HTMLElement[]) {
72
- const tabElements = tabElementsMaybe ??
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[tab.key] ?? {}
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
- existingTab.part = part
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[tab.key]
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[key]
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
- delete this.tabs[key]
130
+ this.tabs.delete(key)
131
+ this.tabOrder.splice(this.tabOrder.indexOf(key), 1)
121
132
  this.removeChild(tab.part)
122
- this.onTabsModified()
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 (!(tabKey in this.tabs)) {
143
+ if (!this.tabs.has(tabKey)) {
133
144
  throw `Unknown tab key ${tabKey}`
134
145
  }
135
- if (this.tabs[tabKey].state != 'enabled') return // tab exists but is not enabled
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 || Object.keys(this.tabs)[0]
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 = Object.values(this.tabs).find(t => t.state == 'enabled')?.key
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 tab of Object.values(this.tabs)) {
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[currentTabKey]
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)