@things-factory/figure-ui 10.1.161 → 10.1.162
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/client/modeller/data-interface.ts +17 -0
- package/client/modeller/figure-preview.ts +51 -15
- package/dist-client/modeller/data-interface.d.ts +9 -0
- package/dist-client/modeller/data-interface.js +18 -0
- package/dist-client/modeller/data-interface.js.map +1 -1
- package/dist-client/modeller/figure-preview.d.ts +5 -0
- package/dist-client/modeller/figure-preview.js +51 -13
- package/dist-client/modeller/figure-preview.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/test/browser/product-page.check.mjs +1 -1
- package/test/browser/screen.check.mjs +7 -7
- package/test/data-motion.test.ts +16 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/figure-ui",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.162",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"@things-factory:registry": "https://registry.npmjs.org"
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"@things-factory/setting-base": "^10.1.159",
|
|
48
48
|
"three": "^0.185.1"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "7be9e6436b89213940c684c0cdc60343e8148e73"
|
|
51
51
|
}
|
|
@@ -698,7 +698,7 @@ describe('the catalogue preview', () => {
|
|
|
698
698
|
product.forget()
|
|
699
699
|
product.openDetail('a')
|
|
700
700
|
})
|
|
701
|
-
await press('figure-detail-dock >>>
|
|
701
|
+
await press('figure-detail-dock >>> button[edit]', 'edit')
|
|
702
702
|
await until(() => product.navigations().length, 'the modeller opened')
|
|
703
703
|
assert.deepEqual(await read(() => product.navigations().map(({ path, detailShown }) => ({ path, detailShown }))), [{ path: '/figure-modeller/a', detailShown: false }])
|
|
704
704
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* The modeller's screen in a real browser: its frame (three panes, the side's
|
|
2
|
+
* The modeller's screen in a real browser: its frame (three panes, the side's seven tabs, the bar over the work), a new
|
|
3
3
|
* figure's first minute, the side panel as parts are chosen, the view tab, the preview, the verdict tab and the card's
|
|
4
4
|
* picture -- each read as a person meets it, after doing what a person does (a click, a key, a narrower window).
|
|
5
5
|
*
|
|
@@ -150,7 +150,7 @@ describe('the verdict tab over a figure, as the modeller page mounts it', () =>
|
|
|
150
150
|
})
|
|
151
151
|
})
|
|
152
152
|
|
|
153
|
-
describe('the frame: parts · canvas · one side of
|
|
153
|
+
describe('the frame: parts · canvas · one side of seven tabs, and the bar over the work', () => {
|
|
154
154
|
before(() => mount('box'))
|
|
155
155
|
|
|
156
156
|
test('three panes: the parts list on the left, the canvas in the middle, the side on the right -- one side, nothing under the canvas', async () => {
|
|
@@ -185,13 +185,13 @@ describe('the frame: parts · canvas · one side of six tabs, and the bar over t
|
|
|
185
185
|
assert.equal(await read(() => getComputedStyle(screenCheck.editor()).containerType), 'inline-size')
|
|
186
186
|
})
|
|
187
187
|
|
|
188
|
-
test('the side\'s
|
|
188
|
+
test('the side\'s seven tabs, in order, each saying its name under its icon -- the name it is read by', async () => {
|
|
189
189
|
const tabs = await read(() =>
|
|
190
190
|
[...screenCheck.editor().shadowRoot.querySelectorAll('aside button[tab]')].map(b => ({ label: b.getAttribute('aria-label'), shows: b.querySelector('span[tab-label]')?.textContent.trim() }))
|
|
191
191
|
)
|
|
192
192
|
assert.deepEqual(
|
|
193
193
|
tabs.map(t => t.label),
|
|
194
|
-
['properties', 'capability', 'motion', 'verdict', 'view', 'history'].map(TAB)
|
|
194
|
+
['properties', 'capability', 'motion', 'data', 'verdict', 'view', 'history'].map(TAB)
|
|
195
195
|
)
|
|
196
196
|
for (const tab of tabs) assert.equal(tab.shows, tab.label, `${tab.label} shows its name`)
|
|
197
197
|
assert.equal(await read(() => screenCheck.editor().shadowRoot.querySelector('aside').firstElementChild.matches('div[tabs]')), true, 'the tabs are the side\'s first row')
|
|
@@ -200,15 +200,15 @@ describe('the frame: parts · canvas · one side of six tabs, and the bar over t
|
|
|
200
200
|
test('a tab shows its panel and hides the others without taking them down -- the verdict keeps what it holds', async () => {
|
|
201
201
|
const panels = () =>
|
|
202
202
|
read(() => [...screenCheck.editor().shadowRoot.querySelectorAll('aside > div[panel]')].map(p => ({ seen: p.getBoundingClientRect().height > 0, connected: p.isConnected, verdict: !!p.querySelector('slot[name=verdict]') })))
|
|
203
|
-
const tabs = ['properties', 'capability', 'motion', 'verdict', 'view', 'history']
|
|
203
|
+
const tabs = ['properties', 'capability', 'motion', 'data', 'verdict', 'view', 'history']
|
|
204
204
|
for (const [at, tab] of tabs.entries()) {
|
|
205
205
|
await pressTab(TAB(tab))
|
|
206
206
|
await until(`${tab} on`, name => screenCheck.editor().shadowRoot.querySelector('button[tab][on]')?.getAttribute('aria-label') === name, TAB(tab))
|
|
207
207
|
const now = await panels()
|
|
208
|
-
assert.equal(now.length,
|
|
208
|
+
assert.equal(now.length, 7, 'seven panels, all standing')
|
|
209
209
|
assert.deepEqual(now.map(p => p.seen), tabs.map((_, i) => i === at), `${tab}: its panel seen, the rest hidden`)
|
|
210
210
|
assert.ok(now.every(p => p.connected))
|
|
211
|
-
assert.ok(now[
|
|
211
|
+
assert.ok(now[tabs.indexOf('verdict')].verdict, 'the verdict panel holds the verdict slot whichever tab is on')
|
|
212
212
|
}
|
|
213
213
|
await pressTab(TAB('properties'))
|
|
214
214
|
})
|
package/test/data-motion.test.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { editFigurePart, quadrupedRobotFigure, robotDogFigure } from '@hatiolab/
|
|
|
13
13
|
import type { FigureAsset, FigureDataProperty } from '@hatiolab/figure-model'
|
|
14
14
|
|
|
15
15
|
import { clipGroupsOf, freeGroupIdOf, groupEdit, undrivenOf } from '../client/modeller/clips.ts'
|
|
16
|
-
import { connectionDraftOf, dataSampleOf, dataTargetsOf, freeDataIdOf, propertyDraftOf, sampleValueOf } from '../client/modeller/data-interface.ts'
|
|
16
|
+
import { connectionDraftOf, dataSampleOf, dataTargetsOf, freeDataIdOf, motionWrittenByData, propertyDraftOf, sampleValueOf } from '../client/modeller/data-interface.ts'
|
|
17
17
|
import { editRefusalOf } from '../client/modeller/refusals.ts'
|
|
18
18
|
|
|
19
19
|
const read = (path: string) => readFileSync(fileURLToPath(new URL(path, import.meta.url)), 'utf8')
|
|
@@ -105,6 +105,21 @@ test('데이터 · 동작 거절은 커널 문장이 아니라 reason 과 값으
|
|
|
105
105
|
assert.match(refusalOf(() => editFigurePart(lone, { kind: 'set-driver', state: 'fl-knee', clip: 'run', duration: 1, keys: [{ seconds: 0, value: 0 }, { seconds: 1, value: 10 }] })), /^figure\.text\.driver-writers /)
|
|
106
106
|
})
|
|
107
107
|
|
|
108
|
+
test('미리보기: 데이터가 정하는 그룹 필드는 그룹 칸이 아니라 데이터 값으로 움직인다 (2026-10-14, 로봇 개)', () => {
|
|
109
|
+
/* The dog's clip and speed are both written by data (mode, cadence): a clip chosen on the group moved nothing. */
|
|
110
|
+
assert.deepEqual(motionWrittenByData(DOG), { locomotion: { clip: true, speed: true } })
|
|
111
|
+
/* Only the speed connected: the clip stays the group's to choose. */
|
|
112
|
+
const speedOnly = { ...DOG, dataInterface: { ...DOG.dataInterface!, connections: DOG.dataInterface!.connections.filter(c => c.target.kind !== 'motion-clip') } }
|
|
113
|
+
assert.deepEqual(motionWrittenByData(speedOnly), { locomotion: { clip: false, speed: true } })
|
|
114
|
+
/* No data interface: every group field is the group's own. */
|
|
115
|
+
const { dataInterface: _gone, ...bare } = DOG
|
|
116
|
+
assert.deepEqual(motionWrittenByData(bare as FigureAsset), {})
|
|
117
|
+
const preview = read('../client/modeller/figure-preview.ts')
|
|
118
|
+
assert.match(preview, /tellInstances\('figureValues', this\.valuing\)/)
|
|
119
|
+
assert.match(preview, /byData\.clip\s*\? nothing/)
|
|
120
|
+
assert.match(preview, /byData\.speed\s*\? nothing/)
|
|
121
|
+
})
|
|
122
|
+
|
|
108
123
|
test('데이터 탭 · 클립 패널 · 미리보기의 배선과 문구', () => {
|
|
109
124
|
const editor = read('../client/modeller/editor.ts')
|
|
110
125
|
assert.match(editor, /renderTab\('data'/)
|