Skip to content

Commit

Permalink
Merge pull request #14130 from influxdata/static-templates
Browse files Browse the repository at this point in the history
Static templates
  • Loading branch information
bthesorceror authored Jun 13, 2019
2 parents 226fce0 + fd458cb commit 827db8a
Show file tree
Hide file tree
Showing 14 changed files with 2,192 additions and 744 deletions.
2,436 changes: 1,731 additions & 705 deletions ui/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"express": "^4.14.0",
"http-proxy-middleware": "^0.18.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^24.1.0",
"jest": "^24.8.0",
"jsdom": "^9.0.0",
"junit-viewer": "^4.11.1",
"mocha": "^5.2.0",
Expand All @@ -144,7 +144,7 @@
"@influxdata/influxdb-templates": "influxdata/influxdb-templates",
"@influxdata/react-custom-scrollbars": "4.3.8",
"@influxdata/giraffe": "0.12.0",
"axios": "^0.18.0",
"axios": "^0.19.0",
"babel-polyfill": "^6.26.0",
"bignumber.js": "^4.0.2",
"calculate-size": "^1.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@
min-height: $form-xs-height;
}

.resource-description--static,
.resource-description--preview,
.input.resource-description--input > input {
font-size: $form-xs-font;
font-weight: 500;
font-family: $ix-text-font;
}

.resource-description--static,
.resource-description--preview,
.resource-description--input {
position: relative;
width: 100%;
}

.resource-description--static,
.resource-description--preview {
width: auto;
display: inline-block;
Expand All @@ -29,9 +32,12 @@
overflow: hidden;
@include no-user-select();
color: $g13-mist;
line-height: $form-xs-font + $ix-border;
}

.resource-description--preview {
transition: color 0.25s ease, background-color 0.25s ease,
border-color 0.25s ease;
line-height: $form-xs-font + $ix-border;

.icon {
position: relative;
Expand Down
12 changes: 10 additions & 2 deletions ui/src/clockface/components/resource_list/ResourceDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {ComponentSize} from '@influxdata/clockface'
import {ErrorHandling} from 'src/shared/decorators/errors'

interface Props {
onUpdate: (name: string) => void
onUpdate?: (name: string) => void
description: string
placeholder?: string
}
Expand All @@ -35,9 +35,17 @@ class ResourceDescription extends Component<Props, State> {
}

public render() {
const {description} = this.props
const {description, onUpdate} = this.props
const {isEditing} = this.state

if (!onUpdate) {
return (
<div className="resource-description">
<div className="resource-description--static">{description}</div>
</div>
)
}

if (isEditing) {
return (
<div className="resource-description">
Expand Down
5 changes: 5 additions & 0 deletions ui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import UpdateVariableOverlay from 'src/variables/components/UpdateVariableOverla
import AllAccessTokenOverlay from 'src/authorizations/components/AllAccessTokenOverlay'
import BucketsTokenOverlay from 'src/authorizations/components/BucketsTokenOverlay'
import TaskImportFromTemplateOverlay from './tasks/components/TaskImportFromTemplateOverlay'
import StaticTemplateViewOverlay from 'src/templates/components/StaticTemplateViewOverlay'

// Actions
import {disablePresentationMode} from 'src/shared/actions/app'
Expand Down Expand Up @@ -263,6 +264,10 @@ class Root extends PureComponent {
path=":id/view"
component={TemplateViewOverlay}
/>
<Route
path=":id/static/view"
component={StaticTemplateViewOverlay}
/>
</Route>
<Route path="variables" component={VariablesIndex}>
<Route
Expand Down
6 changes: 3 additions & 3 deletions ui/src/shared/utils/downloads.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {formatDownloadName} from './download'

describe('formatDownloadName', () => [
describe('formatDownloadName', () => {
it('formats name correctly', () => {
const name1 = 'My Dashboard '
const name2 = 'my_dash'
Expand All @@ -19,5 +19,5 @@ describe('formatDownloadName', () => [
expect(actual1).toEqual(expected1)
expect(actual2).toEqual(expected2)
expect(actual3).toEqual(expected3)
}),
])
})
})
33 changes: 23 additions & 10 deletions ui/src/templates/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import _ from 'lodash'
// Utils
import {templateToExport} from 'src/shared/utils/resourceToTemplate'

import {staticTemplates} from 'src/templates/constants/defaultTemplates'

// Types
import {
TemplateSummary,
Expand Down Expand Up @@ -241,17 +243,14 @@ export const cloneTemplate = (templateID: string) => async (
}
}

export const createResourceFromTemplate = (templateID: string) => async (
dispatch
): Promise<void> => {
try {
const template = await client.templates.get(templateID)
const {
content: {
data: {type},
},
} = template
const createFromTemplate = template => async dispatch => {
const {
content: {
data: {type},
},
} = template

try {
switch (type) {
case TemplateType.Dashboard:
return dispatch(
Expand All @@ -272,6 +271,20 @@ export const createResourceFromTemplate = (templateID: string) => async (
}
}

export const createResourceFromStaticTemplate = (
name: string
) => async dispatch => {
const template = await staticTemplates[name]
dispatch(createFromTemplate(template))
}

export const createResourceFromTemplate = (templateID: string) => async (
dispatch
): Promise<void> => {
const template = await client.templates.get(templateID)
dispatch(createFromTemplate(template))
}

export const addTemplateLabelsAsync = (
templateID: string,
labels: Label[]
Expand Down
137 changes: 137 additions & 0 deletions ui/src/templates/components/StaticTemplateCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Libraries
import React, {PureComponent, MouseEvent} from 'react'
import _ from 'lodash'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'
import {
Button,
ComponentSize,
ComponentSpacer,
FlexDirection,
JustifyContent,
} from '@influxdata/clockface'

// Components
import {ResourceList} from 'src/clockface'

// Actions
import {createResourceFromStaticTemplate} from 'src/templates/actions'

// Selectors
import {viewableLabels} from 'src/labels/selectors'

// Types
import {TemplateSummary, ILabel} from '@influxdata/influx'
import {ComponentColor} from '@influxdata/clockface'
import {AppState, Organization} from 'src/types'

// Constants
interface OwnProps {
template: TemplateSummary
name: string
onFilterChange: (searchTerm: string) => void
}

interface DispatchProps {
onCreateFromTemplate: typeof createResourceFromStaticTemplate
}

interface StateProps {
labels: ILabel[]
org: Organization
}

type Props = DispatchProps & OwnProps & StateProps

class StaticTemplateCard extends PureComponent<Props & WithRouterProps> {
public render() {
const {template} = this.props

return (
<ResourceList.Card
testID="template-card"
contextMenu={() => this.contextMenu}
description={() => this.description}
name={() => (
<ResourceList.Name
onClick={this.handleNameClick}
name={template.meta.name}
parentTestID="template-card--name"
buttonTestID="template-card--name-button"
inputTestID="template-card--input"
/>
)}
metaData={() => [this.templateType]}
/>
)
}

private get contextMenu(): JSX.Element {
return (
<ComponentSpacer
margin={ComponentSize.Medium}
direction={FlexDirection.Row}
justifyContent={JustifyContent.FlexEnd}
>
<Button
text="Create"
color={ComponentColor.Primary}
size={ComponentSize.ExtraSmall}
onClick={this.handleCreate}
/>
</ComponentSpacer>
)
}

private get description(): JSX.Element {
const {template} = this.props
const description = _.get(template, 'content.data.attributes.description')

return (
<ResourceList.Description description={description || 'No description'} />
)
}

private get templateType(): JSX.Element {
const {template} = this.props

return (
<div className="resource-list--meta-item">
{_.get(template, 'content.data.type')}
</div>
)
}

private handleCreate = () => {
const {onCreateFromTemplate, name} = this.props

onCreateFromTemplate(name)
}

private handleNameClick = (e: MouseEvent<HTMLAnchorElement>) => {
e.preventDefault()
this.handleViewTemplate()
}

private handleViewTemplate = () => {
const {router, org, name} = this.props

router.push(`/orgs/${org.id}/templates/${name}/static/view`)
}
}

const mstp = ({labels, orgs: {org}}: AppState): StateProps => {
return {
org,
labels: viewableLabels(labels.list),
}
}

const mdtp: DispatchProps = {
onCreateFromTemplate: createResourceFromStaticTemplate,
}

export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(withRouter<Props>(StaticTemplateCard))
53 changes: 53 additions & 0 deletions ui/src/templates/components/StaticTemplateViewOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, {PureComponent} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
import _ from 'lodash'

// Components
import ViewOverlay from 'src/shared/components/ViewOverlay'
import {ErrorHandling} from 'src/shared/decorators/errors'

// Types
import {RemoteDataState} from '@influxdata/clockface'
import {DocumentCreate} from '@influxdata/influx'

import {staticTemplates} from 'src/templates/constants/defaultTemplates'

interface OwnProps {
params: {id: string}
}

type Props = OwnProps & WithRouterProps

@ErrorHandling
class TemplateExportOverlay extends PureComponent<Props> {
public render() {
return (
<ViewOverlay
resource={this.template}
overlayHeading={this.overlayTitle}
onDismissOverlay={this.onDismiss}
status={RemoteDataState.Done}
/>
)
}

private get template(): DocumentCreate {
const {
params: {id},
} = this.props

return staticTemplates[id]
}

private get overlayTitle() {
return this.template.meta.name
}

private onDismiss = () => {
const {router} = this.props

router.goBack()
}
}

export default withRouter<Props>(TemplateExportOverlay)
Loading

0 comments on commit 827db8a

Please sign in to comment.