Просмотр исходного кода

Merge pull request #172 from smiclea/dropdown-duplicates

Improve duplicated items in the dropdown component
Dorin Paslaru 8 лет назад
Родитель
Сommit
e71fd19250

+ 11 - 7
private/storybook/Decorator.jsx

@@ -15,7 +15,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // @flow
 
 import * as React from 'react'
-import styled from 'styled-components'
+import styled, { injectGlobal } from 'styled-components'
 import Palette from '../../src/components/styleUtils/Palette'
 import StyleProps from '../../src/components/styleUtils/StyleProps'
 
@@ -23,12 +23,16 @@ const Wrapper = styled.div`
   display: inline-block;
   background: ${Palette.grayscale[7]};
   padding: 32px;
-  color: ${Palette.black};
-  font-family: Rubik;
-  font-size: 14px;
-  font-weight: ${StyleProps.fontWeights.regular};
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
+`
+injectGlobal`
+  body {
+    color: ${Palette.black};
+    font-family: Rubik;
+    font-size: 14px;
+    font-weight: ${StyleProps.fontWeights.regular};
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+  }
 `
 
 type Props = {

+ 38 - 4
src/components/molecules/Dropdown/index.jsx

@@ -87,11 +87,21 @@ const ListItem = styled.div`
     color: white;
   }
 `
+const DuplicatedLabel = styled.div`
+  display: flex;
+  font-size: 11px;
+  span {
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    overflow: hidden;
+  }
+`
 
 type Props = {
   selectedItem: any,
   items: any[],
   labelField: string,
+  valueField: string,
   className: string,
   onChange: (item: any) => void,
   noItemsMessage: string,
@@ -153,6 +163,16 @@ class Dropdown extends React.Component<Props, State> {
     return (item[labelField] !== null && item[labelField] !== undefined && item[labelField].toString()) || item.toString()
   }
 
+  getValue(item: any) {
+    let valueField = this.props.valueField || 'value'
+
+    if (item === null || item === undefined) {
+      return null
+    }
+
+    return (item[valueField] !== null && item[valueField] !== undefined && item[valueField].toString()) || this.getLabel(item)
+  }
+
   handlePageClick() {
     if (!this.itemMouseDown) {
       this.setState({ showDropdownList: false })
@@ -220,23 +240,37 @@ class Dropdown extends React.Component<Props, State> {
     }
 
     const body: any = document.body
-    let selectedLabel = this.getLabel(this.props.selectedItem)
+    let selectedValue = this.getValue(this.props.selectedItem)
+    let duplicatedLabels = []
+    this.props.items.forEach((item, i) => {
+      let label = this.getLabel(item)
+      for (let j = i + 1; j < this.props.items.length; j += 1) {
+        if (label === this.getLabel(this.props.items[j]) && !duplicatedLabels.find(item2 => this.getLabel(item2) === label)) {
+          duplicatedLabels.push(label)
+        }
+      }
+    })
+
     let list = ReactDOM.createPortal((
       <List {...this.props} innerRef={ref => { this.listRef = ref }}>
         <Tip innerRef={ref => { this.tipRef = ref }} primary={this.state.firstItemHover} />
         <ListItems>
           {this.props.items.map((item, i) => {
             let label = this.getLabel(item)
+            let value = this.getValue(item)
+            let duplicatedLabel = duplicatedLabels.find(l => l === label)
             let listItem = (
               <ListItem
-                key={label}
+                key={value}
                 onMouseDown={() => { this.itemMouseDown = true }}
                 onMouseUp={() => { this.itemMouseDown = false }}
                 onMouseEnter={() => { this.handleItemMouseEnter(i) }}
                 onMouseLeave={() => { this.handleItemMouseLeave(i) }}
                 onClick={() => { this.handleItemClick(item) }}
-                selected={label === selectedLabel}
-              >{label}
+                selected={value === selectedValue}
+              >
+                {label}
+                {duplicatedLabel ? <DuplicatedLabel> (<span>{value || ''}</span>)</DuplicatedLabel> : ''}
               </ListItem>
             )
 

+ 1 - 0
src/components/molecules/Dropdown/story.jsx

@@ -20,6 +20,7 @@ const items = [
   { label: 'Item 1', value: 'item-1' },
   { label: 'Item 2', value: 'item-2' },
   { label: 'Item 3', value: 'item-3' },
+  { label: 'Item 3', value: 'item-3-duplicated' },
 ]
 
 class Wrapper extends React.Component {

+ 1 - 1
src/components/molecules/WizardOptionsField/index.jsx

@@ -120,7 +120,7 @@ class WizardOptionsField extends React.Component<Props> {
       <Dropdown
         width={320}
         noSelectionMessage="Choose a value"
-        selectedItem={selectedItem ? selectedItem.label : null}
+        selectedItem={selectedItem}
         items={items}
         onChange={item => this.props.onChange(item.value)}
       />

+ 1 - 0
src/components/organisms/WizardEndpointList/index.jsx

@@ -96,6 +96,7 @@ class WizardEndpointList extends React.Component<Props> {
         <Dropdown
           primary={Boolean(selectedItem)}
           items={items}
+          valueField="id"
           labelField="name"
           noSelectionMessage="Select"
           centered

+ 3 - 5
src/components/organisms/WizardNetworks/index.jsx

@@ -173,10 +173,7 @@ class WizardNetworks extends React.Component<Props> {
             }
             return false
           }).map(i => i.instance_name)
-          let selectedNetworkName = this.props.selectedNetworks && this.props.selectedNetworks.find(n => n.sourceNic.network_name === nic.network_name)
-          if (selectedNetworkName) {
-            selectedNetworkName = selectedNetworkName.targetNetwork.name
-          }
+          let selectedNetwork = this.props.selectedNetworks && this.props.selectedNetworks.find(n => n.sourceNic.network_name === nic.network_name)
           return (
             <Nic key={nic.id}>
               <NetworkImage />
@@ -190,9 +187,10 @@ class WizardNetworks extends React.Component<Props> {
                 centered
                 noSelectionMessage="Select ..."
                 noItemsMessage="No networks found"
-                selectedItem={selectedNetworkName}
+                selectedItem={selectedNetwork ? selectedNetwork.targetNetwork : null}
                 items={this.props.networks}
                 labelField="name"
+                valueField="id"
                 onChange={(item: Network) => { this.props.onChange(nic, item) }}
               />
             </Nic>