Various Polish Stories (#11123)

* Decrease space below overlay headings

* Make panels contrast with background when nested in a tabbed page

* Improve styling of user settings page

* Improve styling of Labels and Tokens pages

* Polish Bucket overlays

* Link to org profile from dashboards list

* Refer to actual resource type instead of "This Resource"

* Link homepage card to collectors page

* Update test snapshots
pull/11122/head
alexpaxton 2019-01-15 15:56:15 -08:00 committed by GitHub
parent 2a3b82bd3f
commit cf7ab909fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 664 additions and 600 deletions

View File

@ -121,6 +121,6 @@ $overlay-min-height: 150px;
.overlay--body { .overlay--body {
padding: $overlay-gutter; padding: $overlay-gutter;
padding-top: 18px; padding-top: 0;
min-height: $overlay-min-height; min-height: $overlay-min-height;
} }

View File

@ -5,6 +5,7 @@
$panel-gutter: $ix-marg-b * 2; $panel-gutter: $ix-marg-b * 2;
$panel-background: $g3-castle; $panel-background: $g3-castle;
$panel-nested-background: $g4-onyx;
.panel { .panel {
display: flex; display: flex;
@ -55,3 +56,13 @@ $panel-background: $g3-castle;
.panel-body hr { .panel-body hr {
margin: $ix-marg-c 0; margin: $ix-marg-c 0;
} }
// Panels Nested inside Tabbed Pages
// ----------------------------------------------------------------------------
.tabbed-page .panel {
background-color: $panel-nested-background;
.panel-footer {
background-color: mix($panel-nested-background, $g3-castle, 50%);
}
}

View File

@ -98,6 +98,7 @@ export default class DashboardsIndexTableRow extends PureComponent<Props> {
limitChildCount={4} limitChildCount={4}
className="index-list--labels" className="index-list--labels"
onEdit={this.handleEditLabels} onEdit={this.handleEditLabels}
resourceName="this Dashboard"
/> />
) )
} }
@ -107,6 +108,7 @@ export default class DashboardsIndexTableRow extends PureComponent<Props> {
limitChildCount={4} limitChildCount={4}
className="index-list--labels" className="index-list--labels"
onEdit={this.handleEditLabels} onEdit={this.handleEditLabels}
resourceName="this Dashboard"
> >
{dashboard.labels.map(label => ( {dashboard.labels.map(label => (
<Label <Label
@ -147,10 +149,15 @@ export default class DashboardsIndexTableRow extends PureComponent<Props> {
return dashboard.name || DEFAULT_DASHBOARD_NAME return dashboard.name || DEFAULT_DASHBOARD_NAME
} }
private get ownerName(): string { private get ownerName(): JSX.Element {
const {dashboard, orgs} = this.props const {dashboard, orgs} = this.props
const ownerOrg = orgs.find(o => o.id === dashboard.orgID) const ownerOrg = orgs.find(o => o.id === dashboard.orgID)
return ownerOrg.name
return (
<Link to={`/organizations/${dashboard.orgID}/members_tab`}>
{ownerOrg.name}
</Link>
)
} }
private get nameClassName(): string { private get nameClassName(): string {

View File

@ -1,6 +1,7 @@
// Libraries // Libraries
import React, {PureComponent} from 'react' import React, {PureComponent} from 'react'
import {Link} from 'react-router' import {Link} from 'react-router'
import {connect} from 'react-redux'
// Components // Components
import GradientBorder from 'src/shared/components/cells/GradientBorder' import GradientBorder from 'src/shared/components/cells/GradientBorder'
@ -8,15 +9,25 @@ import DashboardingGraphic from 'src/me/graphics/DashboardingGraphic'
import ExploreGraphic from 'src/me/graphics/ExploreGraphic' import ExploreGraphic from 'src/me/graphics/ExploreGraphic'
import CollectorGraphic from 'src/me/graphics/CollectorGraphic' import CollectorGraphic from 'src/me/graphics/CollectorGraphic'
// Types
import {Organization} from 'src/types/v2'
// Styles // Styles
import 'src/me/components/GettingStarted.scss' import 'src/me/components/GettingStarted.scss'
export default class GettingStarted extends PureComponent { interface StateProps {
orgs: Organization[]
}
class GettingStarted extends PureComponent<StateProps> {
public render() { public render() {
return ( return (
<div className="getting-started"> <div className="getting-started">
<div className="getting-started--container"> <div className="getting-started--container">
<Link to={`/data-explorer`} className="getting-started--card"> <Link
to={this.firstOrgCollectorLink}
className="getting-started--card"
>
<GradientBorder /> <GradientBorder />
<CollectorGraphic /> <CollectorGraphic />
<h3 className="getting-started--title"> <h3 className="getting-started--title">
@ -50,4 +61,23 @@ export default class GettingStarted extends PureComponent {
</div> </div>
) )
} }
private get firstOrgCollectorLink(): string {
const {orgs} = this.props
const firstOrgID = orgs[0].id
return `/organizations/${firstOrgID}/collectors_tab`
}
} }
const mstp = (state): StateProps => {
const {orgs} = state
return {orgs}
}
export default connect<StateProps>(
mstp,
null
)(GettingStarted)

View File

@ -35,15 +35,15 @@ export class Settings extends PureComponent<StateProps, State> {
const {me} = this.state const {me} = this.state
return ( return (
<Grid>
<Grid.Row>
<Grid.Column widthXS={Columns.Six}>
<Panel> <Panel>
<Panel.Header title="About Me"> <Panel.Header title="About Me">
<Button text="Edit About Me" /> <Button text="Edit About Me" />
</Panel.Header> </Panel.Header>
<Panel.Body> <Panel.Body>
<Form> <Form>
<Grid>
<Grid.Row>
<Grid.Column widthXS={Columns.Six}>
<Form.Element label="Username"> <Form.Element label="Username">
<Input <Input
value={me.name} value={me.name}
@ -54,12 +54,12 @@ export class Settings extends PureComponent<StateProps, State> {
onChange={this.handleChangeInput} onChange={this.handleChangeInput}
/> />
</Form.Element> </Form.Element>
</Grid.Column>
</Grid.Row>
</Grid>
</Form> </Form>
</Panel.Body> </Panel.Body>
</Panel> </Panel>
</Grid.Column>
</Grid.Row>
</Grid>
) )
} }

View File

@ -3,10 +3,11 @@ import React, {PureComponent, ChangeEvent} from 'react'
import {connect} from 'react-redux' import {connect} from 'react-redux'
// Components // Components
import {Panel, Input, Spinner} from 'src/clockface' import {IconFont, Input, Spinner} from 'src/clockface'
import ResourceFetcher from 'src/shared/components/resource_fetcher' import ResourceFetcher from 'src/shared/components/resource_fetcher'
import TokenList from 'src/me/components/account/TokensList' import TokenList from 'src/me/components/account/TokensList'
import FilterList from 'src/shared/components/Filter' import FilterList from 'src/shared/components/Filter'
import TabbedPageHeader from 'src/shared/components/tabbed_page/TabbedPageHeader'
// APIs // APIs
import {getAuthorizations} from 'src/authorizations/apis' import {getAuthorizations} from 'src/authorizations/apis'
@ -44,16 +45,16 @@ export class Tokens extends PureComponent<Props, State> {
const {searchTerm} = this.state const {searchTerm} = this.state
return ( return (
<Panel> <>
<Panel.Body> <TabbedPageHeader>
<Input <Input
icon={IconFont.Search}
value={searchTerm} value={searchTerm}
placeholder="Filter tokens by column" placeholder="Filter Tokens..."
onChange={this.handleChangeSearchTerm} onChange={this.handleChangeSearchTerm}
widthPixels={256} widthPixels={256}
/> />
</Panel.Body> </TabbedPageHeader>
<Panel.Body>
<ResourceFetcher<Authorization[]> fetcher={getAuthorizations}> <ResourceFetcher<Authorization[]> fetcher={getAuthorizations}>
{(fetchedAuths, loading) => ( {(fetchedAuths, loading) => (
<Spinner loading={loading}> <Spinner loading={loading}>
@ -73,8 +74,7 @@ export class Tokens extends PureComponent<Props, State> {
</Spinner> </Spinner>
)} )}
</ResourceFetcher> </ResourceFetcher>
</Panel.Body> </>
</Panel>
) )
} }

View File

@ -82,11 +82,13 @@ export default class TokenList extends PureComponent<Props, State> {
private get emptyState(): JSX.Element { private get emptyState(): JSX.Element {
const {searchTerm} = this.props const {searchTerm} = this.props
let emptyStateText = 'Could not find any tokens' let emptyStateText =
'There are not any Tokens associated with this account. Contact your administrator'
if (searchTerm) { if (searchTerm) {
emptyStateText = 'Looks like no tokens match your search term' emptyStateText = 'No Tokens match your search term'
} }
return ( return (
<EmptyState size={ComponentSize.Large}> <EmptyState size={ComponentSize.Large}>
<EmptyState.Text text={emptyStateText} /> <EmptyState.Text text={emptyStateText} />

View File

@ -13,6 +13,25 @@ exports[`Account rendering renders! 1`] = `
} }
} }
> >
<Grid>
<div
className="grid--container"
>
<Select
type={[Function]}
>
<GridRow
key=".0"
>
<div
className="grid--row"
>
<GridColumn
widthXS={6}
>
<div
className="grid--column col-xs-6"
>
<Panel> <Panel>
<div <div
className="panel" className="panel"
@ -69,25 +88,6 @@ exports[`Account rendering renders! 1`] = `
<form <form
className="form--wrapper" className="form--wrapper"
onSubmit={[Function]} onSubmit={[Function]}
>
<Grid>
<div
className="grid--container"
>
<Select
type={[Function]}
>
<GridRow
key=".0"
>
<div
className="grid--row"
>
<GridColumn
widthXS={6}
>
<div
className="grid--column col-xs-6"
> >
<FormElement <FormElement
label="Username" label="Username"
@ -148,6 +148,12 @@ exports[`Account rendering renders! 1`] = `
</Input> </Input>
</div> </div>
</FormElement> </FormElement>
</form>
</Form>
</div>
</PanelBody>
</div>
</Panel>
</div> </div>
</GridColumn> </GridColumn>
</div> </div>
@ -155,11 +161,5 @@ exports[`Account rendering renders! 1`] = `
</Select> </Select>
</div> </div>
</Grid> </Grid>
</form>
</Form>
</div>
</PanelBody>
</div>
</Panel>
</Settings> </Settings>
`; `;

View File

@ -4,21 +4,18 @@ exports[`Account rendering renders! 1`] = `
<Tokens <Tokens
authorizationsLink="api/v2/authorizations" authorizationsLink="api/v2/authorizations"
> >
<Panel> <TabbedPageHeader>
<div <div
className="panel" className="tabbed-page-section--header"
>
<PanelBody>
<div
className="panel-body"
> >
<Input <Input
autoFocus={false} autoFocus={false}
autocomplete="off" autocomplete="off"
disabledTitleText="This input is disabled" disabledTitleText="This input is disabled"
icon="search"
name="" name=""
onChange={[Function]} onChange={[Function]}
placeholder="Filter tokens by column" placeholder="Filter Tokens..."
size="sm" size="sm"
spellCheck={false} spellCheck={false}
status="default" status="default"
@ -27,7 +24,7 @@ exports[`Account rendering renders! 1`] = `
widthPixels={256} widthPixels={256}
> >
<div <div
className="input input-sm" className="input input-sm input--has-icon"
style={ style={
Object { Object {
"width": "256px", "width": "256px",
@ -41,22 +38,21 @@ exports[`Account rendering renders! 1`] = `
disabled={false} disabled={false}
name="" name=""
onChange={[Function]} onChange={[Function]}
placeholder="Filter tokens by column" placeholder="Filter Tokens..."
spellCheck={false} spellCheck={false}
title="" title=""
value="" value=""
/> />
<span
className="input-icon icon search"
/>
<div <div
className="input-shadow" className="input-shadow"
/> />
</div> </div>
</Input> </Input>
</div> </div>
</PanelBody> </TabbedPageHeader>
<PanelBody>
<div
className="panel-body"
>
<ResourceFetcher <ResourceFetcher
fetcher={[Function]} fetcher={[Function]}
> >
@ -242,7 +238,7 @@ exports[`Account rendering renders! 1`] = `
size="lg" size="lg"
> >
<EmptyStateText <EmptyStateText
text="Could not find any tokens" text="There are not any Tokens associated with this account. Contact your administrator"
/> />
</EmptyState> </EmptyState>
} }
@ -505,9 +501,5 @@ exports[`Account rendering renders! 1`] = `
</FilterList> </FilterList>
</Spinner> </Spinner>
</ResourceFetcher> </ResourceFetcher>
</div>
</PanelBody>
</div>
</Panel>
</Tokens> </Tokens>
`; `;

View File

@ -60,25 +60,24 @@ export default class BucketOverlayForm extends PureComponent<Props> {
/> />
</Form.Element> </Form.Element>
</Grid.Column> </Grid.Column>
<Grid.Column>
<Retention <Retention
type={ruleType} type={ruleType}
retentionSeconds={retentionSeconds} retentionSeconds={retentionSeconds}
onChangeRuleType={onChangeRuleType} onChangeRuleType={onChangeRuleType}
onChangeRetentionRule={onChangeRetentionRule} onChangeRetentionRule={onChangeRetentionRule}
/> />
</Grid.Column> </Grid.Row>
<Grid.Row>
<Grid.Column> <Grid.Column>
<Form.Footer> <Form.Footer>
<Button <Button
text="Cancel" text="Cancel"
color={ComponentColor.Danger}
onClick={onCloseModal} onClick={onCloseModal}
type={ButtonType.Button} type={ButtonType.Button}
/> />
<Button <Button
text={buttonText} text={buttonText}
color={ComponentColor.Primary} color={this.submitButtonColor}
type={ButtonType.Submit} type={ButtonType.Submit}
/> />
</Form.Footer> </Form.Footer>
@ -88,4 +87,14 @@ export default class BucketOverlayForm extends PureComponent<Props> {
</Form> </Form>
) )
} }
private get submitButtonColor(): ComponentColor {
const {buttonText} = this.props
if (buttonText === 'Save Changes') {
return ComponentColor.Success
}
return ComponentColor.Primary
}
} }

View File

@ -47,7 +47,7 @@ export default class BucketOverlay extends PureComponent<Props, State> {
const {bucket, nameInputStatus, errorMessage, ruleType} = this.state const {bucket, nameInputStatus, errorMessage, ruleType} = this.state
return ( return (
<OverlayContainer> <OverlayContainer maxWidth={500}>
<OverlayHeading <OverlayHeading
title="Create Bucket" title="Create Bucket"
onDismiss={this.props.onCloseModal} onDismiss={this.props.onCloseModal}

View File

@ -213,15 +213,26 @@ class Labels extends PureComponent<Props, State> {
private get emptyState(): JSX.Element { private get emptyState(): JSX.Element {
const {searchTerm} = this.state const {searchTerm} = this.state
let emptyText = 'No Labels were found'
if (searchTerm) { if (searchTerm) {
emptyText = 'No Labels match your search term' return (
<EmptyState size={ComponentSize.Medium}>
<EmptyState.Text text="No Labels match your search term" />
</EmptyState>
)
} }
return ( return (
<EmptyState size={ComponentSize.Medium}> <EmptyState size={ComponentSize.Medium}>
<EmptyState.Text text={emptyText} /> <EmptyState.Text
text="Looks like you haven't created any Labels , why not create one?"
highlightWords={['Labels']}
/>
<Button
text="Create Label"
color={ComponentColor.Primary}
icon={IconFont.Plus}
onClick={this.handleShowOverlay}
/>
</EmptyState> </EmptyState>
) )
} }

View File

@ -2,7 +2,7 @@
import React, {PureComponent, ChangeEvent} from 'react' import React, {PureComponent, ChangeEvent} from 'react'
// Components // Components
import {Form, Radio} from 'src/clockface' import {Grid, Form, Radio, ButtonShape} from 'src/clockface'
import RetentionDuration from 'src/organizations/components/RetentionDuration' import RetentionDuration from 'src/organizations/components/RetentionDuration'
// Utils // Utils
@ -27,8 +27,9 @@ export default class Retention extends PureComponent<Props> {
return ( return (
<> <>
<Grid.Column>
<Form.Element label="How often to clear data?"> <Form.Element label="How often to clear data?">
<Radio> <Radio shape={ButtonShape.StretchToFit}>
<Radio.Button <Radio.Button
active={type === BucketRetentionRules.TypeEnum.Expire} active={type === BucketRetentionRules.TypeEnum.Expire}
onClick={this.handleRadioClick} onClick={this.handleRadioClick}
@ -45,6 +46,7 @@ export default class Retention extends PureComponent<Props> {
</Radio.Button> </Radio.Button>
</Radio> </Radio>
</Form.Element> </Form.Element>
</Grid.Column>
<RetentionDuration <RetentionDuration
type={type} type={type}
retentionSeconds={retentionSeconds} retentionSeconds={retentionSeconds}

View File

@ -31,7 +31,7 @@ export default class RetentionDuration extends PureComponent<Props> {
return ( return (
<> <>
<Grid.Column widthXS={Columns.Two}> <Grid.Column widthSM={Columns.Three}>
<Form.Element label="Days"> <Form.Element label="Days">
<Input <Input
name={DurationKey.Days} name={DurationKey.Days}
@ -41,7 +41,7 @@ export default class RetentionDuration extends PureComponent<Props> {
/> />
</Form.Element> </Form.Element>
</Grid.Column> </Grid.Column>
<Grid.Column widthXS={Columns.Two}> <Grid.Column widthSM={Columns.Three}>
<Form.Element label="Hours"> <Form.Element label="Hours">
<Input <Input
name={DurationKey.Hours} name={DurationKey.Hours}
@ -52,7 +52,7 @@ export default class RetentionDuration extends PureComponent<Props> {
/> />
</Form.Element> </Form.Element>
</Grid.Column> </Grid.Column>
<Grid.Column widthXS={Columns.Two}> <Grid.Column widthSM={Columns.Three}>
<Form.Element label="Minutes"> <Form.Element label="Minutes">
<Input <Input
name={DurationKey.Minutes} name={DurationKey.Minutes}
@ -63,7 +63,7 @@ export default class RetentionDuration extends PureComponent<Props> {
/> />
</Form.Element> </Form.Element>
</Grid.Column> </Grid.Column>
<Grid.Column widthXS={Columns.Two}> <Grid.Column widthSM={Columns.Three}>
<Form.Element label="Seconds"> <Form.Element label="Seconds">
<Input <Input
name={DurationKey.Seconds} name={DurationKey.Seconds}

View File

@ -44,15 +44,15 @@ export default class BucketOverlay extends PureComponent<Props, State> {
const {bucket, nameInputStatus, errorMessage, ruleType} = this.state const {bucket, nameInputStatus, errorMessage, ruleType} = this.state
return ( return (
<OverlayContainer> <OverlayContainer maxWidth={500}>
<OverlayHeading <OverlayHeading
title="Update Bucket" title="Edit Bucket"
onDismiss={this.props.onCloseModal} onDismiss={this.props.onCloseModal}
/> />
<OverlayBody> <OverlayBody>
<BucketOverlayForm <BucketOverlayForm
name={bucket.name} name={bucket.name}
buttonText="Update" buttonText="Save Changes"
ruleType={ruleType} ruleType={ruleType}
onCloseModal={onCloseModal} onCloseModal={onCloseModal}
errorMessage={errorMessage} errorMessage={errorMessage}

View File

@ -104,7 +104,7 @@ export class TaskRow extends PureComponent<Props & WithRouterProps> {
} }
return ( return (
<Label.Container limitChildCount={4}> <Label.Container limitChildCount={4} resourceName="this Task">
{task.labels.map(label => ( {task.labels.map(label => (
<Label <Label
key={label.resourceID} key={label.resourceID}