diff --git a/Composer/packages/client/__tests__/components/CreationFlow/CreateOptions/index.test.tsx b/Composer/packages/client/__tests__/components/CreationFlow/CreateOptions/index.test.tsx index d8e6f1f249..a95d39733c 100644 --- a/Composer/packages/client/__tests__/components/CreationFlow/CreateOptions/index.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlow/CreateOptions/index.test.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { fireEvent } from '@bfc/test-utils'; import { renderWithStore } from '../../../testUtils'; -import { CreateOptions } from '../../../../src/components/CreationFlow/CreateOptions/CreateOptions'; +import { CreateOptions } from '../../../../src/components/CreationFlow/CreateOptions'; describe('', () => { const handleDismissMock = jest.fn(); diff --git a/Composer/packages/client/__tests__/components/CreationFlow/DefineConversation/index.test.tsx b/Composer/packages/client/__tests__/components/CreationFlow/DefineConversation/index.test.tsx index eabc9d6dcc..e6a0616f95 100644 --- a/Composer/packages/client/__tests__/components/CreationFlow/DefineConversation/index.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlow/DefineConversation/index.test.tsx @@ -6,7 +6,7 @@ import { fireEvent } from '@bfc/test-utils'; import { renderWithStore } from '../../../testUtils'; import { StorageFolder } from '../../../../src/store/types'; -import DefineConversation from '../../../../src/components/CreationFlow/DefineConversation/DefineConversation'; +import DefineConversation from '../../../../src/components/CreationFlow/DefineConversation'; describe('', () => { const onCurrentPathUpdateMock = jest.fn(); diff --git a/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx b/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx index 2cd9b23ebc..8e781d44b6 100644 --- a/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { render, fireEvent } from '@bfc/test-utils'; import { StorageFolder } from '../../../../src/store/types'; -import { FileSelector } from '../../../../src/components/CreationFlow/LocationBrowser/FileSelector'; +import { FileSelector } from '../../../../src/components/CreationFlow/FileSelector'; describe('', () => { const onFileChosen = jest.fn(); diff --git a/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/LocationSelectContent.test.tsx b/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/LocationSelectContent.test.tsx index 36fdbf0c97..4b3b6f62b9 100644 --- a/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/LocationSelectContent.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/LocationSelectContent.test.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { fireEvent } from '@bfc/test-utils'; import { StorageFolder } from '../../../../src/store/types'; -import { LocationSelectContent } from '../../../../src/components/CreationFlow/LocationBrowser/LocationSelectContent'; +import { LocationSelectContent } from '../../../../src/components/CreationFlow/LocationSelectContent'; import { renderWithStore } from '../../../testUtils'; import { CreationFlowStatus } from '../../../../src/constants'; diff --git a/Composer/packages/client/__tests__/components/CreationFlow/index.test.tsx b/Composer/packages/client/__tests__/components/CreationFlow/index.test.tsx index 9851688ad6..a420d94c06 100644 --- a/Composer/packages/client/__tests__/components/CreationFlow/index.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlow/index.test.tsx @@ -7,15 +7,10 @@ import { createHistory, createMemorySource, LocationProvider } from '@reach/rout import { StoreContext } from '../../../src/store'; import CreationFlow from '../../../src/components/CreationFlow/CreationFlow'; +import { DialogWrapper } from '../../../src/components/DialogWrapper'; import { CreationFlowStatus } from '../../../src/constants'; -jest.mock('../../../src/components/DialogWrapper/DialogWrapper', () => { - return { - DialogWrapper: jest.fn((props) => { - return props.children; - }), - }; -}); +jest.mock('../../../src/components/DialogWrapper'); describe('', () => { let storeContext, saveTemplateMock, locationMock, createProjectMock; @@ -36,6 +31,10 @@ describe('', () => { } beforeEach(() => { + (DialogWrapper as jest.Mock).mockImplementation((props) => { + return props.children; + }); + saveTemplateMock = jest.fn(); locationMock = {}; storeContext = { diff --git a/Composer/packages/client/__tests__/components/DialogWrapper/index.test.tsx b/Composer/packages/client/__tests__/components/DialogWrapper/index.test.tsx index 6f1e7f95f7..b6f5a23152 100644 --- a/Composer/packages/client/__tests__/components/DialogWrapper/index.test.tsx +++ b/Composer/packages/client/__tests__/components/DialogWrapper/index.test.tsx @@ -4,8 +4,7 @@ import React from 'react'; import { render } from '@bfc/test-utils'; -import { DialogWrapper } from '../../../src/components/DialogWrapper/DialogWrapper'; -import { DialogTypes } from '../../../src/components/DialogWrapper/styles'; +import { DialogWrapper, DialogTypes } from '../../../src/components/DialogWrapper'; describe('', () => { const props = { diff --git a/Composer/packages/client/__tests__/components/appUpdater.test.tsx b/Composer/packages/client/__tests__/components/appUpdater.test.tsx index bea9d98311..3973fdef04 100644 --- a/Composer/packages/client/__tests__/components/appUpdater.test.tsx +++ b/Composer/packages/client/__tests__/components/appUpdater.test.tsx @@ -3,7 +3,7 @@ import React from 'react'; -import { AppUpdater } from '../../src/components/AppUpdater/AppUpdater'; +import { AppUpdater } from '../../src/components/AppUpdater'; import { AppUpdaterStatus } from '../../src/constants'; import { renderWithStore } from '../testUtils'; diff --git a/Composer/packages/client/__tests__/components/conversation.test.jsx b/Composer/packages/client/__tests__/components/conversation.test.jsx index dd9ed19fc8..723f32b6ad 100644 --- a/Composer/packages/client/__tests__/components/conversation.test.jsx +++ b/Composer/packages/client/__tests__/components/conversation.test.jsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { render } from '@bfc/test-utils'; -import '../../src/components/Conversation/Conversation'; +import '../../src/components/Conversation'; describe('', () => { it('should render the conversation', async () => { diff --git a/Composer/packages/client/__tests__/components/errorBoundary.test.jsx b/Composer/packages/client/__tests__/components/errorBoundary.test.jsx index a4a759220f..2b52b1aceb 100644 --- a/Composer/packages/client/__tests__/components/errorBoundary.test.jsx +++ b/Composer/packages/client/__tests__/components/errorBoundary.test.jsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { render } from '@bfc/test-utils'; -import { ErrorBoundary } from '../../src/components/ErrorBoundary/ErrorBoundary'; +import { ErrorBoundary } from '../../src/components/ErrorBoundary'; const Store = React.createContext({ actions: { diff --git a/Composer/packages/client/__tests__/components/header.test.jsx b/Composer/packages/client/__tests__/components/header.test.jsx index 163d406596..68c28604b7 100644 --- a/Composer/packages/client/__tests__/components/header.test.jsx +++ b/Composer/packages/client/__tests__/components/header.test.jsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { render } from '@bfc/test-utils'; -import { Header } from '../../src/components/Header/Header'; +import { Header } from '../../src/components/Header'; describe('', () => { it('should render the header', () => { diff --git a/Composer/packages/client/__tests__/components/home.test.jsx b/Composer/packages/client/__tests__/components/home.test.jsx index 1c8cbddb19..9a050d768a 100644 --- a/Composer/packages/client/__tests__/components/home.test.jsx +++ b/Composer/packages/client/__tests__/components/home.test.jsx @@ -6,7 +6,7 @@ import { fireEvent, render } from '@bfc/test-utils'; import { RecentBotList } from '../../src/pages/home/RecentBotList'; import { ExampleList } from '../../src/pages/home/ExampleList'; -import { ToolBar } from '../../src/components/ToolBar/ToolBar'; +import { ToolBar } from '../../src/components/ToolBar'; describe('', () => { it('should dispatch onSelectionChanged event when clicked on a link on ', () => { const recentProjects = [ diff --git a/Composer/packages/client/__tests__/components/skill.test.tsx b/Composer/packages/client/__tests__/components/skill.test.tsx index 4f248503cf..5c95b25bf3 100644 --- a/Composer/packages/client/__tests__/components/skill.test.tsx +++ b/Composer/packages/client/__tests__/components/skill.test.tsx @@ -5,14 +5,13 @@ import * as React from 'react'; import { render, fireEvent, getByLabelText, getByTestId } from '@bfc/test-utils'; import { Skill } from '@bfc/shared'; +import httpClient from '../../src//utils/httpUtil'; import Skills from '../../src/pages/skills'; import SkillList from '../../src/pages/skills/skill-list'; -import CreateSkillModal from '../../src/components/SkillForm/CreateSkillModal/CreateSkillModal'; +import CreateSkillModal from '../../src/components/CreateSkillModal'; import { renderWithStore } from '../testUtils'; -jest.mock('../../src/components/SkillForm/CreateSkillModal/validateManifestUrl', () => ({ - validateManifestUrl: () => {}, -})); +jest.mock('../../src//utils/httpUtil'); const items: Skill[] = [ { @@ -81,6 +80,9 @@ describe('', () => { const onSubmit = jest.fn((formData) => { expect(formData.manifestUrl).toBe('http://AwesomeSkill'); }); + + (httpClient.post as jest.Mock).mockResolvedValue(undefined); + const onDismiss = jest.fn(() => {}); const { getByLabelText, getByText } = render( [ { diff --git a/Composer/packages/client/__tests__/navItem.test.jsx b/Composer/packages/client/__tests__/navItem.test.jsx index f952c97bdc..284268c04f 100644 --- a/Composer/packages/client/__tests__/navItem.test.jsx +++ b/Composer/packages/client/__tests__/navItem.test.jsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { render } from '@bfc/test-utils'; -import { NavItem } from '../src/components/NavItem/NavItem'; +import { NavItem } from '../src/components/NavItem'; import { StoreProvider } from '../src/store'; describe('', () => { diff --git a/Composer/packages/client/__tests__/notFound.test.jsx b/Composer/packages/client/__tests__/notFound.test.jsx index 8b8ab477c3..ba122988db 100644 --- a/Composer/packages/client/__tests__/notFound.test.jsx +++ b/Composer/packages/client/__tests__/notFound.test.jsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { render } from '@bfc/test-utils'; import { BASEPATH } from '../src/constants'; -import { NotFound } from '../src/components/NotFound/NotFound'; +import { NotFound } from '../src/components/NotFound'; describe('', () => { it('should render a not found page', async () => { diff --git a/Composer/packages/client/src/App.tsx b/Composer/packages/client/src/App.tsx index 7082ac3e5d..c6514a4b0e 100644 --- a/Composer/packages/client/src/App.tsx +++ b/Composer/packages/client/src/App.tsx @@ -10,15 +10,15 @@ import { FocusZone } from 'office-ui-fabric-react/lib/FocusZone'; import { TooltipHost, DirectionalHint } from 'office-ui-fabric-react/lib/Tooltip'; import formatMessage from 'format-message'; -import { Header } from './components/Header/Header'; -import { NavItem } from './components/NavItem/NavItem'; +import { Header } from './components/Header'; +import { NavItem } from './components/NavItem'; import { BASEPATH } from './constants'; import Routes from './router'; import { StoreContext } from './store'; import { main, sideBar, content, divider, globalNav, leftNavBottom, rightPanel, dividerTop } from './styles'; import { resolveToBasePath } from './utils/fileUtil'; -import { ErrorBoundary } from './components/ErrorBoundary/ErrorBoundary'; -import { RequireAuth } from './components/RequireAuth/RequireAuth'; +import { ErrorBoundary } from './components/ErrorBoundary'; +import { RequireAuth } from './components/RequireAuth'; import onboardingState from './utils/onboardingStorage'; import { isElectron } from './utils/electronUtil'; import { useLinks } from './utils/hooks'; @@ -27,7 +27,7 @@ initializeIcons(undefined, { disableWarnings: true }); const Onboarding = React.lazy(() => import('./Onboarding/Onboarding')); const AppUpdater = React.lazy(() => - import('./components/AppUpdater/AppUpdater').then((module) => ({ default: module.AppUpdater })) + import('./components/AppUpdater').then((module) => ({ default: module.AppUpdater })) ); // eslint-disable-next-line react/display-name diff --git a/Composer/packages/client/src/components/AppUpdater/AppUpdater.tsx b/Composer/packages/client/src/components/AppUpdater.tsx similarity index 86% rename from Composer/packages/client/src/components/AppUpdater/AppUpdater.tsx rename to Composer/packages/client/src/components/AppUpdater.tsx index 0dc5dfa12d..17821b470f 100644 --- a/Composer/packages/client/src/components/AppUpdater/AppUpdater.tsx +++ b/Composer/packages/client/src/components/AppUpdater.tsx @@ -2,19 +2,57 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React, { useContext, useEffect, useMemo, useState, useCallback } from 'react'; import { Dialog, DialogFooter, DialogType } from 'office-ui-fabric-react/lib/Dialog'; -import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react/lib/Button'; +import { DefaultButton, PrimaryButton, IButtonStyles } from 'office-ui-fabric-react/lib/Button'; import { Icon } from 'office-ui-fabric-react/lib/Icon'; import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator'; import { ChoiceGroup } from 'office-ui-fabric-react/lib/ChoiceGroup'; import formatMessage from 'format-message'; +import { IDialogContentStyles, IDialogFooterStyles } from 'office-ui-fabric-react/lib/Dialog'; +import { NeutralColors, SharedColors } from '@uifabric/fluent-theme'; + +import { AppUpdaterStatus } from '../constants'; +import { StoreContext } from '../store'; + +// -------------------- Styles -------------------- // + +const optionIcon = (checked) => css` + vertical-align: text-bottom; + font-size: 18px; + margin-right: 10px; + color: ${checked ? SharedColors.cyanBlue10 : NeutralColors.black}; +`; + +const optionRoot = css` + width: 100%; + height: 100%; +`; + +const dialogCopy = css` + margin: 0px; + color: #000; +`; + +const dialogContent: Partial = { + subText: { color: NeutralColors.black }, + header: { paddingBottom: '6px' }, +}; -import { StoreContext } from '../../store'; -import { AppUpdaterStatus } from '../../constants'; +const dialogFooter: Partial = { + actions: { + marginTop: '46px', + }, +}; -import { dialogContent, dialogCopy, dialogFooter, optionRoot, optionIcon, updateAvailableDismissBtn } from './styles'; +const updateAvailableDismissBtn: Partial = { + root: { + marginRight: '6px;', + }, +}; + +// -------------------- Helpers -------------------- // const { ipcRenderer } = window; @@ -33,6 +71,8 @@ const downloadOptions = { installAndUpdate: 'installAndUpdate', }; +// -------------------- AppUpdater -------------------- // + export const AppUpdater: React.FC<{}> = () => { const { actions: { setAppUpdateError, setAppUpdateProgress, setAppUpdateShowing, setAppUpdateStatus }, diff --git a/Composer/packages/client/src/components/AppUpdater/styles.ts b/Composer/packages/client/src/components/AppUpdater/styles.ts deleted file mode 100644 index a40c2300b2..0000000000 --- a/Composer/packages/client/src/components/AppUpdater/styles.ts +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; -import { IDialogContentStyles, IDialogFooterStyles } from 'office-ui-fabric-react/lib/Dialog'; -import { NeutralColors, SharedColors } from '@uifabric/fluent-theme'; - -export const optionIcon = (checked) => css` - vertical-align: text-bottom; - font-size: 18px; - margin-right: 10px; - color: ${checked ? SharedColors.cyanBlue10 : NeutralColors.black}; -`; - -export const optionRoot = css` - width: 100%; - height: 100%; -`; - -export const dialogCopy = css` - margin: 0px; - color: #000; -`; - -export const dialogContent: Partial = { - subText: { color: NeutralColors.black }, - header: { paddingBottom: '6px' }, -}; - -export const dialogFooter: Partial = { - actions: { - marginTop: '46px', - }, -}; - -export const updateAvailableDismissBtn: Partial = { - root: { - marginRight: '6px;', - }, -}; diff --git a/Composer/packages/client/src/components/Conversation.jsx b/Composer/packages/client/src/components/Conversation.jsx new file mode 100644 index 0000000000..6df21b6c1d --- /dev/null +++ b/Composer/packages/client/src/components/Conversation.jsx @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** @jsx jsx */ +import { jsx, css } from '@emotion/core'; + +// -------------------- Styles -------------------- // + +const container = css` + width: 100%; + background-color: #ffffff; + height: 100%; + overflow: auto; + position: relative; +`; + +const top = css` + width: 100%; + height: 10px; + background-color: #efeaf5; +`; + +// -------------------- Conversation -------------------- // + +const Conversation = (props) => { + return ( + + {props.children} + + ); +}; + +export { Conversation }; diff --git a/Composer/packages/client/src/components/Conversation/Conversation.jsx b/Composer/packages/client/src/components/Conversation/Conversation.jsx deleted file mode 100644 index 4a8340e0ca..0000000000 --- a/Composer/packages/client/src/components/Conversation/Conversation.jsx +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** @jsx jsx */ -import { jsx } from '@emotion/core'; - -import { container } from './styles'; - -const Conversation = (props) => { - return ( - - {props.children} - - ); -}; - -export { Conversation }; diff --git a/Composer/packages/client/src/components/Conversation/styles.js b/Composer/packages/client/src/components/Conversation/styles.js deleted file mode 100644 index af4bd7fde0..0000000000 --- a/Composer/packages/client/src/components/Conversation/styles.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; - -export const container = css` - width: 100%; - background-color: #ffffff; - height: 100%; - overflow: auto; - position: relative; -`; - -export const top = css` - width: 100%; - height: 10px; - background-color: #efeaf5; -`; diff --git a/Composer/packages/client/src/components/SkillForm/CreateSkillModal/CreateSkillModal.tsx b/Composer/packages/client/src/components/CreateSkillModal.tsx similarity index 82% rename from Composer/packages/client/src/components/SkillForm/CreateSkillModal/CreateSkillModal.tsx rename to Composer/packages/client/src/components/CreateSkillModal.tsx index 3417d9a9df..01affe1bda 100644 --- a/Composer/packages/client/src/components/SkillForm/CreateSkillModal/CreateSkillModal.tsx +++ b/Composer/packages/client/src/components/CreateSkillModal.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React, { useState, FormEvent, useEffect, useCallback, useRef } from 'react'; import formatMessage from 'format-message'; import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; @@ -11,14 +11,64 @@ import { Stack, StackItem } from 'office-ui-fabric-react/lib/Stack'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { assignDefined, Skill } from '@bfc/shared'; import debounce from 'lodash/debounce'; +import { FontSizes } from 'office-ui-fabric-react/lib/Styling'; -import { DialogWrapper } from '../../DialogWrapper/DialogWrapper'; -import { DialogTypes } from '../../DialogWrapper/styles'; -import { addSkillDialog } from '../../../constants'; -import { ISkillFormData, ISkillFormDataErrors, skillUrlRegex, skillNameRegex } from '../types'; +import { addSkillDialog } from '../constants'; +import httpClient from '../utils/httpUtil'; -import { FormFieldManifestUrl, FormFieldEditName, MarginLeftSmall, FormModalBody, SpinnerLabel } from './styles'; -import { validateManifestUrl } from './validateManifestUrl'; +import { DialogWrapper, DialogTypes } from './DialogWrapper'; + +// -------------------- Styles -------------------- // + +const FormModalBody = css` + padding: 24px; +`; + +const FormFieldManifestUrl = css` + width: 40rem; +`; + +const FormFieldEditName = css` + width: 20rem; +`; + +const MarginLeftSmall = css` + margin-left: ${FontSizes.small}; +`; + +const SpinnerLabel = css` + justify-content: left; + margin-top: 0.4rem; +`; + +// -------------------- CreateSkillModal -------------------- // + +async function validateManifestUrl(projectId: string, manifestUrl: string): Promise { + // skip validation if there are other local errors. + if (manifestUrl == null || manifestUrl === '') { + return; + } + + try { + await httpClient.post(`/projects/${projectId}/skill/check`, { url: manifestUrl }); + } catch (err) { + return err.response?.data.message ?? err; + } +} + +export interface ISkillFormData { + manifestUrl: string; + name?: string; +} + +export interface ISkillFormDataErrors { + manifestUrl?: string; + manifestUrlFetch?: string; + name?: string; +} + +export const skillUrlRegex = /^http[s]?:\/\/\w+/; +export const skillNameRegex = /^\w[-\w]*$/; export interface ICreateSkillModalProps { isOpen: boolean; @@ -33,7 +83,7 @@ const defaultFormData = { manifestUrl: '', }; -const CreateSkillModal: React.FC = (props) => { +export const CreateSkillModal: React.FC = (props) => { const { editIndex = -1, skills, onSubmit, onDismiss, isOpen, projectId } = props; const originFormData = skills[editIndex]; const initialFormData = originFormData diff --git a/Composer/packages/client/src/components/CreationFlow/CreateOptions/CreateOptions.tsx b/Composer/packages/client/src/components/CreationFlow/CreateOptions.tsx similarity index 77% rename from Composer/packages/client/src/components/CreationFlow/CreateOptions/CreateOptions.tsx rename to Composer/packages/client/src/components/CreationFlow/CreateOptions.tsx index 8c4347dadb..05d17d943f 100644 --- a/Composer/packages/client/src/components/CreationFlow/CreateOptions/CreateOptions.tsx +++ b/Composer/packages/client/src/components/CreationFlow/CreateOptions.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { useState, Fragment, useEffect, useMemo } from 'react'; import find from 'lodash/find'; import formatMessage from 'format-message'; @@ -21,27 +21,88 @@ import { } from 'office-ui-fabric-react/lib/DetailsList'; import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky'; import { ProjectTemplate } from '@bfc/shared'; +import { NeutralColors } from '@uifabric/fluent-theme'; -import { DialogCreationCopy, EmptyBotTemplateId } from '../../../constants'; -import { DialogWrapper } from '../../DialogWrapper/DialogWrapper'; -import { DialogTypes } from '../../DialogWrapper/styles'; +import { DialogCreationCopy, EmptyBotTemplateId } from '../../constants'; +import { DialogWrapper, DialogTypes } from '../DialogWrapper'; -import { - detailListContainer, - listHeader, - rowDetails, - rowTitle, - optionRoot, - optionIcon, - tableCell, - content, -} from './styles'; +// -------------------- Styles -------------------- // + +const optionIcon = (checked) => css` + vertical-align: text-bottom; + font-size: 18px; + margin-right: 10px; + color: ${checked ? '#0078d4' : '#000'}; +`; + +const optionRoot = css` + width: 100%; + height: 100%; +`; + +const detailListContainer = css` + width: 100%; + height: 400px; + position: relative; + overflow: hidden; + flex-grow: 1; +`; + +const listHeader = css` + margin-top: 10px; + margin-bottom: 0; +`; + +const rowDetails = (disabled) => { + return { + root: { + color: disabled ? NeutralColors.gray80 : NeutralColors.black, + selectors: { + '&:hover': { + background: disabled ? NeutralColors.white : NeutralColors.gray30, + color: disabled ? NeutralColors.gray80 : NeutralColors.black, + }, + '&.ms-DetailsRow.is-selected': { + background: disabled ? NeutralColors.white : NeutralColors.gray30, + color: disabled ? NeutralColors.gray80 : NeutralColors.black, + }, + }, + }, + }; +}; + +const rowTitle = (disabled) => { + return { + cellTitle: { + color: disabled ? NeutralColors.gray80 : NeutralColors.black, + selectors: { + ':hover': { + background: disabled ? NeutralColors.white : NeutralColors.gray30, + color: disabled ? NeutralColors.gray80 : NeutralColors.black, + }, + }, + }, + }; +}; + +const tableCell = css` + outline: none; + :focus { + outline: rgb(102, 102, 102) solid 1px; + } +`; + +const content = css` + outline: none; +`; const optionKeys = { createFromScratch: 'createFromScratch', createFromTemplate: 'createFromTemplate', }; +// -------------------- CreateOptions -------------------- // + export function CreateOptions(props) { const [option, setOption] = useState(optionKeys.createFromScratch); const [disabled, setDisabled] = useState(true); diff --git a/Composer/packages/client/src/components/CreationFlow/CreateOptions/styles.ts b/Composer/packages/client/src/components/CreationFlow/CreateOptions/styles.ts deleted file mode 100644 index 63e360e682..0000000000 --- a/Composer/packages/client/src/components/CreationFlow/CreateOptions/styles.ts +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { NeutralColors } from '@uifabric/fluent-theme'; - -export const optionIcon = (checked) => css` - vertical-align: text-bottom; - font-size: 18px; - margin-right: 10px; - color: ${checked ? '#0078d4' : '#000'}; -`; - -export const optionRoot = css` - width: 100%; - height: 100%; -`; - -export const detailListContainer = css` - width: 100%; - height: 400px; - position: relative; - overflow: hidden; - flex-grow: 1; -`; - -export const listHeader = css` - margin-top: 10px; - margin-bottom: 0; -`; - -export const rowDetails = (disabled) => { - return { - root: { - color: disabled ? NeutralColors.gray80 : NeutralColors.black, - selectors: { - '&:hover': { - background: disabled ? NeutralColors.white : NeutralColors.gray30, - color: disabled ? NeutralColors.gray80 : NeutralColors.black, - }, - '&.ms-DetailsRow.is-selected': { - background: disabled ? NeutralColors.white : NeutralColors.gray30, - color: disabled ? NeutralColors.gray80 : NeutralColors.black, - }, - }, - }, - }; -}; - -export const rowTitle = (disabled) => { - return { - cellTitle: { - color: disabled ? NeutralColors.gray80 : NeutralColors.black, - selectors: { - ':hover': { - background: disabled ? NeutralColors.white : NeutralColors.gray30, - color: disabled ? NeutralColors.gray80 : NeutralColors.black, - }, - }, - }, - }; -}; - -export const tableCell = css` - outline: none; - :focus { - outline: rgb(102, 102, 102) solid 1px; - } -`; - -export const content = css` - outline: none; -`; diff --git a/Composer/packages/client/src/components/CreationFlow/CreationFlow.tsx b/Composer/packages/client/src/components/CreationFlow/CreationFlow.tsx index 38f171fd4d..2a71d22bff 100644 --- a/Composer/packages/client/src/components/CreationFlow/CreationFlow.tsx +++ b/Composer/packages/client/src/components/CreationFlow/CreationFlow.tsx @@ -11,9 +11,9 @@ import { CreationFlowStatus } from '../../constants'; import { StoreContext } from '../../store'; import Home from '../../pages/home/Home'; -import { CreateOptions } from './CreateOptions/CreateOptions'; -import { OpenProject } from './OpenProject/OpenProject'; -import DefineConversation from './DefineConversation/DefineConversation'; +import { CreateOptions } from './CreateOptions'; +import { OpenProject } from './OpenProject'; +import DefineConversation from './DefineConversation'; type CreationFlowProps = RouteComponentProps<{}>; diff --git a/Composer/packages/client/src/components/CreationFlow/DefineConversation/DefineConversation.tsx b/Composer/packages/client/src/components/CreationFlow/DefineConversation.tsx similarity index 88% rename from Composer/packages/client/src/components/CreationFlow/DefineConversation/DefineConversation.tsx rename to Composer/packages/client/src/components/CreationFlow/DefineConversation.tsx index 7aeef71014..f411c7ab09 100644 --- a/Composer/packages/client/src/components/CreationFlow/DefineConversation/DefineConversation.tsx +++ b/Composer/packages/client/src/components/CreationFlow/DefineConversation.tsx @@ -12,15 +12,53 @@ import React, { Fragment, useEffect, useCallback } from 'react'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { RouteComponentProps } from '@reach/router'; import querystring from 'query-string'; +import { FontWeights } from '@uifabric/styling'; -import { DialogCreationCopy, nameRegex } from '../../../constants'; -import { DialogWrapper } from '../../DialogWrapper/DialogWrapper'; -import { DialogTypes } from '../../DialogWrapper/styles'; -import { LocationSelectContent } from '../LocationBrowser/LocationSelectContent'; -import { StorageFolder } from '../../../store/types'; -import { FieldConfig, useForm } from '../../../hooks/useForm'; +import { DialogCreationCopy, nameRegex } from '../../constants'; +import { DialogWrapper, DialogTypes } from '../DialogWrapper'; +import { StorageFolder } from '../../store/types'; +import { FieldConfig, useForm } from '../../hooks/useForm'; + +import { LocationSelectContent } from './LocationSelectContent'; + +// -------------------- Styles -------------------- // + +const textFieldlabel = { + label: { + root: [ + { + fontWeight: FontWeights.semibold, + }, + ], + }, +}; + +const name = { + subComponentStyles: textFieldlabel, +}; + +const description = { + subComponentStyles: textFieldlabel, +}; + +const halfstack = { + root: [ + { + flexBasis: '50%', + }, + ], +}; + +const stackinput = { + root: [ + { + marginBottom: '1rem', + }, + ], +}; + +// -------------------- DefineConversation -------------------- // -import { name, description, halfstack, stackinput } from './styles'; const MAXTRYTIMES = 10000; interface DefineConversationFormData { diff --git a/Composer/packages/client/src/components/CreationFlow/DefineConversation/styles.ts b/Composer/packages/client/src/components/CreationFlow/DefineConversation/styles.ts deleted file mode 100644 index c8b8adaceb..0000000000 --- a/Composer/packages/client/src/components/CreationFlow/DefineConversation/styles.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { FontWeights } from '@uifabric/styling'; - -export const textFieldlabel = { - label: { - root: [ - { - fontWeight: FontWeights.semibold, - }, - ], - }, -}; - -export const name = { - subComponentStyles: textFieldlabel, -}; - -export const description = { - subComponentStyles: textFieldlabel, -}; - -export const locationBrowse = { - root: { - marginTop: '20px', - }, - subComponentStyles: textFieldlabel, -}; - -export const locationOnly = { - subComponentStyles: textFieldlabel, -}; - -export const halfstack = { - root: [ - { - flexBasis: '50%', - }, - ], -}; - -export const stackinput = { - root: [ - { - marginBottom: '1rem', - }, - ], -}; diff --git a/Composer/packages/client/src/components/CreationFlow/LocationBrowser/FileSelector.tsx b/Composer/packages/client/src/components/CreationFlow/FileSelector.tsx similarity index 91% rename from Composer/packages/client/src/components/CreationFlow/LocationBrowser/FileSelector.tsx rename to Composer/packages/client/src/components/CreationFlow/FileSelector.tsx index d6f6464378..9ac83011a5 100644 --- a/Composer/packages/client/src/components/CreationFlow/LocationBrowser/FileSelector.tsx +++ b/Composer/packages/client/src/components/CreationFlow/FileSelector.tsx @@ -4,7 +4,7 @@ /** @jsx jsx */ import path from 'path'; -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { useMemo, useState, useRef } from 'react'; import { Icon } from 'office-ui-fabric-react/lib/Icon'; import { IconButton } from 'office-ui-fabric-react/lib/Button'; @@ -25,21 +25,89 @@ import { Stack, StackItem } from 'office-ui-fabric-react/lib/Stack'; import { ComboBox, IComboBox, IComboBoxOption } from 'office-ui-fabric-react/lib/ComboBox'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import moment from 'moment'; +import { mergeStyleSets } from 'office-ui-fabric-react/lib/Styling'; -import { FileTypes, nameRegex } from '../../../constants'; -import { StorageFolder, File } from '../../../store/types'; -import { getFileIconName, calculateTimeDiff } from '../../../utils/fileUtil'; +import { FileTypes, nameRegex } from '../../constants'; +import { StorageFolder, File } from '../../store/types'; +import { getFileIconName, calculateTimeDiff } from '../../utils/fileUtil'; -import { - detailListContainer, - detailListClass, - tableCell, - content, - halfstack, - stackinput, - nameField, - editButton, -} from './styles'; +// -------------------- Styles -------------------- // + +const detailListContainer = css` + position: relative; + overflow: hidden; + flex-grow: 1; +`; + +const detailListClass = mergeStyleSets({ + fileIconHeaderIcon: { + padding: 0, + fontSize: '16px', + }, + fileIconCell: { + textAlign: 'center', + selectors: { + '&:before': { + content: '.', + display: 'inline-block', + verticalAlign: 'middle', + height: '100%', + width: '0px', + visibility: 'hidden', + }, + }, + }, + fileIconImg: { + verticalAlign: 'middle', + maxHeight: '16px', + maxWidth: '16px', + }, +}); + +const tableCell = css` + outline: none; + :focus { + outline: rgb(102, 102, 102) solid 1px; + } +`; + +export const content = css` + outline: none; + margin-top: 3px; +`; + +export const halfstack = { + root: [ + { + flexBasis: '50%', + }, + ], +}; + +export const stackinput = { + root: [ + { + marginBottom: '1rem', + }, + ], +}; + +export const editButton = { + root: { + height: 20, + }, +}; + +export const nameField = { + fieldGroup: { + height: 22, + }, + field: { + height: 22, + }, +}; + +// -------------------- FileSelector -------------------- // interface FileSelectorProps { operationMode: { diff --git a/Composer/packages/client/src/components/CreationFlow/LocationBrowser/styles.ts b/Composer/packages/client/src/components/CreationFlow/LocationBrowser/styles.ts deleted file mode 100644 index 28ef5223e6..0000000000 --- a/Composer/packages/client/src/components/CreationFlow/LocationBrowser/styles.ts +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { mergeStyleSets } from 'office-ui-fabric-react/lib/Styling'; -import { FontWeights } from '@uifabric/styling'; -import { IDropdownStyles } from 'office-ui-fabric-react/lib/Dropdown'; -export const textFieldlabel = { - root: [ - { - fontWeight: FontWeights.semibold, - }, - ], -}; - -export const dropdown: Partial = { - subComponentStyles: { - label: textFieldlabel, - panel: {}, - multiSelectItem: {}, - }, - // root: [ - // { - // marginTop: '2rem', - // }, - // ], -}; - -export const backIcon = css` - font-size: 20px; - cursor: pointer; - transform: rotate(90deg); - width: 20px; - height: 20px; - margin: 18px 0px 0px 3px; - padding: 8px; - &:hover { - background-color: rgb(244, 244, 244); - } -`; - -export const detailListContainer = css` - position: relative; - overflow: hidden; - flex-grow: 1; -`; - -export const fileSelectorContainer = css` - height: 300px; - display: flex; - flex-direction: column; -`; - -export const pathNav = css` - display: flex; -`; - -export const loading = css` - height: 50vh; - width: 600px; -`; - -export const detailListClass = mergeStyleSets({ - fileIconHeaderIcon: { - padding: 0, - fontSize: '16px', - }, - fileIconCell: { - textAlign: 'center', - selectors: { - '&:before': { - content: '.', - display: 'inline-block', - verticalAlign: 'middle', - height: '100%', - width: '0px', - visibility: 'hidden', - }, - }, - }, - fileIconImg: { - verticalAlign: 'middle', - maxHeight: '16px', - maxWidth: '16px', - }, -}); - -export const tableCell = css` - outline: none; - :focus { - outline: rgb(102, 102, 102) solid 1px; - } -`; - -export const content = css` - outline: none; - margin-top: 3px; -`; - -export const halfstack = { - root: [ - { - flexBasis: '50%', - }, - ], -}; - -export const stackinput = { - root: [ - { - marginBottom: '1rem', - }, - ], -}; - -export const editButton = { - root: { - height: 20, - }, -}; - -export const nameField = { - fieldGroup: { - height: 22, - }, - field: { - height: 22, - }, -}; diff --git a/Composer/packages/client/src/components/CreationFlow/LocationBrowser/LocationSelectContent.tsx b/Composer/packages/client/src/components/CreationFlow/LocationSelectContent.tsx similarity index 82% rename from Composer/packages/client/src/components/CreationFlow/LocationBrowser/LocationSelectContent.tsx rename to Composer/packages/client/src/components/CreationFlow/LocationSelectContent.tsx index 0d3f5e9204..63f505db67 100644 --- a/Composer/packages/client/src/components/CreationFlow/LocationBrowser/LocationSelectContent.tsx +++ b/Composer/packages/client/src/components/CreationFlow/LocationSelectContent.tsx @@ -3,18 +3,32 @@ /** @jsx jsx */ import formatMessage from 'format-message'; -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { useContext, useRef } from 'react'; import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner'; -import { CreationFlowStatus } from '../../../constants'; -import { File } from '../../../store/types'; -import { StoreContext } from '../../../store'; -import { FileTypes } from '../../../constants'; -import { StorageFolder } from '../../../store/types'; +import { CreationFlowStatus } from '../../constants'; +import { File } from '../../store/types'; +import { StoreContext } from '../../store'; +import { FileTypes } from '../../constants'; +import { StorageFolder } from '../../store/types'; import { FileSelector } from './FileSelector'; -import { loading, fileSelectorContainer } from './styles'; + +// -------------------- Styles -------------------- // + +const fileSelectorContainer = css` + height: 300px; + display: flex; + flex-direction: column; +`; + +const loading = css` + height: 50vh; + width: 600px; +`; + +// -------------------- LocationSelectContent -------------------- // interface LocationSelectContentProps { operationMode: { diff --git a/Composer/packages/client/src/components/CreationFlow/OpenProject/OpenProject.tsx b/Composer/packages/client/src/components/CreationFlow/OpenProject.tsx similarity index 81% rename from Composer/packages/client/src/components/CreationFlow/OpenProject/OpenProject.tsx rename to Composer/packages/client/src/components/CreationFlow/OpenProject.tsx index e428828596..fc29063f8b 100644 --- a/Composer/packages/client/src/components/CreationFlow/OpenProject/OpenProject.tsx +++ b/Composer/packages/client/src/components/CreationFlow/OpenProject.tsx @@ -9,11 +9,11 @@ import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; import formatMessage from 'format-message'; import { RouteComponentProps } from '@reach/router'; -import { DialogCreationCopy } from '../../../constants'; -import { DialogWrapper } from '../../DialogWrapper/DialogWrapper'; -import { DialogTypes } from '../../DialogWrapper/styles'; -import { LocationSelectContent } from '../LocationBrowser/LocationSelectContent'; -import { StorageFolder } from '../../../store/types'; +import { DialogCreationCopy } from '../../constants'; +import { DialogWrapper, DialogTypes } from '../DialogWrapper'; +import { StorageFolder } from '../../store/types'; + +import { LocationSelectContent } from './LocationSelectContent'; interface OpenProjectProps extends RouteComponentProps<{}> { focusedStorageFolder: StorageFolder; onOpen: (path: string, storage: string) => void; diff --git a/Composer/packages/client/src/components/DialogWrapper/styles.ts b/Composer/packages/client/src/components/DialogWrapper.tsx similarity index 56% rename from Composer/packages/client/src/components/DialogWrapper/styles.ts rename to Composer/packages/client/src/components/DialogWrapper.tsx index 60060d27e8..02d40c23cc 100644 --- a/Composer/packages/client/src/components/DialogWrapper/styles.ts +++ b/Composer/packages/client/src/components/DialogWrapper.tsx @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import React, { useEffect, useState } from 'react'; +import { Dialog, DialogType, IDialogProps } from 'office-ui-fabric-react/lib/Dialog'; import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; import { FontSizes } from '@uifabric/fluent-theme'; import { IDialogContentStyles } from 'office-ui-fabric-react/lib/Dialog'; @@ -11,7 +13,9 @@ export enum DialogTypes { DesignFlow, } -export const styles: { +// -------------------- Styles -------------------- // + +const styles: { [DialogTypes.DesignFlow]: { dialog: Partial; modal: Partial }; [DialogTypes.CreateFlow]: { dialog: Partial; modal: Partial }; } = { @@ -54,3 +58,44 @@ export const styles: { }, }, }; + +interface DialogWrapperProps extends Pick { + isOpen: boolean; + title: string; + subText: string; + dialogType: DialogTypes; +} + +export const DialogWrapper: React.FC = (props) => { + const { isOpen, onDismiss, title, subText, children, dialogType } = props; + const [currentStyle, setStyle] = useState(styles[dialogType]); + + useEffect(() => { + if (dialogType) { + setStyle(styles[dialogType]); + } + }, [dialogType]); + + if (!isOpen) { + return null; + } + + return ( + + {children} + + ); +}; diff --git a/Composer/packages/client/src/components/DialogWrapper/DialogWrapper.tsx b/Composer/packages/client/src/components/DialogWrapper/DialogWrapper.tsx deleted file mode 100644 index 986e601173..0000000000 --- a/Composer/packages/client/src/components/DialogWrapper/DialogWrapper.tsx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import React, { useEffect, useState } from 'react'; -import { Dialog, DialogType, IDialogProps } from 'office-ui-fabric-react/lib/Dialog'; - -import { styles, DialogTypes } from './styles'; - -interface DialogWrapperProps extends Pick { - isOpen: boolean; - title: string; - subText: string; - dialogType: DialogTypes; -} - -export const DialogWrapper: React.FC = (props) => { - const { isOpen, onDismiss, title, subText, children, dialogType } = props; - const [currentStyle, setStyle] = useState(styles[dialogType]); - - useEffect(() => { - if (dialogType) { - setStyle(styles[dialogType]); - } - }, [dialogType]); - - if (!isOpen) { - return null; - } - - return ( - - {children} - - ); -}; diff --git a/Composer/packages/client/src/components/ErrorBoundary/ErrorBoundary.tsx b/Composer/packages/client/src/components/ErrorBoundary.tsx similarity index 97% rename from Composer/packages/client/src/components/ErrorBoundary/ErrorBoundary.tsx rename to Composer/packages/client/src/components/ErrorBoundary.tsx index 6818ec29d1..1826644dac 100644 --- a/Composer/packages/client/src/components/ErrorBoundary/ErrorBoundary.tsx +++ b/Composer/packages/client/src/components/ErrorBoundary.tsx @@ -6,8 +6,9 @@ import React, { Component } from 'react'; import formatMessage from 'format-message'; -import { StoreContext } from '../../store'; -import { ErrorPopup } from '../ErrorPopup/ErrorPopup'; +import { StoreContext } from '../store'; + +import { ErrorPopup } from './ErrorPopup/ErrorPopup'; const githubIssueUrl = `https://github.com/microsoft/BotFramework-Composer/issues`; const errorToShow = { diff --git a/Composer/packages/client/src/components/Header/Header.tsx b/Composer/packages/client/src/components/Header.tsx similarity index 54% rename from Composer/packages/client/src/components/Header/Header.tsx rename to Composer/packages/client/src/components/Header.tsx index 564e98c553..e36ada9442 100644 --- a/Composer/packages/client/src/components/Header/Header.tsx +++ b/Composer/packages/client/src/components/Header.tsx @@ -2,16 +2,74 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import formatMessage from 'format-message'; import { IconButton, IButtonStyles } from 'office-ui-fabric-react/lib/Button'; import { useContext, useCallback, Fragment } from 'react'; +import { SharedColors } from '@uifabric/fluent-theme'; +import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; -import composerIcon from '../../images/composerIcon.svg'; -import { AppUpdaterStatus } from '../../constants'; -import { StoreContext } from '../../store'; +import composerIcon from '../images/composerIcon.svg'; +import { AppUpdaterStatus } from '../constants'; +import { StoreContext } from '../store'; -import { updateAvailableIcon, headerContainer, title, botName, divider, headerTextContainer } from './styles'; +// -------------------- Styles -------------------- // + +const headerContainer = css` + position: relative; + background: ${SharedColors.cyanBlue10}; + height: 50px; + display: flex; + flex-direction: row; + align-items: center; +`; + +const title = css` + margin-left: 20px; + font-weight: ${FontWeights.semibold}; + font-size: 16px; + color: #fff; +`; + +const botName = css` + margin-left: 20px; + font-size: 16px; + color: #fff; +`; + +const divider = css` + height: 24px; + border-right: 1px solid #979797; + margin: 0px 0px 0px 20px; +`; + +const updateAvailableIcon = { + icon: { + color: '#FFF', + fontSize: '20px', + }, + root: { + position: 'absolute', + height: '20px', + width: '20px', + top: 'calc(50% - 10px)', + right: '20px', + }, + rootHovered: { + backgroundColor: 'transparent', + }, + rootPressed: { + backgroundColor: 'transparent', + }, +}; + +const headerTextContainer = css` + display: flex; + flex-direction: row; + flex-wrap: wrap; +`; + +// -------------------- Header -------------------- // type Props = { botName: string; diff --git a/Composer/packages/client/src/components/Header/styles.js b/Composer/packages/client/src/components/Header/styles.js deleted file mode 100644 index 523341ba12..0000000000 --- a/Composer/packages/client/src/components/Header/styles.js +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; -import { SharedColors } from '@uifabric/fluent-theme'; -import { css } from '@emotion/core'; - -export const headerContainer = css` - position: relative; - background: ${SharedColors.cyanBlue10}; - height: 50px; - display: flex; - flex-direction: row; - align-items: center; -`; - -export const title = css` - margin-left: 20px; - font-weight: ${FontWeights.semibold}; - font-size: 16px; - color: #fff; -`; - -export const botName = css` - margin-left: 20px; - font-size: 16px; - color: #fff; -`; - -export const divider = css` - height: 24px; - border-right: 1px solid #979797; - margin: 0px 0px 0px 20px; -`; - -export const updateAvailableIcon = { - icon: { - color: '#FFF', - fontSize: '20px', - }, - root: { - position: 'absolute', - height: '20px', - width: '20px', - top: 'calc(50% - 10px)', - right: '20px', - }, - rootHovered: { - backgroundColor: 'transparent', - }, - rootPressed: { - backgroundColor: 'transparent', - }, -}; - -export const headerTextContainer = css` - display: flex; - flex-direction: row; - flex-wrap: wrap; -`; diff --git a/Composer/packages/client/src/components/LoadingSpinner/LoadingSpinner.tsx b/Composer/packages/client/src/components/LoadingSpinner.tsx similarity index 69% rename from Composer/packages/client/src/components/LoadingSpinner/LoadingSpinner.tsx rename to Composer/packages/client/src/components/LoadingSpinner.tsx index a2729b2544..f1c305a6c8 100644 --- a/Composer/packages/client/src/components/LoadingSpinner/LoadingSpinner.tsx +++ b/Composer/packages/client/src/components/LoadingSpinner.tsx @@ -2,12 +2,18 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React from 'react'; import { Spinner } from 'office-ui-fabric-react/lib/Spinner'; import formatMessage from 'format-message'; -import { container } from './styles'; +const container = css` + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; +`; export const LoadingSpinner: React.FC = () => { return ( diff --git a/Composer/packages/client/src/components/LoadingSpinner/styles.ts b/Composer/packages/client/src/components/LoadingSpinner/styles.ts deleted file mode 100644 index 7a3c404e81..0000000000 --- a/Composer/packages/client/src/components/LoadingSpinner/styles.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; - -export const container = css` - height: 100%; - width: 100%; - display: flex; - align-items: center; - justify-content: center; -`; diff --git a/Composer/packages/client/src/components/MainContent/styles.js b/Composer/packages/client/src/components/MainContent.tsx similarity index 65% rename from Composer/packages/client/src/components/MainContent/styles.js rename to Composer/packages/client/src/components/MainContent.tsx index a1ff9cd716..b0e5370a60 100644 --- a/Composer/packages/client/src/components/MainContent/styles.js +++ b/Composer/packages/client/src/components/MainContent.tsx @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { css } from '@emotion/core'; +/** @jsx jsx */ +import { jsx, css } from '@emotion/core'; const contentTopMargin = 10; const contentBottomMargin = 0; @@ -13,3 +14,9 @@ export const contentContainer = css` margin-bottom: ${contentBottomMargin}px; margin-left: 20px; `; + +export const MainContent = (props: { children: Element }) => ( + + {props.children} + +); diff --git a/Composer/packages/client/src/components/MainContent/MainContent.tsx b/Composer/packages/client/src/components/MainContent/MainContent.tsx deleted file mode 100644 index d642b36ae1..0000000000 --- a/Composer/packages/client/src/components/MainContent/MainContent.tsx +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** @jsx jsx */ -import { jsx } from '@emotion/core'; - -import { contentContainer } from './styles'; - -export const MainContent = (props: { children: Element }) => ( - - {props.children} - -); diff --git a/Composer/packages/client/src/components/Modal/AlertDialog.tsx b/Composer/packages/client/src/components/Modal/AlertDialog.tsx index 88d56f0f8d..e6d7467836 100644 --- a/Composer/packages/client/src/components/Modal/AlertDialog.tsx +++ b/Composer/packages/client/src/components/Modal/AlertDialog.tsx @@ -2,14 +2,36 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; import ReactDOM from 'react-dom'; -import { builtInStyles } from './styles'; import { dialogStyle } from './dialogStyle'; +// -------------------- Styles -------------------- // + +export const builtInStyles = { + [dialogStyle.normal]: css` + padding: 15px; + margin-bottom: 20px; + white-space: pre-line; + `, + [dialogStyle.console]: css` + background: #000; + max-height: 90px; + overflow-y: auto; + font-size: 16px; + line-height: 23px; + color: #fff; + padding: 10px 15px; + margin-bottom: 20px; + white-space: pre-line; + `, +}; + +// -------------------- AlertDialog -------------------- // + type Props = { setting: { title: string; diff --git a/Composer/packages/client/src/components/Modal/ConfirmDialog.tsx b/Composer/packages/client/src/components/Modal/ConfirmDialog.tsx index 19d8a03bc9..617e912657 100644 --- a/Composer/packages/client/src/components/Modal/ConfirmDialog.tsx +++ b/Composer/packages/client/src/components/Modal/ConfirmDialog.tsx @@ -2,16 +2,68 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import * as React from 'react'; import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox'; import ReactDOM from 'react-dom'; +import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; +import { SharedColors } from '@uifabric/fluent-theme'; -import { builtInStyles, dialog, dialogModal, confirmationContainer } from './styles'; import { dialogStyle } from './dialogStyle'; +// -------------------- Styles -------------------- // + +const builtInStyles = { + [dialogStyle.normal]: css` + padding: 15px; + margin-bottom: 20px; + white-space: pre-line; + `, + [dialogStyle.console]: css` + background: #000; + max-height: 90px; + overflow-y: auto; + font-size: 16px; + line-height: 23px; + color: #fff; + padding: 10px 15px; + margin-bottom: 20px; + white-space: pre-line; + `, +}; + +export const dialog = { + title: { + fontWeight: FontWeights.bold, + }, +}; + +export const dialogModal = { + main: { + maxWidth: '600px !important', + }, +}; + +export const confirmationContainer = css` + display: flex; + flex-direction: column; +`; + +export const confirmation = css` + padding: 15px; + margin-bottom: 20px; + white-space: pre-line; + background: ${SharedColors.red10}; +`; + +export const confirmationContent = css` + width: 500px; +`; + +// -------------------- ConfirmDialog -------------------- // + interface ConfirmDialogProps { onCancel: () => void; onConfirm: () => void; diff --git a/Composer/packages/client/src/components/Modal/DisplayManifestModal.tsx b/Composer/packages/client/src/components/Modal/DisplayManifestModal.tsx index 6b3cef5970..c333a393ad 100644 --- a/Composer/packages/client/src/components/Modal/DisplayManifestModal.tsx +++ b/Composer/packages/client/src/components/Modal/DisplayManifestModal.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { useContext, useEffect, useMemo } from 'react'; import { ContextualMenu } from 'office-ui-fabric-react/lib/ContextualMenu'; import { Dialog, DialogFooter, DialogType } from 'office-ui-fabric-react/lib/components/Dialog'; @@ -10,10 +10,38 @@ import { IDragOptions } from 'office-ui-fabric-react/lib/Modal'; import { JsonEditor } from '@bfc/code-editor'; import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; import formatMessage from 'format-message'; +import { FontSizes } from '@uifabric/fluent-theme'; +import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; +import { IDialogContentStyles } from 'office-ui-fabric-react/lib/Dialog'; +import { IModalStyles } from 'office-ui-fabric-react/lib/Modal'; import { StoreContext } from '../../store'; -import { displayManifest as styles } from './styles'; +// -------------------- Styles -------------------- // + +const styles: { content: any; dialog: Partial; modal: Partial } = { + content: css` + height: 675px; + padding-bottom: 4px; + `, + dialog: { + title: { + fontSize: FontSizes.size20, + fontWeight: FontWeights.bold, + paddingBottom: '11px', + paddingTop: '14px', + }, + }, + modal: { + main: { + height: '800px !important', + maxWidth: '80% !important', + width: '600px !important', + }, + }, +}; + +// -------------------- DisplayManifestModal -------------------- // const dragOptions: IDragOptions = { moveMenuItemText: formatMessage('Move'), diff --git a/Composer/packages/client/src/components/Modal/styles.ts b/Composer/packages/client/src/components/Modal/styles.ts deleted file mode 100644 index 8bd4516217..0000000000 --- a/Composer/packages/client/src/components/Modal/styles.ts +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { FontSizes, SharedColors } from '@uifabric/fluent-theme'; -import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; -import { IDialogContentStyles } from 'office-ui-fabric-react/lib/Dialog'; -import { IModalStyles } from 'office-ui-fabric-react/lib/Modal'; - -import { dialogStyle } from './dialogStyle'; - -export const displayManifest: { content: any; dialog: Partial; modal: Partial } = { - content: css` - height: 675px; - padding-bottom: 4px; - `, - dialog: { - title: { - fontSize: FontSizes.size20, - fontWeight: FontWeights.bold, - paddingBottom: '11px', - paddingTop: '14px', - }, - }, - modal: { - main: { - height: '800px !important', - maxWidth: '80% !important', - width: '600px !important', - }, - }, -}; - -export const builtInStyles = { - [dialogStyle.normal]: css` - padding: 15px; - margin-bottom: 20px; - white-space: pre-line; - `, - [dialogStyle.console]: css` - background: #000; - max-height: 90px; - overflow-y: auto; - font-size: 16px; - line-height: 23px; - color: #fff; - padding: 10px 15px; - margin-bottom: 20px; - white-space: pre-line; - `, -}; - -export const dialog = { - title: { - fontWeight: FontWeights.bold, - }, -}; - -export const dialogModal = { - main: { - maxWidth: '600px !important', - }, -}; - -export const confirmationContainer = css` - display: flex; - flex-direction: column; -`; - -export const confirmation = css` - padding: 15px; - margin-bottom: 20px; - white-space: pre-line; - background: ${SharedColors.red10}; -`; - -export const confirmationContent = css` - width: 500px; -`; diff --git a/Composer/packages/client/src/components/NavItem/NavItem.tsx b/Composer/packages/client/src/components/NavItem.tsx similarity index 63% rename from Composer/packages/client/src/components/NavItem/NavItem.tsx rename to Composer/packages/client/src/components/NavItem.tsx index 6f1311943f..1f3778f903 100644 --- a/Composer/packages/client/src/components/NavItem/NavItem.tsx +++ b/Composer/packages/client/src/components/NavItem.tsx @@ -7,11 +7,66 @@ import { useCallback, useContext } from 'react'; import { Link } from '@reach/router'; import { Icon } from 'office-ui-fabric-react/lib/Icon'; import { TooltipHost, DirectionalHint } from 'office-ui-fabric-react/lib/Tooltip'; - -import { StoreContext } from '../../store'; -import { useLocation, useRouterCache } from '../../utils/hooks'; - -import { link, icon } from './styles'; +import { FontSizes } from '@uifabric/fluent-theme'; +import { NeutralColors, CommunicationColors } from '@uifabric/fluent-theme'; +import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; + +import { StoreContext } from '../store'; +import { useLocation, useRouterCache } from '../utils/hooks'; + +// -------------------- Styles -------------------- // + +const link = (active: boolean, disabled: boolean) => css` + display: flex; + align-items: center; + text-decoration: none; + color: ${disabled ? '#999' : '#4f4f4f'}; + position: relative; + + width: 220px; + + ${active + ? `background-color: ${NeutralColors.white}; + + border-left: 3px solid ${CommunicationColors.primary}; + ` + : ` + background-color: transparent; + `} + + ${disabled + ? `pointer-events: none;` + : `&:hover { + background-color: ${NeutralColors.gray50}; + } + &:focus { + outline: none; + .ms-Fabric--isFocusVisible &::after { + content: ""; + position: absolute; + z-index: 1; + border: 1px solid ${NeutralColors.white}; + border-image: initial; + outline: rgb(102, 102, 102) solid 1px; + } + } + `} +`; + +const icon = (active: boolean, disabled: boolean) => + ({ + root: { + color: active ? '#000' : disabled ? '#999' : '#4f4f4f', + padding: '8px 12px', + marginLeft: active ? '1px' : '4px', + marginRight: '12px', + boxSizing: 'border-box', + fontSize: `${FontSizes.size16}`, + width: '40px', + }, + } as IButtonStyles); + +// -------------------- NavItem -------------------- // /** * @param to The string URI to link to. Supports relative and absolute URIs. diff --git a/Composer/packages/client/src/components/NavItem/styles.ts b/Composer/packages/client/src/components/NavItem/styles.ts deleted file mode 100644 index 89e1d919f2..0000000000 --- a/Composer/packages/client/src/components/NavItem/styles.ts +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { FontSizes } from '@uifabric/fluent-theme'; -import { NeutralColors, CommunicationColors } from '@uifabric/fluent-theme'; -import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; - -export const link = (active: boolean, disabled: boolean) => css` - display: flex; - align-items: center; - text-decoration: none; - color: ${disabled ? '#999' : '#4f4f4f'}; - position: relative; - - width: 220px; - - ${active - ? `background-color: ${NeutralColors.white}; - - border-left: 3px solid ${CommunicationColors.primary}; - ` - : ` - background-color: transparent; - `} - - ${disabled - ? `pointer-events: none;` - : `&:hover { - background-color: ${NeutralColors.gray50}; - } - &:focus { - outline: none; - .ms-Fabric--isFocusVisible &::after { - content: ""; - position: absolute; - z-index: 1; - border: 1px solid ${NeutralColors.white}; - border-image: initial; - outline: rgb(102, 102, 102) solid 1px; - } - } - `} -`; - -export const icon = (active: boolean, disabled: boolean) => - ({ - root: { - color: active ? '#000' : disabled ? '#999' : '#4f4f4f', - padding: '8px 12px', - marginLeft: active ? '1px' : '4px', - marginRight: '12px', - boxSizing: 'border-box', - fontSize: `${FontSizes.size16}`, - width: '40px', - }, - } as IButtonStyles); diff --git a/Composer/packages/client/src/components/NavTree/NavTree.tsx b/Composer/packages/client/src/components/NavTree.tsx similarity index 56% rename from Composer/packages/client/src/components/NavTree/NavTree.tsx rename to Composer/packages/client/src/components/NavTree.tsx index 209e58e3e9..3ae4334844 100644 --- a/Composer/packages/client/src/components/NavTree/NavTree.tsx +++ b/Composer/packages/client/src/components/NavTree.tsx @@ -2,15 +2,63 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { useContext } from 'react'; import { Resizable, ResizeCallback } from 're-resizable'; import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; +import { FontWeights, FontSizes } from 'office-ui-fabric-react/lib/Styling'; +import { NeutralColors } from '@uifabric/fluent-theme'; +import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; +import { mergeStyleSets } from 'office-ui-fabric-react/lib/Styling'; -import { StoreContext } from '../../store'; -import { navigateTo } from '../../utils/navigation'; +import { navigateTo } from '../utils/navigation'; +import { StoreContext } from '../store'; -import { root, itemNotSelected, itemSelected } from './styles'; +// -------------------- Styles -------------------- // + +const root = css` + width: 100%; + height: 100%; + border-right: 1px solid #c4c4c4; + box-sizing: border-box; + overflow-y: auto; + overflow-x: hidden; + .ms-List-cell { + min-height: 36px; + } +`; + +const itemBase: IButtonStyles = { + root: { + background: NeutralColors.white, + fontWeight: FontWeights.semilight, + height: '32px', + width: '100%', + fontSize: FontSizes.small, + paddingLeft: '16px', + paddingRight: 0, + border: 0, + textAlign: 'left', + marginLeft: 0, + marginRight: 0, + }, +}; + +const itemNotSelected: IButtonStyles = mergeStyleSets(itemBase, { + root: { + background: NeutralColors.white, + fontWeight: FontWeights.semilight, + }, +}); + +const itemSelected: IButtonStyles = mergeStyleSets(itemBase, { + root: { + background: NeutralColors.gray20, + fontWeight: FontWeights.semibold, + }, +}); + +// -------------------- NavTree -------------------- // export interface INavTreeItem { id: string; diff --git a/Composer/packages/client/src/components/NavTree/styles.ts b/Composer/packages/client/src/components/NavTree/styles.ts deleted file mode 100644 index a86b5e391d..0000000000 --- a/Composer/packages/client/src/components/NavTree/styles.ts +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -import { css } from '@emotion/core'; -import { FontWeights, FontSizes } from 'office-ui-fabric-react/lib/Styling'; -import { NeutralColors } from '@uifabric/fluent-theme'; -import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; -import { mergeStyleSets } from 'office-ui-fabric-react/lib/Styling'; - -export const root = css` - width: 100%; - height: 100%; - border-right: 1px solid #c4c4c4; - box-sizing: border-box; - overflow-y: auto; - overflow-x: hidden; - .ms-List-cell { - min-height: 36px; - } -`; - -const itemBase: IButtonStyles = { - root: { - background: NeutralColors.white, - fontWeight: FontWeights.semilight, - height: '32px', - width: '100%', - fontSize: FontSizes.small, - paddingLeft: '16px', - paddingRight: 0, - border: 0, - textAlign: 'left', - marginLeft: 0, - marginRight: 0, - }, -}; - -export const itemNotSelected: IButtonStyles = mergeStyleSets(itemBase, { - root: { - background: NeutralColors.white, - fontWeight: FontWeights.semilight, - }, -}); -export const itemSelected: IButtonStyles = mergeStyleSets(itemBase, { - root: { - background: NeutralColors.gray20, - fontWeight: FontWeights.semibold, - }, -}); diff --git a/Composer/packages/client/src/components/NotFound.jsx b/Composer/packages/client/src/components/NotFound.jsx new file mode 100644 index 0000000000..3fca8a44dc --- /dev/null +++ b/Composer/packages/client/src/components/NotFound.jsx @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** @jsx jsx */ +import { jsx, css } from '@emotion/core'; +import formatMessage from 'format-message'; + +import { BASEPATH } from '../constants'; + +// -------------------- Styles -------------------- // + +export const notfoundbody = css` + position: absolute; + top: 0; + bottom: 0; + width: 100%; + display: flex; + justify-content: center; + vertical-align: middle; +`; + +export const notfoundcontainer = css` + height: 80%; + display: flex; + justify-content: center; + vertical-align: middle; + flex-direction: column; + text-align: center; +`; + +export const description = css` + font-size: 34px; +`; + +export const notfoundicon = css` + font-size: 76px; +`; + +// -------------------- NotFound -------------------- // + +export const NotFound = (props) => { + const { uri } = props; + if (uri === BASEPATH) { + return null; + } + + return ( + + + + {formatMessage("The page you are looking for can't be found.")} + {'404'} + + + + ); +}; diff --git a/Composer/packages/client/src/components/NotFound/NotFound.jsx b/Composer/packages/client/src/components/NotFound/NotFound.jsx deleted file mode 100644 index 31736f4fac..0000000000 --- a/Composer/packages/client/src/components/NotFound/NotFound.jsx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** @jsx jsx */ -import { jsx } from '@emotion/core'; -import formatMessage from 'format-message'; - -import { BASEPATH } from '../../constants'; - -import { notfoundbody, notfoundcontainer, description, notfoundicon } from './style'; - -export const NotFound = (props) => { - const { uri } = props; - if (uri === BASEPATH) { - return null; - } - - return ( - - - - {formatMessage("The page you are looking for can't be found.")} - {'404'} - - - - ); -}; diff --git a/Composer/packages/client/src/components/NotFound/style.js b/Composer/packages/client/src/components/NotFound/style.js deleted file mode 100644 index f562f91a89..0000000000 --- a/Composer/packages/client/src/components/NotFound/style.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; - -export const notfoundbody = css` - position: absolute; - top: 0; - bottom: 0; - width: 100%; - display: flex; - justify-content: center; - vertical-align: middle; -`; - -export const notfoundcontainer = css` - height: 80%; - display: flex; - justify-content: center; - vertical-align: middle; - flex-direction: column; - text-align: center; -`; - -export const description = css` - font-size: 34px; -`; - -export const notfoundicon = css` - font-size: 76px; -`; diff --git a/Composer/packages/client/src/components/Page.tsx b/Composer/packages/client/src/components/Page.tsx new file mode 100644 index 0000000000..1357cb3b15 --- /dev/null +++ b/Composer/packages/client/src/components/Page.tsx @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** @jsx jsx */ +import { jsx, css } from '@emotion/core'; +import React from 'react'; +import { FontWeights, FontSizes } from 'office-ui-fabric-react/lib/Styling'; + +import { ToolBar, IToolBarItem } from './ToolBar'; +import { NavTree, INavTreeItem } from './NavTree'; + +// -------------------- Styles -------------------- // + +export const root = css` + height: calc(100vh - 50px); + display: flex; + flex-direction: row; + + label: Page; +`; + +export const pageWrapper = css` + display: flex; + flex-direction: column; + flex-grow: 1; + + label: PageWrapper; +`; + +export const header = css` + padding: 5px 20px; + height: 60px; + display: flex; + flex-shrink: 0; + justify-content: space-between; + align-items: center; + + label: PageHeader; +`; + +export const headerTitle = css` + font-size: ${FontSizes.xLarge}; + font-weight: ${FontWeights.semibold}; + + label: PageHeaderTitle; +`; + +export const headerContent = css` + display: flex; + align-items: center; + + label: PageHeaderContent; +`; + +export const main = css` + margin-left: 2px; + height: calc(100vh - 165px); + display: flex; + border-top: 1px solid #dddddd; + position: relative; + nav { + ul { + margin-top: 0px; + } + } + + label: PageMain; +`; + +export const content = css` + flex: 4; + padding: 20px; + position: relative; + overflow: scroll; + + label: PageContent; +`; + +// -------------------- Page -------------------- // + +interface IPageProps { + // TODO: add type + toolbarItems: IToolBarItem[]; + navLinks: INavTreeItem[]; + title: string; + navRegionName: string; + mainRegionName: string; + onRenderHeaderContent?: () => string | JSX.Element | null; + 'data-testid'?: string; +} + +const Page: React.FC = (props) => { + const { title, navLinks, toolbarItems, onRenderHeaderContent, children, navRegionName, mainRegionName } = props; + + return ( + + + + + {title} + {onRenderHeaderContent && {onRenderHeaderContent()}} + + + + + {children} + + + + + ); +}; + +export { Page }; diff --git a/Composer/packages/client/src/components/Page/Page.tsx b/Composer/packages/client/src/components/Page/Page.tsx deleted file mode 100644 index 1521d8f7c6..0000000000 --- a/Composer/packages/client/src/components/Page/Page.tsx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** @jsx jsx */ -import { jsx } from '@emotion/core'; -import React from 'react'; - -import { ToolBar, IToolBarItem } from '../ToolBar/ToolBar'; -import { NavTree, INavTreeItem } from '../NavTree/NavTree'; - -import * as styles from './styles'; - -interface IPageProps { - // TODO: add type - toolbarItems: IToolBarItem[]; - navLinks: INavTreeItem[]; - title: string; - navRegionName: string; - mainRegionName: string; - onRenderHeaderContent?: () => string | JSX.Element | null; - 'data-testid'?: string; -} - -const Page: React.FC = (props) => { - const { title, navLinks, toolbarItems, onRenderHeaderContent, children, navRegionName, mainRegionName } = props; - - return ( - - - - - {title} - {onRenderHeaderContent && {onRenderHeaderContent()}} - - - - - {children} - - - - - ); -}; - -export { Page }; diff --git a/Composer/packages/client/src/components/Page/styles.ts b/Composer/packages/client/src/components/Page/styles.ts deleted file mode 100644 index 2732d57a99..0000000000 --- a/Composer/packages/client/src/components/Page/styles.ts +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { FontWeights, FontSizes } from 'office-ui-fabric-react/lib/Styling'; - -export const root = css` - height: calc(100vh - 50px); - display: flex; - flex-direction: row; - - label: Page; -`; - -export const pageWrapper = css` - display: flex; - flex-direction: column; - flex-grow: 1; - - label: PageWrapper; -`; - -export const header = css` - padding: 5px 20px; - height: 60px; - display: flex; - flex-shrink: 0; - justify-content: space-between; - align-items: center; - - label: PageHeader; -`; - -export const headerTitle = css` - font-size: ${FontSizes.xLarge}; - font-weight: ${FontWeights.semibold}; - - label: PageHeaderTitle; -`; - -export const headerContent = css` - display: flex; - align-items: center; - - label: PageHeaderContent; -`; - -export const main = css` - margin-left: 2px; - height: calc(100vh - 165px); - display: flex; - border-top: 1px solid #dddddd; - position: relative; - nav { - ul { - margin-top: 0px; - } - } - - label: PageMain; -`; - -export const content = css` - flex: 4; - padding: 20px; - position: relative; - overflow: scroll; - - label: PageContent; -`; diff --git a/Composer/packages/client/src/components/Pagination/Pagination.tsx b/Composer/packages/client/src/components/Pagination.tsx similarity index 77% rename from Composer/packages/client/src/components/Pagination/Pagination.tsx rename to Composer/packages/client/src/components/Pagination.tsx index 31b96a7698..b2e10f1629 100644 --- a/Composer/packages/client/src/components/Pagination/Pagination.tsx +++ b/Composer/packages/client/src/components/Pagination.tsx @@ -2,14 +2,36 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; import { Dropdown, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown'; import { useState, useEffect } from 'react'; import formatMessage from 'format-message'; import range from 'lodash/range'; +import { IDropdownStyles } from 'office-ui-fabric-react/lib/Dropdown'; -import { container, dropdownStyles, text } from './style'; +// -------------------- Styles -------------------- // + +export const dropdownStyles: Partial = { + dropdown: { width: 80 }, +}; + +export const container = css` + display: flex; + width: 400px; + height: 45px; + padding-top: 5px; + line-height: 30px; + background-color: transparent; + justify-content: space-around; +`; + +export const text = css` + font-size: 12px; + cursor: default; +`; + +// -------------------- Pagination -------------------- // export interface IPaginationProps { pageCount: number; diff --git a/Composer/packages/client/src/components/Pagination/style.ts b/Composer/packages/client/src/components/Pagination/style.ts deleted file mode 100644 index 166287c7ed..0000000000 --- a/Composer/packages/client/src/components/Pagination/style.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { IDropdownStyles } from 'office-ui-fabric-react/lib/Dropdown'; - -export const dropdownStyles: Partial = { - dropdown: { width: 80 }, -}; - -export const container = css` - display: flex; - width: 400px; - height: 45px; - padding-top: 5px; - line-height: 30px; - background-color: transparent; - justify-content: space-around; -`; - -export const text = css` - font-size: 12px; - cursor: default; -`; diff --git a/Composer/packages/client/src/components/ProjectTree/ProjectTree.tsx b/Composer/packages/client/src/components/ProjectTree/ProjectTree.tsx index 57aa087529..e4f7cb1af9 100644 --- a/Composer/packages/client/src/components/ProjectTree/ProjectTree.tsx +++ b/Composer/packages/client/src/components/ProjectTree/ProjectTree.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React, { useCallback, useContext, useMemo, useRef, useState } from 'react'; import { GroupedList, @@ -18,13 +18,45 @@ import formatMessage from 'format-message'; import { DialogInfo, ITrigger } from '@bfc/shared'; import { Resizable, ResizeCallback } from 're-resizable'; import debounce from 'lodash/debounce'; +import { IGroupedListStyles } from 'office-ui-fabric-react/lib/GroupedList'; +import { ISearchBoxStyles } from 'office-ui-fabric-react/lib/SearchBox'; import { StoreContext } from '../../store'; import { createSelectedPath, getFriendlyName } from '../../utils/dialogUtil'; -import { groupListStyle, root, searchBox } from './styles'; import { TreeItem } from './treeItem'; +// -------------------- Styles -------------------- // + +const groupListStyle: Partial = { + root: { + width: '100%', + boxSizing: 'border-box', + }, +}; + +const searchBox: ISearchBoxStyles = { + root: { + borderBottom: '1px solid #edebe9', + height: '45px', + borderRadius: '0px', + }, +}; + +const root = css` + width: 100%; + height: 100%; + border-right: 1px solid #c4c4c4; + box-sizing: border-box; + overflow-y: auto; + overflow-x: hidden; + .ms-List-cell { + min-height: 36px; + } +`; + +// -------------------- ProjectTree -------------------- // + function createGroupItem(dialog: DialogInfo, currentId: string, position: number) { return { key: dialog.id, diff --git a/Composer/packages/client/src/components/ProjectTree/TriggerCreationModal.tsx b/Composer/packages/client/src/components/ProjectTree/TriggerCreationModal.tsx index dadc777f03..a00ce54648 100644 --- a/Composer/packages/client/src/components/ProjectTree/TriggerCreationModal.tsx +++ b/Composer/packages/client/src/components/ProjectTree/TriggerCreationModal.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React, { useState } from 'react'; import formatMessage from 'format-message'; import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; @@ -17,8 +17,11 @@ import { PlaceHolderSectionName } from '@bfc/indexers/lib/utils/luUtil'; import { DialogInfo, SDKKinds } from '@bfc/shared'; import { LuEditor, inlineModePlaceholder } from '@bfc/code-editor'; import { IComboBoxOption } from 'office-ui-fabric-react/lib/ComboBox'; +import { FontWeights } from '@uifabric/styling'; +import { FontSizes } from '@uifabric/fluent-theme'; -import { nameRegex } from '../../constants'; +import { useStoreContext } from '../../hooks/useStoreContext'; +import { addIntent } from '../../utils/luUtil'; import { generateNewDialog, getTriggerTypes, @@ -32,10 +35,56 @@ import { getActivityTypes, regexRecognizerKey, } from '../../utils/dialogUtil'; -import { addIntent } from '../../utils/luUtil'; -import { useStoreContext } from '../../hooks/useStoreContext'; +import { nameRegex } from '../../constants'; -import { styles, dropdownStyles, dialogWindow, intent } from './styles'; +// -------------------- Styles -------------------- // + +const styles = { + dialog: { + title: { + fontWeight: FontWeights.bold, + fontSize: FontSizes.size20, + paddingTop: '14px', + paddingBottom: '11px', + }, + subText: { + fontSize: FontSizes.size14, + }, + }, + modal: { + main: { + maxWidth: '600px !important', + }, + }, +}; + +const dropdownStyles = { + label: { + fontWeight: FontWeights.semibold, + }, + dropdown: { + width: '400px', + }, + root: { + marginBottom: '20px', + }, +}; + +const dialogWindow = css` + display: flex; + flex-direction: column; + width: 400px; + min-height: 300px; +`; + +const intent = { + root: { + width: '400px', + paddingBottom: '20px', + }, +}; + +// -------------------- Validation Helpers -------------------- // const initialFormDataErrors = { $kind: '', @@ -143,6 +192,8 @@ export interface LuFilePayload { content: string; } +// -------------------- TriggerCreationModal -------------------- // + interface TriggerCreationModalProps { dialogId: string; isOpen: boolean; diff --git a/Composer/packages/client/src/components/ProjectTree/styles.ts b/Composer/packages/client/src/components/ProjectTree/styles.ts deleted file mode 100644 index 3f3cafc50c..0000000000 --- a/Composer/packages/client/src/components/ProjectTree/styles.ts +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { FontWeights } from '@uifabric/styling'; -import { NeutralColors, FontSizes } from '@uifabric/fluent-theme'; -import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; -import { IContextualMenuStyles } from 'office-ui-fabric-react/lib/ContextualMenu'; -import { ICalloutContentStyles } from 'office-ui-fabric-react/lib/Callout'; -import { IGroupedListStyles } from 'office-ui-fabric-react/lib/GroupedList'; -import { ISearchBoxStyles } from 'office-ui-fabric-react/lib/SearchBox'; - -export const groupListStyle: Partial = { - root: { - width: '100%', - boxSizing: 'border-box', - }, -}; - -export const searchBox: ISearchBoxStyles = { - root: { - borderBottom: '1px solid #edebe9', - height: '45px', - borderRadius: '0px', - }, -}; -export const root = css` - width: 100%; - height: 100%; - border-right: 1px solid #c4c4c4; - box-sizing: border-box; - overflow-y: auto; - overflow-x: hidden; - .ms-List-cell { - min-height: 36px; - } -`; - -export const navItem = (isActive: boolean, isSubItemActive: boolean) => css` - width: 100%; - position: relative; - height: 36px; - font-size: 12px; - color: #545454; - background: ${isActive && !isSubItemActive ? '#f2f2f2' : 'transparent'}; - font-weight: ${isActive ? FontWeights.semibold : FontWeights.regular}; - &:hover { - color: #545454; - background: #f2f2f2; - - .dialog-more-btn { - visibility: visible; - } - } - &:focus { - outline: none; - .ms-Fabric--isFocusVisible &::after { - top: 0px; - right: 1px; - bottom: 0px; - left: 1px; - content: ''; - position: absolute; - z-index: 1; - border: 1px solid ${NeutralColors.white}; - border-image: initial; - outline: rgb(102, 102, 102) solid 1px; - } - } -`; - -export const itemText = (depth: number) => css` - outline: none; - :focus { - outline: rgb(102, 102, 102) solid 1px; - z-index: 1; - } - padding-left: ${depth * 16}px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - text-align: left; - cursor: pointer; - width: 100%; - - label: ProjectTreeItemContainer; -`; - -export const content = css` - outline: none; - display: flex; - align-items: center; - - label: ProjectTreeItem; -`; - -export const moreButton = (isActive: boolean): IButtonStyles => { - return { - root: { - padding: '0 4px', - alignSelf: 'stretch', - visibility: isActive ? 'visible' : 'hidden', - height: 'auto', - width: '16px', - }, - menuIcon: { - fontSize: '14px', - color: '#000', - }, - }; -}; - -export const moreMenu: Partial = { - root: { - marginTop: '-7px', - width: '100px', - }, -}; - -export const menuStyle: Partial = { - subComponentStyles: { - menuItem: {}, - callout: moreMenu, - }, -}; - -export const overflowSet = css` - width: 100%; - height: 100%; - padding-left: 12px; - padding-right: 12px; - box-sizing: border-box; - line-height: 36px; - justify-content: space-between; - display: flex; - justify-content: space-between; -`; - -export const styles = { - dialog: { - title: { - fontWeight: FontWeights.bold, - fontSize: FontSizes.size20, - paddingTop: '14px', - paddingBottom: '11px', - }, - subText: { - fontSize: FontSizes.size14, - }, - }, - modal: { - main: { - maxWidth: '600px !important', - }, - }, -}; - -export const dropdownStyles = { - label: { - fontWeight: FontWeights.semibold, - }, - dropdown: { - width: '400px', - }, - root: { - marginBottom: '20px', - }, -}; - -export const dialogWindow = css` - display: flex; - flex-direction: column; - width: 400px; - min-height: 300px; -`; - -export const textFieldlabel = { - label: { - root: [ - { - fontWeight: FontWeights.semibold, - }, - ], - }, -}; - -export const intent = { - root: { - width: '400px', - paddingBottom: '20px', - }, -}; - -export const triggerPhrases = { - root: { - width: '400px', - }, - fieldGroup: { - height: 80, - }, -}; diff --git a/Composer/packages/client/src/components/ProjectTree/treeItem.tsx b/Composer/packages/client/src/components/ProjectTree/treeItem.tsx index 1a2df298cd..6cbafd6190 100644 --- a/Composer/packages/client/src/components/ProjectTree/treeItem.tsx +++ b/Composer/packages/client/src/components/ProjectTree/treeItem.tsx @@ -2,15 +2,122 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React from 'react'; +import { FontWeights } from '@uifabric/styling'; import { OverflowSet, IOverflowSetItemProps } from 'office-ui-fabric-react/lib/OverflowSet'; import { TooltipHost, DirectionalHint } from 'office-ui-fabric-react/lib/Tooltip'; import { IconButton } from 'office-ui-fabric-react/lib/Button'; import { Icon } from 'office-ui-fabric-react/lib/Icon'; import formatMessage from 'format-message'; +import { NeutralColors } from '@uifabric/fluent-theme'; +import { IButtonStyles } from 'office-ui-fabric-react/lib/Button'; +import { IContextualMenuStyles } from 'office-ui-fabric-react/lib/ContextualMenu'; +import { ICalloutContentStyles } from 'office-ui-fabric-react/lib/Callout'; -import { moreButton, overflowSet, menuStyle, navItem, itemText, content } from './styles'; +// -------------------- Styles -------------------- // + +const itemText = (depth: number) => css` + outline: none; + :focus { + outline: rgb(102, 102, 102) solid 1px; + z-index: 1; + } + padding-left: ${depth * 16}px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-align: left; + cursor: pointer; + width: 100%; + + label: ProjectTreeItemContainer; +`; + +const content = css` + outline: none; + display: flex; + align-items: center; + + label: ProjectTreeItem; +`; + +const moreMenu: Partial = { + root: { + marginTop: '-7px', + width: '100px', + }, +}; + +const menuStyle: Partial = { + subComponentStyles: { + menuItem: {}, + callout: moreMenu, + }, +}; + +const moreButton = (isActive: boolean): IButtonStyles => { + return { + root: { + padding: '0 4px', + alignSelf: 'stretch', + visibility: isActive ? 'visible' : 'hidden', + height: 'auto', + width: '16px', + }, + menuIcon: { + fontSize: '14px', + color: '#000', + }, + }; +}; + +const navItem = (isActive: boolean, isSubItemActive: boolean) => css` + width: 100%; + position: relative; + height: 36px; + font-size: 12px; + color: #545454; + background: ${isActive && !isSubItemActive ? '#f2f2f2' : 'transparent'}; + font-weight: ${isActive ? FontWeights.semibold : FontWeights.regular}; + &:hover { + color: #545454; + background: #f2f2f2; + + .dialog-more-btn { + visibility: visible; + } + } + &:focus { + outline: none; + .ms-Fabric--isFocusVisible &::after { + top: 0px; + right: 1px; + bottom: 0px; + left: 1px; + content: ''; + position: absolute; + z-index: 1; + border: 1px solid ${NeutralColors.white}; + border-image: initial; + outline: rgb(102, 102, 102) solid 1px; + } + } +`; + +export const overflowSet = css` + width: 100%; + height: 100%; + padding-left: 12px; + padding-right: 12px; + box-sizing: border-box; + line-height: 36px; + justify-content: space-between; + display: flex; + justify-content: space-between; +`; + +// -------------------- TreeItem -------------------- // interface ITreeItemProps { link: any; diff --git a/Composer/packages/client/src/components/RequireAuth/RequireAuth.tsx b/Composer/packages/client/src/components/RequireAuth.tsx similarity index 77% rename from Composer/packages/client/src/components/RequireAuth/RequireAuth.tsx rename to Composer/packages/client/src/components/RequireAuth.tsx index 1be7875d93..9988deee7c 100644 --- a/Composer/packages/client/src/components/RequireAuth/RequireAuth.tsx +++ b/Composer/packages/client/src/components/RequireAuth.tsx @@ -2,18 +2,40 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React, { useEffect, useState, useContext } from 'react'; import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner'; import formatMessage from 'format-message'; import once from 'lodash/once'; +import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; -import { StoreContext } from '../../store'; -import { BoundAction } from '../../store/types'; +import { StoreContext } from '../store'; +import { BoundAction } from '../store/types'; -import { loading, dialog, consoleStyle } from './styles'; +// -------------------- Styles -------------------- // + +const loading = css` + display: flex; + justify-content: center; + height: 100vh; +`; + +const consoleStyle = css` + background: #000; + color: #fff; + padding: 15px; + margin-bottom: 20px; +`; + +const dialog = { + title: { + fontWeight: FontWeights.bold, + }, +}; + +// -------------------- RequireAuth -------------------- // // only attempt to login once const loginOnce = once((login: BoundAction) => { diff --git a/Composer/packages/client/src/components/RequireAuth/styles.ts b/Composer/packages/client/src/components/RequireAuth/styles.ts deleted file mode 100644 index ea32dd01e9..0000000000 --- a/Composer/packages/client/src/components/RequireAuth/styles.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { FontWeights, FontSizes } from 'office-ui-fabric-react/lib/Styling'; - -export const loading = css` - display: flex; - justify-content: center; - height: 100vh; -`; - -export const consoleStyle = css` - background: #000; - color: #fff; - padding: 15px; - margin-bottom: 20px; -`; -export const dialogSubTitle = css` - font-size: ${FontSizes.medium}; - font-weight: ${FontWeights.semibold}; -`; - -export const dialog = { - title: { - fontWeight: FontWeights.bold, - }, -}; diff --git a/Composer/packages/client/src/components/SkillForm/CreateSkillModal/styles.ts b/Composer/packages/client/src/components/SkillForm/CreateSkillModal/styles.ts deleted file mode 100644 index cfe6a2bcc9..0000000000 --- a/Composer/packages/client/src/components/SkillForm/CreateSkillModal/styles.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { FontSizes } from 'office-ui-fabric-react/lib/Styling'; -import { css } from '@emotion/core'; - -export const FormModalBody = css` - padding: 24px; -`; - -export const FormFieldManifestUrl = css` - width: 40rem; -`; - -export const FormFieldEditName = css` - width: 20rem; -`; - -export const MarginLeftSmall = css` - margin-left: ${FontSizes.small}; -`; - -export const SpinnerLabel = css` - justify-content: left; - margin-top: 0.4rem; -`; diff --git a/Composer/packages/client/src/components/SkillForm/CreateSkillModal/validateManifestUrl.ts b/Composer/packages/client/src/components/SkillForm/CreateSkillModal/validateManifestUrl.ts deleted file mode 100644 index df0a7d4291..0000000000 --- a/Composer/packages/client/src/components/SkillForm/CreateSkillModal/validateManifestUrl.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import httpClient from '../../../utils/httpUtil'; - -export async function validateManifestUrl(projectId: string, manifestUrl: string): Promise { - // skip validation if there are other local errors. - if (manifestUrl == null || manifestUrl === '') { - return; - } - - try { - await httpClient.post(`/projects/${projectId}/skill/check`, { url: manifestUrl }); - } catch (err) { - return err.response?.data.message ?? err; - } -} diff --git a/Composer/packages/client/src/components/SkillForm/types.ts b/Composer/packages/client/src/components/SkillForm/types.ts deleted file mode 100644 index 69a029c9a9..0000000000 --- a/Composer/packages/client/src/components/SkillForm/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -export interface ISkillFormData { - manifestUrl: string; - name?: string; -} - -export interface ISkillFormDataErrors { - manifestUrl?: string; - manifestUrlFetch?: string; - name?: string; -} - -export const skillUrlRegex = /^http[s]?:\/\/\w+/; -export const skillNameRegex = /^\w[-\w]*$/; diff --git a/Composer/packages/client/src/components/TestController/TestController.tsx b/Composer/packages/client/src/components/TestController/TestController.tsx index 3d889684b7..af3852efbf 100644 --- a/Composer/packages/client/src/components/TestController/TestController.tsx +++ b/Composer/packages/client/src/components/TestController/TestController.tsx @@ -2,7 +2,7 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import React, { useState, useRef, Fragment, useContext, useEffect, useCallback } from 'react'; import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; import formatMessage from 'format-message'; @@ -17,12 +17,26 @@ import useNotifications from '../../pages/notifications/useNotifications'; import { navigateTo, openInEmulator } from '../../utils/navigation'; import { PublishLuisDialog } from './publishDialog'; -import { bot, botButton } from './styles'; import { ErrorCallout } from './errorCallout'; import { EmulatorOpenButton } from './emulatorOpenButton'; import { Loading } from './loading'; import { ErrorInfo } from './errorInfo'; +// -------------------- Styles -------------------- // + +export const bot = css` + display: flex; + align-items: center; + position: relative; + height: 100%; +`; + +export const botButton = css` + margin-left: 5px; +`; + +// -------------------- TestController -------------------- // + export const TestController: React.FC = () => { const { state, actions } = useContext(StoreContext); const [modalOpen, setModalOpen] = useState(false); diff --git a/Composer/packages/client/src/components/TestController/errorCallout.tsx b/Composer/packages/client/src/components/TestController/errorCallout.tsx index 06890942d0..816d48e622 100644 --- a/Composer/packages/client/src/components/TestController/errorCallout.tsx +++ b/Composer/packages/client/src/components/TestController/errorCallout.tsx @@ -2,14 +2,36 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import formatMessage from 'format-message'; import { Callout } from 'office-ui-fabric-react/lib/Callout'; import { Stack } from 'office-ui-fabric-react/lib/Stack'; import { Link } from 'office-ui-fabric-react/lib/Link'; import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; +import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; +import { FontSizes } from '@uifabric/fluent-theme'; + +// -------------------- Styles -------------------- // + +const calloutLabel = css` + font-size: ${FontSizes.size18}; + font-weight: ${FontWeights.bold}; +`; + +const calloutContainer = css` + width: 400px; + padding: 10px; +`; + +const calloutDescription = css``; + +const calloutLink = css` + margin-top: 24px; + margin-bottom: 24px; +`; + +// -------------------- ErrorCallout -------------------- // -import { calloutLabel, calloutDescription, calloutContainer, calloutLink } from './styles'; export interface IErrorCalloutProps { onDismiss: () => void; onTry: () => void; diff --git a/Composer/packages/client/src/components/TestController/errorInfo.tsx b/Composer/packages/client/src/components/TestController/errorInfo.tsx index 6bf36121e5..cf900b6ca6 100644 --- a/Composer/packages/client/src/components/TestController/errorInfo.tsx +++ b/Composer/packages/client/src/components/TestController/errorInfo.tsx @@ -2,10 +2,33 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { IconButton } from 'office-ui-fabric-react/lib/Button'; +import { SharedColors } from '@uifabric/fluent-theme'; -import { errorButton, errorCount, errorInfo } from './styles'; +// -------------------- Styles -------------------- // + +const errorInfo = css` + float: left; + display: flex; +`; + +const errorButton = css` + color: ${SharedColors.red20}; + &:hover { + color: ${SharedColors.red20}; + } +`; + +const errorCount = css` + height: 32px; + line-height: 32px; + font-size 16px; + cursor: pointer; + display:inline-block; +`; + +// -------------------- ErrorInfo -------------------- // interface IErrorInfoProps { hidden: boolean; diff --git a/Composer/packages/client/src/components/TestController/styles.ts b/Composer/packages/client/src/components/TestController/styles.ts deleted file mode 100644 index d17487d019..0000000000 --- a/Composer/packages/client/src/components/TestController/styles.ts +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -import { css } from '@emotion/core'; -import { FontWeights } from 'office-ui-fabric-react/lib/Styling'; -import { FontSizes, SharedColors } from '@uifabric/fluent-theme'; - -export const bot = css` - display: flex; - align-items: center; - position: relative; - height: 100%; -`; - -export const botButton = css` - margin-left: 5px; -`; - -export const errorInfo = css` - float: left; - display: flex; -`; - -export const errorButton = css` - color: ${SharedColors.red20}; - &:hover { - color: ${SharedColors.red20}; - } -`; - -export const errorCount = css` - height: 32px; - line-height: 32px; - font-size 16px; - cursor: pointer; - display:inline-block; -`; - -export const calloutLabel = css` - font-size: ${FontSizes.size18}; - font-weight: ${FontWeights.bold}; -`; - -export const calloutContainer = css` - width: 400px; - padding: 10px; -`; - -export const calloutDescription = css``; - -export const calloutAction = css``; - -export const calloutLink = css` - margin-top: 24px; - margin-bottom: 24px; -`; diff --git a/Composer/packages/client/src/components/ToolBar/ToolBar.tsx b/Composer/packages/client/src/components/ToolBar.tsx similarity index 88% rename from Composer/packages/client/src/components/ToolBar/ToolBar.tsx rename to Composer/packages/client/src/components/ToolBar.tsx index 361e7632c7..7d140ad6c6 100644 --- a/Composer/packages/client/src/components/ToolBar/ToolBar.tsx +++ b/Composer/packages/client/src/components/ToolBar.tsx @@ -2,17 +2,47 @@ // Licensed under the MIT License. /** @jsx jsx */ -import { jsx } from '@emotion/core'; +import { jsx, css } from '@emotion/core'; import { useCallback, Fragment, useMemo } from 'react'; import formatMessage from 'format-message'; import { ActionButton, CommandButton } from 'office-ui-fabric-react/lib/Button'; import { DialogInfo } from '@bfc/shared'; import get from 'lodash/get'; +import { NeutralColors } from '@uifabric/fluent-theme'; -import { useStoreContext } from '../../hooks/useStoreContext'; -import { VisualEditorAPI } from '../../pages/design/FrameAPI'; +import { useStoreContext } from '../hooks/useStoreContext'; +import { VisualEditorAPI } from '../pages/design/FrameAPI'; -import { headerSub, leftActions, rightActions, actionButton } from './styles'; +// -------------------- Styles -------------------- // + +const headerSub = css` + height: 44px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid ${NeutralColors.gray30}; +`; + +const leftActions = css` + position: relative; + display: flex; + align-items: stretch; + height: 44px; +`; + +const rightActions = css` + position: relative; + height: 44px; + margin-right: 20px; +`; + +const actionButton = css` + font-size: 16px; + margin-top: 2px; + margin-left: 15px; +`; + +// -------------------- ToolBar -------------------- // export type IToolBarItem = { type: string; diff --git a/Composer/packages/client/src/components/ToolBar/styles.js b/Composer/packages/client/src/components/ToolBar/styles.js deleted file mode 100644 index 10662fe8ec..0000000000 --- a/Composer/packages/client/src/components/ToolBar/styles.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { css } from '@emotion/core'; -import { NeutralColors } from '@uifabric/fluent-theme'; - -export const headerSub = css` - height: 44px; - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid ${NeutralColors.gray30}; -`; - -export const leftActions = css` - position: relative; - display: flex; - align-items: stretch; - height: 44px; -`; - -export const rightActions = css` - position: relative; - height: 44px; - margin-right: 20px; -`; - -export const actionButton = css` - font-size: 16px; - margin-top: 2px; - margin-left: 15px; -`; diff --git a/Composer/packages/client/src/components/Tree/styles.js b/Composer/packages/client/src/components/Tree.tsx similarity index 54% rename from Composer/packages/client/src/components/Tree/styles.js rename to Composer/packages/client/src/components/Tree.tsx index 3c69a45f29..8a92ab1abd 100644 --- a/Composer/packages/client/src/components/Tree/styles.js +++ b/Composer/packages/client/src/components/Tree.tsx @@ -1,10 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { css } from '@emotion/core'; +/** @jsx jsx */ +import { jsx, css } from '@emotion/core'; import { SharedColors } from '@uifabric/fluent-theme'; -export const container = (variant) => { +// -------------------- Styles -------------------- // + +const container = (variant) => { let height = '350px'; switch (variant) { case 'large': @@ -28,3 +31,18 @@ export const container = (variant) => { border-top: 2px solid ${SharedColors.cyanBlue10}; `; }; + +// -------------------- Tree -------------------- // + +interface ITreeProps { + variant: string; + children: Element; +} + +const Tree: React.FC = (props: ITreeProps) => ( + + {props.children} + +); + +export { Tree }; diff --git a/Composer/packages/client/src/components/Tree/Tree.tsx b/Composer/packages/client/src/components/Tree/Tree.tsx deleted file mode 100644 index 13cc846edb..0000000000 --- a/Composer/packages/client/src/components/Tree/Tree.tsx +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/** @jsx jsx */ -import { jsx } from '@emotion/core'; - -import { container } from './styles'; - -interface ITreeProps { - variant: string; - children: Element; -} - -const Tree: React.FC = (props: ITreeProps) => ( - - {props.children} - -); - -export { Tree }; diff --git a/Composer/packages/client/src/pages/design/DesignPage.tsx b/Composer/packages/client/src/pages/design/DesignPage.tsx index 1fc50c8772..2ee04e4048 100644 --- a/Composer/packages/client/src/pages/design/DesignPage.tsx +++ b/Composer/packages/client/src/pages/design/DesignPage.tsx @@ -13,16 +13,16 @@ import { ActionButton } from 'office-ui-fabric-react/lib/Button'; import { JsonEditor } from '@bfc/code-editor'; import { useTriggerApi } from '@bfc/extension'; -import { LoadingSpinner } from '../../components/LoadingSpinner/LoadingSpinner'; +import { LoadingSpinner } from '../../components/LoadingSpinner'; import { TestController } from '../../components/TestController/TestController'; import { DialogDeleting } from '../../constants'; import { createSelectedPath, deleteTrigger, getbreadcrumbLabel } from '../../utils/dialogUtil'; import { LuFilePayload } from '../../components/ProjectTree/TriggerCreationModal'; -import { Conversation } from '../../components/Conversation/Conversation'; +import { Conversation } from '../../components/Conversation'; import { dialogStyle } from '../../components/Modal/dialogStyle'; import { OpenConfirmModal } from '../../components/Modal/ConfirmDialog'; import { ProjectTree } from '../../components/ProjectTree/ProjectTree'; -import { ToolBar, IToolBarItem } from '../../components/ToolBar/ToolBar'; +import { ToolBar, IToolBarItem } from '../../components/ToolBar'; import { clearBreadcrumb } from '../../utils/navigation'; import undoHistory from '../../store/middlewares/undo/history'; import { navigateTo } from '../../utils/navigation'; @@ -42,7 +42,7 @@ import { import { VisualEditor } from './VisualEditor'; import { PropertyEditor } from './PropertyEditor'; -const CreateSkillModal = React.lazy(() => import('../../components/SkillForm/CreateSkillModal/CreateSkillModal')); +const CreateSkillModal = React.lazy(() => import('../../components/CreateSkillModal')); const CreateDialogModal = React.lazy(() => import('./createDialogModal')); const DisplayManifestModal = React.lazy(() => import('../../components/Modal/DisplayManifestModal')); const ExportSkillModal = React.lazy(() => import('./exportSkillModal')); diff --git a/Composer/packages/client/src/pages/design/createDialogModal.tsx b/Composer/packages/client/src/pages/design/createDialogModal.tsx index f4c55d9cf0..94070de347 100644 --- a/Composer/packages/client/src/pages/design/createDialogModal.tsx +++ b/Composer/packages/client/src/pages/design/createDialogModal.tsx @@ -8,8 +8,7 @@ import { Stack, StackItem } from 'office-ui-fabric-react/lib/Stack'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { DialogCreationCopy, nameRegex } from '../../constants'; -import { DialogWrapper } from '../../components/DialogWrapper/DialogWrapper'; -import { DialogTypes } from '../../components/DialogWrapper/styles'; +import { DialogWrapper, DialogTypes } from '../../components/DialogWrapper'; import { StorageFolder } from '../../store/types'; import { StoreContext } from '../../store'; import { FieldConfig, useForm } from '../../hooks/useForm'; diff --git a/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx b/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx index ef48efde81..e376952a98 100644 --- a/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx +++ b/Composer/packages/client/src/pages/design/exportSkillModal/content/FetchManifestSchema.tsx @@ -3,7 +3,7 @@ import React, { useEffect } from 'react'; -import { LoadingSpinner } from '../../../../components/LoadingSpinner/LoadingSpinner'; +import { LoadingSpinner } from '../../../../components/LoadingSpinner'; import { ContentProps } from '../constants'; export const FetchManifestSchema: React.FC = ({ completeStep, editJson, value, setSchema }) => { diff --git a/Composer/packages/client/src/pages/home/Home.tsx b/Composer/packages/client/src/pages/home/Home.tsx index 850ed5534c..56fc18022b 100644 --- a/Composer/packages/client/src/pages/home/Home.tsx +++ b/Composer/packages/client/src/pages/home/Home.tsx @@ -12,7 +12,7 @@ import { navigate } from '@reach/router'; import { StoreContext } from '../../store'; import { CreationFlowStatus } from '../../constants'; -import { ToolBar, IToolBarItem } from '../../components/ToolBar/ToolBar'; +import { ToolBar, IToolBarItem } from '../../components/ToolBar'; import * as home from './styles'; import { ItemContainer } from './ItemContainer'; diff --git a/Composer/packages/client/src/pages/language-generation/LGPage.tsx b/Composer/packages/client/src/pages/language-generation/LGPage.tsx index 3afc4ab98b..059f4c87e0 100644 --- a/Composer/packages/client/src/pages/language-generation/LGPage.tsx +++ b/Composer/packages/client/src/pages/language-generation/LGPage.tsx @@ -8,13 +8,13 @@ import formatMessage from 'format-message'; import { Toggle } from 'office-ui-fabric-react/lib/Toggle'; import { RouteComponentProps, Router } from '@reach/router'; -import { LoadingSpinner } from '../../components/LoadingSpinner/LoadingSpinner'; +import { LoadingSpinner } from '../../components/LoadingSpinner'; import { StoreContext } from '../../store'; import { actionButton } from '../language-understanding/styles'; import { navigateTo } from '../../utils/navigation'; import { TestController } from '../../components/TestController/TestController'; -import { INavTreeItem } from '../../components/NavTree/NavTree'; -import { Page } from '../../components/Page/Page'; +import { INavTreeItem } from '../../components/NavTree'; +import { Page } from '../../components/Page'; import TableView from './table-view'; const CodeEditor = React.lazy(() => import('./code-editor')); diff --git a/Composer/packages/client/src/pages/language-understanding/LUPage.tsx b/Composer/packages/client/src/pages/language-understanding/LUPage.tsx index 63bf0152ca..dee1db38e8 100644 --- a/Composer/packages/client/src/pages/language-understanding/LUPage.tsx +++ b/Composer/packages/client/src/pages/language-understanding/LUPage.tsx @@ -9,10 +9,10 @@ import { RouteComponentProps, Router } from '@reach/router'; import { StoreContext } from '../../store'; import { navigateTo } from '../../utils/navigation'; -import { LoadingSpinner } from '../../components/LoadingSpinner/LoadingSpinner'; +import { LoadingSpinner } from '../../components/LoadingSpinner'; import { TestController } from '../../components/TestController/TestController'; -import { INavTreeItem } from '../../components/NavTree/NavTree'; -import { Page } from '../../components/Page/Page'; +import { INavTreeItem } from '../../components/NavTree'; +import { Page } from '../../components/Page'; import TableView from './table-view'; import { actionButton } from './styles'; diff --git a/Composer/packages/client/src/pages/notifications/NotificationList.tsx b/Composer/packages/client/src/pages/notifications/NotificationList.tsx index 65636cb2d7..47a9ad59a7 100644 --- a/Composer/packages/client/src/pages/notifications/NotificationList.tsx +++ b/Composer/packages/client/src/pages/notifications/NotificationList.tsx @@ -17,7 +17,7 @@ import { FontIcon } from 'office-ui-fabric-react/lib/Icon'; import { useMemo, useState } from 'react'; import formatMessage from 'format-message'; -import { Pagination } from '../../components/Pagination/Pagination'; +import { Pagination } from '../../components/Pagination'; import { INotification } from './types'; import { notification, typeIcon, listRoot, icons, tableView, detailList, tableCell, content } from './styles'; diff --git a/Composer/packages/client/src/pages/notifications/Notifications.tsx b/Composer/packages/client/src/pages/notifications/Notifications.tsx index 759c98a41f..1cf8ad596e 100644 --- a/Composer/packages/client/src/pages/notifications/Notifications.tsx +++ b/Composer/packages/client/src/pages/notifications/Notifications.tsx @@ -6,7 +6,7 @@ import { jsx } from '@emotion/core'; import { useState } from 'react'; import { RouteComponentProps } from '@reach/router'; -import { ToolBar } from '../../components/ToolBar/ToolBar'; +import { ToolBar } from '../../components/ToolBar'; import { navigateTo } from '../../utils/navigation'; import { convertPathToUrl } from '../../utils/navigation'; diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx index 9b2ac68e23..5d0566c449 100644 --- a/Composer/packages/client/src/pages/publish/Publish.tsx +++ b/Composer/packages/client/src/pages/publish/Publish.tsx @@ -14,7 +14,7 @@ import { projectContainer } from '../design/styles'; import { StoreContext } from '../../store'; import { navigateTo } from '../../utils/navigation'; import { PublishTarget } from '../../store/types'; -import { ToolBar, IToolBarItem } from '../../components/ToolBar/ToolBar'; +import { ToolBar, IToolBarItem } from '../../components/ToolBar'; import { OpenConfirmModal } from '../../components/Modal/ConfirmDialog'; import { TargetList } from './targetList'; diff --git a/Composer/packages/client/src/pages/setting/SettingsPage.tsx b/Composer/packages/client/src/pages/setting/SettingsPage.tsx index fd6265c80c..c57aff95a0 100644 --- a/Composer/packages/client/src/pages/setting/SettingsPage.tsx +++ b/Composer/packages/client/src/pages/setting/SettingsPage.tsx @@ -13,8 +13,8 @@ import { StoreContext } from '../../store'; import { TestController } from '../../components/TestController/TestController'; import { OpenConfirmModal } from '../../components/Modal/ConfirmDialog'; import { navigateTo } from '../../utils/navigation'; -import { Page } from '../../components/Page/Page'; -import { INavTreeItem } from '../../components/NavTree/NavTree'; +import { Page } from '../../components/Page'; +import { INavTreeItem } from '../../components/NavTree'; import { useLocation } from '../../utils/hooks'; import { SettingsRoutes } from './router'; diff --git a/Composer/packages/client/src/pages/setting/router.tsx b/Composer/packages/client/src/pages/setting/router.tsx index 6b6f132f30..e8a2f796c1 100644 --- a/Composer/packages/client/src/pages/setting/router.tsx +++ b/Composer/packages/client/src/pages/setting/router.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { Router, Redirect } from '@reach/router'; -import { ErrorBoundary } from '../../components/ErrorBoundary/ErrorBoundary'; +import { ErrorBoundary } from '../../components/ErrorBoundary'; import { About } from '../about/About'; import { DialogSettings } from './dialog-settings/DialogSettings'; diff --git a/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx b/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx index a6f7627fd6..576e636637 100644 --- a/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx +++ b/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx @@ -10,7 +10,7 @@ import { TextField } from 'office-ui-fabric-react/lib/TextField'; import { Link } from 'office-ui-fabric-react/lib/Link'; import { RouteComponentProps } from '@reach/router'; -import { LoadingSpinner } from '../../../components/LoadingSpinner/LoadingSpinner'; +import { LoadingSpinner } from '../../../components/LoadingSpinner'; import { StoreContext } from '../../../store'; import { EjectModal } from './ejectModal'; diff --git a/Composer/packages/client/src/pages/skills/index.tsx b/Composer/packages/client/src/pages/skills/index.tsx index 6697051dbd..0b62a93822 100644 --- a/Composer/packages/client/src/pages/skills/index.tsx +++ b/Composer/packages/client/src/pages/skills/index.tsx @@ -7,11 +7,10 @@ import { RouteComponentProps } from '@reach/router'; import React, { useContext, useCallback, useState } from 'react'; import formatMessage from 'format-message'; -import { ToolBar, IToolBarItem } from '../../components/ToolBar/ToolBar'; +import { ToolBar, IToolBarItem } from '../../components/ToolBar'; import { TestController } from '../../components/TestController/TestController'; import { StoreContext } from '../../store'; -import { ISkillFormData } from '../../components/SkillForm/types'; -import CreateSkillModal from '../../components/SkillForm/CreateSkillModal/CreateSkillModal'; +import { CreateSkillModal, ISkillFormData } from '../../components/CreateSkillModal'; import { ContainerStyle, ContentHeaderStyle, HeaderText } from './styles'; import SkillSettings from './skill-settings'; diff --git a/Composer/packages/client/src/router.tsx b/Composer/packages/client/src/router.tsx index a5e4cfab49..96f4b743ce 100644 --- a/Composer/packages/client/src/router.tsx +++ b/Composer/packages/client/src/router.tsx @@ -9,12 +9,12 @@ import formatMessage from 'format-message'; import { resolveToBasePath } from './utils/fileUtil'; import { data } from './styles'; -import { NotFound } from './components/NotFound/NotFound'; +import { NotFound } from './components/NotFound'; import { BASEPATH } from './constants'; import { StoreContext } from './store'; import { openAlertModal } from './components/Modal/AlertDialog'; import { dialogStyle } from './components/Modal/dialogStyle'; -import { LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner'; +import { LoadingSpinner } from './components/LoadingSpinner'; const DesignPage = React.lazy(() => import('./pages/design/DesignPage')); const LUPage = React.lazy(() => import('./pages/language-understanding/LUPage'));