Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 0 additions & 13 deletions Composer/cypress/integration/ToDoBot.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ context('ToDo Bot', () => {
cy.withinEditor('FormEditor', () => {
cy.getByDisplayValue('AddToDo').should('exist');
});

cy.withinEditor('VisualEditor', () => {
cy.getByText(/Successfully added a todo named/).should('exist');
});
});

it('can open the ClearToDos dialog', () => {
Expand All @@ -40,9 +36,6 @@ context('ToDo Bot', () => {
cy.withinEditor('FormEditor', () => {
cy.getByDisplayValue('ClearToDos').should('exist');
});
cy.withinEditor('VisualEditor', () => {
cy.getByText(/Successfully cleared items/).should('exist');
});
});

it('can open the DeleteToDo dialog', () => {
Expand All @@ -54,9 +47,6 @@ context('ToDo Bot', () => {
cy.withinEditor('FormEditor', () => {
cy.getByDisplayValue('DeleteToDo').should('exist');
});
cy.withinEditor('VisualEditor', () => {
cy.getByText('Edit an Array Property').should('exist');
});
});

it('can open the ShowToDos dialog', () => {
Expand All @@ -68,8 +58,5 @@ context('ToDo Bot', () => {
cy.withinEditor('FormEditor', () => {
cy.getByDisplayValue('ShowToDos').should('exist');
});
cy.withinEditor('VisualEditor', () => {
cy.getByText('You have no todos.').should('exist');
});
});
});
4 changes: 2 additions & 2 deletions Composer/packages/client/src/ShellApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export const ShellApi: React.FC = () => {
if (sourceWindow === VISUAL_EDITOR && dialogId !== '') {
return getDialogData(dialogsMap, dialogId);
} else if (sourceWindow === FORM_EDITOR && focusPath !== '') {
return getDialogData(dialogsMap, dialogId, focused || '');
return getDialogData(dialogsMap, dialogId, focused || selected || '');
}

return '';
Expand All @@ -170,7 +170,7 @@ export const ShellApi: React.FC = () => {
currentDialog,
dialogId,
focusedEvent: selected,
focusedSteps: focused ? [focused] : [],
focusedSteps: focused ? [focused] : selected ? [selected] : [],
};
}

Expand Down
21 changes: 9 additions & 12 deletions Composer/packages/client/src/components/ProjectTree/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React, { useRef, useMemo, useState } from 'react';
import { cloneDeep } from 'lodash';
import {
ActionButton,
GroupedList,
IGroup,
IGroupHeaderProps,
IGroupRenderProps,
IGroupedList,
ActionButton,
IIconProps,
SearchBox,
} from 'office-ui-fabric-react';
import React, { useMemo, useRef, useState } from 'react';
import { cloneDeep } from 'lodash';
import formatMessage from 'format-message';

import { DialogInfo, ITrigger } from '../../store/types';
import { getFriendlyName, createSelectedPath } from '../../utils';
import { createSelectedPath, getFriendlyName } from '../../utils';

import { groupListStyle, addButton, root, searchBox } from './styles';
import { addButton, groupListStyle, root, searchBox } from './styles';
import { TreeItem } from './treeItem';

export function createGroupItem(dialog: DialogInfo, currentId: string, position: number) {
Expand Down Expand Up @@ -103,19 +103,16 @@ export const ProjectTree: React.FC<IProjectTreeProps> = props => {

const onRenderHeader = (props: IGroupHeaderProps) => {
const toggleCollapse = (): void => {
if (groupRef.current && props.group) {
groupRef.current.toggleCollapseAll(true);
props.onToggleCollapse!(props.group);
if (dialogId !== props.group.key) {
onSelect(props.group.key);
}
}
groupRef.current!.toggleCollapseAll(true);
props.onToggleCollapse!(props.group!);
onSelect(props.group!.key);
};
return (
<TreeItem
link={props.group!.data}
depth={0}
isActive={!props.group!.isCollapsed}
isSubItemActive={!!selected}
onSelect={toggleCollapse}
onDelete={onDeleteDialog}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export const root = css`
overflow-y: auto;
`;

export const navItem = (isActive: boolean, depth: number) => css`
export const navItem = (isActive: boolean, isSubItemActive: boolean) => css`
width: 100%;
position: relative;
font-size: 12px;
color: #605e5c;
background: ${isActive && depth !== 0 ? '#f2f2f2' : 'transparent'};
background: ${isActive && !isSubItemActive ? '#f2f2f2' : 'transparent'};
font-weight: ${isActive ? FontWeights.semibold : FontWeights.regular};
&: hover {
color: #605e5c;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ const onRenderOverflowButton = overflowItems => {
};

export const TreeItem = props => {
const { link, isActive, depth, onDelete, onSelect } = props;
const { link, isActive, isSubItemActive, depth, onDelete, onSelect } = props;
return (
<div
tabIndex={1}
css={navItem(isActive, depth)}
css={navItem(isActive, isSubItemActive)}
onClick={() => {
onSelect(link.id);
}}
Expand Down
72 changes: 42 additions & 30 deletions Composer/packages/client/src/pages/design/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,33 @@ import { toLower, get } from 'lodash';
import { VisualEditorAPI } from '../../messenger/FrameAPI';
import { TestController } from '../../TestController';
import { BASEPATH, DialogDeleting } from '../../constants';
import { getbreadcrumbLabel, deleteTrigger, createSelectedPath } from '../../utils';
import { createSelectedPath, deleteTrigger, getbreadcrumbLabel } from '../../utils';
import { TriggerCreationModal } from '../../components/ProjectTree/TriggerCreationModal';

import { Conversation } from './../../components/Conversation';
import { DialogStyle } from './../../components/Modal/styles';
import NewDialogModal from './new-dialog-modal';
import { OpenConfirmModal } from './../../components/Modal/Confirm';
import { ProjectTree } from './../../components/ProjectTree';
import { StoreContext } from './../../store';
import { ToolBar } from './../../components/ToolBar/index';
import { clearBreadcrumb } from './../../utils/navigation';
import { getNewDesigner } from './../../utils/dialogUtil';
import undoHistory from './../../store/middlewares/undo/history';
import {
pageRoot,
contentWrapper,
breadcrumbClass,
contentWrapper,
deleteDialogContent,
editorContainer,
visualPanel,
visualEditor,
formEditor,
editorWrapper,
deleteDialogContent,
formEditor,
middleTriggerContainer,
middleTriggerElements,
pageRoot,
triggerButton,
visualEditor,
visualPanel,
} from './styles';
import NewDialogModal from './new-dialog-modal';
import { ToolBar } from './../../components/ToolBar/index';
import { OpenConfirmModal } from './../../components/Modal/Confirm';
import { DialogStyle } from './../../components/Modal/styles';
import { clearBreadcrumb } from './../../utils/navigation';
import undoHistory from './../../store/middlewares/undo/history';
import { getNewDesigner } from './../../utils/dialogUtil';

const addIconProps = {
iconName: 'CircleAddition',
Expand All @@ -59,6 +59,32 @@ function onRenderBreadcrumbItem(item, render) {
);
}

function onRenderBlankVisual(isTriggerEmpty, onClickAddTrigger) {
return (
<div css={middleTriggerContainer}>
<div css={middleTriggerElements}>
{isTriggerEmpty ? (
<Fragment>
{formatMessage(`This dialog has no trigger yet.`)}
<ActionButton
data-testid="MiddleAddNewTriggerButton"
iconProps={addIconProps}
css={triggerButton}
onClick={onClickAddTrigger}
>
{formatMessage('New Trigger ..')}
</ActionButton>
</Fragment>
) : (
<div>
{formatMessage('Select a trigger on the left')} <br /> {formatMessage('navigation to see actions')}
</div>
)}
</div>
</div>
);
}

function getAllRef(targetId, dialogs) {
let refs = [];
dialogs.forEach(dialog => {
Expand Down Expand Up @@ -338,24 +364,10 @@ function DesignPage(props) {
key="VisualEditor"
name="VisualEditor"
css={visualEditor}
hidden={triggerButtonVisible}
hidden={triggerButtonVisible || !selected}
src={`${rootPath}/extensionContainer.html`}
/>
{triggerButtonVisible && (
<div css={middleTriggerContainer}>
<div css={middleTriggerElements}>
{formatMessage(`This dialog has no triggers configured`)}
<ActionButton
data-testid="MiddleAddNewTriggerButton"
iconProps={addIconProps}
css={triggerButton}
onClick={openNewTriggerModal}
>
{formatMessage('New Trigger ..')}
</ActionButton>
</div>
</div>
)}
{!selected && onRenderBlankVisual(triggerButtonVisible, openNewTriggerModal)}
</div>
<iframe
key="FormEditor"
Expand Down
3 changes: 3 additions & 0 deletions Composer/packages/client/src/pages/design/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ export const middleTriggerElements = css`
display: flex;
flex-direction: column;
align-items: center;
font-size: 18px;
line-height: 24px;
color: #828282;
`;

export const triggerButton = css`
Expand Down
12 changes: 2 additions & 10 deletions Composer/packages/client/src/store/action/navigation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSelectedPath, getSelected } from '../../utils';
import { getSelected } from '../../utils';

import { ActionCreator } from './../types';
import { ActionTypes } from './../../constants';
Expand All @@ -16,15 +16,7 @@ export const setDesignPageLocation: ActionCreator = (

export const navTo: ActionCreator = ({ getState }, dialogId, breadcrumb = []) => {
const state = getState();
const { dialogs } = state;
let currentUri = `/dialogs/${dialogId}`;

const dialog = dialogs.find(item => dialogId === item.id);
if (dialog && dialog.triggers.length > 0) {
currentUri = `${currentUri}?selected=${createSelectedPath(0)}`;

breadcrumb = [...breadcrumb, { dialogId, selected: '', focused: '' }];
}
const currentUri = `/dialogs/${dialogId}`;

if (checkUrl(currentUri, state.designPageLocation)) return;
navigateTo(currentUri, { state: { breadcrumb } });
Expand Down
13 changes: 5 additions & 8 deletions Composer/packages/client/src/store/reducer/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { get, set } from 'lodash';

import { ReducerFunc, DialogSetting } from '../types';
import { getExtension, createSelectedPath } from '../../utils';
import { ActionTypes, FileTypes, SensitiveProperties } from '../../constants';
import settingStorage from '../../utils/dialogSettingStorage';
import { DialogSetting, ReducerFunc } from '../types';
import { UserTokenPayload } from '../action/types';
import { getExtension } from '../../utils';
import settingStorage from '../../utils/dialogSettingStorage';

import createReducer from './createReducer';

Expand Down Expand Up @@ -154,16 +154,13 @@ const setDesignPageLocation: ReducerFunc = (state, { dialogId, selected, focused
state.focusPath = dialogId + '#';
if (focused) {
state.focusPath = dialogId + '#.' + focused;
} else if (selected) {
state.focusPath = dialogId + '#.' + selected;
}

//add current path to the breadcrumb
breadcrumb.push({ dialogId, selected, focused });

//if use navigateto to design page, add events[0] for default select
if (!selected) {
selected = createSelectedPath(0);
breadcrumb = [...breadcrumb, { dialogId, selected, focused }];
}
state.breadcrumb = breadcrumb;
state.designPageLocation = { dialogId, selected, focused };
return state;
Expand Down
19 changes: 13 additions & 6 deletions Composer/packages/client/src/utils/dialogUtil.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { get, set, cloneDeep } from 'lodash';
import { ConceptLabels, seedNewDialog, dialogGroups, DialogGroup, SDKTypes } from 'shared-menus';
import { ConceptLabels, DialogGroup, SDKTypes, dialogGroups, seedNewDialog } from 'shared-menus';
import { cloneDeep, get, set } from 'lodash';
import { ExpressionEngine } from 'botbuilder-expression-parser';
import nanoid from 'nanoid/generate';
import { IDropdownOption } from 'office-ui-fabric-react';
import nanoid from 'nanoid/generate';

import { DialogInfo } from '../store/types';

import { upperCaseName } from './fileUtil';
import { getFocusPath } from './navigation';
import { upperCaseName } from './fileUtil';

const ExpressionParser = new ExpressionEngine();

interface DialogsMap {
Expand Down Expand Up @@ -42,7 +43,7 @@ export function getFriendlyName(data) {
}

if (get(data, 'intent')) {
return `#${get(data, 'intent')}`;
return `${get(data, 'intent')}`;
}

if (ConceptLabels[data.$type] && ConceptLabels[data.$type].title) {
Expand All @@ -55,7 +56,13 @@ export function getFriendlyName(data) {
export function getNewDesigner(name: string, description: string) {
const timestamp = new Date().toISOString();
return {
$designer: { name, description, createdAt: timestamp, updatedAt: timestamp, id: nanoid('1234567890', 6) },
$designer: {
name,
description,
createdAt: timestamp,
updatedAt: timestamp,
id: nanoid('1234567890', 6),
},
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';

import { ConceptLabels } from 'shared-menus';
import { jsx } from '@emotion/core';

import { TriggerSize } from '../../constants/ElementSizes';
import { AttrNames } from '../../constants/ElementAttributes';
import { ElementIcon } from '../../utils/obiPropertyResolver';
import { TriggerSize } from '../../constants/ElementSizes';

import { FormCard } from './templates/FormCard';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { has, uniq } from 'lodash';

import { Path } from '../../../utility/path';
import { JsonWalk, VisitorFunc } from '../../../utility/jsonWalk';
import { DialogChecker } from '../dialogChecker';
import { Path } from '../../../utility/path';

import { FileInfo, Dialog, ITrigger } from './../interface';
import { Dialog, FileInfo, ITrigger } from './../interface';

export class DialogIndexer {
public dialogs: Dialog[] = [];
Expand Down Expand Up @@ -116,9 +116,6 @@ export class DialogIndexer {
trigger.displayName = rule.intent;
}

if (trigger.isIntent && trigger.displayName) {
trigger.displayName = '#' + trigger.displayName;
}
trigers.push(trigger);
}
});
Expand Down