> For the complete documentation index, see [llms.txt](https://tech.x2bee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tech.x2bee.com/dev-guide/dev-start/markdown/mui-x.md).

# 데이터 그리드 (Mui-X)

X2BEE BO(BackOffice) 템플릿은 목록 조회 및 데이터 관리(입력/수정/삭제)를 효율적으로 처리하기 위해 [MUI-X 데이터 그리드](https://mui.com/x/react-data-grid/)를 활용합니다. 이 템플릿은 BO 프로그램 전반에 걸쳐 폭넓게 사용되며, MUI를 확장하여 추가 기능을 제공함으로써 개발 편의성을 크게 향상시킵니다.

***

## X2beeDataGrid

{% stepper %}
{% step %}

### 데이터 그리드 파일 구조

* 파일 위치는 `/src/lib/x2bee-data-grid/*`입니다.

| **파일명**                          | **설명**                                                                    |
| -------------------------------- | ------------------------------------------------------------------------- |
| **x2bee-data-grid.tsx**          | 화면에 그려지는 그리드 컴포넌트입니다.                                                     |
| **x2bee-data-grid-utils.ts**     | 그리드 컴포넌트에서 사용되는 함수들로, 다회 사용되거나 분리가능하고 상대적으로 긴 코드들을 컴포넌트에서 분리해 둔 유틸 파일입니다. |
| **x2bee-data-grid-constants.ts** | 그리드에서 사용되는 상수들을 관리하는 파일입니다.                                               |
| **x2bee-data-grid-types.ts**     | 그리드에서 사용되는 타입들을 관리하는 파일입니다.                                               |
| **x2bee-grid-date-picker.tsx**   | 그리드에서 사용되는 date picker 관련 파일입니다.                                          |
| **use-x2bee-data-grid.ts**       | 그리드에 관련된 hook이 선언된 파일입니다.                                                 |
| **x2bee-data-grid-context.tsx**  | 그리드를 감싼 컴포넌트로 dataRef를 주입해줍니다.                                            |
| {% endstep %}                    |                                                                           |

{% step %}

### 데이터 그리드 컴포넌트 제공 옵션

* [MUI 그리드 옵션](https://mui.com/x/api/data-grid/data-grid-premium/)에서 MUI 제공 옵션에 대해 자세하게 확인할 수 있습니다.
* X2beeDataGrid 컴포넌트에서 추가적으로 제공하는 옵션은 다음과 같습니다.

| **옵션**          | **설명**                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| dataRef         | MUI에서 제공되는 API(apiRef) 외에 추가적으로 제공되는 함수들을 포함한 ref 객체입니다. [소스](https://gitlab.x2bee.com/team-project/ec3-1/bo-mui/-/blob/main/src/lib/x2bee-data-grid/x2bee-data-grid-types.ts) 페이지의 X2beeDataGridDataRefType에서 제공되는 기능들을 확인할 수 있습니다. 대표적으로 그리드에서 관리되는 CUD의 row state별로 row 리스트를 가져올 수 있으며, 버튼의 행 관리 기능도 함수로 제공됩니다.                                                                                                                                        |
| hideDeleteRow   | Row 삭제 시 그리드에서 노출 여부를 설정합니다. 기본값은 false입니다.                                                                                                                                                                                                                                                                                                                                                                                                               |
| enableRowState  | Row의 상태(CUD)를 표시할지 여부를 설정합니다. 기본값은 false입니다.                                                                                                                                                                                                                                                                                                                                                                                                              |
| fetchSave       | Row의 저장 버튼에 대한 콜백 함수입니다. 선언 시 저장 버튼이 노출됩니다.                                                                                                                                                                                                                                                                                                                                                                                                               |
| paginationProps | 페이지네이션을 구현하기 위해, 필요하지 않은 경우 MUI 데이터 그리드의 기본 속성 `rows`를 간단히 사용할 수 있습니다. 기본값으로 최소한 빈 배열을 제공하는 것이 필수적입니다. `paginationProps`가 없으면 `rows`는 필수로 지정되어야 합니다. 이 접근 방식은 MUI의 페이지네이션 구현에 의존하지 않고 X2beeDataGrid 내에서 모든 상태를 내부적으로 관리합니다. 입력 타입은 `X2beeSimplePagination`이며, `paginationProps`, 기존의 `rows`, `pagination`, `pageSizeOptions`와 동시에 사용할 수 없습니다. `paginationProps` 내의 `pageSizeOptions`는 옵션으로 지정할 수 있으며, 제공되지 않을 경우 기본값은 `[100, 500, 1000, 5000, 10000]`입니다. |
| enableNoColumn  | 이 옵션은 기본 열 "No"의 가시성을 설정할 수 있게 해줍니다. 기본값은 true입니다.                                                                                                                                                                                                                                                                                                                                                                                                        |
| {% endstep %}   |                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

{% step %}

### 컴포넌트 사용 가이드

X2beeDataGrid 컴포넌트는 DataGridPremium 컴포넌트를 감싸, 내부적으로 MUI에서 제공하지 않는 추가, 수정, 삭제 상태를 관리하는 역할을 합니다.

* 그리드는 자체적으로 공간을 가지지 않으므로, 반드시 상위 태그 및 컴포넌트에서 공간을 확보해야 정상적으로 렌더링됩니다. 참고: <https://mui.com/x/react-data-grid/layout/>
* 필수로 입력해야 하는 옵션값은 `columns`와 `rows` 또는 `paginationProps`입니다. `paginationProps`와 `rows`는 반드시 둘 중 하나만 입력해야 합니다.

예시:

{% code title="사용 예시" %}

```jsx
<Box sx={{ height: '500px' }}>
  <X2beeDataGrid
    dataRef={dataRef}
    apiRef={apiRef}
    columns={columns}
    checkboxSelection
    onCellDoubleClick={onCellDoubleClickHandler}
    slotProps={{
      columnsManagement: { getTogglableColumns: () => columns.map((el) => el.field) },
      baseCheckbox: { disabled: baseCheckboxDisable }
    }}
    slots={{
      toolbar: () => CustomButtons({
        changeCheckBoxSelectable: (value) => setBaseCheckboxDisable(!value)
      })
    }}
    // pagination용 추가가 필요한 props
    paginationProps={{ fetch: async (paginationModel) => fetch(paginationModel.page, paginationModel.pageSize) }}
  />
</Box>
```

{% endcode %}
{% endstep %}
{% endstepper %}

***

## 그리드 API

{% stepper %}
{% step %}

### 1. 커스텀 그리드 API(dataRef)

* MUI에서 제공되는 그리드 API는 [MUI apiRef 정보](https://mui.com/x/api/data-grid/grid-api/)에서 자세하게 확인할 수 있습니다.
* X2beeDataGrid 컴포넌트 내부의 상태값등에 접근하며, 커스텀 기능들을 호출가능하게 해주는 API 객체입니다.

| **기능**                                                                         | **설명**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| useDataRef()                                                                   | 이 훅은 `dataRef`에 대한 객체를 제공합니다. 예: const dataRef = useDataRef(); \<X2beeDataGrid dataRef={dataRef} ... />                                                                                                                                                                                                                                                                                                                                                                                                                  |
| dataRef.current.all()                                                          | 오브젝트는 `update`, `create`, `delete`라는 세 가지 프로퍼티를 포함하여 반환됩니다. 각 프로퍼티는 수정된 행, 추가된 행, 삭제된 행을 배열 형태로 제공합니다.                                                                                                                                                                                                                                                                                                                                                                                                                   |
| dataRef.current.grid()                                                         | <p>다음은 반환되는 함수 목록 입니다.<br>selectClear, selectDelete, allClear, addRow, setUpdateRows export type X2beeDataGridDataRefGridFnType = { selectClear: () => void // 선택 행 변경취소 selectDelete: () => void // 선택 행 삭제 allClear: () => void // 전체 행 변경취소 addRow: () => void // 행 추가 save: () => void // fetchSave 호출 validation: ValidationFunction // update 및 create 행 valid asyncValidation: AsyncValidationFunction // update 및 create 행 valid를 비동기로 시행 setUpdateRows: (ids: GridRowId\[]) => void // updateRowId를 직접 추가 }</p> |
| dataRef.current.fetch()                                                        | 수동으로 grid에 fetch를 진행할때 사용됩니다. `paginationProps`을 사용하여 fetch를 구현한경우 반드시 해당 기능으로 fetch를 진행해야 합니다.                                                                                                                                                                                                                                                                                                                                                                                                                          |
| dataRef.current.create() / dataRef.current.update() / dataRef.current.delete() | `dataRef.current.all()`에서 제공되는 값들을 별도로 제공하는 함수입니다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| dataRef.current.validation()                                                   | 그리드의 모든 editRow에대해 validation을 진행합니다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| {% endstep %}                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

{% step %}

### 2. API 객체 활용 가이드

MUI에서는 그리드를 제어할 수 있는 API 객체를 제공합니다. X2beeDataGrid에서도 그리드의 등록, 수정, 삭제 관련 기능 및 데이터를 API 객체를 통해 활용할 수 있습니다.

예시:

{% code title="사용 예시" %}

```jsx
const dataRef = useDataRef();
const apiRef = useGridApiRef();
return (
  <>
    <Box>
      <Markdown children={content} />
    </Box>
    <Stack direction="column">
      <Box sx={{ border: 1 }}>데이터 출력</Box>
      <Box sx={{ border: 1 }}>{JSON.stringify(showData)}</Box>
    </Stack>
    <Stack direction="row" borderBottom={1}>
      <Button onClick={() => setShowData(dataRef.current.create())}> 추가 데이터 가져오기 </Button>
      <Button onClick={() => setShowData(dataRef.current.update())}> 수정 데이터 가져오기 </Button>
      <Button onClick={() => setShowData(dataRef.current.delete())}> 삭제 데이터 가져오기 </Button>
      <Button onClick={() => setShowData(dataRef.current.all())}> 모든 데이터 가져오기 </Button>
    </Stack>
    <Box height="500px">
      <X2beeDataGrid
        columns={columns}
        rows={gridSampleRows}
        dataRef={dataRef}
        apiRef={apiRef}
        enableRowState
        // pagination을 위한 추가 props
        fetchSave={(allGridData, validation) => {
          const errorMessage = validation();
          if (errorMessage) alert(errorMessage);
        }}
      />
    </Box>
  </>
);
```

{% endcode %}
{% endstep %}
{% endstepper %}

***

## X2beeDataColDef

{% stepper %}
{% step %}

#### 1. 그리드 컬럼 제공 옵션

* MUI에서 제공하는 옵션은 [MUI 컬럼 옵션](https://mui.com/x/api/data-grid/grid-col-def/) 에서 확인 할 수 있습니다.
* X2beeGridColDef 에서 제공하는 추가옵션은 다음과 같습니다.

| **옵션명**         | **타입**                                                                                                                                                          | **설명**                                                                                                                                                                                                                                                                                      |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| visible         | boolean                                                                                                                                                         | 열이 초기에 노출될지 여부를 설정 가능합니다. initialState의 column hide를 단순화 한 옵션입니다.                                                                                                                                                                                                                           |
| defaultValue    | any                                                                                                                                                             | 열 추가시 기본으로 지정되는 값입니다.                                                                                                                                                                                                                                                                       |
| validBlank      | boolean                                                                                                                                                         | 셀 수정시, 빈값을 허용할지 여부를 설정 가능합니다.                                                                                                                                                                                                                                                               |
| validation      | X2beeGridValidation\[]                                                                                                                                          | 셀 수정시, 값 검증을 위해 사용됩니다. `valid`와 `message`를 prop으로 가지며, `valid`의 리턴값이 `false`일 경우, 셀에서 `message`가 오류로 출력됩니다. 제공되는 params는 다음과 같습니다. { id, value, field, row, otherProps, apiRef }                                                                                                            |
| dateEditor      | Object                                                                                                                                                          | 셀 수정시, DatePicker 사용할 옵션을 설정합니다. `type`을 통해 노출할 달력 형식을 지정할 수 있으며 결과 값을 `dateFormat`을 통해 지정할 수 있습니다. 제공되는 params는 다음과 같습니다. { type: 'date' \| 'dateTime', dateFormat: string, minDate: string, maxDate: string }                                                                             |
| dynamicEditable | [코드 참조](https://gitlab.x2bee.com/team-project/ec3-1/bo-mui/-/blob/main/src/lib/x2bee-data-grid/x2bee-data-grid-types.ts)`X2beeGridColDef`의 `dynamicEditable`참조. | 다른 셀의 값에 의해 해당 셀의 `editable`여부가 동적으로 변경되는 옵션입니다. 사용시 `editable`은 따로 선언해주지 않으셔도 됩니다. 제공되는 params는 다음과 같습니다. { otherProps: GridValidRowModel, apiRef: MutableRefObject, dataRef: MutableRefObject\<X2beeDataGridDataRefType> } 리턴으로 돌려줘야하는 값은 다음과 같습니다. { editable: boolean, value?: string } |
| {% endstep %}   |                                                                                                                                                                 |                                                                                                                                                                                                                                                                                             |

{% step %}

#### 2. 확장된 컬럼 타입 정의 및 유효성 검증 가이드

MUI 에서 제공하는 `GridColDef` 타입을 상속 받아 옵션을 추가한 컬럼 타입입니다. 기존의 MUI의 기능 및 X2beeDataGrid에서 추가적으로 제공하는 기능들을 정의 가능합니다.

예시:

{% code title="cols 예시" %}

```ts
const cols: X2beeGridColDef[] = [
  {
    headerName: '상품번호',
    field: 'goodsNo',
    editable: true,
    width: 150,
    validBlank: '상품번호를 입력해 주세요',
    validation: [
      {
        valid: (params) => {
          if (params.otherProps.goodsType === '묶음상품') {
            const typeInt = parseInt(params.value as string, 10) ?? 1000
            return typeInt >= 1000
          }
          return true
        },
        message: '묶음상품인경우 상품번호가 1000보다 커야합니다'
      },
      {
        valid: (params) => {
          if (params.otherProps.goodsType === '일반상품') {
            const typeInt = parseInt(params.value as string, 10) ?? 1000
            return typeInt < 1000
          }
          return true
        },
        message: '일반상품인경우 상품번호가 1000보다 작아야합니다'
      }
    ]
  },
  {
    headerName: '상품명',
    field: 'goodsNm',
    type: 'string',
    editable: true,
    width: 150,
    validBlank: true,
    validation: [
      {
        valid: (params) => {
          const allRow = params.apiRef.current.getRowModels()
          const allRowIds = params.apiRef.current.getAllRowIds()
          return allRowIds.every(
            (id) => params.id === id || allRow.get(id)?.[params.field] !== params.value
          )
        },
        message: '중복된 상품명은 사용할수 없습니다.'
      }
    ]
  },
  {
    headerName: '상품타입',
    field: 'goodsType',
    type: 'singleSelect',
    valueOptions: [...GoodsTypeArr],
    defaultValue: GoodsTypeArr[0],
    editable: true,
    width: 150
  },
  {
    headerName: '가격',
    field: 'price',
    type: 'number',
    editable: true,
    width: 150,
    validation: [
      {
        valid: (params) => (params.value as number) > 0,
        message: '가격은 0보다 커야합니다'
      }
    ]
  },
  {
    headerName: '등록일',
    field: 'regDate',
    editable: true,
    width: 150,
    defaultValue: dayjs().format(),
    dateEditor: {
      type: 'date',
      dateFormat: 'YYYYMMDD',
      minDate: dayjs().format(),
      maxDate: '2050-12-31'
    }
  }
]
```

{% endcode %}
{% endstep %}
{% endstepper %}

***

## Common-toolbar

{% stepper %}
{% step %}

#### 1. 툴바 및 버튼 컴포넌트 구조

| **컴포넌트**          | **타입**   | **설명**                                |
| ----------------- | -------- | ------------------------------------- |
| Toolbar.Container |          |                                       |
| Toolbar.Button    | add      | 행 추가 기능입니다.                           |
|                   | remove   | 행 삭제 기능입니다.                           |
|                   | reset    | 선택한 행 초기화 기능입니다.                      |
|                   | resetAll | 모든 행에대한 초기화 기능입니다.                    |
|                   | save     | 데이터 그리드에 fetchSave로 입력한 함수를 실행합니다.    |
|                   | excel    | 엑셀 다운로드 기능을 제공합니다.                    |
|                   | custom   | 커스텀 버튼을 제공합니다. 버튼 자체로는 기능을 제공하지 않습니다. |
| {% endstep %}     |          |                                       |

{% step %}

#### 2. 툴바 확장 및 커스터마이징 가이드

이 가이드는 MUI에서 제공하는 `GridToolbarContainer`를 감싸 기능을 추가한 컴포넌트를 상세히 설명합니다.

그리드에 필요한 기본 기능인 열 추가, 삭제, 초기화 외에도 커스텀 버튼 및 엑셀 다운로드 버튼을 추가할 수 있는 방법을 안내합니다.

예시:

{% code title="툴바 슬롯 예시" %}

```jsx
<X2BeeDataGrid
  ...
  slots={{
    toolbar: () => (
      <Toolbar.Container
        leftSlot={
          <>
            <Toolbar.Button type="add" title="기획전 등록" onClick={() => console.log('등록 팝업')} />
            <Toolbar.Button type="remove" />
            <Toolbar.Button type="resetAll" />
            <Toolbar.Button type="save" />
            <Toolbar.Button type="custom" title="일괄 변경" onClick={() => console.log('일괄 변경')} />
          </>
        }
        rightSlot={
          <>
            <Toolbar.Button type="excel" />
            <Toolbar.Button type="custom" title="복사" onClick={() => console.log('복사')} />
          </>
        }
      />
    )
  }}
/>
```

{% endcode %}
{% endstep %}
{% endstepper %}
