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

docs: update sample app strings #1048

Merged
merged 2 commits into from
May 17, 2021
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
14 changes: 4 additions & 10 deletions packages/cli/resource/newParam.json
Original file line number Diff line number Diff line change
Expand Up @@ -273,31 +273,25 @@
{
"id": "in-meeting-app",
"label": "In-meeting App",
"detail": "In-meeting app is a hello-world template which shows how to build an app working in the context of a Teams meeting. ",
"detail": "A template for apps using only in the context of a Teams meeting",
"data": "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
},
{
"id": "todo-list-with-Azure-backend",
"label": "Todo List with backend on Azure",
"detail": "Todo List provides easy way to manage to-do items in Teams Client.",
"detail": "Todo List app with Azure Function backend and Azure SQL database",
"data": "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
},
{
"id": "todo-list-SPFx",
"label": "Todo List with SPFx",
"detail": "Todo List with SPFx is a Todo List for individual user to manage his/her personal to-do items in the format of an app installed on Teams client.",
"detail": "Todo List app hosting on SharePoint",
"data": "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
},
{
"id": "share-now",
"label": "Share Now",
"detail": "The Share Now promotes the exchange of information between colleagues by enabling users to share content within the Teams environment. ",
"data": "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
},
{
"id": "faq-plus",
"label": "FAQ Plus",
"detail": "FAQ Plus is a conversational Q&A bot providing an easy way to answer frequently asked questions by users. ",
"detail": "Knowledge sharing app contains a Tab and a Message Extension",
"data": "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
}
],
Expand Down
80 changes: 47 additions & 33 deletions packages/cli/src/cmds/new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,28 @@ import {
Question,
isAutoSkipSelect,
SingleSelectQuestion,
MultiSelectQuestion
MultiSelectQuestion,
} from "@microsoft/teamsfx-api";

import activate from "../activate";
import * as constants from "../constants";
import { NotFoundInputedFolder, SampleAppClonedFailed } from "../error";
import { NotFoundInputedFolder, SampleAppDownloadFailed } from "../error";
import { validateAndUpdateAnswers, visitInteractively } from "../question/question";
import { YargsCommand } from "../yargsCommand";
import { flattenNodes, getJson, getSingleOptionString, toConfigMap, toYargsOptions } from "../utils";
import {
flattenNodes,
getJson,
getSingleOptionString,
toConfigMap,
toYargsOptions,
} from "../utils";
import CliTelemetry from "../telemetry/cliTelemetry";
import { TelemetryClient } from "applicationinsights";
import { TelemetryEvent, TelemetryProperty, TelemetrySuccess } from "../telemetry/cliTelemetryEvents";
import {
TelemetryEvent,
TelemetryProperty,
TelemetrySuccess,
} from "../telemetry/cliTelemetryEvents";

export default class New extends YargsCommand {
public readonly commandHead = `new`;
Expand Down Expand Up @@ -65,19 +75,21 @@ export default class New extends YargsCommand {
const data = node.data as Question;
if (isAutoSkipSelect(data)) {
// set the only option to default value so yargs will auto fill it.
data.default = getSingleOptionString(data as (SingleSelectQuestion | MultiSelectQuestion));
data.default = getSingleOptionString(data as SingleSelectQuestion | MultiSelectQuestion);
(data as any).hide = true;
}
this.params[data.name] = toYargsOptions(data);
});
yargs.options({
"interactive": {
description: "Select the options interactively",
boolean: true,
default: true,
global: false
}
}).options(this.params);
yargs
.options({
interactive: {
description: "Select the options interactively",
boolean: true,
default: true,
global: false,
},
})
.options(this.params);
}
return yargs.version(false);
}
Expand Down Expand Up @@ -123,7 +135,7 @@ export default class New extends YargsCommand {
}

CliTelemetry.sendTelemetryEvent(TelemetryEvent.CreateProject, {
[TelemetryProperty.Success]: TelemetrySuccess.Yes
[TelemetryProperty.Success]: TelemetrySuccess.Yes,
});
return ok(null);
}
Expand All @@ -141,61 +153,61 @@ class NewTemplete extends YargsCommand {
this.subCommands.forEach((cmd) => {
yargs.command(cmd.command, cmd.description, cmd.builder.bind(cmd), cmd.handler.bind(cmd));
});
const templatesNames = constants.templates.map(t => t.sampleAppName);
const templatesNames = constants.templates.map((t) => t.sampleAppName);
yargs
.positional(
"template-name", {
description: "Enter the template name",
type: "string",
choices: templatesNames,
default: templatesNames[0]
}
)
.positional("template-name", {
description: "Enter the template name",
type: "string",
choices: templatesNames,
default: templatesNames[0],
})
.options(RootFolderNodeData.name, {
type: "string",
description: RootFolderNodeData.description,
default: RootFolderNodeData.default
default: RootFolderNodeData.default,
});
return yargs;
}

public async runCommand(args: {
[argName: string]: string | string[];
}): Promise<Result<null, FxError>> {
const folder = path.resolve(args.folder as string || "./");
const folder = path.resolve((args.folder as string) || "./");
if (!fs.pathExistsSync(folder)) {
throw NotFoundInputedFolder(folder);
}
CliTelemetry.sendTelemetryEvent(TelemetryEvent.DownloadSampleStart);
const templateName = args["template-name"] as string;
const template = constants.templates.find(t => t.sampleAppName === templateName)!;
const template = constants.templates.find((t) => t.sampleAppName === templateName)!;

const result = await this.fetchCodeZip(template.sampleAppUrl);
await this.saveFilesRecursively(new AdmZip(result.data), template.sampleAppName, folder);
console.log(
colors.green(
`Downloaded the '${colors.yellow(template.sampleAppName)}' sample to '${colors.yellow(path.join(folder, template.sampleAppName))}'.`
`Downloaded the '${colors.yellow(template.sampleAppName)}' sample to '${colors.yellow(
path.join(folder, template.sampleAppName)
)}'.`
)
);

CliTelemetry.sendTelemetryEvent(TelemetryEvent.DownloadSample, {
[TelemetryProperty.Success]: TelemetrySuccess.Yes,
[TelemetryProperty.SampleName]: templateName
[TelemetryProperty.SampleName]: templateName,
});
return ok(null);
}

private async fetchCodeZip(url: string) {
try {
const result = await axios.get(url, {
responseType: "arraybuffer"
responseType: "arraybuffer",
});
if (result.status === 200 || result.status === 201) {
return result;
}
throw SampleAppClonedFailed(url, new Error(result.statusText));
throw SampleAppDownloadFailed(url, new Error(result.statusText));
} catch (e) {
throw SampleAppClonedFailed(url, e);
throw SampleAppDownloadFailed(url, e);
}
}

Expand Down Expand Up @@ -235,7 +247,9 @@ class NewTempleteList extends YargsCommand {
console.log(constants.templates);
console.log(
colors.green(
`Use the command ${colors.yellow("teamsfx new template <sampleAppName>")} to create an application from the sample app.`
`Use the command ${colors.yellow(
"teamsfx new template <sampleAppName>"
)} to create an application from the sample app.`
)
);
return ok(null);
Expand Down
25 changes: 9 additions & 16 deletions packages/cli/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,31 @@ export const templates: {
{
tags: ["React", "Azure function", "Azure SQL", "JS"],
title: "Todo List with Azure backend",
description: "Todo List provides an easy way to manage to-do items in Teams Client. This app helps enabling task collaboration and management for your team. The frontend is a React app and the backend is hosted on Azure. You will need an Azure subscription to run the app.",
description: "Todo List app with Azure Function backend and Azure SQL database",
sampleAppName: "todo-list-with-Azure-backend",
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
tags: ["SharePoint", "SPFx", "TS"],
title: "Todo List with SPFx ",
description: "Todo List with SPFx is a Todo List for individuals to manage his/her personal to-do items. This app is hosted on Sharepoint. There is no requirements to deploy Azure resources.",
description: "Todo List app hosting on SharePoint",
sampleAppName: "todo-list-SPFx",
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
tags: ["Tab", "Message Extension", "TS"],
title: "Share Now",
description: "Share Now promotes the exchange of information between colleagues by enabling users to share content within the Teams environment. Users engage the app to share items of interest, discover new shared content, set preferences, and bookmark favorites for later reading.",
description: "Knowledge sharing app contains a Tab and a Message Extension",
sampleAppName: "share-now",
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
},
{
tags: ["Easy QnA", "Bot", "JS"],
title: "FAQ Plus",
description: "FAQ Plus is a conversational Q&A bot providing an easy way to answer frequently asked questions by users. One can ask a question and the bot responds with information in the knowledge base. If the answer is not in the knowledge base, the bot submits the question to a pre-configured team of experts who help provide support.",
sampleAppName: "faq-plus",
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
tags: ["Meeting extension", "JS"],
title: "In-meeting App",
description: "In-meeting app is a hello-world template which shows how to build an app in the context of a Teams meeting. This is a hello-world sample which does not provide any functional feature. This app contains a side panel and a Bot which only shows user profile and can only be added to a Teams meeting.",
description: "A template for apps using only in the context of a Teams meeting",
sampleAppName: "in-meeting-app",
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip"
}
sampleAppUrl: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
];

export enum CLILogLevel {
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ export function ConfigNotFoundError(configpath: string): SystemError {
);
}

export function SampleAppClonedFailed(sampleAppUrl: string, e: Error): SystemError {
e.message = `Cannot clone this sample app from ${sampleAppUrl}. Error: ${e.message}`;
return returnSystemError(e, constants.cliSource, "SampleAppClonedFailed");
export function SampleAppDownloadFailed(sampleAppUrl: string, e: Error): SystemError {
e.message = `Cannot download this sample app from ${sampleAppUrl}. Error: ${e.message}`;
return returnSystemError(e, constants.cliSource, "SampleAppDownloadFailed");
}

export function ReadFileError(e: Error): SystemError {
Expand Down
2 changes: 1 addition & 1 deletion packages/fx-core/src/core/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function NotSupportedProjectType(): UserError {

export function DownloadSampleFail(): SystemError {
return returnUserError(
new Error("Failed to clone sample app"),
new Error("Failed to download sample app"),
CoreSource,
CoreErrorNames.DownloadSampleFail
);
Expand Down
6 changes: 3 additions & 3 deletions packages/fx-core/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,13 @@ class CoreImpl implements Core {
const answer = (
await this.ctx.dialog?.communicate(
new DialogMsg(DialogType.Show, {
description: `Clone '${samples.label}' from Github. This will clone '${samples.label}' repository to your local machine`,
description: `Download '${samples.label}' from Github. This will download '${samples.label}' repository and open to your local machine`,
level: MsgLevel.Info,
items: ["Clone", "Cancel"],
items: ["Download", "Cancel"],
})
)
)?.getAnswer();
if (answer === "Clone") {
if (answer === "Download") {
const url = samples.data as string;
const sampleId = samples.id;
const progress = this.ctx.dialog.createProgressBar("Fetch sample app", 2);
Expand Down
18 changes: 4 additions & 14 deletions packages/fx-core/src/core/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,35 +95,25 @@ export const SampleSelect: SingleSelectQuestion = {
{
id: "in-meeting-app",
label: "In-meeting App",
detail:
"In-meeting app is a hello-world template which shows how to build an app working in the context of a Teams meeting. ",
detail: "A template for apps using only in the context of a Teams meeting",
data: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
id: "todo-list-with-Azure-backend",
label: "Todo List with backend on Azure",
detail: "Todo List provides easy way to manage to-do items in Teams Client.",
detail: "Todo List app with Azure Function backend and Azure SQL database",
data: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
id: "todo-list-SPFx",
label: "Todo List with SPFx",
detail:
"Todo List with SPFx is a Todo List for individual user to manage his/her personal to-do items in the format of an app installed on Teams client.",
detail: "Todo List app hosting on SharePoint",
data: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
id: "share-now",
label: "Share Now",
detail:
"The Share Now promotes the exchange of information between colleagues by enabling users to share content within the Teams environment. ",
data: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
{
id: "faq-plus",
label: "FAQ Plus",
detail:
"FAQ Plus is a conversational Q&A bot providing an easy way to answer frequently asked questions by users. ",
detail: "Knowledge sharing app contains a Tab and a Message Extension",
data: "https://github.com/OfficeDev/TeamsFx-Samples/archive/refs/heads/main.zip",
},
],
Expand Down
10 changes: 5 additions & 5 deletions packages/vscode-extension/src/controls/webviewPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ export class WebviewPanel {
break;
case Commands.CloneSampleApp:
const selection = await vscode.window.showInformationMessage(
`Clone '${msg.data.appName}' from Github. This will clone '${msg.data.appName}' repository to your local machine`,
`Download '${msg.data.appName}' from Github. This will download '${msg.data.appName}' repository and open to your local machine`,
{ modal: false },
"Clone",
"Download",
"Cancel"
);
if (selection === "Clone") {
if (selection === "Download") {
const folder = await vscode.window.showOpenDialog({
canSelectFiles: false,
canSelectFolders: true,
canSelectMany: false,
title: "Select folder to clone the sample app",
title: "Select folder to download the sample app",
});
if (folder !== undefined) {
const dialogManager = DialogManager.getInstance();
Expand All @@ -105,7 +105,7 @@ export class WebviewPanel {
vscode.Uri.file(path.join(folder[0].fsPath, msg.data.appFolder))
);
} else {
vscode.window.showErrorMessage("Failed to clone sample app");
vscode.window.showErrorMessage("Failed to download sample app");
}
} finally {
progress.end();
Expand Down