feat(app): add variable type creation menu
This commit is contained in:
parent
3bd01095eb
commit
68d15440b1
|
|
@ -173,6 +173,7 @@ export const panelMessages = i18n('panels', {
|
|||
exportPreview: 'Preview',
|
||||
exportRenderingPreview: 'Rendering preview…',
|
||||
create: 'Create',
|
||||
add: 'Add',
|
||||
createVariable: 'Create variable',
|
||||
createColorVariable: params('Create color variable from {value}'),
|
||||
createNumberVariable: params('Create number variable from {value}'),
|
||||
|
|
@ -233,6 +234,17 @@ export const panelMessages = i18n('panels', {
|
|||
sizingFixedPx: 'Fixed (px)'
|
||||
})
|
||||
|
||||
export const variableTypeMessages = i18n('variableTypes', {
|
||||
color: 'Color',
|
||||
colorHint: 'Paint values',
|
||||
number: 'Number',
|
||||
numberHint: 'Sizes, spacing, opacity',
|
||||
text: 'Text',
|
||||
textHint: 'Copy and labels',
|
||||
boolean: 'Boolean',
|
||||
booleanHint: 'True or false'
|
||||
})
|
||||
|
||||
export const pageMessages = i18n('pages', {
|
||||
newPage: 'New page',
|
||||
rename: 'Rename',
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
commandMessages,
|
||||
toolMessages,
|
||||
panelMessages,
|
||||
variableTypeMessages,
|
||||
pageMessages,
|
||||
dialogMessages
|
||||
} from '#vue/i18n/messages'
|
||||
|
|
@ -36,6 +37,7 @@ export function useI18n() {
|
|||
commands: useStore(commandMessages),
|
||||
tools: useStore(toolMessages),
|
||||
panels: useStore(panelMessages),
|
||||
variableTypes: useStore(variableTypeMessages),
|
||||
pages: useStore(pageMessages),
|
||||
dialogs: useStore(dialogMessages),
|
||||
locale: useStore(locale) as Ref<Locale>,
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "Variablenname",
|
||||
"create": "Erstellen",
|
||||
"createNumberVariable": "Zahlenvariable aus {value} erstellen",
|
||||
"strokeDash": "Gestrichelter Strich"
|
||||
"strokeDash": "Gestrichelter Strich",
|
||||
"add": "Hinzufügen"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "Neue Seite",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} wurde installiert{size}. Neustart jetzt.",
|
||||
"updateCheckFailed": "Updates konnten nicht geprüft werden: {error}",
|
||||
"updateUnavailable": "Updates sind noch nicht verfügbar. Veröffentliche zuerst ein signiertes Release mit latest.json."
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "Farbe",
|
||||
"colorHint": "Farbwerte",
|
||||
"number": "Zahl",
|
||||
"numberHint": "Größen, Abstände, Deckkraft",
|
||||
"text": "Text",
|
||||
"textHint": "Text und Beschriftungen",
|
||||
"boolean": "Boolean",
|
||||
"booleanHint": "Wahr oder falsch"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "Nombre de variable",
|
||||
"create": "Crear",
|
||||
"createNumberVariable": "Crear variable numérica desde {value}",
|
||||
"strokeDash": "Trazo discontinuo"
|
||||
"strokeDash": "Trazo discontinuo",
|
||||
"add": "Añadir"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "Nueva página",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} se instaló{size}. Reiniciando ahora.",
|
||||
"updateCheckFailed": "No se pudo buscar actualizaciones: {error}",
|
||||
"updateUnavailable": "Las actualizaciones aún no están disponibles. Publica primero una versión firmada con latest.json."
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "Color",
|
||||
"colorHint": "Valores de pintura",
|
||||
"number": "Número",
|
||||
"numberHint": "Tamaños, espaciado, opacidad",
|
||||
"text": "Texto",
|
||||
"textHint": "Texto y etiquetas",
|
||||
"boolean": "Booleano",
|
||||
"booleanHint": "Verdadero o falso"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "Nom de la variable",
|
||||
"create": "Créer",
|
||||
"createNumberVariable": "Créer une variable numérique depuis {value}",
|
||||
"strokeDash": "Trait en pointillés"
|
||||
"strokeDash": "Trait en pointillés",
|
||||
"add": "Ajouter"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "Nouvelle page",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} a été installé{size}. Redémarrage maintenant.",
|
||||
"updateCheckFailed": "Impossible de rechercher des mises à jour : {error}",
|
||||
"updateUnavailable": "Les mises à jour ne sont pas encore disponibles. Publiez d’abord une version signée avec latest.json."
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "Couleur",
|
||||
"colorHint": "Valeurs de peinture",
|
||||
"number": "Nombre",
|
||||
"numberHint": "Tailles, espacements, opacité",
|
||||
"text": "Texte",
|
||||
"textHint": "Texte et libellés",
|
||||
"boolean": "Booléen",
|
||||
"booleanHint": "Vrai ou faux"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "Nome variabile",
|
||||
"create": "Crea",
|
||||
"createNumberVariable": "Crea variabile numerica da {value}",
|
||||
"strokeDash": "Tratto tratteggiato"
|
||||
"strokeDash": "Tratto tratteggiato",
|
||||
"add": "Aggiungi"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "Nuova pagina",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} è stato installato{size}. Riavvio in corso.",
|
||||
"updateCheckFailed": "Impossibile controllare gli aggiornamenti: {error}",
|
||||
"updateUnavailable": "Gli aggiornamenti non sono ancora disponibili. Pubblica prima una release firmata con latest.json."
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "Colore",
|
||||
"colorHint": "Valori colore",
|
||||
"number": "Numero",
|
||||
"numberHint": "Dimensioni, spaziatura, opacità",
|
||||
"text": "Testo",
|
||||
"textHint": "Testi ed etichette",
|
||||
"boolean": "Booleano",
|
||||
"booleanHint": "Vero o falso"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "Nazwa zmiennej",
|
||||
"create": "Utwórz",
|
||||
"createNumberVariable": "Utwórz zmienną liczbową z {value}",
|
||||
"strokeDash": "Obrys przerywany"
|
||||
"strokeDash": "Obrys przerywany",
|
||||
"add": "Dodaj"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "Nowa strona",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} został zainstalowany{size}. Ponowne uruchamianie.",
|
||||
"updateCheckFailed": "Nie udało się sprawdzić aktualizacji: {error}",
|
||||
"updateUnavailable": "Aktualizacje nie są jeszcze dostępne. Najpierw opublikuj podpisane wydanie z latest.json."
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "Kolor",
|
||||
"colorHint": "Wartości wypełnień",
|
||||
"number": "Liczba",
|
||||
"numberHint": "Rozmiary, odstępy, krycie",
|
||||
"text": "Tekst",
|
||||
"textHint": "Tekst i etykiety",
|
||||
"boolean": "Boolowski",
|
||||
"booleanHint": "Prawda lub fałsz"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "Имя переменной",
|
||||
"create": "Создать",
|
||||
"createNumberVariable": "Создать числовую переменную из {value}",
|
||||
"strokeDash": "Пунктирная обводка"
|
||||
"strokeDash": "Пунктирная обводка",
|
||||
"add": "Добавить"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "Новая страница",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} установлен{size}. Перезапуск.",
|
||||
"updateCheckFailed": "Не удалось проверить обновления: {error}",
|
||||
"updateUnavailable": "Обновления пока недоступны. Сначала опубликуйте подписанный релиз с latest.json."
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "Цвет",
|
||||
"colorHint": "Значения заливок",
|
||||
"number": "Число",
|
||||
"numberHint": "Размеры, отступы, прозрачность",
|
||||
"text": "Текст",
|
||||
"textHint": "Текст и подписи",
|
||||
"boolean": "Логический",
|
||||
"booleanHint": "Истина или ложь"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,8 @@
|
|||
"variableName": "变量名称",
|
||||
"create": "创建",
|
||||
"createNumberVariable": "从 {value} 创建数字变量",
|
||||
"strokeDash": "虚线描边"
|
||||
"strokeDash": "虚线描边",
|
||||
"add": "添加"
|
||||
},
|
||||
"pages": {
|
||||
"newPage": "新建页面",
|
||||
|
|
@ -225,5 +226,15 @@
|
|||
"updateInstalled": "OpenPencil {version} 已安装{size}。正在重启。",
|
||||
"updateCheckFailed": "无法检查更新:{error}",
|
||||
"updateUnavailable": "更新尚不可用。请先发布带有 latest.json 的已签名版本。"
|
||||
},
|
||||
"variableTypes": {
|
||||
"color": "颜色",
|
||||
"colorHint": "绘制值",
|
||||
"number": "数字",
|
||||
"numberHint": "尺寸、间距、不透明度",
|
||||
"text": "文本",
|
||||
"textHint": "文案和标签",
|
||||
"boolean": "布尔值",
|
||||
"booleanHint": "真或假"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@ import { colorToHexRaw, parseColor } from '@open-pencil/core/color'
|
|||
import { randomHex } from '@open-pencil/core/random'
|
||||
|
||||
import type { Editor } from '@open-pencil/core/editor'
|
||||
import type { Variable, VariableCollection, VariableValue } from '@open-pencil/core/scene-graph'
|
||||
import type {
|
||||
Variable,
|
||||
VariableCollection,
|
||||
VariableType,
|
||||
VariableValue
|
||||
} from '@open-pencil/core/scene-graph'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
export function createVariableCollectionActions(editor: Editor, activeCollectionId: Ref<string>) {
|
||||
|
|
@ -34,20 +39,34 @@ export function createVariableValueActions(
|
|||
editor: Editor,
|
||||
getActiveCollection: () => VariableCollection | null
|
||||
) {
|
||||
function addVariable() {
|
||||
function defaultVariableValue(type: VariableType): VariableValue {
|
||||
if (type === 'COLOR') return { r: 0, g: 0, b: 0, a: 1 }
|
||||
if (type === 'FLOAT') return 0
|
||||
if (type === 'BOOLEAN') return false
|
||||
return ''
|
||||
}
|
||||
|
||||
function defaultVariableName(type: VariableType): string {
|
||||
if (type === 'COLOR') return 'New color'
|
||||
if (type === 'FLOAT') return 'New number'
|
||||
if (type === 'BOOLEAN') return 'New boolean'
|
||||
return 'New text'
|
||||
}
|
||||
|
||||
function addVariable(type: VariableType = 'COLOR') {
|
||||
const col = getActiveCollection()
|
||||
if (!col) return
|
||||
|
||||
const id = `var:${randomHex(8)}`
|
||||
const valuesByMode: Record<string, VariableValue> = {}
|
||||
for (const mode of col.modes) {
|
||||
valuesByMode[mode.modeId] = { r: 0, g: 0, b: 0, a: 1 }
|
||||
valuesByMode[mode.modeId] = defaultVariableValue(type)
|
||||
}
|
||||
|
||||
editor.addVariable({
|
||||
id,
|
||||
name: 'New variable',
|
||||
type: 'COLOR',
|
||||
name: defaultVariableName(type),
|
||||
type,
|
||||
collectionId: col.id,
|
||||
valuesByMode,
|
||||
description: '',
|
||||
|
|
@ -83,7 +102,7 @@ export function createVariableValueActions(
|
|||
const num = parseFloat(raw)
|
||||
return isNaN(num) ? undefined : num
|
||||
}
|
||||
if (variable.type === 'BOOLEAN') return raw === 'true'
|
||||
if (variable.type === 'BOOLEAN') return raw.toLowerCase() === 'true'
|
||||
return raw
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ import {
|
|||
DialogPortal,
|
||||
DialogRoot,
|
||||
DialogTitle,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuRoot,
|
||||
DropdownMenuTrigger,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsRoot,
|
||||
|
|
@ -25,18 +30,49 @@ import IconX from '~icons/lucide/x'
|
|||
import ColorInput from '@/components/ColorPicker/ColorInput.vue'
|
||||
import Tip from './ui/Tip.vue'
|
||||
import { useDialogUI } from '@/components/ui/dialog'
|
||||
import { useMenuUI } from '@/components/ui/menu'
|
||||
|
||||
import type { VariableType } from '@open-pencil/core/scene-graph'
|
||||
|
||||
const open = defineModel<boolean>('open', { default: false })
|
||||
const cls = useDialogUI({ content: 'flex h-[75vh] w-[800px] max-w-[90vw] flex-col' })
|
||||
const menuCls = useMenuUI({ content: 'w-44' })
|
||||
|
||||
const variableTypeIcons: Record<string, Component> = {
|
||||
const variableTypeIcons: Record<VariableType, Component> = {
|
||||
COLOR: IconPalette,
|
||||
FLOAT: IconHash,
|
||||
STRING: IconType,
|
||||
BOOLEAN: IconToggleLeft
|
||||
}
|
||||
|
||||
const { dialogs, panels } = useI18n()
|
||||
const { dialogs, panels, variableTypes: variableTypeText } = useI18n()
|
||||
|
||||
const variableTypes: Array<{
|
||||
type: VariableType
|
||||
label: () => string
|
||||
description: () => string
|
||||
}> = [
|
||||
{
|
||||
type: 'COLOR',
|
||||
label: () => variableTypeText.value.color,
|
||||
description: () => variableTypeText.value.colorHint
|
||||
},
|
||||
{
|
||||
type: 'FLOAT',
|
||||
label: () => variableTypeText.value.number,
|
||||
description: () => variableTypeText.value.numberHint
|
||||
},
|
||||
{
|
||||
type: 'STRING',
|
||||
label: () => variableTypeText.value.text,
|
||||
description: () => variableTypeText.value.textHint
|
||||
},
|
||||
{
|
||||
type: 'BOOLEAN',
|
||||
label: () => variableTypeText.value.boolean,
|
||||
description: () => variableTypeText.value.booleanHint
|
||||
}
|
||||
]
|
||||
|
||||
const ctx = useVariablesEditor({
|
||||
colorInput: ColorInput,
|
||||
|
|
@ -203,14 +239,38 @@ watch(collectionInput, (input) => {
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<button
|
||||
data-test-id="variables-add-variable"
|
||||
class="flex w-full shrink-0 cursor-pointer items-center gap-1.5 border-t border-border bg-transparent px-4 py-2 text-xs text-muted hover:bg-hover hover:text-surface"
|
||||
@click="ctx.addVariable"
|
||||
>
|
||||
<icon-lucide-plus class="size-3.5" />
|
||||
{{ panels.createVariable }}
|
||||
</button>
|
||||
<div class="flex w-full shrink-0 items-center justify-between gap-2 border-t border-border px-4 py-2">
|
||||
<span class="text-xs text-muted">{{ panels.createVariable }}</span>
|
||||
<DropdownMenuRoot>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<button
|
||||
data-test-id="variables-add-variable"
|
||||
class="flex cursor-pointer items-center gap-1.5 rounded bg-hover px-2.5 py-1.5 text-xs text-surface hover:bg-border"
|
||||
>
|
||||
<icon-lucide-plus class="size-3.5" />
|
||||
{{ panels.add }}
|
||||
<icon-lucide-chevron-down class="size-3" />
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent side="top" :side-offset="8" align="end" :class="menuCls.content">
|
||||
<DropdownMenuItem
|
||||
v-for="item in variableTypes"
|
||||
:key="item.type"
|
||||
:class="menuCls.item"
|
||||
:data-test-id="`variables-add-${item.type.toLowerCase()}`"
|
||||
@select="ctx.addVariable(item.type)"
|
||||
>
|
||||
<component :is="variableTypeIcons[item.type]" :class="menuCls.icon" />
|
||||
<span class="flex min-w-0 flex-1 flex-col">
|
||||
<span>{{ item.label() }}</span>
|
||||
<span class="truncate text-[10px] text-muted">{{ item.description() }}</span>
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuRoot>
|
||||
</div>
|
||||
</TabsContent>
|
||||
</TabsRoot>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,24 @@ test('search filters variable rows', async () => {
|
|||
canvas.assertNoErrors()
|
||||
})
|
||||
|
||||
test('add variable menu creates non-color variable types', async () => {
|
||||
await page.locator('[data-test-id="variables-search-input"]').fill('')
|
||||
await canvas.waitForRender()
|
||||
|
||||
await page.locator('[data-test-id="variables-add-variable"]').click()
|
||||
await page.locator('[data-test-id="variables-add-float"]').click()
|
||||
await expect(page.locator('[data-test-id="variable-row"]').filter({ hasText: 'New number' })).toHaveCount(1)
|
||||
|
||||
await page.locator('[data-test-id="variables-add-variable"]').click()
|
||||
await page.locator('[data-test-id="variables-add-string"]').click()
|
||||
await expect(page.locator('[data-test-id="variable-row"]').filter({ hasText: 'New text' })).toHaveCount(1)
|
||||
|
||||
await page.locator('[data-test-id="variables-add-variable"]').click()
|
||||
await page.locator('[data-test-id="variables-add-boolean"]').click()
|
||||
await expect(page.locator('[data-test-id="variable-row"]').filter({ hasText: 'New boolean' })).toHaveCount(1)
|
||||
canvas.assertNoErrors()
|
||||
})
|
||||
|
||||
test('click name cell activates editable input', async () => {
|
||||
await page.locator('[data-test-id="variables-search-input"]').fill('')
|
||||
await canvas.waitForRender()
|
||||
|
|
|
|||
115
tests/engine/variables-editor.test.ts
Normal file
115
tests/engine/variables-editor.test.ts
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { createVariableCollectionActions, createVariableValueActions } from '#vue/variables/helpers'
|
||||
|
||||
import type { Editor } from '@open-pencil/core/editor'
|
||||
import type { Variable, VariableCollection } from '@open-pencil/core/scene-graph'
|
||||
|
||||
function createEditorHarness() {
|
||||
const collections = new Map<string, VariableCollection>()
|
||||
const variables = new Map<string, Variable>()
|
||||
const collection: VariableCollection = {
|
||||
id: 'col:test',
|
||||
name: 'Test',
|
||||
modes: [
|
||||
{ modeId: 'default', name: 'Default' },
|
||||
{ modeId: 'dark', name: 'Dark' }
|
||||
],
|
||||
defaultModeId: 'default',
|
||||
variableIds: []
|
||||
}
|
||||
collections.set(collection.id, collection)
|
||||
const editor = {
|
||||
addCollection(item: VariableCollection) {
|
||||
collections.set(item.id, item)
|
||||
},
|
||||
renameCollection(id: string, name: string) {
|
||||
const item = collections.get(id)
|
||||
if (item) item.name = name
|
||||
},
|
||||
addVariable(item: Variable) {
|
||||
variables.set(item.id, item)
|
||||
collections.get(item.collectionId)?.variableIds.push(item.id)
|
||||
},
|
||||
removeVariable(id: string) {
|
||||
variables.delete(id)
|
||||
},
|
||||
renameVariable(id: string, name: string) {
|
||||
const item = variables.get(id)
|
||||
if (item) item.name = name
|
||||
},
|
||||
updateVariableValue(id: string, modeId: string, value: unknown) {
|
||||
const item = variables.get(id)
|
||||
if (item) item.valuesByMode[modeId] = value as never
|
||||
},
|
||||
getVariable(id: string) {
|
||||
return variables.get(id)
|
||||
}
|
||||
} as unknown as Editor
|
||||
|
||||
return { editor, collection, collections, variables }
|
||||
}
|
||||
|
||||
describe('variables editor helpers', () => {
|
||||
test('creates variables with type-specific default values for every mode', () => {
|
||||
const { editor, collection, variables } = createEditorHarness()
|
||||
const actions = createVariableValueActions(editor, () => collection)
|
||||
|
||||
actions.addVariable('COLOR')
|
||||
actions.addVariable('FLOAT')
|
||||
actions.addVariable('STRING')
|
||||
actions.addVariable('BOOLEAN')
|
||||
|
||||
const created = [...variables.values()]
|
||||
expect(created.map((item) => item.type)).toEqual(['COLOR', 'FLOAT', 'STRING', 'BOOLEAN'])
|
||||
expect(created.map((item) => item.name)).toEqual([
|
||||
'New color',
|
||||
'New number',
|
||||
'New text',
|
||||
'New boolean'
|
||||
])
|
||||
expect(created.map((item) => item.valuesByMode.default)).toEqual([
|
||||
{ r: 0, g: 0, b: 0, a: 1 },
|
||||
0,
|
||||
'',
|
||||
false
|
||||
])
|
||||
expect(created.map((item) => item.valuesByMode.dark)).toEqual([
|
||||
{ r: 0, g: 0, b: 0, a: 1 },
|
||||
0,
|
||||
'',
|
||||
false
|
||||
])
|
||||
})
|
||||
|
||||
test('parses edited values by variable type', () => {
|
||||
const { editor, collection } = createEditorHarness()
|
||||
const actions = createVariableValueActions(editor, () => collection)
|
||||
const variable = {
|
||||
id: 'var:bool',
|
||||
name: 'Flag',
|
||||
type: 'BOOLEAN',
|
||||
collectionId: collection.id,
|
||||
valuesByMode: { default: false },
|
||||
description: '',
|
||||
hiddenFromPublishing: false
|
||||
} satisfies Variable
|
||||
|
||||
expect(actions.parseVariableValue(variable, 'TRUE')).toBe(true)
|
||||
expect(actions.parseVariableValue(variable, 'false')).toBe(false)
|
||||
expect(actions.parseVariableValue({ ...variable, type: 'FLOAT' }, '12.5')).toBe(12.5)
|
||||
expect(actions.parseVariableValue({ ...variable, type: 'STRING' }, 'hello')).toBe('hello')
|
||||
})
|
||||
|
||||
test('creates and activates new collections', () => {
|
||||
const { editor, collections } = createEditorHarness()
|
||||
const activeCollectionId = ref('')
|
||||
const actions = createVariableCollectionActions(editor, activeCollectionId)
|
||||
|
||||
actions.addCollection()
|
||||
|
||||
expect(activeCollectionId.value).toStartWith('col:')
|
||||
expect(collections.get(activeCollectionId.value)?.name).toBe('New collection')
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue