Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: link to tab #1738

Merged
merged 7 commits into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 2 additions & 19 deletions Composer/packages/client/src/pages/notifications/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { NotificationHeader } from './NotificationHeader';
import { root } from './styles';
import { INotification } from './types';
import { navigateTo } from './../../utils';
import { convertDialogDiagnosticToUrl } from './../../utils/navigation';

const navigations = {
lg: (item: INotification) => {
Expand All @@ -24,25 +25,7 @@ const navigations = {
dialog: (item: INotification) => {
//path is like main.trigers[0].actions[0]
//uri = id?selected=triggers[0]&focused=triggers[0].actions[0]
const path = item.diagnostic.path;
let uri = `/dialogs/${item.id}`;
if (path) {
const matchTriggers = /triggers\[(\d+)\]/g.exec(path);
const actionPatt = /actions\[(\d+)\]/g;
let temp: RegExpExecArray | null = null;
let matchActions: RegExpExecArray | null = null;
while ((temp = actionPatt.exec(path)) !== null) {
matchActions = temp;
}
const trigger = matchTriggers ? `triggers[${+matchTriggers[1]}]` : '';
const action = matchActions ? `actions[${+matchActions[1]}]` : '';
if (trigger) {
uri += `?selected=${trigger}`;
if (action) {
uri += `&focused=${trigger}.${action}`;
}
}
}
const uri = convertDialogDiagnosticToUrl(item.diagnostic);
navigateTo(uri);
},
};
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/client/src/utils/dialogUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export function getSelected(focused: string): string {

export function replaceDialogDiagnosticLabel(path?: string): string {
if (!path) return '';
let list = path.split(': ');
let list = path.split('#');
list = list.map(item => {
return ConceptLabels[item]?.title || item;
});
Expand Down
32 changes: 32 additions & 0 deletions Composer/packages/client/src/utils/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import cloneDeep from 'lodash/cloneDeep';
import { navigate, NavigateOptions } from '@reach/router';
import { Diagnostic } from '@bfc/indexers';
import { parsePathToFocused, parsePathToSelected, parseTypeToFragment } from '@bfc/shared';

import { BreadcrumbItem, DesignPageLocation } from '../store/types';

Expand Down Expand Up @@ -76,6 +78,36 @@ interface NavigationState {
breadcrumb: BreadcrumbItem[];
}

export function convertDialogDiagnosticToUrl(diagnostic: Diagnostic): string {
//path is like main.trigers[0].actions[0]
//uri = id?selected=triggers[0]&focused=triggers[0].actions[0]
const { path, source } = diagnostic;
if (!source) return '';

let uri = `/dialogs/${source}`;
if (!path) return uri;

const items = path.split('#');
const sub = items[0];
const type = items[1];
const property = items[2];

const selected = parsePathToSelected(sub);

if (!selected) return uri;
uri += `?selected=${selected}`;

const focused = parsePathToFocused(sub);
if (!focused) return uri;
uri += `&focused=${focused}`;

const fragment = parseTypeToFragment(type, property);
if (!fragment) return uri;
uri += `#${fragment}`;

return uri;
}

export function navigateTo(to: string, navigateOpts: NavigateOptions<NavigationState> = {}) {
const mapNavPath = resolveToBasePath(BASEPATH, to);
navigate(mapNavPath, navigateOpts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const IsExpression: CheckerFunc = (
}
if (message) {
const diagnostic = new Diagnostic(message, '');
diagnostic.path = `${path}: ${value.$type}: ${property}`;
diagnostic.path = `${path}#${value.$type}#${property}`;
result.push(diagnostic);
}
return result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License

import { parsePathToFocused } from '../../src';

describe('parsePathToFocused', () => {
it('should return focusedPath', () => {
expect(parsePathToFocused('')).toBe('');
expect(parsePathToFocused('main.trigers[0].actions[0]')).toBe('trigers[0].actions[0]');
expect(parsePathToFocused('main.trigers[0].actions[0].actions[1]')).toBe('trigers[0].actions[0].actions[1]');
expect(parsePathToFocused('main.trigers[0].actions[0].elseActions[1]')).toBe(
'trigers[0].actions[0].elseActions[1]'
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License

import { parsePathToSelected } from '../../src';

describe('parsePathToSelected', () => {
it('should return selected path', () => {
expect(parsePathToSelected('')).toBe('');
expect(parsePathToSelected('main.triggers[0].actions[0]')).toBe('triggers[0]');
expect(parsePathToSelected('main')).toBe('');
expect(parsePathToSelected('main.triggers[0]')).toBe('triggers[0]');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License

import { parseTypeToFragment, PromptTab } from './../../src';

describe('parseTypeToFragment', () => {
it('should return corrent tab name', () => {
expect(parseTypeToFragment('Microsoft.TextInput', 'unrecognizedPrompt')).toBe(PromptTab.OTHER);
expect(parseTypeToFragment('Microsoft.TextInput', 'property')).toBe(PromptTab.USER_INPUT);
expect(parseTypeToFragment('Microsoft.TextInput', 'prompt')).toBe(PromptTab.BOT_ASKS);
expect(parseTypeToFragment('Microsoft.NumberInput', 'property')).toBe(PromptTab.USER_INPUT);
expect(parseTypeToFragment('Microsoft.LuisRecognizer', 'property')).toBe('');
expect(parseTypeToFragment('test', 'items')).toBe('');
});
});
6 changes: 6 additions & 0 deletions Composer/packages/lib/shared/src/convertUtils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export * from './parsePathToFocused';
export * from './parsePathToSelected';
export * from './parseTypeToFragment';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these meant to be shared in other packages? I would expect these to live in the client.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export function parsePathToFocused(path: string): string {
//path is like main.trigers[0].actions[0]

const list = path.split('.');

if (list.length > 2) {
list.shift();
return list.join('.');
}
return '';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export function parsePathToSelected(path: string): string {
//path is like main.trigers[0].actions[0]

const triggerPattern = /triggers\[(\d+)\]/g;
const matchTriggers = triggerPattern.exec(path);

const trigger = matchTriggers ? `triggers[${+matchTriggers[1]}]` : '';

return trigger;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { dialogGroups, DialogGroup } from '../viewUtils';
import { PromptTab } from '../promptTabs';

export function parseTypeToFragment(type: string, property: string): string {
const inputTypes = dialogGroups[DialogGroup.INPUT].types;
const index = inputTypes.findIndex(t => t === type);
if (index >= 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (index >= 0) {
if (inputTypes.find(t => t === type)) {

if (property === 'property') return PromptTab.USER_INPUT;
if (property === 'prompt') return PromptTab.BOT_ASKS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried about this scaling to all fields. Not sure what to do about it, but we should start thinking on how to handle this.

return PromptTab.OTHER;
}
return '';
}
1 change: 1 addition & 0 deletions Composer/packages/lib/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export * from './promptTabs';
export * from './appschema';
export * from './types';
export * from './constant';
export * from './convertUtils';
export { LgMetaData, LgTemplateRef } from '@bfc/indexers';