From 9149fe65406da3e7fe91fdde83d2e13bce66ee61 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 6 Aug 2024 13:56:54 +0900 Subject: [PATCH] feat: Add grid component --- package.json | 1 + src/components/Intro.jsx | 20 ++++- .../datepicker/RangeDatePicker.jsx | 0 .../datepicker/SingleDatePicker.jsx | 0 src/components/common/grid/QGrid.jsx | 83 +++++++++++++++++++ yarn.lock | 22 ++++- 6 files changed, 121 insertions(+), 5 deletions(-) rename src/components/{ui => common}/datepicker/RangeDatePicker.jsx (100%) rename src/components/{ui => common}/datepicker/SingleDatePicker.jsx (100%) create mode 100644 src/components/common/grid/QGrid.jsx diff --git a/package.json b/package.json index b4af1ba6..07d6a666 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "@nextui-org/react": "^2.4.2", "@prisma/client": "^5.17.0", + "ag-grid-react": "^32.0.2", "axios": "^1.7.3", "fabric": "^5.3.0", "framer-motion": "^11.2.13", diff --git a/src/components/Intro.jsx b/src/components/Intro.jsx index b6626a37..86be98fa 100644 --- a/src/components/Intro.jsx +++ b/src/components/Intro.jsx @@ -1,8 +1,10 @@ 'use client' import { useState } from 'react' -import SingleDatePicker from './ui/datepicker/SingleDatePicker' -import RangeDatePicker from './ui/datepicker/RangeDatePicker' + +import SingleDatePicker from './common/datepicker/SingleDatePicker' +import RangeDatePicker from './common/datepicker/RangeDatePicker' +import QGrid from './common/grid/QGrid' export default function Intro() { const [startDate, setStartDate] = useState(new Date()) @@ -19,20 +21,30 @@ export default function Intro() { setDateRange, } + const gridProps = { + isPageable: false, + } + return ( <>
-

Single Date Picker

+
Single Date Picker
-

Range Date Picker

+
Range Date Picker
+
+
QGrid
+
+ +
+
) } diff --git a/src/components/ui/datepicker/RangeDatePicker.jsx b/src/components/common/datepicker/RangeDatePicker.jsx similarity index 100% rename from src/components/ui/datepicker/RangeDatePicker.jsx rename to src/components/common/datepicker/RangeDatePicker.jsx diff --git a/src/components/ui/datepicker/SingleDatePicker.jsx b/src/components/common/datepicker/SingleDatePicker.jsx similarity index 100% rename from src/components/ui/datepicker/SingleDatePicker.jsx rename to src/components/common/datepicker/SingleDatePicker.jsx diff --git a/src/components/common/grid/QGrid.jsx b/src/components/common/grid/QGrid.jsx new file mode 100644 index 00000000..a0cd3ef1 --- /dev/null +++ b/src/components/common/grid/QGrid.jsx @@ -0,0 +1,83 @@ +import { useCallback, useEffect, useMemo, useState } from 'react' +import { AgGridReact } from 'ag-grid-react' + +import 'ag-grid-community/styles/ag-grid.css' +import 'ag-grid-community/styles/ag-theme-quartz.css' + +export default function QGrid(props) { + const { gridData, gridColumns, isPageable = true } = props + const [count, setCount] = useState(0) + const [clickedCount, setClickedCount] = useState(0) + /** + * 행 데이터를 설정할 때 useState을 사용하여 렌더링 전반에 걸쳐 일관된 배열 참조를 유지하는 것이 좋습니다 + */ + const [rowData, setRowData] = useState([]) + + /** + * Column Definitions를 설정할 때는 useMemo 또는 useState를 사용하여 렌더 간에 일관된 참조를 유지하십시오. + * 응용 프로그램이 Column Definitions를 동적으로 변경하는 경우에도 렌더링 간에 일관된 참조를 유지하려면 useMemo 또는 useState를 사용하십시오. + */ + const [colDefs, setColDefs] = useState( + gridColumns ?? [ + { field: 'mission', filter: true }, + { field: 'company' }, + { field: 'location' }, + { field: 'date' }, + { field: 'price', valueFormatter: (params) => `₩ ${params.value.toLocaleString()}` }, + { field: 'successful' }, + { field: 'rocket' }, + ], + ) + + /** + * defaultColDef 속성을 제공할 때 이 인라인 또는 구성 요소의 단순 개체로 정의하지 마십시오. 이렇게 하면 모든 렌더링에서 새 인스턴스가 생성됩니다. + * 대신 or useState 를 사용하여 useMemo 렌더 간에 일관된 참조가 유지되도록 합니다. + */ + const defaultColDef = useMemo(() => { + filter: true + }, []) + + /** + * 단순 유형(string, boolean 및 number)의 속성은 렌더링 간에 값으로 비교되므로 후크를 사용할 필요가 없습니다. + */ + const rowBuffer = 0 + + /** + * 모든 렌더링에서 그리드 상태를 재설정하지 않도록 useCallback을 사용하는 것이 좋습니다. + */ + const isRowSelectable = useCallback((node) => node.data.value > count, [count]) + + /** + * Event Listeners의 경우 이벤트 처리기가 그리드 내에서 업데이트를 트리거하지 않으므로 useCallback을 사용할 필요가 없습니다. + * 그러나 콜백과 일관성을 유지하고 항상 useCallback을 사용하는 것이 더 쉬울 수 있습니다. + */ + const onFilterOpened = useCallback(() => { + console.log(`number of clicks is ${clickedCount}`) + }, [clickedCount]) + + // Fetch data & update rowData state + useEffect(() => { + gridData + ? setRowData(gridData) + : fetch('https://www.ag-grid.com/example-assets/space-mission-data.json') // Fetch data from server + .then((result) => result.json()) // Convert to JSON + .then((rowData) => setRowData(rowData)) // Update state of `rowData` + }, []) + + return ( +
+ +
+ ) +} diff --git a/yarn.lock b/yarn.lock index f0291bd0..cfb210ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2152,6 +2152,26 @@ acorn@^8.5.0: resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz" integrity sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw== +ag-charts-types@10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/ag-charts-types/-/ag-charts-types-10.0.2.tgz#fe4d7aa3cdc4ba6f354d7b4bbf65818e242f2fd6" + integrity sha512-Nxo5slHOXlaeg0gRIsVnovAosQzzlYfWJtdDy0Aq/VvpJru/PJ+5i2c9aCyEhgRxhBjImsoegwkgRj7gNOWV6Q== + +ag-grid-community@32.0.2: + version "32.0.2" + resolved "https://registry.yarnpkg.com/ag-grid-community/-/ag-grid-community-32.0.2.tgz#a69d99ee944fa07ab5faa103f6f930fbd2d4b432" + integrity sha512-vLJJUjnsG9hNK41GNuW2EHu1W264kxA/poOpcX4kmyrjU5Uzvelsbj3HdKAO9POV28iqyRdKGYfAWdn8QzA7KA== + dependencies: + ag-charts-types "10.0.2" + +ag-grid-react@^32.0.2: + version "32.0.2" + resolved "https://registry.yarnpkg.com/ag-grid-react/-/ag-grid-react-32.0.2.tgz#675b477f23f1f1338af0c15f174f9da3c68baec9" + integrity sha512-IWYsoyJ/Z763rWbE5/9SaT1n5xwIKrm/QzOG14l7i8z5J6JdJwfV0aQFATmEE8Xws2H48vlLcLdW1cv4hwV3eg== + dependencies: + ag-grid-community "32.0.2" + prop-types "^15.8.1" + agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -3307,7 +3327,7 @@ prisma@^5.17.0: dependencies: "@prisma/engines" "5.17.0" -prop-types@^15.7.2: +prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==