Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
384e11fd
Commit
384e11fd
authored
Mar 18, 2019
by
Peter Holmberg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Copied from new timepicker and unified component branch
parent
c0eb1402
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
40 additions
and
187 deletions
+40
-187
packages/grafana-ui/src/components/Input/Input.test.tsx
+5
-7
packages/grafana-ui/src/components/Input/Input.tsx
+14
-26
packages/grafana-ui/src/components/Input/__snapshots__/Input.test.tsx.snap
+0
-0
packages/grafana-ui/src/components/index.ts
+1
-0
packages/grafana-ui/src/types/forms.ts
+0
-26
packages/grafana-ui/src/types/index.ts
+1
-1
packages/grafana-ui/src/types/input.ts
+0
-0
packages/grafana-ui/src/utils/validate.ts
+17
-8
public/app/core/components/Form/Input.tsx
+0
-94
public/app/core/components/Form/index.ts
+0
-1
public/app/core/utils/validate.ts
+0
-16
public/app/features/dashboard/panel_editor/QueryOptions.tsx
+2
-7
public/app/types/index.ts
+0
-1
No files found.
p
ublic/app/core/components/Form
/Input.test.tsx
→
p
ackages/grafana-ui/src/components/Input
/Input.test.tsx
View file @
384e11fd
import
React
from
'react'
;
import
React
from
'react'
;
import
renderer
from
'react-test-renderer'
;
import
renderer
from
'react-test-renderer'
;
import
{
shallow
}
from
'enzyme'
;
import
{
shallow
}
from
'enzyme'
;
import
{
Input
,
EventsWithValidation
}
from
'./Input'
;
import
{
Input
}
from
'./Input'
;
import
{
ValidationEvents
}
from
'app/types'
;
import
{
EventsWithValidation
}
from
'../../utils'
;
import
{
ValidationEvents
}
from
'../../types'
;
const
TEST_ERROR_MESSAGE
=
'Value must be empty or less than 3 chars'
;
const
TEST_ERROR_MESSAGE
=
'Value must be empty or less than 3 chars'
;
const
testBlurValidation
:
ValidationEvents
=
{
const
testBlurValidation
:
ValidationEvents
=
{
[
EventsWithValidation
.
onBlur
]:
[
[
EventsWithValidation
.
onBlur
]:
[
{
{
rule
:
(
value
:
string
)
=>
{
rule
:
(
value
:
string
)
=>
{
if
(
!
value
||
value
.
length
<
3
)
{
return
!
value
||
value
.
length
<
3
;
return
true
;
}
return
false
;
},
},
errorMessage
:
TEST_ERROR_MESSAGE
,
errorMessage
:
TEST_ERROR_MESSAGE
,
},
},
...
...
packages/grafana-ui/src/components/Input/Input.tsx
View file @
384e11fd
import
React
,
{
PureComponent
}
from
'react'
;
import
React
,
{
PureComponent
,
ChangeEvent
}
from
'react'
;
import
classNames
from
'classnames'
;
import
classNames
from
'classnames'
;
import
{
ValidationEvents
,
ValidationRule
}
from
'../../types/forms'
;
import
{
validate
,
EventsWithValidation
,
hasValidationEvent
}
from
'../../utils'
;
import
{
ValidationEvents
,
ValidationRule
}
from
'../../types'
;
export
enum
InputStatus
{
export
enum
InputStatus
{
Invalid
=
'invalid'
,
Invalid
=
'invalid'
,
Valid
=
'valid'
,
Valid
=
'valid'
,
}
}
export
enum
InputTypes
{
Text
=
'text'
,
Number
=
'number'
,
Password
=
'password'
,
Email
=
'email'
,
}
export
enum
EventsWithValidation
{
onBlur
=
'onBlur'
,
onFocus
=
'onFocus'
,
onChange
=
'onChange'
,
}
interface
Props
extends
React
.
HTMLProps
<
HTMLInputElement
>
{
interface
Props
extends
React
.
HTMLProps
<
HTMLInputElement
>
{
validationEvents
?:
ValidationEvents
;
validationEvents
?:
ValidationEvents
;
hideErrorMessage
?:
boolean
;
hideErrorMessage
?:
boolean
;
...
@@ -27,7 +15,7 @@ interface Props extends React.HTMLProps<HTMLInputElement> {
...
@@ -27,7 +15,7 @@ interface Props extends React.HTMLProps<HTMLInputElement> {
// Override event props and append status as argument
// Override event props and append status as argument
onBlur
?:
(
event
:
React
.
FocusEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onBlur
?:
(
event
:
React
.
FocusEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onFocus
?:
(
event
:
React
.
FocusEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onFocus
?:
(
event
:
React
.
FocusEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onChange
?:
(
event
:
React
.
Form
Event
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onChange
?:
(
event
:
React
.
Change
Event
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
}
}
export
class
Input
extends
PureComponent
<
Props
>
{
export
class
Input
extends
PureComponent
<
Props
>
{
...
@@ -48,24 +36,24 @@ export class Input extends PureComponent<Props> {
...
@@ -48,24 +36,24 @@ export class Input extends PureComponent<Props> {
}
}
validatorAsync
=
(
validationRules
:
ValidationRule
[])
=>
{
validatorAsync
=
(
validationRules
:
ValidationRule
[])
=>
{
return
evt
=>
{
return
(
evt
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
errors
=
validate
(
evt
.
target
.
value
,
validationRules
);
const
errors
=
validate
(
evt
.
target
.
value
,
validationRules
);
this
.
setState
(
prevState
=>
{
this
.
setState
(
prevState
=>
{
return
{
return
{
...
prevState
,
error
:
errors
?
errors
[
0
]
:
null
};
...
prevState
,
error
:
errors
?
errors
[
0
]
:
null
,
};
});
});
};
};
};
};
populateEventPropsWithStatus
=
(
restProps
,
validationEvents
:
ValidationEvents
)
=>
{
populateEventPropsWithStatus
=
(
restProps
:
any
,
validationEvents
:
ValidationEvents
|
undefined
)
=>
{
const
inputElementProps
=
{
...
restProps
};
const
inputElementProps
=
{
...
restProps
};
Object
.
keys
(
EventsWithValidation
).
forEach
((
eventName
:
EventsWithValidation
)
=>
{
if
(
!
validationEvents
)
{
if
(
hasValidationEvent
(
eventName
,
validationEvents
)
||
restProps
[
eventName
])
{
return
inputElementProps
;
inputElementProps
[
eventName
]
=
async
evt
=>
{
}
Object
.
keys
(
EventsWithValidation
).
forEach
(
eventName
=>
{
if
(
hasValidationEvent
(
eventName
as
EventsWithValidation
,
validationEvents
)
||
restProps
[
eventName
])
{
inputElementProps
[
eventName
]
=
async
(
evt
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
evt
.
persist
();
// Needed for async. https://reactjs.org/docs/events.html#event-pooling
evt
.
persist
();
// Needed for async. https://reactjs.org/docs/events.html#event-pooling
if
(
hasValidationEvent
(
eventName
,
validationEvents
))
{
if
(
hasValidationEvent
(
eventName
as
EventsWithValidation
,
validationEvents
))
{
await
this
.
validatorAsync
(
validationEvents
[
eventName
]).
apply
(
this
,
[
evt
]);
await
this
.
validatorAsync
(
validationEvents
[
eventName
]).
apply
(
this
,
[
evt
]);
}
}
if
(
restProps
[
eventName
])
{
if
(
restProps
[
eventName
])
{
...
...
p
ublic/app/core/components/Form
/__snapshots__/Input.test.tsx.snap
→
p
ackages/grafana-ui/src/components/Input
/__snapshots__/Input.test.tsx.snap
View file @
384e11fd
File moved
packages/grafana-ui/src/components/index.ts
View file @
384e11fd
...
@@ -25,6 +25,7 @@ export { ValueMappingsEditor } from './ValueMappingsEditor/ValueMappingsEditor';
...
@@ -25,6 +25,7 @@ export { ValueMappingsEditor } from './ValueMappingsEditor/ValueMappingsEditor';
export
{
Switch
}
from
'./Switch/Switch'
;
export
{
Switch
}
from
'./Switch/Switch'
;
export
{
EmptySearchResult
}
from
'./EmptySearchResult/EmptySearchResult'
;
export
{
EmptySearchResult
}
from
'./EmptySearchResult/EmptySearchResult'
;
export
{
UnitPicker
}
from
'./UnitPicker/UnitPicker'
;
export
{
UnitPicker
}
from
'./UnitPicker/UnitPicker'
;
export
{
Input
,
InputStatus
}
from
'./Input/Input'
;
// Visualizations
// Visualizations
export
{
Gauge
}
from
'./Gauge/Gauge'
;
export
{
Gauge
}
from
'./Gauge/Gauge'
;
...
...
packages/grafana-ui/src/types/forms.ts
deleted
100644 → 0
View file @
c0eb1402
export
enum
InputStatus
{
Invalid
=
'invalid'
,
Valid
=
'valid'
,
}
export
enum
InputTypes
{
Text
=
'text'
,
Number
=
'number'
,
Password
=
'password'
,
Email
=
'email'
,
}
export
enum
EventsWithValidation
{
onBlur
=
'onBlur'
,
onFocus
=
'onFocus'
,
onChange
=
'onChange'
,
}
export
interface
ValidationRule
{
rule
:
(
valueToValidate
:
string
)
=>
boolean
;
errorMessage
:
string
;
}
export
interface
ValidationEvents
{
[
eventName
:
string
]:
ValidationRule
[];
}
packages/grafana-ui/src/types/index.ts
View file @
384e11fd
...
@@ -5,4 +5,4 @@ export * from './plugin';
...
@@ -5,4 +5,4 @@ export * from './plugin';
export
*
from
'./datasource'
;
export
*
from
'./datasource'
;
export
*
from
'./theme'
;
export
*
from
'./theme'
;
export
*
from
'./threshold'
;
export
*
from
'./threshold'
;
export
*
from
'./
forms
'
;
export
*
from
'./
input
'
;
p
ublic/app/types/form
.ts
→
p
ackages/grafana-ui/src/types/input
.ts
View file @
384e11fd
File moved
packages/grafana-ui/src/utils/validate.ts
View file @
384e11fd
import
{
EventsWithValidation
,
ValidationEvents
,
ValidationRule
}
from
'../types'
;
import
{
ValidationRule
,
ValidationEvents
}
from
'../types/input'
;
export
enum
EventsWithValidation
{
onBlur
=
'onBlur'
,
onFocus
=
'onFocus'
,
onChange
=
'onChange'
,
}
export
const
validate
=
(
value
:
string
,
validationRules
:
ValidationRule
[])
=>
{
export
const
validate
=
(
value
:
string
,
validationRules
:
ValidationRule
[])
=>
{
const
errors
=
validationRules
.
reduce
((
acc
,
currentRule
)
=>
{
const
errors
=
validationRules
.
reduce
(
if
(
!
currentRule
.
rule
(
value
))
{
(
acc
,
currRule
)
=>
{
return
acc
.
concat
(
currentRule
.
errorMessage
);
if
(
!
currRule
.
rule
(
value
))
{
}
return
acc
.
concat
(
currRule
.
errorMessage
);
return
acc
;
}
},
[]);
return
acc
;
},
[]
as
string
[]
);
return
errors
.
length
>
0
?
errors
:
null
;
return
errors
.
length
>
0
?
errors
:
null
;
};
};
export
const
hasValidationEvent
=
(
event
:
EventsWithValidation
,
validationEvents
?:
ValidationEvents
)
=>
{
export
const
hasValidationEvent
=
(
event
:
EventsWithValidation
,
validationEvents
:
ValidationEvents
|
undefined
)
=>
{
return
validationEvents
&&
validationEvents
[
event
];
return
validationEvents
&&
validationEvents
[
event
];
};
};
public/app/core/components/Form/Input.tsx
deleted
100644 → 0
View file @
c0eb1402
import
React
,
{
PureComponent
}
from
'react'
;
import
classNames
from
'classnames'
;
import
{
ValidationEvents
,
ValidationRule
}
from
'app/types'
;
import
{
validate
,
hasValidationEvent
}
from
'app/core/utils/validate'
;
export
enum
InputStatus
{
Invalid
=
'invalid'
,
Valid
=
'valid'
,
}
export
enum
InputTypes
{
Text
=
'text'
,
Number
=
'number'
,
Password
=
'password'
,
Email
=
'email'
,
}
export
enum
EventsWithValidation
{
onBlur
=
'onBlur'
,
onFocus
=
'onFocus'
,
onChange
=
'onChange'
,
}
interface
Props
extends
React
.
HTMLProps
<
HTMLInputElement
>
{
validationEvents
?:
ValidationEvents
;
hideErrorMessage
?:
boolean
;
// Override event props and append status as argument
onBlur
?:
(
event
:
React
.
FocusEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onFocus
?:
(
event
:
React
.
FocusEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
onChange
?:
(
event
:
React
.
FormEvent
<
HTMLInputElement
>
,
status
?:
InputStatus
)
=>
void
;
}
export
class
Input
extends
PureComponent
<
Props
>
{
static
defaultProps
=
{
className
:
''
,
};
state
=
{
error
:
null
,
};
get
status
()
{
return
this
.
state
.
error
?
InputStatus
.
Invalid
:
InputStatus
.
Valid
;
}
get
isInvalid
()
{
return
this
.
status
===
InputStatus
.
Invalid
;
}
validatorAsync
=
(
validationRules
:
ValidationRule
[])
=>
{
return
evt
=>
{
const
errors
=
validate
(
evt
.
target
.
value
,
validationRules
);
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
error
:
errors
?
errors
[
0
]
:
null
,
};
});
};
};
populateEventPropsWithStatus
=
(
restProps
,
validationEvents
:
ValidationEvents
)
=>
{
const
inputElementProps
=
{
...
restProps
};
Object
.
keys
(
EventsWithValidation
).
forEach
((
eventName
:
EventsWithValidation
)
=>
{
if
(
hasValidationEvent
(
eventName
,
validationEvents
)
||
restProps
[
eventName
])
{
inputElementProps
[
eventName
]
=
async
evt
=>
{
evt
.
persist
();
// Needed for async. https://reactjs.org/docs/events.html#event-pooling
if
(
hasValidationEvent
(
eventName
,
validationEvents
))
{
await
this
.
validatorAsync
(
validationEvents
[
eventName
]).
apply
(
this
,
[
evt
]);
}
if
(
restProps
[
eventName
])
{
restProps
[
eventName
].
apply
(
null
,
[
evt
,
this
.
status
]);
}
};
}
});
return
inputElementProps
;
};
render
()
{
const
{
validationEvents
,
className
,
hideErrorMessage
,
...
restProps
}
=
this
.
props
;
const
{
error
}
=
this
.
state
;
const
inputClassName
=
classNames
(
'gf-form-input'
,
{
invalid
:
this
.
isInvalid
},
className
);
const
inputElementProps
=
this
.
populateEventPropsWithStatus
(
restProps
,
validationEvents
);
return
(
<
div
className=
"our-custom-wrapper-class"
>
<
input
{
...
inputElementProps
}
className=
{
inputClassName
}
/>
{
error
&&
!
hideErrorMessage
&&
<
span
>
{
error
}
</
span
>
}
</
div
>
);
}
}
public/app/core/components/Form/index.ts
deleted
100644 → 0
View file @
c0eb1402
export
{
Input
}
from
'./Input'
;
public/app/core/utils/validate.ts
deleted
100644 → 0
View file @
c0eb1402
import
{
ValidationRule
,
ValidationEvents
}
from
'app/types'
;
import
{
EventsWithValidation
}
from
'app/core/components/Form/Input'
;
export
const
validate
=
(
value
:
string
,
validationRules
:
ValidationRule
[])
=>
{
const
errors
=
validationRules
.
reduce
((
acc
,
currRule
)
=>
{
if
(
!
currRule
.
rule
(
value
))
{
return
acc
.
concat
(
currRule
.
errorMessage
);
}
return
acc
;
},
[]);
return
errors
.
length
>
0
?
errors
:
null
;
};
export
const
hasValidationEvent
=
(
event
:
EventsWithValidation
,
validationEvents
:
ValidationEvents
)
=>
{
return
validationEvents
&&
validationEvents
[
event
];
};
public/app/features/dashboard/panel_editor/QueryOptions.tsx
View file @
384e11fd
...
@@ -5,17 +5,12 @@ import React, { PureComponent, ChangeEvent, FocusEvent } from 'react';
...
@@ -5,17 +5,12 @@ import React, { PureComponent, ChangeEvent, FocusEvent } from 'react';
import
{
isValidTimeSpan
}
from
'app/core/utils/rangeutil'
;
import
{
isValidTimeSpan
}
from
'app/core/utils/rangeutil'
;
// Components
// Components
import
{
Switch
}
from
'@grafana/ui'
;
import
{
DataSourceSelectItem
,
EventsWithValidation
,
Input
,
InputStatus
,
Switch
,
ValidationEvents
}
from
'@grafana/ui'
;
import
{
Input
}
from
'app/core/components/Form'
;
import
{
EventsWithValidation
}
from
'app/core/components/Form/Input'
;
import
{
InputStatus
}
from
'app/core/components/Form/Input'
;
import
{
DataSourceOption
}
from
'./DataSourceOption'
;
import
{
DataSourceOption
}
from
'./DataSourceOption'
;
import
{
FormLabel
}
from
'@grafana/ui'
;
import
{
FormLabel
}
from
'@grafana/ui'
;
// Types
// Types
import
{
PanelModel
}
from
'../state/PanelModel'
;
import
{
PanelModel
}
from
'../state'
;
import
{
DataSourceSelectItem
}
from
'@grafana/ui/src/types'
;
import
{
ValidationEvents
}
from
'app/types'
;
const
timeRangeValidationEvents
:
ValidationEvents
=
{
const
timeRangeValidationEvents
:
ValidationEvents
=
{
[
EventsWithValidation
.
onBlur
]:
[
[
EventsWithValidation
.
onBlur
]:
[
...
...
public/app/types/index.ts
View file @
384e11fd
...
@@ -12,6 +12,5 @@ export * from './plugins';
...
@@ -12,6 +12,5 @@ export * from './plugins';
export
*
from
'./organization'
;
export
*
from
'./organization'
;
export
*
from
'./appNotifications'
;
export
*
from
'./appNotifications'
;
export
*
from
'./search'
;
export
*
from
'./search'
;
export
*
from
'./form'
;
export
*
from
'./explore'
;
export
*
from
'./explore'
;
export
*
from
'./store'
;
export
*
from
'./store'
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment