Skip to content

Commit

Permalink
XIVY-14730 disable metadata of overwritten variables
Browse files Browse the repository at this point in the history
Make the metadata read only if the variable is found in the known variables of the required projects.
  • Loading branch information
ivy-lgi committed Dec 10, 2024
1 parent 18e193d commit 14ca1ea
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 29 deletions.
4 changes: 2 additions & 2 deletions integrations/standalone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"dependencies": {
"@axonivy/variable-editor": "*",
"@axonivy/variable-editor-protocol": "*",
"@axonivy/ui-components": "~12.0.1-next.390",
"@axonivy/ui-icons": "~12.0.1-next.390",
"@axonivy/ui-components": "~12.0.1-next.401",
"@axonivy/ui-icons": "~12.0.1-next.401",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
Expand Down
28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions packages/variable-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"types": "lib/index.d.ts",
"main": "lib/editor.js",
"dependencies": {
"@axonivy/jsonrpc": "~12.0.1-next.390",
"@axonivy/ui-components": "~12.0.1-next.390",
"@axonivy/ui-icons": "~12.0.1-next.390",
"@axonivy/jsonrpc": "~12.0.1-next.401",
"@axonivy/ui-components": "~12.0.1-next.401",
"@axonivy/ui-icons": "~12.0.1-next.401",
"@axonivy/variable-editor-protocol": "12.0.1-next",
"@tanstack/react-query": "5.32.1",
"@tanstack/react-query-devtools": "5.32.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
import type { Client, ValidationMessages, VariablesEditorDataContext } from '@axonivy/variable-editor-protocol';
import type { RenderHookOptions } from '@testing-library/react';
import { renderHook } from '@testing-library/react';
import { type ReactNode } from 'react';
import { AppProvider } from '../../../../context/AppContext';
import type { ValidationMessages, VariablesEditorDataContext } from '@axonivy/variable-editor-protocol';
import { ClientContextProvider } from '../../../../protocol/ClientContextProvider';
import { QueryProvider } from '../../../../query/QueryProvider';
import { initQueryClient } from '../../../../query/query-client';
import type { TreePath } from '../../../../utils/tree/types';
import type { Variable } from '../variable';

type ContextHelperProps = {
client?: Partial<Client>;
appContext?: {
variables?: Array<Variable>;
selectedVariable?: TreePath;
validations?: ValidationMessages;
};
};

const ContextHelper = (props: ContextHelperProps & { children: ReactNode }) => {
const client = (props.client ?? new EmptyClient()) as Client;
const appContext = {
context: {} as VariablesEditorDataContext,
variables: [],
variables: props.appContext?.variables ?? [],
setVariables: () => {},
selectedVariable: [],
selectedVariable: props.appContext?.selectedVariable ?? [],
setSelectedVariable: () => {},
validations: props.appContext?.validations ?? [],
detail: true,
setDetail: () => {}
};
return <AppProvider value={appContext}>{props.children}</AppProvider>;
return (
<ClientContextProvider client={client}>
<QueryProvider client={initQueryClient()}>
<AppProvider value={appContext}>{props.children}</AppProvider>
</QueryProvider>
</ClientContextProvider>
);
};

export const customRenderHook = <Result, Props>(
Expand All @@ -33,3 +48,5 @@ export const customRenderHook = <Result, Props>(
...options
});
};

class EmptyClient implements Partial<Client> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { Client, MetaRequestTypes, ProjectVarNode } 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';
import { useOverwrites } from './DetailContent';

describe('useOverwrites', () => {
describe('false', () => {
test('in known folder', () => {
const view = customRenderHook(() => useOverwrites(), {
wrapperProps: { client: new ClientMock(), appContext: { variables: variables, selectedVariable: [1, 0] } }
});
expect(view.result.current).toBeFalsy();
});

test('not in known folder', () => {
const view = customRenderHook(() => useOverwrites(), {
wrapperProps: { client: new ClientMock(), appContext: { variables: variables, selectedVariable: [0] } }
});
expect(view.result.current).toBeFalsy();
});
});

describe('true', () => {
test('leaf', async () => {
const view = customRenderHook(() => useOverwrites(), {
wrapperProps: { client: new ClientMock(), appContext: { variables: variables, selectedVariable: [1, 1, 0] } }
});
await waitFor(() => {
expect(view.result.current).toBeTruthy();
});
});

test('not leaf', async () => {
const view = customRenderHook(() => useOverwrites(), {
wrapperProps: { client: new ClientMock(), appContext: { variables: variables, selectedVariable: [1, 1] } }
});
await waitFor(() => {
expect(view.result.current).toBeTruthy();
});
});
});
});

const variables = [
{ name: 'Variable' },
{ name: 'Amazon', children: [{ name: 'AmazonVariable' }, { name: 'Comprehend', children: [{ name: 'SecretKey' }] }] }
] as Array<Variable>;

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);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
import { BasicField, Flex, BasicInput, PanelMessage, Textarea } from '@axonivy/ui-components';
import { BasicField, BasicInput, Flex, PanelMessage, ReadonlyProvider, Textarea } from '@axonivy/ui-components';
import { EMPTY_PROJECT_VAR_NODE, type ProjectVarNode } from '@axonivy/variable-editor-protocol';
import { useMemo } from 'react';
import { useAppContext } from '../../../context/AppContext';
import { getNode, updateNode, hasChildren as variableHasChildren } from '../../../utils/tree/tree-data';
import { useMeta } from '../../../context/useMeta';
import { getNode, getNodesOnPath, updateNode, hasChildren as variableHasChildren } from '../../../utils/tree/tree-data';
import { type VariableUpdates } from '../data/variable';
import './DetailContent.css';
import { Metadata } from './Metadata';
import { Value } from './Value';
import './DetailContent.css';
import { useMemo } from 'react';

export const useOverwrites = () => {
const { context, variables, selectedVariable } = useAppContext();
const variableNodes = getNodesOnPath(variables, selectedVariable);
let currentNode: ProjectVarNode | undefined = useMeta('meta/knownVariables', context, EMPTY_PROJECT_VAR_NODE).data;
for (const variableNode of variableNodes) {
currentNode = currentNode.children.find(child => child.name === variableNode?.name);
if (!currentNode) {
return false;
}
}
return true;
};

export const VariablesDetailContent = () => {
const { variables, setVariables, selectedVariable } = useAppContext();

const variable = useMemo(() => getNode(variables, selectedVariable), [variables, selectedVariable]);
const overwrites = useOverwrites();

if (!variable) {
return <PanelMessage message='Select a variable to edit its properties.' />;
}
Expand All @@ -31,7 +48,11 @@ export const VariablesDetailContent = () => {
onChange={event => handleVariableAttributeChange([{ key: 'description', value: event.target.value }])}
/>
</BasicField>
{!hasChildren && <Metadata variable={variable} onChange={handleVariableAttributeChange} />}
{!hasChildren && (
<ReadonlyProvider readonly={overwrites}>
<Metadata variable={variable} onChange={handleVariableAttributeChange} />
</ReadonlyProvider>
)}
</Flex>
);
};
9 changes: 8 additions & 1 deletion playwright/tests/integration/mock/import.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test } from '@playwright/test';
import { expect, test } from '@playwright/test';
import { VariableEditor } from '../../pageobjects/VariableEditor';

test('importAndOverwrite', async ({ page }) => {
Expand Down Expand Up @@ -44,3 +44,10 @@ test('importAndOverwriteWholeSubTree', async ({ page }) => {
await tree.row(14).click();
await details.expectValues('AccessKey', '<YOUR_ACCESS_KEY>', '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();
});

0 comments on commit 14ca1ea

Please sign in to comment.