@vmscloud/moz-ui-grid-vue 0.2.0 → 0.2.1

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.
@@ -195,6 +195,7 @@ grid.on('row:click', ({ rowIndex }) => {
195
195
  | `showHeader` | `boolean` | `true` | 헤더 표시 여부 |
196
196
  | `rowHeader` | `boolean \| RowHeaderConfig` | `false` | 좌측 행 헤더 컬럼(`_rowHeader`) 표시. `true`면 빈 셀(너비 40, 체크박스 트리거 시 체크박스), 객체면 `width`/`cellRenderer`/`headerRenderer`로 커스터마이즈 (→ [RowHeaderConfig](#rowheaderconfig)). `rowSelection.trigger`가 `'rowHeader'`/`'checkbox'`면 미지정이어도 자동 ON. (구 `showRowHeader` — deprecated alias 유지) |
197
197
  | `showStatusBar` | `boolean` | `true` | 상태 바 표시 |
198
+ | `summaryRow` | `'none' \| 'pinnedTop' \| 'pinnedBottom'` | `'none'` | 집계(총합계) 행 표시 위치. `FieldDef.aggregate` 가 지정된 컬럼을 모아 core 가 행을 직접 소유하며, `getConfig()` 에 실려 레이아웃 프리셋으로 저장·복원된다 |
198
199
  | `alternatingRows` | `boolean` | `false` | 줄무늬 행 스타일 |
199
200
  | `rowStyle` | `string` | — | 행 CSS 스타일 |
200
201
  | `headerStyle` | `string` | — | 헤더 CSS 스타일 |
@@ -352,7 +353,7 @@ grid.on('row:click', ({ rowIndex }) => {
352
353
  | 속성 | 타입 | 설명 |
353
354
  |------|------|------|
354
355
  | `mask` | `MaskConfig` | 마스킹 설정 |
355
- | `aggregate` | `AggregateFunc` | 그룹/피벗 집계 함수 |
356
+ | `aggregate` | `AggregateFunc` | 그룹/피벗 집계 함수. wrapper의 `useSummaryFooter: true`에서는 컬럼 하단 집계에도 사용한다(기본 OFF). 표시를 꺼도 함수는 유지된다 |
356
357
 
357
358
  ### 그룹 행
358
359
 
@@ -669,7 +670,7 @@ interface GridConfigExport {
669
670
  | **뷰 상태** | `sorts`, `filters` |
670
671
  | **서버/수동 row-model** | `rowModel`, `endReachedThresholdRows` |
671
672
  | **트리/디테일** | `treeConfig`, `masterDetailConfig` |
672
- | **UI 옵션** | `theme`, `rowHeight`, `headerHeight`, `rowSelection`, `cellSelection`, `cellSelectionImpliesRows`, `editable`, `tooltipMode`, `alternatingRows`, `showHeader`, `resizableColumns`, `reorderableColumns`, `rowHeader`, `reorderableRows`, `showDragHandleColumn`, `autoFitColumns`, `showStatusBar`, `locale`, `translations`, `keyFields` 등 |
673
+ | **UI 옵션** | `theme`, `rowHeight`, `headerHeight`, `rowSelection`, `cellSelection`, `cellSelectionImpliesRows`, `editable`, `tooltipMode`, `alternatingRows`, `showHeader`, `resizableColumns`, `reorderableColumns`, `rowHeader`, `reorderableRows`, `showDragHandleColumn`, `autoFitColumns`, `showStatusBar`, `summaryRow`, `locale`, `translations`, `keyFields` 등 |
673
674
 
674
675
  **제외되는 항목**
675
676
 
@@ -919,7 +920,7 @@ rowSelection(선택된 행들)·cellSelection(선택된 셀 range)은 서로 다
919
920
  |--------|------|------|
920
921
  | `addPinnedTop(row \| RowConfig)` | `Row` | 새 행/설정으로 상단 고정 행 추가 |
921
922
  | `addPinnedBottom(row \| RowConfig)` | `Row` | 새 행/설정으로 하단 고정 행 추가 |
922
- | `addGrandTotal(aggregates)` | `Row` | 전체 합계 행 추가 |
923
+ | `addGrandTotal(aggregates)` | `Row` | **(deprecated)** 전체 합계 행 추가 — `grid.setSummaryRow('pinnedBottom')` 를 사용할 것. 이 API 로 꽂은 행은 `getConfig()` 에 실리지 않아 레이아웃 프리셋으로 저장·복원되지 않는다 |
923
924
  | `addFilter()` | `Row` | 필터 행 추가 |
924
925
 
925
926
  #### 고정 관리
@@ -1229,6 +1230,55 @@ await grid.changes.commit({ allowInvalid: true });
1229
1230
 
1230
1231
  ---
1231
1232
 
1233
+ #### 그룹 집계 식별자
1234
+
1235
+ `RowGroupConfig.aggregates`의 각 항목에는 선택적인 `id`를 지정할 수 있습니다.
1236
+ 기본 ID는 내장 함수의 경우 `${func}_${column}`(예: `sum_salary`), 콜백은 `column`입니다.
1237
+ `getRowGroupAggregateId(aggregate)`를 core 패키지에서 가져와 유효 ID를 조회할 수 있습니다.
1238
+ 입력과 저장 설정은 원형을 보존하므로 이 조회가 생략된 `id`를 설정 객체에 써넣지는 않습니다.
1239
+
1240
+ - 명시한 ID는 그대로 사용합니다. 이름을 분해해 컬럼·함수를 추론하지 않습니다.
1241
+ - 같은 레벨에서 실제로 적용되는 집계 ID는 유일해야 합니다. 서로 다른 레벨의 scope에서는
1242
+ 같은 ID를 사용할 수 있지만, 모든 레벨 선언과 특정 레벨 선언의 scope가 겹치면 충돌합니다.
1243
+ - `setConfig` 및 그룹 컬럼 변경 시 충돌을 검사합니다. 충돌하면 예외가 발생하며 기존 그룹
1244
+ 설정은 변경되지 않습니다. 그룹 해제 중 보관한 선언은 그룹 복원 시 다시 검사합니다.
1245
+ - 공개 ID는 내부 계산 alias와 별개입니다. ID를 지정해도 기존 집계값·서식의 alias는 바뀌지 않습니다.
1246
+ - 콜백 기본값은 함수의 영속 식별자가 아닙니다. 같은 컬럼에 여러 콜백을 쓰면 ID를 명시해야 하며,
1247
+ 콜백 자체의 JSON 직렬화를 보장하지 않습니다. 수식에서 참조 가능한 문법 역시 별도 계약입니다.
1248
+
1249
+ #### 그룹행 정렬 기준
1250
+
1251
+ core의 `RowGroupConfig.sorts`는 같은 부모 아래 그룹행을 그룹 컬럼별로 정렬합니다.
1252
+ 각 규칙은 `{ column, direction, by }`이며 `column`은 해당 그룹 레벨의 컬럼 id,
1253
+ `direction`은 `'asc' | 'desc'`입니다.
1254
+
1255
+ - `id`: 정렬할 그룹 레벨의 컬럼 ID (집계 데이터 컬럼이 아님).
1256
+ - `basis: 'groupValue'`: **그룹 이름** — 원본 scalar 값을 비교합니다. 생략해도 이 기준입니다.
1257
+ - `basis: 'rowCount'`: 하위 데이터 행 개수.
1258
+ - `basis: 'aggregate', by: 'salaryTotal'`: 해당 레벨의 공개 집계 ID를 정확히 참조합니다.
1259
+ `by`는 문자열 하나이며 객체/배열이 아닙니다. 명시 ID가 없으면 `${func}_${column}`을 사용합니다.
1260
+ 공백 제거·별칭 추측 없이 ID를 비교하며 `scope`는 전체 그룹 경로와 정확히 일치해야 합니다.
1261
+ 유효하지 않은 활성 집계 참조는 오류입니다. `by`만 제공해도 집계 기준을 추론하지 않습니다.
1262
+
1263
+ ```ts
1264
+ await grid.rowGroup.setConfig({
1265
+ columns: ['dept', 'team'],
1266
+ aggregates: [{ id: 'salaryTotal', column: 'salary', func: 'sum', scope: ['dept', 'team'] }],
1267
+ sorts: [
1268
+ { id: 'dept', direction: 'asc', basis: 'groupValue' },
1269
+ { id: 'team', direction: 'desc', basis: 'aggregate', by: 'salaryTotal' },
1270
+ ],
1271
+ });
1272
+ ```
1273
+
1274
+ 저장본 0.4 → 0.5 마이그레이션은 옛 그룹 정렬 `column`/객체 `by`를 새 모델로 변환하고,
1275
+ 피벗 `SortState.byValue`는 동일한 scalar 값 그대로 `by`로 개명합니다. 피벗 집계/정렬 의미는 변하지 않습니다.
1276
+
1277
+ 그룹 내부 데이터 행의 일반 정렬은 별도로 유지됩니다. null/undefined는 기존 정렬 규약대로
1278
+ 오름차순에서는 뒤, 내림차순에서는 앞에 위치합니다. wrapper 정렬 패널의 **그룹 정렬 → 정렬 기준**에서도
1279
+ ‘그룹 이름’을 선택할 수 있습니다. 정렬 규칙이 없을 때와 새 규칙을 추가할 때 모두
1280
+ **그룹 이름 오름차순**이 기본입니다. 기존에 저장한 하위 행 개수·집계 정렬은 그대로 유지됩니다.
1281
+
1232
1282
  ### grid.tree — 트리 API
1233
1283
 
1234
1284
  > 트리 미설정 시 `getConfig()`는 `null` 반환.
@@ -2213,7 +2263,8 @@ grid.off('cell:click', handler);
2213
2263
  | `formattedValue` | `string` | 렌더링된 텍스트 (헤더는 컬럼 라벨) |
2214
2264
  | `tooltipText?` | `string` | 컬럼 커스텀 툴팁 문구(`ColumnDef.headerTooltip`/`cellTooltip`). 있으면 `formattedValue` 대신 표시에 우선 |
2215
2265
  | `isOverflowing` | `boolean` | 셀 내용이 잘려서 표시되는지 |
2216
- | `cellRect` | `DOMRect` | 셀/헤더 DOM 영역 |
2266
+ | `cellRect` | `DOMRect` | 셀/헤더 DOM 영역 (셀 전체. 뷰포트 밖까지 포함) |
2267
+ | `anchorRect` | `DOMRect` | **툴팁을 놓을 기준 영역** — 셀에서 지금 화면에 보이는 띠. 셀이 전부 보이면 `cellRect` 와 같다. 뷰포트보다 긴 세로 병합 셀은 글자가 가시 영역 중앙에 붙어 있으므로, 이 값을 기준으로 배치해야 툴팁이 글자를 따라간다 |
2217
2268
  | `element` | `HTMLElement` | 셀/헤더 DOM 요소 |
2218
2269
  | `errors?` | `string[]` | 유효성 검사 에러 메시지 (없으면 `undefined`). **셀 전용** |
2219
2270
  | `hasError?` | `boolean` | 에러 존재 여부 빠른 플래그. **셀 전용**(헤더엔 없음) |
@@ -2987,7 +3038,7 @@ interface SortState {
2987
3038
  /** 우선순위 (낮을수록 먼저 적용) */
2988
3039
  sequence: number;
2989
3040
  /** 피벗 전용: 값 필드 기준 정렬 (레이블 대신 집계 값 기준) */
2990
- byValue?: string;
3041
+ by?: string;
2991
3042
  /** 커스텀 정렬 키 함수 — 셀 값을 정렬 가능한 키로 변환 */
2992
3043
  sortKey?: (value: CellValue) => number | string;
2993
3044
  /**
@@ -3147,6 +3198,69 @@ await grid.filter([{
3147
3198
  | `conditionFiltersToFormula(filters)` | 조건식 배열 → 수식 문자열 (`ConditionFilterConversion`) |
3148
3199
  | `conditionFiltersToFormulaState(...)` | 조건식 배열 → `FormulaFilterState` |
3149
3200
 
3201
+ #### FilterGroupMap — 일반 행과 그룹 결과 필터
3202
+
3203
+ `grid.filter(map)`의 최상위 키는 **필터 UI 소유권**이다. 컬럼 ID가 아니다.
3204
+ `scope` 생략 또는 `'row'`는 일반 행 필터, `'group'`은 행 그룹 결과 필터다.
3205
+ 그룹 **조건식**의 `states[].id`는 그룹 기준 컬럼 ID이며, 각 조건이 자신의 `basis`를 지정한다.
3206
+ **수식**은 일반 필터처럼 `operator: 'formula'`와 `expression` 하나로 저장한다.
3207
+ wrapper는 수식의 `id`를 `'__formula__'`로 쓰며, 대상 그룹은 수식 안의 참조로 정한다.
3208
+
3209
+ ```typescript
3210
+ await grid.rowGroup.setConfig({
3211
+ columns: ['dept', 'team'],
3212
+ aggregates: [{ id: 'total', column: 'amount', func: 'sum' }],
3213
+ sorts: [{ id: 'dept', basis: 'aggregate', by: 'total', direction: 'desc' }],
3214
+ });
3215
+ await grid.filter({
3216
+ rowEditor: {
3217
+ type: 'conditional', priority: 0, applied: true,
3218
+ states: [{ id: 'amount', operator: 'gte', filterValue: 0, sequence: 0 }],
3219
+ },
3220
+ groupEditor: {
3221
+ scope: 'group', type: 'conditional', priority: 1, applied: true,
3222
+ states: [
3223
+ { id: 'dept', basis: 'aggregate', by: 'total', operator: 'gt', filterValue: 50, sequence: 0 },
3224
+ { id: 'team', basis: 'groupValue', operator: 'eq', filterValue: 'X', logical: 'and', sequence: 1 },
3225
+ ],
3226
+ },
3227
+ });
3228
+ ```
3229
+
3230
+ - `basis: 'groupValue'`: 해당 그룹의 원본 값. 표시 문자열이나 마스크 변환 결과가 아니다.
3231
+ - `basis: 'rowCount'`: 해당 그룹의 데이터 행 개수.
3232
+ - `basis: 'aggregate'`: 해당 레벨 집계의 공개 ID를 `by`로 정확히 참조한다.
3233
+ ID 문자열을 분해해 컬럼·함수를 추측하지 않는다.
3234
+ - 수식 참조는 `GROUP("id", "groupValue")`, `GROUP("id", "rowCount")`,
3235
+ `GROUP("id", "aggregate", "by")`다. 인자는 정확한 ID와 basis 문자열 리터럴이며 기본 레벨은 없다.
3236
+ 예: `{ id: '__formula__', operator: 'formula', expression: 'GROUP("dept", "aggregate", "total") > 50 AND GROUP("team", "groupValue") = "X"', sequence: 0 }`.
3237
+ 한 수식에서 같은 최하위 경로의 여러 레벨·집계·그룹 값·행 개수를 비교하거나 계산할 수 있다.
3238
+ `GROUP`은 그룹 수식 컨텍스트의 참조이며 일반 행 수식/조건부 서식의 함수가 아니다.
3239
+ 기존 `id: 'dept', expression: '$total > 50'` 로컬 집계 수식도 읽을 수 있다.
3240
+ - wrapper 고급 필터의 일반/그룹 탭은 동일한 textarea와 조건 트리 편집기를 공유한다.
3241
+ 그룹 자동완성은 `[현재 그룹 라벨 · 대상 라벨]`을 제안하며 저장 직전에 명시적인 `GROUP(...)` 참조로 변환한다.
3242
+ 트리에서 표현할 수 없는 계산식은 원문을 보존하고 수식 모드에서 편집한다.
3243
+ 기존 조건 목록은 열기만 해서는 재저장하지 않으며, 실제 편집 시 기존 좌결합을 보존한 수식 하나로 저장한다.
3244
+ - `sequence` 순서로 `logical`을 좌→우 결합한다. 묶음 간에는 AND를 적용한다.
3245
+ 부모와 자식 조건은 **같은 최하위 그룹 경로**에서 평가하므로 부모가 false여도 OR 자식 조건을 평가한다.
3246
+ - 일반 행 필터 후 **A 집계로 한 번 판정 → 생존 데이터로 B 재집계·정렬**한다.
3247
+ 예를 들어 부모 A 합계가 100이라 통과한 뒤 팀 필터로 B 합계가 10이 되어도 다시 탈락시키지 않는다.
3248
+ - `applied: false`는 저장하되 실행하지 않는다. 묶음의 대상 그룹 레벨 중 하나라도 없으면
3249
+ **묶음 전체**가 실행에서 제외되며 원본 상태는 유지된다. 활성 묶음의 잘못된 집계 참조·수식은 오류다.
3250
+ - `getFilterGroups()` 및 `getViewState().filterGroups`가 원본 맵을 반환한다.
3251
+ `getViewState().filters`는 실행 가능한 일반 행 필터의 평탄화 결과다.
3252
+ `getConfig()`/`applyConfig()`와 `getViewState()`/`setViewState()` 왕복은 소유 맵을 보존한다.
3253
+ - 피벗에서는 행 그룹 결과 필터를 실행하지 않고 보존한다. 서버 row-model도 상태만 보존하며
3254
+ 서버가 준 행을 로컬에서 탈락시키지 않는다.
3255
+ - Worker는 조건식·수식을 지원한다. 실행 대상 그룹의 함수형 `custom` predicate는 직렬화할 수 없어
3256
+ 명시적으로 거부한다. 비활성·대상 레벨 부재 묶음은 Worker 전송에서 제외하되 원본에서 삭제하지 않는다.
3257
+ - 집계 `id`는 선택적이며 생략 시 `getRowGroupAggregateId()`의 결정적 계산 alias를 사용한다.
3258
+ 같은 레벨에서 ID가 충돌하면 core는 거부한다. wrapper는 동일 컬럼·함수의 중복 추가·변경을 막으며,
3259
+ 같은 컬럼의 다른 함수 집계는 허용한다. 자동 접미사나 UUID를 붙이지 않는다.
3260
+
3261
+ 저장본 버전 `0.5`는 wrapper migrator에서 기존 그룹 정렬과 피벗 `byValue`를 새 정렬 구조로 변환한다.
3262
+ 새 그룹 필터 편집 UI는 제공하지 않으며, 위 core 설정으로 적용한다.
3263
+
3150
3264
  #### ChangesSummary
3151
3265
 
3152
3266
  `grid.changes.getAll()` 반환 타입:
@@ -3784,6 +3898,7 @@ interface GridConfigSnapshot {
3784
3898
  showDragHandleColumn?: boolean;
3785
3899
  autoFitColumns?: boolean;
3786
3900
  showStatusBar?: boolean;
3901
+ summaryRow?: 'none' | 'pinnedTop' | 'pinnedBottom';
3787
3902
  locale?: string;
3788
3903
  translations?: PartialTranslationMap;
3789
3904
  keyFields?: string[];
@@ -231,8 +231,13 @@ type MozGridCoreProps =
231
231
  | `useToolBox` | `boolean` | `true` | 툴박스 표시 |
232
232
  | `useToolBoxSetting` | `boolean` | `true` | 툴박스 설정(기어) 버튼 표시 |
233
233
  | `useExtendFooter` | `boolean` | `true` | 확장 푸터 표시 |
234
- | `useSummaryFooter` | `boolean` | `false` | 푸터 집계(요약) 표시 |
234
+ | `useSummaryFooter` | `boolean` | `false` | 플랫 컬럼 하단 집계 행. 켰을 때 `fields[].aggregate`가 있는 컬럼만 현재 필터 결과로 계산한다. OFF는 footer 전용 계산도 하지 않는다. 컬럼 옵션 → 집계에서 표시·함수 편집 가능 |
235
235
  | `useSort` | `boolean` | `true` | 정렬 기능 활성화 |
236
+ | `useRowGroupSettings` | `boolean` | `true` | 그룹 설정 변경 허용. `false`이면 보기 설정의 그룹 패널 토글을 비활성화하고 정보 아이콘에 안내 툴팁 표시. 컨텍스트 메뉴 진입점은 숨기고 그리드 설정의 그룹핑 탭은 읽기 전용. 기존 그룹·그룹별 집계 보존. 런타임 변경 지원 |
237
+ | `useFieldSettings` | `boolean` | `true` | 플랫 왼쪽 컬럼 목록의 표시·순서 변경 허용. false이면 피벗 필드 탭 본문 전체(검색·선택·드롭존·집계 편집)와 옵션 바 드래그를 차단. 옵션 바에는 별도 안내 표시 없이 정렬·필터·닫기는 유지. 고정·너비는 오른쪽 서식 영역에 속하므로 `useFormatSettings`로 제어. 런타임 변경 지원 |
238
+ | `useFormatSettings` | `boolean` | `true` | 헤더명·헤더/셀 서식·표시형식 변경 허용. 플랫·피벗 서식 영역에 적용. `false`이면 툴박스의 값 필드 설정 항목 전체를 비활성화하고 정보 아이콘·안내 툴팁 표시. 피벗에서는 서식 탭 본문 전체(왼쪽 목록·검색·선택·값 필드 설정 포함)를 단일 덮개로 차단. 기존 집계 결과·계산은 유지하며 레이아웃 탭은 `useLayoutSettings`로 별도 제어. 플랫에서 두 필드 권한 중 하나만 false이면 일부 설정 안내와 영역별 차단(검색·선택 유지), 둘 다 false이면 본문 전체 차단. 두 영역을 함께 바꾸는 컬럼 초기화는 둘 다 true일 때만 허용. 기존 설정·계산 보존, 런타임 변경 지원 |
239
+ | `useLayoutSettings` | `boolean` | `true` | 피벗 레이아웃(합계 표시·위치, 소계 기준, 0값 표시, 접기, 요약 모드) 변경 허용. `false`이면 레이아웃 탭은 안내·덮개로 본문 조작 차단, 툴박스 레이아웃 항목은 정보 아이콘·툴팁과 함께 비활성화. 기존 설정·계산 유지, 런타임 변경 지원. 플랫에는 영향 없음 |
240
+ | `useAggregateSettings` | `boolean` | `true` | 집계 탭의 함수·푸터 표시 설정 변경 허용. `false`여도 기존 집계·푸터 표시·계산 유지. 탭 진입은 유지하고 본문 검색·조작은 차단. 런타임 변경 지원 |
236
241
  | `useCustomCell` | `boolean` | `true` | 조건부 서식(커스텀 셀) 활성화 |
237
242
  | `useContextMenu` | `boolean` | `true` | 컨텍스트 메뉴 활성화 |
238
243
  | `useBuiltinTooltip` | `boolean` | `true` | 내장 셀/헤더 툴팁 렌더러 사용. `false`면 wrapper가 툴팁을 그리지 않음 — 코어 `cell:tooltip` 이벤트는 그대로 발행되므로 소비처가 `@ready`의 `grid.on('cell:tooltip', …)`로 직접 렌더 가능(발행은 `tooltipMode`로 제어) |
@@ -287,7 +292,6 @@ type MozGridCoreProps =
287
292
  |------|------|------|
288
293
  | `useViewSelectColumn` | `boolean?` | 컬럼 표시 선택 항목 토글 |
289
294
  | `useFixedColumn` | `boolean?` | 컬럼 고정 항목 토글 |
290
- | `useGroupColumn` | `boolean?` | 컬럼 그룹화 항목 토글 |
291
295
  | `useContextMenu` | `boolean?` | 컨텍스트 메뉴 마스터 토글(주: `WrapperUIOptions.useContextMenu`와 별개) |
292
296
  | `useSort` | `boolean?` | 정렬 항목 토글 |
293
297
  | `useFilter` | `boolean?` | 필터 항목 토글 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmscloud/moz-ui-grid-vue",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "MozGrid - Vue 3 wrapping library for @vmscloud/moz-ui-grid-core",
5
5
  "license": "ISC",
6
6
  "type": "module",
@@ -69,8 +69,8 @@
69
69
  "echarts": "^5.5.0",
70
70
  "es-toolkit": "^1.0.0",
71
71
  "lit-html": "^3.2.0",
72
- "@vmscloud/moz-ui-grid-core": "^0.1.42",
73
- "@vmscloud/moz-ui-grid-wrapper": "^0.1.13"
72
+ "@vmscloud/moz-ui-grid-core": "^0.1.43",
73
+ "@vmscloud/moz-ui-grid-wrapper": "^0.1.14"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "vue": ">=3.4.0",