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
a8e184c0
Commit
a8e184c0
authored
Nov 30, 2018
by
Johannes Schill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
react-panel: Clean up input validation and increase code readability
parent
69ae3d2e
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
69 additions
and
60 deletions
+69
-60
public/app/core/components/Form/Input.tsx
+40
-50
public/app/core/utils/validate.ts
+11
-0
public/app/features/dashboard/dashgrid/QueriesTab.tsx
+11
-8
public/app/types/form.ts
+5
-1
public/app/types/index.ts
+2
-1
No files found.
public/app/core/components/Form/Input.tsx
View file @
a8e184c0
import
React
,
{
PureComponent
}
from
'react'
;
import
{
ValidationRule
}
from
'app/types'
;
import
{
ValidationEvents
,
ValidationRule
}
from
'app/types'
;
import
{
validate
}
from
'app/core/utils/validate'
;
export
enum
InputStatus
{
Default
=
'default'
,
Loading
=
'loading'
,
Invalid
=
'invalid'
,
Valid
=
'valid'
,
}
...
...
@@ -15,80 +14,71 @@ export enum InputTypes {
Email
=
'email'
,
}
interface
Props
{
status
?:
InputStatus
;
validationRules
:
ValidationRule
[];
hideErrorMessage
?:
boolean
;
onBlurWithStatus
?:
(
evt
,
status
:
InputStatus
)
=>
void
;
emptyToNull
?:
boolean
;
export
enum
EventsWithValidation
{
onBlur
=
'onBlur'
,
onFocus
=
'onFocus'
,
onChange
=
'onChange'
,
}
const
validator
=
(
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
;
}
;
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
&
React
.
HTMLProps
<
HTMLInputElement
>
>
{
export
class
Input
extends
PureComponent
<
Props
>
{
state
=
{
error
:
null
,
};
get
status
()
{
const
{
error
}
=
this
.
state
;
if
(
error
)
{
return
InputStatus
.
Invalid
;
}
return
InputStatus
.
Valid
;
return
this
.
state
.
error
?
InputStatus
.
Invalid
:
InputStatus
.
Valid
;
}
onBlurWithValidation
=
evt
=>
{
const
{
validationRules
,
onBlurWithStatus
,
onBlur
}
=
this
.
props
;
get
isInvalid
()
{
return
this
.
status
===
InputStatus
.
Invalid
;
}
let
errors
=
null
;
if
(
validationRules
)
{
errors
=
validator
(
evt
.
currentTarget
.
value
,
validationRules
);
validatorAsync
=
(
validationRules
:
ValidationRule
[])
=>
{
return
evt
=>
{
const
errors
=
validate
(
evt
.
currentTarget
.
value
,
validationRules
);
this
.
setState
(
prevState
=>
{
return
{
...
prevState
,
error
:
errors
?
errors
[
0
]
:
null
,
};
});
}
};
};
if
(
onBlurWithStatus
)
{
onBlurWithStatus
(
evt
,
errors
?
InputStatus
.
Invalid
:
InputStatus
.
Valid
);
populateEventPropsWithStatus
=
(
restProps
,
validationEvents
:
ValidationEvents
)
=>
{
const
inputElementProps
=
{
...
restProps
};
Object
.
keys
(
EventsWithValidation
).
forEach
(
eventName
=>
{
inputElementProps
[
eventName
]
=
async
evt
=>
{
if
(
validationEvents
[
eventName
])
{
await
this
.
validatorAsync
(
validationEvents
[
eventName
]).
apply
(
this
,
[
evt
]);
}
if
(
onBlur
)
{
onBlur
(
evt
);
if
(
restProps
[
eventName
])
{
restProps
[
eventName
].
apply
(
null
,
[
evt
,
this
.
status
]);
}
};
});
return
inputElementProps
;
};
render
()
{
const
{
status
,
validationRules
,
onBlurWithStatus
,
onBlur
,
className
,
hideErrorMessage
,
emptyToNull
,
...
restProps
}
=
this
.
props
;
const
{
validationEvents
,
className
,
hideErrorMessage
,
...
restProps
}
=
this
.
props
;
const
{
error
}
=
this
.
state
;
let
inputClassName
=
'gf-form-input'
;
inputClassName
=
this
.
status
===
InputStatus
.
Invalid
?
inputClassName
+
' invalid'
:
inputClassName
;
const
inputClassName
=
'gf-form-input'
+
(
this
.
isInvalid
?
' invalid'
:
''
);
const
inputElementProps
=
this
.
populateEventPropsWithStatus
(
restProps
,
validationEvents
);
return
(
<
div
className=
"our-custom-wrapper-class"
>
<
input
{
...
restProps
}
onBlur=
{
this
.
onBlurWithValidation
}
className=
{
inputClassName
}
/>
<
input
{
...
inputElementProps
}
className=
{
inputClassName
}
/>
{
error
&&
!
hideErrorMessage
&&
<
span
>
{
error
}
</
span
>
}
</
div
>
);
...
...
public/app/core/utils/validate.ts
0 → 100644
View file @
a8e184c0
import
{
ValidationRule
}
from
'app/types'
;
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
;
};
public/app/features/dashboard/dashgrid/QueriesTab.tsx
View file @
a8e184c0
...
...
@@ -10,9 +10,9 @@ import config from 'app/core/config';
import
{
QueryInspector
}
from
'./QueryInspector'
;
import
{
Switch
}
from
'app/core/components/Switch/Switch'
;
import
{
Input
}
from
'app/core/components/Form'
;
import
{
InputStatus
}
from
'app/core/components/Form/Input'
;
import
{
InputStatus
,
EventsWithValidation
}
from
'app/core/components/Form/Input'
;
import
{
isValidTimeSpan
}
from
'app/core/utils/rangeutil'
;
import
{
Validation
Rule
}
from
'app/types'
;
import
{
Validation
Events
}
from
'app/types'
;
// Services
import
{
getDatasourceSrv
}
from
'app/features/plugins/datasource_srv'
;
...
...
@@ -42,7 +42,9 @@ interface LoadingPlaceholderProps {
}
const
LoadingPlaceholder
:
SFC
<
LoadingPlaceholderProps
>
=
({
text
})
=>
<
h2
>
{
text
}
</
h2
>;
const
validationRules
:
ValidationRule
[]
=
[
const
timeRangeValidationEvents
:
ValidationEvents
=
{
[
EventsWithValidation
.
onBlur
]:
[
{
rule
:
value
=>
{
if
(
!
value
)
{
...
...
@@ -52,7 +54,8 @@ const validationRules: ValidationRule[] = [
},
errorMessage
:
'Not a valid timespan'
,
},
];
],
};
export
class
QueriesTab
extends
PureComponent
<
Props
,
State
>
{
element
:
any
;
...
...
@@ -322,8 +325,8 @@ export class QueriesTab extends PureComponent<Props, State> {
type=
"text"
className=
"gf-form-input max-width-8"
placeholder=
"1h"
onBlur
WithStatus
=
{
this
.
onOverrideTime
}
validation
Rules=
{
validationRule
s
}
onBlur=
{
this
.
onOverrideTime
}
validation
Events=
{
timeRangeValidationEvent
s
}
hideErrorMessage=
{
true
}
/>
</
div
>
...
...
@@ -338,8 +341,8 @@ export class QueriesTab extends PureComponent<Props, State> {
type=
"text"
className=
"gf-form-input max-width-8"
placeholder=
"1h"
onBlur
WithStatus
=
{
this
.
onTimeShift
}
validation
Rules=
{
validationRule
s
}
onBlur=
{
this
.
onTimeShift
}
validation
Events=
{
timeRangeValidationEvent
s
}
hideErrorMessage=
{
true
}
/>
</
div
>
...
...
public/app/types/form.ts
View file @
a8e184c0
export
interface
ValidationRule
{
rule
:
(
value
:
string
)
=>
boolean
;
rule
:
(
value
ToValidate
:
string
)
=>
boolean
;
errorMessage
:
string
;
}
export
interface
ValidationEvents
{
[
eventName
:
string
]:
ValidationRule
[];
}
public/app/types/index.ts
View file @
a8e184c0
...
...
@@ -30,7 +30,7 @@ import {
AppNotificationTimeout
,
}
from
'./appNotifications'
;
import
{
DashboardSearchHit
}
from
'./search'
;
import
{
ValidationRule
}
from
'./form'
;
import
{
Validation
Events
,
Validation
Rule
}
from
'./form'
;
export
{
Team
,
TeamsState
,
...
...
@@ -89,6 +89,7 @@ export {
AppNotificationTimeout
,
DashboardSearchHit
,
UserState
,
ValidationEvents
,
ValidationRule
,
};
...
...
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