@things-factory/figure-ui 10.1.178 → 10.1.179
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/figure-released.ts +6 -0
- package/client/graphql/index.ts +101 -25
- package/client/graphql/store.ts +2 -1
- package/client/index.ts +1 -0
- package/client/modeller/editor.ts +10 -2
- package/client/modeller/figure-first-save.ts +23 -3
- package/client/modeller/figure-parts.ts +53 -23
- package/client/modeller/figure-properties.ts +41 -7
- package/client/modeller/first-save.ts +2 -0
- package/client/modeller/product-session.ts +5 -3
- package/client/modeller/property-sections.ts +45 -0
- package/client/pages/figure-list-page.ts +52 -10
- package/client/pages/figure-modeller-page.ts +15 -3
- package/client/setting-let/figure-namespace-setting-let.ts +113 -31
- package/client/types.ts +8 -0
- package/client/viewparts/figure-detail-dock.ts +124 -9
- package/client/viewparts/figure-thumb.ts +6 -3
- package/dist-client/figure-released.d.ts +3 -0
- package/dist-client/figure-released.js +5 -0
- package/dist-client/figure-released.js.map +1 -0
- package/dist-client/graphql/index.d.ts +25 -13
- package/dist-client/graphql/index.js +85 -16
- package/dist-client/graphql/index.js.map +1 -1
- package/dist-client/graphql/store.js +2 -1
- package/dist-client/graphql/store.js.map +1 -1
- package/dist-client/index.d.ts +1 -0
- package/dist-client/index.js +1 -0
- package/dist-client/index.js.map +1 -1
- package/dist-client/modeller/editor.d.ts +2 -0
- package/dist-client/modeller/editor.js +13 -2
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/figure-first-save.d.ts +8 -0
- package/dist-client/modeller/figure-first-save.js +28 -3
- package/dist-client/modeller/figure-first-save.js.map +1 -1
- package/dist-client/modeller/figure-parts.d.ts +5 -0
- package/dist-client/modeller/figure-parts.js +54 -22
- package/dist-client/modeller/figure-parts.js.map +1 -1
- package/dist-client/modeller/figure-properties.d.ts +4 -0
- package/dist-client/modeller/figure-properties.js +45 -7
- package/dist-client/modeller/figure-properties.js.map +1 -1
- package/dist-client/modeller/first-save.d.ts +2 -0
- package/dist-client/modeller/first-save.js.map +1 -1
- package/dist-client/modeller/product-session.d.ts +4 -1
- package/dist-client/modeller/product-session.js +3 -3
- package/dist-client/modeller/product-session.js.map +1 -1
- package/dist-client/modeller/property-sections.d.ts +26 -0
- package/dist-client/modeller/property-sections.js +17 -0
- package/dist-client/modeller/property-sections.js.map +1 -0
- package/dist-client/pages/figure-list-page.d.ts +4 -1
- package/dist-client/pages/figure-list-page.js +56 -10
- package/dist-client/pages/figure-list-page.js.map +1 -1
- package/dist-client/pages/figure-modeller-page.d.ts +2 -0
- package/dist-client/pages/figure-modeller-page.js +19 -3
- package/dist-client/pages/figure-modeller-page.js.map +1 -1
- package/dist-client/setting-let/figure-namespace-setting-let.d.ts +16 -5
- package/dist-client/setting-let/figure-namespace-setting-let.js +129 -31
- package/dist-client/setting-let/figure-namespace-setting-let.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/types.d.ts +12 -0
- package/dist-client/types.js.map +1 -1
- package/dist-client/viewparts/figure-detail-dock.d.ts +33 -2
- package/dist-client/viewparts/figure-detail-dock.js +171 -11
- package/dist-client/viewparts/figure-detail-dock.js.map +1 -1
- package/dist-client/viewparts/figure-thumb.d.ts +2 -0
- package/dist-client/viewparts/figure-thumb.js +13 -3
- package/dist-client/viewparts/figure-thumb.js.map +1 -1
- package/package.json +8 -7
- package/test/browser/category-page.js +28 -0
- package/test/browser/category.check.mjs +54 -0
- package/test/browser/mesh-select.check.mjs +1 -1
- package/test/browser/namespace-page.js +75 -0
- package/test/browser/namespace.check.mjs +104 -0
- package/test/browser/parts-page.js +8 -2
- package/test/browser/places-mesh.check.mjs +30 -2
- package/test/browser/property-section-page.js +45 -0
- package/test/browser/property-section.check.mjs +48 -0
- package/test/browser/props.check.mjs +13 -2
- package/test/browser/public-page.js +39 -0
- package/test/browser/public.check.mjs +79 -0
- package/test/browser/retire-page.js +37 -0
- package/test/browser/retire.check.mjs +96 -0
- package/test/figure-released.test.ts +54 -0
- package/test/modeller-route.test.ts +2 -1
- package/translations/en.json +20 -5
- package/translations/es.json +20 -5
- package/translations/ja.json +20 -5
- package/translations/ko.json +20 -5
- package/translations/ms.json +20 -5
- package/translations/zh.json +20 -5
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public figures in the catalogue's detail dock (LV figure-server design G2): the domain's own released figure is made
|
|
3
|
+
* public and private again, the server's refusal said; another domain's public figure is shown by its release and its
|
|
4
|
+
* domain, with nothing to change on it -- no edit, no retire, no public switch, no keeping a card picture.
|
|
5
|
+
*
|
|
6
|
+
* Run: node --test test/browser/public.check.mjs
|
|
7
|
+
*/
|
|
8
|
+
import { test, describe, before, after } from 'node:test'
|
|
9
|
+
import assert from 'node:assert/strict'
|
|
10
|
+
|
|
11
|
+
import { buildPage } from './build.mjs'
|
|
12
|
+
import { openPage } from './serve.mjs'
|
|
13
|
+
|
|
14
|
+
const sleep = ms => new Promise(done => setTimeout(done, ms))
|
|
15
|
+
|
|
16
|
+
let opened
|
|
17
|
+
before(async () => {
|
|
18
|
+
opened = await openPage(await buildPage('public-page.js'), { width: 1500, height: 900 })
|
|
19
|
+
})
|
|
20
|
+
after(async () => {
|
|
21
|
+
await opened?.close()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const page = () => opened.page
|
|
25
|
+
const inDock = (fn, ...args) =>
|
|
26
|
+
page().evaluate((source, a) => (0, eval)(`(${source})`)(document.querySelector('figure-detail-dock').shadowRoot, ...a), String(fn), args)
|
|
27
|
+
async function until(fn, what, ms = 15000) {
|
|
28
|
+
const deadline = Date.now() + ms
|
|
29
|
+
for (;;) {
|
|
30
|
+
if (await inDock(fn).catch(() => false)) return
|
|
31
|
+
if (Date.now() > deadline) assert.fail(`waited for ${what}`)
|
|
32
|
+
await sleep(50)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const shown = async run => {
|
|
36
|
+
await page().evaluate(run)
|
|
37
|
+
await until(root => !!root.querySelector('[meta]') && !root.querySelector('[status][role="status"]'), 'the figure')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe('public, from the detail dock', () => {
|
|
41
|
+
test('a draft offers no public switch', async () => {
|
|
42
|
+
await shown(() => harness.show('draft'))
|
|
43
|
+
assert.equal(await inDock(root => !!root.querySelector('[publish]')), false)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('the own released figure is made public and private again, one call each, the catalogue told', async () => {
|
|
47
|
+
await shown(() => harness.show('shipped'))
|
|
48
|
+
assert.equal(await inDock(root => !!root.querySelector('[publish] [published]')), false)
|
|
49
|
+
await inDock(root => root.querySelector('[publish] button').click())
|
|
50
|
+
await until(root => !!root.querySelector('[publish] [published]'), 'public')
|
|
51
|
+
await inDock(root => root.querySelector('[publish] button').click())
|
|
52
|
+
await until(root => !root.querySelector('[publish] [published]'), 'private again')
|
|
53
|
+
assert.deepEqual(await page().evaluate(() => harness.calls), [{ id: 'shipped', public: true }, { id: 'shipped', public: false }])
|
|
54
|
+
assert.deepEqual(await page().evaluate(() => harness.changed), ['shipped', 'shipped'])
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('a refusal is said under the switch', async () => {
|
|
58
|
+
await page().evaluate(() => harness.refuseWith('mixer has no release yet: only released figures are made public.'))
|
|
59
|
+
await inDock(root => root.querySelector('[publish] button').click())
|
|
60
|
+
await until(root => !!root.querySelector('[retire-error]'), 'the refusal')
|
|
61
|
+
assert.match(await inDock(root => root.querySelector('[retire-error]').textContent), /only released figures/)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test("another domain's public figure: its release and its domain, nothing to change", async () => {
|
|
65
|
+
await shown(() => harness.showTheirs())
|
|
66
|
+
assert.deepEqual(
|
|
67
|
+
await inDock(root => ({
|
|
68
|
+
edit: !!root.querySelector('button[edit]'),
|
|
69
|
+
retire: !!root.querySelector('[retire]'),
|
|
70
|
+
publish: !!root.querySelector('[publish]'),
|
|
71
|
+
owner: root.querySelector('[source] [owner]')?.textContent,
|
|
72
|
+
sourceButtons: root.querySelectorAll('[source] button').length
|
|
73
|
+
})),
|
|
74
|
+
{ edit: false, retire: false, publish: false, owner: 'Other works', sourceButtons: 0 }
|
|
75
|
+
)
|
|
76
|
+
await until(root => !!root.querySelector('figure-asset-viewer'), 'the release drawn')
|
|
77
|
+
assert.equal(await inDock(root => root.querySelector('figure-asset-viewer').keepShot), undefined)
|
|
78
|
+
})
|
|
79
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The catalogue's detail dock with a released figure that can be retired and brought back, and a draft that cannot.
|
|
3
|
+
* Fixtures are in memory; the server's retire is a stand-in that keeps the last call and can refuse.
|
|
4
|
+
*/
|
|
5
|
+
import 'figure-ui-client/viewparts/figure-detail-dock.js'
|
|
6
|
+
import { addFigureBox, createFigureAsset, serializeFigureAsset } from '@hatiolab/figure-model'
|
|
7
|
+
|
|
8
|
+
const source = serializeFigureAsset(addFigureBox(createFigureAsset('Mixer'), { id: 'body', size: { x: 100, y: 100, z: 100 }, position: { x: 0, y: 50, z: 0 } }))
|
|
9
|
+
const figures = {
|
|
10
|
+
shipped: { id: 'shipped', name: 'Mixer', type: 'mixer', namespace: 'system', state: 'released', version: 2, deprecated: false, supersededBy: null, source },
|
|
11
|
+
draft: { id: 'draft', name: 'Sketch', type: 'sketch', namespace: 'system', state: 'draft', version: 0, deprecated: false, supersededBy: null, source }
|
|
12
|
+
}
|
|
13
|
+
const calls = []
|
|
14
|
+
const changed = []
|
|
15
|
+
let refuse = ''
|
|
16
|
+
|
|
17
|
+
const dock = document.createElement('figure-detail-dock')
|
|
18
|
+
dock.load = async id => ({ saved: { ...figures[id] } })
|
|
19
|
+
dock.keepThumbnail = async () => {}
|
|
20
|
+
dock.typeNamesOf = async () => ['mixer', 'mixer-v2', 'sketch']
|
|
21
|
+
dock.retire = async (id, deprecated, supersededBy) => {
|
|
22
|
+
calls.push({ id, deprecated, supersededBy })
|
|
23
|
+
if (refuse) throw new Error(refuse)
|
|
24
|
+
figures[id] = { ...figures[id], deprecated, supersededBy: deprecated ? supersededBy : null }
|
|
25
|
+
const { source: _s, ...row } = figures[id]
|
|
26
|
+
return row
|
|
27
|
+
}
|
|
28
|
+
window.addEventListener('figure-retirement-changed', e => changed.push(e.detail.id))
|
|
29
|
+
document.body.append(dock)
|
|
30
|
+
|
|
31
|
+
window.harness = {
|
|
32
|
+
dock,
|
|
33
|
+
show: id => dock.show(id),
|
|
34
|
+
calls,
|
|
35
|
+
changed,
|
|
36
|
+
refuseWith: message => (refuse = message)
|
|
37
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Retiring a released figure from the catalogue's detail dock (LV figure-server design G12): a released figure offers
|
|
3
|
+
* retire, takes the type to use instead, says it is retired and can be brought back; a draft offers nothing, since it is
|
|
4
|
+
* deleted instead. The server's answer -- a refusal included -- is said in the dock.
|
|
5
|
+
*
|
|
6
|
+
* Run: node --test test/browser/retire.check.mjs
|
|
7
|
+
*/
|
|
8
|
+
import { test, describe, before, after } from 'node:test'
|
|
9
|
+
import assert from 'node:assert/strict'
|
|
10
|
+
|
|
11
|
+
import { buildPage } from './build.mjs'
|
|
12
|
+
import { openPage } from './serve.mjs'
|
|
13
|
+
|
|
14
|
+
const sleep = ms => new Promise(done => setTimeout(done, ms))
|
|
15
|
+
|
|
16
|
+
let opened
|
|
17
|
+
before(async () => {
|
|
18
|
+
opened = await openPage(await buildPage('retire-page.js'), { width: 1500, height: 900 })
|
|
19
|
+
})
|
|
20
|
+
after(async () => {
|
|
21
|
+
await opened?.close()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const page = () => opened.page
|
|
25
|
+
const inDock = (fn, ...args) =>
|
|
26
|
+
page().evaluate((source, a) => (0, eval)(`(${source})`)(document.querySelector('figure-detail-dock').shadowRoot, ...a), String(fn), args)
|
|
27
|
+
async function until(fn, what, ms = 15000) {
|
|
28
|
+
const deadline = Date.now() + ms
|
|
29
|
+
for (;;) {
|
|
30
|
+
if (await inDock(fn).catch(() => false)) return
|
|
31
|
+
if (Date.now() > deadline) assert.fail(`waited for ${what}`)
|
|
32
|
+
await sleep(50)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function show(id) {
|
|
36
|
+
await page().evaluate(i => harness.show(i), id)
|
|
37
|
+
await until(root => !!root.querySelector('[meta]') && !root.querySelector('[status][role="status"]'), `the ${id} figure`)
|
|
38
|
+
}
|
|
39
|
+
async function press(selector) {
|
|
40
|
+
const at = await inDock((root, s) => {
|
|
41
|
+
const r = root.querySelector(s).getBoundingClientRect()
|
|
42
|
+
return { x: r.x + r.width / 2, y: r.y + r.height / 2 }
|
|
43
|
+
}, selector)
|
|
44
|
+
await page().mouse.click(at.x, at.y)
|
|
45
|
+
}
|
|
46
|
+
const retireButtons = () => inDock(root => [...root.querySelectorAll('[retire] button')].map(b => (b.hasAttribute('primary') ? 'primary' : 'quiet')))
|
|
47
|
+
|
|
48
|
+
describe('retiring from the detail dock', () => {
|
|
49
|
+
test('a draft offers no retire: it is deleted instead', async () => {
|
|
50
|
+
await show('draft')
|
|
51
|
+
assert.equal(await inDock(root => !!root.querySelector('[retire]')), false)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('a released figure offers retire; cancel leaves it as it was', async () => {
|
|
55
|
+
await show('shipped')
|
|
56
|
+
assert.deepEqual(await retireButtons(), ['quiet'])
|
|
57
|
+
await press('[retire] button')
|
|
58
|
+
await until(root => !!root.querySelector('[retire] input'), 'the type to use instead')
|
|
59
|
+
assert.deepEqual(await inDock(root => [...root.querySelectorAll('datalist option')].map(o => o.value)), ['mixer-v2', 'sketch'])
|
|
60
|
+
await press('[retire] button:not([primary])')
|
|
61
|
+
await until(root => !root.querySelector('[retire] input'), 'the form closed')
|
|
62
|
+
assert.equal(await page().evaluate(() => harness.calls.length), 0)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('retire with a type to use instead: one call, the dock says it is retired, the catalogue is told', async () => {
|
|
66
|
+
await press('[retire] button')
|
|
67
|
+
await until(root => !!root.querySelector('[retire] input'), 'the type to use instead')
|
|
68
|
+
await press('[retire] input')
|
|
69
|
+
await page().keyboard.type('mixer-v2')
|
|
70
|
+
await press('[retire] button[primary]')
|
|
71
|
+
await until(root => !!root.querySelector('[retire] [retired]'), 'retired')
|
|
72
|
+
assert.deepEqual(await page().evaluate(() => harness.calls), [{ id: 'shipped', deprecated: true, supersededBy: 'mixer-v2' }])
|
|
73
|
+
assert.deepEqual(await page().evaluate(() => harness.changed), ['shipped'])
|
|
74
|
+
/* The page has no translations, so the words are keys; what the dock now holds is the figure the server returned. */
|
|
75
|
+
assert.equal(await page().evaluate(() => document.querySelector('figure-detail-dock').record.saved.supersededBy), 'mixer-v2')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('bring back: one call with no type, retire is offered again', async () => {
|
|
79
|
+
await press('[retire] button')
|
|
80
|
+
await until(root => !root.querySelector('[retire] [retired]'), 'brought back')
|
|
81
|
+
assert.deepEqual((await page().evaluate(() => harness.calls)).at(-1), { id: 'shipped', deprecated: false, supersededBy: null })
|
|
82
|
+
assert.deepEqual(await retireButtons(), ['quiet'])
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('a refusal is said in the dock and the form stays open', async () => {
|
|
86
|
+
await page().evaluate(() => harness.refuseWith('대신 쓸 Figure \'nowhere\' 가 이 도메인에 없다'))
|
|
87
|
+
await press('[retire] button')
|
|
88
|
+
await until(root => !!root.querySelector('[retire] input'), 'the type to use instead')
|
|
89
|
+
await press('[retire] input')
|
|
90
|
+
await page().keyboard.type('nowhere')
|
|
91
|
+
await press('[retire] button[primary]')
|
|
92
|
+
await until(root => !!root.querySelector('[retire-error]'), 'the refusal')
|
|
93
|
+
assert.match(await inDock(root => root.querySelector('[retire-error]').textContent), /nowhere/)
|
|
94
|
+
assert.equal(await inDock(root => !!root.querySelector('[retire] input')), true)
|
|
95
|
+
})
|
|
96
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* A figure once released is retired, never deleted (LV figure-server design G4): the catalog offers no delete for it and
|
|
3
|
+
* says why when the table's delete is pressed; the server refuses it too (figure-service `figure-released-not-deletable`).
|
|
4
|
+
*/
|
|
5
|
+
import { test } from 'node:test'
|
|
6
|
+
import assert from 'node:assert/strict'
|
|
7
|
+
import { readFileSync } from 'node:fs'
|
|
8
|
+
import { fileURLToPath } from 'node:url'
|
|
9
|
+
|
|
10
|
+
import { hasBeenReleased } from '../client/figure-released.js'
|
|
11
|
+
|
|
12
|
+
const read = (path: string) => readFileSync(fileURLToPath(new URL(path, import.meta.url)), 'utf8')
|
|
13
|
+
|
|
14
|
+
test('a figure with a release number has been released, whatever its draft state', () => {
|
|
15
|
+
assert.equal(hasBeenReleased({ version: 0 }), false)
|
|
16
|
+
assert.equal(hasBeenReleased({ version: undefined }), false)
|
|
17
|
+
assert.equal(hasBeenReleased({ version: 1 }), true)
|
|
18
|
+
assert.equal(hasBeenReleased({ version: 7 }), true)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('the catalog card draws its delete button only for a figure never released', () => {
|
|
22
|
+
const thumb = read('../client/viewparts/figure-thumb.ts')
|
|
23
|
+
const guard = thumb.indexOf('hasBeenReleased(figure) ?')
|
|
24
|
+
const button = thumb.indexOf('<button\n remove')
|
|
25
|
+
assert.ok(guard >= 0 && button > guard, 'the remove button sits behind hasBeenReleased')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('the notice is said in every language, and the confirmation no longer speaks of drawings losing it', () => {
|
|
29
|
+
for (const lang of ['en', 'ko', 'ja', 'zh', 'ms', 'es']) {
|
|
30
|
+
const words = JSON.parse(read(`../translations/${lang}.json`))
|
|
31
|
+
assert.match(words['figure.text.released-figure-not-deletable'], /\{name\}/, lang)
|
|
32
|
+
assert.doesNotMatch(words['figure.text.delete-figure-confirm'], /drawing|도면|planos/, lang)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('a retired figure says so on its card, and the retire words are in every language', () => {
|
|
37
|
+
const thumb = read('../client/viewparts/figure-thumb.ts')
|
|
38
|
+
assert.match(thumb, /figure\.deprecated \? i18next\.t\('figure\.label\.retired'\)/)
|
|
39
|
+
for (const lang of ['en', 'ko', 'ja', 'zh', 'ms', 'es']) {
|
|
40
|
+
const words = JSON.parse(read(`../translations/${lang}.json`))
|
|
41
|
+
for (const key of ['figure.label.retired', 'figure.button.retire', 'figure.button.unretire', 'figure.label.superseded-by']) assert.ok(words[key], `${lang} ${key}`)
|
|
42
|
+
assert.match(words['figure.text.retired-instead'], /\{type\}/, lang)
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test("another domain's public figure: its card offers no delete and names its domain", () => {
|
|
47
|
+
const thumb = read('../client/viewparts/figure-thumb.ts')
|
|
48
|
+
assert.match(thumb, /this\.readonly \|\| hasBeenReleased\(figure\) \? '' :/)
|
|
49
|
+
assert.match(thumb, /badge=\$\{this\.readonly \? figure\.domain\?\.name/)
|
|
50
|
+
for (const lang of ['en', 'ko', 'ja', 'zh', 'ms', 'es']) {
|
|
51
|
+
const words = JSON.parse(read(`../translations/${lang}.json`))
|
|
52
|
+
for (const key of ['figure.label.public', 'figure.button.make-public', 'figure.button.make-private', 'figure.button.public-figures']) assert.ok(words[key], `${lang} ${key}`)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
@@ -26,7 +26,8 @@ test('one modeller page at one address: the route and the shell table agree', ()
|
|
|
26
26
|
test('the catalogue opens details first; editing is an explicit action in the detail dock', () => {
|
|
27
27
|
/* The catalogue page (its grid and the shell) is not driven here; the dock's edit button is, in product-page.check.mjs. */
|
|
28
28
|
const list = read('../client/pages/figure-list-page.ts')
|
|
29
|
-
|
|
29
|
+
/* Another domain's public figure opens the same way, shown by its release alone (G2). */
|
|
30
|
+
assert.match(list, /openFigureDetail\(record, this\.scope === 'public'\)/)
|
|
30
31
|
})
|
|
31
32
|
|
|
32
33
|
/* Reloading with unsaved work, and the rail on an opened figure, are checked on the page: test/browser/product-page.check.mjs. */
|
package/translations/en.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"figure.text.collapse-parts-pane": "collapse the part list",
|
|
400
400
|
"figure.text.collapse-properties-pane": "collapse the property pane",
|
|
401
401
|
"figure.text.coordinate-ground-explained": "draws the origin and a grid on the floor",
|
|
402
|
-
"figure.text.delete-figure-confirm": "delete {name}?
|
|
402
|
+
"figure.text.delete-figure-confirm": "delete {name}?",
|
|
403
403
|
"figure.text.designate-in-properties": "nothing designated yet. select a part and set its role in the properties tab.",
|
|
404
404
|
"figure.text.detail-level-explained": "S for signs and posts, M for most equipment, L for the large equipment a view centres on, XL for a mechanism of many joints such as a legged robot. the level sets the part limit.",
|
|
405
405
|
"figure.text.discard-changes-and-start-new": "there are unsaved changes. discard them and start a new figure?",
|
|
@@ -1193,13 +1193,28 @@
|
|
|
1193
1193
|
"figure.label.tab-short-data": "Data",
|
|
1194
1194
|
"figure.title.namespace-setting": "Figure namespace",
|
|
1195
1195
|
"figure.label.namespace": "Namespace",
|
|
1196
|
-
"figure.text.namespace-fixed": "Figures have been made under this namespace, so it cannot change.",
|
|
1197
|
-
"figure.text.namespace-empty-takes-subdomain": "Left empty, the subdomain {subdomain} is used. It cannot change once a figure is made.",
|
|
1198
|
-
"figure.text.namespace-subdomain-unusable": "The subdomain {subdomain} cannot be a namespace. Enter one, for example hatiolab.com.",
|
|
1199
1196
|
"figure.label.follows-part-axis": "{part}'s {axis}",
|
|
1200
1197
|
"figure.text.size-and-space-declared-to-follow": "the figure size was set from its parts, {x} × {y} × {z} mm, and the space it takes was fitted to them.",
|
|
1201
1198
|
"figure.button.release-blocked": "{count} blocks release",
|
|
1202
1199
|
"figure.label.preview-way-one": "one",
|
|
1203
1200
|
"figure.label.preview-way-eight": "eight sizes",
|
|
1204
|
-
"figure.text.preview-needs-space": "set the space it takes to try other sizes."
|
|
1201
|
+
"figure.text.preview-needs-space": "set the space it takes to try other sizes.",
|
|
1202
|
+
"figure.text.released-figure-not-deletable": "{name} has been released and cannot be deleted. retire it in its details.",
|
|
1203
|
+
"figure.label.retired": "retired",
|
|
1204
|
+
"figure.button.retire": "retire",
|
|
1205
|
+
"figure.button.unretire": "bring back",
|
|
1206
|
+
"figure.label.superseded-by": "figure to use instead",
|
|
1207
|
+
"figure.text.retired-instead": "retired · use {type} instead",
|
|
1208
|
+
"figure.label.namespace-default": "default",
|
|
1209
|
+
"figure.label.namespace-suspended": "suspended",
|
|
1210
|
+
"figure.button.namespace-make-default": "make default",
|
|
1211
|
+
"figure.button.namespace-suspend": "suspend",
|
|
1212
|
+
"figure.button.namespace-activate": "use again",
|
|
1213
|
+
"figure.button.namespace-add": "add",
|
|
1214
|
+
"figure.label.public": "public",
|
|
1215
|
+
"figure.button.make-public": "make public",
|
|
1216
|
+
"figure.button.make-private": "make private",
|
|
1217
|
+
"figure.button.public-figures": "public figures of other domains",
|
|
1218
|
+
"figure.text.category-choose": "choose a category",
|
|
1219
|
+
"figure.text.property-section-failed": "the section {section} could not be drawn: {reason}"
|
|
1205
1220
|
}
|
package/translations/es.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"figure.text.collapse-parts-pane": "contraer la lista de piezas",
|
|
400
400
|
"figure.text.collapse-properties-pane": "contraer el panel de propiedades",
|
|
401
401
|
"figure.text.coordinate-ground-explained": "dibuja el origen y una cuadrícula en el suelo",
|
|
402
|
-
"figure.text.delete-figure-confirm": "¿eliminar {name}?
|
|
402
|
+
"figure.text.delete-figure-confirm": "¿eliminar {name}?",
|
|
403
403
|
"figure.text.designate-in-properties": "aún no hay nada designado. seleccione una pieza y defina su función en la pestaña de propiedades.",
|
|
404
404
|
"figure.text.detail-level-explained": "S para señales y postes, M para la mayoría de los equipos, L para el equipo grande en el que se centra una vista, XL para un mecanismo con muchas articulaciones, como un robot con patas. el nivel define el límite de piezas.",
|
|
405
405
|
"figure.text.discard-changes-and-start-new": "hay cambios sin guardar. ¿descartarlos y empezar una nueva figura?",
|
|
@@ -1193,13 +1193,28 @@
|
|
|
1193
1193
|
"figure.label.tab-short-data": "Datos",
|
|
1194
1194
|
"figure.title.namespace-setting": "Namespace de Figure",
|
|
1195
1195
|
"figure.label.namespace": "Namespace",
|
|
1196
|
-
"figure.text.namespace-fixed": "Ya hay figuras creadas con este namespace, por lo que no puede cambiar.",
|
|
1197
|
-
"figure.text.namespace-empty-takes-subdomain": "Si se deja vacío, se usa el subdominio {subdomain}. No puede cambiar una vez creada una figura.",
|
|
1198
|
-
"figure.text.namespace-subdomain-unusable": "El subdominio {subdomain} no puede ser un namespace. Escriba uno, por ejemplo hatiolab.com.",
|
|
1199
1196
|
"figure.label.follows-part-axis": "{axis} de {part}",
|
|
1200
1197
|
"figure.text.size-and-space-declared-to-follow": "el tamaño de la figura se fijó a partir de sus piezas, {x} × {y} × {z} mm, y el espacio que ocupa se ajustó a ellas.",
|
|
1201
1198
|
"figure.button.release-blocked": "{count} impide publicar",
|
|
1202
1199
|
"figure.label.preview-way-one": "una",
|
|
1203
1200
|
"figure.label.preview-way-eight": "ocho tamaños",
|
|
1204
|
-
"figure.text.preview-needs-space": "defina el espacio que ocupa para probar otros tamaños."
|
|
1201
|
+
"figure.text.preview-needs-space": "defina el espacio que ocupa para probar otros tamaños.",
|
|
1202
|
+
"figure.text.released-figure-not-deletable": "{name} ya se publicó y no se puede eliminar. retírela en sus detalles.",
|
|
1203
|
+
"figure.label.retired": "retirada",
|
|
1204
|
+
"figure.button.retire": "retirar",
|
|
1205
|
+
"figure.button.unretire": "recuperar",
|
|
1206
|
+
"figure.label.superseded-by": "figura que la sustituye",
|
|
1207
|
+
"figure.text.retired-instead": "retirada · use {type}",
|
|
1208
|
+
"figure.label.namespace-default": "predeterminado",
|
|
1209
|
+
"figure.label.namespace-suspended": "suspendido",
|
|
1210
|
+
"figure.button.namespace-make-default": "hacer predeterminado",
|
|
1211
|
+
"figure.button.namespace-suspend": "suspender",
|
|
1212
|
+
"figure.button.namespace-activate": "volver a usar",
|
|
1213
|
+
"figure.button.namespace-add": "agregar",
|
|
1214
|
+
"figure.label.public": "pública",
|
|
1215
|
+
"figure.button.make-public": "hacer pública",
|
|
1216
|
+
"figure.button.make-private": "dejar de publicar",
|
|
1217
|
+
"figure.button.public-figures": "figuras públicas de otros dominios",
|
|
1218
|
+
"figure.text.category-choose": "elegir categoría",
|
|
1219
|
+
"figure.text.property-section-failed": "no se pudo dibujar la sección {section}: {reason}"
|
|
1205
1220
|
}
|
package/translations/ja.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"figure.text.collapse-parts-pane": "collapse the part list",
|
|
400
400
|
"figure.text.collapse-properties-pane": "collapse the property pane",
|
|
401
401
|
"figure.text.coordinate-ground-explained": "原点と目盛りを床に表示します",
|
|
402
|
-
"figure.text.delete-figure-confirm": "
|
|
402
|
+
"figure.text.delete-figure-confirm": "{name} を削除しますか?",
|
|
403
403
|
"figure.text.designate-in-properties": "まだ指定された部品がありません。部品を選び、プロパティタブで「能力での役割」を指定してください。",
|
|
404
404
|
"figure.text.detail-level-explained": "S は標識・柱、M はほとんどの設備、L は画面の中心となる大きな設備、XL は脚のあるロボットのように関節の多い装置に使います。等級で部品数の上限が決まります。",
|
|
405
405
|
"figure.text.discard-changes-and-start-new": "保存していない変更があります。破棄して新しく始めますか?",
|
|
@@ -1193,13 +1193,28 @@
|
|
|
1193
1193
|
"figure.label.tab-short-data": "データ",
|
|
1194
1194
|
"figure.title.namespace-setting": "Figure 名前空間",
|
|
1195
1195
|
"figure.label.namespace": "名前空間",
|
|
1196
|
-
"figure.text.namespace-fixed": "この名前空間で Figure を作成済みのため変更できません。",
|
|
1197
|
-
"figure.text.namespace-empty-takes-subdomain": "空欄ならサブドメイン {subdomain} を使います。Figure を作成すると変更できません。",
|
|
1198
|
-
"figure.text.namespace-subdomain-unusable": "サブドメイン {subdomain} は名前空間に使えません。例: hatiolab.com",
|
|
1199
1196
|
"figure.label.follows-part-axis": "{part} の {axis}",
|
|
1200
1197
|
"figure.text.size-and-space-declared-to-follow": "図形サイズを部品から {x} × {y} × {z} mm にし、占有空間も部品に合わせました。",
|
|
1201
1198
|
"figure.button.release-blocked": "発行不可 {count}",
|
|
1202
1199
|
"figure.label.preview-way-one": "1 台",
|
|
1203
1200
|
"figure.label.preview-way-eight": "8 サイズ",
|
|
1204
|
-
"figure.text.preview-needs-space": "占有空間を決めるとサイズを変えて試せます。"
|
|
1201
|
+
"figure.text.preview-needs-space": "占有空間を決めるとサイズを変えて試せます。",
|
|
1202
|
+
"figure.text.released-figure-not-deletable": "{name} は発行済みの Figure のため削除できません。詳細で退役にしてください。",
|
|
1203
|
+
"figure.label.retired": "退役",
|
|
1204
|
+
"figure.button.retire": "退役",
|
|
1205
|
+
"figure.button.unretire": "戻す",
|
|
1206
|
+
"figure.label.superseded-by": "代わりに使う Figure",
|
|
1207
|
+
"figure.text.retired-instead": "退役 · 代わりに {type}",
|
|
1208
|
+
"figure.label.namespace-default": "既定",
|
|
1209
|
+
"figure.label.namespace-suspended": "停止中",
|
|
1210
|
+
"figure.button.namespace-make-default": "既定にする",
|
|
1211
|
+
"figure.button.namespace-suspend": "停止",
|
|
1212
|
+
"figure.button.namespace-activate": "再開",
|
|
1213
|
+
"figure.button.namespace-add": "追加",
|
|
1214
|
+
"figure.label.public": "公開",
|
|
1215
|
+
"figure.button.make-public": "公開する",
|
|
1216
|
+
"figure.button.make-private": "公開をやめる",
|
|
1217
|
+
"figure.button.public-figures": "他ドメインの公開 Figure",
|
|
1218
|
+
"figure.text.category-choose": "分類を選ぶ",
|
|
1219
|
+
"figure.text.property-section-failed": "{section} の区画を描けませんでした: {reason}"
|
|
1205
1220
|
}
|
package/translations/ko.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"figure.text.collapse-parts-pane": "부품 목록 접기",
|
|
400
400
|
"figure.text.collapse-properties-pane": "속성 패널 접기",
|
|
401
401
|
"figure.text.coordinate-ground-explained": "원점과 눈금을 바닥에 표시합니다",
|
|
402
|
-
"figure.text.delete-figure-confirm": "{name} 을 삭제하시겠습니까?
|
|
402
|
+
"figure.text.delete-figure-confirm": "{name} 을 삭제하시겠습니까?",
|
|
403
403
|
"figure.text.designate-in-properties": "아직 지정된 부품이 없습니다. 부품을 선택하고 속성 탭에서 「능력에서의 역할」을 지정하세요.",
|
|
404
404
|
"figure.text.detail-level-explained": "S 는 표지·기둥, M 은 대부분의 설비, L 은 화면의 중심이 되는 큰 설비, XL 은 다리 달린 로봇처럼 관절이 많은 장치에 사용합니다. 등급에 따라 부품 수 한도가 정해집니다.",
|
|
405
405
|
"figure.text.discard-changes-and-start-new": "저장하지 않은 변경이 있습니다. 버리고 새로 시작할까요?",
|
|
@@ -1193,13 +1193,28 @@
|
|
|
1193
1193
|
"figure.label.tab-short-data": "데이터",
|
|
1194
1194
|
"figure.title.namespace-setting": "Figure 이름공간",
|
|
1195
1195
|
"figure.label.namespace": "이름공간",
|
|
1196
|
-
"figure.text.namespace-fixed": "이 이름공간으로 Figure를 만들어서 바꿀 수 없습니다.",
|
|
1197
|
-
"figure.text.namespace-empty-takes-subdomain": "입력하지 않으면 서브도메인 {subdomain} 값을 사용합니다. Figure를 생성한 후에는 변경할 수 없습니다.",
|
|
1198
|
-
"figure.text.namespace-subdomain-unusable": "서브도메인 {subdomain} 값은 이름공간으로 사용할 수 없습니다. 예: hatiolab.com",
|
|
1199
1196
|
"figure.label.follows-part-axis": "{part}의 {axis}",
|
|
1200
1197
|
"figure.text.size-and-space-declared-to-follow": "도형 크기를 부품에 맞춰 {x} × {y} × {z} mm 로 정하고, 차지하는 공간도 부품에 맞췄습니다.",
|
|
1201
1198
|
"figure.button.release-blocked": "발행 막힘 {count}",
|
|
1202
1199
|
"figure.label.preview-way-one": "한 대",
|
|
1203
1200
|
"figure.label.preview-way-eight": "여덟 크기",
|
|
1204
|
-
"figure.text.preview-needs-space": "차지하는 공간을 정하면 크기를 바꿔 볼 수 있습니다."
|
|
1201
|
+
"figure.text.preview-needs-space": "차지하는 공간을 정하면 크기를 바꿔 볼 수 있습니다.",
|
|
1202
|
+
"figure.text.released-figure-not-deletable": "{name} 은 발행한 Figure 라 지울 수 없습니다. 상세에서 퇴역으로 표시하세요.",
|
|
1203
|
+
"figure.label.retired": "퇴역",
|
|
1204
|
+
"figure.button.retire": "퇴역",
|
|
1205
|
+
"figure.button.unretire": "되살리기",
|
|
1206
|
+
"figure.label.superseded-by": "대신 쓸 Figure",
|
|
1207
|
+
"figure.text.retired-instead": "퇴역 · 대신 {type}",
|
|
1208
|
+
"figure.label.namespace-default": "기본",
|
|
1209
|
+
"figure.label.namespace-suspended": "쉬는 중",
|
|
1210
|
+
"figure.button.namespace-make-default": "기본으로",
|
|
1211
|
+
"figure.button.namespace-suspend": "쉬게 하기",
|
|
1212
|
+
"figure.button.namespace-activate": "다시 쓰기",
|
|
1213
|
+
"figure.button.namespace-add": "추가",
|
|
1214
|
+
"figure.label.public": "공개",
|
|
1215
|
+
"figure.button.make-public": "공개하기",
|
|
1216
|
+
"figure.button.make-private": "공개 끄기",
|
|
1217
|
+
"figure.button.public-figures": "다른 도메인의 공개 Figure",
|
|
1218
|
+
"figure.text.category-choose": "분류 고르기",
|
|
1219
|
+
"figure.text.property-section-failed": "{section} 구역을 그리지 못했습니다: {reason}"
|
|
1205
1220
|
}
|
package/translations/ms.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"figure.text.collapse-parts-pane": "collapse the part list",
|
|
400
400
|
"figure.text.collapse-properties-pane": "collapse the property pane",
|
|
401
401
|
"figure.text.coordinate-ground-explained": "melukis asalan dan grid pada lantai",
|
|
402
|
-
"figure.text.delete-figure-confirm": "
|
|
402
|
+
"figure.text.delete-figure-confirm": "padam {name}?",
|
|
403
403
|
"figure.text.designate-in-properties": "belum ada yang ditetapkan. pilih bahagian dan tetapkan peranannya dalam tab sifat.",
|
|
404
404
|
"figure.text.detail-level-explained": "S untuk papan tanda dan tiang, M untuk kebanyakan peralatan, L untuk peralatan besar yang menjadi tumpuan, XL untuk mekanisme banyak sendi seperti robot berkaki. tahap menentukan had bahagian.",
|
|
405
405
|
"figure.text.discard-changes-and-start-new": "ada perubahan belum disimpan. buang dan mulakan yang baharu?",
|
|
@@ -1193,13 +1193,28 @@
|
|
|
1193
1193
|
"figure.label.tab-short-data": "Data",
|
|
1194
1194
|
"figure.title.namespace-setting": "Namespace Figure",
|
|
1195
1195
|
"figure.label.namespace": "Namespace",
|
|
1196
|
-
"figure.text.namespace-fixed": "Figure telah dibuat di bawah namespace ini, jadi ia tidak boleh diubah.",
|
|
1197
|
-
"figure.text.namespace-empty-takes-subdomain": "Jika dibiarkan kosong, subdomain {subdomain} digunakan. Ia tidak boleh diubah selepas figure dibuat.",
|
|
1198
|
-
"figure.text.namespace-subdomain-unusable": "Subdomain {subdomain} tidak boleh menjadi namespace. Masukkan satu, contohnya hatiolab.com.",
|
|
1199
1196
|
"figure.label.follows-part-axis": "{axis} {part}",
|
|
1200
1197
|
"figure.text.size-and-space-declared-to-follow": "saiz rajah ditetapkan daripada bahagiannya, {x} × {y} × {z} mm, dan ruang yang diambil dipadankan dengannya.",
|
|
1201
1198
|
"figure.button.release-blocked": "{count} menghalang terbitan",
|
|
1202
1199
|
"figure.label.preview-way-one": "satu",
|
|
1203
1200
|
"figure.label.preview-way-eight": "lapan saiz",
|
|
1204
|
-
"figure.text.preview-needs-space": "tetapkan ruang yang diambil untuk mencuba saiz lain."
|
|
1201
|
+
"figure.text.preview-needs-space": "tetapkan ruang yang diambil untuk mencuba saiz lain.",
|
|
1202
|
+
"figure.text.released-figure-not-deletable": "{name} telah diterbitkan dan tidak boleh dipadam. bersarakan dalam butirannya.",
|
|
1203
|
+
"figure.label.retired": "bersara",
|
|
1204
|
+
"figure.button.retire": "bersarakan",
|
|
1205
|
+
"figure.button.unretire": "kembalikan",
|
|
1206
|
+
"figure.label.superseded-by": "figure pengganti",
|
|
1207
|
+
"figure.text.retired-instead": "bersara · guna {type}",
|
|
1208
|
+
"figure.label.namespace-default": "lalai",
|
|
1209
|
+
"figure.label.namespace-suspended": "digantung",
|
|
1210
|
+
"figure.button.namespace-make-default": "jadikan lalai",
|
|
1211
|
+
"figure.button.namespace-suspend": "gantung",
|
|
1212
|
+
"figure.button.namespace-activate": "guna semula",
|
|
1213
|
+
"figure.button.namespace-add": "tambah",
|
|
1214
|
+
"figure.label.public": "awam",
|
|
1215
|
+
"figure.button.make-public": "jadikan awam",
|
|
1216
|
+
"figure.button.make-private": "jadikan peribadi",
|
|
1217
|
+
"figure.button.public-figures": "figure awam domain lain",
|
|
1218
|
+
"figure.text.category-choose": "pilih kategori",
|
|
1219
|
+
"figure.text.property-section-failed": "bahagian {section} tidak dapat dilukis: {reason}"
|
|
1205
1220
|
}
|
package/translations/zh.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"figure.text.collapse-parts-pane": "collapse the part list",
|
|
400
400
|
"figure.text.collapse-properties-pane": "collapse the property pane",
|
|
401
401
|
"figure.text.coordinate-ground-explained": "在地面显示原点和网格",
|
|
402
|
-
"figure.text.delete-figure-confirm": "
|
|
402
|
+
"figure.text.delete-figure-confirm": "删除 {name}?",
|
|
403
403
|
"figure.text.designate-in-properties": "还没有指定部件。请选择部件,在属性标签页中设置「在能力中的角色」。",
|
|
404
404
|
"figure.text.detail-level-explained": "S 用于标志和立柱,M 用于大多数设备,L 用于作为画面中心的大型设备,XL 用于腿式机器人等关节众多的装置。等级决定部件数量上限。",
|
|
405
405
|
"figure.text.discard-changes-and-start-new": "有未保存的更改。放弃并新建吗?",
|
|
@@ -1193,13 +1193,28 @@
|
|
|
1193
1193
|
"figure.label.tab-short-data": "数据",
|
|
1194
1194
|
"figure.title.namespace-setting": "Figure 命名空间",
|
|
1195
1195
|
"figure.label.namespace": "命名空间",
|
|
1196
|
-
"figure.text.namespace-fixed": "已用此命名空间创建 Figure,无法更改。",
|
|
1197
|
-
"figure.text.namespace-empty-takes-subdomain": "留空则使用子域名 {subdomain}。创建 Figure 后无法更改。",
|
|
1198
|
-
"figure.text.namespace-subdomain-unusable": "子域名 {subdomain} 不能用作命名空间。例如 hatiolab.com",
|
|
1199
1196
|
"figure.label.follows-part-axis": "{part} 的 {axis}",
|
|
1200
1197
|
"figure.text.size-and-space-declared-to-follow": "已按部件将图形尺寸设为 {x} × {y} × {z} mm,并按部件确定了占用空间。",
|
|
1201
1198
|
"figure.button.release-blocked": "无法发布 {count}",
|
|
1202
1199
|
"figure.label.preview-way-one": "单台",
|
|
1203
1200
|
"figure.label.preview-way-eight": "八种尺寸",
|
|
1204
|
-
"figure.text.preview-needs-space": "确定占用空间后即可尝试其他尺寸。"
|
|
1201
|
+
"figure.text.preview-needs-space": "确定占用空间后即可尝试其他尺寸。",
|
|
1202
|
+
"figure.text.released-figure-not-deletable": "{name} 已发布,无法删除。请在详情中将其退役。",
|
|
1203
|
+
"figure.label.retired": "已退役",
|
|
1204
|
+
"figure.button.retire": "退役",
|
|
1205
|
+
"figure.button.unretire": "恢复",
|
|
1206
|
+
"figure.label.superseded-by": "替代使用的 Figure",
|
|
1207
|
+
"figure.text.retired-instead": "已退役 · 改用 {type}",
|
|
1208
|
+
"figure.label.namespace-default": "默认",
|
|
1209
|
+
"figure.label.namespace-suspended": "已暂停",
|
|
1210
|
+
"figure.button.namespace-make-default": "设为默认",
|
|
1211
|
+
"figure.button.namespace-suspend": "暂停",
|
|
1212
|
+
"figure.button.namespace-activate": "恢复使用",
|
|
1213
|
+
"figure.button.namespace-add": "添加",
|
|
1214
|
+
"figure.label.public": "公开",
|
|
1215
|
+
"figure.button.make-public": "公开",
|
|
1216
|
+
"figure.button.make-private": "取消公开",
|
|
1217
|
+
"figure.button.public-figures": "其他域的公开图形",
|
|
1218
|
+
"figure.text.category-choose": "选择分类",
|
|
1219
|
+
"figure.text.property-section-failed": "无法绘制 {section} 区块:{reason}"
|
|
1205
1220
|
}
|