wooritech/리얼그리드

리얼그리드 기반의 Jira 스타일 이슈트래커 개발하기(with 리엑트) : 2.데이터 관리 및 기본 기능 구현

코딩쉐프 2024. 11. 19. 21:27
728x90

 2.데이터 관리 및 기본 기능 구현

이번 포스트에서는 **리얼그리드(RealGrid)**를 활용하여 Jira 스타일의 이슈 트래커에서 데이터 관리, 페이징, 필터링, 정렬 기능과 함께 동적 스타일을 적용하여 우선순위에 따라 다른 색상을 부여하는 방법을 다룹니다.


주요 구현 기능

  1. 데이터 필터링: 특정 조건에 맞는 데이터를 필터링.
  2. 데이터 정렬: 컬럼 헤더를 클릭하여 데이터를 정렬.
  3. 페이징 처리: 대량 데이터를 페이지별로 나누어 보여줌.
  4. 동적 스타일: 데이터 값(우선순위)에 따라 컬럼의 색상 스타일 동적 변경.

1. 페이징 처리

코드 및 설명

페이징은 데이터를 화면에 효율적으로 표시하기 위해 사용됩니다. gridView.setPaging을 통해 페이지 수를 설정하고, 현재 페이지와 총 페이지 수를 계산하여 화면에 표시합니다.

const setPaging = () => {
    if (gridRef.current) {
        const gridView = gridRef.current.gridView; // RealGridReact의 gridView 객체를 가져옴
        gridView.setPaging(true, 3); // 페이징 활성화(true), 페이지당 데이터 개수는 3개

        const updatePageInfo = () => {
            const currentPageElement = document.querySelector(".current-page-view");
            const totalPageElement = document.querySelector(".total-page-view");

            if (currentPageElement) {
                currentPageElement.textContent = String(gridView.getPage() + 1); // 현재 페이지 (0 기반)
            }
            if (totalPageElement) {
                totalPageElement.textContent = String(gridView.getPageCount()); // 전체 페이지 수
            }
        };

        updatePageInfo(); // 초기 페이지 정보 표시

        // 페이지 변경 시 호출
        gridView.onPageChanged = () => {
            updatePageInfo();
        };

        // 페이지 수 변경 시 호출
        gridView.onPageCountChanged = () => {
            updatePageInfo();
        };
    }
};

새로운 tsx파일 IssueGrid 생성

주요 메서드 및 속성

  1. setPaging(enable: boolean, pageSize: number)
    • enable: 페이징 활성화 여부.
    • pageSize: 한 페이지에 표시할 데이터 개수.
  2. getPage()
    • 현재 페이지 번호(0부터 시작)를 반환.
  3. getPageCount()
    • 전체 페이지 수를 반환.
  4. 이벤트 핸들러
    • onPageChanged: 페이지가 변경될 때 호출.
    • onPageCountChanged: 데이터 변경으로 전체 페이지 수가 달라질 때 호출.

2. 필터링 처리

코드 및 설명

필터링 기능은 사용자가 특정 조건에 따라 데이터를 걸러낼 수 있도록 해줍니다. 아래 코드는 필터 패널을 활성화하고 필터링 버튼을 제공합니다.

gridProps={{
    filtering: { selector: { showButtons: true } }, // 필터 버튼 활성화
    filterPanel: { visible: true }, // 필터 패널 표시
}}

주요 속성 및 설명

  1. filtering
    • 필터링 기능을 설정합니다.
    • selector.showButtons: 필터링 옵션에 버튼을 추가해 적용/취소 기능 제공.
  2. filterPanel
    • 필터 패널을 화면에 표시합니다.
    • filterPanel.visible: 필터 패널 표시 여부.

3. 정렬 처리

코드 및 설명

정렬 기능은 특정 컬럼의 데이터를 오름차순 또는 내림차순으로 정렬할 수 있습니다.

gridProps={{
    sorting: { enabled: true }, // 정렬 기능 활성화
}}

주요 속성 및 설명

  1. sorting
    • sorting.enabled: 정렬 기능을 활성화합니다.
    • 컬럼 헤더를 클릭하면 정렬 상태가 변경됩니다.

4. 동적 스타일 적용

코드 및 설명

데이터 값(우선순위)에 따라 각 행(row)의 스타일을 동적으로 변경합니다. 예를 들어, "높음" 우선순위는 빨간색, **"중간"**은 노란색, **"낮음"**은 초록색으로 표시됩니다.

rowStyleCallback={function (grid, item) {
    const ret = { styleName: "" };
    const priority = grid.getValue(item.index, "priority"); // 현재 행의 "priority" 값 가져오기
    if (priority === "높음") ret.styleName = "red-color";
    else if (priority === "중간") ret.styleName = "yellow-color";
    else if (priority === "낮음") ret.styleName = "green-color";
    return ret;
}}

App.css에 css클래스 정의하여 적용

주요 메서드 및 속성

  1. rowStyleCallback
    • grid: 그리드 객체.
    • item: 현재 행의 데이터.
    • styleName: 특정 CSS 클래스를 동적으로 적용.
  2. grid.getValue(rowIndex, fieldName)
    • rowIndex: 현재 행의 인덱스.
    • fieldName: 컬럼 이름.

5. 이전/다음 페이지 이동

코드 및 설명

현재 페이지를 기준으로 이전 또는 다음 페이지로 이동합니다.

const setPrevPage = () => {
    if (gridRef.current) {
        const gridView = gridRef.current.gridView;
        const currentPage = gridView.getPage();
        if (currentPage > 0) {
            gridView.setPage(currentPage - 1); // 이전 페이지로 이동
        }
    }
};

const setNextPage = () => {
    if (gridRef.current) {
        const gridView = gridRef.current.gridView;
        const currentPage = gridView.getPage();
        const totalPage = gridView.getPageCount();
        if (currentPage < totalPage - 1) {
            gridView.setPage(currentPage + 1); // 다음 페이지로 이동
        }
    }
};

이전페이지/다음페이지 html 버튼태그

주요 메서드

  1. setPage(pageNumber: number)
    • 특정 페이지로 이동합니다.
    • **pageNumber**는 0부터 시작합니다.

최종 코드 통합

아래는 페이징, 필터링, 정렬, 동적 스타일 적용, 페이지 이동 기능을 모두 포함한 코드입니다.

import * as RealGrid from 'realgrid';
import React from 'react';
import { useRef, useEffect } from 'react';
import 'realgrid/realgrid-style.css';
import { RealGridReact, RGDataField, RGDataColumn } from "realgrid-react";

const IssueGrid: React.FC = () => {
    const gridRef = useRef<RealGridReact>(null);
    
    //페이징 처리
    const setPaging =() => {
        if(gridRef.current) {
            const gridView = gridRef.current.gridView;
            
            //const dataProvier = gridRef.current.dataProvider;
            gridView.setPaging(true, 3);
            
            const page= gridView.getPage();
            const totalPage = gridView.getPageCount();

            const updatePageInfo = () => {
                const currentPageElement = document.querySelector(".current-page-view");
                const totalPageElement = document.querySelector(".total-page-view");

                if(currentPageElement) {
                    currentPageElement.textContent = String(gridView.getPage() + 1);
                }
                if (totalPageElement) {
                    totalPageElement.textContent = String(gridView.getPageCount());
                }
            };
            updatePageInfo();
            gridView.onPageChanged = (grid, page) => {
                updatePageInfo();
            }
            gridView.onPageCountChanged = (grid, pageCount) => {
                updatePageInfo();
            };
        }
    }
    const setPrevPage = () => {
        if (gridRef.current) {
            const gridView = gridRef.current.gridView;
            const currentPage = gridView.getPage();
            if (currentPage > 0) {
                gridView.setPage(currentPage - 1);
            }
        }
    };

    // 다음 페이지 이동
    const setNextPage = () => {
        if (gridRef.current) {
            const gridView = gridRef.current.gridView;
            const currentPage = gridView.getPage();
            const totalPage = gridView.getPageCount();
            if (currentPage < totalPage - 1) {
                gridView.setPage(currentPage + 1);
            }
        }
    };
    return (
        <div style={{ width: "100%", height: "550px" }}>
            <RealGridReact
                ref={gridRef}
                
                rowStyleCallback={function(grid, item, fixed) {
                    const ret = {styleName: ""};
                    var priority = grid.getValue(item.index,"priority");
                    if(priority === "높음") {
                        ret.styleName = "red-color"
                    }
                    if(priority === "중간") {
                        ret.styleName = "yellow-color"
                    }
                    if(priority === "낮음") {
                        ret.styleName = "green-color"
                    }
                    return ret
                }}
                rows={[
                    { id: 1, title: "버그 수정", status: "진행 중", priority: "높음", assignee: "홍길동" },
                    { id: 2, title: "기능 추가", status: "완료", priority: "중간", assignee: "김철수" },
                    { id: 3, title: "기능 수정", status: "예정", priority: "낮음", assignee: "김지민" },
                    { id: 4, title: "문서 업데이트", status: "진행 중", priority: "중간", assignee: "이영희" },
                    { id: 5, title: "테스트 케이스 작성", status: "완료", priority: "높음", assignee: "박지성" },
                    { id: 6, title: "API 설계", status: "예정", priority: "낮음", assignee: "최현우" },
                    { id: 7, title: "리팩토링", status: "진행 중", priority: "중간", assignee: "김다정" },
                    { id: 8, title: "배포 준비", status: "완료", priority: "높음", assignee: "오세훈" },
                ]}
                gridProps={{
                   
                    filtering:{selector:{showButtons:true}},
                    filterPanel:{visible:true},
                    sorting:{enabled:true},
                
                }}
                                
            >
                <RGDataField fieldName="id" />
                <RGDataField fieldName="title" />
                <RGDataField fieldName="status" />
                <RGDataField fieldName={"priority"}  />
                <RGDataField fieldName="assignee" />

                <RGDataColumn name="id" fieldName="id" width={50} />
                <RGDataColumn name="title" fieldName="title" width={200} />
                <RGDataColumn name="status" fieldName="status" width={100} />
                <RGDataColumn name="priority" fieldName="priority" width={100} />
                <RGDataColumn name="assignee" fieldName="assignee" width={150} />
            </RealGridReact>
            <div id="page" />
            <button onClick={setPaging} >페이징 처리</button>
            <div>
                <span>현재 페이지: <span className="current-page-view">1</span></span>
                <span> / 총 페이지: <span className="total-page-view">1</span></span>
            </div>
            <div>
                <button onClick={setPrevPage}>이전페이지</button>
            
                <button onClick={setNextPage}>다음페이지</button>
            </div>
        </div>
    );
};

export default IssueGrid;

페이징 처리 이전 화면 ( 필터 패널 / 우선순위 동적 스타일 적용)
필터링 검색 적용
페이징 처리 적용 모습

요약

  • 페이징: setPaging을 사용하여 데이터 페이지 나누기. (참고 문서)
  • 필터링: filterPanel과 filtering 속성으로 활성화.(filterPanel 참고문서 )
  • 정렬: sorting.enabled를 통해 컬럼 정렬.
  • 동적 스타일: rowStyleCallback으로 컬러를 동적으로 변경.(참고문서)
  • 페이지 이동: setPage 메서드를 사용하여 이동.(참고문서)

이 코드를 기반으로 강력한 데이터 관리 기능을 갖춘 이슈 트래커를 완성할 수 있습니다. 😊

728x90