Skip to content

Commit

Permalink
XIVY-15648 meta data details of known variables
Browse files Browse the repository at this point in the history
The endpoint `knownVariables` has been adapted in the core to return the meta data details of variables of type enum (values) and file (extension).
These values are now set on the overwriting variable when using the overwrite dialog.

Additionally:
- Added tests for `nodeIcon`.
- Added tests that editing meta data details is disabled on overwriting variables.
- Minor refactors here and there.
  • Loading branch information
ivy-lgi committed Dec 17, 2024
1 parent 26c7570 commit 2fa2649
Show file tree
Hide file tree
Showing 18 changed files with 277 additions and 122 deletions.
49 changes: 37 additions & 12 deletions integrations/standalone/src/mock/meta.ts
Original file line number Diff line number Diff line change
@@ -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: '<YOUR_SECRET_KEY>',
type: 'password',
metaData: { type: 'password' },
description: 'Secret key to access amazon comprehend',
children: []
},
{
key: 'Amazon.Comprehend.AccessKey',
namespace: 'Amazon.Comprehend',
name: 'AccessKey',
value: '<YOUR_ACCESS_KEY>',
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: []
}
]
}
]
};
13 changes: 8 additions & 5 deletions packages/protocol/src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
export type Severity = ("INFO" | "WARNING" | "ERROR")

export interface Variables {
projectVarNode: ProjectVarNode;
knownVariables: KnownVariables;
validationResult: ValidationResult[];
variablesActionArgs: VariablesActionArgs;
variablesData: VariablesData;
Expand All @@ -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;
Expand Down
13 changes: 10 additions & 3 deletions packages/protocol/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {
ProjectVarNode,
KnownVariables,
ValidationResult,
VariablesActionArgs,
VariablesData,
Expand All @@ -13,7 +13,7 @@ export type SaveArgs = VariablesSaveDataArgs & { directSave?: boolean };
export type ValidationMessages = Array<ValidationResult>;

export interface MetaRequestTypes {
'meta/knownVariables': [VariablesEditorDataContext, ProjectVarNode];
'meta/knownVariables': [VariablesEditorDataContext, KnownVariables];
}

export interface RequestTypes extends MetaRequestTypes {
Expand Down Expand Up @@ -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: ''
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import {
isEnumMetadata,
isFileMetadata,
isFileMetadataFilenameExtension,
isMetadata,
isMetadataType,
metadataOptions,
toEnumMetadataUpdate,
toFileMetadataUpdate
toFileMetadataUpdate,
type Metadata,
type MetadataType
} from './metadata';

test('metadataOptions', () => {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 }
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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'];

Expand All @@ -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';
};
Expand All @@ -47,6 +51,6 @@ export const toEnumMetadataUpdate = (values: Array<string>): 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 };
};
Original file line number Diff line number Diff line change
Expand Up @@ -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: []
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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', () => {
Expand Down Expand Up @@ -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);
});
});
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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 = {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -245,7 +245,7 @@ const parseMetadataComment = (metadata: Metadata) => {
break;
case 'file':
if (isFileMetadata(metadata)) {
metadataComment = 'file: ' + metadata.filenameExtension;
metadataComment = 'file: ' + metadata.extension;
}
break;
default:
Expand All @@ -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) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -47,6 +47,6 @@ class ClientMock implements Partial<Client> {
meta<TMeta extends keyof MetaRequestTypes>(): Promise<MetaRequestTypes[TMeta][1]> {
return Promise.resolve({
children: [{ name: 'Amazon', children: [{ name: 'Comprehend', children: [{ name: 'SecretKey' }, { name: 'AccessKey' }] }] }]
} as ProjectVarNode);
} as KnownVariables);
}
}
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand All @@ -51,7 +51,7 @@ export const Metadata = ({ variable, onChange }: MetadataProps) => {
{isFileMetadata(metadata) && (
<BasicField label='Filename extension'>
<BasicSelect
value={metadata.filenameExtension}
value={metadata.extension}
items={fileMetadataFilenameExtensionOptions}
onValueChange={(filenameExtension: FileMetadataFilenameExtension) => onChange([toFileMetadataUpdate(filenameExtension)])}
/>
Expand Down
Loading

0 comments on commit 2fa2649

Please sign in to comment.