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
4d2be024
Commit
4d2be024
authored
Oct 09, 2018
by
Johannes Schill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start implementing the upgraded react-select in the tag filter box #13425
parent
c0b7ca39
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
147 additions
and
66 deletions
+147
-66
public/app/core/components/TagFilter/TagBadge.tsx
+2
-7
public/app/core/components/TagFilter/TagFilter.tsx
+59
-11
public/app/core/components/TagFilter/TagOption.tsx
+70
-47
public/app/core/components/TagFilter/TagValue.tsx
+1
-1
public/sass/components/_form_select_box.scss
+15
-0
No files found.
public/app/core/components/TagFilter/TagBadge.tsx
View file @
4d2be024
...
...
@@ -5,17 +5,12 @@ export interface Props {
label
:
string
;
removeIcon
:
boolean
;
count
:
number
;
onClick
:
any
;
onClick
?
:
any
;
}
export
class
TagBadge
extends
React
.
Component
<
Props
,
any
>
{
constructor
(
props
)
{
super
(
props
);
this
.
onClick
=
this
.
onClick
.
bind
(
this
);
}
onClick
(
event
)
{
this
.
props
.
onClick
(
event
);
}
render
()
{
...
...
@@ -28,7 +23,7 @@ export class TagBadge extends React.Component<Props, any> {
const
countLabel
=
count
!==
0
&&
<
span
className=
"tag-count-label"
>
{
`(${count})`
}
</
span
>;
return
(
<
span
className=
{
`label label-tag`
}
onClick=
{
this
.
onClick
}
style=
{
tagStyle
}
>
<
span
className=
{
`label label-tag`
}
style=
{
tagStyle
}
>
{
removeIcon
&&
<
i
className=
"fa fa-remove"
/>
}
{
label
}
{
countLabel
}
</
span
>
...
...
public/app/core/components/TagFilter/TagFilter.tsx
View file @
4d2be024
import
_
from
'lodash'
;
import
React
from
'react'
;
import
{
Async
}
from
'react-select
'
;
import
AsyncSelect
from
'react-select/lib/Async
'
;
import
{
TagValue
}
from
'./TagValue'
;
import
{
TagOption
}
from
'./TagOption'
;
import
{
TagBadge
}
from
'./TagBadge'
;
import
IndicatorsContainer
from
'app/core/components/Picker/IndicatorsContainer'
;
import
NoOptionsMessage
from
'app/core/components/Picker/NoOptionsMessage'
;
import
{
components
}
from
'react-select'
;
import
ResetStyles
from
'app/core/components/Picker/ResetStyles'
;
export
interface
Props
{
tags
:
string
[];
...
...
@@ -23,10 +28,11 @@ export class TagFilter extends React.Component<Props, any> {
searchTags
(
query
)
{
return
this
.
props
.
tagOptions
().
then
(
options
=>
{
const
tags
=
_
.
map
(
options
,
tagOption
=>
{
return
{
value
:
tagOption
.
term
,
label
:
tagOption
.
term
,
count
:
tagOption
.
count
};
});
return
{
options
:
tags
};
return
options
.
map
(
option
=>
({
value
:
option
.
term
,
label
:
option
.
term
,
count
:
option
.
count
,
}));
});
}
...
...
@@ -44,23 +50,65 @@ export class TagFilter extends React.Component<Props, any> {
render
()
{
const
selectOptions
=
{
classNamePrefix
:
'gf-form-select2'
,
isMulti
:
true
,
defaultOptions
:
true
,
loadOptions
:
this
.
searchTags
,
onChange
:
this
.
onChange
,
value
:
this
.
props
.
tags
,
multi
:
true
,
className
:
'gf-form-input gf-form-input--form-dropdown'
,
placeholder
:
'Tags'
,
loadingPlaceholder
:
'Loading...'
,
noResultsText
:
'No tags found'
,
optionComponent
:
TagOption
,
loadingMessage
:
()
=>
'Loading...'
,
noOptionsMessage
:
()
=>
'No tags found'
,
getOptionValue
:
i
=>
i
.
value
,
getOptionLabel
:
i
=>
i
.
label
,
styles
:
ResetStyles
,
components
:
{
Option
:
TagOption
,
IndicatorsContainer
,
NoOptionsMessage
,
MultiValueContainer
:
props
=>
{
const
{
data
}
=
props
;
return
(
<
components
.
MultiValueContainer
{
...
props
}
>
<
TagBadge
label=
{
data
.
label
}
removeIcon=
{
true
}
count=
{
data
.
count
}
/>
</
components
.
MultiValueContainer
>
);
},
MultiValueRemove
:
props
=>
{
return
<
components
.
MultiValueRemove
{
...
props
}
>
X
</
components
.
MultiValueRemove
>;
},
},
};
// <AsyncSelect
// classNamePrefix={`gf-form-select2`}
// isMulti={false}
// isLoading={isLoading}
// defaultOptions={true}
// loadOptions={this.debouncedSearch}
// onChange={onSelected}
// className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
// styles={ResetStyles}
// components={{
// Option: PickerOption,
// IndicatorsContainer,
// NoOptionsMessage,
// }}
// placeholder="Select user"
// filterOption={(option: { label: string }, searchText?: string) => {
// return option.label.includes(searchText);
// }}
// loadingMessage={() => 'Loading...'}
// noOptionsMessage={() => 'No users found'}
// getOptionValue={i => i.id}
// getOptionLabel={i => i.label}
selectOptions
[
'valueComponent'
]
=
TagValue
;
return
(
<
div
className=
"gf-form gf-form--has-input-icon gf-form--grow"
>
<
div
className=
"tag-filter"
>
<
Async
{
...
selectOptions
}
/>
<
Async
Select
{
...
selectOptions
}
/>
</
div
>
<
i
className=
"gf-form-input-icon fa fa-tag"
/>
</
div
>
...
...
public/app/core/components/TagFilter/TagOption.tsx
View file @
4d2be024
import
React
from
'react'
;
import
{
components
}
from
'react-select'
;
import
{
OptionProps
}
from
'react-select/lib/components/Option'
;
import
{
TagBadge
}
from
'./TagBadge'
;
export
interface
Props
{
onSelect
:
any
;
onFocus
:
any
;
option
:
any
;
isFocused
:
any
;
className
:
any
;
// https://github.com/JedWatson/react-select/issues/3038
interface
ExtendedOptionProps
extends
OptionProps
<
any
>
{
data
:
any
;
}
export
class
TagOption
extends
React
.
Component
<
Props
,
any
>
{
constructor
(
props
)
{
super
(
props
);
this
.
handleMouseDown
=
this
.
handleMouseDown
.
bind
(
this
);
this
.
handleMouseEnter
=
this
.
handleMouseEnter
.
bind
(
this
);
this
.
handleMouseMove
=
this
.
handleMouseMove
.
bind
(
this
);
}
handleMouseDown
(
event
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
this
.
props
.
onSelect
(
this
.
props
.
option
,
event
);
}
handleMouseEnter
(
event
)
{
this
.
props
.
onFocus
(
this
.
props
.
option
,
event
);
}
handleMouseMove
(
event
)
{
if
(
this
.
props
.
isFocused
)
{
return
;
}
this
.
props
.
onFocus
(
this
.
props
.
option
,
event
);
}
render
()
{
const
{
option
,
className
}
=
this
.
props
;
return
(
<
button
onMouseDown=
{
this
.
handleMouseDown
}
onMouseEnter=
{
this
.
handleMouseEnter
}
onMouseMove=
{
this
.
handleMouseMove
}
title=
{
option
.
title
}
className=
{
`tag-filter-option btn btn-link ${className || ''}`
}
>
<
TagBadge
label=
{
option
.
label
}
removeIcon=
{
false
}
count=
{
option
.
count
}
onClick=
{
this
.
handleMouseDown
}
/>
</
button
>
);
}
}
export
const
TagOption
=
(
props
:
ExtendedOptionProps
)
=>
{
const
{
data
,
className
,
label
}
=
props
;
return
(
<
components
.
Option
{
...
props
}
>
<
div
className=
{
`tag-filter-option btn btn-link ${className || ''}`
}
>
<
TagBadge
label=
{
label
}
removeIcon=
{
true
}
count=
{
data
.
count
}
/>
</
div
>
</
components
.
Option
>
);
};
export
default
TagOption
;
// import React from 'react';
// import { TagBadge } from './TagBadge';
// export interface Props {
// onSelect: any;
// onFocus: any;
// option: any;
// isFocused: any;
// className: any;
// }
// export class TagOption extends React.Component<Props, any> {
// constructor(props) {
// super(props);
// this.handleMouseDown = this.handleMouseDown.bind(this);
// this.handleMouseEnter = this.handleMouseEnter.bind(this);
// this.handleMouseMove = this.handleMouseMove.bind(this);
// }
// handleMouseDown(event) {
// event.preventDefault();
// event.stopPropagation();
// this.props.onSelect(this.props.option, event);
// }
// handleMouseEnter(event) {
// this.props.onFocus(this.props.option, event);
// }
// handleMouseMove(event) {
// if (this.props.isFocused) {
// return;
// }
// this.props.onFocus(this.props.option, event);
// }
// render() {
// const { option, className } = this.props;
// return (
// <button
// onMouseDown={this.handleMouseDown}
// onMouseEnter={this.handleMouseEnter}
// onMouseMove={this.handleMouseMove}
// title={option.title}
// className={`tag-filter-option btn btn-link ${className || ''}`}
// >
// <TagBadge label={option.label} removeIcon={false} count={option.count} onClick={this.handleMouseDown} />
// </button>
// );
// }
// }
public/app/core/components/TagFilter/TagValue.tsx
View file @
4d2be024
...
...
@@ -21,6 +21,6 @@ export class TagValue extends React.Component<Props, any> {
render
()
{
const
{
value
}
=
this
.
props
;
return
<
TagBadge
label=
{
value
.
label
}
removeIcon=
{
tru
e
}
count=
{
0
}
onClick=
{
this
.
onClick
}
/>;
return
<
TagBadge
label=
{
value
.
label
}
removeIcon=
{
fals
e
}
count=
{
0
}
onClick=
{
this
.
onClick
}
/>;
}
}
public/sass/components/_form_select_box.scss
View file @
4d2be024
...
...
@@ -58,6 +58,15 @@ $select-input-bg-disabled: $input-bg-disabled;
background
:
$select-input-bg-disabled
;
position
:
absolute
;
z-index
:
2
;
width
:
100%
;
}
.tag-filter
.gf-form-select2__menu
{
width
:
100%
;
}
.gf-form-select2__multi-value
{
display
:
inline
;
}
.gf-form-select2__option
{
...
...
@@ -106,3 +115,9 @@ $select-input-bg-disabled: $input-bg-disabled;
border
:
0
;
overflow
:
visible
;
}
.gf-form--has-input-icon
{
.gf-form-select2__value-container
{
padding-left
:
30px
;
}
}
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