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 3 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
adddaa2
move provisionig readme into scripts folder so that main package read…
benbrown Mar 29, 2021
620c8fb
Read in and display a readme.md file for the project
benbrown Mar 29, 2021
1be5eb0
Merge branch 'main' into benbrown/readmes
benbrown Mar 29, 2021
c5788b2
remove errant constant
benbrown Mar 29, 2021
6f3d46a
Merge branch 'main' of https://github.com/microsoft/BotFramework-Comp…
benbrown Mar 29, 2021
fd85954
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
benbrown Mar 29, 2021
415bda8
adding bot project tab view
pavolumMsft Apr 1, 2021
a9411c4
Updating botProjectInfo
pavolumMsft Apr 1, 2021
b3e0ea2
Adding support for deep linking into settings page
pavolumMsft Apr 1, 2021
83d3336
Merging latest form main and resolving conflict
pavolumMsft Apr 1, 2021
d4f6571
Main merge clean up
pavolumMsft Apr 1, 2021
7062fc9
Fixing skills settings dependency
pavolumMsft Apr 1, 2021
7bab94a
Adding bottons for luis and qna provision in settings page
pavolumMsft Apr 1, 2021
a15430a
Updating setting after qna and luis provisioning
pavolumMsft Apr 1, 2021
6ad4e83
Merge branch 'main' into benbrown/readmes
pavolum Apr 1, 2021
a388c4e
Naming changes for readme modal
pavolumMsft Apr 1, 2021
3bf7cfa
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
pavolumMsft Apr 1, 2021
6bfcdf5
removing unused isBack option
pavolumMsft Apr 1, 2021
b2f243e
address feedback
benbrown Apr 1, 2021
3821132
Adding formatMesage
pavolumMsft Apr 1, 2021
b679759
Removing unused ref
pavolumMsft Apr 1, 2021
cbc2cc3
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
benbrown Apr 1, 2021
77ed140
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
benbrown Apr 1, 2021
ac01860
Temp remove template tag and text
pavolumMsft Apr 1, 2021
7aa06a7
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
pavolumMsft Apr 1, 2021
4b61a62
Removing unused variables and deps
pavolumMsft Apr 2, 2021
6858230
removing unsed imports
pavolumMsft Apr 2, 2021
3f02de5
Resolving merge conflicts
pavolumMsft Apr 2, 2021
17cb268
Adding testIds to tabs in settings page and updating broken integrati…
pavolumMsft Apr 2, 2021
c86c43c
Merge branch 'main' into benbrown/readmes
pavolum Apr 2, 2021
80d219d
Fixing Luis deploy test to work with tab experience
pavolumMsft Apr 3, 2021
a80a2e4
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
pavolumMsft Apr 3, 2021
1dbdf31
Merging and resolving conflicts
pavolumMsft Apr 5, 2021
9b7bba9
Fixing import in test
pavolumMsft Apr 5, 2021
9fefd80
Fixing header unit test
pavolumMsft Apr 5, 2021
182ad9f
Merge branch 'main' into benbrown/readmes
pavolum Apr 5, 2021
ac28eb2
use iconUrl field instead of icon. Fix for https://github.com/microso…
benbrown Apr 5, 2021
b426df2
Merge branch 'main' into benbrown/readmes
beyackle Apr 5, 2021
7376c45
read in icon and include it as a data url
benbrown Apr 5, 2021
90f0909
Merge branch 'benbrown/fixicon' into benbrown/readmes
benbrown Apr 5, 2021
8322ca4
Merge branch 'main' of https://github.com/microsoft/BotFramework-Comp…
benbrown Apr 5, 2021
2f13e3c
Merge branch 'benbrown/readmes' of https://github.com/microsoft/BotFr…
benbrown Apr 5, 2021
ebb499a
Merge branch 'main' into benbrown/readmes
pavolum Apr 5, 2021
03bfbdf
Simplyfing array inclusion check
pavolumMsft Apr 5, 2021
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
65 changes: 65 additions & 0 deletions Composer/packages/client/src/pages/botProject/BotProjectInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

/** @jsx jsx */
import { jsx } from '@emotion/core';
import { useRecoilValue } from 'recoil';
import React, { useState, Fragment } from 'react';
import { RouteComponentProps } from '@reach/router';
import { DisplayReadme } from '@bfc/ui-shared';
import formatMessage from 'format-message';
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';

import { readmeState, locationState } from '../../recoilModel/atoms';
import { localBotsDataSelector } from '../../recoilModel/selectors/project';

export const BotProjectInfo: React.FC<RouteComponentProps<{
projectId: string;
}>> = (props) => {
const { projectId = '' } = props;
const botProjects = useRecoilValue(localBotsDataSelector);
const botProject = botProjects.find((b) => b.projectId === projectId);
const readme = useRecoilValue(readmeState(projectId));
const location = useRecoilValue(locationState(projectId));
const [readmeHidden, setReadmeHidden] = useState<boolean>(true);

return (
<div>
<h1>{botProject?.name}</h1>
<p>
{formatMessage('File Location:')}
<span
style={{
display: 'inline-block',
overflowWrap: 'break-word',
maxWidth: '100%',
fontSize: 12,
}}
>
{location}
</span>
</p>
{readme && (
<Fragment>
<DefaultButton
onClick={() => {
setReadmeHidden(false);
}}
>
{formatMessage('View project readme')}
</DefaultButton>
<DisplayReadme
hidden={readmeHidden}
readme={readme}
title={'Project Readme'}
onDismiss={() => {
setReadmeHidden(true);
}}
/>
</Fragment>
)}
</div>
);
};

export default BotProjectInfo;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { RouteComponentProps } from '@reach/router';
import { localBotsDataSelector } from '../../recoilModel/selectors/project';
import { useFeatureFlag } from '../../utils/hooks';

import { BotProjectInfo } from './BotProjectInfo';
import { SkillHostEndPoint } from './SkillHostEndPoint';
import { AppIdAndPassword } from './AppIdAndPassword';
import { ExternalService } from './ExternalService';
Expand Down Expand Up @@ -47,6 +48,7 @@ export const BotProjectSettingsTableView: React.FC<RouteComponentProps<{

return (
<div css={container}>
<BotProjectInfo projectId={projectId} />
{isRootBot && <SkillHostEndPoint projectId={projectId} />}
<AppIdAndPassword projectId={projectId} />
<ExternalService projectId={projectId} scrollToSectionId={scrollToSectionId} />
Expand Down
7 changes: 7 additions & 0 deletions Composer/packages/client/src/recoilModel/atoms/botState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ export const locationState = atomFamily<string, string>({
},
});

export const readmeState = atomFamily<string, string>({
Comment thread
pavolum marked this conversation as resolved.
Outdated
key: getFullyQualifiedKey('readme'),
default: (id) => {
return '';
},
});

export const botEnvironmentState = atomFamily<string, string>({
key: getFullyQualifiedKey('botEnvironment'),
default: (id) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
botProjectIdsState,
botProjectSpaceLoadedState,
botStatusState,
readmeState,
currentProjectIdState,
dialogSchemasState,
dialogState,
Expand Down Expand Up @@ -433,7 +434,7 @@ export const initQnaFilesStatus = (projectId: string, qnaFiles: QnAFile[], dialo

export const initBotState = async (callbackHelpers: CallbackInterface, data: any, botFiles: any) => {
const { set } = callbackHelpers;
const { botName, botEnvironment, location, schemas, settings, id: projectId, diagnostics } = data;
const { botName, botEnvironment, location, readme, schemas, settings, id: projectId, diagnostics } = data;
const {
dialogs,
dialogSchemas,
Expand Down Expand Up @@ -500,6 +501,7 @@ export const initBotState = async (callbackHelpers: CallbackInterface, data: any
set(botDiagnosticsState(projectId), diagnostics);
refreshLocalStorage(projectId, settings);
set(settingsState(projectId), mergedSettings);
set(readmeState(projectId), readme);

set(filePersistenceState(projectId), new FilePersistence(projectId));
set(undoHistoryState(projectId), new UndoHistory(projectId));
Expand Down
1 change: 1 addition & 0 deletions Composer/packages/lib/ui-shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dependencies": {
"@emotion/core": "^10.0.27",
"@emotion/styled": "^10.0.27",
"react-markdown": "^5.0.3",
"office-ui-fabric-react": "7.71.0"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation.
Comment thread
pavolum marked this conversation as resolved.
// Licensed under the MIT License.

/** @jsx jsx */
import { jsx } from '@emotion/core';
import { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';
import { ScrollablePane } from 'office-ui-fabric-react/lib/ScrollablePane';
import formatMessage from 'format-message';
import ReactMarkdown from 'react-markdown';

import { DialogTypes, DialogWrapper } from '../DialogWrapper';

type DisplayReadmeProps = {
title: string;
readme: string;
Comment thread
pavolum marked this conversation as resolved.
Outdated
hidden: boolean;
onBack?: () => void;
Comment thread
pavolum marked this conversation as resolved.
Outdated
onDismiss: () => void;
};

export const DisplayReadme = (props: DisplayReadmeProps) => {
return (
<DialogWrapper
dialogType={DialogTypes.CreateFlow}
isOpen={!props.hidden}
title={props.title}
onDismiss={props.onDismiss}
>
<div css={{ height: 500, position: 'relative', border: '1px solid #333' }}>
<ScrollablePane>
<ReactMarkdown css={{ padding: 20 }} linkTarget="_blank">
{props.readme}
</ReactMarkdown>
</ScrollablePane>
</div>
<DialogFooter>
{props.onBack && <DefaultButton text={formatMessage('Back')} onClick={props.onBack} />}
<PrimaryButton text={formatMessage('Okay')} onClick={props.onDismiss} />
Comment thread
pavolum marked this conversation as resolved.
Outdated
</DialogFooter>
</DialogWrapper>
);
};
1 change: 1 addition & 0 deletions Composer/packages/lib/ui-shared/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './LoadingSpinner';
export * from './ConfirmDialog';
export * from './PropertyAssignment';
export * from './Toolbar';
export * from './DisplayReadme/DisplayReadme';
3 changes: 3 additions & 0 deletions Composer/packages/server/src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -3635,6 +3635,9 @@
"view_on_npm_2051324d": {
"message": "View on npm"
},
"view_project_readme_ff079d2e": {
"message": "View project readme"
},
"vishwac_sena_45910bf0": {
"message": "Vishwac Sena"
},
Expand Down
17 changes: 17 additions & 0 deletions Composer/packages/server/src/models/bot/botProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export class BotProject implements IBotProject {
public id: string | undefined;
public name: string;
public dir: string;
public readme: string;
public dataDir: string;
public eTag?: string;
public fileStorage: IFileStorage;
Expand Down Expand Up @@ -83,6 +84,7 @@ export class BotProject implements IBotProject {
this.settingManager = new DefaultSettingManager(this.dir);
this.fileStorage = StorageService.getStorageClient(this.ref.storageId, user);
this.builder = new Builder(this.dir, this.fileStorage, defaultLanguage);
this.readme = '';
}

public get dialogFiles() {
Expand Down Expand Up @@ -181,12 +183,14 @@ export class BotProject implements IBotProject {
this.diagnostics = [];
this.settings = await this.getEnvSettings(false);
this.files = await this._getFiles();
this.readme = await this._getReadme();
};

public getProject = () => {
return {
botName: this.name,
files: Array.from(this.files.values()),
readme: this.readme,
location: this.dir,
schemas: this.getSchemas(),
diagnostics: this.diagnostics,
Expand Down Expand Up @@ -773,6 +777,19 @@ export class BotProject implements IBotProject {
}
};

private _getReadme = async (): Promise<string> => {
const variants = ['readme.md', 'README.md', 'README.MD'];

for (const v in variants) {
const readmePath = Path.join(this.dir, variants[v]);
if (await this.fileStorage.exists(readmePath)) {
return await this.fileStorage.readFile(readmePath);
}
}

return '';
};

private _getFiles = async () => {
if (!(await this.exists())) {
throw new Error(`${this.dir} is not a valid path`);
Expand Down
1 change: 1 addition & 0 deletions extensions/packageManager/src/components/LibraryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface LibraryRef {
language: string;
source?: string;
isCompatible?: boolean;
readme?: string;
}

export interface ILibraryListProps {
Expand Down
28 changes: 25 additions & 3 deletions extensions/packageManager/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the MIT License.

import * as path from 'path';
import * as fs from 'fs';
import { DH_CHECK_P_NOT_SAFE_PRIME } from 'constants';
Comment thread
benbrown marked this conversation as resolved.
Outdated

import axios from 'axios';
import { IExtensionRegistration } from '@botframework-composer/types';
Expand All @@ -26,6 +28,26 @@ const isAdaptiveComponent = (c) => {
return hasSchema(c) || c.includesExports;
};

const loadReadme = async (components) => {
const variants = ['readme.md', 'README.md', 'README.MD'];
for (const c in components) {
if (components[c].path) {
const rootFolder = path.dirname(components[c].path);
for (const v in variants) {
const readmePath = path.join(rootFolder, variants[v]);
// eslint-disable-next-line security/detect-non-literal-fs-filename
if (fs.existsSync(readmePath)) {
// eslint-disable-next-line security/detect-non-literal-fs-filename
components[c].readme = fs.readFileSync(readmePath, 'utf-8');
Comment thread
pavolum marked this conversation as resolved.
Outdated
continue;
}
}
}
}

return components;
};

export default async (composer: IExtensionRegistration): Promise<void> => {
const updateRecentlyUsed = (componentList, runtimeLanguage) => {
const recentlyUsed = (composer.store.read('recentlyUsed') as any[]) || [];
Expand Down Expand Up @@ -216,7 +238,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
if (dryRunMergeResults) {
res.json({
projectId,
components: dryRunMergeResults.components.filter(isAdaptiveComponent),
components: await loadReadme(dryRunMergeResults.components.filter(isAdaptiveComponent)),
});
} else {
res.status(500).json({
Expand Down Expand Up @@ -304,7 +326,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
);

const mergeResults = await realMerge.merge();
const installedComponents = mergeResults.components.filter(isAdaptiveComponent);
const installedComponents = await loadReadme(mergeResults.components.filter(isAdaptiveComponent));
if (mergeResults) {
res.json({
success: true,
Expand Down Expand Up @@ -406,7 +428,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {

res.json({
success: true,
components: mergeResults.components.filter(isAdaptiveComponent),
components: await loadReadme(mergeResults.components.filter(isAdaptiveComponent)),
});

// update the settings.plugins array
Expand Down
33 changes: 32 additions & 1 deletion extensions/packageManager/src/pages/Library.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
useTelemetryClient,
TelemetryClient,
} from '@bfc/extension-client';
import { Toolbar, IToolbarItem, LoadingSpinner } from '@bfc/ui-shared';
import { Toolbar, IToolbarItem, LoadingSpinner, DisplayReadme } from '@bfc/ui-shared';
import ReactMarkdown from 'react-markdown';

import { ContentHeaderStyle, HeaderText } from '../components/styles';
Expand Down Expand Up @@ -78,6 +78,7 @@ const Library: React.FC = () => {
const [readmeContent, setReadmeContent] = useState<string>('');
const [versionOptions, setVersionOptions] = useState<IContextualMenuProps | undefined>(undefined);
const [isUpdate, setIsUpdate] = useState<boolean>(false);
const [readmeHidden, setReadmeHidden] = useState<boolean>(true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This may be my personal opinion here, but I find confusing when the variable value and the thing being hidden/shown matches. (not sure how to word this) So I would suggest something like const [showReadme] = useState(false) instead.

const httpClient = useHttpClient();
const API_ROOT = '';
const TABS = {
Expand Down Expand Up @@ -399,6 +400,14 @@ const Library: React.FC = () => {
setWorking('');
updateInstalledComponents(results.data.components);

// find newly installed item
// and pop up the readme if one exists.
const newItem = results.data.components.find((i) => i.name === packageName);
if (newItem?.readme) {
setSelectedItem(newItem);
setReadmeHidden(false);
}

// reload modified content
await reloadProject();
}
Expand Down Expand Up @@ -571,6 +580,16 @@ const Library: React.FC = () => {
hidden={!isModalVisible}
onUpdateFeed={updateFeed}
/>
{selectedItem && (
<DisplayReadme
hidden={readmeHidden}
readme={selectedItem?.readme}
title={'Project Readme'}
onDismiss={() => {
setReadmeHidden(true);
}}
/>
)}
<Toolbar toolbarItems={toolbarItems} />
<div css={ContentHeaderStyle}>
<h1 css={HeaderText}>{strings.title}</h1>
Expand Down Expand Up @@ -826,6 +845,18 @@ const Library: React.FC = () => {
</p>
)}

{selectedItem.readme && (
<Fragment>
<DefaultButton
onClick={() => {
setReadmeHidden(false);
}}
>
View readme
Comment thread
pavolum marked this conversation as resolved.
Outdated
</DefaultButton>
&nbsp;
Comment thread
pavolum marked this conversation as resolved.
Outdated
</Fragment>
)}
{isInstalled(selectedItem) && <DefaultButton onClick={removeComponent}>Uninstall</DefaultButton>}
</Fragment>
) : (
Expand Down
1 change: 1 addition & 0 deletions extensions/packageManager/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"@emotion/core" "^10.0.27"
"@emotion/styled" "^10.0.27"
office-ui-fabric-react "7.71.0"
react-markdown "^5.0.3"

"@botframework-composer/types@*", "@botframework-composer/types@file:../../Composer/packages/types":
version "0.0.2"
Expand Down
Loading