Quellcode durchsuchen

Improve duplicated items in the dropdown component

For each duplicated item in a dropdown list, display its ID value bellow
its label, this makes it much more easier to understand what's actually
selected. No changes should be seen if there're no duplicated items.

For a quick test of this feature, create an endpoint with the same name
as an existing one, go to Wizard's source or target selection page and
open the dropdown containing the duplicated endpoint names.
Sergiu Miclea vor 8 Jahren
Ursprung
Commit
dcde890bc6

+ 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>