Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions docs/docs/feature-library/enhanced-crm-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const actionHook = function addToEnhancedCRM(flex: typeof Flex, manager:
title: 'My Custom CRM Tab',
order: 0, // optionally define preferred tab order, defaults to 999 if not present
component: <MyCRMTab task={payload.task} key="my-crm-tab" />,
accessoryComponents: [], // optionally define components that should appear within the tab label itself when selected. Array items are objects with `component` and optionally `order` props.
},
];
});
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
import React, { useState, useRef } from 'react';
import { IconButton, ITask } from '@twilio/flex-ui';
import EventEmitter from 'events';

import React, { useEffect, useState, useRef } from 'react';
import { ITask } from '@twilio/flex-ui';

import { IFrameRefreshButtonStyledDiv } from './IFrameCRMTab.Styles';
import { getUrl, displayUrlWhenNoTasks } from '../../config';
import { replaceStringAttributes } from '../../../../utils/helpers';

export interface Props {
task: ITask;
reloadEmitter: EventEmitter;
}

export const IFrameCRMTab = ({ task }: Props) => {
export const IFrameCRMTab = ({ task, reloadEmitter }: Props) => {
const iFrameRef = useRef<HTMLIFrameElement>(null);
const [iFrameKey, setIframeKey] = useState(0 as number);

useEffect(() => {
reloadEmitter.on('reload', handleOnClick);

return () => {
reloadEmitter.off('reload', handleOnClick);
};
}, []);

const handleOnClick = () => {
setIframeKey(Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER + 1)));
};

const url = replaceStringAttributes(task ? getUrl() : displayUrlWhenNoTasks(), task);

return (
<>
<IFrameRefreshButtonStyledDiv onClick={handleOnClick}>
<IconButton variant="primary" icon="Loading" />
</IFrameRefreshButtonStyledDiv>
<iframe key={iFrameKey} src={url} ref={iFrameRef} />
</>
);
return <iframe key={iFrameKey} src={url} ref={iFrameRef} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Actions, ITask } from '@twilio/flex-ui';
import { Flex } from '@twilio-paste/core/flex';
import { Tabs, TabList, Tab, TabPanels, TabPanel, useTabState } from '@twilio-paste/core/tabs';
import { Stack } from '@twilio-paste/core/stack';

export interface Props {
thisTask?: ITask; // task assigned to component
Expand All @@ -21,6 +22,12 @@ interface CRMComponent {
title: string;
component: React.ComponentType;
order?: number;
accessoryComponents?: CRMAccessoryComponent[];
}

interface CRMAccessoryComponent {
component: React.ComponentType;
order?: number;
}

export const TabbedCRMTask = ({ thisTask, task }: Props) => {
Expand Down Expand Up @@ -76,7 +83,22 @@ export const TabbedCRMTask = ({ thisTask, task }: Props) => {
<Tabs state={tabState} element="CRM_TABS">
<TabList aria-label="CRM tabs" element="CRM_TAB_LIST">
{customComponents &&
customComponents.map((component) => <Tab key={`crm-tab-${component.title}`}>{component.title}</Tab>)}
customComponents.map((component) => (
<Tab key={`crm-tab-${component.title}`} id={`crm-tab-${component.title}`}>
{tabState.selectedId === `crm-tab-${component.title}` && component.accessoryComponents?.length ? (
<Stack orientation="horizontal" spacing="space30">
{component.title}
<Stack orientation="horizontal" spacing="space30" element="CRM_TAB_ACCESSORY_STACK">
{component.accessoryComponents
.sort((a, b) => (a.order ?? 999) - (b.order ?? 999))
.map((accessoryComponent) => accessoryComponent.component)}
</Stack>
</Stack>
) : (
component.title
)}
</Tab>
))}
</TabList>
<TabPanels element="CRM_TAB_PANELS">
{customComponents &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import EventEmitter from 'events';

import * as Flex from '@twilio/flex-ui';
import { Button } from '@twilio-paste/core/button';
import { LoadingIcon } from '@twilio-paste/icons/esm/LoadingIcon';

import IFrameCRMTab from '../../custom-components/IFrameCRMTab';
import { FlexActionEvent } from '../../../../types/feature-loader';
import { shouldDisplayUrlWhenNoTasks, getUrlTabTitle, isUrlTabEnabled } from '../../config';

export const actionEvent = FlexActionEvent.before;
export const actionName = 'LoadCRMContainerTabs';
export const actionHook = function addURLTabToEnhancedCRM(flex: typeof Flex) {
export const actionHook = function addURLTabToEnhancedCRM(flex: typeof Flex, manager: Flex.Manager) {
if (!isUrlTabEnabled()) {
return;
}
Expand All @@ -15,9 +19,29 @@ export const actionHook = function addURLTabToEnhancedCRM(flex: typeof Flex) {
return;
}

const reloadEmitter = new EventEmitter();

payload.components = [
...payload.components,
{ title: getUrlTabTitle(), component: <IFrameCRMTab task={payload.task} key="iframe-crm-container" /> },
{
title: getUrlTabTitle(),
component: <IFrameCRMTab reloadEmitter={reloadEmitter} task={payload.task} key="iframe-crm-container" />,
accessoryComponents: [
{
component: (
<Button
variant="secondary_icon"
size="icon_small"
onClick={() => reloadEmitter.emit('reload')}
key="iframe-reload-button"
>
<LoadingIcon decorative={false} title={manager.strings.IframeReloadButtonLabel} />
</Button>
),
order: 0,
},
],
},
];
});
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { PasteCustomCSS } from '@twilio-paste/customization';

export const pasteElementHook = {
CRM_TAB_PANEL: {
overflowY: 'scroll',
Expand All @@ -22,8 +20,12 @@ export const pasteElementHook = {
CRM_TAB_LIST_CHILD: {
marginBottom: 'space0',
},
CRM_TAB_ACCESSORY_STACK: {
marginTop: '-0.75rem',
marginBottom: '-0.75rem',
},
CRM_FLEX: {
alignItems: 'stretch',
overflow: 'auto',
},
} as { [key: string]: PasteCustomCSS };
} as { [key: string]: any };
Loading