From c2f3471afeae6df30e73f16037297bee2821449a Mon Sep 17 00:00:00 2001 From: victor-meng <56978073+victor-meng@users.noreply.github.com> Date: Mon, 16 May 2022 18:23:54 -0700 Subject: [PATCH] Add carousel for quick start (#1271) * Add carousel for quick start * Put carousel behind feature flag * Install type definition for react-youtube * Install type definition for react-youtube * Remove @types/youtube-player * Move feature flag outside of quickstarttutorial component --- images/Placeholder.svg | 8 ++ package-lock.json | 114 ++++++++++++++++-- package.json | 2 + src/Explorer/Tutorials/QuickstartCarousel.tsx | 77 ++++++++++++ src/Explorer/Tutorials/QuickstartTutorial.tsx | 5 - src/Main.tsx | 5 +- 6 files changed, 197 insertions(+), 14 deletions(-) create mode 100644 images/Placeholder.svg create mode 100644 src/Explorer/Tutorials/QuickstartCarousel.tsx diff --git a/images/Placeholder.svg b/images/Placeholder.svg new file mode 100644 index 000000000..31d547883 --- /dev/null +++ b/images/Placeholder.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/package-lock.json b/package-lock.json index df903c500..ce3c13ec8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,6 +95,7 @@ "react-notification-system": "0.2.17", "react-redux": "7.1.3", "react-splitter-layout": "4.0.0", + "react-youtube": "9.0.1", "redux": "4.0.4", "reflect-metadata": "0.1.13", "rx-jupyter": "5.5.12", @@ -134,6 +135,7 @@ "@types/sinon": "2.3.3", "@types/styled-components": "5.1.1", "@types/underscore": "1.7.36", + "@types/youtube-player": "5.5.6", "@typescript-eslint/eslint-plugin": "4.22.0", "@typescript-eslint/parser": "4.22.0", "@webpack-cli/serve": "1.5.2", @@ -6825,6 +6827,12 @@ "@types/node": "*" } }, + "node_modules/@types/youtube-player": { + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/@types/youtube-player/-/youtube-player-5.5.6.tgz", + "integrity": "sha512-RcWWUEuAZZX24dG55Xk558/HHCZxYf798/xPnV6wTwDlUF8HZNAmqyXyi+4QgN2l9juP9GRjCwILxXLSPKQBBw==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", @@ -25033,13 +25041,13 @@ } }, "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" } }, "node_modules/prop-types-exact": { @@ -25958,6 +25966,22 @@ "react-dom": ">=15.0.0" } }, + "node_modules/react-youtube": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-9.0.1.tgz", + "integrity": "sha512-w2yt3o1H0fjlMjoqn8zEmtCqgiV+bYS1JfMSUfh70zky2rwWVORQzpt2DWoDio1+nZ1X9kSTzakdif6gaJdFuQ==", + "dependencies": { + "fast-deep-equal": "3.1.3", + "prop-types": "15.8.1", + "youtube-player": "5.5.2" + }, + "engines": { + "node": ">= 14.x" + }, + "peerDependencies": { + "react": ">=0.14.1" + } + }, "node_modules/reactcss": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", @@ -27391,6 +27415,11 @@ "node": ">= 10" } }, + "node_modules/sister": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz", + "integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA==" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -31155,6 +31184,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/youtube-player": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz", + "integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==", + "dependencies": { + "debug": "^2.6.6", + "load-script": "^1.0.0", + "sister": "^3.0.0" + } + }, + "node_modules/youtube-player/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/youtube-player/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/zalgo-promise": { "version": "1.0.46", "resolved": "https://registry.npmjs.org/zalgo-promise/-/zalgo-promise-1.0.46.tgz", @@ -37098,6 +37150,12 @@ "@types/node": "*" } }, + "@types/youtube-player": { + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/@types/youtube-player/-/youtube-player-5.5.6.tgz", + "integrity": "sha512-RcWWUEuAZZX24dG55Xk558/HHCZxYf798/xPnV6wTwDlUF8HZNAmqyXyi+4QgN2l9juP9GRjCwILxXLSPKQBBw==", + "dev": true + }, "@typescript-eslint/eslint-plugin": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", @@ -51360,13 +51418,13 @@ } }, "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" } }, "prop-types-exact": { @@ -52072,6 +52130,16 @@ "react-lifecycles-compat": "^3.0.4" } }, + "react-youtube": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-9.0.1.tgz", + "integrity": "sha512-w2yt3o1H0fjlMjoqn8zEmtCqgiV+bYS1JfMSUfh70zky2rwWVORQzpt2DWoDio1+nZ1X9kSTzakdif6gaJdFuQ==", + "requires": { + "fast-deep-equal": "3.1.3", + "prop-types": "15.8.1", + "youtube-player": "5.5.2" + } + }, "reactcss": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", @@ -53221,6 +53289,11 @@ "totalist": "^1.0.0" } }, + "sister": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz", + "integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA==" + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -56130,6 +56203,31 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, + "youtube-player": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz", + "integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==", + "requires": { + "debug": "^2.6.6", + "load-script": "^1.0.0", + "sister": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "zalgo-promise": { "version": "1.0.46", "resolved": "https://registry.npmjs.org/zalgo-promise/-/zalgo-promise-1.0.46.tgz", diff --git a/package.json b/package.json index 762d9c9ce..3e76f6f69 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "react-notification-system": "0.2.17", "react-redux": "7.1.3", "react-splitter-layout": "4.0.0", + "react-youtube": "9.0.1", "redux": "4.0.4", "reflect-metadata": "0.1.13", "rx-jupyter": "5.5.12", @@ -130,6 +131,7 @@ "@types/sinon": "2.3.3", "@types/styled-components": "5.1.1", "@types/underscore": "1.7.36", + "@types/youtube-player": "5.5.6", "@typescript-eslint/eslint-plugin": "4.22.0", "@typescript-eslint/parser": "4.22.0", "@webpack-cli/serve": "1.5.2", diff --git a/src/Explorer/Tutorials/QuickstartCarousel.tsx b/src/Explorer/Tutorials/QuickstartCarousel.tsx new file mode 100644 index 000000000..b5a58ead7 --- /dev/null +++ b/src/Explorer/Tutorials/QuickstartCarousel.tsx @@ -0,0 +1,77 @@ +import { DefaultButton, IconButton, Image, Modal, PrimaryButton, Stack, Text } from "@fluentui/react"; +import React, { useState } from "react"; +import Youtube from "react-youtube"; +import Placeholder from "../../../images/Placeholder.svg"; + +interface QuickstartCarouselProps { + isOpen: boolean; +} + +export const QuickstartCarousel: React.FC = ({ + isOpen, +}: QuickstartCarouselProps): JSX.Element => { + const [page, setPage] = useState(1); + return ( + + + + {getHeaderText(page)} + setPage(4)} /> + + {getContent(page)} + + {getDescriptionText(page)} + + + {page !== 1 && ( + setPage(page - 1)} /> + )} + setPage(page + 1)} + /> + + + + ); +}; + +const getHeaderText = (page: number): string => { + switch (page) { + case 1: + return "Welcome! What is Cosmos DB?"; + case 2: + return "Get Started with Sample Data"; + case 3: + return "Connect to your database"; + default: + return ""; + } +}; + +const getContent = (page: number): JSX.Element => { + switch (page) { + case 1: + return ; + case 2: + return ; + case 3: + return ; + default: + return <>; + } +}; + +const getDescriptionText = (page: number): string => { + switch (page) { + case 1: + return "Azure Cosmos DB is a fully managed NoSQL database service for modern app development. "; + case 2: + return "Launch the quickstart for a tutotrial to learn how to create a database, add sample data, connect to a sample app and more."; + case 3: + return "Already have an existing app? Connect your database to an app, or tooling of your choice from Data Explorer."; + default: + return ""; + } +}; diff --git a/src/Explorer/Tutorials/QuickstartTutorial.tsx b/src/Explorer/Tutorials/QuickstartTutorial.tsx index 9da43060c..4b7c0fc71 100644 --- a/src/Explorer/Tutorials/QuickstartTutorial.tsx +++ b/src/Explorer/Tutorials/QuickstartTutorial.tsx @@ -2,15 +2,10 @@ import { TeachingBubble } from "@fluentui/react"; import { useDatabases } from "Explorer/useDatabases"; import { useTeachingBubble } from "hooks/useTeachingBubble"; import React from "react"; -import { userContext } from "UserContext"; export const QuickstartTutorial: React.FC = (): JSX.Element => { const { step, isSampleDBExpanded, isDocumentsTabOpened, setStep } = useTeachingBubble(); - if (!userContext.features.enableNewQuickstart) { - return <>; - } - switch (step) { case 1: return isSampleDBExpanded ? ( diff --git a/src/Main.tsx b/src/Main.tsx index 869f4f7ea..0888f3ec2 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -1,9 +1,11 @@ // CSS Dependencies import { initializeIcons } from "@fluentui/react"; import "bootstrap/dist/css/bootstrap.css"; +import { QuickstartCarousel } from "Explorer/Tutorials/QuickstartCarousel"; import { QuickstartTutorial } from "Explorer/Tutorials/QuickstartTutorial"; import React, { useState } from "react"; import ReactDOM from "react-dom"; +import { userContext } from "UserContext"; import "../externals/jquery-ui.min.css"; import "../externals/jquery-ui.min.js"; import "../externals/jquery-ui.structure.min.css"; @@ -116,7 +118,8 @@ const App: React.FunctionComponent = () => { - + {userContext.features.enableNewQuickstart && } + {userContext.features.enableNewQuickstart && } ); };