Skip to content

Commit

Permalink
XIVY-15526 adds test for badge-tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
ivy-fhe committed Dec 11, 2024
1 parent c57df9d commit f466d81
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 44 deletions.
53 changes: 53 additions & 0 deletions packages/editor/src/utils/CmsTooltip.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { describe } from 'vitest';
import type { ContentObject } from '@axonivy/form-editor-protocol';
import { findCmsEntries } from './CmsTooltip';

describe('test tooltips', () => {
test('test cms entry search', async () => {
const cmsTree: Array<ContentObject> = [
{
name: 'form-test-project',
fullPath: '/',
type: 'FOLDER',
values: {},
children: [
{
name: 'greetings',
fullPath: '/greetings',
type: 'FOLDER',
values: {},
children: [
{
name: 'hello',
fullPath: '/greetings/hello',
type: 'STRING',
values: { en: 'Hello!' },
children: []
},
{
name: 'hello',
fullPath: '/greetings/longEntry',
type: 'STRING',
values: {
en: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent aliquam'
},
children: []
}
]
}
]
}
];

const cmsValidPath = '/greetings/hello';
const cmsInvalidPath = '/notfound';
const cmsLongPath = '/greetings/longEntry';
const cmsValidEntries = findCmsEntries(cmsValidPath, cmsTree);
const cmsInvalidEntries = findCmsEntries(cmsInvalidPath, cmsTree);
const cmsLongEntries = findCmsEntries(cmsLongPath, cmsTree);

expect(cmsValidEntries).toContain('en: Hello!');
expect(cmsInvalidEntries).toContain('no cms entry found');
expect(cmsLongEntries).toContain('en: Lorem ipsum dolor sit amet, consectetur ...');
});
});
47 changes: 47 additions & 0 deletions packages/editor/src/utils/CmsTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { ContentObject } from '@axonivy/form-editor-protocol';
import { useAppContext } from '../context/AppContext';
import { useMeta } from '../context/useMeta';

export const CmsTooltip = ({ text }: { text: string }) => {
const { context } = useAppContext();
const cmsItems = useMeta('meta/cms/cmsTree', { context, requiredProjects: false }, []).data;

text = text.replaceAll(/#{ivy.cms.co\(|['"]|\)}/g, '');
const entries = findCmsEntries(text, cmsItems);
entries.unshift(text);

return entries.map((entry, i) => (
<span key={i}>
{entry}
<br />
</span>
));
};

export const findCmsEntries = (targetPath: string, cmsTree: Array<ContentObject>) => {
const notFound = ['no cms entry found'];
if (cmsTree.length === 0) {
return notFound;
}
const entries = findDeep(targetPath, cmsTree[0]);
if (!entries) {
return notFound;
}
return Object.entries(entries).map(entry => {
let value = entry[1];
if (value.length > 40) {
value = value.substring(0, 40) + '...';
}
return `${entry[0]}: ${value}`;
});
};

const findDeep = (targetPath: string, obj?: ContentObject) => {
if (!obj) return null;
if (obj.fullPath === targetPath) return obj.values;
if (!obj.children || obj.children.length === 0) return null;
return findDeep(
targetPath,
obj.children.find(e => targetPath.startsWith(e.fullPath))
);
};
53 changes: 9 additions & 44 deletions packages/editor/src/utils/badge-properties.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { IvyIcons } from '@axonivy/ui-icons';
import { useAppContext } from '../context/AppContext';
import { useMeta } from '../context/useMeta';
import type { ContentObject } from '@axonivy/form-editor-protocol';
import type { BadgeType } from '@axonivy/ui-components';
import { CmsTooltip } from './CmsTooltip';

const badgePropertyCMS: BadgeType = {
regex: /#{\s*ivy.cms.co[^}]+}/,
icon: IvyIcons.Cms,
badgeTextGen: (text: string) => '.../' + text.replaceAll(/#{\s*ivy.cms.co\(['"]|\/*[^\\]+\/|['"]\)\s*}/g, ''),
badgeTextGen: (text: string) => '...' + text.replaceAll(/#{\s*ivy.cms.co\(['"]|.*(?=\/)|['"]\)\s*}/g, ''),
tooltip: (text: string) => <CmsTooltip text={text} />
};

Expand All @@ -23,49 +21,16 @@ const badgePropertyLogic: BadgeType = {
badgeTextGen: (text: string) => text.replaceAll(/#{\s*logic\.|}/g, '')
};

const badgePropertyBean: BadgeType = {
regex: /#{[^}]*\([^}]*\)}/,
icon: IvyIcons.StartProgram,
badgeTextGen: (text: string) => text.replaceAll(/#{[^}]*\.|\(.*\)|}/g, '') // remove brackets?
};

const badgePropertyExpression: BadgeType = {
regex: /#{[^}]*}/,
icon: IvyIcons.StartProgram,
badgeTextGen: (text: string) => text.replaceAll(/#{\s*|\s*}/g, '')
};

const CmsTooltip = ({ text }: { text: string }) => {
const { context } = useAppContext();
const cmsItems = useMeta('meta/cms/cmsTree', { context, requiredProjects: false }, []).data;

const findCmsEntries = (targetPath: string, cmsTree: Array<ContentObject>) => {
const notFound = ['no cms entry found'];
if (cmsTree.length === 0) {
return notFound;
}
const entries = findDeep(targetPath, cmsTree[0]);
if (!entries) {
return notFound;
}
return Object.entries(entries).map(key => `${key[0]}: ${key[1]}`);
};

const findDeep = (targetPath: string, obj?: ContentObject) => {
if (!obj) return null;
if (obj.fullPath === targetPath) return obj.values;
if (!obj.children || obj.children.length === 0) return null;
return findDeep(
targetPath,
obj.children.find(e => targetPath.startsWith(e.fullPath))
);
};

text = text.replaceAll(/#{ivy.cms.co\(|['"]|\)}/g, '');
const entries = findCmsEntries(text, cmsItems);
entries.unshift(text);
return entries.map((entry, i) => {
return (
<span key={i}>
{entry}
<br />
</span>
);
});
};

export const badgeProps = [badgePropertyData, badgePropertyLogic, badgePropertyCMS, badgePropertyExpression];
export const badgeProps = [badgePropertyData, badgePropertyLogic, badgePropertyCMS, badgePropertyBean, badgePropertyExpression];
23 changes: 23 additions & 0 deletions playwright/tests/integration/properties/input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,26 @@ test('cmsQuickfix', async ({ page }) => {
await label.expectValue('Firstname');
await label.expectInputValue("#{ivy.cms.co('/Labels/Firstname')}");
});

test('cmsToolTip', async ({ page }) => {
const editor = await FormEditor.openNewForm(page, { block: 'Input' });
await editor.canvas.blockByNth(0).inscribe();
await editor.inscription.expectHeader('Input');
const properties = editor.inscription.section('Properties');
const section = properties.collapsible('General');
const label = section.input({ label: 'Label' });
const badge = label.outputLocator.locator('.ui-flex').first();

await label.fill("#{ivy.cms.co('/greetings')}");
await label.blur();
await expect(badge).toContainText('greetings');

await badge.hover();
const tooltip = label.outputLocator
.locator('div', { has: page.locator('.ui-tooltip-content') })
.first()
.locator('.ui-tooltip-content')
.first();
await expect(tooltip).toBeVisible({ timeout: 1500 });
await expect(tooltip).toContainText('/greetingsen: Hello World');
});

0 comments on commit f466d81

Please sign in to comment.