gbs-add-block 1.0.30 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/README.md +6 -3
  2. package/package.json +1 -1
  3. package/source/components/datagrid/context/GridContext.tsx +7 -5
  4. package/source/components/datagrid/createTemplate.tsx +82 -0
  5. package/source/components/datagrid/hooks/usePagination.ts +11 -1
  6. package/source/components/datagrid/type.ts +1 -1
  7. package/source/components/datagrid/hooks/usePageStatus.ts +0 -13
  8. package/source/components/datagridbeta/context/GridContext.tsx +0 -187
  9. package/source/components/datagridbeta/hooks/index.ts +0 -7
  10. package/source/components/datagridbeta/hooks/useColumns.ts +0 -33
  11. package/source/components/datagridbeta/hooks/useDataSource.ts +0 -54
  12. package/source/components/datagridbeta/hooks/useFiltering.ts +0 -135
  13. package/source/components/datagridbeta/hooks/usePageStatus.ts +0 -13
  14. package/source/components/datagridbeta/hooks/usePagination.ts +0 -125
  15. package/source/components/datagridbeta/hooks/useRowSelection.ts +0 -48
  16. package/source/components/datagridbeta/hooks/useSearch.ts +0 -86
  17. package/source/components/datagridbeta/index.tsx +0 -26
  18. package/source/components/datagridbeta/layout/EditableRow.tsx +0 -85
  19. package/source/components/datagridbeta/layout/FilterPopup.tsx +0 -85
  20. package/source/components/datagridbeta/layout/GridBody.tsx +0 -221
  21. package/source/components/datagridbeta/layout/GridPagination.tsx +0 -118
  22. package/source/components/datagridbeta/layout/GridToolbar.tsx +0 -108
  23. package/source/components/datagridbeta/layout/index.tsx +0 -68
  24. package/source/components/datagridbeta/type.ts +0 -183
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # GBS Building Blocks 2.0 (v1.0.30)
1
+ # GBS Building Blocks 2.0 (v1.2.0)
2
2
 
3
3
  Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
4
4
 
@@ -6,9 +6,12 @@ Latest and upgraded version of GBS building blocks with headless UI and removed
6
6
 
7
7
  For detailed documentation on usage and props, Please visit: [Building Block Documentation v2.0](https://gramprokit.vercel.app)
8
8
 
9
- ## What's New 🎉 (Ver 1.0.30)
9
+ ## What's New 🎉 (Ver 1.2.0)
10
10
 
11
- - Type Import Update
11
+ - Updated Data Grid
12
+ - Style Updates
13
+ - Bug Fix
14
+ - New Documentation Site
12
15
 
13
16
  ## Authors
14
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gbs-add-block",
3
- "version": "1.0.30",
3
+ "version": "1.2.0",
4
4
  "description": "React Component Library",
5
5
  "type": "module",
6
6
  "files": [
@@ -7,7 +7,6 @@ import {
7
7
  useSearch,
8
8
  useFiltering,
9
9
  useRowSelection,
10
- usePageStatus,
11
10
  } from "../hooks";
12
11
 
13
12
  const GridContext = createContext<GridContextType | undefined>(undefined);
@@ -70,7 +69,13 @@ export const GridProvider: React.FC<{
70
69
  goToFirstPage,
71
70
  goToPage,
72
71
  resetPage,
73
- } = usePagination(totalPages, lazy, workingDataSource, pageSettings);
72
+ } = usePagination(
73
+ totalPages,
74
+ lazy,
75
+ workingDataSource,
76
+ pageSettings,
77
+ pageStatus
78
+ );
74
79
 
75
80
  // Search functionality
76
81
  const { searchParam, handleSearchInput, handleSearch } = useSearch({
@@ -110,9 +115,6 @@ export const GridProvider: React.FC<{
110
115
  const { selectedRows, handleSelectAll, handleSelect, isRowSelected } =
111
116
  useRowSelection(workingDataSource, onSelectRow);
112
117
 
113
- // Page status reporting - Bug Report - causes re-rendering when currentPage or totalPages change
114
- // usePageStatus(currentPage, totalPages, pageStatus);
115
-
116
118
  // Context value
117
119
  const contextValue: GridContextType = {
118
120
  // State
@@ -0,0 +1,82 @@
1
+ export const createTemplate = (
2
+ type: string,
3
+ config: any = {},
4
+ CustomTemplate?: any
5
+ ) => {
6
+ return ({ rowData }: { rowData: any }) => {
7
+ const field = config.field || "unknown";
8
+
9
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
10
+ const value =
11
+ config.type === "number" ? Number(e.target.value) : e.target.value;
12
+ rowData[field] = value;
13
+ config.onDataChange?.(rowData.id, field, value);
14
+ };
15
+
16
+ const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
17
+ rowData[field] = e.target.value;
18
+ config.onDataChange?.(rowData.id, field, e.target.value);
19
+ };
20
+
21
+ switch (type) {
22
+ case "input":
23
+ return (
24
+ <input
25
+ key={`${field}-${rowData.id}`}
26
+ type={config.type || "text"}
27
+ className={
28
+ config.className ||
29
+ "p-1 text-xs outline-none w-full rounded focus:border-b-2 border-blue-600"
30
+ }
31
+ placeholder={config.placeholder || `Enter ${field}`}
32
+ defaultValue={rowData[field]}
33
+ onChange={handleInputChange}
34
+ onBlur={handleInputChange}
35
+ />
36
+ );
37
+
38
+ case "select":
39
+ return (
40
+ <select
41
+ key={`${field}-${rowData.id}`}
42
+ className={
43
+ config.className ||
44
+ "p-1 w-full text-xs rounded outline-none focus:border-b-2 border-blue-600 dark:bg-zinc-900"
45
+ }
46
+ defaultValue={rowData[field]}
47
+ onChange={handleSelectChange}
48
+ >
49
+ {config.options?.map((option: any, i: number) => (
50
+ <option key={i} value={option.value || option}>
51
+ {option.label || option}
52
+ </option>
53
+ ))}
54
+ </select>
55
+ );
56
+
57
+ case "button":
58
+ return (
59
+ <button
60
+ key={`${field}-${rowData.id}`}
61
+ className={config.className || "border rounded-2xl p-1"}
62
+ onClick={() => config.onClick?.(rowData)}
63
+ >
64
+ {config.text || "Action"}
65
+ </button>
66
+ );
67
+
68
+ case "custom":
69
+ return (
70
+ <CustomTemplate
71
+ rowData={rowData}
72
+ field={field}
73
+ config={config}
74
+ {...config}
75
+ />
76
+ );
77
+
78
+ default:
79
+ return <span>{rowData[field]}</span>;
80
+ }
81
+ };
82
+ };
@@ -4,13 +4,15 @@ export const usePagination = (
4
4
  totalPages: number,
5
5
  lazy: boolean,
6
6
  dataSource?: any[],
7
- pageSettings?: { pageNumber: number }
7
+ pageSettings?: { pageNumber: number },
8
+ pageStatus?: ({ currentPage }: { currentPage: number }) => void
8
9
  ) => {
9
10
  const [currentPage, setCurrentPage] = useState(0);
10
11
  const [pageStart, setPageStart] = useState(0);
11
12
  const [pageEnd, setPageEnd] = useState(10);
12
13
  const [prevDataLength, setPrevDataLength] = useState(0);
13
14
 
15
+ // Update page range based on current page
14
16
  const updatePageRange = useCallback(
15
17
  (page: number) => {
16
18
  const start = Math.floor(page / 10) * 10;
@@ -20,6 +22,7 @@ export const usePagination = (
20
22
  [totalPages]
21
23
  );
22
24
 
25
+ // Initialize page range based on total pages
23
26
  useEffect(() => {
24
27
  if (!lazy) {
25
28
  setPageEnd(Math.min(10, totalPages));
@@ -28,6 +31,13 @@ export const usePagination = (
28
31
  }
29
32
  }, [totalPages, lazy, pageStart]);
30
33
 
34
+ // Update page status if provided
35
+ useEffect(() => {
36
+ if (pageStatus) {
37
+ pageStatus({ currentPage });
38
+ }
39
+ }, [currentPage, pageStatus]);
40
+
31
41
  // This will handle the case when dataSource changes
32
42
  // and adjust the current page accordingly in managed workflow
33
43
  useEffect(() => {
@@ -35,7 +35,7 @@ export type GridProps = {
35
35
  gridColumnStyleSelectAll?: string;
36
36
  gridColumnStyle?: string;
37
37
  rowChange?: any;
38
- pageStatus?: any;
38
+ pageStatus?: ({ currentPage }: { currentPage: number }) => void;
39
39
  activeFilterArrayValue?: ActiveFilterArrayValue[] | any;
40
40
  searchParamValue?: (value: string) => void;
41
41
  showTotalPages?: boolean;
@@ -1,13 +0,0 @@
1
- import { useEffect } from "react";
2
-
3
- export const usePageStatus = (
4
- currentPage: number,
5
- totalPages: number,
6
- pageStatus?: (status: any) => void
7
- ) => {
8
- useEffect(() => {
9
- if (pageStatus) {
10
- pageStatus({ currentPage, totalPages });
11
- }
12
- }, [pageStatus, currentPage, totalPages]);
13
- };
@@ -1,187 +0,0 @@
1
- import React, { createContext, useContext } from "react";
2
- import type { GridContextType, GridProps } from "../type";
3
- import {
4
- useDataSource,
5
- useColumns,
6
- usePagination,
7
- useSearch,
8
- useFiltering,
9
- useRowSelection,
10
- usePageStatus,
11
- } from "../hooks";
12
-
13
- const GridContext = createContext<GridContextType | undefined>(undefined);
14
-
15
- export const GridProvider: React.FC<{
16
- children: React.ReactNode;
17
- props: GridProps;
18
- }> = ({ children, props }) => {
19
- const {
20
- dataSource,
21
- columns = [],
22
- pageSettings,
23
- enableSearch = false,
24
- lazy = false,
25
- enableExcelExport = false,
26
- excelName = "data",
27
- enablePdfExport = false,
28
- pdfName = "data",
29
- pdfOptions = {},
30
- gridButtonClass = "px-1 py-2 text-xs rounded bg-zinc-200 dark:bg-zinc-700 cursor-pointer",
31
- selectAll = false,
32
- onSelectRow,
33
- isFetching,
34
- tableHeaderStyle = "text-left px-2 py-4 bg-zinc-200 dark:bg-zinc-800",
35
- gridContainerClass = "flex flex-col rounded-md overflow-hidden",
36
- gridColumnStyleSelectAll = "px-4 text-xs",
37
- gridColumnStyle = "p-2 text-xs",
38
- rowChange = () => {},
39
- pageStatus = () => {},
40
- activeFilterArrayValue = [],
41
- searchParamValue = () => {},
42
- showTotalPages = false,
43
- onSearch = () => {},
44
- onToolbarButtonClick = () => {},
45
- } = props;
46
-
47
- // Data source management
48
- const {
49
- workingDataSource,
50
- setWorkingDataSource,
51
- fallbackSourceData,
52
- totalPages,
53
- setTotalPages,
54
- } = useDataSource(dataSource, pageSettings, lazy);
55
-
56
- // Column management
57
- const { workingColumns, setWorkingColumns } = useColumns(
58
- columns,
59
- workingDataSource
60
- );
61
-
62
- // Pagination management
63
- const {
64
- currentPage,
65
- pageStart,
66
- pageEnd,
67
- nextPage,
68
- prevPage,
69
- goToEndPage,
70
- goToFirstPage,
71
- goToPage,
72
- resetPage,
73
- } = usePagination(totalPages, lazy, workingDataSource, pageSettings);
74
-
75
- // Search functionality
76
- const { searchParam, handleSearchInput, handleSearch } = useSearch({
77
- workingDataSource,
78
- setWorkingDataSource,
79
- fallbackSourceData,
80
- dataSource,
81
- lazy,
82
- pageSettings,
83
- resetPage,
84
- setTotalPages,
85
- searchParamValue,
86
- });
87
-
88
- // Filtering functionality
89
- const {
90
- activeFilterArray,
91
- toggleFilterPopup,
92
- handleApplyFilter,
93
- clearFilter,
94
- handleFilterAction,
95
- } = useFiltering({
96
- columns,
97
- workingColumns,
98
- setWorkingColumns,
99
- workingDataSource,
100
- setWorkingDataSource,
101
- dataSource,
102
- fallbackSourceData,
103
- resetPage,
104
- setTotalPages,
105
- pageSettings,
106
- activeFilterArrayValue,
107
- });
108
-
109
- // Row selection functionality
110
- const { selectedRows, handleSelectAll, handleSelect, isRowSelected } =
111
- useRowSelection(workingDataSource, onSelectRow);
112
-
113
- // Page status reporting
114
- usePageStatus(currentPage, totalPages, pageStatus);
115
-
116
- // Context value
117
- const contextValue: GridContextType = {
118
- // State
119
- workingDataSource,
120
- fallbackSourceData,
121
- workingColumns,
122
- currentPage,
123
- pageStart,
124
- pageEnd,
125
- totalPages,
126
- searchParam,
127
- activeFilterArray,
128
- selectedRows,
129
- isFetching,
130
-
131
- // Navigation methods
132
- nextPage,
133
- prevPage,
134
- goToEndPage,
135
- goToFirstPage,
136
- goToPage,
137
- lazy,
138
-
139
- // Search methods
140
- handleSearchInput,
141
- handleSearch,
142
-
143
- // Filter methods
144
- toggleFilterPopup,
145
- handleApplyFilter,
146
- clearFilter,
147
- handleFilterAction,
148
-
149
- // Row selection methods
150
- handleSelectAll,
151
- handleSelect,
152
- isRowSelected,
153
-
154
- // Grid settings
155
- columns,
156
- pageSettings,
157
- enableSearch,
158
- enableExcelExport,
159
- enablePdfExport,
160
- excelName,
161
- pdfName,
162
- pdfOptions,
163
- gridButtonClass,
164
- selectAll,
165
- tableHeaderStyle,
166
- gridContainerClass,
167
- gridColumnStyleSelectAll,
168
- gridColumnStyle,
169
- rowChange,
170
- showTotalPages,
171
- onSearch,
172
- onToolbarButtonClick,
173
- };
174
-
175
- return (
176
- <GridContext.Provider value={contextValue}>{children}</GridContext.Provider>
177
- );
178
- };
179
-
180
- // Base context hook
181
- export const useGridContext = () => {
182
- const context = useContext(GridContext);
183
- if (context === undefined) {
184
- throw new Error("useGridContext must be used within a GridProvider");
185
- }
186
- return context;
187
- };
@@ -1,7 +0,0 @@
1
- export { useDataSource } from "./useDataSource";
2
- export { useColumns } from "./useColumns";
3
- export { usePagination } from "./usePagination";
4
- export { useSearch } from "./useSearch";
5
- export { useFiltering } from "./useFiltering";
6
- export { useRowSelection } from "./useRowSelection";
7
- export { usePageStatus } from "./usePageStatus";
@@ -1,33 +0,0 @@
1
- import { useState, useEffect } from "react";
2
-
3
- export const useColumns = (columns: any[], workingDataSource: any[]) => {
4
- const [workingColumns, setWorkingColumns] = useState<any>([]);
5
-
6
- useEffect(() => {
7
- if (columns && columns.length > 0) {
8
- const filteredColumns = columns.map((column) => ({
9
- ...column,
10
- showFilterPopup: false,
11
- isFilterActive: false,
12
- }));
13
- setWorkingColumns(filteredColumns);
14
- } else if (
15
- workingDataSource.length > 0 &&
16
- Object.keys(workingDataSource[0]).length > 0
17
- ) {
18
- const inferredColumns = Object.keys(workingDataSource[0]).map((key) => ({
19
- field: key,
20
- headerText: key.charAt(0).toUpperCase() + key.slice(1),
21
- width: 150,
22
- }));
23
- setWorkingColumns((prevColumns: any) => {
24
- if (JSON.stringify(prevColumns) !== JSON.stringify(inferredColumns)) {
25
- return inferredColumns;
26
- }
27
- return prevColumns;
28
- });
29
- }
30
- }, [columns, workingDataSource]);
31
-
32
- return { workingColumns, setWorkingColumns };
33
- };
@@ -1,54 +0,0 @@
1
- import { useState, useCallback, useEffect } from "react";
2
- import { getSourceData } from "../../utils";
3
-
4
- export const useDataSource = (
5
- dataSource: any,
6
- pageSettings: any,
7
- lazy: boolean
8
- ) => {
9
- const [workingDataSource, setWorkingDataSource] = useState<any>([]);
10
- const [fallbackSourceData, setFallbackSourceData] = useState([]);
11
- const [totalPages, setTotalPages] = useState(0);
12
-
13
- const getGridData = useCallback(async () => {
14
- try {
15
- const sourceData = await getSourceData(dataSource);
16
- const gridData = sourceData.sourcedata;
17
- setFallbackSourceData(gridData);
18
- setWorkingDataSource(gridData);
19
- const totalPages = Math.ceil(gridData.length / pageSettings.pageNumber);
20
- setTotalPages(totalPages);
21
- return totalPages;
22
- } catch (error) {
23
- console.error("Error fetching grid source data:", error);
24
- return 0;
25
- }
26
- }, [dataSource, pageSettings.pageNumber]);
27
-
28
- useEffect(() => {
29
- const handleDataSource = async () => {
30
- if (Array.isArray(dataSource)) {
31
- setWorkingDataSource(dataSource);
32
-
33
- const totalPages =
34
- lazy && pageSettings.totalCount
35
- ? Math.ceil(pageSettings.totalCount / pageSettings.pageNumber)
36
- : Math.ceil(dataSource.length / pageSettings.pageNumber);
37
-
38
- setTotalPages(totalPages);
39
- } else if (typeof dataSource === "string") {
40
- await getGridData();
41
- }
42
- };
43
-
44
- handleDataSource();
45
- }, [dataSource, pageSettings, lazy, getGridData]);
46
-
47
- return {
48
- workingDataSource,
49
- setWorkingDataSource,
50
- fallbackSourceData,
51
- totalPages,
52
- setTotalPages,
53
- };
54
- };
@@ -1,135 +0,0 @@
1
- import { useState, useCallback } from "react";
2
- import {
3
- clearFilterHelper,
4
- handleApplyFilterHelper,
5
- } from "@grampro/headless-helpers";
6
-
7
- interface UseFilteringProps {
8
- columns: any[];
9
- workingColumns: any[];
10
- setWorkingColumns: (columns: any[]) => void;
11
- workingDataSource: any[];
12
- setWorkingDataSource: (data: any[]) => void;
13
- dataSource: any;
14
- fallbackSourceData: any[];
15
- resetPage: (data: any[], settings: any) => number;
16
- setTotalPages: (pages: number) => void;
17
- pageSettings: any;
18
- activeFilterArrayValue?: (filters: any[]) => void;
19
- }
20
-
21
- export const useFiltering = ({
22
- columns,
23
- workingColumns,
24
- setWorkingColumns,
25
- workingDataSource,
26
- setWorkingDataSource,
27
- dataSource,
28
- fallbackSourceData,
29
- resetPage,
30
- setTotalPages,
31
- pageSettings,
32
- activeFilterArrayValue,
33
- }: UseFilteringProps) => {
34
- const [activeFilterArray, setActiveFilterArray] = useState<any>([]);
35
-
36
- const toggleFilterPopup = useCallback(
37
- (index: number) => {
38
- setWorkingColumns(
39
- workingColumns.map((column: any, i: any) =>
40
- i === index
41
- ? { ...column, showFilterPopup: !column.showFilterPopup }
42
- : column
43
- )
44
- );
45
- },
46
- [workingColumns, setWorkingColumns]
47
- );
48
-
49
- const handleApplyFilter = useCallback(
50
- (event: any) => {
51
- const {
52
- columns: updatedColumns,
53
- workingDataSource: updatedFullDataSource,
54
- activeFilterArray: updatedActiveFilterArray,
55
- } = handleApplyFilterHelper(event, columns, workingDataSource);
56
-
57
- setWorkingColumns(updatedColumns);
58
- setWorkingDataSource(updatedFullDataSource);
59
- setActiveFilterArray(updatedActiveFilterArray);
60
- if (activeFilterArrayValue)
61
- activeFilterArrayValue(updatedActiveFilterArray);
62
- const totalPages = resetPage(updatedFullDataSource, pageSettings);
63
- setTotalPages(totalPages);
64
- },
65
- [
66
- columns,
67
- workingDataSource,
68
- setWorkingColumns,
69
- setWorkingDataSource,
70
- activeFilterArrayValue,
71
- resetPage,
72
- pageSettings,
73
- setTotalPages,
74
- ]
75
- );
76
-
77
- const clearFilter = useCallback(
78
- (event: any) => {
79
- const clearDataSource = Array.isArray(dataSource)
80
- ? dataSource
81
- : fallbackSourceData;
82
- const {
83
- columns: updatedColumns,
84
- workingDataSource: updatedDataSource,
85
- activeFilterArray: updatedActiveFilterArray,
86
- } = clearFilterHelper(event, workingColumns, clearDataSource);
87
-
88
- setWorkingColumns(updatedColumns);
89
- setWorkingDataSource(updatedDataSource);
90
- setActiveFilterArray(updatedActiveFilterArray);
91
- if (activeFilterArrayValue)
92
- activeFilterArrayValue(updatedActiveFilterArray);
93
- const totalPages = resetPage(updatedDataSource, pageSettings);
94
- setTotalPages(totalPages);
95
- },
96
- [
97
- dataSource,
98
- fallbackSourceData,
99
- workingColumns,
100
- setWorkingColumns,
101
- setWorkingDataSource,
102
- activeFilterArrayValue,
103
- resetPage,
104
- pageSettings,
105
- setTotalPages,
106
- ]
107
- );
108
-
109
- const handleFilterAction = useCallback(
110
- (action: any, colIndex: number) => {
111
- switch (action.type) {
112
- case "cancel":
113
- toggleFilterPopup(colIndex);
114
- break;
115
- case "applyFilter":
116
- handleApplyFilter(action);
117
- break;
118
- case "clearFilter":
119
- clearFilter(action);
120
- break;
121
- default:
122
- break;
123
- }
124
- },
125
- [toggleFilterPopup, handleApplyFilter, clearFilter]
126
- );
127
-
128
- return {
129
- activeFilterArray,
130
- toggleFilterPopup,
131
- handleApplyFilter,
132
- clearFilter,
133
- handleFilterAction,
134
- };
135
- };
@@ -1,13 +0,0 @@
1
- import { useEffect } from "react";
2
-
3
- export const usePageStatus = (
4
- currentPage: number,
5
- totalPages: number,
6
- pageStatus?: (status: any) => void
7
- ) => {
8
- useEffect(() => {
9
- if (pageStatus) {
10
- pageStatus({ currentPage, totalPages });
11
- }
12
- }, [pageStatus, currentPage, totalPages]);
13
- };