Move shared branded code to branded/ (#14515)

This commit is contained in:
Felix Becker 2020-10-08 15:14:34 +02:00 committed by GitHub
parent 048f49eef3
commit 85f198b04c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
130 changed files with 480 additions and 373 deletions

View File

@ -51,6 +51,25 @@ jobs:
working-directory: client/shared/
run: src lsif upload -github-token=${{ secrets.GITHUB_TOKEN }}
lsif-tsc-branded:
if: github.repository == 'sourcegraph/sourcegraph'
runs-on: ubuntu-latest
container: sourcegraph/lsif-node
steps:
- uses: actions/checkout@v1
- name: Install build dependencies
run: apk --no-cache add python g++ make git
- name: Install dependencies
run: yarn --ignore-engines --ignore-scripts
- name: Generate
run: ./node_modules/.bin/gulp generate
- name: Generate LSIF data
working-directory: client/branded/
run: lsif-tsc -p .
- name: Upload LSIF data
working-directory: client/branded/
run: src lsif upload -github-token=${{ secrets.GITHUB_TOKEN }}
lsif-tsc-browser:
if: github.repository == 'sourcegraph/sourcegraph'
runs-on: ubuntu-latest

3
.gitignore vendored
View File

@ -114,18 +114,21 @@ graphql-operations.ts
# unignore node_modules itself
!/client/web/node_modules
!/client/shared/node_modules
!/client/branded/node_modules
!/client/browser/node_modules
!/client/packages/sourcegraph-extension-api/node_modules
!/client/packages/@sourcegraph/extension-api-types/node_modules
# ignore everything inside node_modules
/client/web/node_modules/*
/client/shared/node_modules/*
/client/branded/node_modules/*
/client/browser/node_modules/*
/client/packages/sourcegraph-extension-api/node_modules/*
/client/packages/@sourcegraph/extension-api-types/node_modules/*
# except .bin
!/client/web/node_modules/.bin
!/client/shared/node_modules/.bin
!/client/branded/node_modules/.bin
!/client/browser/node_modules/.bin
!/client/packages/sourcegraph-extension-api/node_modules/.bin
!/client/packages/@sourcegraph/extension-api-types/node_modules/.bin

2
.vscode/tasks.json vendored
View File

@ -14,7 +14,7 @@
"problemMatcher": "$tsc-watch",
"isBackground": true,
"command": ["node_modules/.bin/tsc"],
"args": ["--build", ".", "--watch", "--incremental"],
"args": ["--build", "tsconfig.all.json", "--watch", "--incremental"],
"runOptions": {
"runOn": "folderOpen",
},

View File

@ -0,0 +1,3 @@
out/
src/graphql/schema.ts
src/graphql-operations.ts

View File

@ -0,0 +1,25 @@
const baseConfig = require('../../.eslintrc.js')
module.exports = {
extends: '../../.eslintrc.js',
parserOptions: {
...baseConfig.parserOptions,
project: [__dirname + '/tsconfig.json'],
},
rules: {
'no-restricted-imports': [
'error',
{
paths: [
...baseConfig.rules['no-restricted-imports'][1].paths,
{
name: 'react-router-dom',
importNames: ['Link'],
message:
"Use the shared/src/shared/components/Link component instead of react-router-dom's Link. Reason: Shared branded code runs on platforms that don't use react-router (such as in the browser extension).",
},
],
},
],
},
overrides: baseConfig.overrides,
}

View File

@ -0,0 +1,3 @@
{
"extends": ["@sourcegraph/stylelint-config"]
}

4
client/branded/README.md Normal file
View File

@ -0,0 +1,4 @@
This folder contains client code that is **branded**, i.e. it implements the visual design language we use across our web app and e.g. in the options menu of the browser extension.
Code in here can use Bootstrap and must not adapt styles of the code host (for more details, see [Styling UI in the handbook](https://about.sourcegraph.com/handbook/engineering/web/styling)).
Any code that is code host agnostic should go into [`../shared`](../shared) instead.

View File

@ -0,0 +1,11 @@
// @ts-check
/** @type {jest.InitialOptions} */
const config = require('../../jest.config.base')
/** @type {jest.InitialOptions} */
module.exports = {
...config,
displayName: 'branded',
rootDir: __dirname,
}

1
client/branded/node_modules/.bin generated vendored Symbolic link
View File

@ -0,0 +1 @@
../../../node_modules/.bin

View File

@ -0,0 +1,8 @@
{
"private": true,
"scripts": {
"eslint": "eslint --cache '**/*.[jt]s?(x)'",
"stylelint": "stylelint 'src/**/*.scss' --quiet",
"test": "jest"
}
}

View File

@ -0,0 +1,32 @@
import { radios } from '@storybook/addon-knobs'
import React from 'react'
import { MemoryRouter, MemoryRouterProps } from 'react-router'
import { ThemeProps } from '../../../shared/src/theme'
import brandedStyles from '../global-styles/index.scss'
import { Tooltip } from './tooltip/Tooltip'
export interface WebStoryProps extends MemoryRouterProps {
children: React.FunctionComponent<ThemeProps>
}
/**
* Wrapper component for webapp Storybook stories that provides light theme and react-router props.
* Takes a render function as children that gets called with the props.
*/
export const BrandedStory: React.FunctionComponent<
WebStoryProps & {
styles?: string
}
> = ({ children, styles = brandedStyles, ...memoryRouterProps }) => {
const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light')
document.body.classList.toggle('theme-light', theme === 'light')
document.body.classList.toggle('theme-dark', theme === 'dark')
const Children = children
return (
<MemoryRouter {...memoryRouterProps}>
<Tooltip />
<Children isLightTheme={theme === 'light'} />
<style title="Webapp CSS">{styles}</style>
</MemoryRouter>
)
}

View File

@ -1,7 +1,7 @@
import * as H from 'history'
import * as React from 'react'
import { parseHash } from '../util/url'
import { Link } from './Link'
import { parseHash } from '../../../shared/src/util/url'
import { Link } from '../../../shared/src/components/Link'
import classNames from 'classnames'
/**

View File

@ -7,7 +7,7 @@ import { radios } from '@storybook/addon-knobs'
const onToggle = action('onToggle')
const { add } = storiesOf('shared/Toggle', module).addDecorator(story => {
const { add } = storiesOf('branded/Toggle', module).addDecorator(story => {
const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light')
document.body.classList.toggle('theme-light', theme === 'light')
document.body.classList.toggle('theme-dark', theme === 'dark')

View File

@ -7,7 +7,7 @@ import { radios } from '@storybook/addon-knobs'
const onToggle = action('onToggle')
const { add } = storiesOf('shared/ToggleBig', module).addDecorator(story => {
const { add } = storiesOf('branded/ToggleBig', module).addDecorator(story => {
const theme = radios('Theme', { Light: 'light', Dark: 'dark' }, 'light')
document.body.classList.toggle('theme-light', theme === 'light')
document.body.classList.toggle('theme-dark', theme === 'dark')

View File

@ -1,4 +1,4 @@
@import '../components/Resizable';
@import '../../../../shared/src/components/Resizable';
.panel {
flex: 1 1 50%;

View File

@ -3,21 +3,24 @@ import CloseIcon from 'mdi-react/CloseIcon'
import * as React from 'react'
import { Observable, Subscription } from 'rxjs'
import { map } from 'rxjs/operators'
import { PanelViewWithComponent, PanelViewProviderRegistrationOptions } from '../api/client/services/panelViews'
import { ContributableMenu, ContributableViewContainer } from '../api/protocol/contribution'
import { ExtensionsControllerProps } from '../extensions/controller'
import { ActionsNavItems } from '../actions/ActionsNavItems'
import { ActivationProps } from '../components/activation/Activation'
import { FetchFileCtx } from '../components/CodeExcerpt'
import { Resizable } from '../components/Resizable'
import { Spacer, Tab, TabsWithURLViewStatePersistence } from '../components/Tabs'
import { PlatformContextProps } from '../platform/context'
import { SettingsCascadeProps } from '../settings/settings'
import { TelemetryProps } from '../telemetry/telemetryService'
import {
PanelViewWithComponent,
PanelViewProviderRegistrationOptions,
} from '../../../../shared/src/api/client/services/panelViews'
import { ContributableMenu, ContributableViewContainer } from '../../../../shared/src/api/protocol/contribution'
import { ExtensionsControllerProps } from '../../../../shared/src/extensions/controller'
import { ActionsNavItems } from '../../../../shared/src/actions/ActionsNavItems'
import { ActivationProps } from '../../../../shared/src/components/activation/Activation'
import { FetchFileCtx } from '../../../../shared/src/components/CodeExcerpt'
import { Resizable } from '../../../../shared/src/components/Resizable'
import { Spacer, Tab, TabsWithURLViewStatePersistence } from '../Tabs'
import { PlatformContextProps } from '../../../../shared/src/platform/context'
import { SettingsCascadeProps } from '../../../../shared/src/settings/settings'
import { TelemetryProps } from '../../../../shared/src/telemetry/telemetryService'
import { EmptyPanelView } from './views/EmptyPanelView'
import { PanelView } from './views/PanelView'
import { ThemeProps } from '../theme'
import { VersionContextProps } from '../search/util'
import { ThemeProps } from '../../../../shared/src/theme'
import { VersionContextProps } from '../../../../shared/src/search/util'
interface Props
extends ExtensionsControllerProps,

View File

@ -8,14 +8,14 @@ import MapSearchIcon from 'mdi-react/MapSearchIcon'
import * as React from 'react'
import { Observable, Subject, Subscription } from 'rxjs'
import { catchError, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators'
import { FetchFileCtx } from '../../components/CodeExcerpt'
import { FileMatch, IFileMatch, ILineMatch } from '../../components/FileMatch'
import { VirtualList } from '../../components/VirtualList'
import { SettingsCascadeProps } from '../../settings/settings'
import { asError, ErrorLike, isErrorLike } from '../../util/errors'
import { property, isDefined } from '../../util/types'
import { parseRepoURI, toPrettyBlobURL, toRepoURL } from '../../util/url'
import { VersionContextProps } from '../../search/util'
import { FetchFileCtx } from '../../../../../shared/src/components/CodeExcerpt'
import { FileMatch, IFileMatch, ILineMatch } from '../../../../../shared/src/components/FileMatch'
import { VirtualList } from '../../../../../shared/src/components/VirtualList'
import { SettingsCascadeProps } from '../../../../../shared/src/settings/settings'
import { asError, ErrorLike, isErrorLike } from '../../../../../shared/src/util/errors'
import { property, isDefined } from '../../../../../shared/src/util/types'
import { parseRepoURI, toPrettyBlobURL, toRepoURL } from '../../../../../shared/src/util/url'
import { VersionContextProps } from '../../../../../shared/src/search/util'
export const FileLocationsError: React.FunctionComponent<{ error: ErrorLike }> = ({ error }) => (
<div className="file-locations__error alert alert-danger m-2">

View File

@ -10,11 +10,14 @@ import React from 'react'
import renderer from 'react-test-renderer'
import { concat, NEVER, of } from 'rxjs'
import * as sinon from 'sinon'
import { createContextService } from '../../api/client/context/contextService'
import { parseTemplate } from '../../api/client/context/expr/evaluator'
import { ContributionsEntry, ContributionUnsubscribable } from '../../api/client/services/contribution'
import { Controller } from '../../extensions/controller'
import { SettingsCascadeOrError } from '../../settings/settings'
import { createContextService } from '../../../../../shared/src/api/client/context/contextService'
import { parseTemplate } from '../../../../../shared/src/api/client/context/expr/evaluator'
import {
ContributionsEntry,
ContributionUnsubscribable,
} from '../../../../../shared/src/api/client/services/contribution'
import { Controller } from '../../../../../shared/src/extensions/controller'
import { SettingsCascadeOrError } from '../../../../../shared/src/settings/settings'
import { HierarchicalLocationsView, HierarchicalLocationsViewProps } from './HierarchicalLocationsView'
import { MaybeLoadingResult } from '@sourcegraph/codeintellify'

View File

@ -5,18 +5,18 @@ import * as H from 'history'
import * as React from 'react'
import { Observable, of, Subject, Subscription } from 'rxjs'
import { catchError, distinctUntilChanged, endWith, map, startWith, switchMap, tap } from 'rxjs/operators'
import { FetchFileCtx } from '../../components/CodeExcerpt'
import { RepoLink } from '../../components/RepoLink'
import { Resizable } from '../../components/Resizable'
import { ExtensionsControllerProps } from '../../extensions/controller'
import { SettingsCascadeProps } from '../../settings/settings'
import { asError, ErrorLike, isErrorLike } from '../../util/errors'
import { parseRepoURI } from '../../util/url'
import { FetchFileCtx } from '../../../../../shared/src/components/CodeExcerpt'
import { RepoLink } from '../../../../../shared/src/components/RepoLink'
import { Resizable } from '../../../../../shared/src/components/Resizable'
import { ExtensionsControllerProps } from '../../../../../shared/src/extensions/controller'
import { SettingsCascadeProps } from '../../../../../shared/src/settings/settings'
import { asError, ErrorLike, isErrorLike } from '../../../../../shared/src/util/errors'
import { parseRepoURI } from '../../../../../shared/src/util/url'
import { registerPanelToolbarContributions } from './contributions'
import { FileLocations, FileLocationsError, FileLocationsNotFound } from './FileLocations'
import { groupLocations } from './locations'
import { MaybeLoadingResult } from '@sourcegraph/codeintellify'
import { VersionContextProps } from '../../search/util'
import { VersionContextProps } from '../../../../../shared/src/search/util'
/** The maximum number of results we'll receive from a provider before we truncate and display a banner. */
const MAXIMUM_LOCATION_RESULTS = 500

View File

@ -1,15 +1,18 @@
import * as H from 'history'
import React from 'react'
import { Observable } from 'rxjs'
import { PanelViewWithComponent, PanelViewProviderRegistrationOptions } from '../../api/client/services/panelViews'
import { FetchFileCtx } from '../../components/CodeExcerpt'
import { Markdown } from '../../components/Markdown'
import { ExtensionsControllerProps } from '../../extensions/controller'
import { SettingsCascadeProps } from '../../settings/settings'
import { renderMarkdown } from '../../util/markdown'
import {
PanelViewWithComponent,
PanelViewProviderRegistrationOptions,
} from '../../../../../shared/src/api/client/services/panelViews'
import { FetchFileCtx } from '../../../../../shared/src/components/CodeExcerpt'
import { Markdown } from '../../../../../shared/src/components/Markdown'
import { ExtensionsControllerProps } from '../../../../../shared/src/extensions/controller'
import { SettingsCascadeProps } from '../../../../../shared/src/settings/settings'
import { renderMarkdown } from '../../../../../shared/src/util/markdown'
import { EmptyPanelView } from './EmptyPanelView'
import { HierarchicalLocationsView } from './HierarchicalLocationsView'
import { VersionContextProps } from '../../search/util'
import { VersionContextProps } from '../../../../../shared/src/search/util'
interface Props extends ExtensionsControllerProps, SettingsCascadeProps, VersionContextProps {
panelView: PanelViewWithComponent & Pick<PanelViewProviderRegistrationOptions, 'id'>

View File

@ -1,6 +1,6 @@
import { Unsubscribable } from 'rxjs'
import { parseContributionExpressions } from '../../api/client/services/contribution'
import { ExtensionsControllerProps } from '../../extensions/controller'
import { parseContributionExpressions } from '../../../../../shared/src/api/client/services/contribution'
import { ExtensionsControllerProps } from '../../../../../shared/src/extensions/controller'
export function registerPanelToolbarContributions({
extensionsController,

View File

@ -1,10 +1,10 @@
import { storiesOf } from '@storybook/react'
import React, { useCallback } from 'react'
import { WebStory } from '../WebStory'
import { BrandedStory } from '../BrandedStory'
import { Tooltip } from './Tooltip'
const { add } = storiesOf('web/Tooltip', module).addDecorator(story => (
<WebStory>{() => <div className="p-5">{story()}</div>}</WebStory>
const { add } = storiesOf('branded/Tooltip', module).addDecorator(story => (
<BrandedStory>{() => <div className="p-5">{story()}</div>}</BrandedStory>
))
add(

View File

@ -13,7 +13,7 @@ import { Form } from '../components/Form'
import openColor from 'open-color'
import { Menu, MenuButton, MenuList, MenuLink } from '@reach/menu-button'
import 'storybook-addon-designs'
import { WebStory } from '../components/WebStory'
import { BrandedStory } from '../components/BrandedStory'
import { CodeSnippet } from '../components/CodeSnippet'
const semanticColors = ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'merged'] as const
@ -23,8 +23,8 @@ const preventDefault = <E extends React.SyntheticEvent>(event: E): E => {
return event
}
const { add } = storiesOf('web/Global styles', module).addDecorator(story => (
<WebStory>{() => <div className="p-3 container">{story()}</div>}</WebStory>
const { add } = storiesOf('branded/Global styles', module).addDecorator(story => (
<BrandedStory>{() => <div className="p-3 container">{story()}</div>}</BrandedStory>
))
const TextStory: React.FunctionComponent = () => (

View File

@ -0,0 +1,176 @@
// Media breakpoints
$media-sm: 576px;
$media-md: 768px;
$media-lg: 992px;
$media-xl: 1200px;
@import './colors.scss';
// Bootstrap configuration before Bootstrap is imported
$border-radius: 2px;
$border-radius-sm: 1px;
$border-radius-lg: 4px;
$font-size-base: 0.875rem;
$line-height-base: (20/14);
$box-shadow: 0 0.25rem 0.5rem rgba($gray-19, 0.07);
$grid-gutter-width: 1.5rem;
// No max width except for xl.
$container-max-widths: (
xl: 1140px,
);
$body-color: var(--body-color);
$body-bg: var(--body-bg);
$text-muted: var(--text-muted);
// Borders
$border-color: var(--border-color);
.theme-dark {
--border-color: #{$color-border};
}
.theme-light {
--border-color: #{$color-light-border};
}
// Links
$link-color: var(--link-color);
$link-hover-color: var(--link-hover-color);
// Alerts
$alert-bg-level: 5;
$alert-border-level: -1;
$alert-color-level: -10;
$alert-bg-level-light: -10;
$alert-border-level-light: -9;
$alert-color-level-light: 6;
$alert-padding-y: 0.75rem;
$alert-padding-x: 0.75rem;
// Badges
$badge-font-size: 0.75em;
$badge-font-weight: 600;
$badge-padding-y: 0.34em;
$badge-padding-x: 0.6em;
// Tooltips
$tooltip-bg: $gray-19;
// Forms
$form-check-input-margin-y: 0.2em;
$input-btn-focus-width: 2px;
$input-focus-border-color: $primary;
// The default focus ring for buttons is very hard to see, raise opacity.
// We only show the focus ring when using the keyboard, when the focus ring
// should be clearly visible.
$btn-focus-box-shadow: 0 0 0 $input-btn-focus-width rgba($primary, 0.8);
// Forms don't manipulate the colors at compile time,
// which is why we can use CSS variables for theming here
// That's nice because the forms theming CSS would otherwise
// be way more complex than it is for other components
$input-bg: var(--input-bg);
$input-disabled-bg: var(--input-disabled-bg);
$input-border-color: var(--input-border-color);
$input-color: var(--input-color);
$input-placeholder-color: var(--input-placeholder-color);
$input-group-addon-color: var(--input-group-addon-color);
$input-group-addon-bg: var(--input-group-addon-bg);
$input-group-addon-border-color: var(--input-group-addon-border-color);
// Dropdown
$dropdown-bg: var(--dropdown-bg);
$dropdown-border-color: var(--dropdown-border-color);
$dropdown-divider-bg: var(--border-color);
$dropdown-link-color: var(--body-color);
$dropdown-link-hover-color: var(--body-color);
$dropdown-link-hover-bg: var(--dropdown-link-hover-bg);
$dropdown-link-active-color: #ffffff;
$dropdown-link-active-bg: var(--primary);
$dropdown-link-disabled-color: var(--text-muted);
$dropdown-header-color: var(--dropdown-header-color);
$dropdown-item-padding-y: 0.25rem;
$dropdown-item-padding-x: 0.5rem;
$dropdown-padding-y: $dropdown-item-padding-y;
// Tables
$table-cell-padding: 0.625rem;
$table-hover-bg: #0e121b;
$table-border-color: #2b3750;
$table-hover-bg-light: #f2f4f8;
$table-border-color-light: #e4e9f1;
// Progress
$progress-height: auto;
// Collapsible
$collapsible-expand-btn-width: 1.25rem;
$hr-border-color: var(--border-color);
$hr-margin-y: 0.25rem;
$code-bg: var(--body-bg);
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
@import 'bootstrap/scss/reboot';
@import 'bootstrap/scss/utilities';
@import 'bootstrap/scss/grid';
@import 'bootstrap/scss/progress';
@import 'bootstrap/scss/tooltip';
@import 'bootstrap/scss/transitions';
@import '../../../shared/src/global-styles/icons';
@import './badge';
@import './card';
@import './dropdown';
@import './modal';
@import './nav';
@import './type';
@import './list-group';
@import './tables';
@import './code';
@import './buttons';
@import './alert';
@import './forms';
@import './highlight';
@import './web-content';
* {
box-sizing: border-box;
}
html {
// Base for layout rem values
font-size: 16px;
}
// Our simple popovers only need these styles. We don't want the caret or special font sizes from
// Bootstrap's popover CSS.
.popover-inner {
background-color: var(--body-bg);
border: solid 1px var(--border-color);
border-radius: $border-radius;
}
// Show a focus ring when performing keyboard navigation. Uses the polyfill at
// https://github.com/WICG/focus-visible because few browsers support :focus-visible.
:focus:not(:focus-visible) {
outline: none;
}
:focus-visible {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}

8
client/branded/src/globals.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
declare module '*.scss' {
const cssModule: string
export default cssModule
}
declare module '*.css' {
const cssModule: string
export default cssModule
}

View File

@ -0,0 +1,24 @@
{
"extends": "../../tsconfig.json",
"references": [{ "path": "../shared" }],
"compilerOptions": {
"jsx": "react",
"module": "esnext",
"sourceRoot": "src",
"baseUrl": ".",
"paths": {
"*": ["src/types/*", "*"],
},
"rootDir": ".",
"outDir": "./out",
"plugins": [
{
"name": "ts-graphql-plugin",
"schema": "../../cmd/frontend/graphqlbackend/schema.graphql",
"tag": "gql",
},
],
},
"include": ["**/*", ".*", "./src/**/*.json"],
"exclude": ["../../node_modules", "./node_modules", "./out"],
}

View File

@ -1,4 +1,4 @@
@import '../../shared/src/global-styles/colors';
@import '../../branded/src/global-styles/colors';
// Bootstrap configuration before Bootstrap is imported
$border-radius: 2px;

View File

@ -1,4 +1,4 @@
@import '../../../../shared/src/components/Toggle';
@import '../../../../branded/src/components/Toggle';
.options-header {
display: flex;

View File

@ -1,5 +1,5 @@
import SettingsOutlineIcon from 'mdi-react/SettingsOutlineIcon'
import { Toggle } from '../../../../shared/src/components/Toggle'
import { Toggle } from '../../../../branded/src/components/Toggle'
import * as React from 'react'
export interface OptionsHeaderProps {

View File

@ -3,14 +3,10 @@ import { action } from '@storybook/addon-actions'
import { storiesOf } from '@storybook/react'
import { OptionsMenu } from './OptionsMenu'
import optionsStyles from '../../options.scss'
import { BrandedStory } from '../../../../branded/src/components/BrandedStory'
storiesOf('browser/Options/OptionsMenu', module)
.addDecorator(story => (
<>
<style>{optionsStyles}</style>
<div>{story()}</div>
</>
))
.addDecorator(story => <BrandedStory styles={optionsStyles}>{() => story()}</BrandedStory>)
.add('Default', () => (
<OptionsMenu
version="0.0.0"

View File

@ -2,6 +2,7 @@ import * as React from 'react'
import { action } from '@storybook/addon-actions'
import { storiesOf } from '@storybook/react'
import { ConnectionErrors, ServerUrlForm, ServerUrlFormProps } from './ServerUrlForm'
import { BrandedStory } from '../../../../branded/src/components/BrandedStory'
import optionsStyles from '../../options.scss'
class Container extends React.Component<{}, { value: string; status: ServerUrlFormProps['status'] }> {
@ -33,12 +34,7 @@ class Container extends React.Component<{}, { value: string; status: ServerUrlFo
}
storiesOf('browser/Options/ServerUrlForm', module)
.addDecorator(story => (
<>
<style>{optionsStyles}</style>
<div>{story()}</div>
</>
))
.addDecorator(story => <BrandedStory styles={optionsStyles}>{() => story()}</BrandedStory>)
.add('Interactive', () => <Container />)
.add('Error Status', () => (
<div style={{ maxWidth: 400, padding: '1rem' }}>

View File

@ -1,20 +1,7 @@
// Options page CSS entry point
@import '../../shared/src/global-styles/colors.scss';
@import '../../shared/src/global-styles/icons.scss';
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
@import 'bootstrap/scss/reboot';
@import 'bootstrap/scss/type';
@import 'bootstrap/scss/utilities';
@import 'bootstrap/scss/grid';
@import 'bootstrap/scss/forms';
@import 'bootstrap/scss/input-group';
@import 'bootstrap/scss/custom-forms';
@import 'bootstrap/scss/buttons';
@import 'bootstrap/scss/button-group';
@import 'bootstrap/scss/alert';
@import '../../branded/src/global-styles/index.scss';
@import '../../branded/src/components/Toggle';
@import './browser-extension/options-page/OptionsContainer';
:root {

View File

@ -10,7 +10,6 @@ $body-bg-color-light: #ffffff;
@import '../../shared/src/commandPalette/CommandList';
@import '../../shared/src/commandPalette/EmptyCommandList.scss';
@import '../../shared/src/components/completion/CompletionWidget.scss';
@import '../../shared/src/components/Toggle';
@import '../../shared/src/extensions/ExtensionStatus';
@import '../../shared/src/notifications/NotificationItem';
@import '../../shared/src/notifications/Notifications';

View File

@ -1,6 +1,6 @@
{
"extends": "../../tsconfig.json",
"references": [{ "path": "../shared" }, { "path": "../../schema" }],
"references": [{ "path": "../shared" }, { "path": "../branded" }, { "path": "../../schema" }],
"compilerOptions": {
"module": "commonjs",
"baseUrl": ".",

View File

@ -1,19 +1,7 @@
# extensions-client-common
This folder contains common TypeScript/React/SCSS client code shared between the browser extension and the web app.
[![build](https://travis-ci.org/sourcegraph/extensions-client-common.svg?branch=master)](https://travis-ci.org/sourcegraph/extensions-client-common)
[![codecov](https://codecov.io/gh/sourcegraph/extensions-client-common/branch/master/graph/badge.svg?token=SLtdKY3zQx)](https://codecov.io/gh/sourcegraph/extensions-client-common)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![sourcegraph: search](https://img.shields.io/badge/sourcegraph-search-brightgreen.svg)](https://sourcegraph.com/github.com/sourcegraph/extensions-client-common)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
Everything in this folder is code-host agnostic and cannot make assumptions about whether it is running inside the Sourcegraph web app, in the browser extension on GitHub, Gitlab, Phabricator, Bitbucket Server, etc.
In particular, components cannot make use of Bootstrap classes, but must accept CSS classes as props and/or have their own code host agnostic SCSS stylesheets.
For more details, see [Styling UI in the handbook](https://about.sourcegraph.com/handbook/engineering/web/styling).
Common TypeScript/React client application code for [Sourcegraph extension](https://docs.sourcegraph.com/extensions) configuration and management, used in:
- Sourcegraph
- "Sourcegraph for X" products (Chrome extension, Firefox extension, and more soon)
## Development
```shell
yarn
yarn test
```
Code that is only used in branded contexts (web app, options menu of the browser extension, ...) should go into [`../branded`](../branded) instead.

View File

@ -1,23 +1,8 @@
{
"private": true,
"version": "12.0.0",
"description": "Common TypeScript/React client application code for Sourcegraph extension configuration and management, used in Sourcegraph and \"Sourcegraph for X\" products",
"main": "src/index.js",
"module": "src/index.js",
"types": "src/index.d.ts",
"files": [
"src"
],
"bugs": {
"url": "https://github.com/sourcegraph/sourcegraph/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/sourcegraph/sourcegraph"
},
"scripts": {
"eslint": "eslint --cache '**/*.[jt]s?(x)'",
"stylelint": "stylelint 'src/**/*.scss'",
"stylelint": "stylelint 'src/**/*.scss' --quiet",
"test": "jest",
"graphql": "gulp graphQlSchema",
"schema": "gulp schema",

View File

@ -10,14 +10,8 @@
@import './components/Markdown';
@import './components/Resizable';
@import './components/ResultContainer';
@import './components/Toggle';
@import './components/ToggleBig';
@import './components/Tabs';
@import './extensions/ExtensionStatus';
@import './hover/HoverOverlay';
@import './notifications/NotificationItem';
@import './notifications/Notifications';
@import './panel/Panel';
@import './panel/views/FileLocations';
@import './panel/views/HierarchicalLocationsView';
@import './symbols/SymbolIcon';

View File

@ -25,7 +25,7 @@
"webpack": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" gulp webpack",
"lint": "yarn run eslint && gulp unusedExports && yarn run stylelint",
"eslint": "eslint --cache '**/*.[tj]s?(x)'",
"stylelint": "stylelint 'src/**/*.scss'",
"stylelint": "stylelint 'src/**/*.scss' --quiet",
"bundlesize": "GITHUB_TOKEN= bundlesize",
"browserslist": "browserslist",
"analyze-bundle": "NODE_ENV=production ENTERPRISE=1 WEBPACK_ANALYZER=1 yarn build"

View File

@ -6,7 +6,7 @@ import { ActivationProps } from '../../shared/src/components/activation/Activati
import { FetchFileCtx } from '../../shared/src/components/CodeExcerpt'
import { ExtensionsControllerProps } from '../../shared/src/extensions/controller'
import * as GQL from '../../shared/src/graphql/schema'
import { ResizablePanel } from '../../shared/src/panel/Panel'
import { ResizablePanel } from '../../branded/src/components/panel/Panel'
import { PlatformContextProps } from '../../shared/src/platform/context'
import { SettingsCascadeProps } from '../../shared/src/settings/settings'
import { ErrorLike } from '../../shared/src/util/errors'

View File

@ -6,164 +6,7 @@ It should import all component stylesheets
// Use duplicate selectors for the light-theme
// stylelint-disable no-duplicate-selectors
// Media breakpoints
$media-sm: 576px;
$media-md: 768px;
$media-lg: 992px;
$media-xl: 1200px;
@import '../../shared/src/global-styles/colors.scss';
// Bootstrap configuration before Bootstrap is imported
$border-radius: 2px;
$border-radius-sm: 1px;
$border-radius-lg: 4px;
$font-size-base: 0.875rem;
$line-height-base: (20/14);
$box-shadow: 0 0.25rem 0.5rem rgba($gray-19, 0.07);
$grid-gutter-width: 1.5rem;
// No max width except for xl.
$container-max-widths: (
xl: 1140px,
);
$body-color: var(--body-color);
$body-bg: var(--body-bg);
$text-muted: var(--text-muted);
// Borders
$border-color: var(--border-color);
.theme-dark {
--border-color: #{$color-border};
}
.theme-light {
--border-color: #{$color-light-border};
}
// Links
$link-color: var(--link-color);
$link-hover-color: var(--link-hover-color);
// Alerts
$alert-bg-level: 5;
$alert-border-level: -1;
$alert-color-level: -10;
$alert-bg-level-light: -10;
$alert-border-level-light: -9;
$alert-color-level-light: 6;
$alert-padding-y: 0.75rem;
$alert-padding-x: 0.75rem;
// Badges
$badge-font-size: 0.75em;
$badge-font-weight: 600;
$badge-padding-y: 0.34em;
$badge-padding-x: 0.6em;
// Tooltips
$tooltip-bg: $gray-19;
// Forms
$form-check-input-margin-y: 0.2em;
$input-btn-focus-width: 2px;
$input-focus-border-color: $primary;
// The default focus ring for buttons is very hard to see, raise opacity.
// We only show the focus ring when using the keyboard, when the focus ring
// should be clearly visible.
$btn-focus-box-shadow: 0 0 0 $input-btn-focus-width rgba($primary, 0.8);
// Forms don't manipulate the colors at compile time,
// which is why we can use CSS variables for theming here
// That's nice because the forms theming CSS would otherwise
// be way more complex than it is for other components
$input-bg: var(--input-bg);
$input-disabled-bg: var(--input-disabled-bg);
$input-border-color: var(--input-border-color);
$input-color: var(--input-color);
$input-placeholder-color: var(--input-placeholder-color);
$input-group-addon-color: var(--input-group-addon-color);
$input-group-addon-bg: var(--input-group-addon-bg);
$input-group-addon-border-color: var(--input-group-addon-border-color);
// Dropdown
$dropdown-bg: var(--dropdown-bg);
$dropdown-border-color: var(--dropdown-border-color);
$dropdown-divider-bg: var(--border-color);
$dropdown-link-color: var(--body-color);
$dropdown-link-hover-color: var(--body-color);
$dropdown-link-hover-bg: var(--dropdown-link-hover-bg);
$dropdown-link-active-color: #ffffff;
$dropdown-link-active-bg: var(--primary);
$dropdown-link-disabled-color: var(--text-muted);
$dropdown-header-color: var(--dropdown-header-color);
$dropdown-item-padding-y: 0.25rem;
$dropdown-item-padding-x: 0.5rem;
$dropdown-padding-y: $dropdown-item-padding-y;
// Tables
$table-cell-padding: 0.625rem;
$table-hover-bg: #0e121b;
$table-border-color: #2b3750;
$table-hover-bg-light: #f2f4f8;
$table-border-color-light: #e4e9f1;
// Progress
$progress-height: auto;
// Collapsible
$collapsible-expand-btn-width: 1.25rem;
$hr-border-color: var(--border-color);
$hr-margin-y: 0.25rem;
$code-bg: var(--body-bg);
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
@import 'bootstrap/scss/reboot';
@import 'bootstrap/scss/utilities';
@import 'bootstrap/scss/grid';
@import 'bootstrap/scss/progress';
@import 'bootstrap/scss/tooltip';
@import 'bootstrap/scss/transitions';
@import './global-styles/badge';
@import './global-styles/card';
@import './global-styles/dropdown';
@import './global-styles/modal';
@import './global-styles/nav';
@import './global-styles/type';
@import '../../shared/src/global-styles/icons';
@import './global-styles/list-group';
@import './global-styles/tables';
@import './global-styles/code';
@import './global-styles/buttons';
@import './global-styles/alert';
@import './global-styles/forms';
@import './global-styles/highlight';
@import './global-styles/web-content';
* {
box-sizing: border-box;
}
html {
// Base for layout rem values
font-size: 16px;
}
@import '../../branded/src/global-styles/index.scss';
// stylelint-disable-next-line selector-max-id
html,
@ -230,24 +73,6 @@ body,
cursor: pointer;
}
// Our simple popovers only need these styles. We don't want the caret or special font sizes from
// Bootstrap's popover CSS.
.popover-inner {
background-color: var(--body-bg);
border: solid 1px var(--border-color);
border-radius: $border-radius;
}
// Show a focus ring when performing keyboard navigation. Uses the polyfill at
// https://github.com/WICG/focus-visible because few browsers support :focus-visible.
:focus:not(:focus-visible) {
outline: none;
}
:focus-visible {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}
// Hide the given element from Percy.
.percy-hide,
.monaco-editor .cursor {
@ -285,7 +110,7 @@ body,
@import './repo/FilePathBreadcrumbs.scss';
@import './repo/settings/RepoSettingsArea';
@import './components/LoaderInput';
@import './components/CodeSnippet';
@import '../../branded/src/components/CodeSnippet';
@import './components/PageHeader';
@import './components/completion/CompletionWidgetDropdown';
@import './components/CopyableText';
@ -295,7 +120,7 @@ body,
@import './components/HeroPage';
@import './components/ModalPage';
@import './components/RadioButtons';
@import './components/tooltip/Tooltip';
@import '../../branded/src/components/tooltip/Tooltip';
@import './components/CtaBanner.scss';
@import './user/settings/UserSettingsArea';
@import './site-admin/SiteAdminAlert';
@ -312,6 +137,10 @@ body,
@import './components/SearchResultMatch';
@import './components/diff/FileDiffNode';
@import './components/externalServices/AddExternalServicesPage';
@import '../../branded/src/components/Tabs';
@import '../../branded/src/components/panel/Panel';
@import '../../branded/src/components/panel/views/FileLocations';
@import '../../branded/src/components/panel/views/HierarchicalLocationsView';
@import '~@sourcegraph/react-loading-spinner/lib/LoadingSpinner.css';
@import '../../shared/src/index';

View File

@ -21,7 +21,7 @@ import { ErrorBoundary } from './components/ErrorBoundary'
import { FeedbackText } from './components/FeedbackText'
import { HeroPage } from './components/HeroPage'
import { RouterLinkOrAnchor } from './components/RouterLinkOrAnchor'
import { Tooltip } from './components/tooltip/Tooltip'
import { Tooltip } from '../../branded/src/components/tooltip/Tooltip'
import { ExtensionAreaRoute } from './extensions/extension/ExtensionArea'
import { ExtensionAreaHeaderNavItem } from './extensions/extension/ExtensionAreaHeader'
import { ExtensionsAreaRoute } from './extensions/ExtensionsArea'

View File

@ -2,7 +2,7 @@ import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
import * as React from 'react'
import { Link, RouteComponentProps } from 'react-router-dom'
import { asError, ErrorLike, isErrorLike } from '../../../shared/src/util/errors'
import { Form } from '../components/Form'
import { Form } from '../../../branded/src/components/Form'
import { HeroPage } from '../components/HeroPage'
import { PageTitle } from '../components/PageTitle'
import { eventLogger } from '../tracking/eventLogger'

View File

@ -2,7 +2,7 @@ import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
import * as H from 'history'
import React, { useCallback, useState } from 'react'
import { Link } from 'react-router-dom'
import { Form } from '../components/Form'
import { Form } from '../../../branded/src/components/Form'
import { eventLogger } from '../tracking/eventLogger'
import { getReturnTo, PasswordInput } from './SignInSignUpCommon'
import { asError } from '../../../shared/src/util/errors'

View File

@ -21,7 +21,7 @@ import {
import * as GQL from '../../../shared/src/graphql/schema'
import { asError, ErrorLike, isErrorLike } from '../../../shared/src/util/errors'
import { pluralize } from '../../../shared/src/util/strings'
import { Form } from './Form'
import { Form } from '../../../branded/src/components/Form'
import { RadioButtons } from './RadioButtons'
import { ErrorMessage } from './alerts'
import { hasProperty } from '../../../shared/src/util/types'

View File

@ -5,7 +5,7 @@ import { NOOP_TELEMETRY_SERVICE, TelemetryProps } from '../../../shared/src/tele
import { ThemeProps } from '../../../shared/src/theme'
import _webStyles from '../SourcegraphWebApp.scss'
import { BreadcrumbSetters, BreadcrumbsProps, useBreadcrumbs } from './Breadcrumbs'
import { Tooltip } from './tooltip/Tooltip'
import { Tooltip } from '../../../branded/src/components/tooltip/Tooltip'
export interface WebStoryProps extends MemoryRouterProps {
children: React.FunctionComponent<

View File

@ -3,7 +3,7 @@ import * as H from 'history'
import React, { useCallback } from 'react'
import * as GQL from '../../../../shared/src/graphql/schema'
import { ErrorLike } from '../../../../shared/src/util/errors'
import { Form } from '../Form'
import { Form } from '../../../../branded/src/components/Form'
import { DynamicallyImportedMonacoSettingsEditor } from '../../settings/DynamicallyImportedMonacoSettingsEditor'
import { AddExternalServiceOptions } from './externalServices'
import { ErrorAlert, ErrorMessage } from '../alerts'

View File

@ -9,7 +9,7 @@ import combySample from './samples/comby.campaign.yaml'
import goImportsSample from './samples/go-imports.campaign.yaml'
import minimalSample from './samples/minimal.campaign.yaml'
import classNames from 'classnames'
import { CodeSnippet } from '../../../components/CodeSnippet'
import { CodeSnippet } from '../../../../../branded/src/components/CodeSnippet'
interface SampleTabHeaderProps {
sample: Sample

View File

@ -1,7 +1,7 @@
import FileDownloadIcon from 'mdi-react/FileDownloadIcon'
import React, { useMemo } from 'react'
import { Link } from '../../../../../shared/src/components/Link'
import { CodeSnippet } from '../../../components/CodeSnippet'
import { CodeSnippet } from '../../../../../branded/src/components/CodeSnippet'
import { Timestamp } from '../../../components/time/Timestamp'
import { CampaignFields } from '../../../graphql-operations'

View File

@ -10,7 +10,7 @@ import * as GQL from '../../../../../shared/src/graphql/schema'
import { asError, createAggregateError, ErrorLike, isErrorLike } from '../../../../../shared/src/util/errors'
import { withAuthenticatedUser } from '../../../auth/withAuthenticatedUser'
import { mutateGraphQL } from '../../../backend/graphql'
import { Form } from '../../../components/Form'
import { Form } from '../../../../../branded/src/components/Form'
import { HeroPage } from '../../../components/HeroPage'
import { PageTitle } from '../../../components/PageTitle'
import { toExtensionID } from '../../../extensions/extension/extension'

View File

@ -12,7 +12,7 @@ import extensionSchemaJSON from '../../../../../shared/src/schema/extension.sche
import { asError, isErrorLike } from '../../../../../shared/src/util/errors'
import { withAuthenticatedUser } from '../../../auth/withAuthenticatedUser'
import { mutateGraphQL } from '../../../backend/graphql'
import { Form } from '../../../components/Form'
import { Form } from '../../../../../branded/src/components/Form'
import { HeroPage } from '../../../components/HeroPage'
import { PageTitle } from '../../../components/PageTitle'
import { DynamicallyImportedMonacoSettingsEditor } from '../../../settings/DynamicallyImportedMonacoSettingsEditor'

View File

@ -11,7 +11,7 @@ import * as GQL from '../../../../../shared/src/graphql/schema'
import { asError, createAggregateError, ErrorLike, isErrorLike } from '../../../../../shared/src/util/errors'
import { withAuthenticatedUser } from '../../../auth/withAuthenticatedUser'
import { mutateGraphQL } from '../../../backend/graphql'
import { Form } from '../../../components/Form'
import { Form } from '../../../../../branded/src/components/Form'
import { ModalPage } from '../../../components/ModalPage'
import { PageTitle } from '../../../components/PageTitle'
import { RegistryPublisher, toExtensionID } from '../../../extensions/extension/extension'

View File

@ -2,7 +2,7 @@ import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
import ChartLineIcon from 'mdi-react/ChartLineIcon'
import React, { useCallback, useState, useMemo } from 'react'
import * as H from 'history'
import { Form } from '../../../components/Form'
import { Form } from '../../../../../branded/src/components/Form'
import { useObservable } from '../../../../../shared/src/util/useObservable'
import { querySearchResultsStats } from './backend'
import { SearchStatsLanguages } from './SearchStatsLanguages'

View File

@ -10,7 +10,7 @@ import * as GQL from '../../../../../../shared/src/graphql/schema'
import { asError, ErrorLike, isErrorLike } from '../../../../../../shared/src/util/errors'
import { mutateGraphQL, queryGraphQL } from '../../../../backend/graphql'
import { FilteredConnection } from '../../../../components/FilteredConnection'
import { Form } from '../../../../components/Form'
import { Form } from '../../../../../../branded/src/components/Form'
import { PageTitle } from '../../../../components/PageTitle'
import { eventLogger } from '../../../../tracking/eventLogger'
import { useEventObservable } from '../../../../../../shared/src/util/useObservable'

View File

@ -7,7 +7,7 @@ import { gql } from '../../../../../../shared/src/graphql/graphql'
import * as GQL from '../../../../../../shared/src/graphql/schema'
import { asError, createAggregateError, isErrorLike } from '../../../../../../shared/src/util/errors'
import { mutateGraphQL } from '../../../../backend/graphql'
import { Form } from '../../../../components/Form'
import { Form } from '../../../../../../branded/src/components/Form'
import { ExpirationDate } from '../../../productSubscription/ExpirationDate'
import { ErrorAlert } from '../../../../components/alerts'
import { useEventObservable } from '../../../../../../shared/src/util/useObservable'

View File

@ -6,7 +6,7 @@ import { from, of, throwError, Observable } from 'rxjs'
import { catchError, startWith, switchMap } from 'rxjs/operators'
import * as GQL from '../../../../../shared/src/graphql/schema'
import { asError, ErrorLike, isErrorLike } from '../../../../../shared/src/util/errors'
import { Form } from '../../../components/Form'
import { Form } from '../../../../../branded/src/components/Form'
import { StripeWrapper } from '../../dotcom/billing/StripeWrapper'
import { ProductPlanFormControl } from '../../dotcom/productPlans/ProductPlanFormControl'
import {

View File

@ -1,4 +1,4 @@
@import '../../../shared/src/components/Toggle.scss';
@import '../../../branded/src/components/Toggle.scss';
.extension-card {
&__icon {

View File

@ -21,7 +21,7 @@ import {
import { configureExtensionRegistry, ConfiguredExtensionRegistry } from './extensions'
import { ExtensionCategory } from '../../../shared/src/schema/extensionSchema'
import { Link } from 'react-router-dom'
import { Form } from '../components/Form'
import { Form } from '../../../branded/src/components/Form'
import { ExtensionsQueryInputToolbar } from './ExtensionsQueryInputToolbar'
import { ThemeProps } from '../../../shared/src/theme'

View File

@ -1,8 +1,8 @@
import React, { useCallback, useMemo, useState } from 'react'
import { Observable, of } from 'rxjs'
import { catchError, map, switchMap } from 'rxjs/operators'
import { Toggle } from '../../../shared/src/components/Toggle'
import { ToggleBig } from '../../../shared/src/components/ToggleBig'
import { Toggle } from '../../../branded/src/components/Toggle'
import { ToggleBig } from '../../../branded/src/components/ToggleBig'
import { PlatformContextProps } from '../../../shared/src/platform/context'
import {
SettingsCascadeProps,

View File

@ -1,4 +1,4 @@
@import '../../../../shared/src/components/ToggleBig.scss';
@import '../../../../branded/src/components/ToggleBig.scss';
.extension-area-header {
padding-top: 0.5rem;

View File

@ -4,7 +4,7 @@ import * as React from 'react'
import { RouteComponentProps } from 'react-router'
import { catchError } from 'rxjs/operators'
import { FeedbackText } from '../components/FeedbackText'
import { Form } from '../components/Form'
import { Form } from '../../../branded/src/components/Form'
import { HeroPage } from '../components/HeroPage'
import { PageTitle } from '../components/PageTitle'
import { eventLogger } from '../tracking/eventLogger'

View File

@ -10,7 +10,7 @@ import { asError, createAggregateError, ErrorLike, isErrorLike } from '../../../
import { refreshAuthenticatedUser, AuthenticatedUser } from '../../auth'
import { withAuthenticatedUser } from '../../auth/withAuthenticatedUser'
import { mutateGraphQL } from '../../backend/graphql'
import { Form } from '../../components/Form'
import { Form } from '../../../../branded/src/components/Form'
import { ModalPage } from '../../components/ModalPage'
import { PageTitle } from '../../components/PageTitle'
import { eventLogger } from '../../tracking/eventLogger'

View File

@ -12,7 +12,7 @@ import { createAggregateError } from '../../../../shared/src/util/errors'
import { mutateGraphQL } from '../../backend/graphql'
import { CopyableText } from '../../components/CopyableText'
import { DismissibleAlert } from '../../components/DismissibleAlert'
import { Form } from '../../components/Form'
import { Form } from '../../../../branded/src/components/Form'
import { eventLogger } from '../../tracking/eventLogger'
import { ErrorAlert } from '../../components/alerts'
import * as H from 'history'

View File

@ -5,7 +5,7 @@ import { Link } from 'react-router-dom'
import { Subject, Subscription } from 'rxjs'
import { catchError, filter, mergeMap, tap } from 'rxjs/operators'
import { ORG_NAME_MAX_LENGTH, VALID_ORG_NAME_REGEXP } from '..'
import { Form } from '../../components/Form'
import { Form } from '../../../../branded/src/components/Form'
import { PageTitle } from '../../components/PageTitle'
import { eventLogger } from '../../tracking/eventLogger'
import { createOrganization } from '../backend'

View File

@ -4,7 +4,7 @@ import { RouteComponentProps } from 'react-router'
import { concat, of, Subject, Subscription } from 'rxjs'
import { catchError, delay, mergeMap, startWith, switchMap, tap, map, distinctUntilKeyChanged } from 'rxjs/operators'
import { ORG_DISPLAY_NAME_MAX_LENGTH } from '../..'
import { Form } from '../../../components/Form'
import { Form } from '../../../../../branded/src/components/Form'
import { PageTitle } from '../../../components/PageTitle'
import { eventLogger } from '../../../tracking/eventLogger'
import { OrgAreaPageProps } from '../../area/OrgArea'

View File

@ -17,7 +17,7 @@ import {
UIRangeSpec,
} from '../../../shared/src/util/url'
import { queryGraphQL, requestGraphQL } from '../backend/graphql'
import { Tooltip } from '../components/tooltip/Tooltip'
import { Tooltip } from '../../../branded/src/components/tooltip/Tooltip'
import { eventLogger } from '../tracking/eventLogger'
/**

Some files were not shown because too many files have changed in this diff Show More