Skip to content

Commit

Permalink
Merge pull request #1880 from epam/feature/use-tree-hook
Browse files Browse the repository at this point in the history
[useTree]: hook
  • Loading branch information
AlekseyManetov authored Apr 3, 2024
2 parents 7a7e323 + 090addd commit 48733f5
Show file tree
Hide file tree
Showing 269 changed files with 30,763 additions and 6,627 deletions.
1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@epam/uui-docs": "5.7.1",
"@epam/uui-editor": "5.7.1",
"@epam/uui-timeline": "5.7.1",
"@tanstack/react-query": "^5.17.19",
"@udecode/plate-common": "25.0.1",
"amplitude-js": "8.9.1",
"classnames": "2.2.6",
Expand Down
2 changes: 1 addition & 1 deletion app/src/common/apiReference/TypeRefTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function TypeRefTable(props: TypeRefTableProps) {
[items, props.isGrouped],
);

const view = exportPropsDs.getView(tableState, setTableState, {
const view = exportPropsDs.useView(tableState, setTableState, {
isFoldedByDefault: () => false,
});

Expand Down
21 changes: 10 additions & 11 deletions app/src/demo/tables/editableTable/ProjectTableDemo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { DataTable, Panel, Button, FlexCell, FlexRow, FlexSpacer, IconButton, useForm, SearchInput, Tooltip } from '@epam/uui';
import { AcceptDropParams, DataTableState, DropParams, DropPosition, Metadata, useList } from '@epam/uui-core';
import { AcceptDropParams, DataTableState, DropParams, DropPosition, Metadata, useArrayDataSource } from '@epam/uui-core';
import { useDataTableFocusManager } from '@epam/uui-components';

import { ReactComponent as undoIcon } from '@epam/assets/icons/content-edit_undo-outline.svg';
Expand Down Expand Up @@ -39,7 +39,7 @@ let savedValue: FormState = { items: getDemoTasks() };

export function ProjectTableDemo() {
const {
lens, value, save, isChanged, revert, undo, canUndo, redo, canRedo, setValue,
value, save, isChanged, revert, undo, canUndo, redo, canRedo, setValue, lens,
} = useForm<FormState>({
value: savedValue,
onSave: async (data) => {
Expand All @@ -52,7 +52,6 @@ export function ProjectTableDemo() {
const [tableState, setTableState] = useState<DataTableState>({ sorting: [{ field: 'order' }], visibleCount: 1000 });
const dataTableFocusManager = useDataTableFocusManager<Task['id']>({}, []);

// Insert new/exiting top/bottom or above/below relative to other task
const insertTask = useCallback((position: DropPosition, relativeTask: Task | null = null, existingTask: Task | null = null) => {
let tempRelativeTask = relativeTask;
const task: Task = existingTask ? { ...existingTask } : { id: lastId--, name: '' };
Expand Down Expand Up @@ -117,15 +116,13 @@ export function ProjectTableDemo() {
[],
);

const { rows, listProps } = useList(
const dataSource = useArrayDataSource<Task, number, any>(
{
type: 'array',
listState: tableState,
setListState: setTableState,
items: Object.values(value.items),
getSearchFields: (item) => [item.name],
getId: (i) => i.id,
getParentId: (i) => i.parentId,
fixItemBetweenSortings: false,
getRowOptions: (task) => ({
...lens.prop('items').prop(task.id).toProps(), // pass IEditable to each row to allow editing
// checkbox: { isVisible: true },
Expand All @@ -141,6 +138,8 @@ export function ProjectTableDemo() {
[],
);

const view = dataSource.useView(tableState, setTableState);

const columns = useMemo(
() => getColumns({ insertTask, deleteTask }),
[insertTask, deleteTask],
Expand All @@ -156,7 +155,7 @@ export function ProjectTableDemo() {
const deleteSelectedItem = useCallback(() => {
if (selectedItem === undefined) return;

const prevRows = [...rows];
const prevRows = [...view.getVisibleRows()];
deleteTask(selectedItem);
const index = prevRows.findIndex((task) => task.id === selectedItem.id);
const newSelectedIndex = index === prevRows.length - 1
Expand All @@ -167,7 +166,7 @@ export function ProjectTableDemo() {
...state,
selectedId: newSelectedIndex >= 0 ? prevRows[newSelectedIndex].id : undefined,
}));
}, [deleteTask, rows, selectedItem, setTableState]);
}, [deleteTask, view, selectedItem, setTableState]);

const keydownHandler = useCallback((event: KeyboardEvent) => {
if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.code === 'Enter') {
Expand Down Expand Up @@ -251,15 +250,15 @@ export function ProjectTableDemo() {
</FlexRow>
<DataTable
headerTextCase="upper"
getRows={ () => rows }
getRows={ view.getVisibleRows }
columns={ columns }
value={ tableState }
onValueChange={ setTableState }
dataTableFocusManager={ dataTableFocusManager }
showColumnsConfig
allowColumnsResizing
allowColumnsReordering
{ ...listProps }
{ ...view.getListProps() }
/>
</Panel>
);
Expand Down
12 changes: 9 additions & 3 deletions app/src/demo/tables/editableTable/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,18 @@ const findAllChildren = (tasks: Task[], parentTask: Task) => {

export const deleteTaskWithChildren = (tasks: Record<number, Task>, taskToDelete: Task | null): Record<number, Task> => {
const currentTasks = { ...tasks };
if (!taskToDelete) {
let taskToBeDeleted = taskToDelete;
if (taskToBeDeleted === undefined) {
const rootItems = Object.values(currentTasks).filter((task) => task.parentId === undefined);
taskToBeDeleted = rootItems[rootItems.length - 1];
}

if (!taskToBeDeleted) {
return currentTasks;
}

const childrenIds = findAllChildren(Object.values(currentTasks), taskToDelete);
[taskToDelete.id, ...childrenIds].forEach((id) => {
const childrenIds = findAllChildren(Object.values(currentTasks), taskToBeDeleted);
[taskToBeDeleted.id, ...childrenIds].forEach((id) => {
delete currentTasks[id];
});

Expand Down
6 changes: 3 additions & 3 deletions app/src/demo/tables/filteredTable/FilteredTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
} from '@epam/uui';
import { getFilters } from './filters';
import {
useLazyDataSource, useUuiContext, UuiContexts, useTableState, LazyDataSourceApiRequest, ITablePreset,
DataQueryFilter,
useUuiContext, UuiContexts, useTableState, LazyDataSourceApiRequest, ITablePreset,
DataQueryFilter, useLazyDataSource,
} from '@epam/uui-core';
import { FilteredTableFooter } from './FilteredTableFooter';
import { Person } from '@epam/uui-docs';
Expand Down Expand Up @@ -58,7 +58,7 @@ export function FilteredTable() {
return result;
}, [svc.api.demo]);

const dataSource = useLazyDataSource<Person, number, Person>(
const dataSource = useLazyDataSource<Person, number, DataQueryFilter<Person>>(
{
api: api,
selectAll: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import { FiltersBlock } from './FiltersBlock';
// import { ColumnsBlock } from './ColumnsBlock';
import { GroupingBlock } from './GroupingBlock';

export interface IFilterPanelProps<TFilter extends Record<string, any>> extends ITableState<TFilter> {
export interface IFilterPanelProps<TFilter> extends ITableState<TFilter> {
columns: DataColumnProps[];
filters: TableFiltersConfig<TFilter>[];
closePanel(): void;
}

function FilterPanel<TFilter = any>(props: IFilterPanelProps<TFilter>) {
function FilterPanel<TFilter extends { groupBy?: string[] } = any>(props: IFilterPanelProps<TFilter>) {
return (
<>
<FlexRow borderBottom size="48" padding="18">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import React, { Dispatch, SetStateAction } from 'react';
import { Accordion, PickerList } from '@epam/uui';
import { DataTableState } from '@epam/uui-core';
import { groupingsDataSource } from '../../groupings';

interface GroupingBlockProps<TFilter> {
tableState: DataTableState<TFilter>;
setTableState(newState: DataTableState<TFilter>): void;
setTableState: Dispatch<SetStateAction<DataTableState<TFilter, any>>>;
}

function GroupingBlock<TFilter extends { groupBy?: string[] }>({ tableState, setTableState }: GroupingBlockProps<TFilter>) {
Expand Down Expand Up @@ -33,4 +33,4 @@ function GroupingBlock<TFilter extends { groupBy?: string[] }>({ tableState, set
);
}

export default React.memo(GroupingBlock);
export default React.memo(GroupingBlock) as typeof GroupingBlock;
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export function MasterDetailedTable() {
.addDefaults({
getType: ({ __typename }) => __typename,
getGroupBy: () => tableStateApi.tableState.filter?.groupBy,
complexIds: true,
backgroundReload: true,
fetchStrategy: 'parallel',
cascadeSelection: true,
Expand Down
2 changes: 1 addition & 1 deletion app/src/demo/tables/masterDetailedTable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type PersonFilters = {
PersonEmploymentGroup: DataQueryFilter<PersonEmploymentGroup>;
};

export type PersonTableFilter = DataQueryFilter<Person> & { groupBy?: GroupByLocation | GroupByEmployment | Array<GroupByLocation | GroupByEmployment> };
export type PersonTableFilter = DataQueryFilter<Person> & { groupBy?: Array<GroupByLocation | GroupByEmployment> };
export interface Grouping {
id: string;
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ export class GroupingConfigBuilder<
LazyDataSourceProps<TGroupsWithMeta<TGroups, TId, TGroupBy>[TType], TId[TType], TFilter[TType]>['api']
>
) {
return this.entitiesConfig[this.defaultEntity].api(...apiArgs);
const [request, context] = apiArgs;
const response = await this.entitiesConfig[this.defaultEntity].api(request, context);
return this.getResultsWithMeta(response, context?.parent, []);
}

private getGroupByPathForParent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Props<TItem, TId> extends IEditable<DataSourceState> {
selectAll?: boolean;
getName?: (item: TItem) => string;
dataSource: IDataSource<TItem, TId, any>;
onValueChange: React.Dispatch<React.SetStateAction<DataSourceState<any, TId>>>;
}

export function DataSourceViewer<TItem, TId>(props: Props<TItem, TId>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function LazyTreePickerModal() {
const handleModalOpening = useCallback(() => {
context.uuiModals
.show((props) => (
<PickerModal
<PickerModal<Location, string>
initialValue={ value }
dataSource={ dataSource }
selectionMode="multi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const personColumns: DataColumnProps<Person, number>[] = [
export default function WithTableExample() {
const { api } = useUuiContext();

const { tableState, setTableState } = useTableState({
const { tableState, setTableState } = useTableState<Person, any>({
columns: personColumns,
});

Expand Down
8 changes: 4 additions & 4 deletions app/src/docs/_examples/tables/ArrayTable.example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { demoData, FeatureClass } from '@epam/uui-docs';
import css from './TablesExamples.module.scss';

export default function ArrayDataTableExample() {
const [value, onValueChange] = useState({});
const [dataSourceState, setDataSourceState] = useState({});

const dataSource = useArrayDataSource<FeatureClass, number, unknown>(
{
Expand All @@ -14,7 +14,7 @@ export default function ArrayDataTableExample() {
[],
);

const view = dataSource.useView(value, onValueChange, {});
const view = dataSource.useView(dataSourceState, setDataSourceState, {});

const productColumns: DataColumnProps<FeatureClass>[] = useMemo(
() => [
Expand Down Expand Up @@ -47,8 +47,8 @@ export default function ArrayDataTableExample() {
<DataTable
{ ...view.getListProps() }
getRows={ view.getVisibleRows }
value={ value }
onValueChange={ onValueChange }
value={ dataSourceState }
onValueChange={ setDataSourceState }
columns={ productColumns }
headerTextCase="upper"
/>
Expand Down
17 changes: 6 additions & 11 deletions app/src/docs/_examples/tables/ColumnsConfig.example.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState, useMemo } from 'react';
import React, { useCallback, useState, useMemo, SetStateAction } from 'react';
import { DataTableState, DataColumnProps, useLazyDataSource, useUuiContext } from '@epam/uui-core';
import { Text, DataTable, Panel, IconButton } from '@epam/uui';
import { City } from '@epam/uui-docs';
Expand Down Expand Up @@ -91,17 +91,12 @@ export default function ColumnsConfigurationDataTableExample() {
[],
);

const handleTableStateChange = useCallback((newState: DataTableState) => {
const handleTableStateChange = useCallback((newState: SetStateAction<DataTableState>) => {
const updatedState = typeof newState === 'function' ? newState(tableState) : newState;
// Set columns config to localStorage
svc.uuiUserSettings.set(LOCAL_STORAGE_KEY, newState.columnsConfig || {});
setTableState(newState);
}, []);

useEffect(() => {
return () => {
citiesDS.unsubscribeView(handleTableStateChange);
};
}, []);
svc.uuiUserSettings.set(LOCAL_STORAGE_KEY, updatedState.columnsConfig || {});
setTableState(updatedState);
}, [svc.uuiUserSettings, tableState]);

const view = citiesDS.useView(tableState, handleTableStateChange, {
getRowOptions: useCallback(() => ({ checkbox: { isVisible: true } }), []),
Expand Down
Loading

0 comments on commit 48733f5

Please sign in to comment.