Merge branch 'master' into presentational-page-components
commit
9798f0ef0c
|
@ -0,0 +1,138 @@
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
main:
|
||||||
|
jobs:
|
||||||
|
- build
|
||||||
|
- deploy-nightly:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only: master
|
||||||
|
- deploy-pre-release:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: /.*/
|
||||||
|
tags:
|
||||||
|
only: /^[0-9]+(\.[0-9]+)*(\S*)([a|rc|beta]([0-9]+))+$/
|
||||||
|
- deploy-release:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore: /.*/
|
||||||
|
tags:
|
||||||
|
only: /^[0-9]+(\.[0-9]+)*$/
|
||||||
|
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
environment:
|
||||||
|
DOCKER_TAG: chronograf-20180327
|
||||||
|
machine: true
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run: |
|
||||||
|
ls -lah
|
||||||
|
pwd
|
||||||
|
- run: ./etc/scripts/docker/pull.sh
|
||||||
|
- run:
|
||||||
|
name: "Run Tests"
|
||||||
|
command: >
|
||||||
|
./etc/scripts/docker/run.sh
|
||||||
|
--debug
|
||||||
|
--test
|
||||||
|
--no-build
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: /home/circleci
|
||||||
|
paths:
|
||||||
|
- project
|
||||||
|
|
||||||
|
deploy-nightly:
|
||||||
|
environment:
|
||||||
|
DOCKER_TAG: chronograf-20180327
|
||||||
|
machine: true
|
||||||
|
steps:
|
||||||
|
- attach_workspace:
|
||||||
|
at: /home/circleci
|
||||||
|
- run: |
|
||||||
|
./etc/scripts/docker/run.sh \
|
||||||
|
--debug \
|
||||||
|
--clean \
|
||||||
|
--package \
|
||||||
|
--platform all \
|
||||||
|
--arch all \
|
||||||
|
--upload \
|
||||||
|
--nightly \
|
||||||
|
--bucket=dl.influxdata.com/chronograf/releases
|
||||||
|
cp build/linux/static_amd64/chronograf .
|
||||||
|
cp build/linux/static_amd64/chronoctl .
|
||||||
|
docker build -t chronograf .
|
||||||
|
docker login -u "$QUAY_USER" -p $QUAY_PASS quay.io
|
||||||
|
docker tag chronograf quay.io/influxdb/chronograf:nightly
|
||||||
|
docker push quay.io/influxdb/chronograf:nightly
|
||||||
|
- store_artifacts:
|
||||||
|
path: ./build/
|
||||||
|
|
||||||
|
deploy-pre-release:
|
||||||
|
environment:
|
||||||
|
DOCKER_TAG: chronograf-20180327
|
||||||
|
machine: true
|
||||||
|
steps:
|
||||||
|
- attach_workspace:
|
||||||
|
at: /home/circleci
|
||||||
|
- run: |
|
||||||
|
./etc/scripts/docker/run.sh \
|
||||||
|
--clean \
|
||||||
|
--debug \
|
||||||
|
--release \
|
||||||
|
--package \
|
||||||
|
--platform all \
|
||||||
|
--arch all \
|
||||||
|
--upload-overwrite \
|
||||||
|
--upload \
|
||||||
|
--bucket dl.influxdata.com/chronograf/releases
|
||||||
|
cp build/linux/static_amd64/chronograf .
|
||||||
|
cp build/linux/static_amd64/chronoctl .
|
||||||
|
docker build -t chronograf .
|
||||||
|
docker login -u "$QUAY_USER" -p $QUAY_PASS quay.io
|
||||||
|
docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
||||||
|
docker push quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
||||||
|
docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
||||||
|
docker push quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
||||||
|
- store_artifacts:
|
||||||
|
path: ./build/
|
||||||
|
|
||||||
|
deploy-release:
|
||||||
|
environment:
|
||||||
|
DOCKER_TAG: chronograf-20180327
|
||||||
|
machine: true
|
||||||
|
steps:
|
||||||
|
- attach_workspace:
|
||||||
|
at: /home/circleci
|
||||||
|
- run: |
|
||||||
|
./etc/scripts/docker/run.sh \
|
||||||
|
--clean \
|
||||||
|
--debug \
|
||||||
|
--release \
|
||||||
|
--package \
|
||||||
|
--platform all \
|
||||||
|
--arch all \
|
||||||
|
--upload-overwrite \
|
||||||
|
--upload \
|
||||||
|
--bucket dl.influxdata.com/chronograf/releases
|
||||||
|
cp build/linux/static_amd64/chronograf .
|
||||||
|
cp build/linux/static_amd64/chronoctl .
|
||||||
|
docker build -t chronograf .
|
||||||
|
docker login -u "$QUAY_USER" -p $QUAY_PASS quay.io
|
||||||
|
docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
||||||
|
docker push quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
||||||
|
docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
||||||
|
docker push quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
||||||
|
docker tag chronograf quay.io/influxdb/chronograf:latest
|
||||||
|
docker push quay.io/influxdb/chronograf:latest
|
||||||
|
- store_artifacts:
|
||||||
|
path: ./build/
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
1. [#3474](https://github.com/influxdata/chronograf/pull/3474): Sort task table on Manage Alert page alphabetically
|
1. [#3474](https://github.com/influxdata/chronograf/pull/3474): Sort task table on Manage Alert page alphabetically
|
||||||
1. [#3590](https://github.com/influxdata/chronograf/pull/3590): Redesign icons in side navigation
|
1. [#3590](https://github.com/influxdata/chronograf/pull/3590): Redesign icons in side navigation
|
||||||
|
1. [#3696](https://github.com/influxdata/chronograf/pull/3696): Add ability to delete entire queries in Flux Editor
|
||||||
1. [#3671](https://github.com/influxdata/chronograf/pull/3671): Remove Snip functionality in hover legend
|
1. [#3671](https://github.com/influxdata/chronograf/pull/3671): Remove Snip functionality in hover legend
|
||||||
1. [#3659](https://github.com/influxdata/chronograf/pull/3659): Upgrade Data Explorer query text field with syntax highlighting and partial multi-line support
|
1. [#3659](https://github.com/influxdata/chronograf/pull/3659): Upgrade Data Explorer query text field with syntax highlighting and partial multi-line support
|
||||||
1. [#3663](https://github.com/influxdata/chronograf/pull/3663): Truncate message preview in Alert Rules table
|
1. [#3663](https://github.com/influxdata/chronograf/pull/3663): Truncate message preview in Alert Rules table
|
||||||
|
|
91
circle.yml
91
circle.yml
|
@ -1,91 +0,0 @@
|
||||||
---
|
|
||||||
machine:
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
environment:
|
|
||||||
DOCKER_TAG: chronograf-20180327
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
override:
|
|
||||||
- ./etc/scripts/docker/pull.sh
|
|
||||||
|
|
||||||
test:
|
|
||||||
override:
|
|
||||||
- >
|
|
||||||
./etc/scripts/docker/run.sh
|
|
||||||
--debug
|
|
||||||
--test
|
|
||||||
--no-build
|
|
||||||
|
|
||||||
deployment:
|
|
||||||
master:
|
|
||||||
branch: master
|
|
||||||
commands:
|
|
||||||
- >
|
|
||||||
./etc/scripts/docker/run.sh
|
|
||||||
--debug
|
|
||||||
--clean
|
|
||||||
--package
|
|
||||||
--platform all
|
|
||||||
--arch all
|
|
||||||
--upload
|
|
||||||
--nightly
|
|
||||||
--bucket=dl.influxdata.com/chronograf/releases
|
|
||||||
- sudo chown -R ubuntu:ubuntu /home/ubuntu
|
|
||||||
- cp build/linux/static_amd64/chronograf .
|
|
||||||
- cp build/linux/static_amd64/chronoctl .
|
|
||||||
- docker build -t chronograf .
|
|
||||||
- docker login -e $QUAY_EMAIL -u "$QUAY_USER" -p $QUAY_PASS quay.io
|
|
||||||
- docker tag chronograf quay.io/influxdb/chronograf:nightly
|
|
||||||
- docker push quay.io/influxdb/chronograf:nightly
|
|
||||||
- mv ./build/* $CIRCLE_ARTIFACTS
|
|
||||||
pre-release:
|
|
||||||
tag: /^[0-9]+(\.[0-9]+)*(\S*)([a|rc|beta]([0-9]+))+$/
|
|
||||||
commands:
|
|
||||||
- >
|
|
||||||
./etc/scripts/docker/run.sh
|
|
||||||
--clean
|
|
||||||
--debug
|
|
||||||
--release
|
|
||||||
--package
|
|
||||||
--platform all
|
|
||||||
--arch all
|
|
||||||
--upload-overwrite
|
|
||||||
--upload
|
|
||||||
--bucket dl.influxdata.com/chronograf/releases
|
|
||||||
- sudo chown -R ubuntu:ubuntu /home/ubuntu
|
|
||||||
- cp build/linux/static_amd64/chronograf .
|
|
||||||
- cp build/linux/static_amd64/chronoctl .
|
|
||||||
- docker build -t chronograf .
|
|
||||||
- docker login -e $QUAY_EMAIL -u "$QUAY_USER" -p $QUAY_PASS quay.io
|
|
||||||
- docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
|
||||||
- docker push quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
|
||||||
- docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
|
||||||
- docker push quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
|
||||||
- mv ./build/* $CIRCLE_ARTIFACTS
|
|
||||||
release:
|
|
||||||
tag: /^[0-9]+(\.[0-9]+)*$/
|
|
||||||
commands:
|
|
||||||
- >
|
|
||||||
./etc/scripts/docker/run.sh
|
|
||||||
--clean
|
|
||||||
--debug
|
|
||||||
--release
|
|
||||||
--package
|
|
||||||
--platform all
|
|
||||||
--arch all
|
|
||||||
--upload-overwrite
|
|
||||||
--upload
|
|
||||||
--bucket dl.influxdata.com/chronograf/releases
|
|
||||||
- sudo chown -R ubuntu:ubuntu /home/ubuntu
|
|
||||||
- cp build/linux/static_amd64/chronograf .
|
|
||||||
- cp build/linux/static_amd64/chronoctl .
|
|
||||||
- docker build -t chronograf .
|
|
||||||
- docker login -e $QUAY_EMAIL -u "$QUAY_USER" -p $QUAY_PASS quay.io
|
|
||||||
- docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
|
||||||
- docker push quay.io/influxdb/chronograf:${CIRCLE_SHA1:0:7}
|
|
||||||
- docker tag chronograf quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
|
||||||
- docker push quay.io/influxdb/chronograf:${CIRCLE_TAG}
|
|
||||||
- docker tag chronograf quay.io/influxdb/chronograf:latest
|
|
||||||
- docker push quay.io/influxdb/chronograf:latest
|
|
||||||
- mv ./build/* $CIRCLE_ARTIFACTS
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
applyMasks,
|
applyMasks,
|
||||||
insertTempVar,
|
insertTempVar,
|
||||||
unMask,
|
unMask,
|
||||||
} from 'src/dashboards/constants'
|
} from 'src/tempVars/constants'
|
||||||
|
|
||||||
@ErrorHandling
|
@ErrorHandling
|
||||||
class QueryTextArea extends Component {
|
class QueryTextArea extends Component {
|
||||||
|
|
|
@ -32,7 +32,7 @@ export const generateURLQueryParamsFromTempVars = (
|
||||||
const selected = values.find(value => value.selected === true)
|
const selected = values.find(value => value.selected === true)
|
||||||
const strippedTempVar = stripTempVar(tempVar)
|
const strippedTempVar = stripTempVar(tempVar)
|
||||||
|
|
||||||
urlQueryParams[strippedTempVar] = selected.value
|
urlQueryParams[strippedTempVar] = _.get(selected, 'value', '')
|
||||||
})
|
})
|
||||||
|
|
||||||
return urlQueryParams
|
return urlQueryParams
|
||||||
|
|
|
@ -3,12 +3,13 @@ import _ from 'lodash'
|
||||||
|
|
||||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||||
import ExpressionNode from 'src/flux/components/ExpressionNode'
|
import ExpressionNode from 'src/flux/components/ExpressionNode'
|
||||||
import VariableName from 'src/flux/components/VariableName'
|
import VariableNode from 'src/flux/components/VariableNode'
|
||||||
import FuncSelector from 'src/flux/components/FuncSelector'
|
import FuncSelector from 'src/flux/components/FuncSelector'
|
||||||
|
import BodyDelete from 'src/flux/components/BodyDelete'
|
||||||
import {funcNames} from 'src/flux/constants'
|
import {funcNames} from 'src/flux/constants'
|
||||||
|
|
||||||
import {Service} from 'src/types'
|
import {Service} from 'src/types'
|
||||||
import {FlatBody, Suggestion} from 'src/types/flux'
|
import {Body, Suggestion} from 'src/types/flux'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
service: Service
|
service: Service
|
||||||
|
@ -16,21 +17,25 @@ interface Props {
|
||||||
suggestions: Suggestion[]
|
suggestions: Suggestion[]
|
||||||
onAppendFrom: () => void
|
onAppendFrom: () => void
|
||||||
onAppendJoin: () => void
|
onAppendJoin: () => void
|
||||||
}
|
onDeleteBody: (bodyID: string) => void
|
||||||
|
|
||||||
interface Body extends FlatBody {
|
|
||||||
id: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BodyBuilder extends PureComponent<Props> {
|
class BodyBuilder extends PureComponent<Props> {
|
||||||
public render() {
|
public render() {
|
||||||
const bodybuilder = this.props.body.map((b, i) => {
|
const {body, onDeleteBody} = this.props
|
||||||
|
|
||||||
|
const bodybuilder = body.map((b, i) => {
|
||||||
if (b.declarations.length) {
|
if (b.declarations.length) {
|
||||||
return b.declarations.map(d => {
|
return b.declarations.map(d => {
|
||||||
if (d.funcs) {
|
if (d.funcs) {
|
||||||
return (
|
return (
|
||||||
<div className="declaration" key={i}>
|
<div className="declaration" key={i}>
|
||||||
<VariableName name={d.name} assignedToQuery={true} />
|
<div className="func-node--wrapper">
|
||||||
|
<VariableNode name={d.name} assignedToQuery={true} />
|
||||||
|
<div className="func-node--menu">
|
||||||
|
<BodyDelete bodyID={b.id} onDeleteBody={onDeleteBody} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<ExpressionNode
|
<ExpressionNode
|
||||||
bodyID={b.id}
|
bodyID={b.id}
|
||||||
declarationID={d.id}
|
declarationID={d.id}
|
||||||
|
@ -38,6 +43,7 @@ class BodyBuilder extends PureComponent<Props> {
|
||||||
funcs={d.funcs}
|
funcs={d.funcs}
|
||||||
declarationsFromBody={this.declarationsFromBody}
|
declarationsFromBody={this.declarationsFromBody}
|
||||||
isLastBody={this.isLastBody(i)}
|
isLastBody={this.isLastBody(i)}
|
||||||
|
onDeleteBody={onDeleteBody}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -45,7 +51,16 @@ class BodyBuilder extends PureComponent<Props> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="declaration" key={i}>
|
<div className="declaration" key={i}>
|
||||||
<VariableName name={b.source} assignedToQuery={false} />
|
<div className="func-node--wrapper">
|
||||||
|
<VariableNode name={b.source} assignedToQuery={false} />
|
||||||
|
<div className="func-node--menu">
|
||||||
|
<BodyDelete
|
||||||
|
bodyID={b.id}
|
||||||
|
type="variable"
|
||||||
|
onDeleteBody={onDeleteBody}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -59,6 +74,7 @@ class BodyBuilder extends PureComponent<Props> {
|
||||||
funcNames={this.funcNames}
|
funcNames={this.funcNames}
|
||||||
declarationsFromBody={this.declarationsFromBody}
|
declarationsFromBody={this.declarationsFromBody}
|
||||||
isLastBody={this.isLastBody(i)}
|
isLastBody={this.isLastBody(i)}
|
||||||
|
onDeleteBody={onDeleteBody}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React, {PureComponent} from 'react'
|
||||||
|
import ConfirmButton from 'src/shared/components/ConfirmButton'
|
||||||
|
|
||||||
|
type BodyType = 'variable' | 'query'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
bodyID: string
|
||||||
|
type?: BodyType
|
||||||
|
onDeleteBody: (bodyID: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyDelete extends PureComponent<Props> {
|
||||||
|
public static defaultProps: Partial<Props> = {
|
||||||
|
type: 'query',
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const {type} = this.props
|
||||||
|
|
||||||
|
if (type === 'variable') {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-square btn-danger"
|
||||||
|
title="Delete Variable"
|
||||||
|
onClick={this.handleDelete}
|
||||||
|
>
|
||||||
|
<span className="icon remove" />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConfirmButton
|
||||||
|
icon="trash"
|
||||||
|
type="btn-danger"
|
||||||
|
confirmText="Delete Query"
|
||||||
|
square={true}
|
||||||
|
confirmAction={this.handleDelete}
|
||||||
|
position="right"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleDelete = (): void => {
|
||||||
|
this.props.onDeleteBody(this.props.bodyID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BodyDelete
|
|
@ -15,6 +15,7 @@ interface Props {
|
||||||
declarationID?: string
|
declarationID?: string
|
||||||
declarationsFromBody: string[]
|
declarationsFromBody: string[]
|
||||||
isLastBody: boolean
|
isLastBody: boolean
|
||||||
|
onDeleteBody: (bodyID: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -42,6 +43,7 @@ class ExpressionNode extends PureComponent<Props, State> {
|
||||||
funcNames,
|
funcNames,
|
||||||
funcs,
|
funcs,
|
||||||
declarationsFromBody,
|
declarationsFromBody,
|
||||||
|
onDeleteBody,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const {nonYieldableIndexesToggled} = this.state
|
const {nonYieldableIndexesToggled} = this.state
|
||||||
|
@ -106,6 +108,7 @@ class ExpressionNode extends PureComponent<Props, State> {
|
||||||
onGenerateScript={onGenerateScript}
|
onGenerateScript={onGenerateScript}
|
||||||
declarationsFromBody={declarationsFromBody}
|
declarationsFromBody={declarationsFromBody}
|
||||||
onToggleYieldWithLast={this.handleToggleYieldWithLast}
|
onToggleYieldWithLast={this.handleToggleYieldWithLast}
|
||||||
|
onDeleteBody={onDeleteBody}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -152,6 +155,7 @@ class ExpressionNode extends PureComponent<Props, State> {
|
||||||
onGenerateScript={onGenerateScript}
|
onGenerateScript={onGenerateScript}
|
||||||
declarationsFromBody={declarationsFromBody}
|
declarationsFromBody={declarationsFromBody}
|
||||||
onToggleYieldWithLast={this.handleToggleYieldWithLast}
|
onToggleYieldWithLast={this.handleToggleYieldWithLast}
|
||||||
|
onDeleteBody={onDeleteBody}
|
||||||
/>
|
/>
|
||||||
<YieldFuncNode
|
<YieldFuncNode
|
||||||
index={i}
|
index={i}
|
||||||
|
|
|
@ -5,9 +5,11 @@ import {tagKeys as fetchTagKeys} from 'src/shared/apis/flux/metaQueries'
|
||||||
import parseValuesColumn from 'src/shared/parsing/flux/values'
|
import parseValuesColumn from 'src/shared/parsing/flux/values'
|
||||||
import FilterTagList from 'src/flux/components/FilterTagList'
|
import FilterTagList from 'src/flux/components/FilterTagList'
|
||||||
import Walker from 'src/flux/ast/walker'
|
import Walker from 'src/flux/ast/walker'
|
||||||
|
import {makeCancelable} from 'src/utils/promises'
|
||||||
|
|
||||||
import {Service} from 'src/types'
|
import {Service} from 'src/types'
|
||||||
import {Links, OnChangeArg, Func, FilterNode} from 'src/types/flux'
|
import {Links, OnChangeArg, Func, FilterNode} from 'src/types/flux'
|
||||||
|
import {WrappedCancelablePromise} from 'src/types/promises'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
links: Links
|
links: Links
|
||||||
|
@ -28,6 +30,8 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
class FilterArgs extends PureComponent<Props, State> {
|
class FilterArgs extends PureComponent<Props, State> {
|
||||||
|
private fetchTagKeysResponse?: WrappedCancelablePromise<string>
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -52,15 +56,24 @@ class FilterArgs extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
const {db, service} = this.props
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.convertStringToNodes()
|
this.convertStringToNodes()
|
||||||
const response = await fetchTagKeys(service, db, [])
|
const response = await this.getTagKeys()
|
||||||
const tagKeys = parseValuesColumn(response)
|
const tagKeys = parseValuesColumn(response)
|
||||||
this.setState({tagKeys})
|
|
||||||
|
this.setState({
|
||||||
|
tagKeys,
|
||||||
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
if (!error.isCanceled) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentWillUnmount() {
|
||||||
|
if (this.fetchTagKeysResponse) {
|
||||||
|
this.fetchTagKeysResponse.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +104,14 @@ class FilterArgs extends PureComponent<Props, State> {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTagKeys(): Promise<string> {
|
||||||
|
const {db, service} = this.props
|
||||||
|
|
||||||
|
this.fetchTagKeysResponse = makeCancelable(fetchTagKeys(service, db, []))
|
||||||
|
|
||||||
|
return this.fetchTagKeysResponse.promise
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({links}) => {
|
const mapStateToProps = ({links}) => {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, {PureComponent, MouseEvent} from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
import BodyDelete from 'src/flux/components/BodyDelete'
|
||||||
import FuncArgs from 'src/flux/components/FuncArgs'
|
import FuncArgs from 'src/flux/components/FuncArgs'
|
||||||
import FuncArgsPreview from 'src/flux/components/FuncArgsPreview'
|
import FuncArgsPreview from 'src/flux/components/FuncArgsPreview'
|
||||||
import {
|
import {
|
||||||
|
@ -28,6 +29,7 @@ interface Props {
|
||||||
declarationsFromBody: string[]
|
declarationsFromBody: string[]
|
||||||
isYielding: boolean
|
isYielding: boolean
|
||||||
isYieldable: boolean
|
isYieldable: boolean
|
||||||
|
onDeleteBody: (bodyID: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -53,14 +55,16 @@ export default class FuncNode extends PureComponent<Props, State> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div className="func-node--wrapper">
|
||||||
className={this.nodeClassName}
|
<div
|
||||||
onClick={this.handleToggleEdit}
|
className={this.nodeClassName}
|
||||||
title="Edit function arguments"
|
onClick={this.handleToggleEdit}
|
||||||
>
|
title="Edit function arguments"
|
||||||
<div className="func-node--connector" />
|
>
|
||||||
<div className="func-node--name">{func.name}</div>
|
<div className="func-node--connector" />
|
||||||
<FuncArgsPreview func={func} />
|
<div className="func-node--name">{func.name}</div>
|
||||||
|
<FuncArgsPreview func={func} />
|
||||||
|
</div>
|
||||||
{this.funcMenu}
|
{this.funcMenu}
|
||||||
</div>
|
</div>
|
||||||
{this.funcArgs}
|
{this.funcArgs}
|
||||||
|
@ -103,13 +107,7 @@ export default class FuncNode extends PureComponent<Props, State> {
|
||||||
return (
|
return (
|
||||||
<div className="func-node--menu">
|
<div className="func-node--menu">
|
||||||
{this.yieldToggleButton}
|
{this.yieldToggleButton}
|
||||||
<button
|
{this.deleteButton}
|
||||||
className="btn btn-sm btn-square btn-danger"
|
|
||||||
onClick={this.handleDelete}
|
|
||||||
title="Delete this Function"
|
|
||||||
>
|
|
||||||
<span className="icon trash" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -140,6 +138,24 @@ export default class FuncNode extends PureComponent<Props, State> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get deleteButton(): JSX.Element {
|
||||||
|
const {func, bodyID, onDeleteBody} = this.props
|
||||||
|
|
||||||
|
if (func.name === 'from') {
|
||||||
|
return <BodyDelete onDeleteBody={onDeleteBody} bodyID={bodyID} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-square btn-danger"
|
||||||
|
onClick={this.handleDelete}
|
||||||
|
title="Delete this Function"
|
||||||
|
>
|
||||||
|
<span className="icon remove" />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private get nodeClassName(): string {
|
private get nodeClassName(): string {
|
||||||
const {isYielding} = this.props
|
const {isYielding} = this.props
|
||||||
const {editing} = this.state
|
const {editing} = this.state
|
||||||
|
@ -147,14 +163,14 @@ export default class FuncNode extends PureComponent<Props, State> {
|
||||||
return classnames('func-node', {active: isYielding || editing})
|
return classnames('func-node', {active: isYielding || editing})
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleDelete = (e: MouseEvent<HTMLElement>): void => {
|
private handleDelete = (): void => {
|
||||||
e.stopPropagation()
|
|
||||||
const {func, bodyID, declarationID} = this.props
|
const {func, bodyID, declarationID} = this.props
|
||||||
|
|
||||||
this.props.onDelete({funcID: func.id, bodyID, declarationID})
|
this.props.onDelete({funcID: func.id, bodyID, declarationID})
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleToggleEdit = (): void => {
|
private handleToggleEdit = (e: MouseEvent<HTMLElement>): void => {
|
||||||
|
e.stopPropagation()
|
||||||
this.setState({editing: !this.state.editing})
|
this.setState({editing: !this.state.editing})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
Suggestion,
|
Suggestion,
|
||||||
OnChangeScript,
|
OnChangeScript,
|
||||||
OnSubmitScript,
|
OnSubmitScript,
|
||||||
|
OnDeleteBody,
|
||||||
FlatBody,
|
FlatBody,
|
||||||
ScriptStatus,
|
ScriptStatus,
|
||||||
} from 'src/types/flux'
|
} from 'src/types/flux'
|
||||||
|
@ -22,6 +23,7 @@ interface Props {
|
||||||
status: ScriptStatus
|
status: ScriptStatus
|
||||||
suggestions: Suggestion[]
|
suggestions: Suggestion[]
|
||||||
onChangeScript: OnChangeScript
|
onChangeScript: OnChangeScript
|
||||||
|
onDeleteBody: OnDeleteBody
|
||||||
onSubmitScript: OnSubmitScript
|
onSubmitScript: OnSubmitScript
|
||||||
onAppendFrom: () => void
|
onAppendFrom: () => void
|
||||||
onAppendJoin: () => void
|
onAppendJoin: () => void
|
||||||
|
@ -63,7 +65,14 @@ class TimeMachine extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private get builder() {
|
private get builder() {
|
||||||
const {body, service, suggestions, onAppendFrom, onAppendJoin} = this.props
|
const {
|
||||||
|
body,
|
||||||
|
service,
|
||||||
|
suggestions,
|
||||||
|
onAppendFrom,
|
||||||
|
onDeleteBody,
|
||||||
|
onAppendJoin,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'Build',
|
name: 'Build',
|
||||||
|
@ -75,6 +84,7 @@ class TimeMachine extends PureComponent<Props> {
|
||||||
body={body}
|
body={body}
|
||||||
service={service}
|
service={service}
|
||||||
suggestions={suggestions}
|
suggestions={suggestions}
|
||||||
|
onDeleteBody={onDeleteBody}
|
||||||
onAppendFrom={onAppendFrom}
|
onAppendFrom={onAppendFrom}
|
||||||
onAppendJoin={onAppendJoin}
|
onAppendJoin={onAppendJoin}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
export const emptyAST = {
|
||||||
|
type: 'Program',
|
||||||
|
location: {
|
||||||
|
start: {
|
||||||
|
line: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
line: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
source: '',
|
||||||
|
},
|
||||||
|
body: [],
|
||||||
|
}
|
||||||
|
|
||||||
export const ast = {
|
export const ast = {
|
||||||
type: 'File',
|
type: 'File',
|
||||||
start: 0,
|
start: 0,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {ast} from 'src/flux/constants/ast'
|
import {ast, emptyAST} from 'src/flux/constants/ast'
|
||||||
import * as editor from 'src/flux/constants/editor'
|
import * as editor from 'src/flux/constants/editor'
|
||||||
import * as argTypes from 'src/flux/constants/argumentTypes'
|
import * as argTypes from 'src/flux/constants/argumentTypes'
|
||||||
import * as funcNames from 'src/flux/constants/funcNames'
|
import * as funcNames from 'src/flux/constants/funcNames'
|
||||||
|
@ -10,6 +10,7 @@ const MAX_RESPONSE_BYTES = 1e7 // 10 MB
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ast,
|
ast,
|
||||||
|
emptyAST,
|
||||||
funcNames,
|
funcNames,
|
||||||
argTypes,
|
argTypes,
|
||||||
editor,
|
editor,
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {UpdateScript} from 'src/flux/actions'
|
||||||
|
|
||||||
import {bodyNodes} from 'src/flux/helpers'
|
import {bodyNodes} from 'src/flux/helpers'
|
||||||
import {getSuggestions, getAST, getTimeSeries} from 'src/flux/apis'
|
import {getSuggestions, getAST, getTimeSeries} from 'src/flux/apis'
|
||||||
import {builder, argTypes} from 'src/flux/constants'
|
import {builder, argTypes, emptyAST} from 'src/flux/constants'
|
||||||
|
|
||||||
import {Source, Service, Notification, FluxTable} from 'src/types'
|
import {Source, Service, Notification, FluxTable} from 'src/types'
|
||||||
import {
|
import {
|
||||||
|
@ -114,6 +114,7 @@ export class FluxPage extends PureComponent<Props, State> {
|
||||||
onAppendJoin={this.handleAppendJoin}
|
onAppendJoin={this.handleAppendJoin}
|
||||||
onChangeScript={this.handleChangeScript}
|
onChangeScript={this.handleChangeScript}
|
||||||
onSubmitScript={this.handleSubmitScript}
|
onSubmitScript={this.handleSubmitScript}
|
||||||
|
onDeleteBody={this.handleDeleteBody}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</KeyboardShortcuts>
|
</KeyboardShortcuts>
|
||||||
|
@ -331,6 +332,13 @@ export class FluxPage extends PureComponent<Props, State> {
|
||||||
this.getASTResponse(script)
|
this.getASTResponse(script)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleDeleteBody = (bodyID: string): void => {
|
||||||
|
const newBody = this.state.body.filter(b => b.id !== bodyID)
|
||||||
|
const script = this.getBodyToScript(newBody)
|
||||||
|
|
||||||
|
this.getASTResponse(script)
|
||||||
|
}
|
||||||
|
|
||||||
private handleScriptUpToYield = (
|
private handleScriptUpToYield = (
|
||||||
bodyID: string,
|
bodyID: string,
|
||||||
declarationID: string,
|
declarationID: string,
|
||||||
|
@ -601,7 +609,8 @@ export class FluxPage extends PureComponent<Props, State> {
|
||||||
const {links} = this.props
|
const {links} = this.props
|
||||||
|
|
||||||
if (!script) {
|
if (!script) {
|
||||||
return
|
this.props.updateScript(script)
|
||||||
|
return this.setState({ast: emptyAST, body: []})
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -45,6 +45,10 @@ class AnnotationInput extends Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
public handleClickOutside = () => {
|
||||||
|
this.props.onConfirmUpdate()
|
||||||
|
this.setState({isEditing: false})
|
||||||
|
}
|
||||||
|
|
||||||
private handleInputClick = () => {
|
private handleInputClick = () => {
|
||||||
this.setState({isEditing: true})
|
this.setState({isEditing: true})
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React, {PureComponent} from 'react'
|
import React, {PureComponent} from 'react'
|
||||||
|
import classnames from 'classnames'
|
||||||
import {ClickOutside} from 'src/shared/components/ClickOutside'
|
import {ClickOutside} from 'src/shared/components/ClickOutside'
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
|
||||||
|
type Position = 'top' | 'bottom' | 'left' | 'right'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
text?: string
|
text?: string
|
||||||
confirmText?: string
|
confirmText?: string
|
||||||
|
@ -12,6 +15,7 @@ interface Props {
|
||||||
icon?: string
|
icon?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
customClass?: string
|
customClass?: string
|
||||||
|
position?: Position
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -47,10 +51,11 @@ class ConfirmButton extends PureComponent<Props, State> {
|
||||||
className={this.className}
|
className={this.className}
|
||||||
onClick={this.handleButtonClick}
|
onClick={this.handleButtonClick}
|
||||||
ref={r => (this.buttonDiv = r)}
|
ref={r => (this.buttonDiv = r)}
|
||||||
|
title={confirmText}
|
||||||
>
|
>
|
||||||
{icon && <span className={`icon ${icon}`} />}
|
{icon && <span className={`icon ${icon}`} />}
|
||||||
{text && text}
|
{text && text}
|
||||||
<div className={`confirm-button--tooltip ${this.calculatedPosition}`}>
|
<div className={this.tooltipClassName}>
|
||||||
<div
|
<div
|
||||||
className="confirm-button--confirmation"
|
className="confirm-button--confirmation"
|
||||||
onClick={this.handleConfirmClick}
|
onClick={this.handleConfirmClick}
|
||||||
|
@ -64,18 +69,6 @@ class ConfirmButton extends PureComponent<Props, State> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private get className() {
|
|
||||||
const {type, size, square, disabled, customClass} = this.props
|
|
||||||
const {expanded} = this.state
|
|
||||||
|
|
||||||
const customClassString = customClass ? ` ${customClass}` : ''
|
|
||||||
const squareString = square ? ' btn-square' : ''
|
|
||||||
const expandedString = expanded ? ' active' : ''
|
|
||||||
const disabledString = disabled ? ' disabled' : ''
|
|
||||||
|
|
||||||
return `confirm-button btn ${type} ${size}${customClassString}${squareString}${expandedString}${disabledString}`
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleButtonClick = () => {
|
private handleButtonClick = () => {
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
return
|
return
|
||||||
|
@ -92,9 +85,27 @@ class ConfirmButton extends PureComponent<Props, State> {
|
||||||
this.setState({expanded: false})
|
this.setState({expanded: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
private get calculatedPosition() {
|
private get className(): string {
|
||||||
|
const {type, size, square, disabled, customClass} = this.props
|
||||||
|
const {expanded} = this.state
|
||||||
|
|
||||||
|
return classnames(`confirm-button btn ${type} ${size}`, {
|
||||||
|
[customClass]: customClass,
|
||||||
|
'btn-square': square,
|
||||||
|
active: expanded,
|
||||||
|
disabled,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private get tooltipClassName(): string {
|
||||||
|
const {position} = this.props
|
||||||
|
|
||||||
|
if (position) {
|
||||||
|
return `confirm-button--tooltip ${position}`
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.buttonDiv || !this.tooltipDiv) {
|
if (!this.buttonDiv || !this.tooltipDiv) {
|
||||||
return ''
|
return 'confirm-button--tooltip bottom'
|
||||||
}
|
}
|
||||||
|
|
||||||
const windowWidth = window.innerWidth
|
const windowWidth = window.innerWidth
|
||||||
|
@ -104,10 +115,10 @@ class ConfirmButton extends PureComponent<Props, State> {
|
||||||
const rightGap = windowWidth - buttonRect.right
|
const rightGap = windowWidth - buttonRect.right
|
||||||
|
|
||||||
if (tooltipRect.width / 2 > rightGap) {
|
if (tooltipRect.width / 2 > rightGap) {
|
||||||
return 'left'
|
return 'confirm-button--tooltip left'
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'bottom'
|
return 'confirm-button--tooltip bottom'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,13 @@ class NewAnnotation extends Component<Props, State> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public handleClickOutside = () => {
|
||||||
|
const {onDismissAddingAnnotation, isTempHovering} = this.props
|
||||||
|
if (!isTempHovering) {
|
||||||
|
onDismissAddingAnnotation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private clampWithinGraphTimerange = (timestamp: number): number => {
|
private clampWithinGraphTimerange = (timestamp: number): number => {
|
||||||
const [xRangeStart] = this.props.dygraph.xAxisRange()
|
const [xRangeStart] = this.props.dygraph.xAxisRange()
|
||||||
return Math.max(xRangeStart, timestamp)
|
return Math.max(xRangeStart, timestamp)
|
||||||
|
|
|
@ -11,18 +11,26 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
|
&.top {
|
||||||
|
bottom: calc(100% + 4px);
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
&.bottom {
|
&.bottom {
|
||||||
top: calc(100% + 4px);
|
top: calc(100% + 4px);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.left {
|
&.left {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: calc(100% + 4px);
|
right: calc(100% + 4px);
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
&.right {
|
||||||
|
top: 50%;
|
||||||
|
left: calc(100% + 4px);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.confirm-button--confirmation {
|
.confirm-button--confirmation {
|
||||||
|
@ -43,11 +51,7 @@
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: '';
|
||||||
border: 8px solid transparent;
|
border: 8px solid transparent;
|
||||||
border-bottom-color: $c-curacao;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 100%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
transition: border-color 0.25s ease;
|
transition: border-color 0.25s ease;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
@ -56,28 +60,35 @@
|
||||||
background-color: $c-dreamsicle;
|
background-color: $c-dreamsicle;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
&:hover:after {
|
|
||||||
border-bottom-color: $c-dreamsicle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirm-button--tooltip.bottom .confirm-button--confirmation:after {
|
.top &:after {
|
||||||
bottom: 100%;
|
top: 100%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
border-bottom-color: $c-curacao;
|
transform: translateX(-50%);
|
||||||
transform: translateX(-50%);
|
border-top-color: $c-curacao;
|
||||||
}
|
}
|
||||||
.confirm-button--tooltip.bottom .confirm-button--confirmation:hover:after {
|
.top &:hover:after {border-top-color: $c-dreamsicle;}
|
||||||
border-bottom-color: $c-dreamsicle;
|
.bottom &:after {
|
||||||
}
|
bottom: 100%;
|
||||||
.confirm-button--tooltip.left .confirm-button--confirmation:after {
|
left: 50%;
|
||||||
left: 100%;
|
transform: translateX(-50%);
|
||||||
top: 50%;
|
border-bottom-color: $c-curacao;
|
||||||
border-left-color: $c-curacao;
|
}
|
||||||
transform: translateY(-50%);
|
.bottom &:hover:after {border-bottom-color: $c-dreamsicle;}
|
||||||
}
|
.left &:after {
|
||||||
.confirm-button--tooltip.left .confirm-button--confirmation:hover:after {
|
top: 50%;
|
||||||
border-left-color: $c-dreamsicle;
|
left: 100%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-left-color: $c-curacao;
|
||||||
|
}
|
||||||
|
.left &:hover:after {border-left-color: $c-dreamsicle;}
|
||||||
|
.right &:after {
|
||||||
|
top: 50%;
|
||||||
|
right: 100%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-right-color: $c-curacao;
|
||||||
|
}
|
||||||
|
.right &:hover:after {border-right-color: $c-dreamsicle;}
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm-button.active {
|
.confirm-button.active {
|
||||||
|
|
|
@ -144,6 +144,8 @@ $flux-invalid-hover: $c-dreamsicle;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.active {
|
&.active {
|
||||||
|
cursor: pointer !important;
|
||||||
|
|
||||||
.func-node--preview {
|
.func-node--preview {
|
||||||
color: $g20-white;
|
color: $g20-white;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +198,7 @@ $flux-invalid-hover: $c-dreamsicle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a query exists unassigned to a variable
|
// When a query exists unassigned to a variable
|
||||||
.func-node:first-child {
|
.func-node--wrapper:first-child .func-node {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
padding-left: $flux-node-gap;
|
padding-left: $flux-node-gap;
|
||||||
.func-node--connector {
|
.func-node--connector {
|
||||||
|
@ -248,24 +250,26 @@ $flux-invalid-hover: $c-dreamsicle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.func-node--wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.func-node--menu {
|
.func-node--menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: 0;
|
|
||||||
transform: translate(100%, -50%);
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.25s ease;
|
transition: opacity 0.25s ease;
|
||||||
|
|
||||||
> button.btn {
|
> button.btn,
|
||||||
|
> .confirm-button {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.func-node:hover .func-node--menu,
|
.func-node--wrapper:hover .func-node--menu,
|
||||||
.func-node.editing .func-node--menu,
|
.func-node.editing + .func-node--menu,
|
||||||
.func-node.active .func-node--menu {
|
.func-node.active + .func-node--menu {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ export const DEFAULT_TEMPLATES: DefaultTemplates = {
|
||||||
values: [],
|
values: [],
|
||||||
type: TemplateType.CSV,
|
type: TemplateType.CSV,
|
||||||
label: '',
|
label: '',
|
||||||
|
query: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[TemplateType.TagKeys]: () => {
|
[TemplateType.TagKeys]: () => {
|
||||||
|
|
|
@ -21,6 +21,7 @@ export type ScriptUpToYield = (
|
||||||
yieldNodeIndex: number,
|
yieldNodeIndex: number,
|
||||||
isYieldable: boolean
|
isYieldable: boolean
|
||||||
) => string
|
) => string
|
||||||
|
export type OnDeleteBody = (bodyID: string) => void
|
||||||
|
|
||||||
export interface ScriptStatus {
|
export interface ScriptStatus {
|
||||||
type: string
|
type: string
|
||||||
|
@ -105,6 +106,9 @@ export interface FlatBody {
|
||||||
funcs?: Func[]
|
funcs?: Func[]
|
||||||
declarations?: FlatDeclaration[]
|
declarations?: FlatDeclaration[]
|
||||||
}
|
}
|
||||||
|
export interface Body extends FlatBody {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface Func {
|
export interface Func {
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface WrappedCancelablePromise<T> {
|
||||||
|
promise: Promise<T>
|
||||||
|
cancel: () => void
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
import {WrappedCancelablePromise} from 'src/types/promises'
|
||||||
|
|
||||||
|
export const makeCancelable = <T>(
|
||||||
|
promise: Promise<T>
|
||||||
|
): WrappedCancelablePromise<T> => {
|
||||||
|
let isCanceled = false
|
||||||
|
|
||||||
|
const wrappedPromise = new Promise<T>(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const value = await promise
|
||||||
|
|
||||||
|
if (isCanceled) {
|
||||||
|
reject({isCanceled})
|
||||||
|
} else {
|
||||||
|
resolve(value)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (isCanceled) {
|
||||||
|
reject({isCanceled})
|
||||||
|
} else {
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
promise: wrappedPromise,
|
||||||
|
cancel() {
|
||||||
|
isCanceled = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ const setup = () => {
|
||||||
onValidate: () => {},
|
onValidate: () => {},
|
||||||
onAppendFrom: () => {},
|
onAppendFrom: () => {},
|
||||||
onAppendJoin: () => {},
|
onAppendJoin: () => {},
|
||||||
|
onDeleteBody: () => {},
|
||||||
status: {type: '', text: ''},
|
status: {type: '', text: ''},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue