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
52 changes: 23 additions & 29 deletions src/components/ContextMenu/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ type Position = StrictPopupProps["position"];

type IParamsForAction = {
selection: any[];
isOpened: boolean;
/**
* Position for the popover.
*/
position?: Position;
[key: string]: any;
}
interface ContextMenuProps {
actions: IAction[];

paramsForAction: IParamsForAction;
/**
* if undefined => the menu is closed else {x, y} position where the menu should open
* The coordinates {x, y} of position where the menu should be rendered when it's opened
*/
positionToOpen?: Point;
/**
* Callback for extra actions when the menu is closed
*/
onClose?: () => void;
[key: string]: any;
}
interface ContextMenuProps {
actions: IAction[];

actionParam: IParamsForAction;
}

const testids = createTestids('ContextMenu', {
Expand All @@ -32,30 +36,20 @@ const testids = createTestids('ContextMenu', {
});
export const contextMenuTestIds = testids;

export class ContextMenu extends React.Component<ContextMenuProps, { isOpened?: boolean }> {
export class ContextMenu extends React.Component<ContextMenuProps> {

constructor(props) {
constructor(props: ContextMenuProps) {
super(props);
this.close = this.close.bind(this);
this.state = {
isOpened: props.positionToOpen
}
}

componentDidUpdate(prevProps: Readonly<ContextMenuProps>, prevState: Readonly<{}>, snapshot?: any): void {
if (this.props.positionToOpen != prevProps.positionToOpen) {
this.setState({ isOpened: this.props.positionToOpen ? true : false });
}
}

close() {
this.setState({ isOpened: false });
this.props.onClose && this.props.onClose();
this.props.actionParam.onClose && this.props.actionParam.onClose();
}

getPopupContext(): HTMLElement {
const x = this.props.positionToOpen?.x;
const y = this.props.positionToOpen?.y;
const x = this.props.actionParam.positionToOpen?.x;
const y = this.props.actionParam.positionToOpen?.y;
return {
getBoundingClientRect: () => ({
left: x,
Expand All @@ -69,18 +63,18 @@ export class ContextMenu extends React.Component<ContextMenuProps, { isOpened?:
}

getVisisbleActions(actions: IAction[]): IAction[] {
return actions.filter(action => action.isVisible ? action.isVisible(this.props.paramsForAction) : true);
return actions.filter(action => action.isVisible ? action.isVisible(this.props.actionParam) : true);
}

render() {
const visibleActions = this.getVisisbleActions(this.props.actions);
return <>
<TestsAreDemoCheat objectToPublish={this} />
<Popup basic wide='very' data-testid={testids.popup} context={this.getPopupContext()}
position={this.props.paramsForAction.position}
position={this.props.actionParam.position}
onClose={() => {
this.close();
}} open={(this.state.isOpened && visibleActions.length > 0)}>
}} open={(this.props.actionParam.isOpened && visibleActions.length > 0)}>
<Menu className="rct9k-context-menu" secondary vertical>
{visibleActions.map((action: IAction) => {
const key = visibleActions.indexOf(action);
Expand All @@ -89,17 +83,17 @@ export class ContextMenu extends React.Component<ContextMenuProps, { isOpened?:
data-testid={testids.menuItem + "_" + key}
key={key}
icon={action.icon}
disabled={action.isDisabled ? action.isDisabled(this.props.paramsForAction) : false}
content={action.label instanceof Function ? action.label({ ...this.props.paramsForAction }) : action.label}
disabled={action.isDisabled ? action.isDisabled(this.props.actionParam) : false}
content={action.label instanceof Function ? action.label({ ...this.props.actionParam }) : action.label}
onClick={(event) => {
let params: IActionParamForRun = { ...this.props.paramsForAction, closeContextMenu: this.close, eventPoint: { x: event.clientX, y: event.clientY } }
let params: IActionParamForRun = { ...this.props.actionParam, closeContextMenu: this.close, eventPoint: { x: event.clientX, y: event.clientY } }
action.run && action.run(params);
if (!params.dontCloseContextMenuAfterRunAutomatically) {
this.close();
}
}}>
</Menu.Item>
: React.cloneElement(action.renderInMenu({ ...this.props.paramsForAction, closeContextMenu: this.close }), { key: visibleActions.indexOf(action), "data-testid": testids.menuItem + "_" + key })
: React.cloneElement(action.renderInMenu({ ...this.props.actionParam, closeContextMenu: this.close }), { key: visibleActions.indexOf(action), "data-testid": testids.menuItem + "_" + key })
);
})
}
Expand Down
19 changes: 10 additions & 9 deletions src/timeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,7 @@ export default class Timeline extends React.Component {
);
});

if (this._table) {
if (this._table && this._table.getApi().updateRowHeights) {
this._table.getApi().updateRowHeights();
}
}
Expand Down Expand Up @@ -2194,12 +2194,19 @@ export default class Timeline extends React.Component {
* @returns { JSX.Element }
*/
renderContextMenu() {
const actionParam = {
let actionParam = {
selection: this._selectionHolder ? this._selectionHolder.state.selectedItems : [],
row: this.state.openedContextMenuRow,
time: this.state.openedContextMenuTime
};
let actions = this.props.onContextMenuShow ? this.props.onContextMenuShow({actionParam}) : [];
let positionToOpen = actions.length > 0 ? this.state.openedContextMenuCoordinates : undefined;
actionParam = {
...actionParam,
positionToOpen,
isOpened: positionToOpen ? true : false,
onClose: () => this.setState({openedContextMenuCoordinates: undefined})
};
if (this.props.onDragToCreateEnded && this.props.forceDragToCreateMode == undefined) {
// If the user doesn't forces the enter/exit from dragToCreateMode =>
// a default mechanism is implemented via an action that enters the drag to create mode
Expand Down Expand Up @@ -2248,13 +2255,7 @@ export default class Timeline extends React.Component {
});
}

return (
<ContextMenu
paramsForAction={actionParam}
positionToOpen={actions.length > 0 ? this.state.openedContextMenuCoordinates : undefined}
actions={actions}
/>
);
return <ContextMenu actionParam={actionParam} actions={actions} />;
}

/**
Expand Down