@vmscloud/moz-ui-grid-vue 0.2.10 → 0.2.11

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.
@@ -15,18 +15,18 @@ export interface UseGridPresetOptions {
15
15
  /** 커스텀 셀 상태 조회 */
16
16
  getCustomCellState?: () => unknown;
17
17
  /** 커스텀 셀 상태 복원. `null` = 빈 상태로 초기화. */
18
- setCustomCellState?: (state: unknown) => void;
18
+ setCustomCellState?: (state: unknown) => void | Promise<void>;
19
19
  /** 컬럼 옵션 시각 서식(헤더/셀 bg·color·font·정렬·헤더라벨) 상태 조회 — wrapper ColumnFormatController. */
20
20
  getColumnFormatState?: () => unknown;
21
21
  /** 컬럼 옵션 시각 서식 상태 복원. `null` = 빈 상태로 초기화. */
22
- setColumnFormatState?: (state: unknown) => void;
22
+ setColumnFormatState?: (state: unknown) => void | Promise<void>;
23
23
  /** wrapper 보기 상태(툴바 펼침/푸터/그룹 패널/피벗 바) 조회 — `GridChrome.getPresetViewState`. */
24
24
  getViewOptionsState?: () => unknown;
25
25
  /** wrapper 보기 상태 복원. `null` 은 보기 상태에 빈 상태가 없으므로 무시해도 된다. */
26
- setViewOptionsState?: (state: unknown) => void;
26
+ setViewOptionsState?: (state: unknown) => void | Promise<void>;
27
27
  /**
28
- * Non-sensitive compatibility notices. 변환/적용 실패는 reject 하지 않고 `console.error` 로 알리며
29
- * 그리드 상태는 바꾸지 않는다(변환 실패는 적용 전에 거절).
28
+ * Non-sensitive compatibility notices. 변환/적용 실패는 결과의 failed로 전달하며
29
+ * console.error에도 기록한다. 변환 실패는 적용 전 거절되지만 extras 실패의 rollback은 보장하지 않는다.
30
30
  */
31
31
  onImportDiagnostics?: (diagnostics: readonly PresetDiagnostic[]) => void;
32
32
  }
@@ -1,8 +1,14 @@
1
1
  import { Ref } from 'vue';
2
+ export type UserLayoutApplyStatus = 'applied' | 'superseded' | 'disposed' | 'failed';
3
+ export interface UserLayoutApplyResult {
4
+ status: UserLayoutApplyStatus;
5
+ requestId: number;
6
+ error?: unknown;
7
+ }
2
8
  interface IUserLayout {
3
9
  id: string;
4
10
  type: string;
5
- importDef: (value: any) => void;
11
+ importDef: (value: any) => void | UserLayoutApplyResult | Promise<void | UserLayoutApplyResult>;
6
12
  exportDef: () => any;
7
13
  strict?: boolean;
8
14
  dependencies?: Ref<any>;
@@ -18,9 +24,22 @@ export declare class UserLayoutInstance {
18
24
  private _default;
19
25
  private _importDef;
20
26
  private _exportDef;
21
- private _pendingDef;
22
27
  private _pending;
23
- dispose: () => void;
28
+ private _disposed;
29
+ private _sequence;
30
+ private _active?;
31
+ private _queued?;
32
+ private _lastApplyResult?;
33
+ private _disposeCallback;
34
+ /** 요청 접수 당시 preset에 완료를 귀속하는 registry 내부 hook. */
35
+ captureApplied?: () => (value: boolean) => void;
36
+ get disposed(): boolean;
37
+ get applying(): boolean;
38
+ get lastApplyResult(): UserLayoutApplyResult | undefined;
39
+ get requestId(): number;
40
+ get dispose(): () => void;
41
+ set dispose(callback: () => void);
42
+ private disposeInstance;
24
43
  setApplied: (value: boolean) => void;
25
44
  strict: boolean;
26
45
  dependencies: Ref<any> | null;
@@ -32,6 +51,10 @@ export declare class UserLayoutInstance {
32
51
  set default(value: any);
33
52
  get current(): any;
34
53
  set current(value: any);
54
+ /** 취소는 import 자체를 중단하지 않으며, 겹친 import는 직렬 실행합니다. */
55
+ apply(value: any): Promise<UserLayoutApplyResult>;
56
+ private finish;
57
+ private drain;
35
58
  setDefaultToCurrent(): void;
36
59
  constructor({ id, type, exportDef, importDef, strict, dependencies, manualLifeCycle }: IUserLayout);
37
60
  }
package/dist/index.cjs CHANGED
@@ -1,28 +1,28 @@
1
- "use strict";var e=Object.defineProperty,t=(t,o,n)=>((t,o,n)=>o in t?e(t,o,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[o]=n)(t,"symbol"!=typeof o?o+"":o,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue"),n=require("@vmscloud/moz-ui-grid-wrapper"),l=require("./chunks/notification.contract-oFkBaE2U.cjs"),r=require("lit-html"),i=require("lit-html/directives/class-map.js"),s=require("./chunks/index-BLDAzbGv.cjs"),a=require("dayjs"),u=require("@vmscloud/moz-ui-grid-core");class d{constructor({id:e,type:n,exportDef:l,importDef:r,strict:i,dependencies:s,manualLifeCycle:a}){t(this,"uniqueId"),t(this,"_id"),t(this,"_type"),t(this,"_default"),t(this,"_importDef"),t(this,"_exportDef"),t(this,"_pendingDef"),t(this,"_pending"),t(this,"dispose",()=>{}),t(this,"setApplied",()=>{}),t(this,"strict"),t(this,"dependencies"),this.uniqueId="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),this._id=e,this._type=n,this._importDef=r,this._exportDef=l,this._default=l(),this._pending=!1,this._pendingDef=null,this.strict=i??!1,this.dependencies=s??null,a||o.onBeforeUnmount(()=>{this.dispose()})}get pending(){return this._pending}set pending(e){if(this._pending=e,!e&&this._pendingDef)try{this._importDef(this._pendingDef),this.setApplied(!0)}catch(t){}finally{this._pendingDef=null}}get id(){return this._id}get type(){return this._type}get default(){return this._default}set default(e){this._default=e}get current(){return this._exportDef()}set current(e){this.pending?this._pendingDef=e:(this._importDef(e),this.setApplied(!0))}setDefaultToCurrent(){this._default=this._exportDef()}}const c=()=>o.inject("user-layout-module",{register:()=>{},currentPreset:o.ref(null)});function p(e){if(!1===e.usePreset)return;const{register:t}=c(),l=(e,t)=>{void 0!==t&&(null==e||e(t))};let r=0,i=Promise.resolve();const s=new d({id:e.name.value,type:e.type,importDef:t=>{const o=++r,a=i.then(async()=>{if(o===r)try{await(async t=>{const o=e.gridInstance.value;if(!o)return;const r=s.default??null,i=n.migrateGridPreset(t??r,{grid:o,getSourceFields:e.getSourceFields,baseline:r});i.diagnostics.length&&e.onImportDiagnostics&&e.onImportDiagnostics(i.diagnostics),i.config&&await n.applyPresetCoreConfig(o,i.config,i.missing),l(e.setColumnFormatState,i.columnFormatConfig),l(e.setCustomCellState,i.customCellConfig),l(e.setViewOptionsState,i.viewOptionsConfig)})(t)}catch(i){}});return i=a,a},exportDef:()=>{var t,o;const l=e.gridInstance.value;if(!l)return null;const r={...n.stampPresetVersion(l.getConfig()),customCellConfig:(null==(t=e.getCustomCellState)?void 0:t.call(e))??null,columnFormatConfig:(null==(o=e.getColumnFormatState)?void 0:o.call(e))??null};return e.getViewOptionsState&&(r.viewOptionsConfig=e.getViewOptionsState()??null),r}});let a=!1;o.watch(e.gridInstance,n=>{if(!n||a)return;if(!e.name.value)return;const l=n.on("data:loaded",()=>{a||(s.setDefaultToCurrent(),o.nextTick(()=>{t(s),a=!0,l()}))})})}let m=null;function f(){if(m)return m;const e=o.ref(!1),t=o.shallowRef(null),n=o.ref({}),l={showPopup:e,activeGrid:t,defaultImportOptions:n,show:(o,l={})=>{t.value=o,n.value=l,e.value=!0},hide:()=>{e.value=!1}};return m=l,l}function g(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}function v(e){const t=null==e?"":String(e);return t.includes(",")||t.includes('"')||t.includes("\n")?`"${t.replace(/"/g,'""')}"`:t}const h={mode:"replace",conflictStrategy:"update",autoCommit:!1};function x(){const e=new Date,t=e=>String(e).padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}class y{constructor(e){t(this,"popup",null),t(this,"grid",null),t(this,"options",{...h}),t(this,"file",null),t(this,"invalid",!1),t(this,"dropActive",!1),t(this,"replacing",!1),this.deps=e}get isOpen(){var e;return(null==(e=this.popup)?void 0:e.isOpen)??!1}get state(){return{file:this.file,invalid:this.invalid,options:{...this.options}}}open(e,t={}){if(this.popup){this.replacing=!0;try{this.popup.close()}finally{this.replacing=!1}}this.grid=e,this.resetState(),this.options={...h},t.mode&&(this.options.mode=t.mode),t.conflictStrategy&&(this.options.conflictStrategy=t.conflictStrategy),"boolean"==typeof t.autoCommit&&(this.options.autoCommit=t.autoCommit);const o=s.getGridVueLocale(),l=new n.Popup({title:o.clientExcelImport,width:540,height:440,closeOnOutsideClick:!0,contentsPadding:"16px",className:"mzc-client-excel-popup",draggable:!0,resizeable:!1,onClose:()=>this.handleClosed(l)});this.popup=l,l.open(()=>this.body(),()=>this.footer())}close(){var e;null==(e=this.popup)||e.close()}destroy(){this.close()}handleClosed(e){this.popup===e&&(this.popup=null),this.resetState(),this.replacing||this.deps.onHidden()}resetState(){this.file=null,this.invalid=!1,this.dropActive=!1}update(){var e;null==(e=this.popup)||e.update()}setFile(e){e&&e.name.toLowerCase().endsWith(".xlsx")?(this.invalid=!1,this.file=e):(this.invalid=!0,this.file=null),this.update()}body(){const e=s.getGridVueLocale(),{mode:t,conflictStrategy:o}=this.options,l=this.file,a=[{value:"replace",label:e.importModeReplace},{value:"append",label:e.importModeAppend},{value:"upsert",label:e.importModeUpsert}],u=[{value:"error",label:e.conflictError},{value:"skip",label:e.conflictSkip},{value:"update",label:e.conflictUpdate}],d=e=>{var t,o;null==(o=null==(t=e.currentTarget.parentElement)?void 0:t.querySelector('input[type="file"]'))||o.click()},c=l?r.html`
2
- ${"replace"===t?r.html`<span class="mzc-client-excel-dropzone__line">${e.overwriteSelected}</span>`:r.nothing}
1
+ "use strict";var e=Object.defineProperty,t=(t,o,n)=>((t,o,n)=>o in t?e(t,o,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[o]=n)(t,"symbol"!=typeof o?o+"":o,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue"),n=require("@vmscloud/moz-ui-grid-wrapper"),l=require("./chunks/notification.contract-oFkBaE2U.cjs"),i=require("lit-html"),r=require("lit-html/directives/class-map.js"),s=require("./chunks/index-BLDAzbGv.cjs"),a=require("dayjs"),u=require("@vmscloud/moz-ui-grid-core");class d{constructor({id:e,type:n,exportDef:l,importDef:i,strict:r,dependencies:s,manualLifeCycle:a}){t(this,"uniqueId"),t(this,"_id"),t(this,"_type"),t(this,"_default"),t(this,"_importDef"),t(this,"_exportDef"),t(this,"_pending"),t(this,"_disposed",!1),t(this,"_sequence",0),t(this,"_active"),t(this,"_queued"),t(this,"_lastApplyResult"),t(this,"_disposeCallback",()=>{}),t(this,"captureApplied"),t(this,"disposeInstance",()=>{this._disposed||(this._disposed=!0,this._active&&this.finish(this._active,"disposed"),this._queued&&this.finish(this._queued,"disposed"),this._queued=void 0,this._disposeCallback())}),t(this,"setApplied",()=>{}),t(this,"strict"),t(this,"dependencies"),this.uniqueId="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),this._id=e,this._type=n,this._importDef=i,this._exportDef=l,this._default=l(),this._pending=!1,this.strict=r??!1,this.dependencies=s??null,a||o.onBeforeUnmount(()=>{this.dispose()})}get disposed(){return this._disposed}get applying(){return!!this._active||!!this._queued}get lastApplyResult(){return this._lastApplyResult}get requestId(){return this._sequence}get dispose(){return this.disposeInstance}set dispose(e){this._disposeCallback=e}get pending(){return this._pending}set pending(e){this._pending=e,this.drain()}get id(){return this._id}get type(){return this._type}get default(){return this._default}set default(e){this._default=e}get current(){return this._exportDef()}set current(e){this.apply(e)}apply(e){const t=++this._sequence;return this._active&&this.finish(this._active,"superseded"),this._queued&&this.finish(this._queued,"superseded"),this._queued=void 0,new Promise(o=>{var n;const l={requestId:t,value:e,resolve:o,settled:!1,applied:this.setApplied};if(this._disposed)this.finish(l,"disposed");else{try{l.applied=(null==(n=this.captureApplied)?void 0:n.call(this))??this.setApplied}catch(i){return void this.finish(l,"failed",i)}this._lastApplyResult=void 0,this._queued=l,this.drain()}})}finish(e,t,o){if(e.settled)return;e.settled=!0;const n={status:t,requestId:e.requestId};void 0!==o&&(n.error=o),e.requestId===this._sequence&&(this._lastApplyResult=n),e.resolve(n)}drain(){if(this._disposed||this._pending||this._active||!this._queued)return;const e=this._queued;this._queued=void 0,this._active=e;const t=(t,o,n=!1)=>{try{e.settled||(n?this.finish(e,"failed",o):t&&"object"==typeof t&&"status"in t&&"applied"!==t.status?this.finish(e,t.status,t.error):(e.applied(!0),this.finish(e,"applied")))}catch(l){this.finish(e,"failed",l)}finally{this._active=void 0,this.drain()}};try{const o=this._importDef(e.value);o&&"function"==typeof o.then?Promise.resolve(o).then(e=>t(e),e=>t(void 0,e,!0)):t(o)}catch(o){t(void 0,o,!0)}}setDefaultToCurrent(){this._default=this._exportDef()}}const c=()=>o.inject("user-layout-module",{register:()=>{},currentPreset:o.ref(null)});function p(e){if(!1===e.usePreset)return;const{register:t}=c(),l=(e,t)=>{if(void 0!==t)return null==e?void 0:e(t)},i=new d({id:e.name.value,type:e.type,importDef:async t=>{const o=i.requestId,r=e.gridInstance.value;if(await Promise.resolve(),i.disposed)return{status:"disposed",requestId:o};if(o!==i.requestId||e.gridInstance.value!==r)return{status:"superseded",requestId:o};if(!r)return{status:"failed",requestId:o,error:new Error("Grid preset: grid-not-ready")};try{return await(async(t,o,r)=>{const s=()=>i.disposed?{status:"disposed",requestId:r}:e.gridInstance.value!==o?{status:"superseded",requestId:r}:void 0,a=i.default??null,u=n.migrateGridPreset(t??a,{grid:o,getSourceFields:e.getSourceFields,baseline:a});u.diagnostics.length&&e.onImportDiagnostics&&e.onImportDiagnostics(u.diagnostics);const d=s();if(d)return d;u.config&&await n.applyPresetCoreConfig(o,u.config,u.missing);const c=[[e.setColumnFormatState,u.columnFormatConfig],[e.setCustomCellState,u.customCellConfig],[e.setViewOptionsState,u.viewOptionsConfig]];for(const[e,n]of c){const t=s();if(t)return t;await l(e,n)}return s()||(await o.waitForSettled(),s()??{status:"applied",requestId:r})})(t,r,o)}catch(s){return{status:"failed",requestId:o,error:s}}},exportDef:()=>{var t,o;const l=e.gridInstance.value;if(!l)return null;const i={...n.stampPresetVersion(l.getConfig()),customCellConfig:(null==(t=e.getCustomCellState)?void 0:t.call(e))??null,columnFormatConfig:(null==(o=e.getColumnFormatState)?void 0:o.call(e))??null};return e.getViewOptionsState&&(i.viewOptionsConfig=e.getViewOptionsState()??null),i}});let r=!1;o.watch(e.gridInstance,(n,l,s)=>{if(!n||r||i.disposed)return;if(!e.name.value)return;let a=!0,u=!1;const d=()=>a&&!i.disposed&&e.gridInstance.value===n,c=n.on("data:loaded",()=>{r||u||!d()||(u=!0,i.setDefaultToCurrent(),o.nextTick(async()=>{if(d()&&!r){r=!0,c();try{await t(i)}catch(e){}}}))});s(()=>{a=!1,c()})})}let m=null;function f(){if(m)return m;const e=o.ref(!1),t=o.shallowRef(null),n=o.ref({}),l={showPopup:e,activeGrid:t,defaultImportOptions:n,show:(o,l={})=>{t.value=o,n.value=l,e.value=!0},hide:()=>{e.value=!1}};return m=l,l}function g(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}function h(e){const t=null==e?"":String(e);return t.includes(",")||t.includes('"')||t.includes("\n")?`"${t.replace(/"/g,'""')}"`:t}const v={mode:"replace",conflictStrategy:"update",autoCommit:!1};function y(){const e=new Date,t=e=>String(e).padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}class x{constructor(e){t(this,"popup",null),t(this,"grid",null),t(this,"options",{...v}),t(this,"file",null),t(this,"invalid",!1),t(this,"dropActive",!1),t(this,"replacing",!1),this.deps=e}get isOpen(){var e;return(null==(e=this.popup)?void 0:e.isOpen)??!1}get state(){return{file:this.file,invalid:this.invalid,options:{...this.options}}}open(e,t={}){if(this.popup){this.replacing=!0;try{this.popup.close()}finally{this.replacing=!1}}this.grid=e,this.resetState(),this.options={...v},t.mode&&(this.options.mode=t.mode),t.conflictStrategy&&(this.options.conflictStrategy=t.conflictStrategy),"boolean"==typeof t.autoCommit&&(this.options.autoCommit=t.autoCommit);const o=s.getGridVueLocale(),l=new n.Popup({title:o.clientExcelImport,width:540,height:440,closeOnOutsideClick:!0,contentsPadding:"16px",className:"mzc-client-excel-popup",draggable:!0,resizeable:!1,onClose:()=>this.handleClosed(l)});this.popup=l,l.open(()=>this.body(),()=>this.footer())}close(){var e;null==(e=this.popup)||e.close()}destroy(){this.close()}handleClosed(e){this.popup===e&&(this.popup=null),this.resetState(),this.replacing||this.deps.onHidden()}resetState(){this.file=null,this.invalid=!1,this.dropActive=!1}update(){var e;null==(e=this.popup)||e.update()}setFile(e){e&&e.name.toLowerCase().endsWith(".xlsx")?(this.invalid=!1,this.file=e):(this.invalid=!0,this.file=null),this.update()}body(){const e=s.getGridVueLocale(),{mode:t,conflictStrategy:o}=this.options,l=this.file,a=[{value:"replace",label:e.importModeReplace},{value:"append",label:e.importModeAppend},{value:"upsert",label:e.importModeUpsert}],u=[{value:"error",label:e.conflictError},{value:"skip",label:e.conflictSkip},{value:"update",label:e.conflictUpdate}],d=e=>{var t,o;null==(o=null==(t=e.currentTarget.parentElement)?void 0:t.querySelector('input[type="file"]'))||o.click()},c=l?i.html`
2
+ ${"replace"===t?i.html`<span class="mzc-client-excel-dropzone__line">${e.overwriteSelected}</span>`:i.nothing}
3
3
  <span class="mzc-client-excel-dropzone__line"><span class="mzc-client-excel-dropzone__accent">${l.name}</span></span>
4
- `:r.html`
4
+ `:i.html`
5
5
  <span class="mzc-client-excel-dropzone__line">
6
6
  ${e.dropHerePrefix}<span class="mzc-client-excel-dropzone__accent">${e.click}</span>${e.dropHereMiddle}<span class="mzc-client-excel-dropzone__accent">${e.drag}</span>${e.dropHereSuffix}
7
7
  </span>
8
- `;return r.html`
8
+ `;return i.html`
9
9
  <div class="mzc-client-excel-body">
10
10
  <div class="mzc-client-excel-options">
11
11
  <div class="mzc-client-excel-option">
12
12
  <span class="mzc-client-excel-option__label">${e.importMode}</span>
13
13
  ${n.radio({variant:"borderless",value:t,options:a,ariaLabel:e.importMode,onChange:e=>{this.options.mode=e,this.update()}})}
14
14
  </div>
15
- ${"replace"!==t?r.html`
15
+ ${"replace"!==t?i.html`
16
16
  <div class="mzc-client-excel-option mzc-client-excel-option--grow">
17
17
  <span class="mzc-client-excel-option__label">${e.conflictStrategy}</span>
18
18
  ${n.select({value:o,options:u,width:"100%",ariaLabel:e.conflictStrategy,onChange:e=>{this.options.conflictStrategy=e,this.update()}})}
19
19
  </div>
20
- `:r.nothing}
20
+ `:i.nothing}
21
21
  </div>
22
22
 
23
23
  <input type="file" accept=".xlsx" class="mzc-client-excel-file" hidden @change=${e=>{var t;const o=e.target;this.setFile(null==(t=o.files)?void 0:t[0]),o.value=""}} />
24
24
  <div
25
- class=${i.classMap({"mzc-client-excel-dropzone":!0,"is-active":this.dropActive})}
25
+ class=${r.classMap({"mzc-client-excel-dropzone":!0,"is-active":this.dropActive})}
26
26
  role="button"
27
27
  tabindex="0"
28
28
  aria-label=${e.clientExcelImport}
@@ -32,7 +32,7 @@
32
32
  @click=${d}
33
33
  @keydown=${e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),d(e))}}
34
34
  >
35
- ${l?r.html`
35
+ ${l?i.html`
36
36
  <svg xmlns="http://www.w3.org/2000/svg" width="89" height="89" viewBox="0 0 89 89" fill="none" aria-hidden="true">
37
37
  <circle cx="44.1176" cy="44.1176" r="44.1176" fill="#E1E9FF" />
38
38
  <g transform="translate(29.5, 29.5)">
@@ -49,7 +49,7 @@
49
49
  </clipPath>
50
50
  </defs>
51
51
  </svg>
52
- `:r.html`
52
+ `:i.html`
53
53
  <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
54
54
  <path
55
55
  d="M50 94.1176C74.3655 94.1176 94.1176 74.3655 94.1176 50C94.1176 25.6345 74.3655 5.88232 50 5.88232C25.6345 5.88232 5.88235 25.6345 5.88235 50C5.88235 74.3655 25.6345 94.1176 50 94.1176Z"
@@ -68,10 +68,10 @@
68
68
  </defs>
69
69
  </svg>
70
70
  `}
71
- ${this.invalid?r.html`<span class="mzc-client-excel-dropzone__error">${e.excelInvalidExcel}</span>`:r.html`<span class="mzc-client-excel-dropzone__text">${c}</span>`}
71
+ ${this.invalid?i.html`<span class="mzc-client-excel-dropzone__error">${e.excelInvalidExcel}</span>`:i.html`<span class="mzc-client-excel-dropzone__text">${c}</span>`}
72
72
  </div>
73
73
  </div>
74
- `}footer(){const e=s.getGridVueLocale();return r.html`
74
+ `}footer(){const e=s.getGridVueLocale();return i.html`
75
75
  ${n.button({label:e.check,variant:"primary",disabled:!this.file,onClick:()=>this.confirm()})}
76
76
  ${n.button({label:e.cancel,onClick:()=>this.close()})}
77
- `}confirm(){const e=this.grid,t=this.file;if(!e||!t)return;const o={...this.options};this.close(),this.runBackgroundImport(e,t,o)}async runBackgroundImport(e,t,o){const n=s.getGridVueLocale(),l=this.deps.notificationStore(),r=g(),i=t.name,a=()=>null==l?void 0:l.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});l&&l.eventMessages.unshift({noti_type:"progress",header_key:n.clientExcelImportProgress,noti_datetime:x(),noti_sender_id:"",prop_value:{session_id:r,file_name:i,status:"in_progress",progress_per:0,operation_type:"upload",remain_time:-1}});try{const n=e.changes;(null==n?void 0:n.hasChanges)&&await n.discardAll(),await e.io.fromExcel(t,{mode:o.mode,conflictStrategy:o.conflictStrategy,autoCommit:o.autoCommit,onProgress:e=>{const t=a();if(!(null==t?void 0:t.prop_value))return;let o="number"==typeof e.percent?e.percent:void 0;void 0===o&&"number"==typeof e.rowsProcessed&&"number"==typeof e.totalRows&&e.totalRows>0&&(o=e.rowsProcessed/e.totalRows*100),"number"==typeof o&&(t.prop_value.progress_per=Math.min(99,Math.max(0,Math.floor(o))))}});const i=a();(null==i?void 0:i.prop_value)&&(i.prop_value.status="completed",i.prop_value.progress_per=100),l&&setTimeout(()=>{const e=l.eventMessages.findIndex(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});-1!==e&&l.eventMessages.splice(e,1)},2e3)}catch(u){const e=a();(null==e?void 0:e.prop_value)&&(e.prop_value.status="error",e.prop_value.error_message=u instanceof Error?u.message:String(u),e.prop_value.progress_per=0,e.prop_value.remain_time=-1)}}}const C={class:"mzc-client-excel-host",hidden:""},_=o.defineComponent({__name:"ClientExcelUploadPopup",setup(e,{expose:t}){const n=f(),r=l.useGridNotificationStore(),i=new y({notificationStore:()=>r,onHidden:()=>n.hide()});return o.watch(n.showPopup,e=>{if(e){const e=n.activeGrid.value;e&&i.open(e,n.defaultImportOptions.value)}else i.close()},{immediate:!0}),o.onBeforeUnmount(()=>i.destroy()),t({controller:i}),(e,t)=>(o.openBlock(),o.createElementBlock("span",C))}}),w=Symbol("MozGridConfig");function S(){const e=o.inject(w,o.computed(()=>({}))),t=o.inject(R,null);return o.computed(()=>({...e.value,locale:(null==t?void 0:t.value)??e.value.locale}))}function b(e){const t=S(),n=o.computed(()=>{const o=e(),n={locale:o.locale??t.value.locale,timeZone:o.timeZone??t.value.timeZone};return void 0!==n.timeZone&&new Intl.DateTimeFormat("en",{timeZone:n.timeZone}),n});o.provide(w,n),o.provide(R,o.computed(()=>n.value.locale))}const M=o.defineComponent({name:"MozGridConfigProvider",props:{config:{type:Object,default:()=>({})}},setup:(e,{slots:t})=>(b(()=>e.config),()=>{var e;return null==(e=t.default)?void 0:e.call(t)})}),R=Symbol("MozGridLocale");const E=o.defineComponent({name:"MozGridLocaleProvider",props:{locale:{type:String,default:void 0}},setup:(e,{slots:t})=>(b(()=>({locale:e.locale})),()=>{var e;return null==(e=t.default)?void 0:e.call(t)})});class B{constructor(){t(this,"instances",new Map),t(this,"appContext",null)}setAppContext(e){this.appContext=e}mount(e,t,n,l={}){const r=this.instances.get(e);if(r)return void Object.assign(r.props,l);const i=o.reactive({...l}),s=o.createApp({render:()=>o.h(n,i)});this.appContext&&(s._context.provides={...this.appContext.provides},s._context.components={...this.appContext.components},s._context.directives={...this.appContext.directives},s._context.config.globalProperties={...this.appContext.config.globalProperties}),this.instances.set(e,{app:s,props:i}),s.mount(t)}mountInstance(e,t,n){const l=o.reactive({...n}),r=o.createApp({render:()=>t(l)});return this.appContext&&(r._context.provides={...this.appContext.provides},r._context.components={...this.appContext.components},r._context.directives={...this.appContext.directives},r._context.config.globalProperties={...this.appContext.config.globalProperties}),r.mount(e),{update:e=>{Object.assign(l,e)},destroy:()=>{r.unmount()}}}updateProps(e,t){const o=this.instances.get(e);o&&Object.assign(o.props,t)}unmount(e){const t=this.instances.get(e);t&&(t.app.unmount(),this.instances.delete(e))}unmountByPrefix(e){for(const t of this.instances.keys())t.startsWith(e)&&this.unmount(t)}unmountAll(){for(const[,e]of this.instances)e.app.unmount();this.instances.clear()}get size(){return this.instances.size}has(e){return this.instances.has(e)}}function k(e,t,o){return e.map(e=>{const n={...e},l=t.get("cell",e.id);if(null==l?void 0:l.slot){const t=l.slot;n.cellRenderer=function(e,t,o){const n=e=>({value:e.value,rowData:e.rowData,columnId:e.columnId,rowId:e.rowId}),l=(e,l)=>{const r=o.mountInstance(e,e=>t(e),n(l));return{update:e=>(r.update(n(e)),!0),destroy(){r.destroy()}}};return l.__cellRendererKind="lifecycle",l}(e.id,t,o)}const r=t.get("header",e.id);if(null==r?void 0:r.slot){const t=r.slot;n.headerRenderer=function(e,t,o){return n=>{const l=document.createElement("div");l.style.display="contents";const r=`header:${e}`,i={columnId:n.columnId,header:n.header};return o.mount(r,l,{render:()=>t(i)},i),l}}(e.id,t,o)}const i=t.get("editor",e.id);if(null==i?void 0:i.slot){const t=i.slot;n.editor=function(e,t,o){return{type:"custom",renderer:n=>{const l=document.createElement("div");l.style.display="contents";const r=`editor:${e}`,i={value:n.value,rowData:n.rowData,columnId:e,onCommit:n.onCommit,onCancel:n.onCancel};return o.mount(r,l,{render:()=>t(i)},i),l},destroy:()=>{o.unmount(`editor:${e}`)}}}(e.id,t,o)}return n})}const P=Symbol("moz-grid-instance"),F=Symbol("moz-grid-container"),z=Symbol("moz-grid-renderer"),D=Symbol("moz-grid-template-registry"),T=Symbol("moz-grid-filter-module"),I=Symbol("moz-grid-sort-module"),G=Symbol("moz-grid-custom-cell-module"),$=Symbol("moz-grid-bulk-editor-module"),H=((e,t)=>{const o=e.__vccOpts||e;for(const[n,l]of t)o[n]=l;return o})(o.defineComponent({__name:"MozGrid",props:o.mergeModels({sourceRevision:{},height:{default:"100%"},contextMenuConfig:{},emptyState:{},locale:{},sourceFields:{},useMultipleChart:{type:Boolean},chartIncludeGrandTotal:{type:Boolean},chartMap:{},chartConfig:{},useRowGroupSettings:{type:Boolean,default:!0},useFieldSettings:{type:Boolean,default:!0},useFormatSettings:{type:Boolean,default:!0},useLayoutSettings:{type:Boolean,default:!0},useAggregateSettings:{type:Boolean,default:!0},useToolBox:{type:Boolean,default:!0},useToolBoxSetting:{type:Boolean,default:!0},useExtendFooter:{type:Boolean,default:!0},useSummaryFooter:{type:Boolean,default:!1},useSort:{type:Boolean,default:!0},useCustomCell:{type:Boolean,default:!0},useContextMenu:{type:Boolean,default:!0},usePivot:{type:Boolean},usePivotBar:{type:Boolean,default:!0},useChart:{type:Boolean},loading:{type:Boolean},useBuiltinTooltip:{type:Boolean,default:!0},toolbarConfig:{},name:{},usePreset:{type:Boolean,default:!0}},{coreConfig:{default:()=>({})},coreConfigModifiers:{}}),emits:o.mergeModels(["ready","data:loaded","data:changed","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","header:click","header:sortClick","header:filterClick","filter:changed","scroll","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","rowGroup:toggle","rowGroup:batchToggle","contextmenu"],["update:coreConfig"]),setup(e,{expose:t,emit:r}){const i=o.useModel(e,"coreConfig"),a=e,u=r,d=o.ref(),c=o.useSlots(),m=function(){const e=o.getCurrentInstance();if(!e)throw new Error("[MozGridVue] useAppContext는 setup() 내에서만 호출할 수 있습니다.");return e.appContext}(),g=new B,v=function(){const e=o.reactive([]);function t(e,t){return t?`${e}:${t}`:e}return{register(o){const n=e.findIndex(e=>t(e.type,e.fieldId)===t(o.type,o.fieldId));n>=0?e[n]=o:e.push(o)},unregister(o,n){const l=t(o,n),r=e.findIndex(e=>t(e.type,e.fieldId)===l);r>=0&&e.splice(r,1)},get(o,n){const l=t(o,n);return e.find(e=>t(e.type,e.fieldId)===l)},getAll:t=>e.filter(e=>e.type===t)}}(),h=o.shallowRef(null),x=f(),y=S(),C=o.computed(()=>a.locale??i.value.locale??y.value.locale),w=o.computed(()=>i.value.timeZone??y.value.timeZone);s.setGridVueLocale(C.value),o.watch(C,e=>s.setGridVueLocale(e));const b=o.ref();let M=null;const R=o.ref({disabled:!0,hasItem:!1}),E=l.useGridNotificationStore(),T=e=>String(e).padStart(2,"0"),I=()=>{const e=new Date;return`${e.getFullYear()}-${T(e.getMonth()+1)}-${T(e.getDate())} ${T(e.getHours())}:${T(e.getMinutes())}:${T(e.getSeconds())}`},G=()=>`mzc-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,$=e=>null==E?void 0:E.eventMessages.find(t=>{var o;return(null==(o=t.prop_value)?void 0:o.session_id)===e}),H=e=>{if(!E)return;const t=E.eventMessages.findIndex(t=>{var o;return(null==(o=t.prop_value)?void 0:o.session_id)===e});-1!==t&&E.eventMessages.splice(t,1)};let V=null;const L={onExportStart:e=>{E&&(V=G(),E.eventMessages.unshift({noti_type:"progress",header_key:"text-file_download",noti_datetime:I(),noti_sender_id:"",prop_value:{session_id:V,file_name:e,status:"in_progress",progress_per:0,operation_type:"download",remain_time:-1}}))},onExportProgress:e=>{if(!V)return;const t=$(V);if(!(null==t?void 0:t.prop_value))return;let o="number"==typeof e.percent?e.percent:void 0;void 0===o&&"number"==typeof e.rowsProcessed&&"number"==typeof e.totalRows&&e.totalRows>0&&(o=e.rowsProcessed/e.totalRows*100),"number"==typeof o&&(t.prop_value.progress_per=Math.min(99,Math.max(0,Math.floor(o))))},onExportComplete:e=>{if(!V)return;const t=V,o=$(t);(null==o?void 0:o.prop_value)&&((null==e?void 0:e.fileName)&&(o.prop_value.file_name=e.fileName),o.prop_value.status="completed",o.prop_value.progress_per=100),setTimeout(()=>H(t),2e3),V=null},onExportError:e=>{if(!V)return;const t=$(V);(null==t?void 0:t.prop_value)&&(t.prop_value.status="error",t.prop_value.error_message=e.message,t.prop_value.progress_per=0,t.prop_value.remain_time=-1),V=null},onExportCancel:()=>{V&&(H(V),V=null)},onImportComplete:()=>{if(!E)return;const e=G();E.eventMessages.unshift({noti_type:"progress",header_key:"text-file_upload",noti_datetime:I(),noti_sender_id:"",prop_value:{session_id:e,file_name:"",status:"completed",progress_per:100,operation_type:"upload",remain_time:-1}}),setTimeout(()=>H(e),2e3)},onImportError:e=>{E&&E.eventMessages.unshift({noti_type:"progress",header_key:"text-file_upload",noti_datetime:I(),noti_sender_id:"",prop_value:{session_id:G(),file_name:"",status:"error",error_message:e.message,progress_per:0,operation_type:"upload",remain_time:-1}})},onClientImportOpen:()=>{var e;if(!h.value)return;const t=(null==(e=a.contextMenuConfig)?void 0:e.clientImportOptions)??{};x.show(h.value,t)}};o.provide(D,v),o.provide(z,g),o.provide(P,h),o.provide(F,b);const O=o.computed(()=>{const e=a.height??"100%";return{height:"number"==typeof e?`${e}px`:e,width:"100%"}});function A(e){return(t,o)=>{const n={render:()=>{var t,n,l;return("tool-items"===e?null==(t=c[e])?void 0:t.call(c,R.value):"option-menu-items"===e?null==(n=c[e])?void 0:n.call(c,o.props):null==(l=c[e])?void 0:l.call(c))??null}},l=`slot:${e}`;return g.mount(l,t,n,{}),()=>g.unmount(l)}}let j,U;function Z(){const e={...i.value},t=function(){const e=i.value.fields;return e===j||(j=e,U=e?k(e,v,g):void 0),U}();return t&&(e.fields=t),void 0!==C.value&&(e.locale=C.value),e.timeZone=w.value,e}function N(){const e=["tool-left","tool-items","option-popup","tool-bottom","notification","footer","empty-state","option-menu-items"],t={};for(const o of e)c[o]&&(t[o]=A(o));return{useToolBox:a.useToolBox,useToolBoxSetting:a.useToolBoxSetting,useExtendFooter:a.useExtendFooter,useSummaryFooter:a.useSummaryFooter,useSort:a.useSort,useCustomCell:a.useCustomCell,useContextMenu:a.useContextMenu,useBuiltinTooltip:a.useBuiltinTooltip,usePivot:a.usePivot,usePivotBar:a.usePivotBar,useChart:a.useChart,useRowGroupSettings:a.useRowGroupSettings,useFieldSettings:a.useFieldSettings,useFormatSettings:a.useFormatSettings,useLayoutSettings:a.useLayoutSettings,useAggregateSettings:a.useAggregateSettings,toolbarConfig:a.toolbarConfig,useMultipleChart:a.useMultipleChart,chartIncludeGrandTotal:a.chartIncludeGrandTotal,chartMap:a.chartMap,chartConfig:a.chartConfig,loading:a.loading,locale:C.value,sourceFields:a.sourceFields,contextMenuConfig:a.contextMenuConfig,emptyState:a.emptyState,slots:t,onToolItemsPropsChange:e=>{R.value=e},excelHooks:L}}const Y=["data:changed","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","header:click","header:sortClick","header:filterClick","filter:changed","scroll","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","rowGroup:toggle","rowGroup:batchToggle","contextmenu"];let K=[];function q(){for(const e of K)try{e()}catch{}K=[]}const W=new WeakSet;function X(e){if(e&&"object"==typeof e){if(W.has(e))return;W.add(e)}}function J(e){if(!d.value)return null;g.setAppContext(m);const t=o.markRaw(new n.GridChrome(d.value,Z(),{...N(),sourceRevision:a.sourceRevision},e));o.markRaw(t.grid),M=t,h.value=t.grid,b.value=d.value;const l=u;t.on("data:loaded",()=>u("data:loaded"));for(const o of Y)t.on(o,e=>l(o,e));return K.push(t.onConfigChange(()=>{i.value=t.getCoreConfig(i.value),t.syncAppliedConfig(Z())})),t.ready().catch(X),t}let Q=null;const ee=new n.LatestSettingsCoordinator({waitUntilSettled:async(e,t)=>{(null==M?void 0:M.waitForReinitSettled)?await M.waitForReinitSettled(t,M.isSourceReplacement(e.config,e.sourceRevision)):await(null==M?void 0:M.ready())},apply:async(e,t)=>{if(!M)return;let o=M;const{reinitRequired:n,completion:l}=o.reconcileCoreConfig(e.config,e.sourceRevision);if(l&&await l,n){const n=o,l=n.captureReinitStateAsync?await n.captureReinitStateAsync(e.config,e.sourceRevision):o.captureReinitState(e.config,e.sourceRevision);if(!t.isCurrent()||M!==o)return;q(),o.destroy(),M=null,g.unmountAll();const r=J(l);if(!r)return;if(o=r,await o.ready(),M!==o)return;await o.restoreReinitState(l)}else await o.ready();t.isCurrent()&&M===o&&Q!==o&&(Q=o,R.value=o.getToolItemsProps(),u("ready",o.grid,o))},onError:X});function te(){ee.request({config:Z(),sourceRevision:a.sourceRevision})}o.onMounted(()=>{J(),te(),o.watch(()=>{const e=i.value;e.data,e.fields;const t={_locale:C.value,_timeZone:w.value,_sourceRevision:a.sourceRevision};for(const o in e)"data"!==o&&"fields"!==o&&(t[o]=e[o]);return t},()=>te(),{deep:!0}),o.watch(()=>{var e,t,o,n;return{useToolBox:a.useToolBox,useToolBoxSetting:a.useToolBoxSetting,useExtendFooter:a.useExtendFooter,useSummaryFooter:a.useSummaryFooter,useSort:a.useSort,useCustomCell:a.useCustomCell,useContextMenu:a.useContextMenu,useBuiltinTooltip:a.useBuiltinTooltip,usePivot:a.usePivot,usePivotBar:a.usePivotBar,useRowGroupSettings:a.useRowGroupSettings,useFieldSettings:a.useFieldSettings,useFormatSettings:a.useFormatSettings,useLayoutSettings:a.useLayoutSettings,useAggregateSettings:a.useAggregateSettings,toolbarConfig:{filter:{disabled:null==(t=null==(e=a.toolbarConfig)?void 0:e.filter)?void 0:t.disabled,hidden:null==(n=null==(o=a.toolbarConfig)?void 0:o.filter)?void 0:n.hidden}}}},e=>null==M?void 0:M.setUIOptions(e)),o.watch(()=>a.loading,e=>null==M?void 0:M.setUIOptions({loading:e}),{immediate:!0}),o.watch(()=>a.sourceFields,e=>null==M?void 0:M.setSourceFields(e),{immediate:!0}),o.watch(()=>a.contextMenuConfig,e=>null==M?void 0:M.setContextMenuConfig(e),{deep:!0}),o.watch(()=>a.chartConfig,e=>{var t;return null==(t=null==M?void 0:M.setChartConfig)?void 0:t.call(M,e)},{deep:!0})}),o.onBeforeUnmount(()=>{ee.destroy(),q(),null==M||M.destroy(),M=null,h.value=null,g.unmountAll()}),p({usePreset:a.usePreset,name:o.toRef(a,"name"),type:"pivot"===i.value.mode?"mozPivotGrid":"mozFlatGrid",gridInstance:h,getSourceFields:()=>{const e=i.value.fields??[],t=new Map(e.map(e=>[e.field??e.id,e.id]));return((null==M?void 0:M.pivot.sourceFields)??[]).map(e=>({id:t.get(e.field)??e.field,field:e.field,header:e.header,dataType:e.dataType}))},getCustomCellState:()=>(null==M?void 0:M.customCell.getCustomCell())??null,setCustomCellState:e=>{null==M||M.customCell.setCustomCell(e??null)},getColumnFormatState:()=>(null==M?void 0:M.columnFormat.getConfig())??null,setColumnFormatState:e=>{null==M||M.columnFormat.setConfig(e??null)},getViewOptionsState:()=>{var e;return(null==(e=null==M?void 0:M.getPresetViewState)?void 0:e.call(M))??null},setViewOptionsState:e=>{var t;null==(t=null==M?void 0:M.setPresetViewState)||t.call(M,e)}});return t(new Proxy({},{get(e,t){if("chrome"===t)return M;const o=M;if(!o)return;const n=o[t];return"function"==typeof n?n.bind(o):n},has:(e,t)=>"chrome"===t||!!M&&t in M})),(e,t)=>(o.openBlock(),o.createElementBlock(o.Fragment,null,[o.createElementVNode("div",{ref_key:"hostRef",ref:d,class:"moz-grid-chrome",style:o.normalizeStyle(O.value)},null,4),o.renderSlot(e.$slots,"default",{},void 0,!0),h.value?(o.openBlock(),o.createBlock(_,{key:0})):o.createCommentVNode("",!0)],64))}}),[["__scopeId","data-v-3e1ac7f7"]]),V=o.defineComponent({name:"CellTemplate",props:{field:{type:String,required:!0}},setup(e){const t=o.inject(D),n=o.useSlots();return t?(o.onMounted(()=>{n.default&&t.register({type:"cell",fieldId:e.field,slot:n.default})}),o.onBeforeUnmount(()=>{t.unregister("cell",e.field)}),()=>null):()=>null}}),L=o.defineComponent({name:"HeaderTemplate",props:{field:{type:String,required:!0}},setup(e){const t=o.inject(D),n=o.useSlots();return t?(o.onMounted(()=>{n.default&&t.register({type:"header",fieldId:e.field,slot:n.default})}),o.onBeforeUnmount(()=>{t.unregister("header",e.field)}),()=>null):()=>null}}),O=o.defineComponent({name:"CellEditor",props:{field:{type:String,required:!0}},setup(e){const t=o.inject(D),n=o.useSlots();return t?(o.onMounted(()=>{n.default&&t.register({type:"editor",fieldId:e.field,slot:n.default})}),o.onBeforeUnmount(()=>{t.unregister("editor",e.field)}),()=>null):()=>null}}),A=o.defineComponent({name:"DetailTemplate",props:{minHeight:{type:Number,default:100},maxHeight:{type:Number},singleExpand:{type:Boolean,default:!1},keepDetailRows:{type:Boolean,default:!0}},setup(e){const t=o.inject(P),n=o.inject(z),l=o.useSlots();return t&&n?(o.onMounted(()=>{const o=t.value;if(!o||!l.default)return;const r=l.default;o.masterDetail.setConfig({minHeight:e.minHeight,maxHeight:e.maxHeight,singleExpand:e.singleExpand,keepMasterDetailRows:e.keepDetailRows,renderer:(e,t,o)=>{const l=`detail:${o}`,i={parentData:t,dataIndex:o};return n.mount(l,e,{render:()=>r(i)},i),()=>{n.unmount(l)}}})}),o.onBeforeUnmount(()=>{null==n||n.unmountByPrefix("detail:")}),()=>null):()=>null}}),j=o.defineComponent({name:"GroupTemplate",setup(){const e=o.inject(P),t=o.inject(z),n=o.useSlots();if(!e||!t)return()=>null;const l=new Map,r=e=>{const t=l.get(e);t&&(l.delete(e),t.destroy())},i=e=>{null==e||e.formatRow.removeHandler("_groupTemplate");for(const t of[...l.keys()])r(t)};let s=null;return o.watch(e,e=>{e!==s&&(i(s),s=e??null,e&&(e=>{if(!n.default)return;const o=n.default;e.formatRow.addHandler("_groupTemplate",e=>{if("group-row"!==e.type)return;const n=e.ctx,i=n.element;if(!i)return;const s={groupKey:n.column,groupValue:n.value,level:n.level,count:n.itemCount,isExpanded:!n.collapsed},a=l.get(i);if(a&&i.classList.contains("ps-group-template-host"))return void a.update(s);a&&r(i);const u=t.mountInstance(i,e=>o(e),s);l.set(i,u),i.addEventListener("ps-group-template-dispose",()=>r(i),{once:!0})})})(e))},{immediate:!0}),o.onBeforeUnmount(()=>{i(s),s=null}),()=>null}});let U=!1;function Z(e){return e?(Object.prototype.hasOwnProperty.call(e,"formatHeaderRow")||Object.defineProperty(e,"formatHeaderRow",{configurable:!0,get:()=>(U||(U=!0),e.formatHeader)}),e):null}const N=o.defineComponent({__name:"MozGridVue",props:{name:{},useToolBox:{type:Boolean,default:!0},useToolBoxSetting:{type:Boolean,default:!0},useExtendFooter:{type:Boolean,default:!0},useSummaryFooter:{type:Boolean,default:!1},useSort:{type:Boolean,default:!0},useCustomCell:{type:Boolean,default:!0},contextMenuConfig:{default:()=>({})},useContextMenu:{type:Boolean,default:!0},loading:{type:Boolean},emptyState:{},fields:{},data:{},mode:{},pivotRowFields:{},pivotColumnFields:{},pivotValueFields:{},height:{default:"100%"},keyFields:{},theme:{},rowHeight:{},headerHeight:{},showHeader:{type:Boolean,default:!0},resizableColumns:{type:Boolean,default:!0},reorderableColumns:{type:Boolean,default:!0},showRowHeader:{type:[Boolean,Object]},rowHeader:{type:[Boolean,Object]},rowSelection:{},cellSelection:{default:()=>({mode:"range"})},cellSelectionImpliesRows:{type:Boolean},editable:{type:Boolean,default:!1},tooltipMode:{default:"overflow"},alternatingRows:{type:Boolean,default:!0},autoFitColumns:{type:Boolean},dynamicRowHeights:{type:Boolean,default:!1},reorderableRows:{type:Boolean,default:!1},locale:{},engine:{},useWorker:{type:Boolean},loader:{},preventKeyEdit:{type:Boolean,default:!0},showStatusBar:{type:Boolean},showDragHandleColumn:{type:Boolean},undoStack:{},formatRow:{},translations:{},rowStyle:{},headerStyle:{},rowHeightChangeThreshold:{},group:{},columnGroups:{},rowTemplate:{}},emits:["ready","data:loaded","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","filter:changed","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","scroll","contextmenu"],setup(e,{expose:t,emit:l}){const r=e,i=l,s=o.computed(()=>{const e={...r};for(const t of n.WRAPPER_EXTRA_KEYS)delete e[t];return delete e.name,delete e.locale,e}),a=o.computed(()=>{const e=r,t={};for(const o of n.WRAPPER_EXTRA_KEYS)void 0!==e[o]&&(t[o]=e[o]);return void 0!==e.locale&&(t.locale=e.locale),t}),u=Object.fromEntries(["ready","data:loaded","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","filter:changed","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","scroll","contextmenu"].map(e=>[e,(...t)=>i(e,...t)]));u.ready=e=>i("ready",Z(e));const d=o.ref(null);function c(){return d.value??null}const p={};return Object.defineProperties(p,{grid:{enumerable:!0,get:()=>{var e;return Z(null==(e=c())?void 0:e.grid)}},core:{enumerable:!0,get:()=>p},filterModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.filter}},sortModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.sort}},customCellModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.customCell}},bulkEditorModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.bulkEditor}}}),p.refresh=async()=>{var e,t;return null==(t=null==(e=c())?void 0:e.grid)?void 0:t.refresh()},p.loadData=async e=>{var t,o;return null==(o=null==(t=c())?void 0:t.grid)?void 0:o.loadData(e)},p.sort=async e=>{var t,o;return null==(o=null==(t=c())?void 0:t.grid)?void 0:o.sort(e)},p.filter=async e=>{var t,o;return null==(o=null==(t=c())?void 0:t.grid)?void 0:o.filter(e)},t(p),(e,t)=>(o.openBlock(),o.createBlock(H,o.mergeProps({ref_key:"mozRef",ref:d,coreConfig:s.value},a.value,{name:r.name},o.toHandlers(o.unref(u))),o.createSlots({default:o.withCtx(()=>[o.renderSlot(e.$slots,"default")]),_:2},[e.$slots["tool-left"]?{name:"tool-left",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"tool-left")]),key:"0"}:void 0,e.$slots["tool-items"]?{name:"tool-items",fn:o.withCtx(t=>[o.renderSlot(e.$slots,"tool-items",o.normalizeProps(o.guardReactiveProps(t)))]),key:"1"}:void 0,e.$slots.notification?{name:"notification",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"notification")]),key:"2"}:void 0,e.$slots.footer?{name:"footer",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"footer")]),key:"3"}:void 0,e.$slots.customState?{name:"empty-state",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"customState")]),key:"4"}:void 0]),1040,["coreConfig","name"]))}}),Y=o.defineComponent({__name:"MozPivotVue",props:{name:{},data:{},rowFields:{},columnFields:{},valueFields:{},height:{default:"100%"},showRowSubTotals:{type:Boolean,default:!1},showRowGrandTotals:{type:Boolean,default:!0},showColumnSubTotals:{type:Boolean,default:!1},showColumnGrandTotals:{type:Boolean,default:!0},trackSourceRows:{type:Boolean,default:!1},showHeader:{type:Boolean,default:!0},alternatingRows:{type:Boolean,default:!1},tooltipMode:{default:"overflow"},rowSelection:{},cellSelection:{default:()=>({mode:"range"})},cellSelectionImpliesRows:{type:Boolean},useToolBox:{type:Boolean,default:!0},useToolBoxSetting:{type:Boolean,default:!0},useFilter:{type:Boolean,default:!0},useSort:{type:Boolean,default:!0},useCustomCell:{type:Boolean,default:!0},useExtendFooter:{type:Boolean,default:!0},useSummaryFooter:{type:Boolean,default:!1},useContextMenu:{type:Boolean,default:!0},contextMenuConfig:{},useChart:{type:Boolean,default:!1},fields:{},availableFields:{},useMultipleChart:{type:Boolean,default:!0},chartIncludeGrandTotal:{type:Boolean,default:!1},chartMap:{},loading:{type:Boolean},emptyState:{}},emits:["ready","data:loaded","filter:changed","pivot:configured","pivot:toggled","update:rowFields","update:columnFields","update:valueFields"],setup(e,{expose:t,emit:l}){const r=e,i=l,s=o.computed(()=>{const e={...r};for(const t of n.WRAPPER_EXTRA_KEYS)delete e[t];return delete e.name,delete e.locale,delete e.availableFields,delete e.useFilter,e.mode="pivot",e}),a=o.computed(()=>{const e=r,t={};for(const o of n.WRAPPER_EXTRA_KEYS)void 0!==e[o]&&(t[o]=e[o]);return void 0!==e.locale&&(t.locale=e.locale),t.sourceFields=e.sourceFields??e.availableFields??e.fields,t}),u=Object.fromEntries(["ready","data:loaded","filter:changed","pivot:toggled"].map(e=>[e,(...t)=>i(e,...t)]));function d(e){var t,o,n;const l=e;i("update:rowFields",l.rowFields??[]),i("update:columnFields",l.columnFields??[]),i("update:valueFields",l.valueFields??[]);const r=null==(n=null==(o=null==(t=p())?void 0:t.pivot)?void 0:o.getRawConfig)?void 0:n.call(o);r&&i("pivot:configured",r)}u.ready=e=>i("ready",Z(e));const c=o.ref(null);function p(){return c.value??null}function m(){var e,t;return null==(t=null==(e=p())?void 0:e.grid)?void 0:t.pivot}const f=o.computed({get:()=>{var e,t;return(null==(t=null==(e=p())?void 0:e.chart)?void 0:t.visible)??!1},set:e=>{var t,o;return null==(o=null==(t=p())?void 0:t.chart)?void 0:o.setVisible(e)}}),g={};return Object.defineProperties(g,{grid:{enumerable:!0,get:()=>{var e;return Z(null==(e=p())?void 0:e.grid)}},core:{enumerable:!0,get:()=>g},pivotApi:{enumerable:!0,get:()=>m()??null},filterModule:{enumerable:!0,get:()=>{var e;return null==(e=p())?void 0:e.filter}},sortModule:{enumerable:!0,get:()=>{var e;return null==(e=p())?void 0:e.sort}},customCellModule:{enumerable:!0,get:()=>{var e;return null==(e=p())?void 0:e.customCell}},showChart:{enumerable:!0,get:()=>f.value,set:e=>{f.value=e}}}),g.refresh=async()=>{var e,t;return null==(t=null==(e=p())?void 0:e.grid)?void 0:t.refresh()},g.setConfig=async e=>{var t;return null==(t=m())?void 0:t.setConfig(e)},g.getResult=()=>{var e;return(null==(e=m())?void 0:e.getResult())??null},g.expandAll=async()=>{var e;return null==(e=m())?void 0:e.expandAllRows()},g.collapseAll=async()=>{var e;return null==(e=m())?void 0:e.collapseAllRows()},g.expandToLevel=async e=>{var t;return null==(t=m())?void 0:t.expandRowToLevel(e)},g.toggleChart=()=>{f.value=!f.value},t(g),(e,t)=>(o.openBlock(),o.createBlock(H,o.mergeProps({ref_key:"mozRef",ref:c,coreConfig:s.value},a.value,{name:r.name,"onUpdate:coreConfig":d},o.toHandlers(o.unref(u))),o.createSlots({default:o.withCtx(()=>[o.renderSlot(e.$slots,"default")]),_:2},[e.$slots["tool-left"]?{name:"tool-left",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"tool-left")]),key:"0"}:void 0,e.$slots["tool-items"]?{name:"tool-items",fn:o.withCtx(t=>[o.renderSlot(e.$slots,"tool-items",o.normalizeProps(o.guardReactiveProps(t)))]),key:"1"}:void 0,e.$slots.footer?{name:"footer",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"footer")]),key:"2"}:void 0,e.$slots.customState?{name:"empty-state",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"customState")]),key:"3"}:void 0]),1040,["coreConfig","name"]))}});exports.GridNotificationKey=l.GridNotificationKey,exports.provideGridNotification=l.provideGridNotification,exports.useGridNotificationStore=l.useGridNotificationStore,exports.ExcelDataType=s.DataType,exports.FileParameter=s.FileParameter,exports.enUS=s.enUS,exports.getGridVueLocale=s.getGridVueLocale,exports.getGridVueLocaleCode=s.getGridVueLocaleCode,exports.jaJP=s.jaJP,exports.koKR=s.koKR,exports.normalizeGridVueLocale=s.normalizeGridVueLocale,exports.openToast=s.openToast,exports.setGridVueLocale=s.setGridVueLocale,exports.showMessage=s.showMessage,exports.useExcelDownloadStore=s.useExcelDownloadStore,exports.useExcelStore=s.useExcelStore,exports.useExcelUploadStore=s.useExcelUploadStore,exports.zhCN=s.zhCN,Object.defineProperty(exports,"ROW_HEADER_COLUMN_ID",{enumerable:!0,get:()=>u.ROW_HEADER_COLUMN_ID}),Object.defineProperty(exports,"UndoStack",{enumerable:!0,get:()=>u.UndoStack}),Object.defineProperty(exports,"getCornerCell",{enumerable:!0,get:()=>u.getCornerCell}),Object.defineProperty(exports,"getRowHeaderCell",{enumerable:!0,get:()=>u.getRowHeaderCell}),exports.CellEditor=O,exports.CellTemplate=V,exports.ClientExcelUploadController=y,exports.ClientExcelUploadPopup=_,exports.DetailTemplate=A,exports.GRID_BULK_EDITOR_MODULE_KEY=$,exports.GRID_CUSTOM_CELL_MODULE_KEY=G,exports.GRID_FILTER_MODULE_KEY=T,exports.GRID_INSTANCE_KEY=P,exports.GRID_RENDERER_KEY=z,exports.GRID_SORT_MODULE_KEY=I,exports.GRID_TEMPLATE_REGISTRY_KEY=D,exports.GroupTemplate=j,exports.HeaderTemplate=L,exports.MOZ_GRID_CONFIG_KEY=w,exports.MOZ_GRID_LOCALE_KEY=R,exports.MozGrid=H,exports.MozGridConfigProvider=M,exports.MozGridLocaleProvider=E,exports.MozGridVue=N,exports.MozPivotVue=Y,exports.StreamingParameter=class{constructor(e){t(this,"params"),t(this,"loading",!0),t(this,"size",0),t(this,"offset",0),t(this,"onReceived"),t(this,"onClosed"),t(this,"onHandleError"),t(this,"onCancelClick"),t(this,"_complete",!1),this.params=e}get ipcObject(){return this.params}get percent(){return 0===this.offset||0===this.size?0:Math.round(this.offset/this.size*100)}get complete(){return this._complete}received(e){this.offset++,this.onReceived&&this.onReceived(e)}closed(e=!0){this._complete=e,this.onClosed&&this.onClosed()}handleError(e,t=!0){this._complete=t,this.onHandleError&&this.onHandleError(e)}},exports.UserLayoutInstance=d,exports.VueRenderer=B,exports.downloadBlob=function(e,t){const o=URL.createObjectURL(e),n=document.createElement("a");n.href=o,n.download=t,n.style.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n),setTimeout(()=>URL.revokeObjectURL(o),0)},exports.exportCsv=async function(e){let t,o;if("pivot"===e.pivot.getMode()){const n=await e.pivot.getDataMatrix();if(!n)return;t=n.headers,o=n.rows}else{const n=await e.getExportData({scope:"all"});if(!n)return;const{headers:l,rows:r}=n,i=l.map(e=>e.id);t=l.map(e=>e.header),o=r.map(e=>i.map(t=>e[t]))}const n=[];n.push(t.map(v).join(","));for(const a of o)n.push(a.map(v).join(","));const l="\ufeff"+n.join("\r\n"),r=new Blob([l],{type:"text/csv;charset=utf-8;"}),i=URL.createObjectURL(r),s=document.createElement("a");s.href=i,s.download=`export_${(new Date).toISOString().slice(0,10)}.csv`,s.click(),URL.revokeObjectURL(i)},exports.generateSessionId=g,exports.pickFile=function(e=".xlsx"){return new Promise(t=>{const o=document.createElement("input");o.type="file",o.accept=e,o.style.display="none";let n=!1;const l=()=>{o.parentNode&&o.parentNode.removeChild(o)};o.onchange=()=>{if(n)return;n=!0;const e=o.files&&o.files.length>0?o.files[0]:null;l(),t(e)};const r=()=>{window.removeEventListener("focus",r),setTimeout(()=>{n||(n=!0,l(),t(null))},300)};window.addEventListener("focus",r),document.body.appendChild(o),o.click()})},exports.runClientExport=async function(e,t,o){var n;const l=`${t.exportFileName??"export"}_${a().format("YYYYMMDD")}.xlsx`,r=g();o&&o.eventMessages.unshift({noti_type:"progress",header_key:"text-file_download",noti_datetime:a().format("YYYY-MM-DD HH:mm:ss"),noti_sender_id:"",prop_value:{session_id:r,file_name:l,status:"in_progress",progress_per:0,operation_type:"download",remain_time:-1}});try{if(await e.io.saveExcelToFile({scope:"all",includeHeaders:!0,suggestedName:l,fallbackToDownload:!0,sheetSplit:"auto",includePinnedRows:!0,onProgress:e=>{if(!o)return;const t=o.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});if(!(null==t?void 0:t.prop_value))return;let n="number"==typeof e.percent?e.percent:void 0;void 0===n&&"number"==typeof e.rowsProcessed&&"number"==typeof e.totalRows&&e.totalRows>0&&(n=e.rowsProcessed/e.totalRows*100),"number"==typeof n&&(t.prop_value.progress_per=Math.min(99,Math.max(0,Math.floor(n))))},...t.clientExportOptions??{}}),o){const e=o.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});(null==e?void 0:e.prop_value)&&(e.prop_value.status="completed",e.prop_value.progress_per=100),setTimeout(()=>{const e=o.eventMessages.findIndex(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});-1!==e&&o.eventMessages.splice(e,1)},2e3)}null==(n=t.onClientExportComplete)||n.call(t,new Blob)}catch(i){if(i instanceof DOMException&&"AbortError"===i.name){if(o){const e=o.eventMessages.findIndex(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});-1!==e&&o.eventMessages.splice(e,1)}return}if(o){const e=o.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===r});(null==e?void 0:e.prop_value)&&(e.prop_value.status="error",e.prop_value.error_message=i instanceof Error?i.message:String(i),e.prop_value.progress_per=0,e.prop_value.remain_time=-1)}}},exports.useClientExcelStore=f,exports.useMozGridConfig=S,exports.useMozGridLocale=function(){const e=o.inject(R,null);return e||o.computed(()=>{})},exports.useUserLayoutModule=c;
77
+ `}confirm(){const e=this.grid,t=this.file;if(!e||!t)return;const o={...this.options};this.close(),this.runBackgroundImport(e,t,o)}async runBackgroundImport(e,t,o){const n=s.getGridVueLocale(),l=this.deps.notificationStore(),i=g(),r=t.name,a=()=>null==l?void 0:l.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});l&&l.eventMessages.unshift({noti_type:"progress",header_key:n.clientExcelImportProgress,noti_datetime:y(),noti_sender_id:"",prop_value:{session_id:i,file_name:r,status:"in_progress",progress_per:0,operation_type:"upload",remain_time:-1}});try{const n=e.changes;(null==n?void 0:n.hasChanges)&&await n.discardAll(),await e.io.fromExcel(t,{mode:o.mode,conflictStrategy:o.conflictStrategy,autoCommit:o.autoCommit,onProgress:e=>{const t=a();if(!(null==t?void 0:t.prop_value))return;let o="number"==typeof e.percent?e.percent:void 0;void 0===o&&"number"==typeof e.rowsProcessed&&"number"==typeof e.totalRows&&e.totalRows>0&&(o=e.rowsProcessed/e.totalRows*100),"number"==typeof o&&(t.prop_value.progress_per=Math.min(99,Math.max(0,Math.floor(o))))}});const r=a();(null==r?void 0:r.prop_value)&&(r.prop_value.status="completed",r.prop_value.progress_per=100),l&&setTimeout(()=>{const e=l.eventMessages.findIndex(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});-1!==e&&l.eventMessages.splice(e,1)},2e3)}catch(u){const e=a();(null==e?void 0:e.prop_value)&&(e.prop_value.status="error",e.prop_value.error_message=u instanceof Error?u.message:String(u),e.prop_value.progress_per=0,e.prop_value.remain_time=-1)}}}const _={class:"mzc-client-excel-host",hidden:""},C=o.defineComponent({__name:"ClientExcelUploadPopup",setup(e,{expose:t}){const n=f(),i=l.useGridNotificationStore(),r=new x({notificationStore:()=>i,onHidden:()=>n.hide()});return o.watch(n.showPopup,e=>{if(e){const e=n.activeGrid.value;e&&r.open(e,n.defaultImportOptions.value)}else r.close()},{immediate:!0}),o.onBeforeUnmount(()=>r.destroy()),t({controller:r}),(e,t)=>(o.openBlock(),o.createElementBlock("span",_))}}),w=Symbol("MozGridConfig");function S(){const e=o.inject(w,o.computed(()=>({}))),t=o.inject(R,null);return o.computed(()=>({...e.value,locale:(null==t?void 0:t.value)??e.value.locale}))}function b(e){const t=S(),n=o.computed(()=>{const o=e(),n={locale:o.locale??t.value.locale,timeZone:o.timeZone??t.value.timeZone};return void 0!==n.timeZone&&new Intl.DateTimeFormat("en",{timeZone:n.timeZone}),n});o.provide(w,n),o.provide(R,o.computed(()=>n.value.locale))}const M=o.defineComponent({name:"MozGridConfigProvider",props:{config:{type:Object,default:()=>({})}},setup:(e,{slots:t})=>(b(()=>e.config),()=>{var e;return null==(e=t.default)?void 0:e.call(t)})}),R=Symbol("MozGridLocale");const E=o.defineComponent({name:"MozGridLocaleProvider",props:{locale:{type:String,default:void 0}},setup:(e,{slots:t})=>(b(()=>({locale:e.locale})),()=>{var e;return null==(e=t.default)?void 0:e.call(t)})});class B{constructor(){t(this,"instances",new Map),t(this,"appContext",null)}setAppContext(e){this.appContext=e}mount(e,t,n,l={}){const i=this.instances.get(e);if(i)return void Object.assign(i.props,l);const r=o.reactive({...l}),s=o.createApp({render:()=>o.h(n,r)});this.appContext&&(s._context.provides={...this.appContext.provides},s._context.components={...this.appContext.components},s._context.directives={...this.appContext.directives},s._context.config.globalProperties={...this.appContext.config.globalProperties}),this.instances.set(e,{app:s,props:r}),s.mount(t)}mountInstance(e,t,n){const l=o.reactive({...n}),i=o.createApp({render:()=>t(l)});return this.appContext&&(i._context.provides={...this.appContext.provides},i._context.components={...this.appContext.components},i._context.directives={...this.appContext.directives},i._context.config.globalProperties={...this.appContext.config.globalProperties}),i.mount(e),{update:e=>{Object.assign(l,e)},destroy:()=>{i.unmount()}}}updateProps(e,t){const o=this.instances.get(e);o&&Object.assign(o.props,t)}unmount(e){const t=this.instances.get(e);t&&(t.app.unmount(),this.instances.delete(e))}unmountByPrefix(e){for(const t of this.instances.keys())t.startsWith(e)&&this.unmount(t)}unmountAll(){for(const[,e]of this.instances)e.app.unmount();this.instances.clear()}get size(){return this.instances.size}has(e){return this.instances.has(e)}}function k(e,t,o){return e.map(e=>{const n={...e},l=t.get("cell",e.id);if(null==l?void 0:l.slot){const t=l.slot;n.cellRenderer=function(e,t,o){const n=e=>({value:e.value,rowData:e.rowData,columnId:e.columnId,rowId:e.rowId}),l=(e,l)=>{const i=o.mountInstance(e,e=>t(e),n(l));return{update:e=>(i.update(n(e)),!0),destroy(){i.destroy()}}};return l.__cellRendererKind="lifecycle",l}(e.id,t,o)}const i=t.get("header",e.id);if(null==i?void 0:i.slot){const t=i.slot;n.headerRenderer=function(e,t,o){return n=>{const l=document.createElement("div");l.style.display="contents";const i=`header:${e}`,r={columnId:n.columnId,header:n.header};return o.mount(i,l,{render:()=>t(r)},r),l}}(e.id,t,o)}const r=t.get("editor",e.id);if(null==r?void 0:r.slot){const t=r.slot;n.editor=function(e,t,o){return{type:"custom",renderer:n=>{const l=document.createElement("div");l.style.display="contents";const i=`editor:${e}`,r={value:n.value,rowData:n.rowData,columnId:e,onCommit:n.onCommit,onCancel:n.onCancel};return o.mount(i,l,{render:()=>t(r)},r),l},destroy:()=>{o.unmount(`editor:${e}`)}}}(e.id,t,o)}return n})}const I=Symbol("moz-grid-instance"),P=Symbol("moz-grid-container"),F=Symbol("moz-grid-renderer"),z=Symbol("moz-grid-template-registry"),T=Symbol("moz-grid-filter-module"),G=Symbol("moz-grid-sort-module"),$=Symbol("moz-grid-custom-cell-module"),D=Symbol("moz-grid-bulk-editor-module"),H=((e,t)=>{const o=e.__vccOpts||e;for(const[n,l]of t)o[n]=l;return o})(o.defineComponent({__name:"MozGrid",props:o.mergeModels({sourceRevision:{},height:{default:"100%"},contextMenuConfig:{},emptyState:{},locale:{},sourceFields:{},useMultipleChart:{type:Boolean},chartIncludeGrandTotal:{type:Boolean},chartMap:{},chartConfig:{},useRowGroupSettings:{type:Boolean,default:!0},useFieldSettings:{type:Boolean,default:!0},useFormatSettings:{type:Boolean,default:!0},useLayoutSettings:{type:Boolean,default:!0},useAggregateSettings:{type:Boolean,default:!0},useToolBox:{type:Boolean,default:!0},useToolBoxSetting:{type:Boolean,default:!0},useExtendFooter:{type:Boolean,default:!0},useSummaryFooter:{type:Boolean,default:!1},useSort:{type:Boolean,default:!0},useCustomCell:{type:Boolean,default:!0},useContextMenu:{type:Boolean,default:!0},usePivot:{type:Boolean},usePivotBar:{type:Boolean,default:!0},useChart:{type:Boolean},loading:{type:Boolean},useBuiltinTooltip:{type:Boolean,default:!0},toolbarConfig:{},name:{},usePreset:{type:Boolean,default:!0}},{coreConfig:{default:()=>({})},coreConfigModifiers:{}}),emits:o.mergeModels(["ready","data:loaded","data:changed","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","header:click","header:sortClick","header:filterClick","filter:changed","scroll","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","rowGroup:toggle","rowGroup:batchToggle","contextmenu"],["update:coreConfig"]),setup(e,{expose:t,emit:i}){const r=o.useModel(e,"coreConfig"),a=e,u=i,d=o.ref(),c=o.useSlots(),m=function(){const e=o.getCurrentInstance();if(!e)throw new Error("[MozGridVue] useAppContext는 setup() 내에서만 호출할 수 있습니다.");return e.appContext}(),g=new B,h=function(){const e=o.reactive([]);function t(e,t){return t?`${e}:${t}`:e}return{register(o){const n=e.findIndex(e=>t(e.type,e.fieldId)===t(o.type,o.fieldId));n>=0?e[n]=o:e.push(o)},unregister(o,n){const l=t(o,n),i=e.findIndex(e=>t(e.type,e.fieldId)===l);i>=0&&e.splice(i,1)},get(o,n){const l=t(o,n);return e.find(e=>t(e.type,e.fieldId)===l)},getAll:t=>e.filter(e=>e.type===t)}}(),v=o.shallowRef(null),y=f(),x=S(),_=o.computed(()=>a.locale??r.value.locale??x.value.locale),w=o.computed(()=>r.value.timeZone??x.value.timeZone);s.setGridVueLocale(_.value),o.watch(_,e=>s.setGridVueLocale(e));const b=o.ref();let M=null;const R=o.ref({disabled:!0,hasItem:!1}),E=l.useGridNotificationStore(),T=e=>String(e).padStart(2,"0"),G=()=>{const e=new Date;return`${e.getFullYear()}-${T(e.getMonth()+1)}-${T(e.getDate())} ${T(e.getHours())}:${T(e.getMinutes())}:${T(e.getSeconds())}`},$=()=>`mzc-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,D=e=>null==E?void 0:E.eventMessages.find(t=>{var o;return(null==(o=t.prop_value)?void 0:o.session_id)===e}),H=e=>{if(!E)return;const t=E.eventMessages.findIndex(t=>{var o;return(null==(o=t.prop_value)?void 0:o.session_id)===e});-1!==t&&E.eventMessages.splice(t,1)};let V=null;const L={onExportStart:e=>{E&&(V=$(),E.eventMessages.unshift({noti_type:"progress",header_key:"text-file_download",noti_datetime:G(),noti_sender_id:"",prop_value:{session_id:V,file_name:e,status:"in_progress",progress_per:0,operation_type:"download",remain_time:-1}}))},onExportProgress:e=>{if(!V)return;const t=D(V);if(!(null==t?void 0:t.prop_value))return;let o="number"==typeof e.percent?e.percent:void 0;void 0===o&&"number"==typeof e.rowsProcessed&&"number"==typeof e.totalRows&&e.totalRows>0&&(o=e.rowsProcessed/e.totalRows*100),"number"==typeof o&&(t.prop_value.progress_per=Math.min(99,Math.max(0,Math.floor(o))))},onExportComplete:e=>{if(!V)return;const t=V,o=D(t);(null==o?void 0:o.prop_value)&&((null==e?void 0:e.fileName)&&(o.prop_value.file_name=e.fileName),o.prop_value.status="completed",o.prop_value.progress_per=100),setTimeout(()=>H(t),2e3),V=null},onExportError:e=>{if(!V)return;const t=D(V);(null==t?void 0:t.prop_value)&&(t.prop_value.status="error",t.prop_value.error_message=e.message,t.prop_value.progress_per=0,t.prop_value.remain_time=-1),V=null},onExportCancel:()=>{V&&(H(V),V=null)},onImportComplete:()=>{if(!E)return;const e=$();E.eventMessages.unshift({noti_type:"progress",header_key:"text-file_upload",noti_datetime:G(),noti_sender_id:"",prop_value:{session_id:e,file_name:"",status:"completed",progress_per:100,operation_type:"upload",remain_time:-1}}),setTimeout(()=>H(e),2e3)},onImportError:e=>{E&&E.eventMessages.unshift({noti_type:"progress",header_key:"text-file_upload",noti_datetime:G(),noti_sender_id:"",prop_value:{session_id:$(),file_name:"",status:"error",error_message:e.message,progress_per:0,operation_type:"upload",remain_time:-1}})},onClientImportOpen:()=>{var e;if(!v.value)return;const t=(null==(e=a.contextMenuConfig)?void 0:e.clientImportOptions)??{};y.show(v.value,t)}};o.provide(z,h),o.provide(F,g),o.provide(I,v),o.provide(P,b);const O=o.computed(()=>{const e=a.height??"100%";return{height:"number"==typeof e?`${e}px`:e,width:"100%"}});function A(e){return(t,o)=>{const n={render:()=>{var t,n,l;return("tool-items"===e?null==(t=c[e])?void 0:t.call(c,R.value):"option-menu-items"===e?null==(n=c[e])?void 0:n.call(c,o.props):null==(l=c[e])?void 0:l.call(c))??null}},l=`slot:${e}`;return g.mount(l,t,n,{}),()=>g.unmount(l)}}let q,j;function U(){const e={...r.value},t=function(){const e=r.value.fields;return e===q||(q=e,j=e?k(e,h,g):void 0),j}();return t&&(e.fields=t),void 0!==_.value&&(e.locale=_.value),e.timeZone=w.value,e}function Z(){const e=["tool-left","tool-items","option-popup","tool-bottom","notification","footer","empty-state","option-menu-items"],t={};for(const o of e)c[o]&&(t[o]=A(o));return{useToolBox:a.useToolBox,useToolBoxSetting:a.useToolBoxSetting,useExtendFooter:a.useExtendFooter,useSummaryFooter:a.useSummaryFooter,useSort:a.useSort,useCustomCell:a.useCustomCell,useContextMenu:a.useContextMenu,useBuiltinTooltip:a.useBuiltinTooltip,usePivot:a.usePivot,usePivotBar:a.usePivotBar,useChart:a.useChart,useRowGroupSettings:a.useRowGroupSettings,useFieldSettings:a.useFieldSettings,useFormatSettings:a.useFormatSettings,useLayoutSettings:a.useLayoutSettings,useAggregateSettings:a.useAggregateSettings,toolbarConfig:a.toolbarConfig,useMultipleChart:a.useMultipleChart,chartIncludeGrandTotal:a.chartIncludeGrandTotal,chartMap:a.chartMap,chartConfig:a.chartConfig,loading:a.loading,locale:_.value,sourceFields:a.sourceFields,contextMenuConfig:a.contextMenuConfig,emptyState:a.emptyState,slots:t,onToolItemsPropsChange:e=>{R.value=e},excelHooks:L}}const N=["data:changed","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","header:click","header:sortClick","header:filterClick","filter:changed","scroll","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","rowGroup:toggle","rowGroup:batchToggle","contextmenu"];let Y=[];function K(){for(const e of Y)try{e()}catch{}Y=[]}const W=new WeakSet;function X(e){if(e&&"object"==typeof e){if(W.has(e))return;W.add(e)}}function J(e){if(!d.value)return null;g.setAppContext(m);const t=o.markRaw(new n.GridChrome(d.value,U(),{...Z(),sourceRevision:a.sourceRevision},e));o.markRaw(t.grid),M=t,v.value=t.grid,b.value=d.value;const l=u;t.on("data:loaded",()=>u("data:loaded"));for(const o of N)t.on(o,e=>l(o,e));return Y.push(t.onConfigChange(()=>{r.value=t.getCoreConfig(r.value),t.syncAppliedConfig(U())})),t.ready().catch(X),t}let Q=null;const ee=new n.LatestSettingsCoordinator({waitUntilSettled:async(e,t)=>{(null==M?void 0:M.waitForReinitSettled)?await M.waitForReinitSettled(t,M.isSourceReplacement(e.config,e.sourceRevision)):await(null==M?void 0:M.ready())},apply:async(e,t)=>{if(!M)return;let o=M;const{reinitRequired:n,completion:l}=o.reconcileCoreConfig(e.config,e.sourceRevision);if(l&&await l,n){const n=o,l=n.captureReinitStateAsync?await n.captureReinitStateAsync(e.config,e.sourceRevision):o.captureReinitState(e.config,e.sourceRevision);if(!t.isCurrent()||M!==o)return;K(),o.destroy(),M=null,g.unmountAll();const i=J(l);if(!i)return;if(o=i,await o.ready(),M!==o)return;await o.restoreReinitState(l)}else await o.ready();t.isCurrent()&&M===o&&Q!==o&&(Q=o,R.value=o.getToolItemsProps(),u("ready",o.grid,o))},onError:X});function te(){ee.request({config:U(),sourceRevision:a.sourceRevision})}o.onMounted(()=>{J(),te(),o.watch(()=>{const e=r.value;e.data,e.fields;const t={_locale:_.value,_timeZone:w.value,_sourceRevision:a.sourceRevision};for(const o in e)"data"!==o&&"fields"!==o&&(t[o]=e[o]);return t},()=>te(),{deep:!0}),o.watch(()=>{var e,t,o,n;return{useToolBox:a.useToolBox,useToolBoxSetting:a.useToolBoxSetting,useExtendFooter:a.useExtendFooter,useSummaryFooter:a.useSummaryFooter,useSort:a.useSort,useCustomCell:a.useCustomCell,useContextMenu:a.useContextMenu,useBuiltinTooltip:a.useBuiltinTooltip,usePivot:a.usePivot,usePivotBar:a.usePivotBar,useRowGroupSettings:a.useRowGroupSettings,useFieldSettings:a.useFieldSettings,useFormatSettings:a.useFormatSettings,useLayoutSettings:a.useLayoutSettings,useAggregateSettings:a.useAggregateSettings,toolbarConfig:{filter:{disabled:null==(t=null==(e=a.toolbarConfig)?void 0:e.filter)?void 0:t.disabled,hidden:null==(n=null==(o=a.toolbarConfig)?void 0:o.filter)?void 0:n.hidden}}}},e=>null==M?void 0:M.setUIOptions(e)),o.watch(()=>a.loading,e=>null==M?void 0:M.setUIOptions({loading:e}),{immediate:!0}),o.watch(()=>a.sourceFields,e=>null==M?void 0:M.setSourceFields(e),{immediate:!0}),o.watch(()=>a.contextMenuConfig,e=>null==M?void 0:M.setContextMenuConfig(e),{deep:!0}),o.watch(()=>a.chartConfig,e=>{var t;return null==(t=null==M?void 0:M.setChartConfig)?void 0:t.call(M,e)},{deep:!0})}),o.onBeforeUnmount(()=>{ee.destroy(),K(),null==M||M.destroy(),M=null,v.value=null,g.unmountAll()}),p({usePreset:a.usePreset,name:o.toRef(a,"name"),type:"pivot"===r.value.mode?"mozPivotGrid":"mozFlatGrid",gridInstance:v,getSourceFields:()=>{const e=r.value.fields??[],t=new Map(e.map(e=>[e.field??e.id,e.id]));return((null==M?void 0:M.pivot.sourceFields)??[]).map(e=>({id:t.get(e.field)??e.field,field:e.field,header:e.header,dataType:e.dataType}))},getCustomCellState:()=>(null==M?void 0:M.customCell.getCustomCell())??null,setCustomCellState:e=>{null==M||M.customCell.setCustomCell(e??null)},getColumnFormatState:()=>(null==M?void 0:M.columnFormat.getConfig())??null,setColumnFormatState:e=>{null==M||M.columnFormat.setConfig(e??null)},getViewOptionsState:()=>{var e;return(null==(e=null==M?void 0:M.getPresetViewState)?void 0:e.call(M))??null},setViewOptionsState:e=>{var t;null==(t=null==M?void 0:M.setPresetViewState)||t.call(M,e)}});return t(new Proxy({},{get(e,t){if("chrome"===t)return M;const o=M;if(!o)return;const n=o[t];return"function"==typeof n?n.bind(o):n},has:(e,t)=>"chrome"===t||!!M&&t in M})),(e,t)=>(o.openBlock(),o.createElementBlock(o.Fragment,null,[o.createElementVNode("div",{ref_key:"hostRef",ref:d,class:"moz-grid-chrome",style:o.normalizeStyle(O.value)},null,4),o.renderSlot(e.$slots,"default",{},void 0,!0),v.value?(o.openBlock(),o.createBlock(C,{key:0})):o.createCommentVNode("",!0)],64))}}),[["__scopeId","data-v-3e1ac7f7"]]),V=o.defineComponent({name:"CellTemplate",props:{field:{type:String,required:!0}},setup(e){const t=o.inject(z),n=o.useSlots();return t?(o.onMounted(()=>{n.default&&t.register({type:"cell",fieldId:e.field,slot:n.default})}),o.onBeforeUnmount(()=>{t.unregister("cell",e.field)}),()=>null):()=>null}}),L=o.defineComponent({name:"HeaderTemplate",props:{field:{type:String,required:!0}},setup(e){const t=o.inject(z),n=o.useSlots();return t?(o.onMounted(()=>{n.default&&t.register({type:"header",fieldId:e.field,slot:n.default})}),o.onBeforeUnmount(()=>{t.unregister("header",e.field)}),()=>null):()=>null}}),O=o.defineComponent({name:"CellEditor",props:{field:{type:String,required:!0}},setup(e){const t=o.inject(z),n=o.useSlots();return t?(o.onMounted(()=>{n.default&&t.register({type:"editor",fieldId:e.field,slot:n.default})}),o.onBeforeUnmount(()=>{t.unregister("editor",e.field)}),()=>null):()=>null}}),A=o.defineComponent({name:"DetailTemplate",props:{minHeight:{type:Number,default:100},maxHeight:{type:Number},singleExpand:{type:Boolean,default:!1},keepDetailRows:{type:Boolean,default:!0}},setup(e){const t=o.inject(I),n=o.inject(F),l=o.useSlots();return t&&n?(o.onMounted(()=>{const o=t.value;if(!o||!l.default)return;const i=l.default;o.masterDetail.setConfig({minHeight:e.minHeight,maxHeight:e.maxHeight,singleExpand:e.singleExpand,keepMasterDetailRows:e.keepDetailRows,renderer:(e,t,o)=>{const l=`detail:${o}`,r={parentData:t,dataIndex:o};return n.mount(l,e,{render:()=>i(r)},r),()=>{n.unmount(l)}}})}),o.onBeforeUnmount(()=>{null==n||n.unmountByPrefix("detail:")}),()=>null):()=>null}}),q=o.defineComponent({name:"GroupTemplate",setup(){const e=o.inject(I),t=o.inject(F),n=o.useSlots();if(!e||!t)return()=>null;const l=new Map,i=e=>{const t=l.get(e);t&&(l.delete(e),t.destroy())},r=e=>{null==e||e.formatRow.removeHandler("_groupTemplate");for(const t of[...l.keys()])i(t)};let s=null;return o.watch(e,e=>{e!==s&&(r(s),s=e??null,e&&(e=>{if(!n.default)return;const o=n.default;e.formatRow.addHandler("_groupTemplate",e=>{if("group-row"!==e.type)return;const n=e.ctx,r=n.element;if(!r)return;const s={groupKey:n.column,groupValue:n.value,level:n.level,count:n.itemCount,isExpanded:!n.collapsed},a=l.get(r);if(a&&r.classList.contains("ps-group-template-host"))return void a.update(s);a&&i(r);const u=t.mountInstance(r,e=>o(e),s);l.set(r,u),r.addEventListener("ps-group-template-dispose",()=>i(r),{once:!0})})})(e))},{immediate:!0}),o.onBeforeUnmount(()=>{r(s),s=null}),()=>null}});let j=!1;function U(e){return e?(Object.prototype.hasOwnProperty.call(e,"formatHeaderRow")||Object.defineProperty(e,"formatHeaderRow",{configurable:!0,get:()=>(j||(j=!0),e.formatHeader)}),e):null}const Z=o.defineComponent({__name:"MozGridVue",props:{name:{},useToolBox:{type:Boolean,default:!0},useToolBoxSetting:{type:Boolean,default:!0},useExtendFooter:{type:Boolean,default:!0},useSummaryFooter:{type:Boolean,default:!1},useSort:{type:Boolean,default:!0},useCustomCell:{type:Boolean,default:!0},contextMenuConfig:{default:()=>({})},useContextMenu:{type:Boolean,default:!0},loading:{type:Boolean},emptyState:{},fields:{},data:{},mode:{},pivotRowFields:{},pivotColumnFields:{},pivotValueFields:{},height:{default:"100%"},keyFields:{},theme:{},rowHeight:{},headerHeight:{},showHeader:{type:Boolean,default:!0},resizableColumns:{type:Boolean,default:!0},reorderableColumns:{type:Boolean,default:!0},showRowHeader:{type:[Boolean,Object]},rowHeader:{type:[Boolean,Object]},rowSelection:{},cellSelection:{default:()=>({mode:"range"})},cellSelectionImpliesRows:{type:Boolean},editable:{type:Boolean,default:!1},tooltipMode:{default:"overflow"},alternatingRows:{type:Boolean,default:!0},autoFitColumns:{type:Boolean},dynamicRowHeights:{type:Boolean,default:!1},reorderableRows:{type:Boolean,default:!1},locale:{},engine:{},useWorker:{type:Boolean},loader:{},preventKeyEdit:{type:Boolean,default:!0},showStatusBar:{type:Boolean},showDragHandleColumn:{type:Boolean},undoStack:{},formatRow:{},translations:{},rowStyle:{},headerStyle:{},rowHeightChangeThreshold:{},group:{},columnGroups:{},rowTemplate:{}},emits:["ready","data:loaded","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","filter:changed","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","scroll","contextmenu"],setup(e,{expose:t,emit:l}){const i=e,r=l,s=o.computed(()=>{const e={...i};for(const t of n.WRAPPER_EXTRA_KEYS)delete e[t];return delete e.name,delete e.locale,e}),a=o.computed(()=>{const e=i,t={};for(const o of n.WRAPPER_EXTRA_KEYS)void 0!==e[o]&&(t[o]=e[o]);return void 0!==e.locale&&(t.locale=e.locale),t}),u=Object.fromEntries(["ready","data:loaded","row:click","row:dblclick","row:pinned","row:unpinned","row:reordered","cell:click","cell:dblclick","cell:change","cell:beforeEdit","cell:editCommitting","cell:editCommitted","cell:tooltip","selection:changed","column:resize","column:reorder","column:pin","column:visibility","sort:changed","filter:changed","undo:stateChange","clipboard:copy","clipboard:paste","validation:changed","columnGroup:toggle","scroll","contextmenu"].map(e=>[e,(...t)=>r(e,...t)]));u.ready=e=>r("ready",U(e));const d=o.ref(null);function c(){return d.value??null}const p={};return Object.defineProperties(p,{grid:{enumerable:!0,get:()=>{var e;return U(null==(e=c())?void 0:e.grid)}},core:{enumerable:!0,get:()=>p},filterModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.filter}},sortModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.sort}},customCellModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.customCell}},bulkEditorModule:{enumerable:!0,get:()=>{var e;return null==(e=c())?void 0:e.bulkEditor}}}),p.refresh=async()=>{var e,t;return null==(t=null==(e=c())?void 0:e.grid)?void 0:t.refresh()},p.loadData=async e=>{var t,o;return null==(o=null==(t=c())?void 0:t.grid)?void 0:o.loadData(e)},p.sort=async e=>{var t,o;return null==(o=null==(t=c())?void 0:t.grid)?void 0:o.sort(e)},p.filter=async e=>{var t,o;return null==(o=null==(t=c())?void 0:t.grid)?void 0:o.filter(e)},t(p),(e,t)=>(o.openBlock(),o.createBlock(H,o.mergeProps({ref_key:"mozRef",ref:d,coreConfig:s.value},a.value,{name:i.name},o.toHandlers(o.unref(u))),o.createSlots({default:o.withCtx(()=>[o.renderSlot(e.$slots,"default")]),_:2},[e.$slots["tool-left"]?{name:"tool-left",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"tool-left")]),key:"0"}:void 0,e.$slots["tool-items"]?{name:"tool-items",fn:o.withCtx(t=>[o.renderSlot(e.$slots,"tool-items",o.normalizeProps(o.guardReactiveProps(t)))]),key:"1"}:void 0,e.$slots.notification?{name:"notification",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"notification")]),key:"2"}:void 0,e.$slots.footer?{name:"footer",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"footer")]),key:"3"}:void 0,e.$slots.customState?{name:"empty-state",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"customState")]),key:"4"}:void 0]),1040,["coreConfig","name"]))}}),N=o.defineComponent({__name:"MozPivotVue",props:{name:{},data:{},rowFields:{},columnFields:{},valueFields:{},height:{default:"100%"},showRowSubTotals:{type:Boolean,default:!1},showRowGrandTotals:{type:Boolean,default:!0},showColumnSubTotals:{type:Boolean,default:!1},showColumnGrandTotals:{type:Boolean,default:!0},trackSourceRows:{type:Boolean,default:!1},showHeader:{type:Boolean,default:!0},alternatingRows:{type:Boolean,default:!1},tooltipMode:{default:"overflow"},rowSelection:{},cellSelection:{default:()=>({mode:"range"})},cellSelectionImpliesRows:{type:Boolean},useToolBox:{type:Boolean,default:!0},useToolBoxSetting:{type:Boolean,default:!0},useFilter:{type:Boolean,default:!0},useSort:{type:Boolean,default:!0},useCustomCell:{type:Boolean,default:!0},useExtendFooter:{type:Boolean,default:!0},useSummaryFooter:{type:Boolean,default:!1},useContextMenu:{type:Boolean,default:!0},contextMenuConfig:{},useChart:{type:Boolean,default:!1},fields:{},availableFields:{},useMultipleChart:{type:Boolean,default:!0},chartIncludeGrandTotal:{type:Boolean,default:!1},chartMap:{},loading:{type:Boolean},emptyState:{}},emits:["ready","data:loaded","filter:changed","pivot:configured","pivot:toggled","update:rowFields","update:columnFields","update:valueFields"],setup(e,{expose:t,emit:l}){const i=e,r=l,s=o.computed(()=>{const e={...i};for(const t of n.WRAPPER_EXTRA_KEYS)delete e[t];return delete e.name,delete e.locale,delete e.availableFields,delete e.useFilter,e.mode="pivot",e}),a=o.computed(()=>{const e=i,t={};for(const o of n.WRAPPER_EXTRA_KEYS)void 0!==e[o]&&(t[o]=e[o]);return void 0!==e.locale&&(t.locale=e.locale),t.sourceFields=e.sourceFields??e.availableFields??e.fields,t}),u=Object.fromEntries(["ready","data:loaded","filter:changed","pivot:toggled"].map(e=>[e,(...t)=>r(e,...t)]));function d(e){var t,o,n;const l=e;r("update:rowFields",l.rowFields??[]),r("update:columnFields",l.columnFields??[]),r("update:valueFields",l.valueFields??[]);const i=null==(n=null==(o=null==(t=p())?void 0:t.pivot)?void 0:o.getRawConfig)?void 0:n.call(o);i&&r("pivot:configured",i)}u.ready=e=>r("ready",U(e));const c=o.ref(null);function p(){return c.value??null}function m(){var e,t;return null==(t=null==(e=p())?void 0:e.grid)?void 0:t.pivot}const f=o.computed({get:()=>{var e,t;return(null==(t=null==(e=p())?void 0:e.chart)?void 0:t.visible)??!1},set:e=>{var t,o;return null==(o=null==(t=p())?void 0:t.chart)?void 0:o.setVisible(e)}}),g={};return Object.defineProperties(g,{grid:{enumerable:!0,get:()=>{var e;return U(null==(e=p())?void 0:e.grid)}},core:{enumerable:!0,get:()=>g},pivotApi:{enumerable:!0,get:()=>m()??null},filterModule:{enumerable:!0,get:()=>{var e;return null==(e=p())?void 0:e.filter}},sortModule:{enumerable:!0,get:()=>{var e;return null==(e=p())?void 0:e.sort}},customCellModule:{enumerable:!0,get:()=>{var e;return null==(e=p())?void 0:e.customCell}},showChart:{enumerable:!0,get:()=>f.value,set:e=>{f.value=e}}}),g.refresh=async()=>{var e,t;return null==(t=null==(e=p())?void 0:e.grid)?void 0:t.refresh()},g.setConfig=async e=>{var t;return null==(t=m())?void 0:t.setConfig(e)},g.getResult=()=>{var e;return(null==(e=m())?void 0:e.getResult())??null},g.expandAll=async()=>{var e;return null==(e=m())?void 0:e.expandAllRows()},g.collapseAll=async()=>{var e;return null==(e=m())?void 0:e.collapseAllRows()},g.expandToLevel=async e=>{var t;return null==(t=m())?void 0:t.expandRowToLevel(e)},g.toggleChart=()=>{f.value=!f.value},t(g),(e,t)=>(o.openBlock(),o.createBlock(H,o.mergeProps({ref_key:"mozRef",ref:c,coreConfig:s.value},a.value,{name:i.name,"onUpdate:coreConfig":d},o.toHandlers(o.unref(u))),o.createSlots({default:o.withCtx(()=>[o.renderSlot(e.$slots,"default")]),_:2},[e.$slots["tool-left"]?{name:"tool-left",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"tool-left")]),key:"0"}:void 0,e.$slots["tool-items"]?{name:"tool-items",fn:o.withCtx(t=>[o.renderSlot(e.$slots,"tool-items",o.normalizeProps(o.guardReactiveProps(t)))]),key:"1"}:void 0,e.$slots.footer?{name:"footer",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"footer")]),key:"2"}:void 0,e.$slots.customState?{name:"empty-state",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"customState")]),key:"3"}:void 0]),1040,["coreConfig","name"]))}});exports.GridNotificationKey=l.GridNotificationKey,exports.provideGridNotification=l.provideGridNotification,exports.useGridNotificationStore=l.useGridNotificationStore,exports.ExcelDataType=s.DataType,exports.FileParameter=s.FileParameter,exports.enUS=s.enUS,exports.getGridVueLocale=s.getGridVueLocale,exports.getGridVueLocaleCode=s.getGridVueLocaleCode,exports.jaJP=s.jaJP,exports.koKR=s.koKR,exports.normalizeGridVueLocale=s.normalizeGridVueLocale,exports.openToast=s.openToast,exports.setGridVueLocale=s.setGridVueLocale,exports.showMessage=s.showMessage,exports.useExcelDownloadStore=s.useExcelDownloadStore,exports.useExcelStore=s.useExcelStore,exports.useExcelUploadStore=s.useExcelUploadStore,exports.zhCN=s.zhCN,Object.defineProperty(exports,"ROW_HEADER_COLUMN_ID",{enumerable:!0,get:()=>u.ROW_HEADER_COLUMN_ID}),Object.defineProperty(exports,"UndoStack",{enumerable:!0,get:()=>u.UndoStack}),Object.defineProperty(exports,"getCornerCell",{enumerable:!0,get:()=>u.getCornerCell}),Object.defineProperty(exports,"getRowHeaderCell",{enumerable:!0,get:()=>u.getRowHeaderCell}),exports.CellEditor=O,exports.CellTemplate=V,exports.ClientExcelUploadController=x,exports.ClientExcelUploadPopup=C,exports.DetailTemplate=A,exports.GRID_BULK_EDITOR_MODULE_KEY=D,exports.GRID_CUSTOM_CELL_MODULE_KEY=$,exports.GRID_FILTER_MODULE_KEY=T,exports.GRID_INSTANCE_KEY=I,exports.GRID_RENDERER_KEY=F,exports.GRID_SORT_MODULE_KEY=G,exports.GRID_TEMPLATE_REGISTRY_KEY=z,exports.GroupTemplate=q,exports.HeaderTemplate=L,exports.MOZ_GRID_CONFIG_KEY=w,exports.MOZ_GRID_LOCALE_KEY=R,exports.MozGrid=H,exports.MozGridConfigProvider=M,exports.MozGridLocaleProvider=E,exports.MozGridVue=Z,exports.MozPivotVue=N,exports.StreamingParameter=class{constructor(e){t(this,"params"),t(this,"loading",!0),t(this,"size",0),t(this,"offset",0),t(this,"onReceived"),t(this,"onClosed"),t(this,"onHandleError"),t(this,"onCancelClick"),t(this,"_complete",!1),this.params=e}get ipcObject(){return this.params}get percent(){return 0===this.offset||0===this.size?0:Math.round(this.offset/this.size*100)}get complete(){return this._complete}received(e){this.offset++,this.onReceived&&this.onReceived(e)}closed(e=!0){this._complete=e,this.onClosed&&this.onClosed()}handleError(e,t=!0){this._complete=t,this.onHandleError&&this.onHandleError(e)}},exports.UserLayoutInstance=d,exports.VueRenderer=B,exports.downloadBlob=function(e,t){const o=URL.createObjectURL(e),n=document.createElement("a");n.href=o,n.download=t,n.style.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n),setTimeout(()=>URL.revokeObjectURL(o),0)},exports.exportCsv=async function(e){let t,o;if("pivot"===e.pivot.getMode()){const n=await e.pivot.getDataMatrix();if(!n)return;t=n.headers,o=n.rows}else{const n=await e.getExportData({scope:"all"});if(!n)return;const{headers:l,rows:i}=n,r=l.map(e=>e.id);t=l.map(e=>e.header),o=i.map(e=>r.map(t=>e[t]))}const n=[];n.push(t.map(h).join(","));for(const a of o)n.push(a.map(h).join(","));const l="\ufeff"+n.join("\r\n"),i=new Blob([l],{type:"text/csv;charset=utf-8;"}),r=URL.createObjectURL(i),s=document.createElement("a");s.href=r,s.download=`export_${(new Date).toISOString().slice(0,10)}.csv`,s.click(),URL.revokeObjectURL(r)},exports.generateSessionId=g,exports.pickFile=function(e=".xlsx"){return new Promise(t=>{const o=document.createElement("input");o.type="file",o.accept=e,o.style.display="none";let n=!1;const l=()=>{o.parentNode&&o.parentNode.removeChild(o)};o.onchange=()=>{if(n)return;n=!0;const e=o.files&&o.files.length>0?o.files[0]:null;l(),t(e)};const i=()=>{window.removeEventListener("focus",i),setTimeout(()=>{n||(n=!0,l(),t(null))},300)};window.addEventListener("focus",i),document.body.appendChild(o),o.click()})},exports.runClientExport=async function(e,t,o){var n;const l=`${t.exportFileName??"export"}_${a().format("YYYYMMDD")}.xlsx`,i=g();o&&o.eventMessages.unshift({noti_type:"progress",header_key:"text-file_download",noti_datetime:a().format("YYYY-MM-DD HH:mm:ss"),noti_sender_id:"",prop_value:{session_id:i,file_name:l,status:"in_progress",progress_per:0,operation_type:"download",remain_time:-1}});try{if(await e.io.saveExcelToFile({scope:"all",includeHeaders:!0,suggestedName:l,fallbackToDownload:!0,sheetSplit:"auto",includePinnedRows:!0,onProgress:e=>{if(!o)return;const t=o.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});if(!(null==t?void 0:t.prop_value))return;let n="number"==typeof e.percent?e.percent:void 0;void 0===n&&"number"==typeof e.rowsProcessed&&"number"==typeof e.totalRows&&e.totalRows>0&&(n=e.rowsProcessed/e.totalRows*100),"number"==typeof n&&(t.prop_value.progress_per=Math.min(99,Math.max(0,Math.floor(n))))},...t.clientExportOptions??{}}),o){const e=o.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});(null==e?void 0:e.prop_value)&&(e.prop_value.status="completed",e.prop_value.progress_per=100),setTimeout(()=>{const e=o.eventMessages.findIndex(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});-1!==e&&o.eventMessages.splice(e,1)},2e3)}null==(n=t.onClientExportComplete)||n.call(t,new Blob)}catch(r){if(r instanceof DOMException&&"AbortError"===r.name){if(o){const e=o.eventMessages.findIndex(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});-1!==e&&o.eventMessages.splice(e,1)}return}if(o){const e=o.eventMessages.find(e=>{var t;return(null==(t=e.prop_value)?void 0:t.session_id)===i});(null==e?void 0:e.prop_value)&&(e.prop_value.status="error",e.prop_value.error_message=r instanceof Error?r.message:String(r),e.prop_value.progress_per=0,e.prop_value.remain_time=-1)}}},exports.useClientExcelStore=f,exports.useMozGridConfig=S,exports.useMozGridLocale=function(){const e=o.inject(R,null);return e||o.computed(()=>{})},exports.useUserLayoutModule=c;
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export { default as MozPivotVue } from './compat/MozPivotVue.vue';
13
13
  export { provideGridNotification, useGridNotificationStore, GridNotificationKey, } from './contracts/notification.contract';
14
14
  export type { GridNotificationContract, NotificationItem, SSENotificationType, ExcelNotificationOperationType, } from './contracts/notification.contract';
15
15
  export { useUserLayoutModule, UserLayoutInstance } from './contracts/userLayout.contract';
16
+ export type { UserLayoutApplyResult, UserLayoutApplyStatus } from './contracts/UserLayoutInstance';
16
17
  export type { UserLayoutModuleContract } from './contracts/userLayout.contract';
17
18
  export { useExcelStore, useExcelDownloadStore, useExcelUploadStore } from './store';
18
19
  export { default as ClientExcelUploadPopup } from './excel/ClientExcelUploadPopup.vue';
package/dist/index.js CHANGED
@@ -24,9 +24,23 @@ class UserLayoutInstance {
24
24
  __publicField(this, "_default");
25
25
  __publicField(this, "_importDef");
26
26
  __publicField(this, "_exportDef");
27
- __publicField(this, "_pendingDef");
28
27
  __publicField(this, "_pending");
29
- __publicField(this, "dispose", () => {
28
+ __publicField(this, "_disposed", false);
29
+ __publicField(this, "_sequence", 0);
30
+ __publicField(this, "_active");
31
+ __publicField(this, "_queued");
32
+ __publicField(this, "_lastApplyResult");
33
+ __publicField(this, "_disposeCallback", () => {
34
+ });
35
+ /** 요청 접수 당시 preset에 완료를 귀속하는 registry 내부 hook. */
36
+ __publicField(this, "captureApplied");
37
+ __publicField(this, "disposeInstance", () => {
38
+ if (this._disposed) return;
39
+ this._disposed = true;
40
+ if (this._active) this.finish(this._active, "disposed");
41
+ if (this._queued) this.finish(this._queued, "disposed");
42
+ this._queued = void 0;
43
+ this._disposeCallback();
30
44
  });
31
45
  __publicField(this, "setApplied", () => {
32
46
  });
@@ -39,7 +53,6 @@ class UserLayoutInstance {
39
53
  this._exportDef = exportDef;
40
54
  this._default = exportDef();
41
55
  this._pending = false;
42
- this._pendingDef = null;
43
56
  this.strict = strict ?? false;
44
57
  this.dependencies = dependencies ?? null;
45
58
  if (!manualLifeCycle) {
@@ -48,21 +61,30 @@ class UserLayoutInstance {
48
61
  });
49
62
  }
50
63
  }
64
+ get disposed() {
65
+ return this._disposed;
66
+ }
67
+ get applying() {
68
+ return !!this._active || !!this._queued;
69
+ }
70
+ get lastApplyResult() {
71
+ return this._lastApplyResult;
72
+ }
73
+ get requestId() {
74
+ return this._sequence;
75
+ }
76
+ get dispose() {
77
+ return this.disposeInstance;
78
+ }
79
+ set dispose(callback) {
80
+ this._disposeCallback = callback;
81
+ }
51
82
  get pending() {
52
83
  return this._pending;
53
84
  }
54
85
  set pending(value) {
55
86
  this._pending = value;
56
- if (!value && this._pendingDef) {
57
- try {
58
- this._importDef(this._pendingDef);
59
- this.setApplied(true);
60
- } catch (e2) {
61
- console.warn(`[UserLayoutInstance] id="${this._id}" importDef 실패:`, e2);
62
- } finally {
63
- this._pendingDef = null;
64
- }
65
- }
87
+ this.drain();
66
88
  }
67
89
  get id() {
68
90
  return this._id;
@@ -80,12 +102,84 @@ class UserLayoutInstance {
80
102
  return this._exportDef();
81
103
  }
82
104
  set current(value) {
83
- if (this.pending) {
84
- this._pendingDef = value;
85
- return;
105
+ void this.apply(value);
106
+ }
107
+ /** 취소는 import 자체를 중단하지 않으며, 겹친 import는 직렬 실행합니다. */
108
+ apply(value) {
109
+ const requestId = ++this._sequence;
110
+ if (this._active) this.finish(this._active, "superseded");
111
+ if (this._queued) this.finish(this._queued, "superseded");
112
+ this._queued = void 0;
113
+ return new Promise((resolve) => {
114
+ var _a;
115
+ const request = {
116
+ requestId,
117
+ value,
118
+ resolve,
119
+ settled: false,
120
+ applied: this.setApplied
121
+ };
122
+ if (this._disposed) {
123
+ this.finish(request, "disposed");
124
+ return;
125
+ }
126
+ try {
127
+ request.applied = ((_a = this.captureApplied) == null ? void 0 : _a.call(this)) ?? this.setApplied;
128
+ } catch (error) {
129
+ this.finish(request, "failed", error);
130
+ return;
131
+ }
132
+ this._lastApplyResult = void 0;
133
+ this._queued = request;
134
+ this.drain();
135
+ });
136
+ }
137
+ finish(request, status, error) {
138
+ if (request.settled) return;
139
+ request.settled = true;
140
+ const result = { status, requestId: request.requestId };
141
+ if (error !== void 0) result.error = error;
142
+ if (request.requestId === this._sequence) this._lastApplyResult = result;
143
+ request.resolve(result);
144
+ }
145
+ drain() {
146
+ if (this._disposed || this._pending || this._active || !this._queued) return;
147
+ const request = this._queued;
148
+ this._queued = void 0;
149
+ this._active = request;
150
+ const complete = (result, error, failed = false) => {
151
+ try {
152
+ if (!request.settled) {
153
+ if (failed) {
154
+ console.warn(`[UserLayoutInstance] id="${this._id}" importDef 실패:`, error);
155
+ this.finish(request, "failed", error);
156
+ } else if (result && typeof result === "object" && "status" in result && result.status !== "applied") {
157
+ this.finish(request, result.status, result.error);
158
+ } else {
159
+ request.applied(true);
160
+ this.finish(request, "applied");
161
+ }
162
+ }
163
+ } catch (error2) {
164
+ this.finish(request, "failed", error2);
165
+ } finally {
166
+ this._active = void 0;
167
+ this.drain();
168
+ }
169
+ };
170
+ try {
171
+ const result = this._importDef(request.value);
172
+ if (result && typeof result.then === "function") {
173
+ Promise.resolve(result).then(
174
+ (value) => complete(value),
175
+ (error) => complete(void 0, error, true)
176
+ );
177
+ } else {
178
+ complete(result);
179
+ }
180
+ } catch (error) {
181
+ complete(void 0, error, true);
86
182
  }
87
- this._importDef(value);
88
- this.setApplied(true);
89
183
  }
90
184
  setDefaultToCurrent() {
91
185
  this._default = this._exportDef();
@@ -113,11 +207,13 @@ function useGridPreset(options) {
113
207
  return def;
114
208
  };
115
209
  const applyExtra = (set, value) => {
116
- if (value !== void 0) set == null ? void 0 : set(value);
210
+ if (value !== void 0) return set == null ? void 0 : set(value);
117
211
  };
118
- const applyPreset = async (preset) => {
119
- const grid = options.gridInstance.value;
120
- if (!grid) return;
212
+ const applyPreset = async (preset, grid, requestId) => {
213
+ const invalidOwner = () => {
214
+ if (layoutInstance.disposed) return { status: "disposed", requestId };
215
+ if (options.gridInstance.value !== grid) return { status: "superseded", requestId };
216
+ };
121
217
  const baseline = layoutInstance.default ?? null;
122
218
  const migrated = migrateGridPreset(preset ?? baseline, {
123
219
  grid,
@@ -128,25 +224,39 @@ function useGridPreset(options) {
128
224
  if (options.onImportDiagnostics) options.onImportDiagnostics(migrated.diagnostics);
129
225
  else console.warn("[Grid preset compatibility]", migrated.diagnostics);
130
226
  }
227
+ const beforeCore = invalidOwner();
228
+ if (beforeCore) return beforeCore;
131
229
  if (migrated.config) await applyPresetCoreConfig(grid, migrated.config, migrated.missing);
132
- applyExtra(options.setColumnFormatState, migrated.columnFormatConfig);
133
- applyExtra(options.setCustomCellState, migrated.customCellConfig);
134
- applyExtra(options.setViewOptionsState, migrated.viewOptionsConfig);
230
+ const extras = [
231
+ [options.setColumnFormatState, migrated.columnFormatConfig],
232
+ [options.setCustomCellState, migrated.customCellConfig],
233
+ [options.setViewOptionsState, migrated.viewOptionsConfig]
234
+ ];
235
+ for (const [set, value] of extras) {
236
+ const invalid = invalidOwner();
237
+ if (invalid) return invalid;
238
+ await applyExtra(set, value);
239
+ }
240
+ const beforeSettlement = invalidOwner();
241
+ if (beforeSettlement) return beforeSettlement;
242
+ await grid.waitForSettled();
243
+ return invalidOwner() ?? { status: "applied", requestId };
135
244
  };
136
- let latestRequest = 0;
137
- let queue = Promise.resolve();
138
- const importDef = (preset) => {
139
- const token = ++latestRequest;
140
- const run = queue.then(async () => {
141
- if (token !== latestRequest) return;
142
- try {
143
- await applyPreset(preset);
144
- } catch (error) {
145
- console.error("[Grid preset] import failed", error);
146
- }
147
- });
148
- queue = run;
149
- return run;
245
+ const importDef = async (preset) => {
246
+ const requestId = layoutInstance.requestId;
247
+ const grid = options.gridInstance.value;
248
+ await Promise.resolve();
249
+ if (layoutInstance.disposed) return { status: "disposed", requestId };
250
+ if (requestId !== layoutInstance.requestId || options.gridInstance.value !== grid) {
251
+ return { status: "superseded", requestId };
252
+ }
253
+ if (!grid) return { status: "failed", requestId, error: new Error("Grid preset: grid-not-ready") };
254
+ try {
255
+ return await applyPreset(preset, grid, requestId);
256
+ } catch (error) {
257
+ console.error("[Grid preset] import failed", error);
258
+ return { status: "failed", requestId, error };
259
+ }
150
260
  };
151
261
  const layoutInstance = new UserLayoutInstance({
152
262
  id: options.name.value,
@@ -155,18 +265,31 @@ function useGridPreset(options) {
155
265
  exportDef
156
266
  });
157
267
  let registered = false;
158
- watch(options.gridInstance, (grid) => {
159
- if (!grid || registered) return;
268
+ watch(options.gridInstance, (grid, _previous, onCleanup) => {
269
+ if (!grid || registered || layoutInstance.disposed) return;
160
270
  if (!options.name.value) return;
271
+ let active = true;
272
+ let scheduled = false;
273
+ const isCurrent = () => active && !layoutInstance.disposed && options.gridInstance.value === grid;
161
274
  const unsub = grid.on("data:loaded", () => {
162
- if (registered) return;
275
+ if (registered || scheduled || !isCurrent()) return;
276
+ scheduled = true;
163
277
  layoutInstance.setDefaultToCurrent();
164
- nextTick(() => {
165
- register(layoutInstance);
278
+ void nextTick(async () => {
279
+ if (!isCurrent() || registered) return;
166
280
  registered = true;
167
281
  unsub();
282
+ try {
283
+ await register(layoutInstance);
284
+ } catch (error) {
285
+ console.error("[Grid preset] registration failed", error);
286
+ }
168
287
  });
169
288
  });
289
+ onCleanup(() => {
290
+ active = false;
291
+ unsub();
292
+ });
170
293
  });
171
294
  }
172
295
  let instance = null;
@@ -3924,7 +3924,7 @@ interface MergeRangeResult {
3924
3924
  > });
3925
3925
  > ```
3926
3926
 
3927
- > **Worker 모드 제약**: `type: 'custom'`은 함수 직렬화 불가로 worker에서 사용 불가. content/hierarchical만 worker 호환.
3927
+ > **Worker custom 병합**: `getMergedRange` / `getMergedRanges`에 앱 Worker entry에 등록한 `WorkerFunctionRef`를 전달하면 Worker 내부에서 실행합니다. inline 함수 본문은 Worker로 전달할 수 없습니다(Main inline 콜백은 유지). 등록 방법과 pinned merge의 비동기 경계는 [Worker 실행 계약](runtime-contracts.md)을 참조하세요.
3928
3928
 
3929
3929
  ---
3930
3930
 
@@ -4232,10 +4232,11 @@ type LifecycleCellRenderer = (
4232
4232
 
4233
4233
  interface CellRendererInstance {
4234
4234
  /**
4235
- * 셀이 재사용되며 데이터가 바뀔 때 호출.
4235
+ * 셀이 재사용되며 데이터가 바뀌거나, 성공한 명시 `loadData` 후 다시 표시될 때 호출.
4236
+ * 동일 행 객체/ID/값/renderer 참조여도 명시 reload는 custom renderer 표시 캐시를 무효화한다.
4236
4237
  * - 반환 `false`: instance가 처리 못함 → 그리드가 destroy 후 re-mount
4237
4238
  * - 반환 `void`/`true`: instance가 자체 갱신함
4238
- * 미정의 시: 값/행이 바뀌면(값 변경, 스크롤 재활용) destroy 후 re-mount. 그대로면 유지.
4239
+ * 미정의 시: 값/행 변경 또는 명시 reload이면 destroy 후 re-mount. 그 외에는 유지.
4239
4240
  */
4240
4241
  update?: (params: CellRendererParams) => boolean | void;
4241
4242
  /** 셀이 사라질 때 호출 — pool release / 컬럼 제거 / grid destroy 시 */
@@ -4243,6 +4244,8 @@ interface CellRendererInstance {
4243
4244
  }
4244
4245
  ```
4245
4246
 
4247
+ 명시 `loadData`의 최신 요청이 데이터를 정상 설치하면, 표시되는 custom renderer는 같은 행 객체/ID/값이어도 다시 평가됩니다. 유지된 lifecycle 인스턴스는 `update`를 받고, update가 없거나 false이면 destroy 후 재마운트됩니다. 보이지 않는 셀을 즉시 mount하지는 않으며 다음 표시 시 최신 reload 상태로 그립니다. 외부 closure 자체의 자동 추적은 제공하지 않습니다. 일반 `refresh()`/스크롤의 기존 dirty-check 정책은 이 계약으로 확대하지 않습니다. 설치 전 실패하거나 뒤늦게 완료된 오래된 load는 새 renderer invalidation 경계를 만들지 않습니다.
4248
+
4246
4249
  ```typescript
4247
4250
  // Simple 형태 — 매 렌더마다 새 요소 반환
4248
4251
  { id: 'status', cellRenderer: ({ value }) => `<span class="badge-${value}">${value}</span>` }
@@ -252,7 +252,7 @@ type MozGridCoreProps =
252
252
  ### 초기화·편집·XLSX 설정 전달
253
253
 
254
254
  - `sourceRevision?: unknown`은 wrapper prop입니다. 외부 데이터셋 교체 때만 바꾸며 `coreConfig` 안에 넣지 않습니다. `ready`의 두 번째 인수 `chrome.getReadyContext()`에서 `{ reason, dataRestored, sourceRevision }`를 확인하세요. [세션 보존·Worker·끝점 API 상세](runtime-contracts.md).
255
- - 같은 소스 재생성은 지원되는 Main flat/tree 세션의 baseline·dirty·undo/redo를 복원한 뒤 ready를 다시 발생시킵니다. Worker/active pivot(깨끗하거나 미로드 상태도 포함)·미지원 custom history는 차단됩니다. busy capture 실패는 기존 인스턴스를 유지하지만 **자동 대기·재시도하지 않습니다**. 정책 확대는 별도 결정 사항입니다.
255
+ - 일반 런타임 설정은 공통 coordinator가 추적된 작업 종료를 기다려 동일 인스턴스에 적용하며 `ready`를 다시 발생시키지 않습니다. 실제 같은 소스 인스턴스 교체에서는 비동기 capture/restore로 baseline·dirty·지원 undo/redo를 이전하며 Worker 세션과 pivot 상태도 포함합니다. 미지원 custom history나 호환되지 않는 keyFields 변경은 거부합니다. capture 실패 시 기존 인스턴스를 유지하고 오류를 보고하며, 실제 load/validation 실패를 무한 재시도하지 않습니다. 세부 경계는 [실행 계약](runtime-contracts.md)을 따릅니다.
256
256
 
257
257
  - **행 식별 설정은 필수**입니다. 업무 키가 있으면 `coreConfig.keyFields`를 명시하고, 키 없이 시작하려면 `coreConfig.enableReferCache: true`를 설정하세요(기본 `false`). 두 설정 모두 생략하거나 `keyFields: []`를 전달하면 초기화할 수 없습니다. 원본 `id` 필드를 자동으로 키로 선택하지 않습니다. 자동 ID 수명과 행 객체 참조 계약은 [코어 Config](reference.md#config-설정)를 참조하세요.
258
258
  - 내장 숫자/날짜시간 편집기는 별도 래퍼 prop이 아니라 `coreConfig.fields[].editor`로 전달합니다. 아래 설정을 기존 `coreConfig`에 병합하세요.
@@ -0,0 +1,154 @@
1
+ # 선택 끝점·Worker 함수·데이터 세션 실행 계약
2
+
3
+ 이 문서는 현재 공급자 소스에 구현된 계약입니다. npm 배포 완료를 의미하지 않습니다. 기본 API는 [Core](reference.md), [Vue](reference_vue.md), [React](reference_react.md)를 참조하세요.
4
+
5
+ ## 논리적 선택 끝점
6
+
7
+ ```ts
8
+ const focus = grid.selection.getFocusCell(); // SelectedCell | null
9
+ const sameFocus = grid.cells.getFocusCell(); // 동일한 조회
10
+ if (focus) console.log(focus.columnId, focus.row.id);
11
+ ```
12
+
13
+ - 반환은 `{ row: RowHandle, columnId: string }`입니다. 정규화한 범위의 우하단이 아니라 논리적 선택 target입니다. 역방향 드래그에서도 끝점을 구분합니다.
14
+ - `getActiveCell()`의 traversal 앵커 계약을 바꾸지 않습니다. 프로그램 범위 선택의 끝점과 다음 Shift 탐색 기준도 별개입니다.
15
+ - 마우스 release가 유효한 데이터 셀이면 마지막 mousemove가 없어도 반영합니다. viewport 밖·헤더·빈 공간·그룹 배너·detail 등 비데이터 영역 release에서는 마지막으로 수용한 데이터 target을 유지합니다.
16
+ - 선택 해제, 끝점이 더 이상 선택범위에 속하지 않는 경우, 제거되거나 다른 영역으로 이동한 pinned 행, 동기적으로 identity를 확인할 수 없는 lazy slot은 `null`입니다. sparse 좌표 선택 자체를 취소하는 것은 아닙니다.
17
+ - getter는 전체 선택을 열거하거나 비동기 fetch하지 않습니다. `row.viewIndex`는 화면 위치, `row.sourceIndex`는 해석 가능한 원본 위치입니다. pinned의 내부 음수 좌표를 소비처 좌표로 만들어 반환하지 않습니다.
18
+ - 탭 전환처럼 끝점 **열**이 필요한 작업에 사용하세요. 업무 행·삭제 payload까지 끝점 행으로 교체해야 한다는 의미는 아닙니다.
19
+
20
+ ## 신뢰하는 앱 Worker entry
21
+
22
+ 일반 Main 모드의 inline 함수는 그대로 Main에서 실행합니다. 재사용을 위해 registry로 바꿀 필요가 없습니다. Worker 계산에는 함수 본문 대신 명시적 참조를 보냅니다.
23
+
24
+ ```ts
25
+ import type { WorkerFunctionRef } from '@vmscloud/moz-ui-grid-core';
26
+ const sumRef: WorkerFunctionRef = { workerFunction: 'app:sum', params: { factor: 1 } };
27
+ ```
28
+
29
+ `workerFunction`은 정적 등록 ID이며 `params`는 structured-clone 가능해야 합니다. 등록 함수는 기존 callback 인수 **뒤에** params를 받습니다. 계산 함수는 동기 함수여야 하며 Promise 반환은 오류입니다. 중복 등록 ID, 미등록 ID, Worker 계산 경계의 inline 함수는 오류입니다. Main 콜백 왕복이나 Main 계산 fallback으로 우회하지 않습니다.
30
+
31
+ 다음은 앱에서 빌드할 두 파일의 최소 예입니다. `/worker` entry는 import만으로 설치되지 않으므로 등록 뒤 `installProcessorWorker()`를 호출합니다.
32
+
33
+ ```ts
34
+ // app-grid.worker.ts
35
+ import { DataLoader } from '@vmscloud/moz-ui-grid-core';
36
+ import type { Row } from '@vmscloud/moz-ui-grid-core';
37
+ import { registerWorkerFunctions, installProcessorWorker } from '@vmscloud/moz-ui-grid-core/worker';
38
+
39
+ class AppLoader extends DataLoader {
40
+ async fetchData(): Promise<Row[]> {
41
+ const response = await fetch(String(this.params.url));
42
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
43
+ return response.json();
44
+ }
45
+ }
46
+ registerWorkerFunctions({
47
+ 'app:sum': (values: unknown[], _ctx: unknown, params: { factor: number }) =>
48
+ values.reduce<number>((sum, value) => sum + Number(value), 0) * params.factor,
49
+ });
50
+ installProcessorWorker({ loaders: { 'app:data': AppLoader } });
51
+ ```
52
+
53
+ ```ts
54
+ // 앱 Main — container는 앱이 확보한 HTMLElement
55
+ import { PureSheet } from '@vmscloud/moz-ui-grid-core';
56
+ const grid = new PureSheet(container, {
57
+ keyFields: ['id'],
58
+ useWorker: true,
59
+ workerFactory: () => new Worker(new URL('./app-grid.worker.ts', import.meta.url), { type: 'module' }),
60
+ loader: { module: 'app:data', params: { url: '/api/inventory' } },
61
+ fields: [{ id: 'id' }, { id: 'qty', dataType: 'number' }],
62
+ });
63
+ await grid.waitForReady();
64
+ grid.rows.addPinnedBottom({
65
+ id: 'total', variant: 'grandtotal',
66
+ aggregates: [{ columnId: 'qty', func: { workerFunction: 'app:sum', params: { factor: 1 } } }],
67
+ });
68
+ await grid.refresh();
69
+ ```
70
+
71
+ `LoaderConfig.module`의 타입은 `URL | string`이지만 현재 실행 경로는 그 문자열을 `loaders` map에서 찾습니다. 임의 URL을 동적으로 import하지 않습니다. URL을 쓴다면 등록 키가 그 문자열 표현과 정확히 같아야 합니다. loader 생성자는 `new () => DataLoader`이며 정적으로 import한 클래스를 map에 넣습니다. `workerFactory`는 PureSheet → GridCore → ProcessorFactory로 전달됩니다. Worker에서 직접 데이터를 로드하는 경계를 유지하세요.
72
+
73
+ ### 지원 범위와 미지원
74
+
75
+ | 기능 | 현재 계약 |
76
+ |---|---|
77
+ | custom filter `predicate`, sort `sortKey`, 계산 필드 `formula` | 해당 callback 위치에 WorkerFunctionRef를 사용해 Worker 내부 실행 |
78
+ | 컬럼 `aggregate`, `rowGroupConfig.aggregates[].func`, pinned `aggregates[].func` | Worker 내부 집계. 등록 그룹 함수는 실제 멤버 values와 ctx를 받음. pinned 결과는 Main에서 재계산하지 않음 |
79
+ | custom merge `getMergedRange` / `getMergedRanges` | 등록 참조 지원. pinned merge는 비동기 Worker 결과를 렌더/export 경로에서 사용 |
80
+ | pivot 계산·집계·정렬 | 대응 callback 위치의 등록 참조 지원. 모든 callback property 이름이 동일한 것은 아니므로 각 타입을 따름 |
81
+ | Worker 검색·컬럼 값 수집의 mask formatter | 등록 참조 실행 지원. 내장 mask는 recipe로 전달 |
82
+ | UI 표시 mask | 등록 formatter는 비동기 표시 coordinator를 통해 해석합니다. 표시 결과를 원본 데이터에 쓰지 않습니다. 편집 parser와 표시 formatter의 계약은 구분합니다. |
83
+ | XLSX Worker formatter | processor XLSX session/transport를 통해 등록 함수를 실행합니다. Worker 실행 실패를 Main 계산으로 숨기지 않습니다. |
84
+
85
+ DOM renderer와 일반 UI callback을 Worker 함수로 모두 치환하는 API가 아닙니다. 일반 Main inline 콜백은 유지됩니다.
86
+
87
+ ## Inventory Main 고정 합계 callback
88
+
89
+ `grid.rows.addPinnedBottom({ variant: 'grandtotal', aggregates: [{ columnId, func }] })`의 Main 함수형 집계는 **현재 필터를 통과한 데이터**를 입력으로 사용합니다. native 문자열 집계 cache가 있는 혼합 구성과 custom-only 구성의 범위가 같습니다. `columnId`와 원본 `field`가 달라도 원본 field를 읽습니다.
90
+
91
+ ```ts
92
+ // grid의 fields에는 { id: 'qty', field: 'amount', dataType: 'number' }가 있다고 가정
93
+ const mean = (values: unknown[]) => values.length
94
+ ? values.reduce<number>((sum, value) => sum + Number(value), 0) / values.length
95
+ : 0;
96
+ grid.rows.addPinnedBottom({
97
+ id: 'mean', variant: 'grandtotal',
98
+ aggregates: [{ columnId: 'qty', func: mean }],
99
+ });
100
+ await grid.filter([{ id: 'qty', operator: 'gt', filterValue: 0 }]);
101
+ await grid.refresh();
102
+ ```
103
+
104
+ null/undefined 원소는 callback 입력에서 제외하지만 0은 포함합니다. null-only/빈 필터 결과의 `values`는 빈 배열이며 반환값은 callback이 결정합니다. callback이 반환한 null을 0으로 바꾸지 않으며 소수를 임의 반올림하지 않습니다. `func` 생략 시 컬럼 aggregate를 상속하고 그것도 없으면 sum입니다. CSV/XLSX에 고정행을 포함하려면 Core export의 `includePinnedRows: true`를 사용하세요. 이 절의 필터 범위 계약은 grandtotal에 관한 것으로 모든 subtotal 경로의 동등성까지 주장하지 않습니다.
105
+
106
+ ## 데이터 세션과 설정 재생성
107
+
108
+ ```ts
109
+ // PureSheet의 공개 API
110
+ const token = await oldGrid.captureDataSessionAsync(); // Worker 포함 비동기 capture
111
+ // 같은 keyFields를 가진 호환 새 sheet가 준비된 뒤:
112
+ if (token) await newGrid.restoreDataSession(token); // Promise<void>
113
+ ```
114
+
115
+ 토큰은 같은 런타임의 불투명 메모리 객체입니다. JSON/localStorage 프리셋이 아니며 복제·직렬화하거나 `{ version: 1 }`로 만들어 복원할 수 없습니다. 표시 데이터만 다시 load하는 대신 **원본 baseline, dirty 추가/수정/삭제, 지원 undo/redo 명령과 cursor, 자동 ID, tree config/state**를 이전합니다. `getConfig()`의 layout snapshot과 다릅니다.
116
+
117
+ - live/ready 인스턴스에서만 capture할 수 있습니다. 편집 중이면 commit을 먼저 시도하고 취소/검증 실패로 편집이 남으면 PS906입니다.
118
+ - 진행 중 load/refresh, undo 동기화, 미완료 batch/transaction 등은 capture를 거부할 수 있습니다. 호출한 비동기 API를 직접 await하고 undo/redo 완료 이벤트를 확인하세요. `ready()`는 모든 작업 완료 barrier가 아닙니다.
119
+ - Worker 세션은 `captureDataSessionAsync()`를 사용합니다. pivot 상태도 세션에 포함됩니다. custom 명령은 지원되는 capture/rebind 계약이 필요하며 미지원 history는 거부합니다. 공유 UndoStack의 다른 그리드 명령은 원래 소유자 바인딩을 유지합니다.
120
+ - keyFields 변경은 같은 세션 복원과 호환되지 않습니다. 캡처 뒤 공유 history가 바뀐 stale 토큰도 거부합니다. 표시 행만 load해서 실패를 숨기면 baseline/history가 사라지므로 그런 fallback은 제공하지 않습니다.
121
+
122
+ ### Vue/React handshake
123
+
124
+ 두 어댑터의 `sourceRevision?: unknown`은 **wrapper prop**입니다(coreConfig 안의 키가 아님). 외부 loader 데이터셋이 실제 교체될 때만 바꾸고, 편집이나 일반 화면 설정 변경에는 유지하세요. 비교는 `Object.is`이며 객체를 매번 새로 만들면 교체로 인식합니다.
125
+
126
+ `GridChrome.getReadyContext(): Readonly<GridChromeReadyContext>`:
127
+
128
+ ```ts
129
+ interface GridChromeReadyContext {
130
+ reason: 'initial' | 'configuration' | 'source-replacement';
131
+ dataRestored: boolean;
132
+ sourceRevision?: unknown;
133
+ }
134
+ ```
135
+
136
+ - 일반 런타임 설정은 공통 coordinator가 동일 인스턴스에 적용하며 ready를 다시 발생시키지 않습니다. 실제 인스턴스 교체가 필요한 경로에서만 새 sheet 복원 후 `ready(grid, chrome)` / `onReady(grid, chrome)`를 호출합니다. context는 두 번째 인수에서 읽습니다.
137
+ - 재생성 시 `data`/`loader` 참조 또는 sourceRevision이 바뀌면 source replacement로 간주해 이전 세션 capture를 건너뜁니다. 새 데이터 baseline이며 `dataRestored: false`입니다. dirty를 지우기 위한 우회로로 revision을 올리지 마세요.
138
+ - 실제 같은 소스 인스턴스 교체는 destroy **전에** 비동기 capture합니다. 실패하면 기존 인스턴스를 유지하고 오류를 보고합니다. 공통 coordinator는 추적된 작업 종료를 기다려 최신 설정 요청을 적용하며, 실제 load/validation 실패를 무한 재시도하지 않습니다.
139
+ - 공개 `waitForSettled(signal?)`은 추적된 작업의 종료를 기다립니다. `ready()`와 구분하며 세션 capture의 유효성 검증을 대신하지 않습니다.
140
+ - `restoreReinitState()` 오류는 호출자에게 전파합니다. 실패 뒤 성공 ready를 내보내지 않습니다. restore 전에 dataSession을 포함한 `GridChromeReinitState`를 GridChrome 생성자 네 번째 인수로 전달해야 constructor data/loader bootstrap과 경쟁하지 않습니다. Vue/React 어댑터가 이 순서를 관리합니다.
141
+
142
+ ```ts
143
+ // 두 프레임워크에서 사용할 ready 핸들러의 핵심 (bindEvents/loadOwnedSource는 소비처 함수)
144
+ function handleReady(grid: PureSheet, chrome: GridChrome) {
145
+ bindEvents(grid); // 새 인스턴스이므로 매 ready마다 연결
146
+ const context = chrome.getReadyContext();
147
+ if (context.dataRestored && Object.is(context.sourceRevision, currentSourceRevision)) return;
148
+ // 외부 로더를 소비처가 단독 소유할 때만 실행.
149
+ // coreConfig.data/loader와 중복으로 로드하지 말 것.
150
+ void loadOwnedSource(grid);
151
+ }
152
+ ```
153
+
154
+ 소비처가 복원된 ready마다 다시 loadData/tree reload를 호출하면 baseline/dirty가 덮일 수 있습니다. Fab 같은 외부 로더 화면은 로드 소유자를 하나로 정하고 revision별 초기 로드와 같은 revision의 복원을 구분해야 합니다. 일반 런타임 설정의 동일 인스턴스 적용과 실제 인스턴스 교체의 세션 이전을 구분하세요. 미지원 history를 조용히 버리는 fallback은 제공하지 않습니다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmscloud/moz-ui-grid-vue",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "MozGrid - Vue 3 wrapping library for @vmscloud/moz-ui-grid-core",
5
5
  "license": "ISC",
6
6
  "type": "module",
@@ -80,8 +80,8 @@
80
80
  "build-storybook": "storybook build"
81
81
  },
82
82
  "dependencies": {
83
- "@vmscloud/moz-ui-grid-core": "^0.1.47",
84
- "@vmscloud/moz-ui-grid-wrapper": "^0.1.23",
83
+ "@vmscloud/moz-ui-grid-core": "^0.1.51",
84
+ "@vmscloud/moz-ui-grid-wrapper": "^0.1.24",
85
85
  "bytebuffer": "^5.0.1",
86
86
  "crypto-js": "^4.2.0",
87
87
  "echarts": "^5.5.0",