Merge remote-tracking branch 'origin/master' into sgc/tsm1

pull/19446/head
Stuart Carnie 2020-08-13 09:23:34 -07:00
commit fc6ff065e2
No known key found for this signature in database
GPG Key ID: 848D9C9718D78B4F
46 changed files with 1538 additions and 1157 deletions

View File

@ -3,6 +3,7 @@ package influxdb
import (
"errors"
"fmt"
"os"
"path/filepath"
)
@ -218,8 +219,21 @@ type Permission struct {
Resource Resource `json:"resource"`
}
var newMatchBehavior bool
func init() {
_, newMatchBehavior = os.LookupEnv("MATCHER_BEHAVIOR")
}
// Matches returns whether or not one permission matches the other.
func (p Permission) Matches(perm Permission) bool {
if newMatchBehavior {
return p.matchesV2(perm)
}
return p.matchesV1(perm)
}
func (p Permission) matchesV1(perm Permission) bool {
if p.Action != perm.Action {
return false
}
@ -232,6 +246,13 @@ func (p Permission) Matches(perm Permission) bool {
return true
}
if p.Resource.OrgID != nil && perm.Resource.OrgID != nil && p.Resource.ID != nil && perm.Resource.ID != nil {
if *p.Resource.OrgID != *perm.Resource.OrgID && *p.Resource.ID == *perm.Resource.ID {
fmt.Printf("v1: old match used: p.Resource.OrgID=%s perm.Resource.OrgID=%s p.Resource.ID=%s",
*p.Resource.OrgID, *perm.Resource.OrgID, *p.Resource.ID)
}
}
if p.Resource.OrgID != nil && p.Resource.ID == nil {
pOrgID := *p.Resource.OrgID
if perm.Resource.OrgID != nil {
@ -255,6 +276,53 @@ func (p Permission) Matches(perm Permission) bool {
return false
}
func (p Permission) matchesV2(perm Permission) bool {
if p.Action != perm.Action {
return false
}
if p.Resource.Type != perm.Resource.Type {
return false
}
if p.Resource.OrgID == nil && p.Resource.ID == nil {
return true
}
if p.Resource.OrgID != nil && perm.Resource.OrgID != nil && p.Resource.ID != nil && perm.Resource.ID != nil {
if *p.Resource.OrgID != *perm.Resource.OrgID && *p.Resource.ID == *perm.Resource.ID {
fmt.Printf("v2: old match used: p.Resource.OrgID=%s perm.Resource.OrgID=%s p.Resource.ID=%s",
*p.Resource.OrgID, *perm.Resource.OrgID, *p.Resource.ID)
}
}
if p.Resource.OrgID != nil {
if perm.Resource.OrgID != nil {
if *p.Resource.OrgID == *perm.Resource.OrgID {
if p.Resource.ID == nil {
return true
}
if perm.Resource.ID != nil {
return *p.Resource.ID == *perm.Resource.ID
}
}
return false
}
}
if p.Resource.ID != nil {
pID := *p.Resource.ID
if perm.Resource.ID != nil {
permID := *perm.Resource.ID
if pID == permID {
return true
}
}
}
return false
}
func (p Permission) String() string {
return fmt.Sprintf("%s:%s", p.Action, p.Resource)
}

10
node_modules/.yarn-integrity generated vendored
View File

@ -1,10 +0,0 @@
{
"systemParams": "darwin-x64-83",
"modulesFolders": [],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}

View File

@ -278,8 +278,8 @@ describe('Buckets', () => {
})
})
describe('add data', () => {
it('writing data to buckets', () => {
describe('add data', function() {
it('can write data to buckets', () => {
cy.get('@org').then(({id: orgID}: Organization) => {
// writing a well-formed line is accepted
cy.getByTestID('add-data--button').click()
@ -293,31 +293,97 @@ describe('Buckets', () => {
cy.getByTestID('bucket-add-line-protocol').click()
cy.getByTestID('Enter Manually').click()
cy.getByTestID('lp-write-data--button').should('be.disabled')
cy.getByTestID('line-protocol--text-area').type('m1,t1=v1 v=1.0')
cy.getByTestID('next').click()
cy.getByTestID('line-protocol--status').should('have.class', 'success')
cy.getByTestID('next').click()
cy.getByTestID('lp-write-data--button').click()
cy.getByTestID('line-protocol--status').contains('Success')
cy.getByTestID('lp-close--button').click()
// writing a poorly-formed line errors
cy.getByTestID('add-data--button').click()
cy.getByTestID('bucket-add-line-protocol').click()
cy.getByTestID('Enter Manually').click()
cy.getByTestID('line-protocol--text-area').type('invalid invalid')
cy.getByTestID('next').click()
cy.getByTestID('line-protocol--status').should('have.class', 'error')
cy.getByTestID('next').click()
cy.getByTestID('lp-write-data--button').click()
cy.getByTestID('line-protocol--status').contains('Unable')
cy.getByTestID('lp-cancel--button').click()
// writing a well-formed line with millisecond precision is accepted
cy.getByTestID('add-data--button').click()
cy.getByTestID('bucket-add-line-protocol').click()
cy.getByTestID('Enter Manually').click()
cy.getByTestID('wizard-step--lp-precision--dropdown').click()
cy.getByTestID('wizard-step--lp-precision-ms').click()
const now = Date.now()
cy.getByTestID('line-protocol--text-area').type(`m2,t2=v2 v=2.0 ${now}`)
cy.getByTestID('next').click()
cy.getByTestID('line-protocol--status').should('have.class', 'success')
cy.getByTestID('next').click()
cy.getByTestID('lp-write-data--button').click()
cy.getByTestID('line-protocol--status').contains('Success')
})
})
it('upload a file and write data', () => {
cy.getByTestID('add-data--button').click()
cy.getByTestID('bucket-add-line-protocol').click()
cy.getByTestID('Upload File').click()
// When a file is larger than 10MB
const bigFile = 'data-big.txt'
const type = 'plain/text'
const testFile = new File(
['a'.repeat(1e7) + 'just a bit over 10mb'],
bigFile,
{type}
)
const event = {dataTransfer: {files: [testFile]}, force: true}
cy.getByTestID('drag-and-drop--input')
.trigger('dragover', event)
.trigger('drop', event)
cy.getByTestID('dnd--header-error').contains(bigFile)
cy.getByTestID('cancel-upload--button').click()
cy.getByTestID('wizard-step--lp-precision--dropdown').click()
cy.getByTestID('wizard-step--lp-precision-ms').click()
cy.getByTestID('wizard-step--lp-precision--dropdown').contains(
'Milliseconds'
)
// When a file is the correct size
const smallFile = 'data.txt'
cy.fixture(smallFile, 'base64')
.then(Cypress.Blob.base64StringToBlob)
.then(blob => {
const type = 'plain/text'
const testFile = new File([blob], smallFile, {type})
const event = {dataTransfer: {files: [testFile]}, force: true}
cy.getByTestID('drag-and-drop--input')
.trigger('dragover', event)
.trigger('drop', event)
})
cy.getByTestID('write-data--button').click()
cy.getByTestID('lp-close--button').click()
// navigate to data explorer to see data
cy.getByTestID('nav-item-data-explorer').click({force: true})
cy.getByTestID('timerange-dropdown').click()
cy.getByTestID('dropdown-item-customtimerange').click()
// time range start
cy.getByTestID('timerange--input')
.first()
.clear()
.type('2020-08-06 00:00:00.000')
// time range stop
cy.getByTestID('timerange--input')
.last()
.clear()
.type('2020-08-08 00:00:00.000')
cy.getByTestID('daterange--apply-btn').click()
cy.fixture('user.json').then(({bucket}) => {
cy.getByTestID(`selector-list ${bucket}`).click()
// mymeasurement comes from fixtures/data.txt
cy.getByTestID('selector-list mymeasurement').should('exist')
})
})
})

View File

@ -0,0 +1,20 @@
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113000
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113001
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113002
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113003
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113004
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113005
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113006
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113007
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113008
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113009
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113010
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113011
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113012
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113013
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113014
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113015
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113016
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113017
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113018
mymeasurement,tag1=value1,tag2=value2 fieldkey="fieldvalue" 1596817113019

View File

@ -86,7 +86,7 @@
"clean-webpack-plugin": "^3.0.0",
"cross-env": "^5.2.0",
"css-loader": "^3.1.0",
"cypress": "4.7.0",
"cypress": "4.12.1",
"cypress-file-upload": "^4.0.7",
"cypress-pipe": "^1.5.0",
"cypress-plugin-tab": "^1.0.5",

View File

@ -73,7 +73,6 @@ const BucketCardActions: FC<Props> = ({
const handleAddLineProtocol = () => {
onSetDataLoadersBucket(orgID, bucket.name, bucket.id)
onSetDataLoadersType(DataLoaderType.LineProtocol)
history.push(
`/orgs/${orgID}/load-data/buckets/${bucket.id}/line-protocols/new`
)

View File

@ -0,0 +1,66 @@
// Libraries
import React, {FC, useContext} from 'react'
// Components
import {Context} from './LineProtocolWizard'
import {
Button,
ButtonType,
ComponentColor,
ComponentSize,
ComponentStatus,
} from '@influxdata/clockface'
// Types
import {RemoteDataState} from 'src/types'
interface Props {
onSubmit: () => void
onCancel: () => void
onClose: () => void
}
const EnterManuallyButtons: FC<Props> = ({onSubmit, onCancel, onClose}) => {
const [{writeStatus, body}] = useContext(Context)
const status = body ? ComponentStatus.Default : ComponentStatus.Disabled
if (writeStatus === RemoteDataState.Error) {
return (
<Button
color={ComponentColor.Default}
text="Cancel"
size={ComponentSize.Medium}
type={ButtonType.Button}
onClick={onCancel}
testID="lp-cancel--button"
/>
)
}
if (writeStatus === RemoteDataState.Done) {
return (
<Button
color={ComponentColor.Default}
text="Close"
size={ComponentSize.Medium}
type={ButtonType.Button}
onClick={onClose}
testID="lp-close--button"
/>
)
}
return (
<Button
color={ComponentColor.Primary}
text="Write Data"
size={ComponentSize.Medium}
type={ButtonType.Button}
status={status}
testID="lp-write-data--button"
onClick={onSubmit}
/>
)
}
export default EnterManuallyButtons

View File

@ -0,0 +1,45 @@
// Types
import {RemoteDataState, WritePrecision, LineProtocolTab} from 'src/types'
export const SET_BODY = 'SET_BODY'
export const SET_TAB = 'SET_TAB'
export const SET_WRITE_STATUS = 'SET_WRITE_STATUS'
export const SET_PRECISION = 'SET_PRECISION'
export const RESET_LINE_PROTOCOL_STATE = 'RESET_LINE_PROTOCOL_STATE'
export type Action =
| ReturnType<typeof setBody>
| ReturnType<typeof setTab>
| ReturnType<typeof setWriteStatus>
| ReturnType<typeof setPrecision>
| ReturnType<typeof reset>
export const setBody = (body: string) =>
({
type: SET_BODY,
body,
} as const)
export const setTab = (tab: LineProtocolTab) =>
({
type: SET_TAB,
tab,
} as const)
export const setWriteStatus = (writeStatus: RemoteDataState, writeError = '') =>
({
type: SET_WRITE_STATUS,
writeStatus,
writeError,
} as const)
export const setPrecision = (precision: WritePrecision) =>
({
type: SET_PRECISION,
precision,
} as const)
export const reset = () =>
({
type: RESET_LINE_PROTOCOL_STATE,
} as const)

View File

@ -0,0 +1,66 @@
import {RemoteDataState, WritePrecision} from 'src/types'
import {produce} from 'immer'
import {
Action,
SET_BODY,
SET_PRECISION,
SET_WRITE_STATUS,
SET_TAB,
RESET_LINE_PROTOCOL_STATE,
} from 'src/buckets/components/lineProtocol/LineProtocol.creators'
export interface LineProtocolState {
body: string
tab: 'Upload File' | 'Enter Manually'
writeStatus: RemoteDataState
writeError: string
precision: WritePrecision
}
export const initialState = (): LineProtocolState => ({
body: '',
tab: 'Upload File',
writeStatus: RemoteDataState.NotStarted,
writeError: '',
precision: WritePrecision.Ns,
})
const lineProtocolReducer = (
state = initialState(),
action: Action
): LineProtocolState =>
produce(state, draftState => {
switch (action.type) {
case SET_BODY: {
draftState.body = action.body
return
}
case SET_TAB: {
draftState.tab = action.tab
return
}
case SET_WRITE_STATUS: {
draftState.writeStatus = action.writeStatus
draftState.writeError = action.writeError
return
}
case SET_PRECISION: {
draftState.precision = action.precision
return
}
case RESET_LINE_PROTOCOL_STATE: {
draftState.body = ''
draftState.writeStatus = RemoteDataState.NotStarted
draftState.writeError = ''
return
}
}
})
export default lineProtocolReducer

View File

@ -0,0 +1,50 @@
// Libraries
import {Dispatch} from 'react'
// Action Creators
import {
setWriteStatus,
Action,
} from 'src/buckets/components/lineProtocol/LineProtocol.creators'
// APIs
import {postWrite as apiPostWrite} from 'src/client'
// Types
import {RemoteDataState, WritePrecision} from 'src/types'
export const writeLineProtocolAction = async (
dispatch: Dispatch<Action>,
org: string,
bucket: string,
body: string,
precision: WritePrecision
) => {
try {
dispatch(setWriteStatus(RemoteDataState.Loading))
const resp = await apiPostWrite({
data: body,
query: {org, bucket, precision},
})
if (resp.status === 204) {
dispatch(setWriteStatus(RemoteDataState.Done))
} else if (resp.status === 429) {
dispatch(
setWriteStatus(
RemoteDataState.Error,
'Failed due to plan limits: read cardinality reached'
)
)
} else if (resp.status === 403) {
dispatch(setWriteStatus(RemoteDataState.Error, resp.data.message))
} else {
const message = resp?.data?.message || 'Failed to write data'
dispatch(setWriteStatus(RemoteDataState.Error, message))
throw new Error(message)
}
} catch (error) {
console.error(error)
}
}

View File

@ -0,0 +1,46 @@
// Libraries
import React, {FC, useContext} from 'react'
import {useHistory, useParams} from 'react-router'
// Actions
import {reset} from 'src/buckets/components/lineProtocol/LineProtocol.creators'
// Components
import {Context} from 'src/buckets/components/lineProtocol/LineProtocolWizard'
import EnterManuallyButtons from './EnterManuallyButtons'
import UploadFileButtons from './UploadFileButtons'
interface Props {
onSubmit: () => void
}
const LineProtocolButtons: FC<Props> = ({onSubmit}) => {
const history = useHistory()
const {orgID} = useParams<{orgID: string}>()
const [{tab}, dispatch] = useContext(Context)
const handleCancel = () => {
dispatch(reset())
}
const handleClose = () => {
history.push(`/orgs/${orgID}/load-data/buckets`)
}
if (tab === 'Enter Manually') {
return (
<EnterManuallyButtons
onClose={handleClose}
onCancel={handleCancel}
onSubmit={onSubmit}
/>
)
}
if (tab === 'Upload File') {
return <UploadFileButtons onClose={handleClose} onCancel={handleCancel} />
}
return null
}
export default LineProtocolButtons

View File

@ -0,0 +1,71 @@
// Libraries
import React, {useReducer, Dispatch} from 'react'
import {useHistory, useParams} from 'react-router-dom'
import {useSelector} from 'react-redux'
// Components
import {Overlay, OverlayFooter} from '@influxdata/clockface'
import LineProtocol from 'src/buckets/components/lineProtocol/configure/LineProtocol'
import {getByID} from 'src/resources/selectors'
// Actions
import {writeLineProtocolAction} from 'src/buckets/components/lineProtocol/LineProtocol.thunks'
// Reducers
import reducer, {
initialState,
LineProtocolState,
} from 'src/buckets/components/lineProtocol/LineProtocol.reducer'
// Types
import {ResourceType, AppState, Bucket} from 'src/types'
import {Action} from 'src/buckets/components/lineProtocol/LineProtocol.creators'
import LineProtocolFooterButtons from './LineProtocolFooterButtons'
// Selectors
import {getOrg} from 'src/organizations/selectors'
type LineProtocolContext = [LineProtocolState, Dispatch<Action>]
export const Context = React.createContext<LineProtocolContext>(null)
const getState = (bucketID: string) => (state: AppState) => {
const bucket = getByID<Bucket>(state, ResourceType.Buckets, bucketID)
const org = getOrg(state).name
return {bucket: bucket?.name || '', org}
}
const LineProtocolWizard = () => {
const history = useHistory()
const {bucketID, orgID} = useParams()
const {bucket, org} = useSelector(getState(bucketID))
const [state, dispatch] = useReducer(reducer, initialState())
const {body, precision} = state
const handleDismiss = () => {
history.push(`/orgs/${orgID}/load-data/buckets`)
}
const handleSubmit = () => {
writeLineProtocolAction(dispatch, org, bucket, body, precision)
}
return (
<Context.Provider value={[state, dispatch]}>
<Overlay visible={true}>
<Overlay.Container maxWidth={800}>
<Overlay.Header
title="Add Data Using Line Protocol"
onDismiss={handleDismiss}
/>
<LineProtocol onSubmit={handleSubmit} />
<OverlayFooter>
<LineProtocolFooterButtons onSubmit={handleSubmit} />
</OverlayFooter>
</Overlay.Container>
</Overlay>
</Context.Provider>
)
}
export default LineProtocolWizard

View File

@ -0,0 +1,53 @@
// Libraries
import React, {FC, useContext} from 'react'
// Components
import {Context} from './LineProtocolWizard'
import {
Button,
ButtonType,
ComponentColor,
ComponentSize,
} from '@influxdata/clockface'
// Types
import {RemoteDataState} from 'src/types'
interface Props {
onClose: () => void
onCancel: () => void
}
const UploadFileButtons: FC<Props> = ({onClose, onCancel}) => {
const [{writeStatus}] = useContext(Context)
if (writeStatus === RemoteDataState.Error) {
return (
<Button
color={ComponentColor.Default}
text="Cancel"
size={ComponentSize.Medium}
type={ButtonType.Button}
onClick={onCancel}
testID="lp-cancel--button"
/>
)
}
if (writeStatus === RemoteDataState.Done) {
return (
<Button
color={ComponentColor.Default}
text="Close"
size={ComponentSize.Medium}
type={ButtonType.Button}
onClick={onClose}
testID="lp-close--button"
/>
)
}
return null
}
export default UploadFileButtons

View File

@ -0,0 +1,194 @@
import React, {PureComponent, ChangeEvent, RefObject} from 'react'
import classnames from 'classnames'
// Components
import DragAndDropHeader from './DragAndDropHeader'
import DragAndDropButtons from './DragAndDropButtons'
import DragInfo from './DragInfo'
export const MAX_FILE_SIZE = 1e7
interface Props {
className: string
onSubmit: () => void
onSetBody: (body: string) => void
}
interface State {
fileSize: number
inputContent: string
uploadContent: string
fileName: string
dragClass: string
}
let dragCounter = 0
class DragAndDrop extends PureComponent<Props, State> {
private fileInput: RefObject<HTMLInputElement>
constructor(props: Props) {
super(props)
this.fileInput = React.createRef()
this.state = {
fileSize: -Infinity,
inputContent: null,
uploadContent: '',
fileName: '',
dragClass: 'drag-none',
}
}
public componentDidMount() {
window.addEventListener('dragover', this.handleWindowDragOver)
window.addEventListener('drop', this.handleFileDrop)
window.addEventListener('dragenter', this.handleDragEnter)
window.addEventListener('dragleave', this.handleDragLeave)
}
public componentWillUnmount() {
window.removeEventListener('dragover', this.handleWindowDragOver)
window.removeEventListener('drop', this.handleFileDrop)
window.removeEventListener('dragenter', this.handleDragEnter)
window.removeEventListener('dragleave', this.handleDragLeave)
}
public render() {
const {uploadContent, fileName, fileSize} = this.state
return (
<div className={this.containerClass}>
<div className={this.dragAreaClass} onClick={this.handleFileOpen}>
<DragAndDropHeader
uploadContent={uploadContent}
fileName={fileName}
fileSize={fileSize}
/>
<DragInfo uploadContent={uploadContent} />
<input
type="file"
data-testid="drag-and-drop--input"
ref={this.fileInput}
className="drag-and-drop--input"
accept="*"
onChange={this.handleFileClick}
/>
<DragAndDropButtons
onSubmit={this.handleSubmit}
fileSize={fileSize}
onCancel={this.handleCancelFile}
uploadContent={uploadContent}
/>
</div>
</div>
)
}
private handleSubmit = () => {
this.props.onSubmit()
}
private handleWindowDragOver = (event: DragEvent) => {
event.preventDefault()
}
private get containerClass(): string {
const {dragClass} = this.state
const {className} = this.props
return classnames('drag-and-drop', {
[dragClass]: true,
[className]: className,
})
}
private get dragAreaClass(): string {
const {uploadContent} = this.state
return classnames('drag-and-drop--form', {active: !uploadContent})
}
private handleFileClick = (e: ChangeEvent<HTMLInputElement>): void => {
const file: File = e.currentTarget.files[0]
const fileSize = file.size
this.setState({
fileName: file.name,
fileSize,
})
if (fileSize >= MAX_FILE_SIZE) {
return
}
e.preventDefault()
e.stopPropagation()
this.uploadFile(file)
}
private handleFileDrop = (e: DragEvent): void => {
const file: File = e.dataTransfer.files[0]
const fileSize = file.size
this.setState({
fileName: file.name,
fileSize: file.size,
dragClass: 'drag-none',
})
if (fileSize >= MAX_FILE_SIZE) {
return
}
e.preventDefault()
e.stopPropagation()
this.uploadFile(file)
}
private uploadFile = (file: File) => {
const reader = new FileReader()
reader.onload = () => {
this.setState(
{
uploadContent: reader.result as string,
fileName: file.name,
},
() => {
this.props.onSetBody(this.state.uploadContent)
}
)
}
reader.readAsText(file)
}
private handleFileOpen = (): void => {
const {uploadContent} = this.state
if (uploadContent === '') {
this.fileInput.current.click()
}
}
private handleCancelFile = (): void => {
this.setState({uploadContent: '', fileSize: -Infinity})
this.fileInput.current.value = ''
}
private handleDragEnter = (e: DragEvent): void => {
dragCounter += 1
e.preventDefault()
this.setState({dragClass: 'drag-over'})
}
private handleDragLeave = (e: DragEvent): void => {
dragCounter -= 1
e.preventDefault()
if (dragCounter === 0) {
this.setState({dragClass: 'drag-none'})
}
}
}
export default DragAndDrop

View File

@ -0,0 +1,65 @@
import React, {FC} from 'react'
import {
Button,
ComponentColor,
ComponentSize,
ButtonType,
} from '@influxdata/clockface'
interface Props {
fileSize: number
uploadContent: string
onCancel: () => void
onSubmit: () => void
}
const MAX_FILE_SIZE = 1e7 // 10MB
const DragAndDropButtons: FC<Props> = ({
fileSize,
uploadContent,
onCancel,
onSubmit,
}) => {
if (fileSize > MAX_FILE_SIZE) {
return (
<span className="drag-and-drop--buttons">
<Button
color={ComponentColor.Default}
text="Cancel"
size={ComponentSize.Medium}
type={ButtonType.Button}
onClick={onCancel}
testID="cancel-upload--button"
/>
</span>
)
}
if (!uploadContent) {
return null
}
return (
<span className="drag-and-drop--buttons">
<Button
color={ComponentColor.Primary}
text="Write Data"
size={ComponentSize.Medium}
type={ButtonType.Submit}
onClick={onSubmit}
testID="write-data--button"
/>
<Button
color={ComponentColor.Default}
text="Cancel"
size={ComponentSize.Medium}
type={ButtonType.Submit}
onClick={onCancel}
testID="cancel-upload--button"
/>
</span>
)
}
export default DragAndDropButtons

View File

@ -0,0 +1,34 @@
// Libraries
import React, {FC} from 'react'
import {MAX_FILE_SIZE} from './DragAndDrop'
interface Props {
uploadContent: string
fileName: string
fileSize: number
}
const DragAndDropHeader: FC<Props> = ({uploadContent, fileName, fileSize}) => {
if (fileSize > MAX_FILE_SIZE) {
return (
<div
className="drag-and-drop--header error"
data-testid="dnd--header-error"
>
{fileName} is greater than 10MB
</div>
)
}
if (uploadContent) {
return <div className="drag-and-drop--header selected">{fileName}</div>
}
return (
<div className="drag-and-drop--header empty">
Drop a file here or click to upload. Max size 10MB.
</div>
)
}
export default DragAndDropHeader

View File

@ -0,0 +1,15 @@
// Libraries
import React, {FC} from 'react'
import cn from 'classnames'
interface Props {
uploadContent: string
}
const DragInfo: FC<Props> = ({uploadContent}) => {
const className = cn('drag-and-drop--graphic', {success: uploadContent})
return <div className={className} />
}
export default DragInfo

View File

@ -0,0 +1,28 @@
// Libraries
import React, {FC} from 'react'
// Components
import {Form, Overlay} from '@influxdata/clockface'
import LineProtocolTabs from 'src/buckets/components/lineProtocol/configure/LineProtocolTabs'
import LineProtocolHelperText from 'src/buckets/components/lineProtocol/LineProtocolHelperText'
// Types
import {LineProtocolTab} from 'src/types/index'
type OwnProps = {onSubmit: () => void}
type Props = OwnProps
const tabs: LineProtocolTab[] = ['Upload File', 'Enter Manually']
const LineProtocol: FC<Props> = ({onSubmit}) => {
return (
<Form>
<Overlay.Body style={{textAlign: 'center'}}>
<LineProtocolTabs tabs={tabs} onSubmit={onSubmit} />
<LineProtocolHelperText />
</Overlay.Body>
</Form>
)
}
export default LineProtocol

View File

@ -0,0 +1,59 @@
// Libraries
import React, {useContext, FC} from 'react'
// Components
import PrecisionDropdown from 'src/buckets/components/lineProtocol/configure/PrecisionDropdown'
import TabSelector from 'src/buckets/components/lineProtocol/configure/TabSelector'
import TabBody from 'src/buckets/components/lineProtocol/configure/TabBody'
import {Context} from 'src/buckets/components/lineProtocol/LineProtocolWizard'
// Types
import {LineProtocolTab, RemoteDataState, WritePrecision} from 'src/types'
// Actions
import {
setBody,
setTab,
setPrecision,
} from 'src/buckets/components/lineProtocol/LineProtocol.creators'
import StatusIndicator from '../verify/StatusIndicator'
interface OwnProps {
tabs: LineProtocolTab[]
onSubmit: () => void
}
type Props = OwnProps
const LineProtocolTabs: FC<Props> = ({tabs, onSubmit}) => {
const [state, dispatch] = useContext(Context)
const {tab, precision, writeStatus} = state
const handleTabClick = (tab: LineProtocolTab) => {
dispatch(setBody(''))
dispatch(setTab(tab))
}
const handleSetPrecision = (p: WritePrecision) => {
dispatch(setPrecision(p))
}
if (writeStatus !== RemoteDataState.NotStarted) {
return <StatusIndicator />
}
return (
<>
<div className="line-protocol--header">
<TabSelector activeLPTab={tab} tabs={tabs} onClick={handleTabClick} />
<PrecisionDropdown
setPrecision={handleSetPrecision}
precision={precision}
/>
</div>
<TabBody onSubmit={onSubmit} />
</>
)
}
export default LineProtocolTabs

View File

@ -5,7 +5,7 @@ import React, {PureComponent} from 'react'
import {Dropdown} from '@influxdata/clockface'
// Types
import {WritePrecision} from '@influxdata/influx'
import {WritePrecision} from 'src/types'
import {Precision} from 'src/types/dataLoaders'
interface Props {

View File

@ -0,0 +1,49 @@
// Libraries
import React, {FC, ChangeEvent, useContext} from 'react'
// Components
import {TextArea} from '@influxdata/clockface'
import DragAndDrop from 'src/buckets/components/lineProtocol/configure/DragAndDrop'
import {Context} from 'src/buckets/components/lineProtocol/LineProtocolWizard'
// Action
import {setBody} from 'src/buckets/components/lineProtocol/LineProtocol.creators'
interface Props {
onSubmit: () => void
}
const TabBody: FC<Props> = ({onSubmit}) => {
const [{body, tab}, dispatch] = useContext(Context)
const handleTextChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
dispatch(setBody(e.target.value))
}
const handleSetBody = (b: string) => {
dispatch(setBody(b))
}
switch (tab) {
case 'Upload File':
return (
<DragAndDrop
className="line-protocol--content"
onSubmit={onSubmit}
onSetBody={handleSetBody}
/>
)
case 'Enter Manually':
return (
<TextArea
value={body}
placeholder="Write text here"
onChange={handleTextChange}
testID="line-protocol--text-area"
className="line-protocol--content"
/>
)
}
}
export default TabBody

View File

@ -3,7 +3,7 @@ import React, {PureComponent} from 'react'
import {SelectGroup, ButtonShape} from '@influxdata/clockface'
import {LineProtocolTab} from 'src/types'
import Tab from 'src/dataLoaders/components/lineProtocolWizard/configure/Tab'
import Tab from 'src/buckets/components/lineProtocol/configure/Tab'
interface Props {
tabs: LineProtocolTab[]

View File

@ -0,0 +1,59 @@
// Libraries
import React, {FC, useContext} from 'react'
import cn from 'classnames'
// Components
import {SparkleSpinner} from '@influxdata/clockface'
import {Context} from 'src/buckets/components/lineProtocol/LineProtocolWizard'
// Types
import {RemoteDataState} from 'src/types'
const getStatusText = (s, writeError) => {
let status = ''
let message = ''
switch (s) {
case RemoteDataState.Loading:
status = 'Loading...'
message = 'Just a moment'
break
case RemoteDataState.Done:
status = 'Data Written Successfully'
message = 'Hooray!'
break
case RemoteDataState.Error:
status = 'Unable to Write Data'
message = `${writeError}`
break
}
return {
status,
message,
}
}
const className = status =>
cn(`line-protocol--status`, {
loading: status === RemoteDataState.Loading,
success: status === RemoteDataState.Done,
error: status === RemoteDataState.Error,
})
const StatusIndicator: FC = () => {
const [{writeStatus, writeError}] = useContext(Context)
return (
<div className="line-protocol--spinner">
<p data-testid="line-protocol--status" className={className(status)}>
{getStatusText(writeStatus, writeError).status}
</p>
<SparkleSpinner loading={writeStatus} sizePixels={220} />
<p className={className(status)}>
{getStatusText(writeStatus, writeError).message}
</p>
</div>
)
}
export default StatusIndicator

View File

@ -11,7 +11,7 @@ import BucketsTab from 'src/buckets/components/BucketsTab'
import GetResources from 'src/resources/components/GetResources'
import GetAssetLimits from 'src/cloud/components/GetAssetLimits'
import LimitChecker from 'src/cloud/components/LimitChecker'
import LineProtocolWizard from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
import LineProtocolWizard from 'src/buckets/components/lineProtocol/LineProtocolWizard'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import UpdateBucketOverlay from 'src/buckets/components/UpdateBucketOverlay'
import RenameBucketOverlay from 'src/buckets/components/RenameBucketOverlay'

View File

@ -6,7 +6,6 @@ import {normalize} from 'normalizr'
import {client} from 'src/utils/api'
import {ScraperTargetRequest, PermissionResource} from '@influxdata/influx'
import {createAuthorization} from 'src/authorizations/apis'
import {postWrite as apiPostWrite} from 'src/client'
// Schemas
import {authSchema} from 'src/schemas'
@ -30,14 +29,12 @@ import {
TelegrafPlugin,
TelegrafPluginName,
DataLoaderType,
LineProtocolTab,
Plugin,
BundleName,
ConfigurationState,
} from 'src/types/dataLoaders'
import {
GetState,
RemoteDataState,
Authorization,
AuthEntities,
ResourceType,
@ -45,7 +42,6 @@ import {
Telegraf,
} from 'src/types'
import {
WritePrecision,
TelegrafRequest,
TelegrafPluginOutputInfluxDBV2,
Permission,
@ -57,7 +53,6 @@ import {addTelegraf, editTelegraf} from 'src/telegrafs/actions/creators'
import {addAuthorization} from 'src/authorizations/actions/creators'
import {notify} from 'src/shared/actions/notifications'
import {
readWriteCardinalityLimitReached,
TelegrafConfigCreationError,
TelegrafConfigCreationSuccess,
TokenCreationError,
@ -72,10 +67,6 @@ export type Action =
| AddConfigValue
| RemoveConfigValue
| SetActiveTelegrafPlugin
| SetLineProtocolBody
| SetActiveLPTab
| SetLPStatus
| SetPrecision
| UpdateTelegrafPlugin
| AddPluginBundle
| AddTelegrafPlugins
@ -553,83 +544,6 @@ export const setPluginConfiguration = (
payload: {telegrafPlugin},
})
interface SetLineProtocolBody {
type: 'SET_LINE_PROTOCOL_BODY'
payload: {lineProtocolBody: string}
}
export const setLineProtocolBody = (
lineProtocolBody: string
): SetLineProtocolBody => ({
type: 'SET_LINE_PROTOCOL_BODY',
payload: {lineProtocolBody},
})
interface SetActiveLPTab {
type: 'SET_ACTIVE_LP_TAB'
payload: {activeLPTab: LineProtocolTab}
}
export const setActiveLPTab = (
activeLPTab: LineProtocolTab
): SetActiveLPTab => ({
type: 'SET_ACTIVE_LP_TAB',
payload: {activeLPTab},
})
interface SetLPStatus {
type: 'SET_LP_STATUS'
payload: {lpStatus: RemoteDataState; lpError: string}
}
export const setLPStatus = (
lpStatus: RemoteDataState,
lpError: string = ''
): SetLPStatus => ({
type: 'SET_LP_STATUS',
payload: {lpStatus, lpError},
})
interface SetPrecision {
type: 'SET_PRECISION'
payload: {precision: WritePrecision}
}
export const setPrecision = (precision: WritePrecision): SetPrecision => ({
type: 'SET_PRECISION',
payload: {precision},
})
export const writeLineProtocolAction = (
org: string,
bucket: string,
body: string,
precision: WritePrecision
) => async dispatch => {
try {
dispatch(setLPStatus(RemoteDataState.Loading))
const resp = await apiPostWrite({
data: body,
query: {org, bucket, precision},
})
if (resp.status === 204) {
dispatch(setLPStatus(RemoteDataState.Done))
} else if (resp.status === 429) {
dispatch(notify(readWriteCardinalityLimitReached(resp.data.message)))
dispatch(setLPStatus(RemoteDataState.Error))
} else if (resp.status === 403) {
dispatch(setLPStatus(RemoteDataState.Error, resp.data.message))
} else {
dispatch(setLPStatus(RemoteDataState.Error, 'failed to write data'))
throw new Error(get(resp, 'data.message', 'Failed to write data'))
}
} catch (error) {
console.error(error)
}
}
export const saveScraperTarget = () => async (
dispatch: Dispatch<Action>,
getState: GetState

View File

@ -1,149 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect, ConnectedProps} from 'react-redux'
import {withRouter, RouteComponentProps} from 'react-router-dom'
// Components
import {Overlay} from '@influxdata/clockface'
import {ErrorHandling} from 'src/shared/decorators/errors'
import LineProtocolStepSwitcher from 'src/dataLoaders/components/lineProtocolWizard/verify/LineProtocolStepSwitcher'
// Actions
import {notify as notifyAction} from 'src/shared/actions/notifications'
import {
setBucketInfo,
incrementCurrentStepIndex,
decrementCurrentStepIndex,
setCurrentStepIndex,
clearSteps,
} from 'src/dataLoaders/actions/steps'
import {clearDataLoaders} from 'src/dataLoaders/actions/dataLoaders'
// Types
import {AppState, ResourceType} from 'src/types'
import {Bucket} from 'src/types'
// Selectors
import {getAll} from 'src/resources/selectors'
export interface LineProtocolStepProps {
currentStepIndex: number
onIncrementCurrentStepIndex: () => void
onDecrementCurrentStepIndex: () => void
notify: typeof notifyAction
onExit: () => void
}
interface OwnProps {
onCompleteSetup: () => void
startingStep?: number
}
type ReduxProps = ConnectedProps<typeof connector>
type Props = OwnProps & ReduxProps
@ErrorHandling
class LineProtocolWizard extends PureComponent<
Props & RouteComponentProps<{orgID: string}>
> {
public componentDidMount() {
this.handleSetBucketInfo()
this.handleSetStartingValues()
}
public render() {
const {buckets} = this.props
return (
<Overlay visible={true}>
<Overlay.Container maxWidth={800}>
<Overlay.Header
title="Add Data Using Line Protocol"
onDismiss={this.handleDismiss}
/>
<LineProtocolStepSwitcher
stepProps={this.stepProps}
buckets={buckets}
/>
</Overlay.Container>
</Overlay>
)
}
private handleSetBucketInfo = () => {
const {bucket, buckets} = this.props
if (!bucket && buckets && buckets.length) {
const {orgID, name, id} = buckets[0]
this.props.onSetBucketInfo(orgID, name, id)
}
}
private handleSetStartingValues = () => {
const {startingStep} = this.props
const hasStartingStep = startingStep || startingStep === 0
if (hasStartingStep) {
this.props.onSetCurrentStepIndex(startingStep)
}
}
private handleDismiss = () => {
const {history, onClearDataLoaders, onClearSteps} = this.props
onClearDataLoaders()
onClearSteps()
history.goBack()
}
private get stepProps(): LineProtocolStepProps {
const {
notify,
currentStepIndex,
onDecrementCurrentStepIndex,
onIncrementCurrentStepIndex,
} = this.props
return {
currentStepIndex,
onIncrementCurrentStepIndex,
onDecrementCurrentStepIndex,
notify,
onExit: this.handleDismiss,
}
}
}
const mstp = (state: AppState) => {
const {
dataLoading: {
steps: {currentStep, bucket},
},
me: {name},
} = state
const buckets = getAll<Bucket>(state, ResourceType.Buckets)
return {
currentStepIndex: currentStep,
username: name,
bucket,
buckets,
}
}
const mdtp = {
notify: notifyAction,
onSetBucketInfo: setBucketInfo,
onIncrementCurrentStepIndex: incrementCurrentStepIndex,
onDecrementCurrentStepIndex: decrementCurrentStepIndex,
onSetCurrentStepIndex: setCurrentStepIndex,
onClearDataLoaders: clearDataLoaders,
onClearSteps: clearSteps,
}
const connector = connect(mstp, mdtp)
export default connector(withRouter(LineProtocolWizard))

View File

@ -1,37 +0,0 @@
// Libraries
import React from 'react'
import {shallow} from 'enzyme'
// Components
import {LineProtocol} from 'src/dataLoaders/components/lineProtocolWizard/configure/LineProtocol'
import {WritePrecision} from '@influxdata/influx'
const setup = (override = {}) => {
const props = {
bucket: 'a',
org: 'a',
onClickNext: jest.fn(),
lineProtocolBody: '',
precision: WritePrecision.Ns,
setLPStatus: jest.fn(),
writeLineProtocolAction: jest.fn(),
currentStepIndex: 0,
onIncrementCurrentStepIndex: jest.fn(),
onDecrementCurrentStepIndex: jest.fn(),
notify: jest.fn(),
onExit: jest.fn(),
...override,
}
const wrapper = shallow(<LineProtocol {...props} />)
return {wrapper}
}
describe('LineProtocol', () => {
describe('rendering', () => {
it('renders!', () => {
const {wrapper} = setup()
expect(wrapper.exists()).toBe(true)
})
})
})

View File

@ -1,93 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect, ConnectedProps} from 'react-redux'
// Components
import {Form, Overlay} from '@influxdata/clockface'
import LineProtocolTabs from 'src/dataLoaders/components/lineProtocolWizard/configure/LineProtocolTabs'
import OnboardingButtons from 'src/onboarding/components/OnboardingButtons'
import LineProtocolHelperText from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolHelperText'
// Actions
import {
setLPStatus as setLPStatusAction,
writeLineProtocolAction,
} from 'src/dataLoaders/actions/dataLoaders'
// Decorator
import {ErrorHandling} from 'src/shared/decorators/errors'
// Types
import {LineProtocolTab} from 'src/types/dataLoaders'
import {AppState} from 'src/types/index'
import {RemoteDataState} from 'src/types'
import {LineProtocolStepProps} from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
// Selectors
import {getOrg} from 'src/organizations/selectors'
type OwnProps = LineProtocolStepProps
type ReduxProps = ConnectedProps<typeof connector>
type Props = OwnProps & ReduxProps
@ErrorHandling
export class LineProtocol extends PureComponent<Props> {
public componentDidMount() {
const {setLPStatus} = this.props
setLPStatus(RemoteDataState.NotStarted)
}
public render() {
const {bucket, org} = this.props
return (
<Form onSubmit={this.handleSubmit}>
<Overlay.Body style={{textAlign: 'center'}}>
<LineProtocolTabs
tabs={this.LineProtocolTabs}
bucket={bucket}
org={org}
/>
<LineProtocolHelperText />
</Overlay.Body>
<OnboardingButtons autoFocusNext={true} nextButtonText="Write Data" />
</Form>
)
}
private get LineProtocolTabs(): LineProtocolTab[] {
return [LineProtocolTab.UploadFile, LineProtocolTab.EnterManually]
}
private handleSubmit = () => {
const {onIncrementCurrentStepIndex} = this.props
this.handleUpload()
onIncrementCurrentStepIndex()
}
private handleUpload = () => {
const {bucket, org, lineProtocolBody, precision} = this.props
this.props.writeLineProtocolAction(org, bucket, lineProtocolBody, precision)
}
}
const mstp = (state: AppState) => {
const {dataLoading} = state
const {
dataLoaders: {lineProtocolBody, precision},
steps: {bucket},
} = dataLoading
const org = getOrg(state).name
return {lineProtocolBody, precision, bucket, org}
}
const mdtp = {
setLPStatus: setLPStatusAction,
writeLineProtocolAction,
}
const connector = connect(mstp, mdtp)
export default connector(LineProtocol)

View File

@ -1,34 +0,0 @@
// Libraries
import React from 'react'
import {shallow} from 'enzyme'
// Components
import {LineProtocolTabs} from 'src/dataLoaders/components/lineProtocolWizard/configure/LineProtocolTabs'
import {LineProtocolTab} from 'src/types/dataLoaders'
const setup = (override?) => {
const props = {
tabs: [
LineProtocolTab.UploadFile,
LineProtocolTab.EnterManually,
LineProtocolTab.EnterURL,
],
bucket: 'a',
org: 'a',
...override,
}
const wrapper = shallow(<LineProtocolTabs {...props} />)
return {wrapper}
}
describe('LineProtocolTabs', () => {
describe('rendering', () => {
it('renders!', () => {
const {wrapper} = setup()
expect(wrapper.exists()).toBe(true)
})
})
})

View File

@ -1,107 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect, ConnectedProps} from 'react-redux'
// Components
import PrecisionDropdown from 'src/dataLoaders/components/lineProtocolWizard/configure/PrecisionDropdown'
import TabSelector from 'src/dataLoaders/components/lineProtocolWizard/configure/TabSelector'
import TabBody from 'src/dataLoaders/components/lineProtocolWizard/configure/TabBody'
// Types
import {AppState, LineProtocolTab} from 'src/types'
// Actions
import {
setLineProtocolBody,
setActiveLPTab,
setPrecision,
} from 'src/dataLoaders/actions/dataLoaders'
interface OwnProps {
tabs: LineProtocolTab[]
bucket: string
org: string
}
type ReduxProps = ConnectedProps<typeof connector>
type Props = OwnProps & ReduxProps
interface State {
urlInput: string
}
export class LineProtocolTabs extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
urlInput: '',
}
}
public render() {
const {
setPrecision,
precision,
activeLPTab,
tabs,
setLineProtocolBody,
lineProtocolBody,
} = this.props
const {urlInput} = this.state
return (
<>
<div className="line-protocol--header">
<TabSelector
activeLPTab={activeLPTab}
tabs={tabs}
onClick={this.handleTabClick}
/>
<PrecisionDropdown
setPrecision={setPrecision}
precision={precision}
/>
</div>
<TabBody
onURLChange={this.handleURLChange}
activeLPTab={activeLPTab}
precision={precision}
urlInput={urlInput}
lineProtocolBody={lineProtocolBody}
setLineProtocolBody={setLineProtocolBody}
/>
</>
)
}
private handleTabClick = (tab: LineProtocolTab) => {
const {setActiveLPTab, setLineProtocolBody} = this.props
setLineProtocolBody('')
setActiveLPTab(tab)
}
private handleURLChange = (urlInput: string) => {
this.setState({urlInput})
}
}
const mstp = ({
dataLoading: {
dataLoaders: {lineProtocolBody, activeLPTab, precision},
},
}: AppState) => {
return {lineProtocolBody, activeLPTab, precision}
}
const mdtp = {
setLineProtocolBody,
setActiveLPTab,
setPrecision,
}
const connector = connect(mstp, mdtp)
export default connector(LineProtocolTabs)

View File

@ -1,95 +0,0 @@
// Libraries
import React, {PureComponent, ChangeEvent} from 'react'
// Components
import {
Form,
Input,
Grid,
TextArea,
Columns,
InputType,
ComponentSize,
} from '@influxdata/clockface'
import DragAndDrop from 'src/shared/components/DragAndDrop'
import {LineProtocolTab} from 'src/types'
import {WritePrecision} from '@influxdata/influx'
import {setLineProtocolBody} from 'src/dataLoaders/actions/dataLoaders'
interface Props {
lineProtocolBody: string
activeLPTab: LineProtocolTab
precision: WritePrecision
setLineProtocolBody: typeof setLineProtocolBody
onURLChange: (url: string) => void
urlInput: string
}
export default class extends PureComponent<Props> {
public render() {
const {lineProtocolBody, activeLPTab, urlInput} = this.props
switch (activeLPTab) {
case LineProtocolTab.UploadFile:
return (
<DragAndDrop
submitText="Upload File"
handleSubmit={this.handleSetLineProtocol}
submitOnDrop={true}
submitOnUpload={true}
className="line-protocol--content"
/>
)
case LineProtocolTab.EnterManually:
return (
<TextArea
value={lineProtocolBody}
placeholder="Write text here"
onChange={this.handleTextChange}
testID="line-protocol--text-area"
className="line-protocol--content"
/>
)
case LineProtocolTab.EnterURL:
return (
<Grid>
<Grid.Row>
<Grid.Column
widthXS={Columns.Twelve}
widthMD={Columns.Ten}
offsetMD={Columns.One}
>
<Form.Element label="File URL:">
<Input
titleText="File URL:"
type={InputType.Text}
placeholder="http://..."
value={urlInput}
onChange={this.handleChange}
autoFocus={true}
size={ComponentSize.Large}
/>
</Form.Element>
</Grid.Column>
</Grid.Row>
</Grid>
)
}
}
private handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const {value} = e.target
this.props.onURLChange(value)
}
private handleTextChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const {setLineProtocolBody} = this.props
setLineProtocolBody(e.target.value)
}
private handleSetLineProtocol = (lpBody: string) => {
const {setLineProtocolBody} = this.props
setLineProtocolBody(lpBody)
}
}

View File

@ -1,34 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import {ErrorHandling} from 'src/shared/decorators/errors'
import LineProtocol from 'src/dataLoaders/components/lineProtocolWizard/configure/LineProtocol'
import LineProtocolVerifyStep from 'src/dataLoaders/components/lineProtocolWizard/verify/LineProtocolVerifyStep'
// Types
import {LineProtocolStepProps} from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
import {Bucket, LineProtocolStep} from 'src/types'
interface Props {
stepProps: LineProtocolStepProps
buckets: Bucket[]
}
@ErrorHandling
class StepSwitcher extends PureComponent<Props> {
public render() {
const {stepProps} = this.props
switch (stepProps.currentStepIndex) {
case LineProtocolStep.Configure:
return <LineProtocol {...stepProps} />
case LineProtocolStep.Verify:
return <LineProtocolVerifyStep {...stepProps} />
default:
return <div />
}
}
}
export default StepSwitcher

View File

@ -1,39 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
import _ from 'lodash'
// Components
import {Form, Overlay} from '@influxdata/clockface'
import StatusIndicator from 'src/dataLoaders/components/lineProtocolWizard/verify/StatusIndicator'
import OnboardingButtons from 'src/onboarding/components/OnboardingButtons'
import LineProtocolHelperText from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolHelperText'
// Types
import {LineProtocolStepProps} from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
// Decorators
import {ErrorHandling} from 'src/shared/decorators/errors'
type Props = LineProtocolStepProps
@ErrorHandling
export class VerifyLineProtocolStep extends PureComponent<Props> {
public render() {
const {onDecrementCurrentStepIndex, onExit} = this.props
return (
<Form onSubmit={onExit}>
<Overlay.Body style={{textAlign: 'center'}}>
<StatusIndicator />
<LineProtocolHelperText />
</Overlay.Body>
<OnboardingButtons
onClickBack={onDecrementCurrentStepIndex}
nextButtonText="Finish"
/>
</Form>
)
}
}
export default VerifyLineProtocolStep

View File

@ -1,29 +0,0 @@
// Libraries
import React from 'react'
import {shallow} from 'enzyme'
// Components
import {StatusIndicator} from 'src/dataLoaders/components/lineProtocolWizard/verify/StatusIndicator'
// Types
import {RemoteDataState} from 'src/types'
const setup = (override?) => {
const props = {
status: RemoteDataState.NotStarted,
...override,
}
const wrapper = shallow(<StatusIndicator {...props} />)
return {wrapper}
}
describe('StatusIndicator', () => {
describe('rendering', () => {
it('renders!', () => {
const {wrapper} = setup()
expect(wrapper.exists()).toBe(true)
})
})
})

View File

@ -1,78 +0,0 @@
// Libraries
import React, {PureComponent} from 'react'
import classnames from 'classnames'
import {connect} from 'react-redux'
// Components
import {SparkleSpinner} from '@influxdata/clockface'
// Types
import {RemoteDataState} from 'src/types'
import {AppState} from 'src/types'
interface StateProps {
status: RemoteDataState
errorMessage: string
}
type Props = StateProps
export class StatusIndicator extends PureComponent<Props> {
public render() {
const {status} = this.props
return (
<div className="line-protocol--spinner">
<p data-testid="line-protocol--status" className={this.statusClassName}>
{this.statusText.status}
</p>
<SparkleSpinner loading={status} sizePixels={220} />
<p className={this.statusClassName}>{this.statusText.message}</p>
</div>
)
}
private get statusClassName(): string {
const {status} = this.props
return classnames(`line-protocol--status`, {
loading: status === RemoteDataState.Loading,
success: status === RemoteDataState.Done,
error: status === RemoteDataState.Error,
})
}
private get statusText() {
let status = ''
let message = ''
switch (this.props.status) {
case RemoteDataState.Loading:
status = 'Loading...'
message = 'Just a moment'
break
case RemoteDataState.Done:
status = 'Data Written Successfully'
message = 'Hooray!'
break
case RemoteDataState.Error:
status = 'Unable to Write Data'
message = `Error: ${this.props.errorMessage}`
break
}
return {
status,
message,
}
}
}
const mstp = ({
dataLoading: {
dataLoaders: {lpStatus, lpError},
},
}: AppState) => ({
status: lpStatus,
errorMessage: lpError,
})
export default connect<StateProps, {}, {}>(mstp, null)(StatusIndicator)

View File

@ -16,24 +16,16 @@ import {validateURI} from 'src/shared/utils/validateURI'
import {Action} from 'src/dataLoaders/actions/dataLoaders'
import {
DataLoaderType,
LineProtocolTab,
DataLoadersState,
ConfigurationState,
ConfigFieldType,
Plugin,
} from 'src/types/dataLoaders'
import {RemoteDataState} from 'src/types'
import {WritePrecision} from '@influxdata/influx'
import {QUICKSTART_SCRAPER_TARGET_URL} from 'src/dataLoaders/constants/pluginConfigs'
export const INITIAL_STATE: DataLoadersState = {
telegrafPlugins: [],
type: DataLoaderType.Empty,
lineProtocolBody: '',
activeLPTab: LineProtocolTab.UploadFile,
lpStatus: RemoteDataState.NotStarted,
lpError: '',
precision: WritePrecision.Ns,
telegrafConfigID: null,
pluginBundles: [],
scraperTarget: {
@ -315,35 +307,6 @@ export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
id,
},
}
case 'SET_LINE_PROTOCOL_BODY':
return {
...state,
lineProtocolBody: action.payload.lineProtocolBody,
}
case 'SET_ACTIVE_LP_TAB':
return {
...state,
activeLPTab: action.payload.activeLPTab,
}
case 'SET_LP_STATUS':
const {lpStatus, lpError} = action.payload
if (lpStatus === RemoteDataState.Error) {
return {
...state,
lpStatus,
lpError,
}
}
return {
...state,
lpStatus,
lpError: '',
}
case 'SET_PRECISION':
return {
...state,
precision: action.payload.precision,
}
case 'SET_TOKEN':
return {
...state,

View File

@ -4,110 +4,113 @@
*/
.drag-and-drop {
border: 2px dashed $g6-smoke;
border-radius: 3px;
width: 100%;
height: 100%;
transition: background-color 0.25s ease, border-color 0.25s ease;
align-content: center;
align-items: center;
justify-content: center;
border: 2px dashed $g6-smoke;
border-radius: 3px;
width: 100%;
height: 100%;
transition: background-color 0.25s ease, border-color 0.25s ease;
align-content: center;
align-items: center;
justify-content: center;
}
.drag-and-drop--form {
position: relative;
z-index: $z--drag-n-drop;
background-color: $g2-kevlar;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
padding: 30px 18px;
color: $g6-smoke;
width: 100%;
height: 100%;
}
input[type='file'].drag-and-drop--input {
display: none;
}
.drag-and-drop--graphic {
position: relative;
z-index: $z--drag-n-drop;
background-color: $g2-kevlar;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
padding: 30px 18px;
color: $g6-smoke;
width: 100%;
height: 100%;
}
input[type='file'].drag-and-drop--input {
display: none;
}
.drag-and-drop--graphic {
background-image: url('../../assets/images/drag-n-drop.svg');
background-size: 100% 100%;
background-position: center center;
width: 90px;
height: 90px;
color: $g6-smoke;
&.success {
background-image: url('../../assets/images/drag-n-drop.svg');
background-size: 100% 100%;
background-position: center center;
width: 90px;
height: 90px;
color: $g6-smoke;
&.success {
background-image: url('../../assets/images/drag-n-drop.svg');
}
}
.drag-and-drop--header {
@include no-user-select();
width: 100%;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 0 0 30px 0;
font-size: 20px;
font-weight: 400;
&.empty {
color: $g6-smoke;
}
&.selected {
color: $c-rainforest;
}
}
.drag-and-drop--header {
@include no-user-select();
width: 100%;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 0 0 30px 0;
font-size: 20px;
font-weight: 400;
&.empty {
color: $g6-smoke;
}
.drag-and-drop--buttons {
display: flex;
align-items: center;
flex-wrap: nowrap;
margin-top: 18px;
> button {
margin: 0 4px;
}
&.selected {
color: $c-rainforest;
}
/*
&.error {
color: $c-fire;
}
}
.drag-and-drop--buttons {
display: flex;
align-items: center;
flex-wrap: nowrap;
margin-top: 18px;
> button {
margin: 0 4px;
}
}
/*
Styles for hover state and drag-over state look the same
------------------------------------------------------------------------------
*/
.drag-and-drop--form.active:hover,
.drag-and-drop.drag-over .drag-and-drop--form {
cursor: pointer;
background-color: $g4-onyx;
border-color: $g6-smoke;
}
/*
.drag-and-drop--form.active:hover,
.drag-and-drop.drag-over .drag-and-drop--form {
cursor: pointer;
background-color: $g4-onyx;
border-color: $g6-smoke;
}
/*
Compact display mode
------------------------------------------------------------------------------
*/
.drag-and-drop.compact .drag-and-drop--form {
flex-direction: row;
.drag-and-drop--graphic,
.drag-and-drop--buttons {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.drag-and-drop--graphic {
left: 20px;
width: 50px;
height: 50px;
}
.drag-and-drop--header {
font-size: 15px;
margin-bottom: 0;
margin-right: 80px;
margin-left: 80px;
word-break: break-all;
white-space: pre-wrap;
}
.drag-and-drop--buttons {
margin-top: 0;
right: 20px;
flex-direction: column;
align-items: stretch;
> button {
margin: 2px 0;
}
.drag-and-drop.compact .drag-and-drop--form {
flex-direction: row;
.drag-and-drop--graphic,
.drag-and-drop--buttons {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.drag-and-drop--graphic {
left: 20px;
width: 50px;
height: 50px;
}
.drag-and-drop--header {
font-size: 15px;
margin-bottom: 0;
margin-right: 80px;
margin-left: 80px;
word-break: break-all;
white-space: pre-wrap;
}
.drag-and-drop--buttons {
margin-top: 0;
right: 20px;
flex-direction: column;
align-items: stretch;
> button {
margin: 2px 0;
}
}
}

View File

@ -71,6 +71,7 @@ class DragAndDrop extends PureComponent<Props, State> {
<div className={this.infoClass} />
<input
type="file"
data-testid="drag-and-drop--input"
ref={r => (this.fileInput = r)}
className="drag-and-drop--input"
accept={this.fileTypesToAccept}
@ -183,7 +184,7 @@ class DragAndDrop extends PureComponent<Props, State> {
}
private handleFileClick = (e: any): void => {
const file = e.currentTarget.files[0]
const file: File = e.currentTarget.files[0]
if (!file) {
return

View File

@ -5,12 +5,36 @@ export const FROM: FluxToolbarFunction = {
args: [
{
name: 'bucket',
desc: 'The name of the bucket to query.',
desc: 'Name of the bucket to query.',
type: 'String',
},
{
name: 'bucketID',
desc: 'The string-encoded ID of the bucket to query.',
desc: 'String-encoded ID of the bucket to query.',
type: 'String',
},
{
name: 'host',
desc:
'URL of the InfluxDB instance to query (only required when querying a different organization or remote InfluxDB instance).',
type: 'String',
},
{
name: 'org',
desc:
'Organization name (only required when querying a different organization or remote InfluxDB instance).',
type: 'String',
},
{
name: 'orgID',
desc:
'String-encoded organization ID (only required when querying a different organization or remote InfluxDB instance).',
type: 'String',
},
{
name: 'token',
desc:
'InfluxDB authentication token (only required when querying a different organization or remote InfluxDB instance).',
type: 'String',
},
],
@ -29,12 +53,12 @@ export const RANGE: FluxToolbarFunction = {
{
name: 'start',
desc: 'The earliest time to include in results.',
type: 'Duration | Time',
type: 'Duration | Time | Integer',
},
{
name: 'stop',
desc: 'The latest time to include in results. Defaults to `now()`.',
type: 'Duration | Time',
type: 'Duration | Time | Integer',
},
],
package: '',
@ -172,7 +196,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
name: 'unit',
desc:
'Time duration to use when calculating the rate. Defaults to `1s`.',
type: 'Array of Strings',
type: 'Duration',
},
],
package: 'experimental/aggregate',
@ -226,6 +250,23 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/built-in/transformations/aggregates/aggregatewindow/',
},
{
name: 'array.from',
args: [
{
name: 'rows',
desc: 'Array of records to construct a table with.',
type: 'Array of Objects',
},
],
package: 'experimental/array',
desc: 'Constructs a table from an array of objects.',
example:
'array.from(rows: [{_time: 2020-01-01T00:00:00Z, _value: "foo"},{_time: 2020-01-02T00:00:00Z, _value: "bar"}])',
category: 'Inputs',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/array/from/',
},
{
name: 'bigtable.from',
args: [
@ -526,7 +567,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -542,7 +583,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -559,7 +600,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -576,7 +617,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -593,7 +634,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -609,7 +650,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -626,7 +667,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -643,7 +684,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -660,7 +701,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -677,7 +718,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
{
name: 'unit',
@ -700,7 +741,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -717,7 +758,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -734,7 +775,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -750,7 +791,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 't',
desc: 'The time to operate on.',
type: 'Time | Duration | Integer',
type: 'Time | Duration',
},
],
package: 'date',
@ -1343,12 +1384,6 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
desc: 'S2 Cell level used in `s2_cell_id` tag. Default is `-1`.',
type: 'Integer',
},
{
name: 'correlationKey',
desc:
'List of columns used to uniquely identify a row for output. Default is `["_time"]`.',
type: 'Array of Strings',
},
{
name: 'strict',
desc: 'Enable strict geographic data filtering. Default is `true`',
@ -1460,6 +1495,22 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/s2cellidtoken/',
},
{
name: 'geo.s2CellLatLon',
args: [
{
name: 'token',
desc: 'S2 cell ID token.',
type: 'String',
},
],
package: 'experimental/geo',
desc: 'Returns the latitude and longitude of the center of an S2 cell.',
example: 'geo.s2CellLatLon(token: "89c284")',
category: 'Transformations',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/s2celllatlon/',
},
{
name: 'geo.shapeData',
args: [
@ -1478,12 +1529,6 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
desc: 'S2 cell level to use when generating the S2 cell ID token.',
type: 'Integer',
},
{
name: 'correlationKey',
desc:
'List of columns used to uniquely identify a row for output. Default is `["_time"]`.',
type: 'Array of Strings',
},
],
package: 'experimental/geo',
desc:
@ -1494,6 +1539,131 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/shapedata/',
},
{
name: 'geo.ST_Contains',
args: [
{
name: 'region',
desc: 'Region to test.',
type: 'Object',
},
{
name: 'geometry',
desc:
'GIS geometry to test. Can be either point or linestring geometry.',
type: 'Object',
},
],
package: 'experimental/geo',
desc: 'Tests if the region contains the GIS geometry.',
example:
'geo.ST_Contains(region: {lat: 40.7, lon: -73.3, radius: 20.0}, geometry: {lon: 39.7515, lat: 15.08433})',
category: 'Tests',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/st_contains/',
},
{
name: 'geo.ST_Distance',
args: [
{
name: 'region',
desc: 'Region to test.',
type: 'Object',
},
{
name: 'geometry',
desc:
'GIS geometry to test. Can be either point or linestring geometry.',
type: 'Object',
},
],
package: 'experimental/geo',
desc: 'Returns the distance between the region and GIS geometry.',
example:
'geo.ST_Distance(region: {lat: 40.7, lon: -73.3, radius: 20.0}, geometry: {lon: 39.7515, lat: 15.08433})',
category: 'Transformations',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/st_distance/',
},
{
name: 'geo.ST_DWithin',
args: [
{
name: 'region',
desc: 'Region to test.',
type: 'Object',
},
{
name: 'geometry',
desc:
'GIS geometry to test. Can be either point or linestring geometry.',
type: 'Object',
},
{
name: 'distance',
desc: 'Maximum distance allowed between the region and geometry.',
type: 'Float',
},
],
package: 'experimental/geo',
desc: 'Tests if a region is within a specified distance from GIS geometry.',
example:
'geo.ST_DWithin(region: {lat: 40.7, lon: -73.3, radius: 20.0}, geometry: {lon: 39.7515, lat: 15.08433}, distance: 1000.0)',
category: 'Tests',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/st_dwithin/',
},
{
name: 'geo.ST_Intersects',
args: [
{
name: 'region',
desc: 'Region to test.',
type: 'Object',
},
{
name: 'geometry',
desc:
'GIS geometry to test. Can be either point or linestring geometry.',
type: 'Object',
},
],
package: 'experimental/geo',
desc: 'Tests if a region intersects with GIS geometry.',
example:
'geo.ST_Intersects(region: {lat: 40.7, lon: -73.3, radius: 20.0}, geometry: {linestring: "39.7515 14.01433, 38.3527 13.9228, 36.9978 15.08433"})',
category: 'Tests',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/st_intersects/',
},
{
name: 'geo.ST_Length',
args: [
{
name: 'geometry',
desc:
'GIS geometry to test. Can be either point or linestring geometry.',
type: 'Object',
},
],
package: 'experimental/geo',
desc: 'Returns the spherical length of GIS geometry.',
example:
'geo.ST_Length(geometry: {linestring: "39.7515 14.01433, 38.3527 13.9228, 36.9978 15.08433"})',
category: 'Transformations',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/st_length/',
},
{
name: 'geo.ST_LineString',
args: [],
package: 'experimental/geo',
desc: 'Converts a series of geographic points into linestring',
example: 'geo.ST_LineString()',
category: 'Transformations',
link:
'https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/st_linestring/',
},
{
name: 'geo.strictFilter',
args: [
@ -1513,14 +1683,7 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
},
{
name: 'geo.toRows',
args: [
{
name: 'correlationKey',
desc:
'List of columns used to uniquely identify a row for output. Default is `["_time"]`.',
type: 'Array of Strings',
},
],
args: [],
package: 'experimental/geo',
desc:
'Pivots geo-temporal data into row-wise sets based on time and other correlation columns.',
@ -2093,12 +2256,6 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
'A list of columns from which values are extracted. All columns indicated must be of the same type.',
type: 'Array of Strings',
},
{
name: 'fn',
desc:
'Function used to identify a set of columns. All columns indicated must be of the same type.',
type: 'Function',
},
],
package: '',
desc:
@ -3644,12 +3801,12 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 'start',
desc: 'The earliest time to include in results.',
type: 'Duration | Time',
type: 'Duration | Time | Integer',
},
{
name: 'stop',
desc: 'The latest time to include in results. Defaults to `now()`.',
type: 'Duration | Time',
type: 'Duration | Time | Integer',
},
],
package: 'experimental/query',
@ -3671,12 +3828,12 @@ export const FLUX_FUNCTIONS: FluxToolbarFunction[] = [
{
name: 'start',
desc: 'The earliest time to include in results.',
type: 'Duration | Time',
type: 'Duration | Time | Integer',
},
{
name: 'stop',
desc: 'The latest time to include in results. Defaults to `now()`.',
type: 'Duration | Time',
type: 'Duration | Time | Integer',
},
{
name: 'measurement',

View File

@ -14,3 +14,12 @@ export interface DemoBucket extends Omit<OwnBucket, 'type'> {
export type Bucket = DemoBucket | OwnBucket
export type RetentionRule = GenBucket['retentionRules'][0]
export type LineProtocolTab = 'Upload File' | 'Enter Manually'
export enum WritePrecision {
Ms = 'ms',
S = 's',
Us = 'us',
Ns = 'ns',
}

View File

@ -33,8 +33,6 @@ import {
TelegrafPluginOutputFileConfig,
TelegrafPluginOutputInfluxDBV2Config,
} from '@influxdata/influx'
import {RemoteDataState} from 'src/types'
import {WritePrecision} from '@influxdata/influx'
export enum DataLoaderStep {
'Configure',
@ -62,12 +60,7 @@ export interface DataLoadersState {
telegrafPlugins: TelegrafPlugin[]
pluginBundles: BundleName[]
type: DataLoaderType
activeLPTab: LineProtocolTab
telegrafConfigID: string
lpStatus: RemoteDataState
lpError: string
lineProtocolBody: string
precision: WritePrecision
scraperTarget: ScraperTarget
telegrafConfigName: string
telegrafConfigDescription: string
@ -83,7 +76,6 @@ export enum ConfigurationState {
export enum DataLoaderType {
CSV = 'CSV',
Streaming = 'Streaming',
LineProtocol = 'Line Protocol',
ClientLibrary = 'Client Library',
Scraping = 'Scraping',
Empty = '',
@ -165,12 +157,6 @@ export type TelegrafPluginName =
| TelegrafPluginOutputFile.NameEnum.File
| TelegrafPluginOutputInfluxDBV2.NameEnum.InfluxdbV2
export enum LineProtocolTab {
UploadFile = 'Upload File',
EnterManually = 'Enter Manually',
EnterURL = 'Enter URL',
}
export enum LineProtocolStatus {
ImportData = 'importData',
Loading = 'loading',

View File

@ -1,5 +1,6 @@
// function definitions
import {Source} from 'src/types'
export type OnDeleteFuncNode = (ids: DeleteFuncNodeArgs) => void
export type OnChangeArg = (inputArg: InputArg) => void
export type OnAddNode = (

View File

@ -703,7 +703,7 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@cypress/listr-verbose-renderer@0.4.1":
"@cypress/listr-verbose-renderer@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a"
integrity sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=
@ -713,7 +713,7 @@
date-fns "^1.27.2"
figures "^1.7.0"
"@cypress/request@2.88.5":
"@cypress/request@^2.88.5":
version "2.88.5"
resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.5.tgz#8d7ecd17b53a849cfd5ab06d5abe7d84976375d7"
integrity sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==
@ -739,7 +739,7 @@
tunnel-agent "^0.6.0"
uuid "^3.3.2"
"@cypress/xvfb@1.2.4":
"@cypress/xvfb@^1.2.4":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a"
integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==
@ -762,10 +762,10 @@
resolved "https://registry.yarnpkg.com/@influxdata/flux/-/flux-0.5.1.tgz#e39e7a7af9163fc9494422c8fed77f3ae1b68f56"
integrity sha512-GHlkXBhSdJ2m56JzDkbnKPAqLj3/lexPooacu14AWTO4f2sDGLmzM7r0AxgdtU1M2x7EXNBwgGOI5EOAdN6mkw==
"@influxdata/giraffe@0.23.0":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@influxdata/giraffe/-/giraffe-0.23.0.tgz#bde0dbff3497a6cf7cf2de54ed22d63377e1975f"
integrity sha512-o4y6Y4Aw4V1LAu4EqA4e/8LFgXuLc+dZVtK+nfWUupQnOHGNPvoHbfDQeniPZzRM3vkcmC8cSDZtuBdW24DVzg==
"@influxdata/giraffe@0.24.0":
version "0.24.0"
resolved "https://registry.yarnpkg.com/@influxdata/giraffe/-/giraffe-0.24.0.tgz#d48eb242a1af7f3adfeac9eb4b12c10de4f5919b"
integrity sha512-t5t75gX/zO2hUaY7xsRFc/QzyvZzc29z5+J1BmInS1n/Ytb7+1vU7JalwAZrG7UnuPmKj/S4RYh0FMEaWRwCoQ==
"@influxdata/influx@0.5.5":
version "0.5.5"
@ -1274,12 +1274,12 @@
resolved "https://registry.yarnpkg.com/@types/shallowequal/-/shallowequal-1.1.1.tgz#aad262bb3f2b1257d94c71d545268d592575c9b1"
integrity sha512-Lhni3aX80zbpdxRuWhnuYPm8j8UQaa571lHP/xI4W+7BAFhSIhRReXnqjEgT/XzPoXZTJkCqstFMJ8CZTK6IlQ==
"@types/sinonjs__fake-timers@6.0.1":
"@types/sinonjs__fake-timers@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e"
integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==
"@types/sizzle@2.3.2":
"@types/sizzle@^2.3.2":
version "2.3.2"
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
@ -1831,10 +1831,10 @@ aproba@^1.1.1:
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
arch@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e"
integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==
arch@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.2.tgz#0c52bbe7344bb4fa260c443d2cbad9c00ff2f0bf"
integrity sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==
arg@^4.1.0:
version "4.1.1"
@ -1981,7 +1981,7 @@ async@^2.5.0, async@^2.6.2:
dependencies:
lodash "^4.17.14"
async@^3.1.0:
async@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
@ -2212,7 +2212,7 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
bluebird@3.7.2, bluebird@^3.5.5:
bluebird@^3.5.5, bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
@ -2541,7 +2541,7 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
cachedir@2.3.0:
cachedir@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8"
integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==
@ -2710,7 +2710,7 @@ charenc@~0.0.1:
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
check-more-types@2.24.0:
check-more-types@^2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=
@ -2884,7 +2884,7 @@ cli-cursor@^3.1.0:
dependencies:
restore-cursor "^3.1.0"
cli-table3@0.5.1:
cli-table3@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"
integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==
@ -3060,11 +3060,6 @@ commander@2.8.x:
dependencies:
graceful-readlink ">= 1.0.0"
commander@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83"
integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw==
commander@^2.12.1, commander@^2.18.0, commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -3075,6 +3070,11 @@ commander@^2.7.1, commander@~2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
commander@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
commander@~2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
@ -3087,7 +3087,7 @@ commander@~2.9.0:
dependencies:
graceful-readlink ">= 1.0.0"
common-tags@1.8.0:
common-tags@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
@ -3624,48 +3624,48 @@ cypress-plugin-tab@^1.0.5:
dependencies:
ally.js "^1.4.1"
cypress@4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.7.0.tgz#3ea29bddaf9a1faeaa5b8d54b60a84ed1cafa83d"
integrity sha512-Vav6wUFhPRlImIND/2lOQlUnAWzgCC/iXyJlJjX9nJOJul5LC1vUpf/m8Oiae870PFPyT0ZLLwPHKTXZNdXmHw==
cypress@4.12.1:
version "4.12.1"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.12.1.tgz#0ead1b9f4c0917d69d8b57f996b6e01fe693b6ec"
integrity sha512-9SGIPEmqU8vuRA6xst2CMTYd9sCFCxKSzrHt0wr+w2iAQMCIIsXsQ5Gplns1sT6LDbZcmLv6uehabAOl3fhc9Q==
dependencies:
"@cypress/listr-verbose-renderer" "0.4.1"
"@cypress/request" "2.88.5"
"@cypress/xvfb" "1.2.4"
"@types/sinonjs__fake-timers" "6.0.1"
"@types/sizzle" "2.3.2"
arch "2.1.1"
bluebird "3.7.2"
cachedir "2.3.0"
chalk "2.4.2"
check-more-types "2.24.0"
cli-table3 "0.5.1"
commander "4.1.0"
common-tags "1.8.0"
debug "4.1.1"
eventemitter2 "4.1.2"
execa "1.0.0"
executable "4.1.1"
extract-zip "1.7.0"
fs-extra "8.1.0"
getos "3.1.4"
is-ci "2.0.0"
is-installed-globally "0.1.0"
lazy-ass "1.6.0"
listr "0.14.3"
lodash "4.17.15"
log-symbols "3.0.0"
minimist "1.2.5"
moment "2.24.0"
ospath "1.2.2"
pretty-bytes "5.3.0"
ramda "0.26.1"
request-progress "3.0.0"
supports-color "7.1.0"
tmp "0.1.0"
untildify "4.0.0"
url "0.11.0"
yauzl "2.10.0"
"@cypress/listr-verbose-renderer" "^0.4.1"
"@cypress/request" "^2.88.5"
"@cypress/xvfb" "^1.2.4"
"@types/sinonjs__fake-timers" "^6.0.1"
"@types/sizzle" "^2.3.2"
arch "^2.1.2"
bluebird "^3.7.2"
cachedir "^2.3.0"
chalk "^2.4.2"
check-more-types "^2.24.0"
cli-table3 "~0.5.1"
commander "^4.1.1"
common-tags "^1.8.0"
debug "^4.1.1"
eventemitter2 "^6.4.2"
execa "^1.0.0"
executable "^4.1.1"
extract-zip "^1.7.0"
fs-extra "^8.1.0"
getos "^3.2.1"
is-ci "^2.0.0"
is-installed-globally "^0.3.2"
lazy-ass "^1.6.0"
listr "^0.14.3"
lodash "^4.17.19"
log-symbols "^3.0.0"
minimist "^1.2.5"
moment "^2.27.0"
ospath "^1.2.2"
pretty-bytes "^5.3.0"
ramda "~0.26.1"
request-progress "^3.0.0"
supports-color "^7.1.0"
tmp "~0.1.0"
untildify "^4.0.0"
url "^0.11.0"
yauzl "^2.10.0"
d3-array@^1.2.0:
version "1.2.4"
@ -3763,13 +3763,6 @@ debug@3.1.0, debug@=3.1.0:
dependencies:
ms "2.0.0"
debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@ -3777,6 +3770,13 @@ debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5:
dependencies:
ms "^2.1.1"
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
decamelize@^1.0.0, decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@ -4530,10 +4530,10 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter2@4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-4.1.2.tgz#0e1a8477af821a6ef3995b311bf74c23a5247f15"
integrity sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU=
eventemitter2@^6.4.2:
version "6.4.3"
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820"
integrity sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==
eventemitter3@^3.0.0:
version "3.1.2"
@ -4570,7 +4570,7 @@ exec-sh@^0.3.2:
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b"
integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==
execa@1.0.0, execa@^1.0.0:
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
@ -4583,7 +4583,7 @@ execa@1.0.0, execa@^1.0.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
executable@4.1.1:
executable@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c"
integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==
@ -4747,7 +4747,7 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
extract-zip@1.7.0:
extract-zip@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
@ -5110,7 +5110,7 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-extra@8.1.0:
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
@ -5200,12 +5200,12 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
getos@3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.4.tgz#29cdf240ed10a70c049add7b6f8cb08c81876faf"
integrity sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw==
getos@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5"
integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==
dependencies:
async "^3.1.0"
async "^3.2.0"
getpass@^0.1.1:
version "0.1.7"
@ -5270,12 +5270,12 @@ glob@^7.1.1, glob@^7.1.2:
once "^1.3.0"
path-is-absolute "^1.0.0"
global-dirs@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=
global-dirs@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201"
integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==
dependencies:
ini "^1.3.4"
ini "^1.3.5"
global-modules@2.0.0:
version "2.0.0"
@ -6103,7 +6103,7 @@ is-callable@^1.1.5:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
is-ci@2.0.0, is-ci@^2.0.0:
is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
@ -6227,13 +6227,13 @@ is-hexadecimal@^1.0.0:
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835"
integrity sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==
is-installed-globally@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80"
integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=
is-installed-globally@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==
dependencies:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
global-dirs "^2.0.1"
is-path-inside "^3.0.1"
is-number-object@^1.0.3:
version "1.0.3"
@ -6276,13 +6276,6 @@ is-path-in-cwd@^2.0.0:
dependencies:
is-path-inside "^2.1.0"
is-path-inside@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
integrity sha1-jvW33lBDej/cprToZe96pVy0gDY=
dependencies:
path-is-inside "^1.0.1"
is-path-inside@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2"
@ -6290,6 +6283,11 @@ is-path-inside@^2.1.0:
dependencies:
path-is-inside "^1.0.2"
is-path-inside@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017"
integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@ -7122,7 +7120,7 @@ last-call-webpack-plugin@^3.0.0:
lodash "^4.17.5"
webpack-sources "^1.1.0"
lazy-ass@1.6.0:
lazy-ass@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM=
@ -7191,7 +7189,7 @@ listr-verbose-renderer@^0.5.0:
date-fns "^1.27.2"
figures "^2.0.0"
listr@0.14.3:
listr@^0.14.3:
version "0.14.3"
resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586"
integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==
@ -7333,22 +7331,20 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@4.17.15, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
lodash@^4.15.0, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
log-symbols@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
dependencies:
chalk "^2.4.2"
lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
lodash@^4.17.19:
version "4.17.19"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
log-symbols@^1.0.2:
version "1.0.2"
@ -7357,6 +7353,13 @@ log-symbols@^1.0.2:
dependencies:
chalk "^1.0.0"
log-symbols@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
dependencies:
chalk "^2.4.2"
log-update@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
@ -7666,16 +7669,16 @@ minimist@0.0.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
minimist@1.2.5, minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimist@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimist@~0.0.1:
version "0.0.10"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
@ -7790,16 +7793,16 @@ mocha@^5.2.0:
mkdirp "0.5.1"
supports-color "5.4.0"
moment@2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
moment@^2.13.0, moment@^2.8.2:
version "2.22.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=
moment@^2.27.0:
version "2.27.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
monaco-editor-textmate@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/monaco-editor-textmate/-/monaco-editor-textmate-2.2.1.tgz#93f3f1932061dd2311b92a42ea1c027cfeb3e439"
@ -8390,7 +8393,7 @@ os-tmpdir@~1.0.2:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
ospath@1.2.2:
ospath@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=
@ -8596,7 +8599,7 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-is-inside@^1.0.1, path-is-inside@^1.0.2:
path-is-inside@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
@ -9109,7 +9112,7 @@ prettier@^1.19.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
pretty-bytes@5.3.0:
pretty-bytes@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2"
integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==
@ -9359,7 +9362,7 @@ railroad-diagrams@^1.0.0:
resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=
ramda@0.26.1, ramda@^0.26:
ramda@^0.26, ramda@~0.26.1:
version "0.26.1"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
@ -9920,7 +9923,7 @@ replace-ext@1.0.0:
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
request-progress@3.0.0:
request-progress@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe"
integrity sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=
@ -10991,13 +10994,6 @@ supports-color@6.1.0, supports-color@^6.1.0:
dependencies:
has-flag "^3.0.0"
supports-color@7.1.0, supports-color@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
dependencies:
has-flag "^4.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@ -11017,6 +11013,13 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
supports-color@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
dependencies:
has-flag "^4.0.0"
svgo@^1.0.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.2.2.tgz#0253d34eccf2aed4ad4f283e11ee75198f9d7316"
@ -11202,13 +11205,6 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3:
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tmp@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877"
integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==
dependencies:
rimraf "^2.6.3"
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@ -11216,6 +11212,13 @@ tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
tmp@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877"
integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==
dependencies:
rimraf "^2.6.3"
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
@ -11677,7 +11680,7 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
untildify@4.0.0:
untildify@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
@ -11717,7 +11720,7 @@ url-parse@^1.4.3:
querystringify "^2.1.1"
requires-port "^1.0.0"
url@0.11.0, url@^0.11.0:
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
@ -12386,7 +12389,7 @@ yargs@~3.10.0:
decamelize "^1.0.0"
window-size "0.1.0"
yauzl@2.10.0, yauzl@^2.10.0:
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=

View File

@ -1,4 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1