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
2 changes: 1 addition & 1 deletion Composer/cypress/integration/Onboarding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ context('Onboarding', () => {

//enable onboarding setting
cy.visitPage('Settings');
cy.findByText('App Settings').click();
cy.findByText('Application Settings').click();
cy.findByLabelText('Onboarding').click();
cy.visitPage('Design');
});
Expand Down
2 changes: 2 additions & 0 deletions Composer/packages/client/src/components/NavTree/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface INavTreeItem {
name: string;
ariaLabel?: string;
url: string;
disabled?: boolean;
}

interface INavTreeProps {
Expand Down Expand Up @@ -54,6 +55,7 @@ const NavTree: React.FC<INavTreeProps> = (props) => {
return (
<DefaultButton
key={item.id}
disabled={item.disabled}
href={item.url}
styles={isSelected ? itemSelected : itemNotSelected}
text={item.name}
Expand Down
41 changes: 30 additions & 11 deletions Composer/packages/client/src/pages/setting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/** @jsx jsx */
import { jsx } from '@emotion/core';
import { useContext, useMemo } from 'react';
import { useContext, useMemo, useEffect } from 'react';
import formatMessage from 'format-message';
import { RouteComponentProps } from '@reach/router';
import { FontIcon } from 'office-ui-fabric-react/lib/Icon';
Expand All @@ -15,26 +15,45 @@ import { OpenConfirmModal } from '../../components/Modal/Confirm';
import { navigateTo } from '../../utils';
import { Page } from '../../components/Page';
import { INavTreeItem } from '../../components/NavTree';
import { useLocation } from '../../utils/hooks';

import Routes from './router';
import { SettingsRoutes } from './router';

const getProjectLink = (path: string, id?: string) => {
return id ? `/settings/bot/${id}/${path}` : `/settings/${path}`;
};

const SettingPage: React.FC<RouteComponentProps<{ '*': string }>> = () => {
const { state, actions } = useContext(StoreContext);
const { projectId } = state;
const makeProjectLink = (id: string, path: string) => {
return `/bot/${id}/settings/${path}`;
};

const { navigate } = useLocation();

// If no project is open and user tries to access a bot-scoped settings (e.g., browser history, deep link)
// Redirect them to the default settings route that is not bot-scoped
useEffect(() => {
if (!projectId && location.pathname.indexOf('/settings/bot/') !== -1) {
navigate('/settings/application');
}
}, [projectId]);

const settingLabels = {
botSettings: formatMessage('Bot Settings'),
appSettings: formatMessage('App Settings'),
appSettings: formatMessage('Application Settings'),
runtime: formatMessage('Runtime Config'),
about: formatMessage('About'),
};

const links: INavTreeItem[] = [
{ id: 'dialog-settings', name: settingLabels.botSettings, url: makeProjectLink(projectId, 'dialog-settings') },
{ id: 'preferences', name: settingLabels.appSettings, url: makeProjectLink(projectId, 'preferences') },
{ id: 'runtime', name: settingLabels.runtime, url: makeProjectLink(projectId, 'runtime') },
{
id: 'dialog-settings',
name: settingLabels.botSettings,
url: getProjectLink('dialog-settings', projectId),
disabled: !projectId,
},
{ id: 'application', name: settingLabels.appSettings, url: getProjectLink('application') },
{ id: 'runtime', name: settingLabels.runtime, url: getProjectLink('runtime', projectId), disabled: !projectId },
{ id: 'about', name: settingLabels.about, url: getProjectLink('about') },

// { key: '/settings/publish', name: settingLabels.publish, url: '' },

Expand Down Expand Up @@ -134,7 +153,7 @@ const SettingPage: React.FC<RouteComponentProps<{ '*': string }>> = () => {
return page.name;
}

return settingLabels.botSettings;
return settingLabels.appSettings;
}, [location.pathname]);

return (
Expand All @@ -145,7 +164,7 @@ const SettingPage: React.FC<RouteComponentProps<{ '*': string }>> = () => {
title={title}
toolbarItems={toolbarItems}
>
<Routes />
<SettingsRoutes projectId={projectId} />
</Page>
);
};
Expand Down
39 changes: 17 additions & 22 deletions Composer/packages/client/src/pages/setting/router.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import * as React from 'react';
import { Router, Redirect } from '@reach/router';

import { ErrorBoundary } from '../../components/ErrorBoundary';
import { About } from '../about';

import { DialogSettings } from './dialog-settings';
import { AppSettings } from './app-settings';
import { RuntimeSettings } from './runtime-settings';

const getRedirect = () => {
const { pathname } = location;

const path = pathname.endsWith('/') ? pathname.substring(0, pathname.length - 1) : pathname;
return `${path}/dialog-settings`;
};

const Routes = () => {
return (
<ErrorBoundary>
<Router>
<Redirect noThrow from="/" to={getRedirect()} />
<DialogSettings default path="dialog-settings" />
<AppSettings path="preferences" />
<RuntimeSettings path="runtime" />
</Router>
</ErrorBoundary>
);
};

export default Routes;
export const SettingsRoutes = React.memo(({ projectId }: { projectId: string }) => (
<ErrorBoundary>
<Router>
<Redirect
noThrow
from="/"
to={projectId ? `/settings/bot/${projectId}/dialog-settings` : '/settings/application'}
/>
<AppSettings default path="application" />
<About path="about" />
<DialogSettings path="/bot/:projectId/dialog-settings" />
<RuntimeSettings path="/bot/:projectId/runtime" />
</Router>
</ErrorBoundary>
));
4 changes: 1 addition & 3 deletions Composer/packages/client/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import React, { useContext, useEffect, Suspense } from 'react';
import { Router, Redirect, RouteComponentProps } from '@reach/router';

import { resolveToBasePath } from './utils/fileUtil';
import { About } from './pages/about';
import { data } from './styles';
import { NotFound } from './components/NotFound';
import { BASEPATH } from './constants';
Expand Down Expand Up @@ -45,17 +44,16 @@ const Routes = (props) => {
<Redirect noThrow from="/" to={resolveToBasePath(BASEPATH, 'home')} />
<ProjectRouter path="/bot/:projectId">
<DesignPage path="dialogs/:dialogId/*" />
<SettingPage path="settings/*" />
<LUPage path="language-understanding/:dialogId/*" />
<LGPage path="language-generation/:dialogId/*" />
<Notifications path="notifications" />
<Publish path="publish/:targetName" />
<Skills path="skills/*" />
<DesignPage path="*" />
</ProjectRouter>
<SettingPage path="settings/*" />
<BotCreationFlowRouter path="projects/*" />
<BotCreationFlowRouter path="home" />
<About path="about" />
<NotFound default />
</Router>
</Suspense>
Expand Down
15 changes: 4 additions & 11 deletions Composer/packages/client/src/utils/pageLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@ export const topLinks = (projectId: string, openedDialogId: string) => {
exact: true,
disabled: !botLoaded,
},
{
to: `/bot/${projectId}/settings/`,
iconName: 'Settings',
labelName: formatMessage('Settings'),
exact: false,
disabled: !botLoaded,
},
];

if (process.env.COMPOSER_AUTH_PROVIDER === 'abs-h') {
Expand All @@ -72,10 +65,10 @@ export const topLinks = (projectId: string, openedDialogId: string) => {

export const bottomLinks = [
{
to: '/about',
iconName: 'info',
labelName: formatMessage('About'),
exact: true,
to: `/settings`,
iconName: 'Settings',
labelName: formatMessage('Settings'),
exact: false,
disabled: false,
},
];