@simplysm/angular 14.0.19 → 14.0.22

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.
Files changed (143) hide show
  1. package/dist/core/provideSdAngular.js +1 -1
  2. package/dist/core/providers/sd-activated-modal.provider.d.ts +13 -0
  3. package/dist/core/providers/sd-activated-modal.provider.d.ts.map +1 -0
  4. package/dist/core/providers/sd-activated-modal.provider.js +15 -0
  5. package/dist/core/providers/sd-app-structure.provider.d.ts +3 -64
  6. package/dist/core/providers/sd-app-structure.provider.d.ts.map +1 -1
  7. package/dist/core/providers/sd-app-structure.provider.js +1 -252
  8. package/dist/core/providers/sd-app-structure.types.d.ts +52 -0
  9. package/dist/core/providers/sd-app-structure.types.d.ts.map +1 -0
  10. package/dist/core/providers/sd-app-structure.types.js +1 -0
  11. package/dist/core/providers/sd-app-structure.utils.d.ts +13 -0
  12. package/dist/core/providers/sd-app-structure.utils.d.ts.map +1 -0
  13. package/dist/core/providers/sd-app-structure.utils.js +250 -0
  14. package/dist/{ui/overlay/busy → core/providers}/sd-busy.provider.d.ts +1 -1
  15. package/dist/core/providers/sd-busy.provider.d.ts.map +1 -0
  16. package/dist/{ui/overlay/busy → core/providers}/sd-busy.provider.js +1 -1
  17. package/dist/core/providers/sd-print.provider.js +1 -1
  18. package/dist/core/providers/sd-service-client-factory.provider.js +1 -1
  19. package/dist/{ui/overlay/toast → core/providers}/sd-toast.provider.d.ts +1 -1
  20. package/dist/core/providers/sd-toast.provider.d.ts.map +1 -0
  21. package/dist/{ui/overlay/toast → core/providers}/sd-toast.provider.js +3 -3
  22. package/dist/core/types/select-modal-output-result.d.ts +8 -0
  23. package/dist/core/types/select-modal-output-result.d.ts.map +1 -0
  24. package/dist/core/types/select-modal-output-result.js +1 -0
  25. package/dist/core/utils/setups/setupCanDeactivate.js +1 -1
  26. package/dist/core/utils/useViewTitleSignal.js +1 -1
  27. package/dist/core/utils/useViewTypeSignal.js +1 -1
  28. package/dist/features/base/sd-base-container.control.js +1 -1
  29. package/dist/features/data-view/sd-data-detail.control.js +1 -1
  30. package/dist/features/data-view/sd-data-sheet.control.d.ts +24 -37
  31. package/dist/features/data-view/sd-data-sheet.control.d.ts.map +1 -1
  32. package/dist/features/data-view/sd-data-sheet.control.js +98 -152
  33. package/dist/features/data-view/sd-data-sheet.types.d.ts +17 -0
  34. package/dist/features/data-view/sd-data-sheet.types.d.ts.map +1 -0
  35. package/dist/features/data-view/sd-data-sheet.types.js +1 -0
  36. package/dist/{core/utils/setups → features/data-view}/setupCloserWhenSingleSelectionChange.d.ts +1 -1
  37. package/dist/features/data-view/setupCloserWhenSingleSelectionChange.d.ts.map +1 -0
  38. package/dist/features/data-view/useDataSheetExcelManager.d.ts +14 -0
  39. package/dist/features/data-view/useDataSheetExcelManager.d.ts.map +1 -0
  40. package/dist/features/data-view/useDataSheetExcelManager.js +31 -0
  41. package/dist/features/data-view/useDataSheetFilterManager.d.ts +13 -0
  42. package/dist/features/data-view/useDataSheetFilterManager.d.ts.map +1 -0
  43. package/dist/features/data-view/useDataSheetFilterManager.js +19 -0
  44. package/dist/features/data-view/useDataSheetInlineEditManager.d.ts +26 -0
  45. package/dist/features/data-view/useDataSheetInlineEditManager.d.ts.map +1 -0
  46. package/dist/features/data-view/useDataSheetInlineEditManager.js +54 -0
  47. package/dist/features/data-view/useDataSheetModalEditManager.d.ts +19 -0
  48. package/dist/features/data-view/useDataSheetModalEditManager.d.ts.map +1 -0
  49. package/dist/features/data-view/useDataSheetModalEditManager.js +44 -0
  50. package/dist/features/data-view/useDataSheetRefreshManager.d.ts +25 -0
  51. package/dist/features/data-view/useDataSheetRefreshManager.d.ts.map +1 -0
  52. package/dist/features/data-view/useDataSheetRefreshManager.js +50 -0
  53. package/dist/features/permission-table/sd-permission-table.control.d.ts +1 -1
  54. package/dist/features/permission-table/sd-permission-table.control.d.ts.map +1 -1
  55. package/dist/index.d.ts +12 -6
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +10 -5
  58. package/dist/ui/data/sheet/sd-sheet-config.modal.d.ts +1 -2
  59. package/dist/ui/data/sheet/sd-sheet-config.modal.d.ts.map +1 -1
  60. package/dist/ui/data/sheet/sd-sheet-config.modal.js +8 -11
  61. package/dist/ui/data/sheet/sd-sheet.control.d.ts +22 -30
  62. package/dist/ui/data/sheet/sd-sheet.control.d.ts.map +1 -1
  63. package/dist/ui/data/sheet/sd-sheet.control.js +52 -210
  64. package/dist/ui/data/sheet/useSheetCellStyling.d.ts +22 -0
  65. package/dist/ui/data/sheet/useSheetCellStyling.d.ts.map +1 -0
  66. package/dist/ui/data/sheet/useSheetCellStyling.js +95 -0
  67. package/dist/ui/data/sheet/useSheetColumnResizing.d.ts +17 -0
  68. package/dist/ui/data/sheet/useSheetColumnResizing.d.ts.map +1 -0
  69. package/dist/ui/data/sheet/useSheetColumnResizing.js +65 -0
  70. package/dist/ui/data/sheet/useSheetDisplayPipeline.d.ts +24 -0
  71. package/dist/ui/data/sheet/useSheetDisplayPipeline.d.ts.map +1 -0
  72. package/dist/ui/data/sheet/useSheetDisplayPipeline.js +52 -0
  73. package/dist/ui/form/button/sd-modal-select-button.control.d.ts +1 -7
  74. package/dist/ui/form/button/sd-modal-select-button.control.d.ts.map +1 -1
  75. package/dist/ui/form/button/sd-modal-select-button.control.js +1 -1
  76. package/dist/ui/form/choice/sd-state-preset.control.js +1 -1
  77. package/dist/ui/form/select/sd-select.control.d.ts +1 -1
  78. package/dist/ui/form/select/sd-select.control.d.ts.map +1 -1
  79. package/dist/ui/form/select/sd-select.control.js +23 -27
  80. package/dist/ui/layout/sd-gap.control.d.ts +1 -2
  81. package/dist/ui/layout/sd-gap.control.d.ts.map +1 -1
  82. package/dist/ui/layout/sd-gap.control.js +22 -24
  83. package/dist/ui/navigation/menu-utils.d.ts +2 -7
  84. package/dist/ui/navigation/menu-utils.d.ts.map +1 -1
  85. package/dist/ui/overlay/busy/sd-busy-container.control.d.ts +1 -1
  86. package/dist/ui/overlay/busy/sd-busy-container.control.d.ts.map +1 -1
  87. package/dist/ui/overlay/busy/sd-busy-container.control.js +1 -1
  88. package/dist/ui/overlay/modal/sd-confirm-modal.control.d.ts.map +1 -1
  89. package/dist/ui/overlay/modal/sd-confirm-modal.control.js +29 -23
  90. package/dist/ui/overlay/modal/sd-modal.control.js +1 -1
  91. package/dist/ui/overlay/modal/sd-modal.provider.d.ts +0 -10
  92. package/dist/ui/overlay/modal/sd-modal.provider.d.ts.map +1 -1
  93. package/dist/ui/overlay/modal/sd-modal.provider.js +1 -13
  94. package/dist/ui/overlay/modal/sd-prompt-modal.control.d.ts.map +1 -1
  95. package/dist/ui/overlay/modal/sd-prompt-modal.control.js +40 -33
  96. package/dist/ui/overlay/toast/sd-toast.control.d.ts +1 -1
  97. package/dist/ui/overlay/toast/sd-toast.control.d.ts.map +1 -1
  98. package/package.json +5 -5
  99. package/src/core/provideSdAngular.ts +1 -1
  100. package/src/core/providers/sd-activated-modal.provider.ts +12 -0
  101. package/src/core/providers/sd-app-structure.provider.ts +2 -405
  102. package/src/core/providers/sd-app-structure.types.ts +60 -0
  103. package/src/core/providers/sd-app-structure.utils.ts +350 -0
  104. package/src/{ui/overlay/busy → core/providers}/sd-busy.provider.ts +1 -1
  105. package/src/core/providers/sd-print.provider.ts +1 -1
  106. package/src/core/providers/sd-service-client-factory.provider.ts +1 -1
  107. package/src/{ui/overlay/toast → core/providers}/sd-toast.provider.ts +4 -4
  108. package/src/core/types/select-modal-output-result.ts +7 -0
  109. package/src/core/utils/setups/setupCanDeactivate.ts +1 -1
  110. package/src/core/utils/useViewTitleSignal.ts +1 -1
  111. package/src/core/utils/useViewTypeSignal.ts +1 -1
  112. package/src/features/base/sd-base-container.control.ts +1 -1
  113. package/src/features/data-view/sd-data-detail.control.ts +1 -1
  114. package/src/features/data-view/sd-data-sheet.control.ts +117 -216
  115. package/src/features/data-view/sd-data-sheet.types.ts +18 -0
  116. package/src/{core/utils/setups → features/data-view}/setupCloserWhenSingleSelectionChange.ts +1 -1
  117. package/src/features/data-view/useDataSheetExcelManager.ts +57 -0
  118. package/src/features/data-view/useDataSheetFilterManager.ts +30 -0
  119. package/src/features/data-view/useDataSheetInlineEditManager.ts +89 -0
  120. package/src/features/data-view/useDataSheetModalEditManager.ts +76 -0
  121. package/src/features/data-view/useDataSheetRefreshManager.ts +90 -0
  122. package/src/features/permission-table/sd-permission-table.control.ts +1 -1
  123. package/src/index.ts +17 -11
  124. package/src/ui/data/sheet/sd-sheet-config.modal.ts +7 -11
  125. package/src/ui/data/sheet/sd-sheet.control.ts +50 -238
  126. package/src/ui/data/sheet/useSheetCellStyling.ts +113 -0
  127. package/src/ui/data/sheet/useSheetColumnResizing.ts +92 -0
  128. package/src/ui/data/sheet/useSheetDisplayPipeline.ts +64 -0
  129. package/src/ui/form/button/sd-modal-select-button.control.ts +1 -8
  130. package/src/ui/form/choice/sd-state-preset.control.ts +1 -1
  131. package/src/ui/form/select/sd-select.control.ts +21 -26
  132. package/src/ui/layout/sd-gap.control.ts +17 -21
  133. package/src/ui/navigation/menu-utils.ts +3 -7
  134. package/src/ui/overlay/busy/sd-busy-container.control.ts +1 -1
  135. package/src/ui/overlay/modal/sd-confirm-modal.control.ts +8 -26
  136. package/src/ui/overlay/modal/sd-modal.control.ts +1 -1
  137. package/src/ui/overlay/modal/sd-modal.provider.ts +1 -10
  138. package/src/ui/overlay/modal/sd-prompt-modal.control.ts +17 -43
  139. package/src/ui/overlay/toast/sd-toast.control.ts +1 -1
  140. package/dist/core/utils/setups/setupCloserWhenSingleSelectionChange.d.ts.map +0 -1
  141. package/dist/ui/overlay/busy/sd-busy.provider.d.ts.map +0 -1
  142. package/dist/ui/overlay/toast/sd-toast.provider.d.ts.map +0 -1
  143. /package/dist/{core/utils/setups → features/data-view}/setupCloserWhenSingleSelectionChange.js +0 -0
@@ -1,26 +1,26 @@
1
1
  import { NgTemplateOutlet } from "@angular/common";
2
- import { ChangeDetectionStrategy, Component, computed, contentChild, contentChildren, Directive, effect, inject, input, model, output, reflectComponentType, signal, TemplateRef, viewChild, ViewEncapsulation, } from "@angular/core";
3
- import { obj } from "@simplysm/core-common";
2
+ import { ChangeDetectionStrategy, Component, computed, contentChild, contentChildren, Directive, effect, input, model, output, reflectComponentType, signal, TemplateRef, viewChild, ViewEncapsulation, } from "@angular/core";
4
3
  import { mark } from "../../core/utils/mark";
5
4
  import { SdButtonControl } from "../../ui/form/button/sd-button.control";
6
5
  import { SdFormControl } from "../../ui/form/sd-form.control";
7
6
  import { SdSheetColumnDirective } from "../../ui/data/sheet/sd-sheet-column.directive";
8
7
  import { SdSheetControl } from "../../ui/data/sheet/sd-sheet.control";
9
- import { SdFileDialogProvider } from "../../core/providers/sd-file-dialog.provider";
10
- import { SdToastProvider } from "../../ui/overlay/toast/sd-toast.provider";
11
- import { SdSharedDataProvider } from "../../core/providers/sd-shared-data.provider";
12
8
  import { useViewTypeSignal } from "../../core/utils/useViewTypeSignal";
13
9
  import { setupCumulateSelectedKeys } from "../../core/utils/setups/setupCumulateSelectedKeys";
14
- import { setupCloserWhenSingleSelectionChange } from "../../core/utils/setups/setupCloserWhenSingleSelectionChange";
10
+ import { setupCloserWhenSingleSelectionChange } from "./setupCloserWhenSingleSelectionChange";
15
11
  import { setupCanDeactivate } from "../../core/utils/setups/setupCanDeactivate";
16
12
  import { injectParent } from "../../core/utils/injectParent";
17
- import { withBusy } from "../../core/utils/withBusy";
18
13
  import { FormatPipe } from "../../core/pipes/format.pipe";
19
14
  import { TXT_CHANGE_IGNORE_CONFIRM } from "../../core/commons";
20
15
  import { SdBaseContainerControl } from "../base/sd-base-container.control";
21
16
  import { SdDataSheetColumnDirective } from "./sd-data-sheet-column.directive";
22
17
  import { SdAnchorControl } from "../../ui/form/button/sd-anchor.control";
23
18
  import { NgIcon } from "@ng-icons/core";
19
+ import { useDataSheetFilterManager } from "./useDataSheetFilterManager";
20
+ import { useDataSheetRefreshManager } from "./useDataSheetRefreshManager";
21
+ import { useDataSheetInlineEditManager } from "./useDataSheetInlineEditManager";
22
+ import { useDataSheetModalEditManager } from "./useDataSheetModalEditManager";
23
+ import { useDataSheetExcelManager } from "./useDataSheetExcelManager";
24
24
  import { tablerDeviceFloppy, tablerEdit, tablerEraser, tablerCirclePlus, tablerFileExcel, tablerRefresh, tablerRestore, tablerSearch, tablerUpload, } from "@ng-icons/tabler-icons";
25
25
  import * as i0 from "@angular/core";
26
26
  const _c0 = ["pageTopbarTpl"];
@@ -489,16 +489,17 @@ function SdDataSheetControl_Conditional_5_ng_template_2_Template(rf, ctx) { if (
489
489
  function SdDataSheetControl_Conditional_5_Template(rf, ctx) { if (rf & 1) {
490
490
  i0.ɵɵtemplate(0, SdDataSheetControl_Conditional_5_ng_template_0_Template, 5, 3, "ng-template", null, 5, i0.ɵɵtemplateRefExtractor)(2, SdDataSheetControl_Conditional_5_ng_template_2_Template, 2, 2, "ng-template", null, 6, i0.ɵɵtemplateRefExtractor);
491
491
  } }
492
- //#endregion
493
492
  //#region AbsSdDataSheet
494
493
  export class AbsSdDataSheet {
495
494
  hideTool;
496
495
  diffsExcludes;
497
- //-- injected
498
- _sdToast = inject(SdToastProvider);
499
- _sdSharedData = inject(SdSharedDataProvider);
500
- _sdFileDialog = inject(SdFileDialogProvider);
501
- //-- state
496
+ //-- composable instances
497
+ _filterMgr;
498
+ _refreshMgr;
499
+ _inlineEditMgr;
500
+ _modalEditMgr;
501
+ _excelMgr;
502
+ //-- shared state (D1: class 소유)
502
503
  key = reflectComponentType(this.constructor)?.selector;
503
504
  viewType = useViewTypeSignal(() => this);
504
505
  busyCount = signal(0, ...(ngDevMode ? [{ debugName: "busyCount" }] : /* istanbul ignore next */ []));
@@ -518,10 +519,9 @@ export class AbsSdDataSheet {
518
519
  page = signal(0, ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
519
520
  pageLength = signal(0, ...(ngDevMode ? [{ debugName: "pageLength" }] : /* istanbul ignore next */ []));
520
521
  sortingDefs = signal([], ...(ngDevMode ? [{ debugName: "sortingDefs" }] : /* istanbul ignore next */ []));
521
- filter = signal({}, ...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
522
- lastFilter = signal({}, ...(ngDevMode ? [{ debugName: "lastFilter" }] : /* istanbul ignore next */ []));
523
- //-- change tracking
524
- _itemsSnapshot = [];
522
+ //-- filter state (composable에서 생성, 재할당)
523
+ filter;
524
+ lastFilter;
525
525
  //-- computed
526
526
  isSelectedItemsHasDeleted = computed(() => this.selectedItems().some((item) => this.itemPropInfo.isDeleted != null &&
527
527
  item[this.itemPropInfo.isDeleted]), ...(ngDevMode ? [{ debugName: "isSelectedItemsHasDeleted" }] : /* istanbul ignore next */ []));
@@ -545,49 +545,76 @@ export class AbsSdDataSheet {
545
545
  selectMode: () => this.selectMode(),
546
546
  close: this.close,
547
547
  });
548
- effect(() => {
549
- const filter = this.bindFilter();
550
- this.filter.set(filter);
551
- this.lastFilter.set(obj.clone(filter));
548
+ //-- filter composable
549
+ this._filterMgr = useDataSheetFilterManager({
550
+ bindFilter: () => this.bindFilter(),
551
+ busyCount: this.busyCount,
552
+ canUse: () => this.canUse(),
553
+ page: this.page,
554
+ checkIgnoreChanges: () => this.checkIgnoreChanges(),
552
555
  });
553
- effect((onCleanup) => {
554
- this.page();
555
- this.lastFilter();
556
- this.sortingDefs();
557
- this.prepareRefreshEffect?.();
558
- let cancelled = false;
559
- onCleanup(() => {
560
- cancelled = true;
561
- });
562
- queueMicrotask(async () => {
563
- if (cancelled)
564
- return;
565
- if (!this.canUse()) {
566
- this.initialized.set(true);
567
- return;
568
- }
569
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
570
- await this._sdSharedData.wait();
571
- await this.refresh();
572
- }));
573
- this.initialized.set(true);
574
- });
556
+ this.filter = this._filterMgr.filter;
557
+ this.lastFilter = this._filterMgr.lastFilter;
558
+ //-- refresh composable
559
+ this._refreshMgr = useDataSheetRefreshManager({
560
+ busyCount: this.busyCount,
561
+ initialized: this.initialized,
562
+ canUse: () => this.canUse(),
563
+ items: this.items,
564
+ selectedItems: this.selectedItems,
565
+ pageLength: this.pageLength,
566
+ summaryData: this.summaryData,
567
+ page: this.page,
568
+ lastFilter: this.lastFilter,
569
+ sortingDefs: this.sortingDefs,
570
+ getItemInfoFn: (item) => this.getItemInfoFn(item),
571
+ search: (p) => this.search(p),
572
+ prepareRefreshEffect: () => this.prepareRefreshEffect?.(),
573
+ getDiffsExcludes: () => this.diffsExcludes,
574
+ });
575
+ //-- inline edit composable
576
+ this._inlineEditMgr = useDataSheetInlineEditManager({
577
+ busyCount: this.busyCount,
578
+ canEdit: () => this.canEdit(),
579
+ items: this.items,
580
+ submitted: this.submitted,
581
+ itemPropInfo: () => this.itemPropInfo,
582
+ getItemInfoFn: (item) => this.getItemInfoFn(item),
583
+ getDiffs: () => this._refreshMgr.getDiffs(),
584
+ refresh: () => this._refreshMgr.refresh(),
585
+ getNewItemFn: () => this.newItem?.bind(this),
586
+ getSubmitFn: () => this.submit?.bind(this),
587
+ errorMessageFn: (err) => this._getOrmDataEditToastErrorMessage(err),
588
+ });
589
+ //-- modal edit composable
590
+ this._modalEditMgr = useDataSheetModalEditManager({
591
+ busyCount: this.busyCount,
592
+ canEdit: () => this.canEdit(),
593
+ selectedItemKeys: this.selectedItemKeys,
594
+ selectedItems: this.selectedItems,
595
+ close: this.close,
596
+ refresh: () => this._refreshMgr.refresh(),
597
+ getEditItemFn: () => this.editItem?.bind(this),
598
+ getToggleDeleteItemsFn: () => this.toggleDeleteItems?.bind(this),
599
+ errorMessageFn: (err) => this._getOrmDataEditToastErrorMessage(err),
600
+ });
601
+ //-- excel composable
602
+ this._excelMgr = useDataSheetExcelManager({
603
+ busyCount: this.busyCount,
604
+ search: (p) => this.search(p),
605
+ refresh: () => this._refreshMgr.refresh(),
606
+ getDownloadExcelFn: () => this.downloadExcel?.bind(this),
607
+ getUploadExcelFn: () => this.uploadExcel?.bind(this),
608
+ errorMessageFn: (err) => this._getOrmDataEditToastErrorMessage(err),
575
609
  });
576
610
  setupCanDeactivate(() => this.viewType() === "modal" || this.checkIgnoreChanges());
577
611
  }
578
- //-- query
612
+ //-- D2: class 메서드 (커스터마이징 가능)
579
613
  checkIgnoreChanges() {
580
- return this._getDiffs().length === 0 || confirm(TXT_CHANGE_IGNORE_CONFIRM);
614
+ return this._refreshMgr.getDiffs().length === 0 || confirm(TXT_CHANGE_IGNORE_CONFIRM);
581
615
  }
582
616
  doFilterSubmit() {
583
- if (this.busyCount() > 0)
584
- return;
585
- if (!this.canUse())
586
- return;
587
- if (!this.checkIgnoreChanges())
588
- return;
589
- this.page.set(0);
590
- this.lastFilter.set(obj.clone(this.filter()));
617
+ this._filterMgr.doFilterSubmit();
591
618
  }
592
619
  doRefresh() {
593
620
  if (this.busyCount() > 0)
@@ -599,120 +626,39 @@ export class AbsSdDataSheet {
599
626
  mark(this.lastFilter);
600
627
  }
601
628
  async refresh() {
602
- const result = await this.search(true);
603
- this.items.set(result.items);
604
- this._itemsSnapshot = obj.clone(result.items);
605
- this.pageLength.set(result.pageLength ?? 0);
606
- this.summaryData.set(result.summary ?? {});
607
- const selectedKeySet = new Set(this.selectedItems().map((sel) => this.getItemInfoFn(sel).key));
608
- this.selectedItems.set(this.items().filter((item) => selectedKeySet.has(this.getItemInfoFn(item).key)));
629
+ await this._refreshMgr.refresh();
609
630
  }
610
- //-- inline edit
631
+ //-- inline edit (delegated to composable)
611
632
  async doAddItem() {
612
- if (!this.newItem)
613
- return;
614
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
615
- const newItem = await this.newItem();
616
- this.items.update((items) => [newItem, ...items]);
617
- }));
633
+ await this._inlineEditMgr.doAddItem();
618
634
  }
619
635
  async doSubmit(opt) {
620
- if (this.busyCount() > 0)
621
- return;
622
- if (opt?.permCheck && !this.canEdit())
623
- return;
624
- if (!this.submit)
625
- return;
626
- const diffs = this._getDiffs();
627
- if (diffs.length === 0) {
628
- if (!opt?.hideNoChangeMessage) {
629
- this._sdToast.info("변경사항이 없습니다.");
630
- }
631
- return;
632
- }
633
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
634
- const result = await this.submit(diffs);
635
- if (!result)
636
- return;
637
- this._sdToast.success("저장되었습니다.");
638
- await this.refresh();
639
- this.submitted.emit(true);
640
- }, (err) => this._getOrmDataEditToastErrorMessage(err)));
636
+ await this._inlineEditMgr.doSubmit(opt);
641
637
  }
642
638
  doToggleDeleteItem(item) {
643
- if (!this.canEdit())
644
- return;
645
- if (this.itemPropInfo.isDeleted == null)
646
- return;
647
- if (this.getItemInfoFn(item).key == null) {
648
- this.items.update((items) => items.filter((item1) => item1 !== item));
649
- return;
650
- }
651
- item[this.itemPropInfo.isDeleted] = !item[this.itemPropInfo.isDeleted];
652
- mark(this.items);
639
+ this._inlineEditMgr.doToggleDeleteItem(item);
653
640
  }
654
- //-- modal edit
641
+ //-- modal edit (delegated to composable)
655
642
  async doEditItem(item) {
656
- if (!this.editItem)
657
- return;
658
- const result = await this.editItem(item);
659
- if (!result)
660
- return;
661
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
662
- await this.refresh();
663
- }));
643
+ await this._modalEditMgr.doEditItem(item);
664
644
  }
665
645
  async doToggleDeleteItems(del) {
666
- if (!this.canEdit())
667
- return;
668
- if (!this.toggleDeleteItems)
669
- return;
670
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
671
- const result = await this.toggleDeleteItems(del);
672
- if (!result)
673
- return;
674
- await this.refresh();
675
- this._sdToast.success(`${del ? "삭제" : "복구"} 되었습니다.`);
676
- }, (err) => this._getOrmDataEditToastErrorMessage(err)));
677
- }
678
- //-- excel
679
- async doDownloadExcel() {
680
- if (!this.downloadExcel)
681
- return;
682
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
683
- const items = (await this.search(false)).items;
684
- await this.downloadExcel(items);
685
- }));
686
- }
687
- async doUploadExcel() {
688
- if (!this.uploadExcel)
689
- return;
690
- const file = await this._sdFileDialog.showAsync(false, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
691
- if (!file)
692
- return;
693
- await withBusy(this.busyCount, () => this._sdToast.try(async () => {
694
- await this.uploadExcel(file);
695
- await this.refresh();
696
- this._sdToast.success("엑셀 업로드가 완료 되었습니다.");
697
- }, (err) => this._getOrmDataEditToastErrorMessage(err)));
646
+ await this._modalEditMgr.doToggleDeleteItems(del);
698
647
  }
699
- //-- modal selection
700
648
  doModalConfirm() {
701
- this.close.emit({
702
- selectedItemKeys: this.selectedItemKeys(),
703
- selectedItems: this.selectedItems(),
704
- });
649
+ this._modalEditMgr.doModalConfirm();
705
650
  }
706
651
  doModalCancel() {
707
- this.close.emit({
708
- selectedItemKeys: [],
709
- selectedItems: [],
710
- });
652
+ this._modalEditMgr.doModalCancel();
711
653
  }
712
- //-- private
713
- _getDiffs() {
714
- return this.items().oneWayDiffs(this._itemsSnapshot, (item) => this.getItemInfoFn(item).key, this.diffsExcludes ? { excludes: this.diffsExcludes } : undefined).filter((d) => d.type !== "same");
654
+ //-- excel (delegated to composable)
655
+ async doDownloadExcel() {
656
+ await this._excelMgr.doDownloadExcel();
715
657
  }
658
+ async doUploadExcel() {
659
+ await this._excelMgr.doUploadExcel();
660
+ }
661
+ //-- private
716
662
  _getOrmDataEditToastErrorMessage(err) {
717
663
  const message = err instanceof Error ? err.message : String(err);
718
664
  if (message.includes("a parent row: a foreign key constraint") ||
@@ -1174,4 +1120,4 @@ export class SdDataSheetControl {
1174
1120
  `,
1175
1121
  }]
1176
1122
  }], () => [], { formCtrl: [{ type: i0.ViewChild, args: ["formCtrl", { isSignal: true }] }], insertText: [{ type: i0.Input, args: [{ isSignal: true, alias: "insertText", required: false }] }], deleteText: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteText", required: false }] }], restoreText: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreText", required: false }] }], deleteIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteIcon", required: false }] }], restoreIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreIcon", required: false }] }], pageTopbarTplRef: [{ type: i0.ContentChild, args: ["pageTopbarTpl", { ...{ read: TemplateRef }, isSignal: true }] }], prevTplRef: [{ type: i0.ContentChild, args: ["prevTpl", { ...{ read: TemplateRef }, isSignal: true }] }], filterTplRef: [{ type: i0.ContentChild, args: ["filterTpl", { ...{ read: TemplateRef }, isSignal: true }] }], beforeToolTplRef: [{ type: i0.ContentChild, args: ["beforeToolTpl", { ...{ read: TemplateRef }, isSignal: true }] }], toolTplRef: [{ type: i0.ContentChild, args: ["toolTpl", { ...{ read: TemplateRef }, isSignal: true }] }], modalBottomTplRef: [{ type: i0.ContentChild, args: ["modalBottomTpl", { ...{ read: TemplateRef }, isSignal: true }] }], columnControls: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdDataSheetColumnDirective), { isSignal: true }] }], modalActionTplRef: [{ type: i0.ViewChild, args: ["modalActionTpl", { ...{ read: TemplateRef }, isSignal: true }] }] }); })();
1177
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdDataSheetControl, { className: "SdDataSheetControl", filePath: "packages/angular/src/features/data-view/sd-data-sheet.control.ts", lineNumber: 782, forbidOrphanRendering: true }); })();
1123
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SdDataSheetControl, { className: "SdDataSheetControl", filePath: "packages/angular/src/features/data-view/sd-data-sheet.control.ts", lineNumber: 683, forbidOrphanRendering: true }); })();
@@ -0,0 +1,17 @@
1
+ export interface ISdDataSheetItemPropInfo<I> {
2
+ isDeleted: (keyof I & string) | undefined;
3
+ lastModifiedAt: (keyof I & string) | undefined;
4
+ lastModifiedBy: (keyof I & string) | undefined;
5
+ }
6
+ export interface ISdDataSheetItemInfo<K> {
7
+ key: K;
8
+ canSelect: boolean;
9
+ canEdit: boolean;
10
+ canDelete: boolean;
11
+ }
12
+ export interface ISdDataSheetSearchResult<I> {
13
+ items: I[];
14
+ pageLength?: number;
15
+ summary?: Partial<I>;
16
+ }
17
+ //# sourceMappingURL=sd-data-sheet.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sd-data-sheet.types.d.ts","sourceRoot":"","sources":["../../../src/features/data-view/sd-data-sheet.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB,CAAC,CAAC;IACzC,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC;IAC1C,cAAc,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC;IAC/C,cAAc,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,GAAG,EAAE,CAAC,CAAC;IACP,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB,CAAC,CAAC;IACzC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACtB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { type OutputEmitterRef, type Signal } from "@angular/core";
2
- import type { ISelectModalOutputResult } from "../../../ui/form/button/sd-modal-select-button.control";
2
+ import type { ISelectModalOutputResult } from "../../core/types/select-modal-output-result";
3
3
  export declare function setupCloserWhenSingleSelectionChange<TItem, TKey>(options: {
4
4
  selectedItemKeys: Signal<TKey[]>;
5
5
  selectedItems: Signal<TItem[]>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupCloserWhenSingleSelectionChange.d.ts","sourceRoot":"","sources":["../../../src/features/data-view/setupCloserWhenSingleSelectionChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,MAAM,EAAU,MAAM,eAAe,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAE5F,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;IACzE,gBAAgB,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,KAAK,EAAE,gBAAgB,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;CAC1D,GAAG,IAAI,CAoBP"}
@@ -0,0 +1,14 @@
1
+ import { type WritableSignal } from "@angular/core";
2
+ import type { ISdDataSheetSearchResult } from "./sd-data-sheet.types";
3
+ export declare function useDataSheetExcelManager<TItem>(options: {
4
+ busyCount: WritableSignal<number>;
5
+ search: (usePagination: boolean) => Promise<ISdDataSheetSearchResult<TItem>> | ISdDataSheetSearchResult<TItem>;
6
+ refresh: () => Promise<void>;
7
+ getDownloadExcelFn: () => ((items: TItem[]) => Promise<void> | void) | undefined;
8
+ getUploadExcelFn: () => ((file: File) => Promise<void> | void) | undefined;
9
+ errorMessageFn: (err: unknown) => string;
10
+ }): {
11
+ doDownloadExcel: () => Promise<void>;
12
+ doUploadExcel: () => Promise<void>;
13
+ };
14
+ //# sourceMappingURL=useDataSheetExcelManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDataSheetExcelManager.d.ts","sourceRoot":"","sources":["../../../src/features/data-view/useDataSheetExcelManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAU,MAAM,eAAe,CAAC;AAI5D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEtE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE;IACvD,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,CACN,aAAa,EAAE,OAAO,KACnB,OAAO,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;IAChF,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,kBAAkB,EAAE,MAChB,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAC1C,SAAS,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3E,cAAc,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CAC1C;2BAImC,OAAO,CAAC,IAAI,CAAC;yBAYf,OAAO,CAAC,IAAI,CAAC;EAuB9C"}
@@ -0,0 +1,31 @@
1
+ import { inject } from "@angular/core";
2
+ import { SdToastProvider } from "../../core/providers/sd-toast.provider";
3
+ import { SdFileDialogProvider } from "../../core/providers/sd-file-dialog.provider";
4
+ import { withBusy } from "../../core/utils/withBusy";
5
+ export function useDataSheetExcelManager(options) {
6
+ const sdToast = inject(SdToastProvider);
7
+ const sdFileDialog = inject(SdFileDialogProvider);
8
+ async function doDownloadExcel() {
9
+ const downloadExcelFn = options.getDownloadExcelFn();
10
+ if (!downloadExcelFn)
11
+ return;
12
+ await withBusy(options.busyCount, () => sdToast.try(async () => {
13
+ const items = (await options.search(false)).items;
14
+ await downloadExcelFn(items);
15
+ }));
16
+ }
17
+ async function doUploadExcel() {
18
+ const uploadExcelFn = options.getUploadExcelFn();
19
+ if (!uploadExcelFn)
20
+ return;
21
+ const file = await sdFileDialog.showAsync(false, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
22
+ if (!file)
23
+ return;
24
+ await withBusy(options.busyCount, () => sdToast.try(async () => {
25
+ await uploadExcelFn(file);
26
+ await options.refresh();
27
+ sdToast.success("엑셀 업로드가 완료 되었습니다.");
28
+ }, (err) => options.errorMessageFn(err)));
29
+ }
30
+ return { doDownloadExcel, doUploadExcel };
31
+ }
@@ -0,0 +1,13 @@
1
+ import { type Signal, type WritableSignal } from "@angular/core";
2
+ export declare function useDataSheetFilterManager<TFilter extends Record<string, any>>(options: {
3
+ bindFilter: () => TFilter;
4
+ busyCount: Signal<number>;
5
+ canUse: () => boolean;
6
+ page: WritableSignal<number>;
7
+ checkIgnoreChanges: () => boolean;
8
+ }): {
9
+ filter: WritableSignal<TFilter>;
10
+ lastFilter: WritableSignal<TFilter>;
11
+ doFilterSubmit: () => void;
12
+ };
13
+ //# sourceMappingURL=useDataSheetFilterManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDataSheetFilterManager.d.ts","sourceRoot":"","sources":["../../../src/features/data-view/useDataSheetFilterManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAgB,MAAM,eAAe,CAAC;AAG/E,wBAAgB,yBAAyB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;IACtF,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,kBAAkB,EAAE,MAAM,OAAO,CAAC;CACnC;;;0BAU4B,IAAI;EAUhC"}
@@ -0,0 +1,19 @@
1
+ import { linkedSignal } from "@angular/core";
2
+ import { obj } from "@simplysm/core-common";
3
+ export function useDataSheetFilterManager(options) {
4
+ const filter = linkedSignal({ ...(ngDevMode ? { debugName: "filter" } : /* istanbul ignore next */ {}), source: options.bindFilter,
5
+ computation: (f) => f });
6
+ const lastFilter = linkedSignal({ ...(ngDevMode ? { debugName: "lastFilter" } : /* istanbul ignore next */ {}), source: options.bindFilter,
7
+ computation: (f) => obj.clone(f) });
8
+ function doFilterSubmit() {
9
+ if (options.busyCount() > 0)
10
+ return;
11
+ if (!options.canUse())
12
+ return;
13
+ if (!options.checkIgnoreChanges())
14
+ return;
15
+ options.page.set(0);
16
+ lastFilter.set(obj.clone(filter()));
17
+ }
18
+ return { filter, lastFilter, doFilterSubmit };
19
+ }
@@ -0,0 +1,26 @@
1
+ import { type OutputEmitterRef, type WritableSignal } from "@angular/core";
2
+ import type { ArrayOneWayDiffResult } from "@simplysm/core-common";
3
+ import type { ISdDataSheetItemPropInfo } from "./sd-data-sheet.types";
4
+ export declare function useDataSheetInlineEditManager<TItem, TKey>(options: {
5
+ busyCount: WritableSignal<number>;
6
+ canEdit: () => boolean;
7
+ items: WritableSignal<TItem[]>;
8
+ submitted: OutputEmitterRef<boolean>;
9
+ itemPropInfo: () => ISdDataSheetItemPropInfo<TItem>;
10
+ getItemInfoFn: (item: TItem) => {
11
+ key: TKey;
12
+ };
13
+ getDiffs: () => ArrayOneWayDiffResult<TItem>[];
14
+ refresh: () => Promise<void>;
15
+ getNewItemFn: () => (() => Promise<TItem> | TItem) | undefined;
16
+ getSubmitFn: () => ((diffs: ArrayOneWayDiffResult<TItem>[]) => Promise<boolean> | boolean) | undefined;
17
+ errorMessageFn: (err: unknown) => string;
18
+ }): {
19
+ doAddItem: () => Promise<void>;
20
+ doSubmit: (opt?: {
21
+ permCheck?: boolean;
22
+ hideNoChangeMessage?: boolean;
23
+ }) => Promise<void>;
24
+ doToggleDeleteItem: (item: TItem) => void;
25
+ };
26
+ //# sourceMappingURL=useDataSheetInlineEditManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDataSheetInlineEditManager.d.ts","sourceRoot":"","sources":["../../../src/features/data-view/useDataSheetInlineEditManager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAInE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEtE,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;IAClE,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/B,SAAS,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACpD,aAAa,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK;QAAE,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC;IAC9C,QAAQ,EAAE,MAAM,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC;IAC/D,WAAW,EAAE,MACT,CAAC,CAAC,KAAK,EAAE,qBAAqB,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,GACvE,SAAS,CAAC;IACd,cAAc,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CAC1C;qBAG6B,OAAO,CAAC,IAAI,CAAC;qBAYX;QAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,KAAG,OAAO,CAAC,IAAI,CAAC;+BA8BiB,KAAK,KAAG,IAAI;EAe/C"}
@@ -0,0 +1,54 @@
1
+ import { inject, } from "@angular/core";
2
+ import { mark } from "../../core/utils/mark";
3
+ import { SdToastProvider } from "../../core/providers/sd-toast.provider";
4
+ import { withBusy } from "../../core/utils/withBusy";
5
+ export function useDataSheetInlineEditManager(options) {
6
+ const sdToast = inject(SdToastProvider);
7
+ async function doAddItem() {
8
+ const newItemFn = options.getNewItemFn();
9
+ if (!newItemFn)
10
+ return;
11
+ await withBusy(options.busyCount, () => sdToast.try(async () => {
12
+ const newItem = await newItemFn();
13
+ options.items.update((items) => [newItem, ...items]);
14
+ }));
15
+ }
16
+ async function doSubmit(opt) {
17
+ if (options.busyCount() > 0)
18
+ return;
19
+ if (opt?.permCheck && !options.canEdit())
20
+ return;
21
+ const submitFn = options.getSubmitFn();
22
+ if (!submitFn)
23
+ return;
24
+ const diffs = options.getDiffs();
25
+ if (diffs.length === 0) {
26
+ if (!opt?.hideNoChangeMessage) {
27
+ sdToast.info("변경사항이 없습니다.");
28
+ }
29
+ return;
30
+ }
31
+ await withBusy(options.busyCount, () => sdToast.try(async () => {
32
+ const result = await submitFn(diffs);
33
+ if (!result)
34
+ return;
35
+ sdToast.success("저장되었습니다.");
36
+ await options.refresh();
37
+ options.submitted.emit(true);
38
+ }, (err) => options.errorMessageFn(err)));
39
+ }
40
+ function doToggleDeleteItem(item) {
41
+ if (!options.canEdit())
42
+ return;
43
+ const propInfo = options.itemPropInfo();
44
+ if (propInfo.isDeleted == null)
45
+ return;
46
+ if (options.getItemInfoFn(item).key == null) {
47
+ options.items.update((items) => items.filter((item1) => item1 !== item));
48
+ return;
49
+ }
50
+ item[propInfo.isDeleted] = !item[propInfo.isDeleted];
51
+ mark(options.items);
52
+ }
53
+ return { doAddItem, doSubmit, doToggleDeleteItem };
54
+ }
@@ -0,0 +1,19 @@
1
+ import { type OutputEmitterRef, type Signal, type WritableSignal } from "@angular/core";
2
+ import type { ISelectModalOutputResult } from "../../core/types/select-modal-output-result";
3
+ export declare function useDataSheetModalEditManager<TItem, TKey>(options: {
4
+ busyCount: WritableSignal<number>;
5
+ canEdit: () => boolean;
6
+ selectedItemKeys: Signal<TKey[]>;
7
+ selectedItems: Signal<TItem[]>;
8
+ close: OutputEmitterRef<ISelectModalOutputResult<TItem>>;
9
+ refresh: () => Promise<void>;
10
+ getEditItemFn: () => ((item?: TItem) => Promise<boolean | undefined> | boolean | undefined) | undefined;
11
+ getToggleDeleteItemsFn: () => ((del: boolean) => Promise<boolean>) | undefined;
12
+ errorMessageFn: (err: unknown) => string;
13
+ }): {
14
+ doEditItem: (item?: TItem) => Promise<void>;
15
+ doToggleDeleteItems: (del: boolean) => Promise<void>;
16
+ doModalConfirm: () => void;
17
+ doModalCancel: () => void;
18
+ };
19
+ //# sourceMappingURL=useDataSheetModalEditManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDataSheetModalEditManager.d.ts","sourceRoot":"","sources":["../../../src/features/data-view/useDataSheetModalEditManager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,MAAM,EACX,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAE5F,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;IACjE,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/B,KAAK,EAAE,gBAAgB,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,aAAa,EAAE,MACX,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC,GACtE,SAAS,CAAC;IACd,sBAAsB,EAAE,MACpB,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GACpC,SAAS,CAAC;IACd,cAAc,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CAC1C;wBAGkC,KAAK,KAAG,OAAO,CAAC,IAAI,CAAC;+BAcd,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC;0BAmBpC,IAAI;yBAOL,IAAI;EAQ/B"}
@@ -0,0 +1,44 @@
1
+ import { inject, } from "@angular/core";
2
+ import { SdToastProvider } from "../../core/providers/sd-toast.provider";
3
+ import { withBusy } from "../../core/utils/withBusy";
4
+ export function useDataSheetModalEditManager(options) {
5
+ const sdToast = inject(SdToastProvider);
6
+ async function doEditItem(item) {
7
+ const editItemFn = options.getEditItemFn();
8
+ if (!editItemFn)
9
+ return;
10
+ const result = await editItemFn(item);
11
+ if (!result)
12
+ return;
13
+ await withBusy(options.busyCount, () => sdToast.try(async () => {
14
+ await options.refresh();
15
+ }));
16
+ }
17
+ async function doToggleDeleteItems(del) {
18
+ if (!options.canEdit())
19
+ return;
20
+ const toggleDeleteItemsFn = options.getToggleDeleteItemsFn();
21
+ if (!toggleDeleteItemsFn)
22
+ return;
23
+ await withBusy(options.busyCount, () => sdToast.try(async () => {
24
+ const result = await toggleDeleteItemsFn(del);
25
+ if (!result)
26
+ return;
27
+ await options.refresh();
28
+ sdToast.success(`${del ? "삭제" : "복구"} 되었습니다.`);
29
+ }, (err) => options.errorMessageFn(err)));
30
+ }
31
+ function doModalConfirm() {
32
+ options.close.emit({
33
+ selectedItemKeys: options.selectedItemKeys(),
34
+ selectedItems: options.selectedItems(),
35
+ });
36
+ }
37
+ function doModalCancel() {
38
+ options.close.emit({
39
+ selectedItemKeys: [],
40
+ selectedItems: [],
41
+ });
42
+ }
43
+ return { doEditItem, doToggleDeleteItems, doModalConfirm, doModalCancel };
44
+ }
@@ -0,0 +1,25 @@
1
+ import { type Signal, type WritableSignal } from "@angular/core";
2
+ import { type ArrayOneWayDiffResult } from "@simplysm/core-common";
3
+ import type { ISdDataSheetSearchResult } from "./sd-data-sheet.types";
4
+ export declare function useDataSheetRefreshManager<TItem, TKey extends string | number | undefined>(options: {
5
+ busyCount: WritableSignal<number>;
6
+ initialized: WritableSignal<boolean>;
7
+ canUse: () => boolean;
8
+ items: WritableSignal<TItem[]>;
9
+ selectedItems: WritableSignal<TItem[]>;
10
+ pageLength: WritableSignal<number>;
11
+ summaryData: WritableSignal<Partial<TItem>>;
12
+ page: Signal<number>;
13
+ lastFilter: Signal<unknown>;
14
+ sortingDefs: Signal<unknown[]>;
15
+ getItemInfoFn: (item: TItem) => {
16
+ key: TKey;
17
+ };
18
+ search: (usePagination: boolean) => Promise<ISdDataSheetSearchResult<TItem>> | ISdDataSheetSearchResult<TItem>;
19
+ prepareRefreshEffect?: () => void;
20
+ getDiffsExcludes: () => string[] | undefined;
21
+ }): {
22
+ refresh: () => Promise<void>;
23
+ getDiffs: () => ArrayOneWayDiffResult<TItem>[];
24
+ };
25
+ //# sourceMappingURL=useDataSheetRefreshManager.d.ts.map