From 1a3e6cc917345298c678de56649fc41a1948a2a9 Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Feb 2019 17:34:55 -0800 Subject: [PATCH] Consolidate and standardize styles of resource renaming Co-Authored-By: palakp41 --- .../components/index_views/IndexList.scss | 6 -- .../dashboard_index/DashboardsIndex.tsx | 1 + .../DashboardsIndexContents.tsx | 6 +- .../components/dashboard_index/Table.tsx | 64 +++++++---- .../dashboard_index/TableRow.test.tsx | 1 + .../components/dashboard_index/TableRow.tsx | 52 ++++----- .../components/dashboard_index/TableRows.tsx | 6 +- ui/src/dashboards/constants/index.ts | 4 + ui/src/organizations/components/BucketRow.tsx | 4 + .../organizations/components/CollectorRow.tsx | 4 + .../components/OrgDashboardIndex.tsx | 6 +- .../organizations/components/ScraperRow.tsx | 4 + ui/src/shared/components/EditableName.scss | 102 +++++++++--------- ui/src/shared/components/EditableName.tsx | 89 ++++++++------- ui/src/tasks/components/TaskRow.tsx | 4 + 15 files changed, 188 insertions(+), 165 deletions(-) diff --git a/ui/src/clockface/components/index_views/IndexList.scss b/ui/src/clockface/components/index_views/IndexList.scss index d3748cb5219..53df207dd9d 100644 --- a/ui/src/clockface/components/index_views/IndexList.scss +++ b/ui/src/clockface/components/index_views/IndexList.scss @@ -207,9 +207,3 @@ .index-list--row-cell .index-list--cell a { white-space: nowrap; } - -.index-list--resource-name { - margin-left: 6px; - margin-right: $ix-marg-a + $ix-marg-b; - font-size: 17px; -} diff --git a/ui/src/dashboards/components/dashboard_index/DashboardsIndex.tsx b/ui/src/dashboards/components/dashboard_index/DashboardsIndex.tsx index 2727bcdc66f..2dc1a73d8ba 100644 --- a/ui/src/dashboards/components/dashboard_index/DashboardsIndex.tsx +++ b/ui/src/dashboards/components/dashboard_index/DashboardsIndex.tsx @@ -146,6 +146,7 @@ class DashboardIndex extends PureComponent { onEditLabels={this.handleStartEditingLabels} notify={notify} searchTerm={searchTerm} + showOwnerColumn={true} /> diff --git a/ui/src/dashboards/components/dashboard_index/DashboardsIndexContents.tsx b/ui/src/dashboards/components/dashboard_index/DashboardsIndexContents.tsx index 47f03d85c3b..914caa1cfd2 100644 --- a/ui/src/dashboards/components/dashboard_index/DashboardsIndexContents.tsx +++ b/ui/src/dashboards/components/dashboard_index/DashboardsIndexContents.tsx @@ -25,7 +25,7 @@ interface Props { onEditLabels: (dashboard: Dashboard) => void notify: (message: Notification) => void searchTerm: string - showInlineEdit?: boolean + showOwnerColumn: boolean } @ErrorHandling @@ -42,7 +42,7 @@ export default class DashboardsIndexContents extends Component { onEditLabels, searchTerm, orgs, - showInlineEdit, + showOwnerColumn, } = this.props return ( @@ -58,7 +58,7 @@ export default class DashboardsIndexContents extends Component { onUpdateDashboard={onUpdateDashboard} onEditLabels={onEditLabels} orgs={orgs} - showInlineEdit={showInlineEdit} + showOwnerColumn={showOwnerColumn} /> ) } diff --git a/ui/src/dashboards/components/dashboard_index/Table.tsx b/ui/src/dashboards/components/dashboard_index/Table.tsx index 1642621781b..3bfa6f77d3b 100644 --- a/ui/src/dashboards/components/dashboard_index/Table.tsx +++ b/ui/src/dashboards/components/dashboard_index/Table.tsx @@ -20,6 +20,10 @@ import SortingHat from 'src/shared/components/sorting_hat/SortingHat' import {Sort} from 'src/clockface' import {Dashboard, Organization} from 'src/types/v2' +// Constants +const OWNER_COL_WIDTH = 17 +const NAME_COL_WIDTH = 63 + interface Props { searchTerm: string dashboards: Dashboard[] @@ -32,7 +36,7 @@ interface Props { onSetDefaultDashboard: (dashboardLink: string) => void onEditLabels: (dashboard: Dashboard) => void orgs: Organization[] - showInlineEdit?: boolean + showOwnerColumn: boolean } interface DatedDashboard extends Dashboard { @@ -57,29 +61,22 @@ class DashboardsTable extends PureComponent { public render() { const {sortKey, sortDirection} = this.state - const headerKeys: SortKey[] = ['name', 'owner', 'modified', 'default'] return ( + {this.ownerColumnHeader} - @@ -96,6 +93,37 @@ class DashboardsTable extends PureComponent { ) } + private get headerKeys(): SortKey[] { + return ['name', 'owner', 'modified', 'default'] + } + + private get ownerColumnHeader(): JSX.Element { + const {showOwnerColumn} = this.props + const {sortKey, sortDirection} = this.state + + if (showOwnerColumn) { + return ( + + ) + } + } + + private get nameColWidth(): string { + const {showOwnerColumn} = this.props + + if (showOwnerColumn) { + return `${NAME_COL_WIDTH}%` + } + + return `${NAME_COL_WIDTH + OWNER_COL_WIDTH}%` + } + private handleClickColumn = (nextSort: Sort, sortKey: SortKey) => { this.setState({sortKey, sortDirection: nextSort}) } @@ -109,7 +137,7 @@ class DashboardsTable extends PureComponent { onUpdateDashboard, onEditLabels, orgs, - showInlineEdit, + showOwnerColumn, } = this.props const {sortKey, sortDirection} = this.state @@ -130,7 +158,7 @@ class DashboardsTable extends PureComponent { onUpdateDashboard={onUpdateDashboard} onEditLabels={onEditLabels} orgs={orgs} - showInlineEdit={showInlineEdit} + showOwnerColumn={showOwnerColumn} /> )} diff --git a/ui/src/dashboards/components/dashboard_index/TableRow.test.tsx b/ui/src/dashboards/components/dashboard_index/TableRow.test.tsx index 28ee410f914..444ec9c2308 100644 --- a/ui/src/dashboards/components/dashboard_index/TableRow.test.tsx +++ b/ui/src/dashboards/components/dashboard_index/TableRow.test.tsx @@ -18,6 +18,7 @@ const setup = (override = {}) => { onExportDashboard: jest.fn(), onUpdateDashboard: jest.fn(), onEditLabels: jest.fn(), + showOwnerColumn: true, ...override, } diff --git a/ui/src/dashboards/components/dashboard_index/TableRow.tsx b/ui/src/dashboards/components/dashboard_index/TableRow.tsx index 83fb89a5cbb..9a924183f28 100644 --- a/ui/src/dashboards/components/dashboard_index/TableRow.tsx +++ b/ui/src/dashboards/components/dashboard_index/TableRow.tsx @@ -1,7 +1,6 @@ // Libraries import React, {PureComponent} from 'react' import {Link} from 'react-router' -import classnames from 'classnames' // Components import { @@ -37,7 +36,7 @@ interface Props { onExportDashboard: (dashboard: Dashboard) => void onUpdateDashboard: (dashboard: Dashboard) => void onEditLabels: (dashboard: Dashboard) => void - showInlineEdit?: boolean + showOwnerColumn: boolean } export default class DashboardsIndexTableRow extends PureComponent { @@ -67,7 +66,7 @@ export default class DashboardsIndexTableRow extends PureComponent { /> - {this.ownerName} + {this.ownerCell} {this.lastModifiedCell} @@ -91,21 +90,24 @@ export default class DashboardsIndexTableRow extends PureComponent { ) } - private get resourceNames(): JSX.Element { - const {showInlineEdit, dashboard} = this.props - if (showInlineEdit) { - return ( - - ) + private get ownerCell(): JSX.Element { + const {showOwnerColumn} = this.props + + if (showOwnerColumn) { + return {this.ownerName} } + } + + private get resourceNames(): JSX.Element { + const {dashboard} = this.props + return ( - - {this.name} - + ) } @@ -120,7 +122,6 @@ export default class DashboardsIndexTableRow extends PureComponent { return ( @@ -167,12 +168,6 @@ export default class DashboardsIndexTableRow extends PureComponent { onEditLabels(dashboard) } - private get name(): string { - const {dashboard} = this.props - - return dashboard.name || DEFAULT_DASHBOARD_NAME - } - private get ownerName(): JSX.Element { const {dashboard, orgs} = this.props const ownerOrg = orgs.find(o => o.id === dashboard.orgID) @@ -184,17 +179,6 @@ export default class DashboardsIndexTableRow extends PureComponent { ) } - private get nameClassName(): string { - const {dashboard} = this.props - - const dashboardIsUntitled = - dashboard.name === '' || dashboard.name === DEFAULT_DASHBOARD_NAME - - return classnames('index-list--resource-name', { - 'untitled-name': dashboardIsUntitled, - }) - } - private handleUpdateDescription = (description: string): void => { const {onUpdateDashboard} = this.props const dashboard = {...this.props.dashboard, description} diff --git a/ui/src/dashboards/components/dashboard_index/TableRows.tsx b/ui/src/dashboards/components/dashboard_index/TableRows.tsx index 450d8135c1f..bfd68455b27 100644 --- a/ui/src/dashboards/components/dashboard_index/TableRows.tsx +++ b/ui/src/dashboards/components/dashboard_index/TableRows.tsx @@ -15,7 +15,7 @@ interface Props { onUpdateDashboard: (dashboard: Dashboard) => void onEditLabels: (dashboard: Dashboard) => void orgs: Organization[] - showInlineEdit?: boolean + showOwnerColumn: boolean } export default class DashboardsIndexTableRows extends PureComponent { @@ -28,7 +28,7 @@ export default class DashboardsIndexTableRows extends PureComponent { onUpdateDashboard, onEditLabels, orgs, - showInlineEdit, + showOwnerColumn, } = this.props return dashboards.map(d => ( @@ -41,7 +41,7 @@ export default class DashboardsIndexTableRows extends PureComponent { onUpdateDashboard={onUpdateDashboard} onEditLabels={onEditLabels} orgs={orgs} - showInlineEdit={showInlineEdit} + showOwnerColumn={showOwnerColumn} /> )) } diff --git a/ui/src/dashboards/constants/index.ts b/ui/src/dashboards/constants/index.ts index 2fdcca8bbfd..6ffe632c07d 100644 --- a/ui/src/dashboards/constants/index.ts +++ b/ui/src/dashboards/constants/index.ts @@ -89,6 +89,10 @@ type NewDefaultDashboard = Pick< > export const DEFAULT_CELL_NAME = 'Name this Cell' export const DEFAULT_DASHBOARD_NAME = 'Name this Dashboard' +export const DEFAULT_BUCKET_NAME = 'Name this Bucket' +export const DEFAULT_COLLECTOR_NAME = 'Name this Collector' +export const DEFAULT_TASK_NAME = 'Name this Task' +export const DEFAULT_SCRAPER_NAME = 'Name this Scraper' export const NEW_DASHBOARD: NewDefaultDashboard = { name: DEFAULT_DASHBOARD_NAME, cells: [NEW_DEFAULT_DASHBOARD_CELL], diff --git a/ui/src/organizations/components/BucketRow.tsx b/ui/src/organizations/components/BucketRow.tsx index f7334975a7a..4dfb8cc107e 100644 --- a/ui/src/organizations/components/BucketRow.tsx +++ b/ui/src/organizations/components/BucketRow.tsx @@ -12,6 +12,9 @@ import { ComponentColor, } from 'src/clockface' +// Constants +import {DEFAULT_BUCKET_NAME} from 'src/dashboards/constants' + // Types import {Bucket} from '@influxdata/influx' import {DataLoaderType} from 'src/types/v2/dataLoaders' @@ -40,6 +43,7 @@ export default class BucketRow extends PureComponent { onUpdate={this.handleUpdateBucketName} name={bucket.name} onEditName={this.handleEditBucket} + noNameString={DEFAULT_BUCKET_NAME} /> {bucket.ruleString} diff --git a/ui/src/organizations/components/CollectorRow.tsx b/ui/src/organizations/components/CollectorRow.tsx index 489ecc7d871..fecf3574a17 100644 --- a/ui/src/organizations/components/CollectorRow.tsx +++ b/ui/src/organizations/components/CollectorRow.tsx @@ -14,6 +14,9 @@ import { import {Telegraf} from '@influxdata/influx' import EditableName from 'src/shared/components/EditableName' +// Constants +import {DEFAULT_COLLECTOR_NAME} from 'src/dashboards/constants' + interface Props { collector: Telegraf bucket: string @@ -34,6 +37,7 @@ export default class CollectorRow extends PureComponent { {bucket} diff --git a/ui/src/organizations/components/OrgDashboardIndex.tsx b/ui/src/organizations/components/OrgDashboardIndex.tsx index 20c91dcb5aa..606d488eff6 100644 --- a/ui/src/organizations/components/OrgDashboardIndex.tsx +++ b/ui/src/organizations/components/OrgDashboardIndex.tsx @@ -6,7 +6,7 @@ import {downloadTextFile} from 'src/shared/utils/download' import _ from 'lodash' // Components -import DashboardsContents from 'src/dashboards/components/dashboard_index/DashboardIndexContents' +import DashboardsIndexContents from 'src/dashboards/components/dashboard_index/DashboardsIndexContents' import { OverlayTechnology, Button, @@ -133,7 +133,7 @@ class OrgDashboardIndex extends PureComponent { titleText="Create a new dashboard" /> - { onEditLabels={this.handleStartEditingLabels} notify={notify} searchTerm={searchTerm} - showInlineEdit={true} + showOwnerColumn={false} /> {this.renderImportOverlay} {this.renderLabelEditorOverlay} diff --git a/ui/src/organizations/components/ScraperRow.tsx b/ui/src/organizations/components/ScraperRow.tsx index 0ebdeec1bb6..d37237eb41f 100644 --- a/ui/src/organizations/components/ScraperRow.tsx +++ b/ui/src/organizations/components/ScraperRow.tsx @@ -11,6 +11,9 @@ import { import {ScraperTargetResponse} from '@influxdata/influx' import EditableName from 'src/shared/components/EditableName' +// Constants +import {DEFAULT_SCRAPER_NAME} from 'src/dashboards/constants' + interface Props { scraper: ScraperTargetResponse onDeleteScraper: (scraper) => void @@ -27,6 +30,7 @@ export default class ScraperRow extends PureComponent { {scraper.bucket} diff --git a/ui/src/shared/components/EditableName.scss b/ui/src/shared/components/EditableName.scss index 5530883f178..784fa220f33 100644 --- a/ui/src/shared/components/EditableName.scss +++ b/ui/src/shared/components/EditableName.scss @@ -5,82 +5,78 @@ @import 'src/style/modules'; -$rename-dash-title-padding: 5px; +$resource-name-font-size: 17px; +$resource-name-font-wight: 600; +$rename-dash-title-padding: 6px; -.editable-name { - height: $form-xs-height; - width: 100%; - margin-top: -3px; -} -.editable-name--preview, +.editable-name > a, .input.editable-name--input > input { - font-size: $form-xs-font; - font-weight: 400; + font-size: $resource-name-font-size; + font-weight: $resource-name-font-wight; font-family: $ix-text-font; padding: 0 $rename-dash-title-padding; } -.editable-name--preview, -.editable-name--input { - position: relative; - width: 100%; +.editable-name > a { + white-space: nowrap; + line-height: $resource-name-font-size; + padding-left: ($rename-dash-title-padding + $ix-border); + padding-right: 0; } -.editable-name--preview { - display: inline-flex; - justify-content: flex-start; - align-items: center; - border-radius: $radius; - position: relative; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - @include no-user-select(); - color: $g13-mist; - transition: color 0.25s ease, background-color 0.25s ease, border-color 0.25s ease; - border: $ix-border solid transparent; +.editable-name { height: $form-xs-height; - line-height: $form-xs-height - ($ix-border * 2); - - .icon { - position: relative; - display: inline-block; - margin-left: $ix-marg-b; - opacity: 0; - transition: opacity 0.25s ease; - color: $g11-sidewalk; - } - - &:hover .icon { - opacity: 1; - } - - &.untitled { - color: $g9-mountain; - font-style: italic; - } + position: relative; + display: inline-block; +} + +.editable-name--toggle { + font-size: $resource-name-font-size * 0.75; + transform: translateY(-10%); + padding: $ix-marg-a; + display: inline-block; + margin-left: $ix-marg-b; + transition: color 0.25s ease, opacity 0.25s ease; + opacity: 1; + color: $g11-sidewalk; &:hover { - cursor: text; - color: $g20-white; - // background-color: $g3-castle; - // border-color: $g3-castle; + cursor: pointer; + color: $g15-platinum; } } + +.input.editable-name--input { + position: absolute; + top: -1px; + left: 0; + width: 100%; +} + /* Ensure placeholder text matches font weight of title */ .input.editable-name--input > input { &::-webkit-input-placeholder { - font-weight: $page-title-weight !important; + font-weight: $resource-name-font-wight !important; } &::-moz-placeholder { - font-weight: $page-title-weight !important; + font-weight: $resource-name-font-wight !important; } &:-ms-input-placeholder { - font-weight: $page-title-weight !important; + font-weight: $resource-name-font-wight !important; } &:-moz-placeholder { - font-weight: $page-title-weight !important; + font-weight: $resource-name-font-wight !important; } } + + +/* When used inside an index list, hide edit button until row hover */ + +.index-list--row .editable-name--toggle { + opacity: 0; +} +.index-list--row:hover .editable-name--toggle { + opacity: 1; +} \ No newline at end of file diff --git a/ui/src/shared/components/EditableName.tsx b/ui/src/shared/components/EditableName.tsx index 1d5aec8cafa..e3ed77a94e6 100644 --- a/ui/src/shared/components/EditableName.tsx +++ b/ui/src/shared/components/EditableName.tsx @@ -12,14 +12,20 @@ import {ErrorHandling} from 'src/shared/decorators/errors' // Styles import 'src/shared/components/EditableName.scss' -interface Props { +interface PassedProps { onUpdate: (name: string) => void name: string - onEditName: (e?: MouseEvent) => void - hrefValue?: string + onEditName?: (e?: MouseEvent) => void placeholder?: string + noNameString: string } +interface DefaultProps { + hrefValue?: string +} + +type Props = PassedProps & DefaultProps + interface State { isEditing: boolean workingName: string @@ -27,9 +33,10 @@ interface State { @ErrorHandling class EditableName extends Component { - public static defaultProps: Partial = { + public static defaultProps: DefaultProps = { hrefValue: '#', } + constructor(props: Props) { super(props) @@ -40,54 +47,46 @@ class EditableName extends Component { } public render() { - const {name, onEditName, hrefValue} = this.props - const {isEditing} = this.state - - if (isEditing) { - return ( -
- - {this.input} - -
- ) - } + const {name, onEditName, hrefValue, noNameString} = this.props return ( - <> +
- {name || 'No name'} + {name || noNameString} -
-
- -
+
+
- + {this.input} +
) } private get input(): JSX.Element { const {placeholder} = this.props - const {workingName} = this.state + const {workingName, isEditing} = this.state - return ( - - ) + if (isEditing) { + return ( + + + + ) + } } private handleStartEditing = (): void => { @@ -127,11 +126,11 @@ class EditableName extends Component { e.currentTarget.select() } - private get previewClassName(): string { - const {name} = this.props + private get className(): string { + const {name, noNameString} = this.props - return classnames('editable-name--preview', { - untitled: name === '', + return classnames('editable-name', { + 'untitled-name': name === noNameString, }) } } diff --git a/ui/src/tasks/components/TaskRow.tsx b/ui/src/tasks/components/TaskRow.tsx index b5c463d6c98..1ab63e4c4c8 100644 --- a/ui/src/tasks/components/TaskRow.tsx +++ b/ui/src/tasks/components/TaskRow.tsx @@ -20,6 +20,9 @@ import { import {downloadTextFile} from 'src/shared/utils/download' import {Task as TaskAPI, Organization} from '@influxdata/influx' +// Constants +import {DEFAULT_TASK_NAME} from 'src/dashboards/constants' + interface Task extends TaskAPI { organization: Organization } @@ -102,6 +105,7 @@ export class TaskRow extends PureComponent { onUpdate={this.handleUpdateTask} name={task.name} onEditName={this.handleClick} + noNameString={DEFAULT_TASK_NAME} /> ) }