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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useRecoilValue } from 'recoil';
import formatMessage from 'format-message';
import { TeachingBubble } from 'office-ui-fabric-react/lib/TeachingBubble';
import { ScrollablePane } from 'office-ui-fabric-react/lib/ScrollablePane';
import { DisplayMarkdownDialog } from '@bfc/ui-shared';

import TelemetryClient from '../../telemetry/TelemetryClient';
import { localBotsDataSelector } from '../../recoilModel/selectors/project';
Expand All @@ -20,6 +21,7 @@ import { rootBotProjectIdSelector } from '../../recoilModel/selectors/project';
import { navigateTo } from '../../utils/navigation';
import { DisableFeatureToolTip } from '../DisableFeatureToolTip';
import { usePVACheck } from '../../hooks/usePVACheck';
import { projectReadmeState } from '../../recoilModel/atoms';

import { GetStartedTask } from './GetStartedTask';
import { NextSteps } from './types';
Expand All @@ -39,6 +41,8 @@ export const GetStartedNextSteps: React.FC<GetStartedProps> = (props) => {
const botProject = useMemo(() => botProjects.find((b) => b.projectId === projectId), [botProjects, projectId]);
const [displayManageLuis, setDisplayManageLuis] = useState<boolean>(false);
const [displayManageQNA, setDisplayManageQNA] = useState<boolean>(false);
const readme = useRecoilValue(projectReadmeState(projectId));
const [readmeHidden, setReadmeHidden] = useState<boolean>(true);

const { setSettings, setQnASettings } = useRecoilValue(dispatcherState);
const rootBotProjectId = useRecoilValue(rootBotProjectIdSelector) || '';
Expand Down Expand Up @@ -98,12 +102,14 @@ export const GetStartedNextSteps: React.FC<GetStartedProps> = (props) => {
const linkToPackageManager = `/bot/${rootBotProjectId}/plugin/package-manager/package-manager`;
const linkToConnections = `/bot/${rootBotProjectId}/botProjectsSettings/#connections`;
const linkToPublishProfile = `/bot/${rootBotProjectId}/publish/all#addNewPublishProfile`;
const linkToCompletePublishProfile = `/bot/${rootBotProjectId}/publish/all#completePublishProfile`;
const linkToLUISSettings = `/bot/${rootBotProjectId}/botProjectsSettings/#luisKey`;
const linktoQNASettings = `/bot/${rootBotProjectId}/botProjectsSettings/#qnaKey`;
const linkToLGEditor = `/bot/${rootBotProjectId}/language-generation`;
const linkToLUEditor = `/bot/${rootBotProjectId}/language-understanding`;
const linkToAppInsights = 'http://aka.ms/botinsights';
const linkToDevOps = 'https://aka.ms/bfcomposercicd';
const linkToReadme = `/bot/${rootBotProjectId}/botProjectsSettings`;

useEffect(() => {
const newNextSteps: NextSteps[] = [];
Expand All @@ -116,6 +122,13 @@ export const GetStartedNextSteps: React.FC<GetStartedProps> = (props) => {
const hasPublishingProfile =
botProject?.setting?.publishTargets && botProject?.setting?.publishTargets?.length > 0 ? true : false;

const hasPartialPublishingProfile =
botProject?.setting?.publishTargets &&
botProject?.setting?.publishTargets?.length == 1 &&
JSON.parse(botProject.setting.publishTargets[0].configuration).hostname == ''
? true
: false;

if (props.requiresLUIS) {
newNextSteps.push({
key: 'luis',
Expand Down Expand Up @@ -164,20 +177,74 @@ export const GetStartedNextSteps: React.FC<GetStartedProps> = (props) => {
newNextSteps[0].highlight();
}

if (readme) {
newRecomendedSteps.push({
key: 'readme',
label: formatMessage('Review your template readme'),
description: formatMessage('Find additional template-specific guidance for setting up your bot.'),
checked: false,
onClick: (step) => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'readme', priority: 'recommended' });
openLink(linkToReadme);
setReadmeHidden(false);
},
isDisabled: false,
});
}
if (!hasPublishingProfile) {
newRecomendedSteps.push({
key: 'publishing',
label: formatMessage('Create a publishing profile'),
description: formatMessage('Set up hosting and other Azure resources to enable publishing'),
required: true,
checked: hasPublishingProfile,
onClick: (step) => {
onClick: () => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'publishing', priority: 'recommended' });
openLink(linkToPublishProfile);
},
isDisabled: false,
});
}
if (hasPartialPublishingProfile) {
newRecomendedSteps.push({
key: 'partialProfile',
label: formatMessage('Complete your publishing profile'),
description: formatMessage(
'Finish setting up your environment and provisionig resources so that you can publish your bot.'
),
checked: hasPublishingProfile && !hasPartialPublishingProfile,
onClick: () => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'partialProfile', priority: 'recommended' });
openLink(linkToCompletePublishProfile);
},
isDisabled: false,
});
}

newRecomendedSteps.push({
key: 'editlg',
label: formatMessage('Edit what your bot says'),
description: formatMessage('Customize your bot by editing and adding bot responses.'),
learnMore: '',
checked: false,
onClick: () => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'editlg', priority: 'recommended' });
openLink(linkToLGEditor);
},
isDisabled: false,
});
newRecomendedSteps.push({
key: 'editlu',
label: formatMessage('Train your language model'),
description: formatMessage('Ensure your bot can understand your users by frequently training your LUIS model.'),
learnMore: '',
checked: false,
onClick: () => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'editlu', priority: 'recommended' });
openLink(linkToLUEditor);
},
isDisabled: false,
});

setRecommendedNextSteps(newRecomendedSteps);

const optSteps = [
Expand All @@ -193,30 +260,6 @@ export const GetStartedNextSteps: React.FC<GetStartedProps> = (props) => {
},
isDisabled: isPVABot,
},
{
key: 'editlg',
label: formatMessage('Edit what your bot says'),
description: formatMessage('Customize your bot by editing and adding bot responses.'),
learnMore: '',
checked: false,
onClick: () => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'editlg', priority: 'optional' });
openLink(linkToLGEditor);
},
isDisabled: false,
},
{
key: 'editlu',
label: formatMessage('Train your language model'),
description: formatMessage('Ensure your bot can understand your users by frequently training your LUIS model.'),
learnMore: '',
checked: false,
onClick: () => {
TelemetryClient.track('GettingStartedActionClicked', { taskName: 'editlu', priority: 'optional' });
openLink(linkToLUEditor);
},
isDisabled: false,
},
{
key: 'insights',
label: formatMessage('Enable Insights'),
Expand Down Expand Up @@ -292,6 +335,14 @@ export const GetStartedNextSteps: React.FC<GetStartedProps> = (props) => {
}}
onToggleVisibility={setDisplayManageQNA}
/>
<DisplayMarkdownDialog
content={readme}
hidden={readmeHidden}
title={formatMessage('Project Readme')}
onDismiss={() => {
setReadmeHidden(true);
}}
/>

{highlightLUIS && (
<TeachingBubble
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const BotProjectInfo: React.FC<RouteComponentProps<{
<DisplayMarkdownDialog
content={readme}
hidden={readmeHidden}
title={'Project Readme'}
title={formatMessage('Project Readme')}
onDismiss={() => {
setReadmeHidden(true);
}}
Expand Down
12 changes: 12 additions & 0 deletions Composer/packages/client/src/pages/botProject/PublishTargets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const editPublishProfile = {

type PublishTargetsProps = {
projectId: string;
completePartial?: boolean;
scrollToSectionId?: string;
};

Expand All @@ -62,6 +63,17 @@ export const PublishTargets: React.FC<PublishTargetsProps> = (props) => {
const publishTargetsRef = React.useRef<HTMLDivElement>(null);
const [current, setCurrent] = useState<{ index: number; item: PublishTarget } | null>(null);

useEffect(() => {
if (props.completePartial && publishTargets && publishTargets.length > 0) {
setCurrent({ item: publishTargets[0], index: 0 });
if (isShowAuthDialog(true)) {
setShowAuthDialog(true);
} else {
setDialogHidden(false);
}
}
}, [props.completePartial, publishTargets]);

useEffect(() => {
if (projectId) {
getPublishTargetTypes(projectId);
Expand Down
6 changes: 5 additions & 1 deletion Composer/packages/client/src/pages/publish/Publish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st
const decoded = props.location?.search ? decodeURIComponent(props.location.search) : '';
const { publishTargetName, url } = querystring.parse(decoded);
const [skillManifestUrl, setSkillManifestUrl] = useState('');
const [completionRequired, setCompletionRequired] = useState<boolean>(false);

useEffect(() => {
if (publishTargetName && botStatusList.length > 0 && skillPublishStatus === SKILL_PUBLISH_STATUS.INITIAL) {
Expand Down Expand Up @@ -277,6 +278,9 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st
useEffect(() => {
if (location.hash === '#addNewPublishProfile') {
setActiveTab('addNewPublishProfile');
} else if (location.hash === '#completePublishProfile') {
setActiveTab('addNewPublishProfile');
setCompletionRequired(true);
}
}, [location]);

Expand Down Expand Up @@ -506,7 +510,7 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st
</Stack.Item>
)}
<Stack.Item align="stretch" styles={{ root: { flexGrow: 1, overflow: 'auto', maxHeight: '100%' } }}>
<PublishTargets projectId={provisionProject} />
<PublishTargets completePartial={completionRequired} projectId={provisionProject} />
</Stack.Item>
</Stack>
</PivotItem>
Expand Down