Commit ab31d52b by Torkel Ödegaard

Merge branch 'panel-edit-style-changes' into select-refactor

parents b9a05a85 58cc2e34
import React from 'react'; import React from 'react';
import { components } from 'react-select'; import { components } from 'react-select';
import { OptionProps } from 'react-select/lib/components/Option'; import { OptionProps } from 'react-select/lib/components/Option';
...@@ -6,13 +6,15 @@ export interface Props { ...@@ -6,13 +6,15 @@ export interface Props {
children: Element; children: Element;
} }
export const PickerOption = (props: OptionProps<any>) => { export const NoOptionsMessage = (props: OptionProps<any>) => {
const { children, className } = props; const { children } = props;
return ( return (
<components.Option {...props}> <components.Option {...props}>
<div className={`description-picker-option__button btn btn-link ${className}`}>{children}</div> <div className="gf-form-select-box__desc-option">
<div className="gf-form-select-box__desc-option__body">{children}</div>
</div>
</components.Option> </components.Option>
); );
}; };
export default PickerOption; export default NoOptionsMessage;
// import React, { PureComponent } from 'react'; // Libraries
// import Select as ReactSelect from 'react-select'; import classNames from 'classnames';
// import DescriptionOption from './DescriptionOption'; import React, { PureComponent } from 'react';
// import IndicatorsContainer from './IndicatorsContainer'; import { default as ReactSelect } from 'react-select';
// import ResetStyles from './ResetStyles'; import { default as ReactAsyncSelect } from 'react-select/lib/Async';
//
// export interface OptionType { // Components
// label: string; import { Option, SingleValue } from './PickerOption';
// value: string; import IndicatorsContainer from './IndicatorsContainer';
// } import NoOptionsMessage from './NoOptionsMessage';
// import ResetStyles from './ResetStyles';
// interface Props {
// defaultValue?: any; export interface SelectOptionItem {
// getOptionLabel: (item: T) => string; label?: string;
// getOptionValue: (item: T) => string; value?: string;
// onChange: (item: T) => {} | void; imgUrl?: string;
// options: T[]; description?: string;
// placeholder?: string; [key: string]: any;
// width?: number; }
// value: T;
// className?: string; interface CommonProps {
// } defaultValue?: any;
// getOptionLabel?: (item: SelectOptionItem) => string;
// export class Select<T> extends PureComponent<Props<T>> { getOptionValue?: (item: SelectOptionItem) => string;
// static defaultProps = { onChange: (item: SelectOptionItem) => {} | void;
// width: null, placeholder?: string;
// className: '', width?: number;
// } value?: SelectOptionItem;
// className?: string;
// render() { components: object;
// const { defaultValue, getOptionLabel, getOptionValue, onSelected, options, placeholder, width, value, className } = this.props; }
// let widthClass = '';
// if (width) { interface SelectProps {
// widthClass = 'width-'+width; options: SelectOptionItem[];
// } }
//
// return ( interface AsyncProps {
// <ReactSelect defaultOptions: boolean;
// classNamePrefix="gf-form-select-box" loadOptions: (query: string) => Promise<SelectOptionItem[]>;
// className={`gf-form-input gf-form-input--form-dropdown ${widthClass} ${className}`} isLoading: boolean;
// components={{ loadingMessage?: () => string;
// Option: DescriptionOption, noOptionsMessage?: () => string;
// IndicatorsContainer, }
// }}
// defaultValue={defaultValue} export class Select extends PureComponent<CommonProps & SelectProps> {
// value={value} static defaultProps = {
// getOptionLabel={getOptionLabel} width: null,
// getOptionValue={getOptionValue} className: '',
// menuShouldScrollIntoView={false} components: {},
// isSearchable={false} };
// onChange={onSelected}
// options={options} render() {
// placeholder={placeholder || 'Choose'} const {
// styles={ResetStyles} defaultValue,
// /> getOptionLabel,
// ); getOptionValue,
// } onChange,
// } options,
// placeholder,
// export default Select; width,
value,
className,
} = this.props;
let widthClass = '';
if (width) {
widthClass = 'width-' + width;
}
const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
return (
<ReactSelect
classNamePrefix="gf-form-select-box"
className={selectClassNames}
components={{
Option,
SingleValue,
IndicatorsContainer,
}}
defaultValue={defaultValue}
value={value}
getOptionLabel={getOptionLabel}
getOptionValue={getOptionValue}
menuShouldScrollIntoView={false}
isSearchable={false}
onChange={onChange}
options={options}
placeholder={placeholder || 'Choose'}
styles={ResetStyles}
/>
);
}
}
export class AsyncSelect extends PureComponent<CommonProps & AsyncProps> {
static defaultProps = {
width: null,
className: '',
components: {},
loadingMessage: () => 'Loading...',
};
render() {
const {
defaultValue,
getOptionLabel,
getOptionValue,
onChange,
placeholder,
width,
value,
className,
loadOptions,
defaultOptions,
isLoading,
loadingMessage,
noOptionsMessage,
} = this.props;
let widthClass = '';
if (width) {
widthClass = 'width-' + width;
}
const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
return (
<ReactAsyncSelect
classNamePrefix="gf-form-select-box"
className={selectClassNames}
components={{
Option,
SingleValue,
IndicatorsContainer,
NoOptionsMessage,
}}
defaultValue={defaultValue}
value={value}
getOptionLabel={getOptionLabel}
getOptionValue={getOptionValue}
menuShouldScrollIntoView={false}
isSearchable={false}
onChange={onChange}
loadOptions={loadOptions}
isLoading={isLoading}
defaultOptions={defaultOptions}
placeholder={placeholder || 'Choose'}
styles={ResetStyles}
loadingMessage={loadingMessage}
noOptionsMessage={noOptionsMessage}
/>
);
}
}
export default Select;
// Libraries
import React, { Component } from 'react'; import React, { Component } from 'react';
import AsyncSelect from 'react-select/lib/Async';
import PickerOption from './PickerOption'; // Components
import { AsyncSelect } from 'app/core/components/Picker/Select';
// Utils & Services
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { getBackendSrv } from 'app/core/services/backend_srv'; import { getBackendSrv } from 'app/core/services/backend_srv';
// Types
import { User } from 'app/types'; import { User } from 'app/types';
import ResetStyles from './ResetStyles';
import IndicatorsContainer from './IndicatorsContainer';
import NoOptionsMessage from './NoOptionsMessage';
export interface Props { export interface Props {
onSelected: (user: User) => void; onSelected: (user: User) => void;
...@@ -40,6 +43,7 @@ export class UserPicker extends Component<Props, State> { ...@@ -40,6 +43,7 @@ export class UserPicker extends Component<Props, State> {
.then(result => { .then(result => {
return result.map(user => ({ return result.map(user => ({
id: user.userId, id: user.userId,
value: user.userId,
label: user.login === user.email ? user.login : `${user.login} - ${user.email}`, label: user.login === user.email ? user.login : `${user.login} - ${user.email}`,
imgUrl: user.avatarUrl, imgUrl: user.avatarUrl,
login: user.login, login: user.login,
...@@ -57,24 +61,13 @@ export class UserPicker extends Component<Props, State> { ...@@ -57,24 +61,13 @@ export class UserPicker extends Component<Props, State> {
return ( return (
<div className="user-picker"> <div className="user-picker">
<AsyncSelect <AsyncSelect
classNamePrefix={`gf-form-select-box`} className={className}
isMulti={false}
isLoading={isLoading} isLoading={isLoading}
defaultOptions={true} defaultOptions={true}
loadOptions={this.debouncedSearch} loadOptions={this.debouncedSearch}
onChange={onSelected} onChange={onSelected}
className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
styles={ResetStyles}
components={{
Option: PickerOption,
IndicatorsContainer,
NoOptionsMessage,
}}
placeholder="Select user" placeholder="Select user"
loadingMessage={() => 'Loading...'}
noOptionsMessage={() => 'No users found'} noOptionsMessage={() => 'No users found'}
getOptionValue={i => i.id}
getOptionLabel={i => i.label}
/> />
</div> </div>
); );
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { Label } from 'app/core/components/Label/Label'; import { Label } from 'app/core/components/Label/Label';
import SimplePicker from 'app/core/components/Picker/SimplePicker'; import Select from 'app/core/components/Picker/Select';
import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv'; import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchHit } from 'app/types'; import { DashboardSearchHit } from 'app/types';
...@@ -17,12 +17,12 @@ export interface State { ...@@ -17,12 +17,12 @@ export interface State {
dashboards: DashboardSearchHit[]; dashboards: DashboardSearchHit[];
} }
const themes = [{ value: '', text: 'Default' }, { value: 'dark', text: 'Dark' }, { value: 'light', text: 'Light' }]; const themes = [{ value: '', label: 'Default' }, { value: 'dark', label: 'Dark' }, { value: 'light', label: 'Light' }];
const timezones = [ const timezones = [
{ value: '', text: 'Default' }, { value: '', label: 'Default' },
{ value: 'browser', text: 'Local browser time' }, { value: 'browser', label: 'Local browser time' },
{ value: 'utc', text: 'UTC' }, { value: 'utc', label: 'UTC' },
]; ];
export class SharedPreferences extends PureComponent<Props, State> { export class SharedPreferences extends PureComponent<Props, State> {
...@@ -91,12 +91,10 @@ export class SharedPreferences extends PureComponent<Props, State> { ...@@ -91,12 +91,10 @@ export class SharedPreferences extends PureComponent<Props, State> {
<h3 className="page-heading">Preferences</h3> <h3 className="page-heading">Preferences</h3>
<div className="gf-form"> <div className="gf-form">
<span className="gf-form-label width-11">UI Theme</span> <span className="gf-form-label width-11">UI Theme</span>
<SimplePicker <Select
value={themes.find(item => item.value === theme)} value={themes.find(item => item.value === theme)}
options={themes} options={themes}
getOptionValue={i => i.value} onChange={theme => this.onThemeChanged(theme.value)}
getOptionLabel={i => i.text}
onSelected={theme => this.onThemeChanged(theme.value)}
width={20} width={20}
/> />
</div> </div>
...@@ -107,11 +105,11 @@ export class SharedPreferences extends PureComponent<Props, State> { ...@@ -107,11 +105,11 @@ export class SharedPreferences extends PureComponent<Props, State> {
> >
Home Dashboard Home Dashboard
</Label> </Label>
<SimplePicker <Select
value={dashboards.find(dashboard => dashboard.id === homeDashboardId)} value={dashboards.find(dashboard => dashboard.id === homeDashboardId)}
getOptionValue={i => i.id} getOptionValue={i => i.id}
getOptionLabel={i => i.title} getOptionLabel={i => i.title}
onSelected={(dashboard: DashboardSearchHit) => this.onHomeDashboardChanged(dashboard.id)} onChange={(dashboard: DashboardSearchHit) => this.onHomeDashboardChanged(dashboard.id)}
options={dashboards} options={dashboards}
placeholder="Chose default dashboard" placeholder="Chose default dashboard"
width={20} width={20}
...@@ -119,11 +117,9 @@ export class SharedPreferences extends PureComponent<Props, State> { ...@@ -119,11 +117,9 @@ export class SharedPreferences extends PureComponent<Props, State> {
</div> </div>
<div className="gf-form"> <div className="gf-form">
<label className="gf-form-label width-11">Timezone</label> <label className="gf-form-label width-11">Timezone</label>
<SimplePicker <Select
value={timezones.find(item => item.value === timezone)} value={timezones.find(item => item.value === timezone)}
getOptionValue={i => i.value} onChange={timezone => this.onTimeZoneChanged(timezone.value)}
getOptionLabel={i => i.text}
onSelected={timezone => this.onTimeZoneChanged(timezone.value)}
options={timezones} options={timezones}
width={20} width={20}
/> />
......
...@@ -111,11 +111,11 @@ function panelHeader($compile) { ...@@ -111,11 +111,11 @@ function panelHeader($compile) {
*/ */
function togglePanelStackPosition() { function togglePanelStackPosition() {
const menuOpenClass = 'dropdown-menu-open'; const menuOpenClass = 'dropdown-menu-open';
const panelGridClass = '.react-grid-item.panel'; const panelGridClass = '.react-grid-item';
let panelElem = elem let panelElem = elem
.find('[data-toggle=dropdown]') .find('[data-toggle=dropdown]')
.parentsUntil('.panel') .parentsUntil(panelGridClass)
.parent(); .parent();
const menuElem = elem.find('[data-toggle=dropdown]').parent(); const menuElem = elem.find('[data-toggle=dropdown]').parent();
panelElem = panelElem && panelElem.length ? panelElem[0] : undefined; panelElem = panelElem && panelElem.length ? panelElem[0] : undefined;
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { Label } from 'app/core/components/Label/Label'; import { Label } from 'app/core/components/Label/Label';
import SimplePicker from 'app/core/components/Picker/SimplePicker'; import Select from 'app/core/components/Picker/Select';
import UnitPicker from 'app/core/components/Picker/Unit/UnitPicker'; import UnitPicker from 'app/core/components/Picker/Unit/UnitPicker';
import { OptionModuleProps } from './module'; import { OptionModuleProps } from './module';
const statOptions = [ const statOptions = [
{ value: 'min', text: 'Min' }, { value: 'min', label: 'Min' },
{ value: 'max', text: 'Max' }, { value: 'max', label: 'Max' },
{ value: 'avg', text: 'Average' }, { value: 'avg', label: 'Average' },
{ value: 'current', text: 'Current' }, { value: 'current', label: 'Current' },
{ value: 'total', text: 'Total' }, { value: 'total', label: 'Total' },
{ value: 'name', text: 'Name' }, { value: 'name', label: 'Name' },
{ value: 'first', text: 'First' }, { value: 'first', label: 'First' },
{ value: 'delta', text: 'Delta' }, { value: 'delta', label: 'Delta' },
{ value: 'diff', text: 'Difference' }, { value: 'diff', label: 'Difference' },
{ value: 'range', text: 'Range' }, { value: 'range', label: 'Range' },
{ value: 'last_time', text: 'Time of last point' }, { value: 'last_time', label: 'Time of last point' },
]; ];
const labelWidth = 6; const labelWidth = 6;
...@@ -43,12 +43,10 @@ export default class ValueOptions extends PureComponent<OptionModuleProps> { ...@@ -43,12 +43,10 @@ export default class ValueOptions extends PureComponent<OptionModuleProps> {
<h5 className="page-heading">Value</h5> <h5 className="page-heading">Value</h5>
<div className="gf-form-inline"> <div className="gf-form-inline">
<Label width={labelWidth}>Stat</Label> <Label width={labelWidth}>Stat</Label>
<SimplePicker <Select
width={12} width={12}
options={statOptions} options={statOptions}
getOptionLabel={i => i.text} onChange={this.onStatChange}
getOptionValue={i => i.value}
onSelected={this.onStatChange}
value={statOptions.find(option => option.value === stat)} value={statOptions.find(option => option.value === stat)}
/> />
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment