All files / modules/70-pipeline/components/StageSelection StageSelection.tsx

100% Statements 16/16
57.14% Branches 4/7
100% Functions 4/4
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86              2x 2x 2x 2x 2x   2x   2x 2x   2x                       2x 3x 3x   3x             16x                                             18x                                          
/*
 * Copyright 2021 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
import React from 'react'
import { Select as BPSelect, ISelectProps, IItemRendererProps } from '@blueprintjs/select'
import { Button, IconName, Icon } from '@wings-software/uicore'
import { Menu } from '@blueprintjs/core'
import cx from 'classnames'
 
import { String } from 'framework/strings'
import type { StageSelectOption } from '@pipeline/components/PipelineStudio/CommonUtils/CommonUtils'
import { getIconFromStageModule, getIconStylesFromCollection } from '@pipeline/utils/executionUtils'
import css from './StageSelection.module.scss'
 
const Select = BPSelect.ofType<StageSelectOption>()
 
export type { StageSelectOption }
 
export interface StageSelectionProps
  extends Omit<ISelectProps<StageSelectOption>, 'itemRenderer' | 'items' | 'onItemSelect'> {
  selectedStageId?: string
  selectOptions: StageSelectOption[]
  onStageChange(item: StageSelectOption): void
  chevronIcon?: IconName
}
 
export function StageSelection(props: StageSelectionProps): React.ReactElement {
  const { selectOptions, onStageChange, selectedStageId, chevronIcon = 'chevron-down', className, ...rest } = props
  const selectedStage = selectOptions.find(({ value }) => value === selectedStageId)
 
  return (
    <Select
      className={cx(css.select, className)}
      itemRenderer={(
        item: StageSelectOption,
        { modifiers: { disabled }, handleClick }: IItemRendererProps
      ): React.ReactElement => {
        return (
          <Menu.Item
            key={item.value as string}
            className={css.menuItem}
            active={item.value === selectedStageId}
            onClick={handleClick}
            disabled={disabled}
            text={
              <React.Fragment>
                <Icon
                  className={css.icon}
                  name={getIconFromStageModule(item.type.toLowerCase(), item.node?.nodeType)}
                  style={getIconStylesFromCollection(item.node.nodeType)}
                />
                <span>{item.label}</span>
              </React.Fragment>
            }
          />
        )
      }}
      items={selectOptions}
      onItemSelect={onStageChange}
      filterable={false}
      itemsEqual={(a, b) => a.value === b.value}
      {...rest}
      popoverProps={{ minimal: true, wrapperTagName: 'div', targetTagName: 'div', ...rest.popoverProps }}
    >
      <Button className={css.btn} rightIcon={chevronIcon} iconProps={{ className: css.icon }}>
        {selectedStage ? (
          <React.Fragment>
            <Icon
              className={css.icon}
              name={getIconFromStageModule(selectedStage.type.toLowerCase(), selectedStage.node.nodeType)}
              style={getIconStylesFromCollection(selectedStage.node.nodeType)}
            />
            <span>{selectedStage.label}</span>
          </React.Fragment>
        ) : (
          <String stringID="selectStage" />
        )}
      </Button>
    </Select>
  )
}