Skip to content

Commit

Permalink
@W-13900452: support Guidance Panel in layout.json
Browse files Browse the repository at this point in the history
* Add lint and editor support for GuidancePanel object in layout schema
* Add schema-based validation and tests for guidance panel properties
* Add code-completion, default snippets, and hover text on guidance panel json fields and tests
* Refactor backgroundImage to be used by regular panel and guidance panel
* Add support for linkbox item in regular panel items and groupbox items as well as tests
  • Loading branch information
xshenwork authored Sep 11, 2023
1 parent e0232ca commit 883a7b7
Show file tree
Hide file tree
Showing 10 changed files with 559 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ describe('layout-schema.json hookup', () => {
{ type: 'Variable', expected: ['name'] },
{ type: 'Image', expected: ['image'] },
{ type: 'Text', expected: ['text'] },
{ type: 'LinkBox', expected: ['text', 'url', 'title', 'icon'] },
{ type: 'GroupBox', expected: ['text', 'description', 'items'] }
].forEach(({ type, expected }) => {
it(type, async () => {
Expand All @@ -85,9 +86,9 @@ describe('layout-schema.json hookup', () => {
);
await waitForDiagnostics(
layoutEditor.document.uri,
// there should be the 'error' error and one about the missing item field
// there should be the 'error' error and one about the missing required item field/property
d => d && d.length >= 2,
'initial errors on layout.json'
'initial errors on layout.json. There should be at least two diagnotics found.'
);

const tree = parseTree(layoutEditor.document.getText());
Expand All @@ -100,4 +101,59 @@ describe('layout-schema.json hookup', () => {
});
});
});

describe('has correct code completions for guidance panel item type', () => {
async function createTemplateWithItemType(type: string) {
const initialJson: any = {
error: 'This should cause a schema error to look for',
pages: [
{
title: '',
layout: {
type: 'SingleColumn',
center: {
items: []
}
},
guidancePanel: {
title: 'Guidance Panel Title',
items: [{ type }]
}
}
]
};
return createTemplateWithLayout(initialJson);
}

// make sure the doNotSuggest logic in layout-schema.json for the type-specific fields in guidance panel items works
[
// these types should see some available completions in the item
{ type: 'Image', expected: ['image'] },
{ type: 'Text', expected: ['text'] },
{ type: 'LinkBox', expected: ['text', 'url', 'title', 'icon'] }
].forEach(({ type, expected }) => {
it(type, async () => {
const layoutEditor = await createTemplateWithItemType(type);
await waitFor(
() => layoutEditor.document.languageId,
lang => lang === TEMPLATE_JSON_LANG_ID,
{ timeoutMessage: 'timeout waiting for layout.json languageId' }
);
await waitForDiagnostics(
layoutEditor.document.uri,
// there should be the 'error' error and one about the missing required item field/property
d => d && d.length >= 2,
'initial errors on layout.json. There should be at least two diagnotics found.'
);

const tree = parseTree(layoutEditor.document.getText());
// find the variableType {} in the json
const typeNode = tree && findNodeAtLocation(tree, ['pages', 0, 'guidancePanel', 'items', 0, 'type']);
expect(typeNode, 'name').to.not.be.undefined;
// go right at the start of the item's json (just before "type": "...")
const position = layoutEditor.document.positionAt(typeNode!.parent!.offset + 1);
await verifyCompletionsContain(layoutEditor.document, position, ...expected);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('TemplateEditorManager configures layoutDefinition', () => {
// this should be right the opening '{'
position = doc.positionAt(node!.offset).translate({ characterDelta: 1 });
// make sure it has the fields from the schema that aren't in the document
await verifyCompletionsContain(doc, position, 'condition', 'helpUrl', 'backgroundImage');
await verifyCompletionsContain(doc, position, 'condition', 'helpUrl', 'backgroundImage', 'guidancePanel');

// find the start of the first page layout
node = findNodeAtLocation(tree!, ['pages', 0, 'layout']);
Expand All @@ -98,6 +98,22 @@ describe('TemplateEditorManager configures layoutDefinition', () => {
position = doc.positionAt(node!.offset).translate({ characterDelta: 1 });
// make sure it has the fields from the schema that aren't in the document
await verifyCompletionsContain(doc, position, 'header');

// find the start of the second page guidance panel
node = findNodeAtLocation(tree!, ['pages', 1, 'guidancePanel']);
expect(node, 'pages[1].guidancePanel').to.not.be.undefined;
// this should be right the opening '{'
position = doc.positionAt(node!.offset).translate({ characterDelta: 1 });
// make sure it has the fields from the schema that aren't in the document
await verifyCompletionsContain(doc, position, 'backgroundImage');

// find the start of the app details page
node = findNodeAtLocation(tree!, ['appDetails']);
expect(node, 'appDetails').to.not.be.undefined;
// this should be right the opening '{'
position = doc.positionAt(node!.offset).translate({ characterDelta: 1 });
// make sure it has the fields from the schema that aren't in the document
await verifyCompletionsContain(doc, position, 'guidancePanel', 'navigation');
});

it('json-schema defaultSnippets', async () => {
Expand Down Expand Up @@ -143,7 +159,8 @@ describe('TemplateEditorManager configures layoutDefinition', () => {
'New Image item',
'New Text item',
'New Variable item',
'New Groupbox item'
'New GroupBox item',
'New LinkBox item'
);

// go to just after the [ in items[3] (a GroupBox item type) "items"
Expand All @@ -154,7 +171,14 @@ describe('TemplateEditorManager configures layoutDefinition', () => {
expect.fail("Expected to find '[' after '\"items[3].items\":'");
}
position = scan.end.translate({ characterDelta: 1 });
await verifyCompletionsContain(doc, position, 'New Image item', 'New Text item', 'New Variable item');
await verifyCompletionsContain(
doc,
position,
'New Image item',
'New Text item',
'New Variable item',
'New LinkBox item'
);

// go right after the [ in "displayMessages"
node = findNodeAtLocation(tree!, ['displayMessages']);
Expand All @@ -165,6 +189,36 @@ describe('TemplateEditorManager configures layoutDefinition', () => {
}
position = scan.end.translate({ characterDelta: 1 });
await verifyCompletionsContain(doc, position, 'New displayMessage');

// go to just before the { in "guidancePanel" on page 2
node = findNodeAtLocation(tree!, ['pages', 1, 'guidancePanel']);
expect(node, 'pages[1].guidancePanel').to.not.be.undefined;
scan = scanLinesUntil(doc, ch => ch === '{', doc.positionAt(node!.offset));
if (scan.ch !== '{') {
expect.fail("Expected to find '{' after '\"guidancePanel\":'");
}
position = scan.end.translate({ characterDelta: -1 });
await verifyCompletionsContain(doc, position, 'New guidance panel');

// go to just after the [ in "guidancePanel.items"
node = findNodeAtLocation(tree!, ['pages', 1, 'guidancePanel', 'items']);
expect(node, 'pages[1].guidancePanel.items').to.not.be.undefined;
scan = scanLinesUntil(doc, ch => ch === '[', doc.positionAt(node!.offset));
if (scan.ch !== '[') {
expect.fail("Expected to find '[' after '\"items\":'");
}
position = scan.end.translate({ characterDelta: 1 });
await verifyCompletionsContain(doc, position, 'New Image item', 'New Text item', 'New LinkBox item');

// go to just before the { in "guidancePanel.backgroundImage" on page 3
node = findNodeAtLocation(tree!, ['pages', 2, 'guidancePanel', 'backgroundImage']);
expect(node, 'pages[2].guidancePanel.backgroundImage').to.not.be.undefined;
scan = scanLinesUntil(doc, ch => ch === '{', doc.positionAt(node!.offset));
if (scan.ch !== '{') {
expect.fail("Expected to find '{' after '\"pages[2].guidancePanel.backgroundImage\":'");
}
position = scan.end.translate({ characterDelta: -1 });
await verifyCompletionsContain(doc, position, 'New background image', 'null');
});

it('on change of path value', async () => {
Expand Down
Loading

0 comments on commit 883a7b7

Please sign in to comment.