All files / libs/payout-definition/plans/components/src/lib/unique-by-form-component UniqueByFormComponent.tsx

0% Statements 0/105
0% Branches 0/1
0% Functions 0/1
0% Lines 0/105

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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106                                                                                                                                                                                                                   
import { css } from '@emotion/react';
import { IconPlus, IconTrash } from '@tabler/icons-react';
import { memo, useCallback, useMemo } from 'react';
import { FormattedMessage } from 'react-intl';

import {
  Button,
  FormFieldLabel,
  Group,
  IconButton,
  Select,
  Stack,
  type SelectOption,
} from '@allshares/studio-design-system';
import { buildPropertiesOptions } from '@amalia/data-capture/fields/components';
import { getProperties, type CustomObjectDefinition } from '@amalia/data-capture/record-models/types';
import { type FilterUniqueBy } from '@amalia/payout-definition/plans/types';

interface OrderByFormComponentProps {
  readonly customObjectDefinition?: CustomObjectDefinition;
  readonly value: FilterUniqueBy[] | null;
  readonly onChange: (value: FilterUniqueBy[]) => void;
}

export const UniqueByFormComponent = memo(function UniqueByFormComponent({
  customObjectDefinition,
  value,
  onChange,
}: OrderByFormComponentProps) {
  const propertyOptions = useMemo(
    () => buildPropertiesOptions(getProperties(customObjectDefinition), customObjectDefinition?.externalIds[0] ?? null),
    [customObjectDefinition],
  );

  const onChangeFieldMachineName = useCallback(
    (index: number, fieldMachineName: string) => {
      onChange(value!.map((v, i) => (i === index ? { ...v, fieldMachineName } : v)));
    },
    [value, onChange],
  );

  const handleAddElement = useCallback(() => {
    const propertyToAdd = customObjectDefinition && getProperties(customObjectDefinition).at(0)?.machineName;
    if (propertyToAdd) {
      onChange((value ?? []).concat({ fieldMachineName: propertyToAdd }));
    }
  }, [value, onChange, customObjectDefinition]);

  const handleDelete = useCallback(
    (index: number) => {
      onChange((value ?? []).filter((_, i) => index !== i));
    },
    [value, onChange],
  );

  return (
    <Stack gap={value?.length ? 12 : 6}>
      <FormFieldLabel size="small">
        <FormattedMessage defaultMessage="Unique by" />
      </FormFieldLabel>
      <Stack gap={12}>
        {(value ?? []).map(({ fieldMachineName }, index) => (
          <Group
            // eslint-disable-next-line react/no-array-index-key -- no id to order on here.
            key={index}
            align="center"
            gap={12}
            css={css`
              & > div {
                flex-grow: 1;
                max-width: 600px;
              }
            `}
          >
            <Select<SelectOption<string>, false, false, false>
              isClearable={false}
              options={propertyOptions}
              size="small"
              value={fieldMachineName}
              onChange={(newValue) => onChangeFieldMachineName(index, newValue)}
            />

            <IconButton
              icon={<IconTrash />}
              label={<FormattedMessage defaultMessage="Delete unique by" />}
              size="small"
              variant="danger"
              onClick={() => handleDelete(index)}
            />
          </Group>
        ))}
      </Stack>
      <div>
        <Button
          icon={<IconPlus />}
          size="small"
          variant="primary-light"
          onClick={handleAddElement}
        >
          <FormattedMessage defaultMessage="Add unique by" />
        </Button>
      </div>
    </Stack>
  );
});