Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export type Operator = {
hideValue?: boolean
warning?: string
valuePlaceholder?: string
append?: string
type?: string
}
export type ChangeRequestSummary = {
id: number
Expand Down
177 changes: 0 additions & 177 deletions frontend/web/components/base/select/MultiSelect.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { MultiValueProps } from 'react-select/lib/components/MultiValue'
import { MultiSelectOption } from './MultiSelect'

export const CustomMultiValue = ({
color,
data,
removeProps,
}: MultiValueProps<MultiSelectOption> & { color?: string }) => {
return (
<div
className='d-flex align-items-center'
style={{
backgroundColor: color,
borderRadius: '4px',
color: 'white',
fontSize: '12px',
maxWidth: '150px',
overflow: 'hidden',
padding: '2px 6px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
maxHeight: '24px'
}}
>
<span
className='mr-1'
style={{
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{data.label}
</span>
<span
onClick={() => removeProps?.onClick?.(data)}
style={{
cursor: 'pointer',
fontSize: '14px',
lineHeight: '1',
}}
>
×
</span>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import { OptionProps } from 'react-select/lib/components/Option'
import { MultiSelectOption } from './MultiSelect'

export const CustomOption = ({
children,
color,
...props
}: OptionProps<MultiSelectOption> & { color?: string }) => {
return (
<div
{...props.innerProps}
className={`d-flex align-items-center p-2 ${
props.isFocused ? 'bg-light' : ''
}`}
style={{ cursor: 'pointer' }}
>
{color && (
<div
style={{
backgroundColor: color,
borderRadius: '2px',
flexShrink: 0,
height: '12px',
marginRight: '8px',
width: '12px',
}}
/>
)}
<span>{children}</span>
</div>
)
}
105 changes: 105 additions & 0 deletions frontend/web/components/base/select/multi-select/MultiSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import classNames from 'classnames'
import React, { FC } from 'react'
import { MultiValueProps } from 'react-select/lib/components/MultiValue'
import { OptionProps } from 'react-select/lib/components/Option'

import { CustomMultiValue } from './CustomMultiValue'
import { CustomOption } from './CustomOption'

export interface MultiSelectOption {
label: string
value: string
}

export interface MultiSelectProps {
selectedValues: string[]
onSelectionChange: (selectedValues: string[]) => void
options: MultiSelectOption[]
colorMap?: Map<string, string>
label?: string
placeholder?: string
className?: string
disabled?: boolean
size?: 'small' | 'default' | 'large'
hideSelectedOptions?: boolean
inline?: boolean
}

export const MultiSelect: FC<MultiSelectProps> = ({
className = '',
colorMap,
disabled = false,
label,
onSelectionChange,
options,
placeholder = 'Select options...',
selectedValues,
size = 'default',
hideSelectedOptions = false,
}) => {
return (
<div className={classNames(
className,
label ? `d-flex flex-column gap-2` : ''
)}>
{label && <label>{label}</label>}
<Select
isMulti
hideSelectedOptions={hideSelectedOptions}
closeMenuOnSelect={false}
placeholder={placeholder}
isDisabled={disabled}
size={size}
onChange={(selectedOptions: MultiSelectOption[]) => {
const values = selectedOptions
? selectedOptions.map((opt: MultiSelectOption) => opt.value)
: []
onSelectionChange(values)
}}
components={{
MultiValue: (props: MultiValueProps<MultiSelectOption>) => (
<CustomMultiValue
{...props}
color={colorMap?.get(props.data.value) || '#5D6D7E'}
/>
),
...(colorMap ? {Option: (props: OptionProps<MultiSelectOption>) => <CustomOption
{...props}
color={colorMap.get(props.data.value)}
/>} : {}),
}}
value={selectedValues.map((value) => ({
label: options.find((opt) => opt.value === value)?.label || value,
value,
}))}
options={options}
className='react-select react-select__extensible w-100'
styles={{
control: (base: any) => ({
...base,
cursor: 'pointer',
}),
multiValue: (base: any) => ({
...base,
flexShrink: 0,
margin: '2px',
}),
valueContainer: (base: any) => ({
...base,
flexWrap: 'nowrap',
gap: '2px',
paddingBottom: '6px',
paddingTop: '6px',
flex: 1
}),
input: (base: any) => ({
...base,
margin: 0,
paddingBottom: 0,
paddingTop: 0,
}),
}}
/>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { MultiSelect } from './MultiSelect'
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class TheComponent extends Component {
/>
<div>
<InputGroup
className="col-4"
component={
<EnvironmentSelect
projectId={this.props.projectId}
Expand Down
Loading
Loading