فهرست منبع

Merge pull request #14817 from grafana/grafana-ui/select

Migrate Select components to @grafana/ui
Torkel Ödegaard 7 سال پیش
والد
کامیت
bc78c8d56e
25فایلهای تغییر یافته به همراه111 افزوده شده و 74 حذف شده
  1. 4 1
      packages/grafana-ui/src/components/Select/IndicatorsContainer.tsx
  2. 4 0
      packages/grafana-ui/src/components/Select/NoOptionsMessage.tsx
  3. 13 8
      packages/grafana-ui/src/components/Select/Select.tsx
  4. 22 12
      packages/grafana-ui/src/components/Select/SelectOption.test.tsx
  5. 6 3
      packages/grafana-ui/src/components/Select/SelectOption.tsx
  6. 2 2
      packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx
  7. 0 0
      packages/grafana-ui/src/components/Select/_Select.scss
  8. 7 2
      packages/grafana-ui/src/components/Select/__snapshots__/SelectOption.test.tsx.snap
  9. 27 0
      packages/grafana-ui/src/components/Select/resetSelectStyles.ts
  10. 1 0
      packages/grafana-ui/src/components/index.scss
  11. 7 0
      packages/grafana-ui/src/components/index.ts
  12. 1 1
      public/app/core/components/PermissionList/AddPermission.tsx
  13. 1 1
      public/app/core/components/PermissionList/DisabledPermissionListItem.tsx
  14. 1 1
      public/app/core/components/PermissionList/PermissionListItem.tsx
  15. 1 1
      public/app/core/components/Select/DataSourcePicker.tsx
  16. 0 25
      public/app/core/components/Select/ResetStyles.tsx
  17. 1 1
      public/app/core/components/Select/TeamPicker.tsx
  18. 1 1
      public/app/core/components/Select/UnitPicker.tsx
  19. 1 1
      public/app/core/components/Select/UserPicker.tsx
  20. 1 1
      public/app/core/components/SharedPreferences/SharedPreferences.tsx
  21. 2 4
      public/app/core/components/TagFilter/TagFilter.tsx
  22. 1 1
      public/app/plugins/panel/gauge/MappingRow.tsx
  23. 1 1
      public/app/plugins/panel/gauge/ValueOptions.tsx
  24. 4 5
      public/sass/_grafana.scss
  25. 2 2
      yarn.lock

+ 4 - 1
public/app/core/components/Select/IndicatorsContainer.tsx → packages/grafana-ui/src/components/Select/IndicatorsContainer.tsx

@@ -1,7 +1,10 @@
 import React from 'react';
+
+// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
+// @ts-ignore
 import { components } from '@torkelo/react-select';
 
-export const IndicatorsContainer = props => {
+export const IndicatorsContainer = (props: any) => {
   const isOpen = props.selectProps.menuIsOpen;
   return (
     <components.IndicatorsContainer {...props}>

+ 4 - 0
public/app/core/components/Select/NoOptionsMessage.tsx → packages/grafana-ui/src/components/Select/NoOptionsMessage.tsx

@@ -1,5 +1,9 @@
 import React from 'react';
+
+// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
+// @ts-ignore
 import { components } from '@torkelo/react-select';
+// @ts-ignore
 import { OptionProps } from '@torkelo/react-select/lib/components/Option';
 
 export interface Props {

+ 13 - 8
public/app/core/components/Select/Select.tsx → packages/grafana-ui/src/components/Select/Select.tsx

@@ -1,16 +1,21 @@
 // Libraries
 import classNames from 'classnames';
 import React, { PureComponent } from 'react';
+
+// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
+// @ts-ignore
 import { default as ReactSelect } from '@torkelo/react-select';
+// @ts-ignore
 import { default as ReactAsyncSelect } from '@torkelo/react-select/lib/Async';
+// @ts-ignore
 import { components } from '@torkelo/react-select';
 
 // Components
-import { Option, SingleValue } from './PickerOption';
-import OptionGroup from './OptionGroup';
+import { SelectOption, SingleValue } from './SelectOption';
+import SelectOptionGroup from './SelectOptionGroup';
 import IndicatorsContainer from './IndicatorsContainer';
 import NoOptionsMessage from './NoOptionsMessage';
-import ResetStyles from './ResetStyles';
+import resetSelectStyles from './resetSelectStyles';
 import { CustomScrollbar } from '@grafana/ui';
 
 export interface SelectOptionItem {
@@ -53,7 +58,7 @@ interface AsyncProps {
   loadingMessage?: () => string;
 }
 
-export const MenuList = props => {
+export const MenuList = (props: any) => {
   return (
     <components.MenuList {...props}>
       <CustomScrollbar autoHide={false}>{props.children}</CustomScrollbar>
@@ -112,11 +117,11 @@ export class Select extends PureComponent<CommonProps & SelectProps> {
         classNamePrefix="gf-form-select-box"
         className={selectClassNames}
         components={{
-          Option,
+          Option: SelectOption,
           SingleValue,
           IndicatorsContainer,
           MenuList,
-          Group: OptionGroup,
+          Group: SelectOptionGroup,
         }}
         defaultValue={defaultValue}
         value={value}
@@ -127,7 +132,7 @@ export class Select extends PureComponent<CommonProps & SelectProps> {
         onChange={onChange}
         options={options}
         placeholder={placeholder || 'Choose'}
-        styles={ResetStyles}
+        styles={resetSelectStyles()}
         isDisabled={isDisabled}
         isLoading={isLoading}
         isClearable={isClearable}
@@ -212,7 +217,7 @@ export class AsyncSelect extends PureComponent<CommonProps & AsyncProps> {
         isLoading={isLoading}
         defaultOptions={defaultOptions}
         placeholder={placeholder || 'Choose'}
-        styles={ResetStyles}
+        styles={resetSelectStyles()}
         loadingMessage={loadingMessage}
         noOptionsMessage={noOptionsMessage}
         isDisabled={isDisabled}

+ 22 - 12
public/app/core/components/Select/PickerOption.test.tsx → packages/grafana-ui/src/components/Select/SelectOption.test.tsx

@@ -1,11 +1,11 @@
 import React from 'react';
 import renderer from 'react-test-renderer';
-import PickerOption from './PickerOption';
+import SelectOption from './SelectOption';
+import { OptionProps } from 'react-select/lib/components/Option';
 
-const model = {
+const model: OptionProps<any> = {
   cx: jest.fn(),
   clearValue: jest.fn(),
-  onSelect: jest.fn(),
   getStyles: jest.fn(),
   getValue: jest.fn(),
   hasValue: true,
@@ -18,21 +18,31 @@ const model = {
   isFocused: false,
   isSelected: false,
   innerRef: null,
-  innerProps: null,
+  innerProps: {
+    id: '',
+    key: '',
+    onClick: jest.fn(),
+    onMouseOver: jest.fn(),
+    tabIndex: 1,
+  },
   label: 'Option label',
-  type: null,
+  type: 'option',
   children: 'Model title',
-  data: {
-    title: 'Model title',
-    imgUrl: 'url/to/avatar',
-    label: 'User picker label',
-  },
   className: 'class-for-user-picker',
 };
 
-describe('PickerOption', () => {
+describe('SelectOption', () => {
   it('renders correctly', () => {
-    const tree = renderer.create(<PickerOption {...model} />).toJSON();
+    const tree = renderer
+      .create(
+        <SelectOption
+          {...model}
+          data={{
+            imgUrl: 'url/to/avatar',
+          }}
+        />
+      )
+      .toJSON();
     expect(tree).toMatchSnapshot();
   });
 });

+ 6 - 3
public/app/core/components/Select/PickerOption.tsx → packages/grafana-ui/src/components/Select/SelectOption.tsx

@@ -1,4 +1,7 @@
 import React from 'react';
+
+// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
+// @ts-ignore
 import { components } from '@torkelo/react-select';
 import { OptionProps } from 'react-select/lib/components/Option';
 
@@ -10,7 +13,7 @@ interface ExtendedOptionProps extends OptionProps<any> {
   };
 }
 
-export const Option = (props: ExtendedOptionProps) => {
+export const SelectOption = (props: ExtendedOptionProps) => {
   const { children, isSelected, data } = props;
 
   return (
@@ -28,7 +31,7 @@ export const Option = (props: ExtendedOptionProps) => {
 };
 
 // was not able to type this without typescript error
-export const SingleValue = props => {
+export const SingleValue = (props: any) => {
   const { children, data } = props;
 
   return (
@@ -41,4 +44,4 @@ export const SingleValue = props => {
   );
 };
 
-export default Option;
+export default SelectOption;

+ 2 - 2
public/app/core/components/Select/OptionGroup.tsx → packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx

@@ -9,7 +9,7 @@ interface State {
   expanded: boolean;
 }
 
-export default class OptionGroup extends PureComponent<ExtendedGroupProps, State> {
+export default class SelectOptionGroup extends PureComponent<ExtendedGroupProps, State> {
   state = {
     expanded: false,
   };
@@ -24,7 +24,7 @@ export default class OptionGroup extends PureComponent<ExtendedGroupProps, State
     }
   }
 
-  componentDidUpdate(nextProps) {
+  componentDidUpdate(nextProps: ExtendedGroupProps) {
     if (nextProps.selectProps.inputValue !== '') {
       this.setState({ expanded: true });
     }

+ 0 - 0
public/sass/components/_form_select_box.scss → packages/grafana-ui/src/components/Select/_Select.scss


+ 7 - 2
public/app/core/components/Select/__snapshots__/PickerOption.test.tsx.snap → packages/grafana-ui/src/components/Select/__snapshots__/SelectOption.test.tsx.snap

@@ -1,7 +1,12 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`PickerOption renders correctly 1`] = `
-<div>
+exports[`SelectOption renders correctly 1`] = `
+<div
+  id=""
+  onClick={[MockFunction]}
+  onMouseOver={[MockFunction]}
+  tabIndex={1}
+>
   <div
     className="gf-form-select-box__desc-option"
   >

+ 27 - 0
packages/grafana-ui/src/components/Select/resetSelectStyles.ts

@@ -0,0 +1,27 @@
+export default function resetSelectStyles() {
+  return {
+    clearIndicator: () => ({}),
+    container: () => ({}),
+    control: () => ({}),
+    dropdownIndicator: () => ({}),
+    group: () => ({}),
+    groupHeading: () => ({}),
+    indicatorsContainer: () => ({}),
+    indicatorSeparator: () => ({}),
+    input: () => ({}),
+    loadingIndicator: () => ({}),
+    loadingMessage: () => ({}),
+    menu: () => ({}),
+    menuList: ({ maxHeight }: { maxHeight: number }) => ({
+      maxHeight,
+    }),
+    multiValue: () => ({}),
+    multiValueLabel: () => ({}),
+    multiValueRemove: () => ({}),
+    noOptionsMessage: () => ({}),
+    option: () => ({}),
+    placeholder: () => ({}),
+    singleValue: () => ({}),
+    valueContainer: () => ({}),
+  };
+}

+ 1 - 0
packages/grafana-ui/src/components/index.scss

@@ -1,3 +1,4 @@
 @import 'CustomScrollbar/CustomScrollbar';
 @import 'DeleteButton/DeleteButton';
 @import 'Tooltip/Tooltip';
+@import 'Select/Select';

+ 7 - 0
packages/grafana-ui/src/components/index.ts

@@ -2,6 +2,13 @@ export { DeleteButton } from './DeleteButton/DeleteButton';
 export { Tooltip } from './Tooltip/Tooltip';
 export { Portal } from './Portal/Portal';
 export { CustomScrollbar } from './CustomScrollbar/CustomScrollbar';
+
+// Select
+export { Select, AsyncSelect, SelectOptionItem } from './Select/Select';
+export { IndicatorsContainer } from './Select/IndicatorsContainer';
+export { NoOptionsMessage } from './Select/NoOptionsMessage';
+export { default as resetSelectStyles } from './Select/resetSelectStyles';
+
 export { LoadingPlaceholder } from './LoadingPlaceholder/LoadingPlaceholder';
 export { ColorPicker } from './ColorPicker/ColorPicker';
 export { SeriesColorPickerPopover } from './ColorPicker/SeriesColorPickerPopover';

+ 1 - 1
public/app/core/components/PermissionList/AddPermission.tsx

@@ -1,7 +1,7 @@
 import React, { Component } from 'react';
 import { UserPicker } from 'app/core/components/Select/UserPicker';
 import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker';
-import { Select, SelectOptionItem } from 'app/core/components/Select/Select';
+import { Select, SelectOptionItem } from '@grafana/ui';
 import { User } from 'app/types';
 import {
   dashboardPermissionLevels,

+ 1 - 1
public/app/core/components/PermissionList/DisabledPermissionListItem.tsx

@@ -1,5 +1,5 @@
 import React, { Component } from 'react';
-import Select from 'app/core/components/Select/Select';
+import { Select } from '@grafana/ui';
 import { dashboardPermissionLevels } from 'app/types/acl';
 
 export interface Props {

+ 1 - 1
public/app/core/components/PermissionList/PermissionListItem.tsx

@@ -1,5 +1,5 @@
 import React, { PureComponent } from 'react';
-import { Select } from 'app/core/components/Select/Select';
+import { Select } from '@grafana/ui';
 import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl';
 import { FolderInfo } from 'app/types';
 

+ 1 - 1
public/app/core/components/Select/DataSourcePicker.tsx

@@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
 import _ from 'lodash';
 
 // Components
-import Select from './Select';
+import { Select } from '@grafana/ui';
 
 // Types
 import { DataSourceSelectItem } from 'app/types';

+ 0 - 25
public/app/core/components/Select/ResetStyles.tsx

@@ -1,25 +0,0 @@
-export default {
-  clearIndicator: () => ({}),
-  container: () => ({}),
-  control: () => ({}),
-  dropdownIndicator: () => ({}),
-  group: () => ({}),
-  groupHeading: () => ({}),
-  indicatorsContainer: () => ({}),
-  indicatorSeparator: () => ({}),
-  input: () => ({}),
-  loadingIndicator: () => ({}),
-  loadingMessage: () => ({}),
-  menu: () => ({}),
-  menuList: ({ maxHeight }: { maxHeight: number }) => ({
-    maxHeight,
-  }),
-  multiValue: () => ({}),
-  multiValueLabel: () => ({}),
-  multiValueRemove: () => ({}),
-  noOptionsMessage: () => ({}),
-  option: () => ({}),
-  placeholder: () => ({}),
-  singleValue: () => ({}),
-  valueContainer: () => ({}),
-};

+ 1 - 1
public/app/core/components/Select/TeamPicker.tsx

@@ -1,6 +1,6 @@
 import React, { Component } from 'react';
 import _ from 'lodash';
-import { AsyncSelect } from './Select';
+import { AsyncSelect } from '@grafana/ui';
 import { debounce } from 'lodash';
 import { getBackendSrv } from 'app/core/services/backend_srv';
 

+ 1 - 1
public/app/core/components/Select/UnitPicker.tsx

@@ -1,5 +1,5 @@
 import React, { PureComponent } from 'react';
-import Select from './Select';
+import { Select } from '@grafana/ui';
 import kbn from 'app/core/utils/kbn';
 
 interface Props {

+ 1 - 1
public/app/core/components/Select/UserPicker.tsx

@@ -3,7 +3,7 @@ import React, { Component } from 'react';
 import _ from 'lodash';
 
 // Components
-import { AsyncSelect } from './Select';
+import { AsyncSelect } from '@grafana/ui';
 
 // Utils & Services
 import { debounce } from 'lodash';

+ 1 - 1
public/app/core/components/SharedPreferences/SharedPreferences.tsx

@@ -1,7 +1,7 @@
 import React, { PureComponent } from 'react';
 
 import { Label } from 'app/core/components/Label/Label';
-import Select from 'app/core/components/Select/Select';
+import { Select } from '@grafana/ui';
 import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
 
 import { DashboardSearchHit } from 'app/types';

+ 2 - 4
public/app/core/components/TagFilter/TagFilter.tsx

@@ -1,12 +1,10 @@
 import React from 'react';
+import { NoOptionsMessage, IndicatorsContainer, resetSelectStyles } from '@grafana/ui';
 import AsyncSelect from '@torkelo/react-select/lib/Async';
 
 import { TagOption } from './TagOption';
 import { TagBadge } from './TagBadge';
-import IndicatorsContainer from 'app/core/components/Select/IndicatorsContainer';
-import NoOptionsMessage from 'app/core/components/Select/NoOptionsMessage';
 import { components } from '@torkelo/react-select';
-import ResetStyles from 'app/core/components/Select/ResetStyles';
 
 export interface Props {
   tags: string[];
@@ -51,7 +49,7 @@ export class TagFilter extends React.Component<Props, any> {
       getOptionValue: i => i.value,
       getOptionLabel: i => i.label,
       value: tags,
-      styles: ResetStyles,
+      styles: resetSelectStyles(),
       filterOption: (option, searchQuery) => {
         const regex = RegExp(searchQuery, 'i');
         return regex.test(option.value);

+ 1 - 1
public/app/plugins/panel/gauge/MappingRow.tsx

@@ -1,6 +1,6 @@
 import React, { PureComponent } from 'react';
 import { Label } from 'app/core/components/Label/Label';
-import { Select } from 'app/core/components/Select/Select';
+import { Select } from '@grafana/ui';
 import { MappingType, RangeMap, ValueMap } from 'app/types';
 
 interface Props {

+ 1 - 1
public/app/plugins/panel/gauge/ValueOptions.tsx

@@ -1,6 +1,6 @@
 import React, { PureComponent } from 'react';
 import { Label } from 'app/core/components/Label/Label';
-import Select from 'app/core/components/Select/Select';
+import { Select} from '@grafana/ui';
 import UnitPicker from 'app/core/components/Select/UnitPicker';
 import { PanelOptionsProps } from '@grafana/ui';
 import { Options } from './types';

+ 4 - 5
public/sass/_grafana.scss

@@ -1,4 +1,4 @@
-// DEPENDENCIES
+ // DEPENDENCIES
 @import '../../node_modules/react-table/react-table.css';
 
 // VENDOR
@@ -38,9 +38,6 @@
 @import 'layout/lists';
 @import 'layout/page';
 
-// LOAD @grafana/ui components
-@import '../../packages/grafana-ui/src/index';
-
 // COMPONENTS
 @import 'components/scrollbar';
 @import 'components/cards';
@@ -97,7 +94,6 @@
 @import 'components/page_header';
 @import 'components/dashboard_settings';
 @import 'components/empty_list_cta';
-@import 'components/form_select_box';
 @import 'components/panel_editor';
 @import 'components/toolbar';
 @import 'components/add_data_source.scss';
@@ -107,6 +103,9 @@
 @import 'components/value-mappings';
 @import 'components/popover-box';
 
+// LOAD @grafana/ui components
+@import '../../packages/grafana-ui/src/index';
+
 // PAGES
 @import 'pages/login';
 @import 'pages/dashboard';

+ 2 - 2
yarn.lock

@@ -1105,7 +1105,7 @@
   dependencies:
     "@types/react" "*"
 
-"@types/react@*", "@types/react@^16.1.0", "@types/react@^16.7.6":
+"@types/react@*", "@types/react@16.7.6", "@types/react@^16.1.0", "@types/react@^16.7.6":
   version "16.7.6"
   resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"
   integrity sha512-QBUfzftr/8eg/q3ZRgf/GaDP6rTYc7ZNem+g4oZM38C9vXyV8AWRWaTQuW5yCoZTsfHrN7b3DeEiUnqH9SrnpA==
@@ -3185,7 +3185,7 @@ caniuse-api@^1.5.2:
     lodash.memoize "^4.1.2"
     lodash.uniq "^4.5.0"
 
-caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
+caniuse-db@1.0.30000772, caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
   version "1.0.30000772"
   resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000772.tgz#51aae891768286eade4a3d8319ea76d6a01b512b"
   integrity sha1-UarokXaChureSj2DGep21qAbUSs=