7417 workflows i can send emails using the email account (#7431)
- update `send-email.workflow-action.ts` so it send email via the google sdk - remove useless `workflow-action.email.ts` - add `send` authorization to google api scopes - update the front workflow email step form to provide a `connectedAccountId` from the available connected accounts - update the permissions of connected accounts: ask users to reconnect when selecting missing send permission 
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useMemo, useRef, useState } from 'react';
|
||||
import React, { MouseEvent, useMemo, useRef, useState } from 'react';
|
||||
import { IconChevronDown, IconComponent } from 'twenty-ui';
|
||||
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
@ -11,6 +11,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
import { SelectHotkeyScope } from '../types/SelectHotkeyScope';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export type SelectOption<Value extends string | number | null> = {
|
||||
value: Value;
|
||||
@ -18,6 +19,12 @@ export type SelectOption<Value extends string | number | null> = {
|
||||
Icon?: IconComponent;
|
||||
};
|
||||
|
||||
type CallToActionButton = {
|
||||
text: string;
|
||||
onClick: (event: MouseEvent<HTMLDivElement>) => void;
|
||||
Icon?: IconComponent;
|
||||
};
|
||||
|
||||
export type SelectProps<Value extends string | number | null> = {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
@ -32,6 +39,7 @@ export type SelectProps<Value extends string | number | null> = {
|
||||
options: SelectOption<Value>[];
|
||||
value?: Value;
|
||||
withSearchInput?: boolean;
|
||||
callToActionButton?: CallToActionButton;
|
||||
};
|
||||
|
||||
const StyledContainer = styled.div<{ fullWidth?: boolean }>`
|
||||
@ -89,6 +97,7 @@ export const Select = <Value extends string | number | null>({
|
||||
options,
|
||||
value,
|
||||
withSearchInput,
|
||||
callToActionButton,
|
||||
}: SelectProps<Value>) => {
|
||||
const selectContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -97,8 +106,8 @@ export const Select = <Value extends string | number | null>({
|
||||
|
||||
const selectedOption =
|
||||
options.find(({ value: key }) => key === value) ||
|
||||
options[0] ||
|
||||
emptyOption;
|
||||
emptyOption ||
|
||||
options[0];
|
||||
const filteredOptions = useMemo(
|
||||
() =>
|
||||
searchInputValue
|
||||
@ -109,7 +118,9 @@ export const Select = <Value extends string | number | null>({
|
||||
[options, searchInputValue],
|
||||
);
|
||||
|
||||
const isDisabled = disabledFromProps || options.length <= 1;
|
||||
const isDisabled =
|
||||
disabledFromProps ||
|
||||
(options.length <= 1 && !isDefined(callToActionButton));
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
@ -177,6 +188,18 @@ export const Select = <Value extends string | number | null>({
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
)}
|
||||
{!!callToActionButton && !!filteredOptions.length && (
|
||||
<DropdownMenuSeparator />
|
||||
)}
|
||||
{!!callToActionButton && (
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
<MenuItem
|
||||
onClick={callToActionButton.onClick}
|
||||
LeftIcon={callToActionButton.Icon}
|
||||
text={callToActionButton.text}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }}
|
||||
|
||||
@ -4,6 +4,7 @@ import { userEvent, within } from '@storybook/test';
|
||||
import { ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
import { Select, SelectProps } from '../Select';
|
||||
import { IconPlus } from 'packages/twenty-ui';
|
||||
|
||||
type RenderProps = SelectProps<string | number | null>;
|
||||
|
||||
@ -56,3 +57,13 @@ export const Disabled: Story = {
|
||||
export const WithSearch: Story = {
|
||||
args: { withSearchInput: true },
|
||||
};
|
||||
|
||||
export const CallToActionButton: Story = {
|
||||
args: {
|
||||
callToActionButton: {
|
||||
onClick: () => {},
|
||||
Icon: IconPlus,
|
||||
text: 'Add action',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user