diff --git a/integrations/standalone/src/mock/meta.ts b/integrations/standalone/src/mock/meta.ts index 0df488ec..1a419785 100644 --- a/integrations/standalone/src/mock/meta.ts +++ b/integrations/standalone/src/mock/meta.ts @@ -1,45 +1,70 @@ -import type { ProjectVarNode } from '@axonivy/variable-editor-protocol'; +import type { KnownVariables, MetaData } from '@axonivy/variable-editor-protocol'; -export const knownVariables: ProjectVarNode = { - key: '', +export const knownVariables: KnownVariables = { + namespace: '', name: '', value: '', - type: 'folder', + metaData: { type: 'folder' }, description: '', children: [ { - key: 'Amazon', + namespace: '', name: 'Amazon', value: '', - type: 'folder', + metaData: { type: 'folder' }, description: '', children: [ { - key: 'Amazon.Comprehend', + namespace: 'Amazon', name: 'Comprehend', value: '', - type: 'folder', + metaData: { type: 'folder' }, description: 'Amazon comprehend connector settings', children: [ { - key: 'Amazon.Comprehend.SecretKey', + namespace: 'Amazon.Comprehend', name: 'SecretKey', value: '', - type: 'password', + metaData: { type: 'password' }, description: 'Secret key to access amazon comprehend', children: [] }, { - key: 'Amazon.Comprehend.AccessKey', + namespace: 'Amazon.Comprehend', name: 'AccessKey', value: '', - type: 'string', + metaData: { type: 'string' }, description: 'Access key to access amazon comprehend', children: [] } ] } ] + }, + { + namespace: '', + name: 'Meta', + value: '', + metaData: { type: 'folder' }, + description: '', + children: [ + { + namespace: 'Meta', + name: 'Enum', + value: 'two', + metaData: { type: 'enum', values: ['one', 'two', 'three'] } as MetaData, + description: '', + children: [] + }, + { + namespace: 'Meta', + name: 'File', + value: '', + metaData: { type: 'file', extension: 'json' } as MetaData, + description: '', + children: [] + } + ] } ] }; diff --git a/packages/protocol/src/editor.ts b/packages/protocol/src/editor.ts index a352bc76..2c1fac14 100644 --- a/packages/protocol/src/editor.ts +++ b/packages/protocol/src/editor.ts @@ -9,7 +9,7 @@ export type Severity = ("INFO" | "WARNING" | "ERROR") export interface Variables { - projectVarNode: ProjectVarNode; + knownVariables: KnownVariables; validationResult: ValidationResult[]; variablesActionArgs: VariablesActionArgs; variablesData: VariablesData; @@ -18,14 +18,17 @@ export interface Variables { void: Void; [k: string]: unknown; } -export interface ProjectVarNode { - children: ProjectVarNode[]; +export interface KnownVariables { + children: KnownVariables[]; description: string; - key: string; + metaData: MetaData; name: string; - type: string; + namespace: string; value: string; } +export interface MetaData { + type: string; +} export interface ValidationResult { message: string; path: string; diff --git a/packages/protocol/src/types.ts b/packages/protocol/src/types.ts index 6bd023d1..f9f54edb 100644 --- a/packages/protocol/src/types.ts +++ b/packages/protocol/src/types.ts @@ -1,5 +1,5 @@ import type { - ProjectVarNode, + KnownVariables, ValidationResult, VariablesActionArgs, VariablesData, @@ -13,7 +13,7 @@ export type SaveArgs = VariablesSaveDataArgs & { directSave?: boolean }; export type ValidationMessages = Array; export interface MetaRequestTypes { - 'meta/knownVariables': [VariablesEditorDataContext, ProjectVarNode]; + 'meta/knownVariables': [VariablesEditorDataContext, KnownVariables]; } export interface RequestTypes extends MetaRequestTypes { @@ -51,4 +51,11 @@ export interface ClientContext { client: Client; } -export const EMPTY_PROJECT_VAR_NODE: ProjectVarNode = { children: [], description: '', key: '', name: '', type: '', value: '' }; +export const EMPTY_KNOWN_VARIABLES: KnownVariables = { + children: [], + description: '', + metaData: { type: '' }, + name: '', + namespace: '', + value: '' +}; diff --git a/packages/variable-editor/src/components/variables/data/metadata.test.ts b/packages/variable-editor/src/components/variables/data/metadata.test.ts index 1932f52b..3506583b 100644 --- a/packages/variable-editor/src/components/variables/data/metadata.test.ts +++ b/packages/variable-editor/src/components/variables/data/metadata.test.ts @@ -3,10 +3,13 @@ import { isEnumMetadata, isFileMetadata, isFileMetadataFilenameExtension, + isMetadata, isMetadataType, metadataOptions, toEnumMetadataUpdate, - toFileMetadataUpdate + toFileMetadataUpdate, + type Metadata, + type MetadataType } from './metadata'; test('metadataOptions', () => { @@ -54,6 +57,44 @@ describe('isMetadataType', () => { }); }); +describe('isMetadata', () => { + describe('true', () => { + test('empty', () => { + expect(isMetadata({ type: '' })).toBeTruthy(); + }); + + test('password', () => { + expect(isMetadata({ type: 'password' })).toBeTruthy(); + }); + + test('daytime', () => { + expect(isMetadata({ type: 'daytime' })).toBeTruthy(); + }); + + test('enum', () => { + expect(isMetadata({ type: 'enum' })).toBeTruthy(); + }); + + test('file', () => { + expect(isMetadata({ type: 'file' })).toBeTruthy(); + }); + }); + + describe('false', () => { + test('other', () => { + expect(isMetadata({ type: 'other' as MetadataType })).toBeFalsy(); + }); + + test('undefined', () => { + expect(isMetadata()).toBeFalsy(); + }); + + test('type is undefined', () => { + expect(isMetadata({} as Metadata)).toBeFalsy(); + }); + }); +}); + describe('isEnumMetadata', () => { test('true', () => { expect(isEnumMetadata({ type: 'enum' })).toBeTruthy(); @@ -108,9 +149,9 @@ test('toEnumMetadataUpdate', () => { }); test('toFileMetadataUpdate', () => { - const filenameExtension = 'txt'; - expect(toFileMetadataUpdate(filenameExtension)).toEqual({ + const extension = 'txt'; + expect(toFileMetadataUpdate(extension)).toEqual({ key: 'metadata', - value: { type: 'file', filenameExtension: filenameExtension } + value: { type: 'file', extension } }); }); diff --git a/packages/variable-editor/src/components/variables/data/metadata.ts b/packages/variable-editor/src/components/variables/data/metadata.ts index 15981f03..3d9aba49 100644 --- a/packages/variable-editor/src/components/variables/data/metadata.ts +++ b/packages/variable-editor/src/components/variables/data/metadata.ts @@ -8,7 +8,7 @@ export interface EnumMetadata extends Metadata { } export interface FileMetadata extends Metadata { - filenameExtension: FileMetadataFilenameExtension; + extension: FileMetadataFilenameExtension; } export type FileMetadataFilenameExtension = (typeof fileMetadataFilenameExtensionOptions)[number]['value']; @@ -29,6 +29,10 @@ export const isMetadataType = (metadataType: string): metadataType is MetadataTy return metadataType === '' || metadataOptions.some(option => option.value === metadataType); }; +export const isMetadata = (metadata?: Metadata): metadata is Metadata => { + return metadata !== undefined && isMetadataType(metadata.type); +}; + export const isEnumMetadata = (metadata?: Metadata): metadata is EnumMetadata => { return metadata !== undefined && metadata.type === 'enum'; }; @@ -47,6 +51,6 @@ export const toEnumMetadataUpdate = (values: Array): VariableUpdate => { }; export const toFileMetadataUpdate = (filenameExtension: FileMetadataFilenameExtension): VariableUpdate => { - const metadata: FileMetadata = { type: 'file', filenameExtension: filenameExtension }; + const metadata: FileMetadata = { type: 'file', extension: filenameExtension }; return { key: 'metadata', value: metadata }; }; diff --git a/packages/variable-editor/src/components/variables/data/test-utils/variables-with-metadata.ts b/packages/variable-editor/src/components/variables/data/test-utils/variables-with-metadata.ts index 3a7c050c..c74dd3ab 100644 --- a/packages/variable-editor/src/components/variables/data/test-utils/variables-with-metadata.ts +++ b/packages/variable-editor/src/components/variables/data/test-utils/variables-with-metadata.ts @@ -44,7 +44,7 @@ export const rootVariableWithMetadata: RootVariable = { name: 'fileKey', value: 'fileValue', description: '', - metadata: { type: 'file', filenameExtension: 'json' } as FileMetadata, + metadata: { type: 'file', extension: 'json' } as FileMetadata, children: [] } ] diff --git a/packages/variable-editor/src/components/variables/data/variable-utils.test.ts b/packages/variable-editor/src/components/variables/data/variable-utils.test.ts index 5564b096..eda7cfa2 100644 --- a/packages/variable-editor/src/components/variables/data/variable-utils.test.ts +++ b/packages/variable-editor/src/components/variables/data/variable-utils.test.ts @@ -1,4 +1,5 @@ import { IvyIcons } from '@axonivy/ui-icons'; +import type { KnownVariables } from '@axonivy/variable-editor-protocol'; import { content, contentStringsOnly, rootVariable } from './test-utils/variables'; import { contentEmpty, @@ -23,7 +24,7 @@ import { rootVariableWithMetadata } from './test-utils/variables-with-metadata'; import type { Variable } from './variable'; -import { toContent, toVariables, variableIcon } from './variable-utils'; +import { nodeIcon, toContent, toVariables, variableIcon } from './variable-utils'; describe('toVariables', () => { test('default', () => { @@ -146,3 +147,35 @@ describe('variableIcon', () => { expect(variableIcon(variable)).toEqual(IvyIcons.Note); }); }); + +describe('nodeIcon', () => { + test('default', () => { + const node = { metaData: { type: 'other' } } as KnownVariables; + expect(nodeIcon(node)).toEqual(IvyIcons.Quote); + }); + + test('mapping', () => { + const node = { metaData: { type: 'folder' } } as KnownVariables; + expect(nodeIcon(node)).toEqual(IvyIcons.FolderOpen); + }); + + test('password', () => { + const node = { metaData: { type: 'password' } } as KnownVariables; + expect(nodeIcon(node)).toEqual(IvyIcons.Password); + }); + + test('daytime', () => { + const node = { metaData: { type: 'daytime' } } as KnownVariables; + expect(nodeIcon(node)).toEqual(IvyIcons.CalendarTime); + }); + + test('enum', () => { + const node = { metaData: { type: 'enum' } } as KnownVariables; + expect(nodeIcon(node)).toEqual(IvyIcons.List); + }); + + test('file', () => { + const node = { metaData: { type: 'file' } } as KnownVariables; + expect(nodeIcon(node)).toEqual(IvyIcons.Note); + }); +}); diff --git a/packages/variable-editor/src/components/variables/data/variable-utils.ts b/packages/variable-editor/src/components/variables/data/variable-utils.ts index c2d5a38d..4805023a 100644 --- a/packages/variable-editor/src/components/variables/data/variable-utils.ts +++ b/packages/variable-editor/src/components/variables/data/variable-utils.ts @@ -1,4 +1,5 @@ import { IvyIcons } from '@axonivy/ui-icons'; +import type { KnownVariables } from '@axonivy/variable-editor-protocol'; import { Pair, Scalar, YAMLMap, isMap, isPair, isScalar, parseDocument, stringify } from 'yaml'; import { addSingleLeadingWhitespaceToEachLine, getLastLine, removeSingleLeadingWhitespaceFromEachLine } from '../../../utils/string/string'; import { hasChildren } from '../../../utils/tree/tree-data'; @@ -13,7 +14,6 @@ import { type MetadataType } from './metadata'; import type { RootVariable, Variable } from './variable'; -import type { ProjectVarNode } from '@axonivy/variable-editor-protocol'; export const toVariables = (content: string) => { const rootVariable: RootVariable = { @@ -184,7 +184,7 @@ const enrichVariableWithEnumMetadata = (variable: Variable, metadata: string) => const enrichVariableWithFileMetadata = (variable: Variable, metadata: string) => { const filenameExtension = metadata.replace(/^file:\s*/, ''); if (isFileMetadataFilenameExtension(filenameExtension)) { - const fileMetadata: FileMetadata = { type: 'file', filenameExtension: filenameExtension }; + const fileMetadata: FileMetadata = { type: 'file', extension: filenameExtension }; variable.metadata = fileMetadata; } return variable; @@ -245,7 +245,7 @@ const parseMetadataComment = (metadata: Metadata) => { break; case 'file': if (isFileMetadata(metadata)) { - metadataComment = 'file: ' + metadata.filenameExtension; + metadataComment = 'file: ' + metadata.extension; } break; default: @@ -262,8 +262,8 @@ export const variableIcon = (variable: Variable) => { return icon(variable.metadata.type); }; -export const nodeIcon = (variableNode: ProjectVarNode) => { - return icon(variableNode.type); +export const nodeIcon = (node: KnownVariables) => { + return icon(node.metaData.type); }; const icon = (type: string) => { diff --git a/packages/variable-editor/src/components/variables/detail/DetailContent.test.ts b/packages/variable-editor/src/components/variables/detail/DetailContent.test.ts index ed61851b..4d45bf52 100644 --- a/packages/variable-editor/src/components/variables/detail/DetailContent.test.ts +++ b/packages/variable-editor/src/components/variables/detail/DetailContent.test.ts @@ -1,4 +1,4 @@ -import type { Client, MetaRequestTypes, ProjectVarNode } from '@axonivy/variable-editor-protocol'; +import type { Client, MetaRequestTypes, KnownVariables } from '@axonivy/variable-editor-protocol'; import { waitFor } from '@testing-library/react'; import { customRenderHook } from '../data/test-utils/test-utils'; import type { Variable } from '../data/variable'; @@ -47,6 +47,6 @@ class ClientMock implements Partial { meta(): Promise { return Promise.resolve({ children: [{ name: 'Amazon', children: [{ name: 'Comprehend', children: [{ name: 'SecretKey' }, { name: 'AccessKey' }] }] }] - } as ProjectVarNode); + } as KnownVariables); } } diff --git a/packages/variable-editor/src/components/variables/detail/DetailContent.tsx b/packages/variable-editor/src/components/variables/detail/DetailContent.tsx index 9ff24f44..5fc82ae8 100644 --- a/packages/variable-editor/src/components/variables/detail/DetailContent.tsx +++ b/packages/variable-editor/src/components/variables/detail/DetailContent.tsx @@ -1,5 +1,5 @@ import { BasicField, BasicInput, Flex, PanelMessage, ReadonlyProvider, Textarea, useReadonly } from '@axonivy/ui-components'; -import { EMPTY_PROJECT_VAR_NODE, type ProjectVarNode } from '@axonivy/variable-editor-protocol'; +import { EMPTY_KNOWN_VARIABLES, type KnownVariables } from '@axonivy/variable-editor-protocol'; import { useMemo } from 'react'; import { useAppContext } from '../../../context/AppContext'; import { useMeta } from '../../../context/useMeta'; @@ -11,7 +11,7 @@ import { Value } from './Value'; export const useOverwrites = () => { const { context, variables, selectedVariable } = useAppContext(); - let currentNode: ProjectVarNode | undefined = useMeta('meta/knownVariables', context, EMPTY_PROJECT_VAR_NODE).data; + let currentNode: KnownVariables | undefined = useMeta('meta/knownVariables', context, EMPTY_KNOWN_VARIABLES).data; if (currentNode === undefined || currentNode.children.length === 0) { return false; } diff --git a/packages/variable-editor/src/components/variables/detail/Metadata.tsx b/packages/variable-editor/src/components/variables/detail/Metadata.tsx index b9543d58..dc18066a 100644 --- a/packages/variable-editor/src/components/variables/detail/Metadata.tsx +++ b/packages/variable-editor/src/components/variables/detail/Metadata.tsx @@ -35,7 +35,7 @@ export const Metadata = ({ variable, onChange }: MetadataProps) => { case 'file': updates.push({ key: 'value', value: '' }); if (isFileMetadata(newMetadata)) { - newMetadata.filenameExtension = 'txt'; + newMetadata.extension = 'txt'; } } updates.push({ key: 'metadata', value: newMetadata }); @@ -51,7 +51,7 @@ export const Metadata = ({ variable, onChange }: MetadataProps) => { {isFileMetadata(metadata) && ( onChange([toFileMetadataUpdate(filenameExtension)])} /> diff --git a/packages/variable-editor/src/components/variables/dialog/OverwriteDialog.tsx b/packages/variable-editor/src/components/variables/dialog/OverwriteDialog.tsx index a6122013..228b1fe1 100644 --- a/packages/variable-editor/src/components/variables/dialog/OverwriteDialog.tsx +++ b/packages/variable-editor/src/components/variables/dialog/OverwriteDialog.tsx @@ -1,13 +1,13 @@ import { Button, Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, selectRow } from '@axonivy/ui-components'; import { IvyIcons } from '@axonivy/ui-icons'; +import type { KnownVariables } from '@axonivy/variable-editor-protocol'; import { type Table } from '@tanstack/react-table'; import { useState } from 'react'; import { useAppContext } from '../../../context/AppContext'; -import type { ProjectVarNode } from '@axonivy/variable-editor-protocol'; import { toRowId } from '../../../utils/tree/tree'; import { addNode } from '../../../utils/tree/tree-data'; import type { AddNodeReturnType } from '../../../utils/tree/types'; -import { isMetadataType, type MetadataType } from '../data/metadata'; +import { isMetadata, type Metadata } from '../data/metadata'; import { createVariable, type Variable } from '../data/variable'; import { VariableBrowser } from './VariableBrowser'; @@ -18,15 +18,16 @@ type OverwriteProps = { export const OverwriteDialog = ({ table }: OverwriteProps) => { const { setVariables, setSelectedVariable } = useAppContext(); - const insertVariable = (node?: ProjectVarNode): void => { - if (node) { - setVariables(old => { - const addNodeReturnValue = addVariable(old, node); - selectRow(table, toRowId(addNodeReturnValue.newNodePath)); - setSelectedVariable(addNodeReturnValue.newNodePath); - return addNodeReturnValue.newData; - }); + const insertVariable = (node?: KnownVariables): void => { + if (!node) { + return; } + setVariables(old => { + const addNodeReturnValue = addVariable(old, node); + selectRow(table, toRowId(addNodeReturnValue.newNodePath)); + setSelectedVariable(addNodeReturnValue.newNodePath); + return addNodeReturnValue.newData; + }); }; const [dialogState, setDialogState] = useState(false); @@ -51,29 +52,27 @@ export const OverwriteDialog = ({ table }: OverwriteProps) => { ); }; -const addVariable = (variables: Array, node: ProjectVarNode): AddNodeReturnType => { - const lastDot = node.key.lastIndexOf('.'); - const namespace = node.key.substring(0, lastDot); - let metadataType: MetadataType = ''; - if (isMetadataType(node.type)) { - metadataType = node.type; +const addVariable = (variables: Array, node: KnownVariables): AddNodeReturnType => { + let metadata: Metadata = { type: '' }; + const nodeMetaData = node.metaData as Metadata; + if (isMetadata(nodeMetaData)) { + metadata = nodeMetaData; } - const returnValue = addNode(node.name, namespace, variables, name => { + let returnValue = addNode(node.name, node.namespace, variables, name => { if (name === node.name) { return { name, value: node.value, children: [], description: node.description, - metadata: { type: metadataType } + metadata: metadata }; } return createVariable(name); }); - let childReturnValue = returnValue; + const newNodePath = returnValue.newNodePath; for (const child of node.children) { - childReturnValue = addVariable(childReturnValue.newData, child); + returnValue = addVariable(returnValue.newData, child); } - returnValue.newData = childReturnValue.newData; - return returnValue; + return { newData: returnValue.newData, newNodePath }; }; diff --git a/packages/variable-editor/src/components/variables/dialog/VariableBrowser.tsx b/packages/variable-editor/src/components/variables/dialog/VariableBrowser.tsx index 4d278ef2..2e3ae94c 100644 --- a/packages/variable-editor/src/components/variables/dialog/VariableBrowser.tsx +++ b/packages/variable-editor/src/components/variables/dialog/VariableBrowser.tsx @@ -1,14 +1,14 @@ -import { useBrowser, BrowsersView } from '@axonivy/ui-components'; +import { BrowsersView, useBrowser } from '@axonivy/ui-components'; import { IvyIcons } from '@axonivy/ui-icons'; -import { EMPTY_PROJECT_VAR_NODE, type ProjectVarNode } from '@axonivy/variable-editor-protocol'; +import { EMPTY_KNOWN_VARIABLES, type KnownVariables } from '@axonivy/variable-editor-protocol'; import { useMemo } from 'react'; import { useAppContext } from '../../../context/AppContext'; import { useMeta } from '../../../context/useMeta'; import { toNodes } from './known-variables'; -export const VariableBrowser = ({ applyFn }: { applyFn: (node?: ProjectVarNode) => void }) => { +export const VariableBrowser = ({ applyFn }: { applyFn: (node?: KnownVariables) => void }) => { const { context } = useAppContext(); - const knownVariables = useMeta('meta/knownVariables', context, EMPTY_PROJECT_VAR_NODE).data; + const knownVariables = useMeta('meta/knownVariables', context, EMPTY_KNOWN_VARIABLES).data; const nodes = useMemo(() => toNodes(knownVariables), [knownVariables]); const variableBrowser = useBrowser(nodes); return ( @@ -18,30 +18,30 @@ export const VariableBrowser = ({ applyFn }: { applyFn: (node?: ProjectVarNode) name: 'Variables', icon: IvyIcons.Tool, browser: variableBrowser, - infoProvider: row => + infoProvider: row => } ]} - apply={(type, result) => { - applyFn(result?.data as ProjectVarNode); + apply={(_, result) => { + applyFn(result?.data as KnownVariables); }} applyBtn={{ label: 'Import', icon: IvyIcons.FileImport }} /> ); }; -const InfoProvider = ({ node }: { node?: ProjectVarNode }) => { - let value = node?.value; - if (value !== undefined && node?.type == 'password') { - value = '***'; +const InfoProvider = ({ node }: { node?: KnownVariables }) => { + if (!node) { + return; } - if (value !== undefined && value !== '') { - value = node?.name + ' = ' + value; + let value = node.value; + if (node.metaData.type === 'password') { + value = '***'; } return (
-
{node?.key}
-
{node?.description}
-
{value}
+
{`${node.namespace}.${node.name}`}
+
{node.description}
+ {value &&
{node.name + ' = ' + value}
}
); }; diff --git a/packages/variable-editor/src/components/variables/dialog/known-variables.test.ts b/packages/variable-editor/src/components/variables/dialog/known-variables.test.ts index 20d66129..b40cec08 100644 --- a/packages/variable-editor/src/components/variables/dialog/known-variables.test.ts +++ b/packages/variable-editor/src/components/variables/dialog/known-variables.test.ts @@ -1,40 +1,40 @@ -import { EMPTY_PROJECT_VAR_NODE, type ProjectVarNode } from '@axonivy/variable-editor-protocol'; +import { EMPTY_KNOWN_VARIABLES, type KnownVariables } from '@axonivy/variable-editor-protocol'; import { toNodes } from './known-variables'; -const knownVariables: ProjectVarNode = { - key: '', +const knownVariables: KnownVariables = { + namespace: '', name: '', value: '', - type: 'folder', + metaData: { type: 'folder' }, description: '', children: [ { - key: 'Amazon', + namespace: '', name: 'Amazon', value: '', - type: 'folder', + metaData: { type: 'folder' }, description: '', children: [ { - key: 'Amazon.Comprehend', + namespace: 'Amazon', name: 'Comprehend', value: '', - type: 'folder', + metaData: { type: 'folder' }, description: 'Amazon comprehend connector settings', children: [ { - key: 'Amazon.Comprehend.SecretKey', + namespace: 'Amazon.Comprehend', name: 'SecretKey', value: '', - type: 'password', + metaData: { type: 'password' }, description: 'Secret key to access amazon comprehend', children: [] }, { - key: 'Amazon.Comprehend.AccessKey', + namespace: 'Amazon.Comprehend', name: 'AccessKey', value: '', - type: 'string', + metaData: { type: 'string' }, description: 'Access key to access amazon comprehend', children: [] } @@ -46,7 +46,7 @@ const knownVariables: ProjectVarNode = { }; test('toNodes', () => { - expect(toNodes(EMPTY_PROJECT_VAR_NODE)).toEqual([]); + expect(toNodes(EMPTY_KNOWN_VARIABLES)).toEqual([]); const nodes = toNodes(knownVariables); expect(nodes).toHaveLength(1); diff --git a/packages/variable-editor/src/components/variables/dialog/known-variables.ts b/packages/variable-editor/src/components/variables/dialog/known-variables.ts index b637f9fc..8e5f744f 100644 --- a/packages/variable-editor/src/components/variables/dialog/known-variables.ts +++ b/packages/variable-editor/src/components/variables/dialog/known-variables.ts @@ -1,16 +1,16 @@ import type { BrowserNode } from '@axonivy/ui-components'; -import type { ProjectVarNode } from '@axonivy/variable-editor-protocol'; +import type { KnownVariables } from '@axonivy/variable-editor-protocol'; import { nodeIcon } from '../data/variable-utils'; -export const toNodes = (root?: ProjectVarNode): Array => { +export const toNodes = (root?: KnownVariables): Array => { if (!root) { return []; } return root.children.map(varNode => toNode(varNode)); }; -const toNode = (node: ProjectVarNode): BrowserNode => { - const c = node.children.map(child => toNode(child)); +const toNode = (node: KnownVariables): BrowserNode => { + const children = node.children.map(child => toNode(child)); const icon = nodeIcon(node); const info = node.description; return { @@ -18,6 +18,6 @@ const toNode = (node: ProjectVarNode): BrowserNode => { info, icon, data: node, - children: c + children }; }; diff --git a/playwright/tests/integration/mock/detail.spec.ts b/playwright/tests/integration/mock/detail.spec.ts index a8a853c5..6ee59207 100644 --- a/playwright/tests/integration/mock/detail.spec.ts +++ b/playwright/tests/integration/mock/detail.spec.ts @@ -100,7 +100,7 @@ test('new enum variable', async () => { await details.fill('myName', 'Monday', 'This is myName with a value of Monday', 'Enum'); await details.expectValues('myName', 'Monday', 'This is myName with a value of Monday', 'Enum'); - await details.listOfPossibleValues.expectValues(['Monday']); + await details.listOfPossibleValues.expectValues('Monday'); await details.expectTitle('Variables - project-name - myName'); await editor.tree.row(11).expectValues(['myName', 'Monday']); await editor.tree.row(10).click(); @@ -109,7 +109,7 @@ test('new enum variable', async () => { await details.expectTitle('Variables - project-name - myName'); await details.expectValues('myName', 'Monday', 'This is myName with a value of Monday', 'Enum'); - await details.listOfPossibleValues.expectValues(['Monday']); + await details.listOfPossibleValues.expectValues('Monday'); }); test('add/delete enum variable', async () => { @@ -122,7 +122,7 @@ test('add/delete enum variable', async () => { await details.listOfPossibleValues.addValue('Tuesday'); await details.listOfPossibleValues.addValue('Wednesday'); - await details.listOfPossibleValues.expectValues(['Monday', 'Tuesday', 'Wednesday']); + await details.listOfPossibleValues.expectValues('Monday', 'Tuesday', 'Wednesday'); await details.enumValue.choose('Tuesday'); await details.enumValue.expectValue('Tuesday'); @@ -135,7 +135,7 @@ test('add/delete enum variable', async () => { await details.listOfPossibleValues.deleteValue('Tuesday'); await details.listOfPossibleValues.deleteValue('Wednesday'); - await details.listOfPossibleValues.expectValues(['Monday']); + await details.listOfPossibleValues.expectValues('Monday'); }); test('edit name', async () => { diff --git a/playwright/tests/integration/mock/import.spec.ts b/playwright/tests/integration/mock/import.spec.ts index 2abe8562..13de691b 100644 --- a/playwright/tests/integration/mock/import.spec.ts +++ b/playwright/tests/integration/mock/import.spec.ts @@ -1,23 +1,44 @@ import { expect, test } from '@playwright/test'; +import { describe } from 'node:test'; import { VariableEditor } from '../../pageobjects/VariableEditor'; -test('importAndOverwrite', async ({ page }) => { - const editor = await VariableEditor.openMock(page); - await editor.tree.expectRowCount(11); +describe('importAndOverwrite', async () => { + test('password', async ({ page }) => { + const editor = await VariableEditor.openMock(page); + await editor.tree.expectRowCount(11); - const overwrite = editor.overwrite; - await overwrite.open(); - const variables = overwrite.variables; - await variables.cell(0, 0).expectValue('Amazon'); - await variables.cell(1, 0).expectValue('ComprehendAmazon comprehend connector settings'); - await variables.cell(1, 0).expand(); - await variables.cell(2, 0).expectValue('SecretKeySecret key to access amazon comprehend'); - await variables.row(2).click(); - await overwrite.importBtn.click(); - await overwrite.expectClosed(); + const overwrite = editor.overwrite; + await overwrite.open(); + const variables = overwrite.variables; + await variables.cell(0, 0).expectValue('Amazon'); + await variables.cell(1, 0).expectValue('ComprehendAmazon comprehend connector settings'); + await variables.cell(1, 0).expand(); + await variables.cell(2, 0).expectValue('SecretKeySecret key to access amazon comprehend'); + await variables.row(2).click(); + await overwrite.importBtn.click(); + await overwrite.expectClosed(); - const details = editor.details; - await details.expectValues('SecretKey', '', 'Secret key to access amazon comprehend', 'Password'); + const details = editor.details; + await details.expectValues('SecretKey', '', 'Secret key to access amazon comprehend', 'Password'); + }); + + test('enum has values', async ({ page }) => { + const editor = await VariableEditor.openMock(page); + await editor.overwrite.open(); + await editor.overwrite.variables.row(2).expand(); + await editor.overwrite.variables.row(3).click(); + await editor.overwrite.importBtn.click(); + await editor.details.listOfPossibleValues.expectValues('one', 'two', 'three'); + }); + + test('file has extension', async ({ page }) => { + const editor = await VariableEditor.openMock(page); + await editor.overwrite.open(); + await editor.overwrite.variables.row(2).expand(); + await editor.overwrite.variables.row(4).click(); + await editor.overwrite.importBtn.click(); + await editor.details.fileNameExtension.expectValue('json'); + }); }); test('importAndOverwriteWholeSubTree', async ({ page }) => { @@ -45,9 +66,24 @@ test('importAndOverwriteWholeSubTree', async ({ page }) => { await details.expectValues('AccessKey', '', 'Access key to access amazon comprehend', 'Default'); }); -test('disabledMetadataOfOverwrittenVariable', async ({ page }) => { - const editor = await VariableEditor.openMock(page); - await editor.addVariable('SecretKey', 'Amazon.Comprehend'); - await editor.tree.row(13).click(); - await expect(editor.details.metaData.locator).toBeDisabled(); +describe('disabledMetadataOfOverwrittenVariable', async () => { + test('enum', async ({ page }) => { + const editor = await VariableEditor.openMock(page); + await editor.overwrite.open(); + await editor.overwrite.variables.row(2).click(); + await editor.overwrite.importBtn.click(); + await editor.tree.row(12).click(); + await expect(editor.details.metaData.locator).toBeDisabled(); + await editor.details.listOfPossibleValues.expectToBeDisabled(); + }); + + test('file', async ({ page }) => { + const editor = await VariableEditor.openMock(page); + await editor.overwrite.open(); + await editor.overwrite.variables.row(2).click(); + await editor.overwrite.importBtn.click(); + await editor.tree.row(13).click(); + await expect(editor.details.metaData.locator).toBeDisabled(); + await expect(editor.details.fileNameExtension.locator).toBeDisabled(); + }); }); diff --git a/playwright/tests/pageobjects/EnumValues.ts b/playwright/tests/pageobjects/EnumValues.ts index af55c90e..67c15918 100644 --- a/playwright/tests/pageobjects/EnumValues.ts +++ b/playwright/tests/pageobjects/EnumValues.ts @@ -1,6 +1,6 @@ -import type { Locator, Page } from '@playwright/test'; -import { Table } from './Table'; +import { expect, type Locator, type Page } from '@playwright/test'; import { Button } from './Button'; +import { Table } from './Table'; export class EnumValues { private readonly table: Table; @@ -41,10 +41,17 @@ export class EnumValues { await this.table.cell(rowCount - 1, 0).fill(value); } - async expectValues(values: string[]) { + async expectValues(...values: Array) { await this.table.expectRowCount(values.length); for (let row = 0; row < values.length; row++) { await this.table.cell(row, 0).expectValue(values[row]); } } + + async expectToBeDisabled() { + const rowCount = await this.table.rowCount(); + for (let row = 0; row < rowCount; row++) { + await expect(this.table.row(row).locator.locator('.ui-input')).toBeDisabled(); + } + } }