Skip to content

Commit

Permalink
fix: fn editable, exporting menu types, auto select first input, type…
Browse files Browse the repository at this point in the history
…d data param in renderparams

* More typescript, menu export

* Fix functional editable

* Fix forward ref error

* Add key to fragment list

* Tidy up forward ref types

* Don't stop editing in here, its done elsewhere

* Fix focus on popover inputs

* Fix space not working to select checkbox

* Type the data property of cellRendererParams

* Lint imports
  • Loading branch information
matttdawson committed Oct 30, 2022
1 parent 5972c2a commit e2e4470
Show file tree
Hide file tree
Showing 35 changed files with 306 additions and 977 deletions.
2 changes: 2 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ export { TextInputFormatted } from "./src/lui/TextInputFormatted";

export * from "./src/utils/bearing";
export * from "./src/utils/util";

export * from "./src/react-menu3/index";
9 changes: 6 additions & 3 deletions src/components/GridCell.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useContext, useMemo, useState } from "react";
import { ForwardedRef, forwardRef, useCallback, useContext, useMemo, useState } from "react";
import { GridBaseRow } from "./Grid";
import { UpdatingContext } from "@contexts/UpdatingContext";
import { GridContext } from "@contexts/GridContext";
Expand Down Expand Up @@ -27,7 +27,7 @@ export interface GenericCellEditorColDef<
FormProps extends GenericCellEditorParams<RowType>,
> extends ColDef {
cellEditorParams?: FormProps;
cellRendererParams?: GenericCellRendererParams;
cellRendererParams?: GenericCellRendererParams<RowType>;
}

export const GridCellRenderer = (cellRendererParams: ICellRendererParams) => {
Expand Down Expand Up @@ -77,8 +77,9 @@ interface GenericCellEditorICellEditorParams<RowType extends GridBaseRow, FormPr
colDef: GenericCellEditorColDef<RowType, FormProps>;
}

export const GenericCellEditorComponent = <RowType extends GridBaseRow, FormProps extends Record<string, any>>(
export const GenericCellEditorComponentFr = <RowType extends GridBaseRow, FormProps extends Record<string, any>>(
props: GenericCellEditorICellEditorParams<RowType, FormProps>,
_: ForwardedRef<any>, // We don't forward the ref, as that's for generic aggrid cell editing
) => {
const { updatingCells, getSelectedRows } = useContext(GridContext);

Expand Down Expand Up @@ -123,3 +124,5 @@ export const GenericCellEditorComponent = <RowType extends GridBaseRow, FormProp
</>
);
};

export const GenericCellEditorComponent = forwardRef(GenericCellEditorComponentFr);
2 changes: 1 addition & 1 deletion src/components/GridPopoverHook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { GridContext } from "@contexts/GridContext";
import { GridFormProps } from "./GridCell";
import { GridBaseRow } from "./Grid";
import { ControlledMenu } from "../react-menu3";
import { ControlledMenu } from "@react-menu3";

export const useGridPopoverHook = <RowType extends GridBaseRow>(
props: GridFormProps<RowType>,
Expand Down
51 changes: 32 additions & 19 deletions src/components/gridForm/GridFormMultiSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "../../react-menu3/styles/index.scss";

import { MenuItem, MenuDivider, FocusableItem, RadioChangeEvent } from "@react-menu3";
import { useCallback, useEffect, useRef, useState } from "react";
import { MenuItem, MenuDivider, FocusableItem, ClickEvent } from "@react-menu3";
import { Fragment, useCallback, useEffect, useRef, useState, KeyboardEvent } from "react";
import { GridBaseRow } from "../Grid";
import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
import { delay } from "lodash-es";
Expand Down Expand Up @@ -99,7 +99,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
return undefined;
}
const str = (option.label as string) || "";
return str.toLowerCase().indexOf(filter) === -1 ? option.value : undefined;
return str.toLowerCase().indexOf(filter.trim()) === -1 ? option.value : undefined;
})
.filter((r) => r !== undefined),
);
Expand All @@ -110,7 +110,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
<div className={"Grid-popoverContainerList"}>
{options && formProps.filtered && (
<>
<FocusableItem className={"filter-item"}>
<FocusableItem className={"filter-item"} key={"filter"}>
{({ ref }: any) => (
<div style={{ display: "flex", width: "100%" }}>
<input
Expand All @@ -134,34 +134,47 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
item.value === MenuSeparatorString ? (
<MenuDivider key={`$$divider_${index}`} />
) : filteredValues.includes(item.value) ? null : (
<>
<Fragment key={`${index}`}>
<MenuItem
key={`${item.value}`}
onClick={(e: RadioChangeEvent) => {
// FIXME Matt Event type guessed here
key={`${index}`}
onClick={(e: ClickEvent) => {
e.keepOpen = true;
if (selectedValues.includes(e.value)) {
if (selectedValues.includes(item.value)) {
setSelectedValues(selectedValues.filter((value) => value != item.value));
} else {
setSelectedValues([...selectedValues, item.value as string]);
setSelectedValues([...selectedValues, item.value]);
}
}}
onKeyDown={async (e: KeyboardEvent) => {
if (e.key === "Enter") triggerSave().then();
else if (e.key === " ") {
if (selectedValues.includes(item.value)) {
setSelectedValues(selectedValues.filter((value) => value != item.value));
} else {
setSelectedValues([...selectedValues, item.value]);
}
e.preventDefault();
e.stopPropagation();
}
return false;
}}
onKeyDown={async (e) => e.key === "Enter" && triggerSave().then()}
>
<LuiCheckboxInput
isChecked={selectedValues.includes(item.value)}
value={`${item.value}`}
label={item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
onChange={(e) => {
if (e.target.checked) {
setSelectedValues([...selectedValues, item.value as string]);
} else {
setSelectedValues(selectedValues.filter((value) => value != item.value));
}
inputProps={{
onClick: (e) => {
e.preventDefault();
e.stopPropagation();
return false;
},
}}
onChange={() => {
/*Do nothing, change handled by menuItem*/
}}
/>
</MenuItem>

{selectedValues.includes(item.value) && item.subComponent && (
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.value}_subcomponent`}>
{(ref: any) =>
Expand All @@ -177,7 +190,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
}
</FocusableItem>
)}
</>
</Fragment>
),
)}
</div>
Expand Down
18 changes: 11 additions & 7 deletions src/components/gridRender/GridRenderGenericCell.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import "./GridRenderGenericCell.scss";

import { useContext } from "react";
import { UpdatingContext } from "../../contexts/UpdatingContext";
import { UpdatingContext } from "@contexts/UpdatingContext";
import { GridLoadableCell } from "../GridLoadableCell";
import { GridIcon } from "../GridIcon";
import { ColDef, ICellRendererParams } from "ag-grid-community";
import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
import { GenericCellEditorParams } from "../GridCell";
import { GridBaseRow } from "../Grid";

export interface RowICellRendererParams<RowType extends GridBaseRow> extends ICellRendererParams {
data: RowType;
}

export interface GenericCellColDef<RowType extends GridBaseRow, FormProps extends Record<string, any>> extends ColDef {
cellRendererParams?: GenericCellRendererParams;
cellRendererParams?: GenericCellRendererParams<RowType>;
cellEditorParams?: GenericCellEditorParams<RowType> & FormProps;
}

export interface GenericCellRendererParams {
export interface GenericCellRendererParams<RowType extends GridBaseRow> {
singleClickEdit?: boolean;
warning?: (props: ICellRendererParams) => string | boolean | undefined;
info?: (props: ICellRendererParams) => string | boolean | undefined;
warning?: (props: RowICellRendererParams<RowType>) => string | boolean | undefined;
info?: (props: RowICellRendererParams<RowType>) => string | boolean | undefined;
}

export const GridRendererGenericCell = (props: ICellRendererParams): JSX.Element => {
export const GridRendererGenericCell = <RowType extends GridBaseRow>(props: ICellRendererParams): JSX.Element => {
const { checkUpdating } = useContext(UpdatingContext);

const cellRendererParams = props.colDef?.cellRendererParams as GenericCellRendererParams | undefined;
const cellRendererParams = props.colDef?.cellRendererParams as GenericCellRendererParams<RowType> | undefined;
const warningFn = cellRendererParams?.warning;
const warningText = warningFn ? warningFn(props) : undefined;
const infoFn = cellRendererParams?.info;
Expand Down
16 changes: 14 additions & 2 deletions src/components/gridRender/GridRenderPopoutMenuCell.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { useContext } from "react";
import { ICellRendererParams } from "ag-grid-community";
import { ColDef, ICellRendererParams } from "ag-grid-community";
import { UpdatingContext } from "@contexts/UpdatingContext";
import { GridLoadableCell } from "../GridLoadableCell";
import { LuiIcon } from "@linzjs/lui";
import { Column } from "ag-grid-community/dist/lib/entities/column";

export const GridRenderPopoutMenuCell = (props: ICellRendererParams) => {
const { checkUpdating } = useContext(UpdatingContext);
const isLoading = checkUpdating(props.colDef?.field ?? "", props.data.id);
const disabled = !props.colDef?.editable;
const editable = props.colDef?.editable;
const disabled = !(typeof editable === "function"
? editable({
node: props.node,
data: props.data,
column: props.column as Column,
colDef: props.colDef as ColDef,
api: props.api,
columnApi: props.columnApi,
context: props.context,
})
: editable);

return (
<GridLoadableCell
Expand Down
5 changes: 3 additions & 2 deletions src/contexts/GridContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,10 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
}
// This is needed to trigger postSortRowsHook
gridApi.refreshClientSideRowModel();
stopEditing();
} else {
// Don't set saving if ok as the form has already closed
setSaving && setSaving(false);
}
setSaving && setSaving(false);
return ok;
});
};
Expand Down
Loading

0 comments on commit e2e4470

Please sign in to comment.