chore: Updated TableView component in table extension to solve sentry (#3309)

error of table not being defined while getting getBoundingClientRect()
and solve other TS issues

- Added ResolvedPos import from @tiptap/pm/model
- Updated setCellsBackgroundColor function parameter type to string
- Declared ToolboxItem type for toolbox items
- Modified columnsToolboxItems and rowsToolboxItems to use the ToolboxItem type
- Updated createToolbox function parameters to specify Element or null for triggerButton and ToolboxItem[] for items
- Added ts-expect-error comment above the toolbox variable declaration
- Updated update method parameter type to readonly Decoration[]
- Changed destructuring assignment of hoveredTable and hoveredCell in updateControls method to use Object.values and reduce method
- Added null check for this.table in updateControls method
- Wrapped the code that updates columnsControl and rowsControl with null checks for each control
- Replaced ts-ignore comments with proper dispatch calls in selectColumn and selectRow methods

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
M. Palanikannan 2024-01-04 16:30:10 +05:30 committed by sriram veeraghanta
parent 64ca267db4
commit b340232e76

View File

@ -1,5 +1,5 @@
import { h } from "jsx-dom-cjs"; import { h } from "jsx-dom-cjs";
import { Node as ProseMirrorNode } from "@tiptap/pm/model"; import { Node as ProseMirrorNode, ResolvedPos } from "@tiptap/pm/model";
import { Decoration, NodeView } from "@tiptap/pm/view"; import { Decoration, NodeView } from "@tiptap/pm/view";
import tippy, { Instance, Props } from "tippy.js"; import tippy, { Instance, Props } from "tippy.js";
@ -8,6 +8,12 @@ import { CellSelection, TableMap, updateColumnsOnResize } from "@tiptap/pm/table
import { icons } from "src/ui/extensions/table/table/icons"; import { icons } from "src/ui/extensions/table/table/icons";
type ToolboxItem = {
label: string;
icon: string;
action: (args: any) => void;
};
export function updateColumns( export function updateColumns(
node: ProseMirrorNode, node: ProseMirrorNode,
colgroup: HTMLElement, colgroup: HTMLElement,
@ -75,7 +81,7 @@ const defaultTippyOptions: Partial<Props> = {
placement: "right", placement: "right",
}; };
function setCellsBackgroundColor(editor: Editor, backgroundColor) { function setCellsBackgroundColor(editor: Editor, backgroundColor: string) {
return editor return editor
.chain() .chain()
.focus() .focus()
@ -88,7 +94,7 @@ function setCellsBackgroundColor(editor: Editor, backgroundColor) {
.run(); .run();
} }
const columnsToolboxItems = [ const columnsToolboxItems: ToolboxItem[] = [
{ {
label: "Add Column Before", label: "Add Column Before",
icon: icons.insertLeftTableIcon, icon: icons.insertLeftTableIcon,
@ -109,7 +115,7 @@ const columnsToolboxItems = [
}: { }: {
editor: Editor; editor: Editor;
triggerButton: HTMLElement; triggerButton: HTMLElement;
controlsContainer; controlsContainer: Element;
}) => { }) => {
createColorPickerToolbox({ createColorPickerToolbox({
triggerButton, triggerButton,
@ -127,7 +133,7 @@ const columnsToolboxItems = [
}, },
]; ];
const rowsToolboxItems = [ const rowsToolboxItems: ToolboxItem[] = [
{ {
label: "Add Row Above", label: "Add Row Above",
icon: icons.insertTopTableIcon, icon: icons.insertTopTableIcon,
@ -172,11 +178,12 @@ function createToolbox({
tippyOptions, tippyOptions,
onClickItem, onClickItem,
}: { }: {
triggerButton: HTMLElement; triggerButton: Element | null;
items: { icon: string; label: string }[]; items: ToolboxItem[];
tippyOptions: any; tippyOptions: any;
onClickItem: any; onClickItem: (item: ToolboxItem) => void;
}): Instance<Props> { }): Instance<Props> {
// @ts-expect-error
const toolbox = tippy(triggerButton, { const toolbox = tippy(triggerButton, {
content: h( content: h(
"div", "div",
@ -278,14 +285,14 @@ export class TableView implements NodeView {
decorations: Decoration[]; decorations: Decoration[];
editor: Editor; editor: Editor;
getPos: () => number; getPos: () => number;
hoveredCell; hoveredCell: ResolvedPos | null = null;
map: TableMap; map: TableMap;
root: HTMLElement; root: HTMLElement;
table: HTMLElement; table: HTMLTableElement;
colgroup: HTMLElement; colgroup: HTMLTableColElement;
tbody: HTMLElement; tbody: HTMLElement;
rowsControl?: HTMLElement; rowsControl?: HTMLElement | null;
columnsControl?: HTMLElement; columnsControl?: HTMLElement | null;
columnsToolbox?: Instance<Props>; columnsToolbox?: Instance<Props>;
rowsToolbox?: Instance<Props>; rowsToolbox?: Instance<Props>;
controls?: HTMLElement; controls?: HTMLElement;
@ -398,13 +405,13 @@ export class TableView implements NodeView {
this.render(); this.render();
} }
update(node: ProseMirrorNode, decorations) { update(node: ProseMirrorNode, decorations: readonly Decoration[]) {
if (node.type !== this.node.type) { if (node.type !== this.node.type) {
return false; return false;
} }
this.node = node; this.node = node;
this.decorations = decorations; this.decorations = [...decorations];
this.map = TableMap.get(this.node); this.map = TableMap.get(this.node);
if (this.editor.isEditable) { if (this.editor.isEditable) {
@ -430,19 +437,16 @@ export class TableView implements NodeView {
} }
updateControls() { updateControls() {
const { hoveredTable: table, hoveredCell: cell } = Object.values(this.decorations).reduce( const { hoveredTable: table, hoveredCell: cell } = Object.values(this.decorations).reduce((acc, curr) => {
(acc, curr) => { if (curr.spec.hoveredCell !== undefined) {
if (curr.spec.hoveredCell !== undefined) { acc["hoveredCell"] = curr.spec.hoveredCell;
acc["hoveredCell"] = curr.spec.hoveredCell; }
}
if (curr.spec.hoveredTable !== undefined) { if (curr.spec.hoveredTable !== undefined) {
acc["hoveredTable"] = curr.spec.hoveredTable; acc["hoveredTable"] = curr.spec.hoveredTable;
} }
return acc; return acc;
}, }, {} as Record<string, HTMLElement>) as any;
{} as Record<string, HTMLElement>
) as any;
if (table === undefined || cell === undefined) { if (table === undefined || cell === undefined) {
return this.root.classList.add("controls--disabled"); return this.root.classList.add("controls--disabled");
@ -453,14 +457,21 @@ export class TableView implements NodeView {
const cellDom = this.editor.view.nodeDOM(cell.pos) as HTMLElement; const cellDom = this.editor.view.nodeDOM(cell.pos) as HTMLElement;
if (!this.table) {
return;
}
const tableRect = this.table.getBoundingClientRect(); const tableRect = this.table.getBoundingClientRect();
const cellRect = cellDom.getBoundingClientRect(); const cellRect = cellDom.getBoundingClientRect();
this.columnsControl.style.left = `${cellRect.left - tableRect.left - this.table.parentElement!.scrollLeft}px`; if (this.columnsControl) {
this.columnsControl.style.width = `${cellRect.width}px`; this.columnsControl.style.left = `${cellRect.left - tableRect.left - this.table.parentElement!.scrollLeft}px`;
this.columnsControl.style.width = `${cellRect.width}px`;
this.rowsControl.style.top = `${cellRect.top - tableRect.top}px`; }
this.rowsControl.style.height = `${cellRect.height}px`; if (this.rowsControl) {
this.rowsControl.style.top = `${cellRect.top - tableRect.top}px`;
this.rowsControl.style.height = `${cellRect.height}px`;
}
} }
selectColumn() { selectColumn() {
@ -471,10 +482,7 @@ export class TableView implements NodeView {
const headCellPos = this.map.map[colIndex + this.map.width * (this.map.height - 1)] + (this.getPos() + 1); const headCellPos = this.map.map[colIndex + this.map.width * (this.map.height - 1)] + (this.getPos() + 1);
const cellSelection = CellSelection.create(this.editor.view.state.doc, anchorCellPos, headCellPos); const cellSelection = CellSelection.create(this.editor.view.state.doc, anchorCellPos, headCellPos);
this.editor.view.dispatch( this.editor.view.dispatch(this.editor.state.tr.setSelection(cellSelection));
// @ts-ignore
this.editor.state.tr.setSelection(cellSelection)
);
} }
selectRow() { selectRow() {
@ -485,9 +493,6 @@ export class TableView implements NodeView {
const headCellPos = this.map.map[anchorCellIndex + (this.map.width - 1)] + (this.getPos() + 1); const headCellPos = this.map.map[anchorCellIndex + (this.map.width - 1)] + (this.getPos() + 1);
const cellSelection = CellSelection.create(this.editor.state.doc, anchorCellPos, headCellPos); const cellSelection = CellSelection.create(this.editor.state.doc, anchorCellPos, headCellPos);
this.editor.view.dispatch( this.editor.view.dispatch(this.editor.view.state.tr.setSelection(cellSelection));
// @ts-ignore
this.editor.view.state.tr.setSelection(cellSelection)
);
} }
} }