Unverified Commit a87354bd authored by Tamika Tannis's avatar Tamika Tannis Committed by GitHub

fix: Miscellaneous UI Fixes (#469)

* Fix dashboard preview modal title

* Improve vertical spacing in resource header

* Apply min-height to left panel metadata sections

* Update EditableSection rendering when missing optional props

* Update style for left panel metadata sections

* Fix resource detail height; Remove duplicate style

* Add hover effects on the service links

* Update EditableSection tests
parent 6da70150
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
$resource-header-height: 84px; $resource-header-height: 84px;
.resource-detail-layout { .resource-detail-layout {
height: calc(100% - #{$nav-bar-height} - #{$footer-height}); height: calc(100vh - #{$nav-bar-height} - #{$footer-height});
.resource-header { .resource-header {
display: flex; display: flex;
height: $resource-header-height; height: $resource-header-height;
border-bottom: 2px solid $divider; border-bottom: 2px solid $divider;
padding: 16px 24px 0; padding: 16px 24px;
.icon-header { .icon-header {
...@@ -20,11 +20,13 @@ $resource-header-height: 84px; ...@@ -20,11 +20,13 @@ $resource-header-height: 84px;
.header-section { .header-section {
&.header-title { &.header-title {
flex-grow: 1; flex-grow: 1;
overflow: hidden;
.header-title-text { .header-title-text {
display: inline-block; display: inline-block;
max-width: calc(100% - 100px); max-width: calc(100% - 100px);
// Better align the header-title-text
// (84px header height - 32px vertical padding - 2px border - 20px subtitle line-height) = 30px
line-height: 30px;
} }
} }
...@@ -97,13 +99,20 @@ $resource-header-height: 84px; ...@@ -97,13 +99,20 @@ $resource-header-height: 84px;
.section-title { .section-title {
color: $text-tertiary; color: $text-tertiary;
margin: 40px 0 8px; margin-bottom: 8px;
}
.editable-section,
.metadata-section {
margin-top: 40px;
min-height: 70px;
display: inline-table;
} }
.editable-text { .editable-text {
font-size: 16px; font-size: 16px;
.markdown-wrapper{ .markdown-wrapper {
font-size: 16px; font-size: 16px;
} }
} }
......
...@@ -33,7 +33,7 @@ const PreviewModal = ({ imageSrc, onClose }: PreviewModalProps) => { ...@@ -33,7 +33,7 @@ const PreviewModal = ({ imageSrc, onClose }: PreviewModalProps) => {
return ( return (
<Modal show={show} onHide={handleClose} scrollable="true" className="dashboard-preview-modal"> <Modal show={show} onHide={handleClose} scrollable="true" className="dashboard-preview-modal">
<Modal.Header closeButton={true}> <Modal.Header closeButton={true}>
<Modal.Title className="text-center">Constants.DASHBOARD_PREVIEW_MODAL_TITLE</Modal.Title> <Modal.Title className="text-center">{Constants.DASHBOARD_PREVIEW_MODAL_TITLE}</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<img <img
......
...@@ -207,6 +207,7 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard ...@@ -207,6 +207,7 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard
</EditableSection> </EditableSection>
<section className="column-layout-2"> <section className="column-layout-2">
<section className="left-panel"> <section className="left-panel">
<section className="metadata-section">
<div className="section-title title-3">Owners</div> <div className="section-title title-3">Owners</div>
<div> <div>
{ {
...@@ -229,19 +230,26 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard ...@@ -229,19 +230,26 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard
/> />
} }
</div> </div>
</section>
<section className="metadata-section">
<div className="section-title title-3">Created</div> <div className="section-title title-3">Created</div>
<div className="body-2 text-primary"> <div className="body-2 text-primary">
{ formatDateTimeShort({ epochTimestamp: dashboard.created_timestamp}) } { formatDateTimeShort({ epochTimestamp: dashboard.created_timestamp}) }
</div> </div>
</section>
<section className="metadata-section">
<div className="section-title title-3">Last Updated</div> <div className="section-title title-3">Last Updated</div>
<div className="body-2 text-primary"> <div className="body-2 text-primary">
{ formatDateTimeShort({ epochTimestamp: dashboard.updated_timestamp }) } { formatDateTimeShort({ epochTimestamp: dashboard.updated_timestamp }) }
</div> </div>
</section>
<section className="metadata-section">
<div className="section-title title-3">Recent View Count</div> <div className="section-title title-3">Recent View Count</div>
<div className="body-2 text-primary"> <div className="body-2 text-primary">
{ dashboard.recent_view_count } { dashboard.recent_view_count }
</div> </div>
</section> </section>
</section>
<section className="right-panel"> <section className="right-panel">
<EditableSection title="Tags"> <EditableSection title="Tags">
<TagInput <TagInput
...@@ -249,10 +257,13 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard ...@@ -249,10 +257,13 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard
uriKey={ this.props.dashboard.uri } uriKey={ this.props.dashboard.uri }
/> />
</EditableSection> </EditableSection>
<section className="metadata-section">
<div className="section-title title-3">Last Successful Run</div> <div className="section-title title-3">Last Successful Run</div>
<div className="body-2 text-primary"> <div className="body-2 text-primary">
{ formatDateTimeShort({ epochTimestamp: dashboard.last_successful_run_timestamp }) } { formatDateTimeShort({ epochTimestamp: dashboard.last_successful_run_timestamp }) }
</div> </div>
</section>
<section className="metadata-section">
<div className="section-title title-3">Last Run</div> <div className="section-title title-3">Last Run</div>
<div> <div>
<div className="body-2 text-primary"> <div className="body-2 text-primary">
...@@ -268,6 +279,7 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard ...@@ -268,6 +279,7 @@ export class DashboardPage extends React.Component<DashboardPageProps, Dashboard
</div> </div>
</section> </section>
</section> </section>
</section>
<ImagePreview uri={this.state.uri} redirectUrl={dashboard.url} /> <ImagePreview uri={this.state.uri} redirectUrl={dashboard.url} />
</section> </section>
<section className="right-panel"> <section className="right-panel">
......
...@@ -155,37 +155,43 @@ class TableDetail extends React.Component<TableDetailProps & RouteComponentProps ...@@ -155,37 +155,43 @@ class TableDetail extends React.Component<TableDetailProps & RouteComponentProps
</header> </header>
<article className="column-layout-1"> <article className="column-layout-1">
<section className="left-panel"> <section className="left-panel">
{}
<EditableSection title="Description"> <EditableSection title="Description">
<TableDescEditableText <TableDescEditableText
maxLength={ AppConfig.editableText.tableDescLength } maxLength={ AppConfig.editableText.tableDescLength }
value={ data.description } value={ data.description }
editable={ data.is_editable } editable={ data.is_editable }
/> />
</EditableSection>
<span> <span>
{ notificationsEnabled() && <RequestDescriptionText/> } { notificationsEnabled() && <RequestDescriptionText/> }
</span> </span>
{issueTrackingEnabled() && <TableIssues tableKey={ this.key } tableName={ this.getDisplayName()}/>} </EditableSection>
{
issueTrackingEnabled() &&
<section className="metadata-section">
<TableIssues tableKey={ this.key } tableName={ this.getDisplayName()}/>
</section>
}
<section className="column-layout-2"> <section className="column-layout-2">
<section className="left-panel"> <section className="left-panel">
{ {
!data.is_view && !data.is_view &&
<> <section className="metadata-section">
<div className="section-title title-3">Date Range</div> <div className="section-title title-3">Date Range</div>
<WatermarkLabel watermarks={ data.watermarks }/> <WatermarkLabel watermarks={ data.watermarks }/>
</> </section>
} }
{ {
!!data.last_updated_timestamp && !!data.last_updated_timestamp &&
<> <section className="metadata-section">
<div className="section-title title-3">Last Updated</div> <div className="section-title title-3">Last Updated</div>
<div className="body-2">{ formatDateTimeShort({ epochTimestamp: data.last_updated_timestamp }) }</div> <div className="body-2">{ formatDateTimeShort({ epochTimestamp: data.last_updated_timestamp }) }</div>
</> </section>
} }
<section className="metadata-section">
<div className="section-title title-3">Frequent Users</div> <div className="section-title title-3">Frequent Users</div>
<FrequentUsers readers={ data.table_readers }/> <FrequentUsers readers={ data.table_readers }/>
</section> </section>
</section>
<section className="right-panel"> <section className="right-panel">
<EditableSection title="Tags"> <EditableSection title="Tags">
<TagInput <TagInput
......
@import 'variables'; @import 'variables';
.table-detail { .table-detail {
height: calc(100% - #{$nav-bar-height} - #{$footer-height});
.column-layout-1 .left-panel { .column-layout-1 .left-panel {
.programmatic-title { .programmatic-title {
color: $text-primary; color: $text-primary;
...@@ -15,4 +13,13 @@ ...@@ -15,4 +13,13 @@
margin: 10px 0 4px; margin: 10px 0 4px;
} }
} }
.header-links {
.avatar-label {
&:focus,
&:hover {
color: $link-hover-color;
}
}
}
} }
...@@ -88,5 +88,10 @@ describe("EditableSection", () => { ...@@ -88,5 +88,10 @@ describe("EditableSection", () => {
expect(wrapper.find(".edit-button").props().href).toBe(props.editUrl); expect(wrapper.find(".edit-button").props().href).toBe(props.editUrl);
}); });
}); });
it("does not render button if readOnly=true and there is no external editUrl", () => {
const wrapper = setup({ readOnly: true }, <div/>).wrapper;
expect(wrapper.find(".edit-button").exists()).toBeFalsy();
});
}); });
}); });
import * as React from 'react'; import * as React from 'react';
import { OverlayTrigger, Popover } from 'react-bootstrap'; import { OverlayTrigger, Popover } from 'react-bootstrap';
import * as Constants from './constants';
import './styles.scss'; import './styles.scss';
export interface EditableSectionProps { export interface EditableSectionProps {
...@@ -22,6 +24,10 @@ export interface EditableSectionChildProps { ...@@ -22,6 +24,10 @@ export interface EditableSectionChildProps {
} }
export class EditableSection extends React.Component<EditableSectionProps, EditableSectionState> { export class EditableSection extends React.Component<EditableSectionProps, EditableSectionState> {
static defaultProps: Partial<EditableSectionProps> = {
editText: Constants.EDIT_TEXT,
};
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -53,6 +59,10 @@ export class EditableSection extends React.Component<EditableSectionProps, Edita ...@@ -53,6 +59,10 @@ export class EditableSection extends React.Component<EditableSectionProps, Edita
renderReadOnlyButton = (): React.ReactNode => { renderReadOnlyButton = (): React.ReactNode => {
const { editText, editUrl } = this.props; const { editText, editUrl } = this.props;
const popoverHoverFocus = (<Popover id="popover-trigger-hover-focus">{ editText }</Popover>); const popoverHoverFocus = (<Popover id="popover-trigger-hover-focus">{ editText }</Popover>);
if (!editUrl) {
return null;
}
return ( return (
<OverlayTrigger <OverlayTrigger
trigger={["hover", "focus"]} trigger={["hover", "focus"]}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment