accessor: getColumnAccessor()

in packages/unitables/src/bee/UnitablesBeeTable.tsx [261:594]


              accessor: getColumnAccessor(insideProperty),
              dataType: insideProperty.dataType,
              isRowIndexColumn: false,
              width,
              setWidth: setColumnWidth(insideProperty.joinedName),
              minWidth,
            };
          }),
        };
      } else {
        let minWidth = column.width;
        let width = (getObjectValueByPath(configs, column.name) as UnitablesCellConfigs)?.width ?? column.width;
        if (column.type === "array") {
          width = calculateListFieldWidth(column.joinedName);
          minWidth = calculateListFieldWidth(column.joinedName);
        }
        return {
          originalId: uuid + `field-${column.name}-parent`,
          label: "",
          accessor: getColumnAccessor(column) + "-parent",
          dataType: undefined as any,
          isRowIndexColumn: false,
          width: undefined,
          columns: [
            {
              originalId: uuid + `field-${column.name}`,
              label: column.name,
              accessor: getColumnAccessor(column),
              dataType: column.dataType,
              isRowIndexColumn: false,
              width,
              setWidth: setColumnWidth(column.name),
              minWidth,
            },
          ],
        };
      }
    });
  }, [columns, uuid, configs, setColumnWidth, calculateListFieldWidth]);

  const getColumnKey = useCallback((column: ReactTable.ColumnInstance<ROWTYPE>) => {
    return column.originalId ?? column.id;
  }, []);

  const getRowKey = useCallback((row: ReactTable.Row<ROWTYPE>) => {
    return row.original.id;
  }, []);

  return (
    <StandaloneBeeTable
      cellComponentByColumnAccessor={cellComponentByColumnAccessor}
      scrollableParentRef={scrollableParentRef}
      getColumnKey={getColumnKey}
      getRowKey={getRowKey}
      tableId={id}
      isEditableHeader={false}
      headerLevelCountForAppendingRowIndexColumn={1}
      headerVisibility={BeeTableHeaderVisibility.AllLevels}
      operationConfig={beeTableOperationConfig}
      allowedOperations={allowedOperations}
      columns={beeTableColumns}
      rows={rows}
      enableKeyboardNavigation={true}
      shouldRenderRowIndexColumn={true}
      shouldShowRowsInlineControls={true}
      shouldShowColumnsInlineControls={false}
      onRowAdded={onRowAdded}
      onRowDuplicated={onRowDuplicated}
      onRowReset={onRowReset}
      onRowDeleted={onRowDeleted}
      rowWrapper={rowWrapper}
      resizerStopBehavior={ResizerStopBehavior.SET_WIDTH_ALWAYS}
    />
  );
}

function getColumnAccessor(c: UnitablesColumnType) {
  return `field-${c.joinedName}`;
}

function UnitablesBeeTableCell({
  joinedName,
  rowCount,
  columnCount,
}: BeeTableCellProps<ROWTYPE> & {
  joinedName: string;
  rowCount: number;
  columnCount: number;
}) {
  const [{ field, onChange: onFieldChange, name: fieldName }] = useField(joinedName, {});
  const cellRef = useRef<HTMLDivElement | null>(null);
  const [autoFieldKey, forceUpdate] = useReducer((x) => x + 1, 0);
  const { containerCellCoordinates } = useBeeTableCoordinates();
  const { isBeeTableChange } = useUnitablesContext();
  const { submitRow, rowInputs } = useUnitablesRow(containerCellCoordinates?.rowIndex ?? 0);
  const fieldInput = useMemo(() => getObjectValueByPath(rowInputs, fieldName), [rowInputs, fieldName]);
  const [isSelectFieldOpen, setIsSelectFieldOpen] = useState(false);
  const fieldCharacteristics = useMemo(() => {
    if (!field) {
      return;
    }
    return {
      xDmnType: field["x-dmn-type"] as X_DMN_TYPE,
      isEnum: !!field.enum,
      isList: field.type === "array",
    };
  }, [field]);
  const previousFieldInput = useRef(fieldInput);

  // keep previous updated;
  useEffect(() => {
    previousFieldInput.current = fieldInput;
  }, [fieldInput]);

  // FIXME: Decouple from DMN --> https://github.com/apache/incubator-kie-issues/issues/166
  const setValue = useCallback(
    (newValue?: string) => {
      isBeeTableChange.current = true;
      const newValueWithoutSymbols = newValue?.replace(/\r/g, "") ?? "";

      if (field.enum) {
        if (field.enum.findIndex((value: unknown) => value === newValueWithoutSymbols) >= 0) {
          onFieldChange(newValueWithoutSymbols);
        } else {
          onFieldChange(field.placeholder);
        }
        // Changing the values using onChange will not re-render <select> nodes;
        // This ensure a re-render of the SelectField;
        forceUpdate();
      } else if (field.type === "string") {
        if (field.format === "time") {
          if (moment(newValueWithoutSymbols, [moment.HTML5_FMT.TIME, moment.HTML5_FMT.TIME_SECONDS], true).isValid()) {
            onFieldChange(newValueWithoutSymbols);
          } else {
            onFieldChange("");
          }
        } else if (field.format === "date") {
          if (moment(newValueWithoutSymbols, [moment.HTML5_FMT.DATE]).isValid()) {
            onFieldChange(newValueWithoutSymbols);
          } else {
            onFieldChange("");
          }
        } else if (field.format === "date-time") {
          const valueAsNumber = Date.parse(newValueWithoutSymbols);
          if (!isNaN(valueAsNumber)) {
            onFieldChange(newValueWithoutSymbols);
          } else {
            onFieldChange("");
          }
        } else {
          onFieldChange(newValueWithoutSymbols);
        }
      } else if (field.type === "number") {
        const numberValue = parseFloat(newValueWithoutSymbols);
        onFieldChange(isNaN(numberValue) ? undefined : numberValue);
      } else if (field.type === "boolean") {
        onFieldChange(newValueWithoutSymbols === "true");
      } else if (field.type === "array") {
        // FIXME: Support lists --> https://github.com/apache/incubator-kie-issues/issues/167
      } else if (field.type === "object" && typeof newValue !== "object") {
        // objects are flattened in a single row - this case shouldn't happen;
      } else {
        onFieldChange(newValue);
      }
      submitRow();
    },
    [isBeeTableChange, field.enum, field.type, field.placeholder, field.format, submitRow, onFieldChange]
  );

  const { isActive, isEditing } = useBeeTableSelectableCellRef(
    containerCellCoordinates?.rowIndex ?? 0,
    containerCellCoordinates?.columnIndex ?? 0,
    setValue,
    useCallback(() => `${fieldInput ?? ""}`, [fieldInput])
  );
  const { mutateSelection } = useBeeTableSelectionDispatch();

  const navigateVertically = useCallback(
    (args: { isShiftPressed: boolean }) => {
      mutateSelection({
        part: SelectionPart.ActiveCell,
        columnCount: () => columnCount,
        rowCount,
        deltaColumns: 0,
        deltaRows: args.isShiftPressed ? -1 : 1,
        isEditingActiveCell: false,
        keepInsideSelection: true,
      });
    },
    [mutateSelection, rowCount, columnCount]
  );

  const setEditingCell = useCallback(
    (isEditing: boolean) => {
      mutateSelection({
        part: SelectionPart.ActiveCell,
        columnCount: () => columnCount,
        rowCount,
        deltaColumns: 0,
        deltaRows: 0,
        isEditingActiveCell: isEditing,
        keepInsideSelection: true,
      });
    },
    [mutateSelection, rowCount, columnCount]
  );

  const onKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLDivElement>) => {
      // TAB
      if (e.key.toLowerCase() === "tab") {
        // ListField - START
        if (fieldCharacteristics?.isList) {
          // Get all uniforms components inside the ListField;
          const uniformsComponents = cellRef.current?.querySelectorAll('[id^="uniforms-"]');
          if (uniformsComponents === undefined) {
            setEditingCell(false);
            return;
          }

          const uniformComponentTargetIndex = Array.from(uniformsComponents ?? []).findIndex(
            (component) => component.id === (e.target as HTMLElement).id
          );

          // If it wasn't possible to retrieve the index, it should focus on the first button;
          if (uniformComponentTargetIndex < 0) {
            (uniformsComponents?.item(1) as HTMLElement).parentElement?.focus();
            setEditingCell(true);
            e.stopPropagation();
            return;
          }

          const nextUniformsComponent = e.shiftKey
            ? uniformsComponents[uniformComponentTargetIndex - 1]
            : uniformsComponents[uniformComponentTargetIndex + 1];

          // Should leave ListField if nextUniformsComponent doesn't exist
          if (nextUniformsComponent === undefined) {
            setEditingCell(false);
            return;
          }

          // TextField, BoolField, DateTimeField, NumField, ListAddField, ListDelField
          if (
            nextUniformsComponent.tagName.toLowerCase() === "input" ||
            nextUniformsComponent.tagName.toLowerCase() === "button"
          ) {
            (nextUniformsComponent as HTMLButtonElement | HTMLInputElement).parentElement?.focus();
            setEditingCell(true);
            submitRow();
            e.stopPropagation();
            return;
          }

          // Nested ListFields or SelectField
          if (nextUniformsComponent.tagName.toLowerCase() === "div") {
            (nextUniformsComponent as HTMLElement)?.focus();
            setEditingCell(true);
            submitRow();
            e.stopPropagation();
            return;
          }
        } // ListField - END

        submitRow();
        setEditingCell(false);
        if (fieldCharacteristics?.isEnum) {
          setIsSelectFieldOpen((prev) => {
            if (prev) {
              cellRef.current?.getElementsByTagName("button")?.[0]?.click();
            }
            return false;
          });
        }
        return;
      }

      // ESC
      if (e.key.toLowerCase() === "escape") {
        e.stopPropagation();
        onFieldChange(previousFieldInput.current);
        cellRef.current?.focus();
        setEditingCell(false);
        if (fieldCharacteristics?.isEnum) {
          setIsSelectFieldOpen((prev) => {
            if (prev) {
              cellRef.current?.getElementsByTagName("button")?.[0]?.click();
            }
            return false;
          });
        }
        return;
      }

      // ENTER
      if (e.key.toLowerCase() === "enter") {
        // ListField - START
        if (fieldCharacteristics?.isList) {
          e.stopPropagation();
          e.preventDefault();
          const uniformsComponents = cellRef.current?.querySelectorAll('[id^="uniforms-"]');
          if (!uniformsComponents) {
            return;
          }

          // To search the uniforms components avoiding returning the top ListField
          // we search backwards;
          const reversedUniformsComponents = Array.from(uniformsComponents).reverse();
          const reversedUniformComponentTargetIndex = reversedUniformsComponents.findIndex((component) =>
            component.contains(e.target as HTMLElement)
          );
          const uniformsComponent = reversedUniformsComponents[reversedUniformComponentTargetIndex];

          // If field is selected, and the target is not present
          if (!uniformsComponent) {
            // check if it's a button from a SelectField
            const selectFieldUl = document.querySelectorAll(`ul[name^="${fieldName}."]`)?.item(0);
            if (selectFieldUl && selectFieldUl.contains(e.target as HTMLElement)) {
              setIsSelectFieldOpen(false);
              submitRow();
              (cellRef.current?.querySelector(`[id=${selectFieldUl.id}]`) as HTMLDivElement)
                ?.getElementsByTagName("button")
                ?.item(0)
                ?.focus();
            } else if (uniformsComponents[1].tagName.toLowerCase() === "button") {
              (uniformsComponents[1] as HTMLButtonElement)?.focus();
            }
          } else {
            // A button is the ListAddField or ListDelField
            if (uniformsComponent.tagName.toLowerCase() === "button") {
              (uniformsComponent as HTMLButtonElement)?.click();

              // The ListField ListDelField is the last element
              if (reversedUniformComponentTargetIndex === 0) {