ngx-thin-admin 0.0.0-alpha.6 → 0.0.0-alpha.7

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.
@@ -228,6 +228,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
228
228
  ], template: "<h2 mat-dialog-title>{{ data.title }}</h2>\n<mat-dialog-content>\n {{ data.message }}\n</mat-dialog-content>\n<mat-dialog-actions>\n <button class=\"cancel-btn\" matButton [mat-dialog-close]=\"undefined\">\n {{ data.cancelButtonText || t('common.cancel') }}\n </button>\n <button matButton [mat-dialog-close]=\"true\" cdkFocusInitial>\n {{ data.positiveButtonText || t('common.ok') }}\n </button>\n</mat-dialog-actions>\n", styles: [".cancel-btn{--mat-button-text-label-text-color: #333}\n"] }]
229
229
  }] });
230
230
 
231
+ function getErrorMessage(error) {
232
+ if (typeof error === 'string') {
233
+ return error;
234
+ }
235
+ else if (error instanceof Error) {
236
+ return error.message;
237
+ }
238
+ else if (error?.error?.message) {
239
+ if (Array.isArray(error.error.message)) {
240
+ return error.error.message[0];
241
+ }
242
+ else {
243
+ return error.error.message;
244
+ }
245
+ }
246
+ else {
247
+ return 'An unknown error occurred';
248
+ }
249
+ }
250
+
231
251
  class ListCategorySelector {
232
252
  /**
233
253
  * Config for the category selector
@@ -286,7 +306,11 @@ class ListCategorySelector {
286
306
  }
287
307
  // Call the category creator function
288
308
  try {
289
- await this.config.creator(categoryLabel);
309
+ const res = await this.config.creator(categoryLabel);
310
+ if (res && 'ok' in res && !res.ok) {
311
+ const errorMessage = getErrorMessage(res);
312
+ throw new Error(errorMessage);
313
+ }
290
314
  }
291
315
  catch (e) {
292
316
  this.snackbar.open(`Error: ${e?.message ?? this.t('category.errorCouldNotCreate', { categoryType: this.config.singularLabel ?? this.t('category.defaultSingular') })}`, undefined, {
@@ -310,7 +334,11 @@ class ListCategorySelector {
310
334
  }
311
335
  // Call the category updater function
312
336
  try {
313
- await this.config.updater(category);
337
+ const res = await this.config.updater(category);
338
+ if (res && 'ok' in res && !res.ok) {
339
+ const errorMessage = getErrorMessage(res);
340
+ throw new Error(errorMessage);
341
+ }
314
342
  }
315
343
  catch (e) {
316
344
  this.snackbar.open(`Error: ${e?.message ??
@@ -338,7 +366,11 @@ class ListCategorySelector {
338
366
  }
339
367
  // Call the category deleter function
340
368
  try {
341
- await this.config.deleter(category);
369
+ const res = await this.config.deleter(category);
370
+ if (res && 'ok' in res && !res.ok) {
371
+ const errorMessage = getErrorMessage(res);
372
+ throw new Error(errorMessage);
373
+ }
342
374
  }
343
375
  catch (e) {
344
376
  this.snackbar.open(`Error: ${e?.message ??
@@ -743,26 +775,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
743
775
  ], template: "<h2 mat-dialog-title>\n {{\n t('item.changeCategoryDialogTitle', {\n categoryType: data.categorySelectorConfig.singularLabel || t('category.defaultSingular'),\n })\n }}\n</h2>\n\n<mat-dialog-content>\n @if (data.itemLabel) {\n <p style=\"margin-top: 5px; margin-bottom: 1rem\">\n {{\n t('item.changeCategoryDialogMessage', {\n label: data.itemLabel,\n categoryType: data.categorySelectorConfig.singularLabel || t('category.defaultSingular'),\n })\n }}\n </p>\n }\n\n <mat-form-field appearance=\"outline\" style=\"width: 100%; margin-top: 10px\">\n <mat-label>{{\n data.categorySelectorConfig.singularLabel || t('category.defaultSingular')\n }}</mat-label>\n <mat-select [(ngModel)]=\"selectedCategoryId\" [disabled]=\"isLoading\">\n <mat-option [value]=\"undefined\">{{ t('category.unselected') }}</mat-option>\n @for (category of categories; track category.id) {\n <mat-option [value]=\"category.id\">{{ category.label }}</mat-option>\n }\n </mat-select>\n @if (isLoading) {\n <mat-spinner matSuffix diameter=\"20\" style=\"margin-right: 12px\"></mat-spinner>\n }\n </mat-form-field>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n @if (data.categorySelectorConfig.creator) {\n <button mat-button (click)=\"createNewCategory()\" [disabled]=\"isLoading\">\n <mat-icon style=\"margin-right: 4px; font-size: 1.2rem; width: 1.2rem; height: 1.2rem\"\n >add</mat-icon\n >\n <span>{{ t('common.create') }}</span>\n </button>\n }\n\n <span style=\"flex: 1\"></span>\n\n <button mat-button mat-dialog-close>\n {{ data.cancelButtonText || t('common.cancel') }}\n </button>\n <button mat-flat-button color=\"primary\" (click)=\"save()\" [disabled]=\"isLoading\">\n {{ data.positiveButtonText || t('common.save') }}\n </button>\n</mat-dialog-actions>\n" }]
744
776
  }] });
745
777
 
746
- function getErrorMessage(error) {
747
- if (typeof error === 'string') {
748
- return error;
749
- }
750
- else if (error instanceof Error) {
751
- return error.message;
752
- }
753
- else if (error?.error?.message) {
754
- if (Array.isArray(error.error.message)) {
755
- return error.error.message[0];
756
- }
757
- else {
758
- return error.error.message;
759
- }
760
- }
761
- else {
762
- return 'An unknown error occurred';
763
- }
764
- }
765
-
766
778
  class NgxThinAdminList {
767
779
  /**
768
780
  * Config for list
@@ -821,6 +833,10 @@ class NgxThinAdminList {
821
833
  * Template for cells
822
834
  */
823
835
  cellTplWithLink;
836
+ /**
837
+ * Category Selector
838
+ */
839
+ categorySelector;
824
840
  /**
825
841
  * Services
826
842
  */
@@ -1030,7 +1046,11 @@ class NgxThinAdminList {
1030
1046
  const newCategoryId = result.categoryId;
1031
1047
  const categoryType = this.categorySelectorConfig.singularLabel || this.t('category.defaultSingular');
1032
1048
  try {
1033
- await this.listConfig.categoryChanger(id, newCategoryId);
1049
+ const res = await this.listConfig.categoryChanger(id, newCategoryId);
1050
+ if (res && 'ok' in res && !res.ok) {
1051
+ const errorMessage = getErrorMessage(res);
1052
+ throw new Error(errorMessage);
1053
+ }
1034
1054
  }
1035
1055
  catch (e) {
1036
1056
  const errorMessage = getErrorMessage(e);
@@ -1040,10 +1060,12 @@ class NgxThinAdminList {
1040
1060
  this.snackbar.open(this.t('item.successCategoryChanged', { label, categoryType }), undefined, {
1041
1061
  duration: 3000,
1042
1062
  });
1063
+ // Refresh the list and category selector
1043
1064
  this.fetchList();
1065
+ this.categorySelector?.fetchCategories();
1044
1066
  }
1045
1067
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: NgxThinAdminList, deps: [], target: i0.ɵɵFactoryTarget.Component });
1046
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: NgxThinAdminList, isStandalone: true, selector: "ngx-thin-admin-list", inputs: { listConfig: "listConfig", categorySelectorConfig: "categorySelectorConfig", itemDeleterConfig: "itemDeleterConfig", listColumns: "listColumns", query: "query" }, viewQueries: [{ propertyName: "cellTplWithLink", first: true, predicate: ["cellTplWithLink"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Category Selector -->\n@if (categorySelectorConfig) {\n <lib-list-category-selector\n [config]=\"categorySelectorConfig\"\n [(selectedCategory)]=\"selectedCategory\"\n (selectedCategoryChange)=\"onSelectedCategoryChange($event)\"\n ></lib-list-category-selector>\n}\n<!---->\n\n<!-- Toolbar Template -->\n<ng-template #toolbarTpl>\n <div class=\"custom-toolbar\">\n <!-- List Title -->\n <span class=\"list-title\">\n @if (listConfig?.title; as listTitle) {\n @if (query.keyword || query.categoryId) {\n <!-- Title (with link for reset filter) -->\n <a\n href=\"javascript:void(0)\"\n (click)=\"query.keyword = ''; query.categoryId = undefined; this.fetchList()\"\n [matTooltip]=\"t('list.clearFilters')\"\n >{{ listTitle }}</a\n >\n <!---->\n } @else {\n <!-- Title -->\n {{ listTitle }}\n <!---->\n }\n } @else {\n <!-- Default Title -->\n {{ t('list.defaultTitle') }}\n <!---->\n }\n\n @if (query.categoryId && selectedCategory?.[0]; as categoryLabel) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Category -->\n {{ categoryLabel.label }}\n <!---->\n }\n\n @if (query.keyword) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Keyword -->\n \"{{ query.keyword }}\"\n <!---->\n }\n </span>\n <!---->\n\n @if (query.keyword || query.categoryId) {\n <span style=\"width: 8px\"></span>\n <!-- Clear Filters Button -->\n <button\n mat-icon-button\n class=\"clear-filters-button\"\n [matTooltip]=\"t('list.clearFilters')\"\n (click)=\"clearFilters()\"\n >\n <mat-icon>filter_alt_off</mat-icon>\n </button>\n <!---->\n }\n\n <span style=\"flex: 1\"></span>\n\n <!-- Create Button -->\n @if (listConfig?.createButton; as createBtn) {\n @if ($any(createBtn).routerLink; as routerLinkUrl) {\n <!-- Create Button with Router Link -->\n <a\n [routerLink]=\"routerLinkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).link; as linkUrl) {\n <!-- Create Button with Link -->\n <a\n [href]=\"linkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).click; as handler) {\n <!-- Create Button with Handler -->\n <button\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n (click)=\"handler()\"\n >\n {{ createBtn?.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </button>\n }\n }\n <!---->\n\n <span style=\"width: 30px\"></span>\n\n <!-- Search Field -->\n <mat-form-field class=\"search-keyword xs-input\" appearance=\"outline\">\n <mat-icon matPrefix>search</mat-icon>\n <input\n matInput\n [placeholder]=\"\n selectedCategory?.[0]?.label\n ? t('list.searchInCategoryPlaceholder', { category: selectedCategory?.[0]?.label })\n : t('list.searchDefaultPlaceholder')\n \"\n [(ngModel)]=\"query.keyword\"\n (keyup)=\"onKeywordInput()\"\n style=\"padding-top: 3px\"\n />\n\n <!-- Search clear button -->\n <button\n matSuffix\n mat-icon-button\n [attr.aria-label]=\"t('list.clearSearchKeyword')\"\n [matTooltip]=\"t('list.clearSearchKeyword')\"\n (click)=\"query.keyword = ''; this.fetchList()\"\n [style.visibility]=\"query.keyword ? 'visible' : 'hidden'\"\n >\n <mat-icon>highlight_off</mat-icon>\n </button>\n <!---->\n </mat-form-field>\n <!---->\n\n <span style=\"width: 8px\"></span>\n\n <!-- Refresh Button -->\n <button mat-icon-button [matTooltip]=\"t('list.refresh')\" (click)=\"fetchList()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <!---->\n\n <span style=\"width: 5px\"></span>\n\n <!-- CSV Export Button -->\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"csvExportMenu\"\n [matTooltip]=\"t('list.exportAsCsv')\"\n >\n <mat-icon>download</mat-icon>\n </button>\n <!---->\n\n <!-- CSV Export Menu -->\n <mat-menu #csvExportMenu=\"matMenu\">\n @for (encoder of csvExportService.getAvailableEncoders(); track encoder.key) {\n <!-- Export with specific charset -->\n <p style=\"color: #333; font-size: 0.8rem; margin: 1rem 0.75rem 1rem 0.7rem\">\n CSV ({{ encoder.label }})\n </p>\n <button mat-menu-item (click)=\"exportAsCsv(encoder.key)\">\n <mat-icon>download</mat-icon>\n <span>{{ t('list.exportItems', { count: totalCount }) }}</span>\n </button>\n <!---->\n }\n </mat-menu>\n <!---->\n </div>\n</ng-template>\n<!---->\n\n<!-- List (Grid) -->\n<mtx-grid\n [data]=\"gridData\"\n [columns]=\"gridColumns\"\n [showToolbar]=\"true\"\n [toolbarTemplate]=\"toolbarTpl\"\n [length]=\"totalCount\"\n [loading]=\"isLoading\"\n [pageOnFront]=\"false\"\n [pageIndex]=\"query.page\"\n [pageSize]=\"query.perPage\"\n [pageSizeOptions]=\"listConfig?.pageSizes ?? [10, 25, 50, 100]\"\n columnMenuButtonType=\"icon\"\n columnMenuButtonClass=\"column-menu-button\"\n columnMenuButtonIcon=\"view_column\"\n (page)=\"onPageChange($event)\"\n></mtx-grid>\n<!---->\n\n<!-- Cell Template with Link -->\n<ng-template #cellTplWithLink let-row let-index=\"index\" let-col=\"colDef\">\n @if (col.link) {\n <a [href]=\"col.link(row)\">\n {{ row[col.field] }}\n </a>\n } @else if (col.routerLink) {\n <a [routerLink]=\"col.routerLink(row)\">\n {{ row[col.field] }}\n </a>\n } @else {\n {{ row[col.field] }}\n }\n</ng-template>\n<!---->\n", styles: [":host{display:flex;gap:1rem;padding:1rem;box-sizing:border-box}lib-list-category-selector{display:block;width:200px;background-color:#fcfcfc;border-radius:9px;padding:.5rem;box-sizing:border-box}lib-list-category-selector .category-list{max-height:300px;overflow-y:auto}::ng-deep .mtx-grid-toolbar{display:block;background-color:#fcfcfc;border-top-left-radius:9px;border-top-right-radius:9px;margin-bottom:1px}::ng-deep .mtx-grid-toolbar .custom-toolbar{display:flex;align-items:center;justify-content:space-between;height:37px}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title{font-size:1rem;line-height:37px}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title a{color:var(--mat-theme-primary)}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title a:hover{text-decoration:underline}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title .list-title-separator{color:#aaa;vertical-align:middle;margin:auto .2rem 4px}::ng-deep .mtx-grid-toolbar .custom-toolbar .clear-filters-button{color:var(--mat-sys-on-primary-container);min-width:32px;padding:0;vertical-align:middle}::ng-deep .mtx-grid-toolbar .custom-toolbar .clear-filters-button mat-icon{vertical-align:middle;margin-bottom:3px}::ng-deep .mtx-grid-toolbar .custom-toolbar .create-item-button{text-decoration:none!important}::ng-deep .mtx-grid-toolbar .custom-toolbar .search-keyword{width:15rem;--mat-form-field-container-height: 18.5px;--mat-form-field-container-text-line-height: 18.5px;--mat-form-field-container-vertical-padding: 8.5px;--mat-form-field-outlined-container-shape: 28px;--mat-form-field-subscript-text-line-height: 0px}::ng-deep .mtx-grid-toolbar .custom-toolbar button{color:var(--mat-sys-on-primary-container)}::ng-deep .mtx-grid-toolbar ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mtx-grid-toolbar ::ng-deep mtx-grid-column-menu button[mat-icon-button]{color:var(--mat-sys-on-primary-container);margin-right:.5rem}::ng-deep .mtx-grid-main{background-color:#fcfcfc}table{width:100%}::ng-deep table thead,::ng-deep table tbody{background-color:#fcfcfc!important}::ng-deep .mtx-grid-footer,::ng-deep .mat-mdc-paginator{display:block;background-color:#fcfcfc!important;border-bottom-left-radius:9px!important;border-bottom-right-radius:9px!important}a,::ng-deep table a,::ng-deep table a:visited{color:var(--mat-sys-on-primary-container);text-decoration:none}a:hover,::ng-deep table a:hover,::ng-deep table a:visited:hover{text-decoration:underline}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MtxGridModule }, { kind: "component", type: i2$2.MtxGrid, selector: "mtx-grid", inputs: ["displayedColumns", "columns", "data", "length", "loading", "trackBy", "columnResizable", "emptyValuePlaceholder", "pageOnFront", "showPaginator", "pageDisabled", "showFirstLastButtons", "pageIndex", "pageSize", "pageSizeOptions", "hidePageSize", "paginationTemplate", "sortOnFront", "sortActive", "sortDirection", "sortDisableClear", "sortDisabled", "sortStart", "rowHover", "rowStriped", "expandable", "expansionTemplate", "multiSelectable", "multiSelectionWithClick", "rowSelectable", "hideRowSelectionCheckbox", "disableRowClickSelection", "rowSelectionFormatter", "rowClassFormatter", "rowSelected", "cellSelectable", "showToolbar", "toolbarTitle", "toolbarTemplate", "columnHideable", "columnHideableChecked", "columnSortable", "columnPinnable", "columnPinOptions", "showColumnMenuButton", "columnMenuButtonText", "columnMenuButtonType", "columnMenuButtonColor", "columnMenuButtonClass", "columnMenuButtonIcon", "columnMenuButtonFontIcon", "columnMenuButtonSvgIcon", "showColumnMenuHeader", "columnMenuHeaderText", "columnMenuHeaderTemplate", "showColumnMenuFooter", "columnMenuFooterText", "columnMenuFooterTemplate", "noResultText", "noResultTemplate", "headerTemplate", "headerExtraTemplate", "cellTemplate", "useContentRowTemplate", "useContentHeaderRowTemplate", "useContentFooterRowTemplate", "showSummary", "summaryTemplate", "showSidebar", "sidebarTemplate", "showStatusbar", "statusbarTemplate"], outputs: ["page", "sortChange", "rowClick", "rowContextMenu", "expansionChange", "rowSelectedChange", "cellSelectedChange", "columnChange"], exportAs: ["mtxGrid"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: ListCategorySelector, selector: "lib-list-category-selector", inputs: ["config", "selectedCategory"], outputs: ["selectedCategoryChange"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
1068
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: NgxThinAdminList, isStandalone: true, selector: "ngx-thin-admin-list", inputs: { listConfig: "listConfig", categorySelectorConfig: "categorySelectorConfig", itemDeleterConfig: "itemDeleterConfig", listColumns: "listColumns", query: "query" }, viewQueries: [{ propertyName: "cellTplWithLink", first: true, predicate: ["cellTplWithLink"], descendants: true, static: true }, { propertyName: "categorySelector", first: true, predicate: ListCategorySelector, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Category Selector -->\n@if (categorySelectorConfig) {\n <lib-list-category-selector\n [config]=\"categorySelectorConfig\"\n [(selectedCategory)]=\"selectedCategory\"\n (selectedCategoryChange)=\"onSelectedCategoryChange($event)\"\n ></lib-list-category-selector>\n}\n<!---->\n\n<!-- Toolbar Template -->\n<ng-template #toolbarTpl>\n <div class=\"custom-toolbar\">\n <!-- List Title -->\n <span class=\"list-title\">\n @if (listConfig?.title; as listTitle) {\n @if (query.keyword || query.categoryId) {\n <!-- Title (with link for reset filter) -->\n <a\n href=\"javascript:void(0)\"\n (click)=\"query.keyword = ''; query.categoryId = undefined; this.fetchList()\"\n [matTooltip]=\"t('list.clearFilters')\"\n >{{ listTitle }}</a\n >\n <!---->\n } @else {\n <!-- Title -->\n {{ listTitle }}\n <!---->\n }\n } @else {\n <!-- Default Title -->\n {{ t('list.defaultTitle') }}\n <!---->\n }\n\n @if (query.categoryId && selectedCategory?.[0]; as categoryLabel) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Category -->\n {{ categoryLabel.label }}\n <!---->\n }\n\n @if (query.keyword) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Keyword -->\n \"{{ query.keyword }}\"\n <!---->\n }\n </span>\n <!---->\n\n @if (query.keyword || query.categoryId) {\n <span style=\"width: 8px\"></span>\n <!-- Clear Filters Button -->\n <button\n mat-icon-button\n class=\"clear-filters-button\"\n [matTooltip]=\"t('list.clearFilters')\"\n (click)=\"clearFilters()\"\n >\n <mat-icon>filter_alt_off</mat-icon>\n </button>\n <!---->\n }\n\n <span style=\"flex: 1\"></span>\n\n <!-- Create Button -->\n @if (listConfig?.createButton; as createBtn) {\n @if ($any(createBtn).routerLink; as routerLinkUrl) {\n <!-- Create Button with Router Link -->\n <a\n [routerLink]=\"routerLinkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).link; as linkUrl) {\n <!-- Create Button with Link -->\n <a\n [href]=\"linkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).click; as handler) {\n <!-- Create Button with Handler -->\n <button\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n (click)=\"handler()\"\n >\n {{ createBtn?.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </button>\n }\n }\n <!---->\n\n <span style=\"width: 30px\"></span>\n\n <!-- Search Field -->\n <mat-form-field class=\"search-keyword xs-input\" appearance=\"outline\">\n <mat-icon matPrefix>search</mat-icon>\n <input\n matInput\n [placeholder]=\"\n selectedCategory?.[0]?.label\n ? t('list.searchInCategoryPlaceholder', { category: selectedCategory?.[0]?.label })\n : t('list.searchDefaultPlaceholder')\n \"\n [(ngModel)]=\"query.keyword\"\n (keyup)=\"onKeywordInput()\"\n style=\"padding-top: 3px\"\n />\n\n <!-- Search clear button -->\n <button\n matSuffix\n mat-icon-button\n [attr.aria-label]=\"t('list.clearSearchKeyword')\"\n [matTooltip]=\"t('list.clearSearchKeyword')\"\n (click)=\"query.keyword = ''; this.fetchList()\"\n [style.visibility]=\"query.keyword ? 'visible' : 'hidden'\"\n >\n <mat-icon>highlight_off</mat-icon>\n </button>\n <!---->\n </mat-form-field>\n <!---->\n\n <span style=\"width: 8px\"></span>\n\n <!-- Refresh Button -->\n <button mat-icon-button [matTooltip]=\"t('list.refresh')\" (click)=\"fetchList()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <!---->\n\n <span style=\"width: 5px\"></span>\n\n <!-- CSV Export Button -->\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"csvExportMenu\"\n [matTooltip]=\"t('list.exportAsCsv')\"\n >\n <mat-icon>download</mat-icon>\n </button>\n <!---->\n\n <!-- CSV Export Menu -->\n <mat-menu #csvExportMenu=\"matMenu\">\n @for (encoder of csvExportService.getAvailableEncoders(); track encoder.key) {\n <!-- Export with specific charset -->\n <p style=\"color: #333; font-size: 0.8rem; margin: 1rem 0.75rem 1rem 0.7rem\">\n CSV ({{ encoder.label }})\n </p>\n <button mat-menu-item (click)=\"exportAsCsv(encoder.key)\">\n <mat-icon>download</mat-icon>\n <span>{{ t('list.exportItems', { count: totalCount }) }}</span>\n </button>\n <!---->\n }\n </mat-menu>\n <!---->\n </div>\n</ng-template>\n<!---->\n\n<!-- List (Grid) -->\n<mtx-grid\n [data]=\"gridData\"\n [columns]=\"gridColumns\"\n [showToolbar]=\"true\"\n [toolbarTemplate]=\"toolbarTpl\"\n [length]=\"totalCount\"\n [loading]=\"isLoading\"\n [pageOnFront]=\"false\"\n [pageIndex]=\"query.page\"\n [pageSize]=\"query.perPage\"\n [pageSizeOptions]=\"listConfig?.pageSizes ?? [10, 25, 50, 100]\"\n columnMenuButtonType=\"icon\"\n columnMenuButtonClass=\"column-menu-button\"\n columnMenuButtonIcon=\"view_column\"\n (page)=\"onPageChange($event)\"\n></mtx-grid>\n<!---->\n\n<!-- Cell Template with Link -->\n<ng-template #cellTplWithLink let-row let-index=\"index\" let-col=\"colDef\">\n @if (col.link) {\n <a [href]=\"col.link(row)\">\n {{ row[col.field] }}\n </a>\n } @else if (col.routerLink) {\n <a [routerLink]=\"col.routerLink(row)\">\n {{ row[col.field] }}\n </a>\n } @else {\n {{ row[col.field] }}\n }\n</ng-template>\n<!---->\n", styles: [":host{display:flex;gap:1rem;padding:1rem;box-sizing:border-box}lib-list-category-selector{display:block;width:200px;background-color:#fcfcfc;border-radius:9px;padding:.5rem;box-sizing:border-box}lib-list-category-selector .category-list{max-height:300px;overflow-y:auto}::ng-deep .mtx-grid-toolbar{display:block;background-color:#fcfcfc;border-top-left-radius:9px;border-top-right-radius:9px;margin-bottom:1px}::ng-deep .mtx-grid-toolbar .custom-toolbar{display:flex;align-items:center;justify-content:space-between;height:37px}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title{font-size:1rem;line-height:37px}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title a{color:var(--mat-theme-primary)}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title a:hover{text-decoration:underline}::ng-deep .mtx-grid-toolbar .custom-toolbar .list-title .list-title-separator{color:#aaa;vertical-align:middle;margin:auto .2rem 4px}::ng-deep .mtx-grid-toolbar .custom-toolbar .clear-filters-button{color:var(--mat-sys-on-primary-container);min-width:32px;padding:0;vertical-align:middle}::ng-deep .mtx-grid-toolbar .custom-toolbar .clear-filters-button mat-icon{vertical-align:middle;margin-bottom:3px}::ng-deep .mtx-grid-toolbar .custom-toolbar .create-item-button{text-decoration:none!important}::ng-deep .mtx-grid-toolbar .custom-toolbar .search-keyword{width:15rem;--mat-form-field-container-height: 18.5px;--mat-form-field-container-text-line-height: 18.5px;--mat-form-field-container-vertical-padding: 8.5px;--mat-form-field-outlined-container-shape: 28px;--mat-form-field-subscript-text-line-height: 0px}::ng-deep .mtx-grid-toolbar .custom-toolbar button{color:var(--mat-sys-on-primary-container)}::ng-deep .mtx-grid-toolbar ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .mtx-grid-toolbar ::ng-deep mtx-grid-column-menu button[mat-icon-button]{color:var(--mat-sys-on-primary-container);margin-right:.5rem}::ng-deep .mtx-grid-main{background-color:#fcfcfc}table{width:100%}::ng-deep table thead,::ng-deep table tbody{background-color:#fcfcfc!important}::ng-deep .mtx-grid-footer,::ng-deep .mat-mdc-paginator{display:block;background-color:#fcfcfc!important;border-bottom-left-radius:9px!important;border-bottom-right-radius:9px!important}a,::ng-deep table a,::ng-deep table a:visited{color:var(--mat-sys-on-primary-container);text-decoration:none}a:hover,::ng-deep table a:hover,::ng-deep table a:visited:hover{text-decoration:underline}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MtxGridModule }, { kind: "component", type: i2$2.MtxGrid, selector: "mtx-grid", inputs: ["displayedColumns", "columns", "data", "length", "loading", "trackBy", "columnResizable", "emptyValuePlaceholder", "pageOnFront", "showPaginator", "pageDisabled", "showFirstLastButtons", "pageIndex", "pageSize", "pageSizeOptions", "hidePageSize", "paginationTemplate", "sortOnFront", "sortActive", "sortDirection", "sortDisableClear", "sortDisabled", "sortStart", "rowHover", "rowStriped", "expandable", "expansionTemplate", "multiSelectable", "multiSelectionWithClick", "rowSelectable", "hideRowSelectionCheckbox", "disableRowClickSelection", "rowSelectionFormatter", "rowClassFormatter", "rowSelected", "cellSelectable", "showToolbar", "toolbarTitle", "toolbarTemplate", "columnHideable", "columnHideableChecked", "columnSortable", "columnPinnable", "columnPinOptions", "showColumnMenuButton", "columnMenuButtonText", "columnMenuButtonType", "columnMenuButtonColor", "columnMenuButtonClass", "columnMenuButtonIcon", "columnMenuButtonFontIcon", "columnMenuButtonSvgIcon", "showColumnMenuHeader", "columnMenuHeaderText", "columnMenuHeaderTemplate", "showColumnMenuFooter", "columnMenuFooterText", "columnMenuFooterTemplate", "noResultText", "noResultTemplate", "headerTemplate", "headerExtraTemplate", "cellTemplate", "useContentRowTemplate", "useContentHeaderRowTemplate", "useContentFooterRowTemplate", "showSummary", "summaryTemplate", "showSidebar", "sidebarTemplate", "showStatusbar", "statusbarTemplate"], outputs: ["page", "sortChange", "rowClick", "rowContextMenu", "expansionChange", "rowSelectedChange", "cellSelectedChange", "columnChange"], exportAs: ["mtxGrid"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: ListCategorySelector, selector: "lib-list-category-selector", inputs: ["config", "selectedCategory"], outputs: ["selectedCategoryChange"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
1047
1069
  }
1048
1070
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: NgxThinAdminList, decorators: [{
1049
1071
  type: Component,
@@ -1077,6 +1099,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1077
1099
  }], cellTplWithLink: [{
1078
1100
  type: ViewChild,
1079
1101
  args: ['cellTplWithLink', { static: true }]
1102
+ }], categorySelector: [{
1103
+ type: ViewChild,
1104
+ args: [ListCategorySelector]
1080
1105
  }] } });
1081
1106
 
1082
1107
  class FormlyMatPrefixAddonWrapper extends FieldWrapper {
@@ -1476,7 +1501,11 @@ class NgxThinAdminEditor {
1476
1501
  return;
1477
1502
  }
1478
1503
  try {
1479
- await this.itemDeleterConfig.deleter(id);
1504
+ const res = await this.itemDeleterConfig.deleter(id);
1505
+ if (res && 'ok' in res && !res.ok) {
1506
+ const errorMessage = getErrorMessage(res);
1507
+ throw new Error(errorMessage);
1508
+ }
1480
1509
  }
1481
1510
  catch (e) {
1482
1511
  const errorMessage = getErrorMessage(e);
@@ -1527,9 +1556,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1527
1556
  ReactiveFormsModule,
1528
1557
  FormlyForm,
1529
1558
  MatButton,
1530
- MatIconButton,
1531
1559
  MatIcon,
1532
- MatTooltip,
1533
1560
  RouterLink,
1534
1561
  MatProgressBar,
1535
1562
  MatCard,
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-thin-admin.mjs","sources":["../../../projects/ngx-thin-admin/src/lib/i18n.ts","../../../projects/ngx-thin-admin/src/lib/shared/category-editor-dialog/category-editor-dialog.ts","../../../projects/ngx-thin-admin/src/lib/shared/category-editor-dialog/category-editor-dialog.html","../../../projects/ngx-thin-admin/src/lib/shared/confirm-dialog/confirm-dialog.ts","../../../projects/ngx-thin-admin/src/lib/shared/confirm-dialog/confirm-dialog.html","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/list-category-selector/list-category-selector.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/list-category-selector/list-category-selector.html","../../../projects/ngx-thin-admin/src/lib/shared/csv-export-service.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/category-change-dialog/category-change-dialog.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/category-change-dialog/category-change-dialog.html","../../../projects/ngx-thin-admin/src/lib/shared/error-handler.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/ngx-thin-admin-list.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/ngx-thin-admin-list.html","../../../projects/ngx-thin-admin/src/lib/shared/formly/mat-prefix-addon-wrapper/mat-prefix-addon-wrapper.ts","../../../projects/ngx-thin-admin/src/lib/shared/formly/file-input/file-type.component.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-editor/ngx-thin-admin-editor.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-editor/ngx-thin-admin-editor.html","../../../projects/ngx-thin-admin/src/public-api.ts","../../../projects/ngx-thin-admin/src/ngx-thin-admin.ts"],"sourcesContent":["import { InjectionToken, Provider } from '@angular/core';\n\nexport type NgxThinAdminLocale = 'en' | 'ja';\n\nexport type NgxThinAdminI18nKey =\n | 'common.cancel'\n | 'common.ok'\n | 'common.save'\n | 'common.create'\n | 'common.edit'\n | 'common.delete'\n | 'common.back'\n | 'list.defaultTitle'\n | 'list.clearFilters'\n | 'list.searchDefaultPlaceholder'\n | 'list.searchInCategoryPlaceholder'\n | 'list.clearSearchKeyword'\n | 'list.refresh'\n | 'list.exportAsCsv'\n | 'list.exportedFileName'\n | 'list.exportItems'\n | 'editor.titleForCreate'\n | 'editor.titleForEdit'\n | 'editor.idLabel'\n | 'editor.saveChanges'\n | 'editor.errorInvalidInput'\n | 'editor.errorNoSaver'\n | 'editor.successSaved'\n | 'editor.backToList'\n | 'category.defaultSingular'\n | 'category.defaultPlural'\n | 'category.all'\n | 'category.editorDialogTitleForCreate'\n | 'category.editorDialogTitleForEdit'\n | 'category.deletionDialogTitle'\n | 'category.deletionDialogMessage'\n | 'category.errorCouldNotCreate'\n | 'category.errorFailedUpdate'\n | 'category.errorFailedDelete'\n | 'category.errorCouldNotSave'\n | 'category.successCreated'\n | 'category.successUpdated'\n | 'category.successDeleted'\n | 'item.defaultSingular'\n | 'item.deletionDialogTitle'\n | 'item.deletionDialogMessage'\n | 'item.errorFailedDelete'\n | 'item.successDeleted'\n | 'item.changeCategory'\n | 'item.changeCategoryDialogTitle'\n | 'item.changeCategoryDialogMessage'\n | 'item.successCategoryChanged'\n | 'item.errorFailedCategoryChange'\n | 'category.unselected'\n | 'csv.exporting'\n | 'csv.exportCompleted'\n | 'csv.exportCompletedWithErrors'\n | 'csv.errorGenerateFailed';\n\nexport type NgxThinAdminI18nParams = Record<string, string | number | undefined>;\nexport type NgxThinAdminTranslate = (\n key: NgxThinAdminI18nKey,\n params?: NgxThinAdminI18nParams,\n) => string;\n\nexport interface NgxThinAdminI18nConfig {\n locale?: NgxThinAdminLocale;\n messages?: Partial<Record<NgxThinAdminI18nKey, string>>;\n translate?: NgxThinAdminTranslate;\n}\n\nconst messagesEn: Record<NgxThinAdminI18nKey, string> = {\n 'common.cancel': 'Cancel',\n 'common.ok': 'OK',\n 'common.save': 'Save',\n 'common.create': 'Create',\n 'common.edit': 'Edit',\n 'common.delete': 'Delete',\n 'common.back': 'Back',\n 'list.defaultTitle': 'List',\n 'list.clearFilters': 'Clear filters',\n 'list.searchDefaultPlaceholder': 'Search...',\n 'list.searchInCategoryPlaceholder': 'Search in {category}...',\n 'list.clearSearchKeyword': 'Clear search keyword',\n 'list.refresh': 'Refresh',\n 'list.exportAsCsv': 'Export as CSV',\n 'list.exportedFileName': 'exported',\n 'list.exportItems': 'Export {count} items',\n 'editor.titleForCreate': 'Create {itemType}',\n 'editor.titleForEdit': 'Edit {itemType}',\n 'editor.idLabel': 'ID',\n 'editor.saveChanges': 'Save Changes',\n 'editor.errorInvalidInput': 'Invalid input',\n 'editor.errorNoSaver': 'No saver function provided',\n 'editor.successSaved': 'Data saved successfully',\n 'editor.backToList': 'To List',\n 'category.defaultSingular': 'Category',\n 'category.defaultPlural': 'Categories',\n 'category.all': 'All',\n 'category.editorDialogTitleForCreate': 'Create {categoryType}',\n 'category.editorDialogTitleForEdit': 'Edit {categoryType}',\n 'category.deletionDialogTitle': 'Delete {categoryType}',\n 'category.deletionDialogMessage':\n 'Are you sure you want to delete the {categoryType} \"{label}\"? This action cannot be undone.',\n 'category.errorCouldNotCreate': 'Could not create {categoryType}',\n 'category.errorFailedUpdate': 'Failed to update {categoryType} \"{label}\"',\n 'category.errorFailedDelete': 'Failed to delete {categoryType} \"{label}\"',\n 'category.errorCouldNotSave': 'Could not save {categoryType}',\n 'category.successCreated': '{categoryType} \"{label}\" has been created successfully',\n 'category.successUpdated': '{categoryType} \"{label}\" has been updated successfully',\n 'category.successDeleted': '{categoryType} \"{label}\" has been deleted successfully',\n 'item.defaultSingular': 'Item',\n 'item.deletionDialogTitle': 'Delete {itemType}',\n 'item.deletionDialogMessage':\n 'Are you sure you want to delete \"{label}\" ({id})? This action cannot be undone.',\n 'item.errorFailedDelete': 'Failed to delete \"{label}\"',\n 'item.successDeleted': '\"{label}\" has been deleted successfully',\n 'item.changeCategory': 'Change {categoryType}',\n 'item.changeCategoryDialogTitle': 'Change {categoryType}',\n 'item.changeCategoryDialogMessage': 'Select a {categoryType} to move \"{label}\" to.',\n 'item.successCategoryChanged': '{categoryType} changed successfully',\n 'item.errorFailedCategoryChange': 'Failed to change {categoryType} for \"{label}\"',\n 'category.unselected': 'Uncategorized',\n 'csv.exporting': 'Exporting CSV...',\n 'csv.exportCompleted': 'CSV export completed. Exported {count} items.',\n 'csv.exportCompletedWithErrors': 'CSV exported up to {count} items, but errors occurred: {error}',\n 'csv.errorGenerateFailed': 'Failed to generate CSV file.',\n};\n\nconst messagesJa: Record<NgxThinAdminI18nKey, string> = {\n 'common.cancel': 'キャンセル',\n 'common.ok': 'OK',\n 'common.save': '保存',\n 'common.create': '作成',\n 'common.edit': '編集',\n 'common.delete': '削除',\n 'common.back': '戻る',\n 'list.defaultTitle': '一覧',\n 'list.clearFilters': 'フィルターをクリア',\n 'list.searchDefaultPlaceholder': '検索...',\n 'list.searchInCategoryPlaceholder': '{category} 内を検索...',\n 'list.clearSearchKeyword': '検索キーワードをクリア',\n 'list.refresh': '再読み込み',\n 'list.exportAsCsv': 'CSV でエクスポート',\n 'list.exportedFileName': 'exported',\n 'list.exportItems': '{count} 件をエクスポート',\n 'editor.titleForCreate': '{itemType}の作成',\n 'editor.titleForEdit': '{itemType}の編集',\n 'editor.idLabel': 'ID',\n 'editor.saveChanges': '変更を保存',\n 'editor.errorInvalidInput': '入力内容が不正です',\n 'editor.errorNoSaver': '保存処理が設定されていません',\n 'editor.successSaved': '保存しました',\n 'editor.backToList': '一覧へ',\n 'category.defaultSingular': 'カテゴリ',\n 'category.defaultPlural': 'カテゴリ',\n 'category.all': 'すべて',\n 'category.editorDialogTitleForCreate': '{categoryType}の作成',\n 'category.editorDialogTitleForEdit': '{categoryType}の編集',\n 'category.deletionDialogTitle': '{categoryType}の削除',\n 'category.deletionDialogMessage':\n '{categoryType} \"{label}\" を削除しますか?この操作は元に戻せません。',\n 'category.errorCouldNotCreate': '{categoryType} を作成できませんでした',\n 'category.errorFailedUpdate': '{categoryType} \"{label}\" の更新に失敗しました',\n 'category.errorFailedDelete': '{categoryType} \"{label}\" の削除に失敗しました',\n 'category.errorCouldNotSave': '{categoryType} を保存できませんでした',\n 'category.successCreated': '{categoryType} \"{label}\" を作成しました',\n 'category.successUpdated': '{categoryType} \"{label}\" を更新しました',\n 'category.successDeleted': '{categoryType} \"{label}\" を削除しました',\n 'item.defaultSingular': '項目',\n 'item.deletionDialogTitle': '{itemType}の削除',\n 'item.deletionDialogMessage': '\"{label}\" ({id}) を削除しますか?この操作は元に戻せません。',\n 'item.errorFailedDelete': '\"{label}\" の削除に失敗しました',\n 'item.successDeleted': '\"{label}\" を削除しました',\n 'item.changeCategory': '{categoryType}を変更',\n 'item.changeCategoryDialogTitle': '{categoryType}の変更',\n 'item.changeCategoryDialogMessage': '\"{label}\" の移動先を選択してください',\n 'item.successCategoryChanged': '{categoryType}を変更しました',\n 'item.errorFailedCategoryChange': '「{label}」の{categoryType}変更に失敗しました',\n 'category.unselected': '未分類',\n 'csv.exporting': 'CSV をエクスポート中...',\n 'csv.exportCompleted': 'CSV エクスポートが完了しました。{count} 件をエクスポートしました。',\n 'csv.exportCompletedWithErrors':\n '{count} 件までエクスポートしましたが、エラーが発生しました: {error}',\n 'csv.errorGenerateFailed': 'CSV ファイルの生成に失敗しました。',\n};\n\nfunction interpolate(message: string, params?: NgxThinAdminI18nParams): string {\n if (!params) {\n return message;\n }\n\n return message.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const value = params[key];\n return value === undefined ? '' : String(value);\n });\n}\n\nfunction createTranslatorFromMessages(\n baseMessages: Record<NgxThinAdminI18nKey, string>,\n overrides?: Partial<Record<NgxThinAdminI18nKey, string>>,\n): NgxThinAdminTranslate {\n const merged = { ...baseMessages, ...overrides };\n return (key: NgxThinAdminI18nKey, params?: NgxThinAdminI18nParams): string => {\n return interpolate(merged[key] ?? messagesEn[key], params);\n };\n}\n\nexport const NGX_THIN_ADMIN_TRANSLATE = new InjectionToken<NgxThinAdminTranslate>(\n 'NGX_THIN_ADMIN_TRANSLATE',\n {\n providedIn: 'root',\n factory: () => createTranslatorFromMessages(messagesEn),\n },\n);\n\nexport function provideNgxThinAdminI18n(config?: NgxThinAdminI18nConfig): Provider {\n return {\n provide: NGX_THIN_ADMIN_TRANSLATE,\n useFactory: () => {\n if (config?.translate) {\n return config.translate;\n }\n\n const locale = config?.locale ?? 'en';\n const base = locale === 'ja' ? messagesJa : messagesEn;\n return createTranslatorFromMessages(base, config?.messages);\n },\n };\n}\n","import { Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MAT_DIALOG_DATA,\n MatDialogRef,\n} from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { NgxThinAdminCategory, NgxThinAdminCategorySelectorConfig } from '../../interfaces';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\n\nexport interface CategoryEditorDialogData {\n config: NgxThinAdminCategorySelectorConfig;\n editCategory?: NgxThinAdminCategory;\n positiveButtonText?: string;\n cancelButtonText?: string;\n}\n\n@Component({\n selector: 'lib-category-editor-dialog',\n imports: [\n MatFormFieldModule,\n MatInputModule,\n FormsModule,\n MatButtonModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n ],\n templateUrl: './category-editor-dialog.html',\n styleUrl: './category-editor-dialog.scss',\n})\nexport class CategoryEditorDialog {\n readonly dialogRef = inject(MatDialogRef<CategoryEditorDialog>);\n readonly data = inject<CategoryEditorDialogData>(MAT_DIALOG_DATA);\n private readonly translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n categoryLabel?: string;\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n save() {\n if (!this.categoryLabel) {\n return;\n }\n\n this.dialogRef.close({\n label: this.categoryLabel,\n });\n }\n}\n","<h2 mat-dialog-title>\n @if (data.editCategory) {\n {{\n t('category.editorDialogTitleForEdit', {\n categoryType: data.config.singularLabel ?? t('category.defaultSingular'),\n })\n }}\n } @else {\n {{\n t('category.editorDialogTitleForCreate', {\n categoryType: data.config.singularLabel ?? t('category.defaultSingular'),\n })\n }}\n }\n</h2>\n<form (ngSubmit)=\"save()\">\n <mat-dialog-content>\n <mat-form-field>\n <mat-label>{{ data.config.exampleLabel ?? data.config.singularLabel ?? '' }}</mat-label>\n <input\n matInput\n [(ngModel)]=\"categoryLabel\"\n name=\"categoryLabel\"\n cdkFocusInitial\n [value]=\"data.editCategory ? data.editCategory.label : ''\"\n />\n </mat-form-field>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button type=\"button\" class=\"cancel-btn\" matButton [mat-dialog-close]=\"undefined\">\n {{ data.cancelButtonText ?? t('common.cancel') }}\n </button>\n <button type=\"submit\" matButton>{{ data.positiveButtonText ?? t('common.save') }}</button>\n </mat-dialog-actions>\n</form>\n","import { Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MAT_DIALOG_DATA,\n MatDialogRef,\n} from '@angular/material/dialog';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\n\nexport interface ConfirmDialogData {\n title?: string;\n message?: string;\n positiveButtonText?: string;\n cancelButtonText?: string;\n}\n\n@Component({\n selector: 'lib-confirm-dialog',\n imports: [\n FormsModule,\n MatButtonModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n ],\n templateUrl: './confirm-dialog.html',\n styleUrl: './confirm-dialog.scss',\n})\nexport class ConfirmDialog {\n readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);\n readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);\n private readonly translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n}\n","<h2 mat-dialog-title>{{ data.title }}</h2>\n<mat-dialog-content>\n {{ data.message }}\n</mat-dialog-content>\n<mat-dialog-actions>\n <button class=\"cancel-btn\" matButton [mat-dialog-close]=\"undefined\">\n {{ data.cancelButtonText || t('common.cancel') }}\n </button>\n <button matButton [mat-dialog-close]=\"true\" cdkFocusInitial>\n {{ data.positiveButtonText || t('common.ok') }}\n </button>\n</mat-dialog-actions>\n","import {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n inject,\n Input,\n Output,\n SimpleChanges,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatListOption, MatSelectionList } from '@angular/material/list';\nimport {\n NgxThinAdminCategory,\n NgxThinAdminCategoryListResponse,\n NgxThinAdminCategorySelectorConfig,\n} from '../../interfaces';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatMenu, MatMenuContent, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatDialog } from '@angular/material/dialog';\nimport {\n CategoryEditorDialog,\n CategoryEditorDialogData,\n} from '../../shared/category-editor-dialog/category-editor-dialog';\nimport { lastValueFrom, single } from 'rxjs';\nimport { ConfirmDialog, ConfirmDialogData } from '../../shared/confirm-dialog/confirm-dialog';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\n\n@Component({\n selector: 'lib-list-category-selector',\n imports: [\n FormsModule,\n MatIcon,\n MatIconButton,\n MatSelectionList,\n MatMenu,\n MatMenuItem,\n MatMenuTrigger,\n MatListOption,\n MatMenuContent,\n ],\n templateUrl: './list-category-selector.html',\n styleUrl: './list-category-selector.scss',\n})\nexport class ListCategorySelector {\n /**\n * Config for the category selector\n */\n @Input() config?: NgxThinAdminCategorySelectorConfig;\n\n /**\n * Selected category. This will be updated when the user selects a category from the list.\n */\n @Input()\n selectedCategory?: (NgxThinAdminCategory | undefined)[];\n\n /**\n * Event emitted when the selected category changes.\n */\n @Output()\n selectedCategoryChange = new EventEmitter<(NgxThinAdminCategory | undefined)[]>();\n\n /**\n * Categories to be displayed in the category selector.\n */\n categories: NgxThinAdminCategory[] = [];\n\n /**\n * Services\n */\n private snackbar = inject(MatSnackBar);\n private dialog = inject(MatDialog);\n private cdr = inject(ChangeDetectorRef);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n ngOnChanges(changes: SimpleChanges<ListCategorySelector>) {\n if (\n changes.config &&\n changes.config.currentValue?.fetcher !== changes.config.previousValue?.fetcher\n ) {\n this.fetchCategories();\n }\n }\n\n async fetchCategories() {\n if (!this.config?.fetcher) {\n return;\n } else if (!(this.config.fetcher instanceof Function)) {\n throw new Error('categoryFetcher must be a function');\n }\n\n console.log('Fetching categories');\n try {\n const result = await Promise.resolve(this.config.fetcher());\n console.log(result);\n this.categories = result.categories;\n this.cdr.markForCheck();\n console.log('Fetched categories:', this.categories);\n } catch (e) {\n console.error('Error fetching categories:', e);\n }\n }\n\n async createCategory(categoryLabel: string) {\n if (!this.config?.creator) {\n return;\n }\n\n // Call the category creator function\n try {\n await this.config.creator(categoryLabel);\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${e?.message ?? this.t('category.errorCouldNotCreate', { categoryType: this.config.singularLabel ?? this.t('category.defaultSingular') })}`,\n undefined,\n {\n duration: 3000,\n },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(\n this.t('category.successCreated', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: categoryLabel,\n }),\n undefined,\n {\n duration: 3000,\n },\n );\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async updateCategory(category: NgxThinAdminCategory) {\n if (!this.config?.updater) {\n return;\n }\n\n // Call the category updater function\n try {\n await this.config.updater(category);\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorFailedUpdate', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(\n this.t('category.successUpdated', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n }),\n undefined,\n {\n duration: 3000,\n },\n );\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async deleteCategory(category: NgxThinAdminCategory) {\n if (!this.config?.deleter) {\n return;\n }\n\n // Call the category deleter function\n try {\n await this.config.deleter(category);\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorFailedDelete', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(\n this.t('category.successDeleted', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n }),\n undefined,\n {\n duration: 3000,\n },\n );\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async openCategoryEditorDialog(editCategory: NgxThinAdminCategory | undefined) {\n // Open a dialog for category creation / editing\n const dialogRef = this.dialog.open(CategoryEditorDialog, {\n width: '400px',\n data: {\n config: this.config!,\n editCategory: editCategory,\n positiveButtonText: editCategory ? this.t('common.save') : this.t('common.create'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies CategoryEditorDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result || !result.label) {\n return;\n }\n\n // Call the category creator / updater function\n try {\n if (editCategory) {\n await this.updateCategory({ ...editCategory, label: result.label });\n } else {\n await this.createCategory(result.label);\n }\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorCouldNotSave', {\n categoryType: this.config!.singularLabel ?? this.t('category.defaultSingular'),\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n }\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async openCategoryDeletionDialog(category: NgxThinAdminCategory) {\n // Open a dialog for category deletion\n const dialogRef = this.dialog.open(ConfirmDialog, {\n width: '400px',\n data: {\n title: this.t('category.deletionDialogTitle', {\n categoryType: this.config?.singularLabel ?? this.t('category.defaultSingular'),\n }),\n message: this.t('category.deletionDialogMessage', {\n categoryType: this.config?.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n }),\n positiveButtonText: this.t('common.delete'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies ConfirmDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n // Call the category deleter function\n try {\n await this.deleteCategory(category);\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorFailedDelete', {\n categoryType: this.config?.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n }\n\n // Refresh category list\n this.fetchCategories();\n }\n}\n","<header>\n <!-- Category selector title -->\n <span class=\"category-selector-title\">\n {{ config?.title ?? t('category.defaultPlural') }}\n </span>\n <!---->\n\n <!-- Category Creation button -->\n @if (config?.creator) {\n <button\n mat-icon-button\n (click)=\"openCategoryEditorDialog(undefined)\"\n class=\"create-category-button\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n <!---->\n</header>\n\n<mat-selection-list\n #categorySelector\n [multiple]=\"false\"\n [hideSingleSelectionIndicator]=\"true\"\n [(ngModel)]=\"selectedCategory\"\n (selectionChange)=\"this.selectedCategoryChange.emit(selectedCategory)\"\n>\n <!-- \"All\" Category -->\n <mat-list-option\n [value]=\"undefined\"\n [class.active]=\"selectedCategory && selectedCategory[0] === undefined\"\n >\n <div matListItemTitle>\n <!-- Category label -->\n {{ t('category.all') }}&nbsp;\n <!---->\n </div>\n </mat-list-option>\n <!---->\n\n <!-- Each category -->\n @for (category of categories; track category.id) {\n <mat-list-option\n [value]=\"category\"\n [class.active]=\"selectedCategory && selectedCategory[0]?.id === category.id\"\n >\n <div matListItemTitle>\n <!-- Category label -->\n {{ category.label }}&nbsp;\n <!---->\n\n <!-- Count of items in the category -->\n @if (category.itemCount !== undefined) {\n <small> ({{ category.itemCount }}) </small>\n }\n <!---->\n </div>\n\n <!-- Category menu button -->\n @if (\n selectedCategory &&\n selectedCategory[0] !== undefined &&\n selectedCategory[0].id === category.id &&\n (config?.updater || config?.deleter)\n ) {\n <button\n matIconButton\n [matMenuTriggerFor]=\"menu\"\n [matMenuTriggerData]=\"{ category: category }\"\n class=\"category-menu-button\"\n >\n <mat-icon>more_vert</mat-icon>\n </button>\n }\n <!---->\n </mat-list-option>\n }\n <!---->\n</mat-selection-list>\n\n<!-- Category Menu -->\n<mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent let-category=\"category\">\n @if (config?.updater) {\n <button mat-menu-item (click)=\"openCategoryEditorDialog(category)\">\n {{ t('common.edit') }}\n </button>\n }\n @if (config?.deleter) {\n <button mat-menu-item (click)=\"openCategoryDeletionDialog(category)\">\n {{ t('common.delete') }}\n </button>\n }\n </ng-template>\n</mat-menu>\n<!---->\n","import { inject, Injectable } from '@angular/core';\nimport {\n ListFetcher,\n NgxThinAdminListColumn,\n NgxThinAdminListQuery,\n NgxThinAdminListResponse,\n} from '../interfaces';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { ColumnOption, stringify as csvStringify } from 'csv-stringify/browser/esm/sync';\nimport { NGX_THIN_ADMIN_TRANSLATE } from '../i18n';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CsvExportService {\n private snackbar = inject(MatSnackBar);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n private encoders: {\n key: string;\n label: string;\n mimeCharset: string;\n encoder: ((input: string) => ArrayBuffer | null) | undefined;\n }[] = [\n {\n key: 'utf8',\n label: 'UTF-8',\n mimeCharset: 'UTF-8',\n encoder: undefined,\n },\n ];\n\n constructor() {\n this.loadOptionalEncoders();\n }\n\n private async loadOptionalEncoders() {\n // Optional charset support for Shift_JIS (commonly used in Japan)\n try {\n // @ts-ignore\n const Encoding = (await import('encoding-japanese')) as any;\n this.encoders.push({\n key: 'sjis',\n label: 'Shift_JIS',\n mimeCharset: 'Shift_JIS',\n encoder: (input: string) => {\n const sjisArrayBuffer = Encoding.convert(input, {\n from: 'UNICODE',\n to: 'SJIS',\n type: 'arraybuffer',\n });\n return new Uint8Array(sjisArrayBuffer).buffer;\n },\n });\n } catch (error) {\n console.error(\n 'Shift_JIS encoder is not available. If you need it, please install \"encoding-japanese\" package.',\n error,\n );\n // Do nothing\n }\n }\n\n getAvailableEncoders() {\n return this.encoders.map((encoder) => ({\n key: encoder.key,\n label: encoder.label,\n }));\n }\n\n async exportListAsCsv(\n encoderKey: string,\n fileNamePrefix: string,\n fetcher: ListFetcher,\n listQuery: Omit<NgxThinAdminListQuery, 'page' | 'perPage'>,\n columns: NgxThinAdminListColumn[],\n ) {\n const CSV_EXPORT_MAX_PAGE_INDEX = 1000;\n const CSV_EXPORT_PAGE_SIZE = 25;\n\n console.log('Starting CSV export', listQuery, encoderKey);\n\n // Get encoder\n const encoderInfo = this.encoders.find((e) => e.key === encoderKey);\n if (!encoderInfo) {\n console.error(`exportListAsCsv - Encoder not found for key: ${encoderKey}`);\n return;\n }\n const mimeCharset = encoderInfo.mimeCharset;\n const encoder = encoderInfo.encoder;\n\n // Initialize\n const items: any[] = [];\n let errorMessage: string | undefined = undefined;\n\n // 処理中メッセージを表示\n const mes = this.snackbar.open(this.translate('csv.exporting'));\n\n // Replace characters in the file name prefix that cannot be used in file names\n fileNamePrefix = fileNamePrefix.replace(/[/¥\\\\*?:\"<>|@\\s;^.]/g, '_');\n\n // Truncate the file name prefix if it is too long\n const FILE_NAME_PREFIX_MAX_LENGTH = 100;\n if (fileNamePrefix.length > FILE_NAME_PREFIX_MAX_LENGTH) {\n fileNamePrefix = fileNamePrefix.substring(0, FILE_NAME_PREFIX_MAX_LENGTH);\n }\n\n // Generate file name\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const date = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n const datetimeString = `${year}${month}${date}_${hours}${minutes}${seconds}`;\n const csvFileName = `${fileNamePrefix}_${datetimeString}.csv`;\n\n // Fetch items page by page\n let numOfExportedItems = 0;\n for (let pageIndex = 0; pageIndex < CSV_EXPORT_MAX_PAGE_INDEX; pageIndex++) {\n const query: NgxThinAdminListQuery = {\n ...listQuery,\n page: pageIndex,\n perPage: CSV_EXPORT_PAGE_SIZE,\n };\n\n let result: NgxThinAdminListResponse;\n try {\n result = await fetcher(query);\n } catch (error: any) {\n console.error(`exportListAsCsv - Error fetching data:`, error);\n errorMessage = error.message || 'Unknown error';\n break;\n }\n\n // Wait for few seconds\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n if (result.items.length === 0) {\n // No items, exit\n break;\n }\n\n // Add fetched items\n items.push(...result.items);\n numOfExportedItems += result.items.length;\n }\n\n // Determine CSV columns\n const csvColumns: ColumnOption[] = columns\n .filter((column) => {\n if (column.type === 'button') {\n // Exclude columns that are buttons\n return false;\n }\n return true;\n })\n .map((column) => {\n // Get the column key (e.g., \"name\")\n const columnKey: string = column.field;\n // Get the column header string (e.g., \"User Name\")\n let columnHeader: string;\n if (typeof column.header === 'string') {\n columnHeader = column.header;\n } else {\n columnHeader = columnKey;\n }\n // Return column information for csv-stringify\n return {\n key: column.field,\n header: columnHeader,\n };\n })\n .filter((column) => column !== null);\n\n // Convert to CSV\n const csv = csvStringify(items, {\n header: true,\n columns: csvColumns,\n });\n\n // Generate Blob\n let blob: Blob | undefined = undefined;\n if (encoder) {\n const encodedData = encoder(csv);\n if (encodedData) {\n blob = new Blob([encodedData], { type: `text/csv; charset=${mimeCharset}` });\n } else {\n console.error(`exportListAsCsv - Encoding failed for encoder: ${encoderKey}`);\n }\n } else {\n blob = new Blob([csv], { type: `text/csv; charset=${mimeCharset}` });\n }\n\n if (!blob) {\n console.error(`exportListAsCsv - Blob is not created`);\n mes.dismiss();\n this.snackbar.open(this.translate('csv.errorGenerateFailed'), undefined, {\n duration: 5000,\n });\n return;\n }\n\n // Download as CSV\n const objectUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.download = csvFileName;\n a.href = objectUrl;\n a.click();\n\n // Revoke object URL after download\n URL.revokeObjectURL(objectUrl);\n\n // Dissmiss processing message\n mes.dismiss();\n\n // 結果メッセージを表示\n if (errorMessage) {\n this.snackbar.open(\n this.translate('csv.exportCompletedWithErrors', {\n count: numOfExportedItems,\n error: errorMessage,\n }),\n undefined,\n {\n duration: 5000,\n },\n );\n } else {\n this.snackbar.open(\n this.translate('csv.exportCompleted', { count: numOfExportedItems }),\n undefined,\n {\n duration: 3000,\n },\n );\n }\n }\n}\n","import { Component, inject, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MAT_DIALOG_DATA,\n MatDialogRef,\n MatDialog,\n} from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { NgxThinAdminCategory, NgxThinAdminCategorySelectorConfig } from '../../interfaces';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport {\n CategoryEditorDialog,\n CategoryEditorDialogData,\n} from '../../shared/category-editor-dialog/category-editor-dialog';\nimport { lastValueFrom } from 'rxjs';\n\nexport interface CategoryChangeDialogData {\n itemLabel?: string;\n categorySelectorConfig: NgxThinAdminCategorySelectorConfig;\n currentCategoryId?: string;\n positiveButtonText?: string;\n cancelButtonText?: string;\n}\n\n@Component({\n selector: 'lib-category-change-dialog',\n imports: [\n MatFormFieldModule,\n MatSelectModule,\n FormsModule,\n MatButtonModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MatProgressSpinnerModule,\n MatIconModule,\n ],\n templateUrl: './category-change-dialog.html',\n styleUrl: './category-change-dialog.scss',\n})\nexport class CategoryChangeDialog implements OnInit {\n readonly dialogRef = inject(MatDialogRef<CategoryChangeDialog>);\n readonly data = inject<CategoryChangeDialogData>(MAT_DIALOG_DATA);\n private readonly translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly dialog = inject(MatDialog);\n private readonly snackbar = inject(MatSnackBar);\n\n categories: NgxThinAdminCategory[] = [];\n selectedCategoryId?: string;\n isLoading = false;\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n async ngOnInit() {\n this.selectedCategoryId = this.data.currentCategoryId;\n this.isLoading = true;\n this.cdr.markForCheck();\n\n try {\n const result = await Promise.resolve(this.data.categorySelectorConfig.fetcher());\n this.categories = result.categories;\n } catch (e) {\n console.error('Failed to fetch categories:', e);\n } finally {\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n save() {\n this.dialogRef.close({\n categoryId: this.selectedCategoryId,\n });\n }\n\n async createNewCategory() {\n if (!this.data.categorySelectorConfig.creator) return;\n\n const dialogRef = this.dialog.open(CategoryEditorDialog, {\n width: '400px',\n data: {\n config: this.data.categorySelectorConfig,\n editCategory: undefined,\n positiveButtonText: this.t('common.create'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies CategoryEditorDialogData,\n });\n\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result || !result.label) {\n return;\n }\n\n this.isLoading = true;\n this.cdr.markForCheck();\n\n try {\n const newCategory = await Promise.resolve(this.data.categorySelectorConfig.creator(result.label));\n \n this.snackbar.open(\n this.t('category.successCreated', {\n categoryType: this.data.categorySelectorConfig.singularLabel ?? this.t('category.defaultSingular'),\n label: result.label,\n }),\n undefined,\n { duration: 3000 }\n );\n\n // Re-fetch categories\n const fetchResult = await Promise.resolve(this.data.categorySelectorConfig.fetcher());\n this.categories = fetchResult.categories;\n \n // Auto-select the newly created category\n this.selectedCategoryId = newCategory.id;\n\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorCouldNotSave', {\n categoryType: this.data.categorySelectorConfig.singularLabel ?? this.t('category.defaultSingular'),\n })\n }`,\n undefined,\n { duration: 3000 }\n );\n } finally {\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n }\n}\n","<h2 mat-dialog-title>\n {{\n t('item.changeCategoryDialogTitle', {\n categoryType: data.categorySelectorConfig.singularLabel || t('category.defaultSingular'),\n })\n }}\n</h2>\n\n<mat-dialog-content>\n @if (data.itemLabel) {\n <p style=\"margin-top: 5px; margin-bottom: 1rem\">\n {{\n t('item.changeCategoryDialogMessage', {\n label: data.itemLabel,\n categoryType: data.categorySelectorConfig.singularLabel || t('category.defaultSingular'),\n })\n }}\n </p>\n }\n\n <mat-form-field appearance=\"outline\" style=\"width: 100%; margin-top: 10px\">\n <mat-label>{{\n data.categorySelectorConfig.singularLabel || t('category.defaultSingular')\n }}</mat-label>\n <mat-select [(ngModel)]=\"selectedCategoryId\" [disabled]=\"isLoading\">\n <mat-option [value]=\"undefined\">{{ t('category.unselected') }}</mat-option>\n @for (category of categories; track category.id) {\n <mat-option [value]=\"category.id\">{{ category.label }}</mat-option>\n }\n </mat-select>\n @if (isLoading) {\n <mat-spinner matSuffix diameter=\"20\" style=\"margin-right: 12px\"></mat-spinner>\n }\n </mat-form-field>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n @if (data.categorySelectorConfig.creator) {\n <button mat-button (click)=\"createNewCategory()\" [disabled]=\"isLoading\">\n <mat-icon style=\"margin-right: 4px; font-size: 1.2rem; width: 1.2rem; height: 1.2rem\"\n >add</mat-icon\n >\n <span>{{ t('common.create') }}</span>\n </button>\n }\n\n <span style=\"flex: 1\"></span>\n\n <button mat-button mat-dialog-close>\n {{ data.cancelButtonText || t('common.cancel') }}\n </button>\n <button mat-flat-button color=\"primary\" (click)=\"save()\" [disabled]=\"isLoading\">\n {{ data.positiveButtonText || t('common.save') }}\n </button>\n</mat-dialog-actions>\n","export function getErrorMessage(error: any): string {\n if (typeof error === 'string') {\n return error;\n } else if (error instanceof Error) {\n return error.message;\n } else if (error?.error?.message) {\n if (Array.isArray(error.error.message)) {\n return error.error.message[0];\n } else {\n return error.error.message;\n }\n } else {\n return 'An unknown error occurred';\n }\n}\n","import {\n Component,\n inject,\n Input,\n OnChanges,\n OnInit,\n SimpleChanges,\n TemplateRef,\n ViewChild,\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatInput, MatPrefix, MatSuffix } from '@angular/material/input';\nimport { MatFormField } from '@angular/material/select';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { MtxGridColumn, MtxGridModule } from '@ng-matero/extensions/grid';\nimport {\n NgxThinAdminCategory,\n NgxThinAdminCategorySelectorConfig,\n NgxThinAdminListColumn,\n NgxThinAdminListConfig,\n NgxThinAdminListQuery,\n NgxThinAdminListResponse,\n NgxThinAdminItemDeleterConfig,\n} from '../interfaces';\nimport { FormsModule } from '@angular/forms';\nimport { PageEvent } from '@angular/material/paginator';\nimport { ChangeDetectorRef } from '@angular/core';\nimport { ListCategorySelector } from './list-category-selector/list-category-selector';\nimport { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatListOption } from '@angular/material/list';\nimport { CsvExportService } from '../shared/csv-export-service';\nimport { RouterLink } from '@angular/router';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../i18n';\nimport { MatDialog } from '@angular/material/dialog';\nimport { ConfirmDialog, ConfirmDialogData } from '../shared/confirm-dialog/confirm-dialog';\nimport {\n CategoryChangeDialog,\n CategoryChangeDialogData,\n} from './category-change-dialog/category-change-dialog';\nimport { lastValueFrom } from 'rxjs';\nimport { getErrorMessage } from '../shared/error-handler';\n\n@Component({\n selector: 'ngx-thin-admin-list',\n imports: [\n FormsModule,\n MtxGridModule,\n MatButton,\n MatIcon,\n MatIconButton,\n MatTooltip,\n MatFormField,\n MatInput,\n MatPrefix,\n MatSuffix,\n ListCategorySelector,\n MatMenu,\n MatMenuItem,\n MatMenuTrigger,\n RouterLink,\n ],\n templateUrl: './ngx-thin-admin-list.html',\n styleUrl: './ngx-thin-admin-list.scss',\n})\nexport class NgxThinAdminList implements OnChanges, OnInit {\n /**\n * Config for list\n */\n @Input()\n listConfig?: NgxThinAdminListConfig;\n\n /**\n * Config for category selector. If provided, a category selector will be displayed in the UI.\n */\n @Input()\n categorySelectorConfig?: NgxThinAdminCategorySelectorConfig;\n\n /**\n * Config for item deleter (If provided, item deletion feature is enabled)\n * It works by calling openItemDeletionDialog(row) from the click handler of the column definition.\n */\n @Input()\n itemDeleterConfig?: NgxThinAdminItemDeleterConfig;\n\n /**\n * Column schema (extended type of MtxGridColumn)\n * @see https://ng-matero.github.io/extensions/components/grid/api\n */\n @Input()\n listColumns?: MtxGridColumn[];\n\n /**\n * Query (Optional)\n */\n @Input() query: NgxThinAdminListQuery = {\n keyword: '',\n page: 0,\n perPage: 10,\n categoryId: undefined,\n };\n\n /**\n * Fetcher function to retrieve list data.\n * This should be provided as part of listConfig.\n */\n private listFetcher?: (\n query: NgxThinAdminListQuery,\n ) => Promise<NgxThinAdminListResponse> | NgxThinAdminListResponse;\n\n /**\n * Internal state for grid\n */\n isLoading = false;\n gridColumns: MtxGridColumn[] = [];\n gridData: any[] = [];\n totalCount: number = 0;\n\n /**\n * Internal state for category list\n */\n categories: NgxThinAdminCategory[] = [];\n selectedCategory?: NgxThinAdminCategory[] = [];\n\n /**\n * Internal subject to trigger keyword change with debounce\n */\n private keywordChanged$ = new Subject<void>();\n ngOnInit(): void {\n this.keywordChanged$.pipe(debounceTime(500)).subscribe(() => {\n this.fetchList();\n });\n }\n\n /**\n * Template for cells\n */\n @ViewChild('cellTplWithLink', { static: true }) cellTplWithLink!: TemplateRef<any>;\n\n /**\n * Services\n */\n private cdr = inject(ChangeDetectorRef);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n private snackbar = inject(MatSnackBar);\n csvExportService = inject(CsvExportService);\n private dialog = inject(MatDialog);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n ngOnChanges(changes: SimpleChanges<NgxThinAdminList>) {\n // Columns\n if (changes.listColumns?.currentValue || changes.listConfig?.currentValue) {\n this.buildGridColumns();\n }\n\n // List - trigger strictly when listFetcher is newly provided or explicitly changed\n if (changes.listConfig?.currentValue?.fetcher !== changes.listConfig?.previousValue?.fetcher) {\n this.listFetcher = changes.listConfig?.currentValue?.fetcher;\n this.fetchList();\n }\n }\n\n private buildGridColumns() {\n if (!this.listColumns) {\n this.gridColumns = [];\n return;\n }\n\n let columns = this.listColumns.map((col: NgxThinAdminListColumn) => {\n if (col.link || col.routerLink) {\n return { ...col, cellTemplate: this.cellTplWithLink };\n }\n return col;\n });\n\n if (this.listConfig?.categoryChanger && this.categorySelectorConfig) {\n const actionsColIndex = columns.findIndex(\n (col) => col.field === 'actions' && col.type === 'button',\n );\n\n const categoryType = this.categorySelectorConfig.singularLabel || this.t('category.defaultSingular');\n const changeCategoryBtn = {\n type: 'icon' as const,\n icon: 'folder_shared',\n tooltip: this.t('item.changeCategory', { categoryType }),\n click: (record: any) => this.openItemCategoryChangeDialog(record),\n };\n\n if (actionsColIndex >= 0) {\n const col = { ...columns[actionsColIndex] };\n const originalButtons = col.buttons;\n if (typeof originalButtons === 'function') {\n col.buttons = (record: any) => [...originalButtons(record), changeCategoryBtn];\n } else {\n col.buttons = [...(originalButtons || []), changeCategoryBtn];\n }\n columns[actionsColIndex] = col;\n } else {\n columns.push({\n header: 'Actions',\n field: 'actions',\n type: 'button',\n buttons: [changeCategoryBtn],\n });\n }\n }\n\n this.gridColumns = columns;\n }\n\n async fetchList() {\n if (!this.listFetcher) {\n return;\n } else if (!(this.listFetcher instanceof Function)) {\n throw new Error('listFetcher must be a function');\n }\n\n console.log('Fetching data with query:', this.query);\n this.isLoading = true;\n\n try {\n const result = await Promise.resolve(this.listFetcher(this.query));\n this.gridData = result.items;\n this.totalCount = result.totalCount;\n } catch (e) {\n console.error('Error fetching list data:', e);\n } finally {\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n clearFilters() {\n this.query.keyword = '';\n this.query.categoryId = undefined;\n this.selectedCategory = [];\n this.fetchList();\n }\n\n onKeywordInput() {\n this.keywordChanged$.next();\n }\n\n async exportAsCsv(encoderKey: 'utf8' | string) {\n if (!this.listFetcher) {\n return;\n }\n\n // Determine file name prefix\n let fileNamePrefix: string = this.listConfig?.title\n ? this.listConfig.title\n : this.t('list.exportedFileName');\n if (this.selectedCategory && this.selectedCategory[0]?.id) {\n // If a category is selected, include the category label in the file name prefix\n fileNamePrefix += `_${this.selectedCategory[0]?.label}`;\n }\n if (this.query.keyword && this.query.keyword.length > 0) {\n // If a search keyword is entered, include it in the file name prefix\n fileNamePrefix += `_${this.query.keyword}`;\n }\n\n // Execute export\n await this.csvExportService.exportListAsCsv(\n encoderKey,\n fileNamePrefix,\n this.listFetcher,\n {\n categoryId: this.selectedCategory ? this.selectedCategory[0]?.id : undefined,\n keyword: this.query.keyword,\n },\n this.listColumns!,\n );\n }\n\n onPageChange(event: PageEvent) {\n this.query.page = event.pageIndex;\n this.query.perPage = event.pageSize;\n this.fetchList();\n }\n\n onSelectedCategoryChange($event: (NgxThinAdminCategory | undefined)[]) {\n console.log('Selected category changed:', $event);\n const categoryId = $event && $event.length >= 1 && $event[0] ? $event[0].id : undefined;\n this.query.categoryId = categoryId;\n this.fetchList();\n }\n\n async openItemDeletionDialog(item: any) {\n if (!this.itemDeleterConfig?.deleter) {\n return;\n }\n\n // Get the label and ID to query in the confirmation dialog\n const idKey = this.listConfig?.idFieldKey;\n const labelKey = this.listConfig?.labelFieldKey;\n const id = idKey ? item[idKey] : (item.id ?? JSON.stringify(item));\n const label = labelKey ? item[labelKey] : id;\n const itemType = this.listConfig?.singularLabel || this.t('item.defaultSingular');\n\n // Open the confirmation dialog\n const dialogRef = this.dialog.open(ConfirmDialog, {\n width: '400px',\n data: {\n title: this.t('item.deletionDialogTitle', { itemType }),\n message: this.t('item.deletionDialogMessage', { label, id }),\n positiveButtonText: this.t('common.delete'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies ConfirmDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n // Execute delete process\n await this.deleteItem(id, label);\n }\n\n async deleteItem(id: string, label: string) {\n if (!this.itemDeleterConfig?.deleter) {\n return;\n }\n\n try {\n await this.itemDeleterConfig.deleter(id);\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(\n `Error: ${errorMessage || this.t('item.errorFailedDelete', { label })}`,\n undefined,\n { duration: 3000 },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(this.t('item.successDeleted', { label }), undefined, {\n duration: 3000,\n });\n\n // Refresh the list after deletion\n this.fetchList();\n }\n\n async openItemCategoryChangeDialog(item: any) {\n if (!this.listConfig?.categoryChanger || !this.categorySelectorConfig) {\n return;\n }\n\n const idKey = this.listConfig?.idFieldKey;\n const labelKey = this.listConfig?.labelFieldKey;\n const id = idKey ? item[idKey] : (item.id ?? JSON.stringify(item));\n const label = labelKey ? item[labelKey] : id;\n\n let currentCategoryId: string | undefined;\n if (typeof this.listConfig.categoryFieldKey === 'function') {\n currentCategoryId = this.listConfig.categoryFieldKey(item);\n } else if (typeof this.listConfig.categoryFieldKey === 'string') {\n currentCategoryId = item[this.listConfig.categoryFieldKey];\n } else {\n currentCategoryId = item.categoryId ?? item.category?.id;\n }\n\n const dialogRef = this.dialog.open(CategoryChangeDialog, {\n width: '400px',\n data: {\n itemLabel: label,\n categorySelectorConfig: this.categorySelectorConfig,\n currentCategoryId: currentCategoryId,\n positiveButtonText: this.t('common.save'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies CategoryChangeDialogData,\n });\n\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n const newCategoryId = result.categoryId;\n const categoryType = this.categorySelectorConfig.singularLabel || this.t('category.defaultSingular');\n \n try {\n await this.listConfig.categoryChanger(id, newCategoryId);\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(\n `Error: ${errorMessage || this.t('item.errorFailedCategoryChange', { label, categoryType })}`,\n undefined,\n { duration: 3000 },\n );\n return;\n }\n\n this.snackbar.open(this.t('item.successCategoryChanged', { label, categoryType }), undefined, {\n duration: 3000,\n });\n\n this.fetchList();\n }\n}\n","<!-- Category Selector -->\n@if (categorySelectorConfig) {\n <lib-list-category-selector\n [config]=\"categorySelectorConfig\"\n [(selectedCategory)]=\"selectedCategory\"\n (selectedCategoryChange)=\"onSelectedCategoryChange($event)\"\n ></lib-list-category-selector>\n}\n<!---->\n\n<!-- Toolbar Template -->\n<ng-template #toolbarTpl>\n <div class=\"custom-toolbar\">\n <!-- List Title -->\n <span class=\"list-title\">\n @if (listConfig?.title; as listTitle) {\n @if (query.keyword || query.categoryId) {\n <!-- Title (with link for reset filter) -->\n <a\n href=\"javascript:void(0)\"\n (click)=\"query.keyword = ''; query.categoryId = undefined; this.fetchList()\"\n [matTooltip]=\"t('list.clearFilters')\"\n >{{ listTitle }}</a\n >\n <!---->\n } @else {\n <!-- Title -->\n {{ listTitle }}\n <!---->\n }\n } @else {\n <!-- Default Title -->\n {{ t('list.defaultTitle') }}\n <!---->\n }\n\n @if (query.categoryId && selectedCategory?.[0]; as categoryLabel) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Category -->\n {{ categoryLabel.label }}\n <!---->\n }\n\n @if (query.keyword) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Keyword -->\n \"{{ query.keyword }}\"\n <!---->\n }\n </span>\n <!---->\n\n @if (query.keyword || query.categoryId) {\n <span style=\"width: 8px\"></span>\n <!-- Clear Filters Button -->\n <button\n mat-icon-button\n class=\"clear-filters-button\"\n [matTooltip]=\"t('list.clearFilters')\"\n (click)=\"clearFilters()\"\n >\n <mat-icon>filter_alt_off</mat-icon>\n </button>\n <!---->\n }\n\n <span style=\"flex: 1\"></span>\n\n <!-- Create Button -->\n @if (listConfig?.createButton; as createBtn) {\n @if ($any(createBtn).routerLink; as routerLinkUrl) {\n <!-- Create Button with Router Link -->\n <a\n [routerLink]=\"routerLinkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).link; as linkUrl) {\n <!-- Create Button with Link -->\n <a\n [href]=\"linkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).click; as handler) {\n <!-- Create Button with Handler -->\n <button\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n (click)=\"handler()\"\n >\n {{ createBtn?.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </button>\n }\n }\n <!---->\n\n <span style=\"width: 30px\"></span>\n\n <!-- Search Field -->\n <mat-form-field class=\"search-keyword xs-input\" appearance=\"outline\">\n <mat-icon matPrefix>search</mat-icon>\n <input\n matInput\n [placeholder]=\"\n selectedCategory?.[0]?.label\n ? t('list.searchInCategoryPlaceholder', { category: selectedCategory?.[0]?.label })\n : t('list.searchDefaultPlaceholder')\n \"\n [(ngModel)]=\"query.keyword\"\n (keyup)=\"onKeywordInput()\"\n style=\"padding-top: 3px\"\n />\n\n <!-- Search clear button -->\n <button\n matSuffix\n mat-icon-button\n [attr.aria-label]=\"t('list.clearSearchKeyword')\"\n [matTooltip]=\"t('list.clearSearchKeyword')\"\n (click)=\"query.keyword = ''; this.fetchList()\"\n [style.visibility]=\"query.keyword ? 'visible' : 'hidden'\"\n >\n <mat-icon>highlight_off</mat-icon>\n </button>\n <!---->\n </mat-form-field>\n <!---->\n\n <span style=\"width: 8px\"></span>\n\n <!-- Refresh Button -->\n <button mat-icon-button [matTooltip]=\"t('list.refresh')\" (click)=\"fetchList()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <!---->\n\n <span style=\"width: 5px\"></span>\n\n <!-- CSV Export Button -->\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"csvExportMenu\"\n [matTooltip]=\"t('list.exportAsCsv')\"\n >\n <mat-icon>download</mat-icon>\n </button>\n <!---->\n\n <!-- CSV Export Menu -->\n <mat-menu #csvExportMenu=\"matMenu\">\n @for (encoder of csvExportService.getAvailableEncoders(); track encoder.key) {\n <!-- Export with specific charset -->\n <p style=\"color: #333; font-size: 0.8rem; margin: 1rem 0.75rem 1rem 0.7rem\">\n CSV ({{ encoder.label }})\n </p>\n <button mat-menu-item (click)=\"exportAsCsv(encoder.key)\">\n <mat-icon>download</mat-icon>\n <span>{{ t('list.exportItems', { count: totalCount }) }}</span>\n </button>\n <!---->\n }\n </mat-menu>\n <!---->\n </div>\n</ng-template>\n<!---->\n\n<!-- List (Grid) -->\n<mtx-grid\n [data]=\"gridData\"\n [columns]=\"gridColumns\"\n [showToolbar]=\"true\"\n [toolbarTemplate]=\"toolbarTpl\"\n [length]=\"totalCount\"\n [loading]=\"isLoading\"\n [pageOnFront]=\"false\"\n [pageIndex]=\"query.page\"\n [pageSize]=\"query.perPage\"\n [pageSizeOptions]=\"listConfig?.pageSizes ?? [10, 25, 50, 100]\"\n columnMenuButtonType=\"icon\"\n columnMenuButtonClass=\"column-menu-button\"\n columnMenuButtonIcon=\"view_column\"\n (page)=\"onPageChange($event)\"\n></mtx-grid>\n<!---->\n\n<!-- Cell Template with Link -->\n<ng-template #cellTplWithLink let-row let-index=\"index\" let-col=\"colDef\">\n @if (col.link) {\n <a [href]=\"col.link(row)\">\n {{ row[col.field] }}\n </a>\n } @else if (col.routerLink) {\n <a [routerLink]=\"col.routerLink(row)\">\n {{ row[col.field] }}\n </a>\n } @else {\n {{ row[col.field] }}\n }\n</ng-template>\n<!---->\n","import { Component, TemplateRef, ViewChild, AfterViewInit } from '@angular/core';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatPrefix, MatSuffix } from '@angular/material/input';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { FieldWrapper, FormlyFieldConfig } from '@ngx-formly/core';\n\n@Component({\n selector: 'lib-formly-mat-prefix-addon-wrapper',\n imports: [MatIconButton, MatIcon, MatSuffix, MatTooltip],\n template: `\n <ng-container #fieldComponent></ng-container>\n\n <ng-template #matSuffix>\n @if (props['addonRight']) {\n @if (props['addonRight']['icon']) {\n <button\n mat-icon-button\n matSuffix\n style=\"margin-right: 1rem;\"\n [matTooltip]=\"props['addonRight']['tooltip'] ?? ''\"\n (click)=\"props['addonRight'].onClick ? addonRightClick($event) : null\"\n type=\"button\"\n >\n <mat-icon>{{ props['addonRight']['icon'] }}</mat-icon>\n </button>\n }\n @if (props['addonRight']['text']) {\n <span>{{ props['addonRight']['text'] }}</span>\n }\n }\n </ng-template>\n `,\n})\nexport class FormlyMatPrefixAddonWrapper extends FieldWrapper implements AfterViewInit {\n @ViewChild('matPrefix', { static: true }) matPrefix!: TemplateRef<any>;\n @ViewChild('matSuffix', { static: true }) matSuffix!: TemplateRef<any>;\n\n ngAfterViewInit() {\n if (this.matPrefix) {\n this.props['prefix'] = this.matPrefix;\n }\n\n if (this.matSuffix) {\n this.props['suffix'] = this.matSuffix;\n }\n }\n\n addonRightClick($event: any) {\n if (this.props['addonRight'].onClick) {\n this.props['addonRight'].onClick(this.to, this, $event);\n }\n }\n\n addonLeftClick($event: any) {\n if (this.props['addonLeft'].onClick) {\n this.props['addonLeft'].onClick(this.to, this, $event);\n }\n }\n}\n\nexport function formlyAddonsExtension(field: FormlyFieldConfig) {\n if (!field.props || (field.wrappers && field.wrappers.indexOf('addons') !== -1)) {\n return;\n }\n\n if (field.props['addonLeft'] || field.props['addonRight']) {\n field.wrappers = [...(field.wrappers || []), 'addons'];\n }\n}\n","import { Component } from '@angular/core';\nimport { FormlyAttributes, FieldType, FieldTypeConfig } from '@ngx-formly/core';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport {\n MatFormField,\n MatLabel,\n MatHint,\n MatSuffix,\n} from '@angular/material/form-field';\n\n@Component({\n selector: 'formly-field-file',\n template: `\n <mat-form-field appearance=\"outline\" floatLabel=\"always\" subscriptSizing=\"dynamic\" style=\"width:100%\">\n <!-- Field label -->\n @if (props.label) {\n <mat-label>{{ props.label }}{{ props.required ? ' *' : '' }}</mat-label>\n }\n \n <!-- Choosed file name -->\n <input matInput type=\"text\" readonly [value]=\"fileName\" [formlyAttributes]=\"field\" (click)=\"fileInput.click()\" />\n\n <!-- File choose button -->\n <button mat-icon-button matSuffix style=\"margin-right: 1rem;\" type=\"button\" (click)=\"fileInput.click()\">\n <mat-icon>attach_file</mat-icon>\n </button>\n\n <!-- Actual file input (hidden) -->\n <input\n type=\"file\"\n #fileInput\n style=\"display: none\"\n [attr.accept]=\"props['accept'] ?? null\"\n (change)=\"onFileChange($event)\"\n />\n\n <!-- Field description -->\n @if (props.description) {\n <mat-hint>{{ props.description }}</mat-hint>\n }\n </mat-form-field>\n `,\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormlyAttributes,\n MatInputModule,\n MatIcon,\n MatIconButton,\n MatFormField,\n MatLabel,\n MatHint,\n MatSuffix,\n ],\n})\nexport class FormlyFieldFile extends FieldType<FieldTypeConfig> {\n /** 表示用のファイル名 */\n fileName = '';\n\n /** ファイルが選択されたときの処理 */\n onFileChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0] ?? null;\n\n // formControl に File オブジェクトをセット\n this.formControl.setValue(file);\n this.formControl.markAsDirty();\n\n // 表示用のファイル名を更新\n this.fileName = file?.name ?? '';\n }\n}\n\n","import {\n ChangeDetectorRef,\n Component,\n inject,\n Input,\n OnChanges,\n SimpleChanges,\n} from '@angular/core';\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatCard, MatCardHeader, MatCardContent } from '@angular/material/card';\nimport { FormlyFieldConfig, FormlyForm, provideFormlyCore } from '@ngx-formly/core';\nimport { withFormlyMaterial } from '@ngx-formly/material';\nimport {\n NgxThinAdminEditorConfig,\n NgxThinAdminEditorField,\n NgxThinAdminItemDeleterConfig,\n} from '../interfaces';\nimport { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';\nimport {\n formlyAddonsExtension,\n FormlyMatPrefixAddonWrapper,\n} from '../shared/formly/mat-prefix-addon-wrapper/mat-prefix-addon-wrapper';\nimport { MatProgressBar } from '@angular/material/progress-bar';\nimport { getErrorMessage } from '../shared/error-handler';\nimport { FormlyFieldFile } from '../shared/formly/file-input/file-type.component';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../i18n';\nimport { MatDialog } from '@angular/material/dialog';\nimport { ConfirmDialog, ConfirmDialogData } from '../shared/confirm-dialog/confirm-dialog';\nimport { lastValueFrom } from 'rxjs';\nimport { Router, RouterLink } from '@angular/router';\n\n@Component({\n selector: 'ngx-thin-admin-editor',\n imports: [\n ReactiveFormsModule,\n FormlyForm,\n MatButton,\n MatIconButton,\n MatIcon,\n MatTooltip,\n RouterLink,\n MatProgressBar,\n MatCard,\n MatCardHeader,\n MatCardContent,\n ],\n providers: [\n provideFormlyCore(withFormlyMaterial()),\n provideFormlyCore({\n wrappers: [\n {\n name: 'addons',\n component: FormlyMatPrefixAddonWrapper,\n },\n ],\n extensions: [{ name: 'addons', extension: { onPopulate: formlyAddonsExtension } }],\n types: [\n {\n name: 'file',\n component: FormlyFieldFile,\n },\n ],\n }),\n {\n // Apply default appearance and other settings to all Material form fields in this component\n provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,\n useValue: {\n appearance: 'outline',\n floatLabel: 'always',\n subscriptSizing: 'dynamic',\n },\n },\n ],\n templateUrl: './ngx-thin-admin-editor.html',\n styleUrl: './ngx-thin-admin-editor.scss',\n})\nexport class NgxThinAdminEditor implements OnChanges {\n /**\n * Config for editor\n */\n @Input()\n editorConfig?: NgxThinAdminEditorConfig;\n\n /**\n * Fields for formly form\n */\n @Input()\n editorFields?: NgxThinAdminEditorField[];\n\n /**\n * Id of the item being edited.\n */\n @Input()\n itemId?: string;\n\n /**\n * Config for item deleter\n */\n @Input()\n itemDeleterConfig?: NgxThinAdminItemDeleterConfig;\n\n /**\n * Internal state for form\n */\n isSaving = false;\n isLoading = false;\n form = new FormGroup({});\n data: any = {};\n formData: any = {};\n\n /**\n * For history back\n */\n windowHistory = window.history;\n\n /**\n * Services\n */\n private snackbar = inject(MatSnackBar);\n private cdr = inject(ChangeDetectorRef);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n private dialog = inject(MatDialog);\n private router = inject(Router);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n get editorItemType(): string {\n return this.editorConfig?.singularLabel || this.t('item.defaultSingular');\n }\n\n ngOnChanges(changes: SimpleChanges<NgxThinAdminEditor>) {\n // Fetcher\n if (\n changes.editorConfig &&\n changes.editorConfig.currentValue?.fetcher !== changes.editorConfig.previousValue?.fetcher\n ) {\n this.fetchItem();\n } else if (changes.itemId && changes.itemId.currentValue !== changes.itemId.previousValue) {\n this.fetchItem();\n }\n\n // Fields\n if (changes.editorFields?.currentValue) {\n this.editorFields = changes.editorFields.currentValue.map((col: NgxThinAdminEditorField) => {\n return this.overwriteFieldProps(col);\n });\n }\n }\n\n overwriteFieldProps(field: NgxThinAdminEditorField) {\n if (!field.props) {\n field.props = {};\n }\n\n // requiredOnCreate\n if (field.props.requiredOnCreate) {\n if (this.itemId === undefined) {\n field.props.required = true;\n } else {\n field.props.required = false;\n }\n }\n\n // disabledOnUpdate\n if (field.props.disabledOnUpdate) {\n if (this.itemId !== undefined) {\n //formControl.disable();\n field.props.disabled = true;\n } else {\n //formControl.enable();\n field.props.disabled = false;\n }\n }\n\n return field;\n }\n\n async fetchItem() {\n if (!this.editorConfig?.fetcher) {\n return;\n } else if (!this.itemId) {\n this.data = {};\n return;\n }\n\n // Set loading state\n this.isLoading = true;\n this.cdr.markForCheck();\n\n // Call the fetcher function to get the item data\n try {\n let res = await this.editorConfig.fetcher(this.itemId);\n\n if (res instanceof Response) {\n if (!res.ok) {\n const data = await res.json();\n throw new Error(\n data.error ?? data.message ?? `Failed to fetch data: ${res.status} ${res.statusText}`,\n );\n }\n res = await res.json();\n }\n\n this.data = { ...res };\n this.formData = { ...res };\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(`Error: ${errorMessage}`, undefined, {\n duration: 3000,\n });\n\n // Reset loading state\n this.isLoading = false;\n this.cdr.markForCheck();\n return;\n }\n\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n\n async save() {\n if (this.form.status === 'INVALID') {\n this.snackbar.open(`Error: ${this.t('editor.errorInvalidInput')}`, undefined, {\n duration: 3000,\n });\n\n // Mark field to show validation errors\n Object.keys(this.form.controls).forEach((key) => {\n const control = this.form.get(key);\n control?.markAsTouched();\n });\n\n return;\n }\n\n if (!this.editorConfig?.saver) {\n this.snackbar.open(`Error: ${this.t('editor.errorNoSaver')}`, undefined, {\n duration: 3000,\n });\n return;\n }\n\n // Disable the form and save button to prevent multiple submissions\n this.form.disable();\n this.isSaving = true;\n\n // Call the saver function\n let result: any;\n try {\n let res: any = await this.editorConfig.saver(this.formData, this.itemId);\n\n if (res instanceof Response) {\n if (!res.ok) {\n const data = await res.json();\n throw new Error(\n data.error ?? data.message ?? `Failed to save data: ${res.status} ${res.statusText}`,\n );\n }\n res = await res.json();\n }\n\n result = res;\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(`Error: ${errorMessage}`, undefined, {\n duration: 3000,\n });\n\n // Re-enable the form and save button\n this.form.enable();\n this.isSaving = false;\n\n return;\n }\n\n // Show success message\n this.snackbar.open(this.t('editor.successSaved'), undefined, {\n duration: 3000,\n });\n\n // Update form data with the result from the saver (e.g., to get generated ID)\n this.data = { ...result };\n this.formData = { ...result };\n\n // Re-enable the form and save button\n this.form.enable();\n for (const field of this.editorFields ?? []) {\n this.overwriteFieldProps(field);\n }\n this.isSaving = false;\n }\n\n async openDeletionDialog() {\n if (!this.itemDeleterConfig?.deleter || this.itemId === undefined) {\n return;\n }\n\n // Get the label and ID to query in the confirmation dialog\n const id = this.itemId;\n const label = this.editorConfig?.labelFieldKey\n ? this.data[this.editorConfig.labelFieldKey]\n : id;\n const itemType = this.editorItemType;\n\n // Open the confirmation dialog\n const dialogRef = this.dialog.open(ConfirmDialog, {\n width: '400px',\n data: {\n title: this.t('item.deletionDialogTitle', { itemType }),\n message: this.t('item.deletionDialogMessage', { label, id }),\n positiveButtonText: this.t('common.delete'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies ConfirmDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n // Execute delete process\n await this.deleteItem(id, label);\n }\n\n async deleteItem(id: string, label: string) {\n if (!this.itemDeleterConfig?.deleter) {\n return;\n }\n\n try {\n await this.itemDeleterConfig.deleter(id);\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(\n `Error: ${errorMessage || this.t('item.errorFailedDelete', { label })}`,\n undefined,\n { duration: 3000 },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(this.t('item.successDeleted', { label }), undefined, {\n duration: 3000,\n });\n\n // Subsequence routing\n if (this.itemDeleterConfig.afterDeleteNavigateTo) {\n this.router.navigate([this.itemDeleterConfig.afterDeleteNavigateTo]);\n }\n }\n}\n","<mat-card>\n <mat-card-header style=\"position: relative\">\n <!-- Back button -->\n @if (editorConfig?.backButton) {\n @if ($any(editorConfig?.backButton).historyBack && windowHistory.length > 1) {\n <button mat-button (click)=\"windowHistory.back()\" class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </button>\n } @else if ($any(editorConfig?.backButton).routerLink; as backButtonLink) {\n <a [routerLink]=\"backButtonLink\" mat-button class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </a>\n } @else if ($any(editorConfig?.backButton).link; as backButtonLink) {\n <a [href]=\"backButtonLink\" mat-button class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </a>\n } @else if ($any(editorConfig?.backButton).click; as handler) {\n <button mat-button (click)=\"handler()\" class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </button>\n }\n }\n <!---->\n\n <!-- Editor title -->\n <h3 style=\"margin: 0\" [style.margin-top]=\"editorConfig?.backButton ? '1rem' : '0'\">\n @if (itemId !== undefined && $any(data); as editItem) {\n @if (editorConfig?.labelFieldKey && editItem[editorConfig!.labelFieldKey!]) {\n <!-- e.g., \"Edit - Taro (taro) \" -->\n {{ t('common.edit') }} &nbsp; <span style=\"color: #aaaaaa\">-</span>\n <span class=\"editor-item-label\">{{ editItem[editorConfig!.labelFieldKey!] }}</span>\n @if (editorConfig?.idFieldKey && editItem[editorConfig!.idFieldKey!]) {\n <small class=\"editor-header-sub\">{{ editItem[editorConfig!.idFieldKey!] }}</small>\n }\n <!---->\n } @else if (editItem.id) {\n <!-- e.g., \"Edit - ID: 123\" -->\n {{ t('common.edit') }} &nbsp; <span style=\"color: #aaaaaa\">-</span>\n {{ t('editor.idLabel') }}:\n <span class=\"editor-item-label\">{{ editItem.id }}</span>\n <!---->\n } @else {\n <!-- e.g., \"Edit Account (123)\" -->\n {{ t('editor.titleForEdit', { itemType: editorItemType }) }}\n @if (editorConfig?.idFieldKey && editItem[editorConfig!.idFieldKey!]) {\n <small class=\"editor-header-sub\">{{ editItem[editorConfig!.idFieldKey!] }}</small>\n }\n <!---->\n }\n } @else {\n <!-- Create Account -->\n {{ t('editor.titleForCreate', { itemType: editorItemType }) }}\n <!---->\n }\n </h3>\n <!---->\n </mat-card-header>\n\n <mat-card-content>\n @if (isLoading || isSaving) {\n <mat-progress-bar mode=\"indeterminate\" style=\"margin-top: 1rem\"></mat-progress-bar>\n }\n\n @if (!isLoading) {\n <form [formGroup]=\"form\" (ngSubmit)=\"save()\">\n <formly-form\n [form]=\"form\"\n [fields]=\"$any(editorFields) ?? []\"\n [model]=\"formData\"\n ></formly-form>\n\n <!-- Button Area -->\n <div\n style=\"\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 0.5rem;\n \"\n >\n <!-- Delete button (visible only in edit mode and if itemDeleterConfig is provided) -->\n @if (itemDeleterConfig?.deleter && itemId !== undefined) {\n <button\n type=\"button\"\n mat-stroked-button\n color=\"warn\"\n (click)=\"openDeletionDialog()\"\n [disabled]=\"isLoading || isSaving\"\n >\n {{ t('common.delete') }}\n </button>\n } @else {\n <span></span>\n }\n <!---->\n\n <!-- Submit button (visible only if saver is provided) -->\n @if (editorConfig?.saver) {\n <button\n type=\"submit\"\n mat-flat-button\n style=\"color: white; transform: translateY(-0.3rem)\"\n >\n @if (itemId !== undefined) {\n {{ t('editor.saveChanges') }}\n } @else {\n {{ t('common.create') }}\n }\n </button>\n }\n <!---->\n </div>\n <!---->\n </form>\n }\n </mat-card-content>\n</mat-card>\n","/*\n * Public API Surface of ngx-thin-admin\n */\n\nexport * from './lib/ngx-thin-admin-list/ngx-thin-admin-list';\nexport * from './lib/ngx-thin-admin-editor/ngx-thin-admin-editor';\nexport * from './lib/interfaces';\nexport * from './lib/i18n';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","csvStringify","i2","MatFormField","MatSuffix"],"mappings":"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"}
1
+ {"version":3,"file":"ngx-thin-admin.mjs","sources":["../../../projects/ngx-thin-admin/src/lib/i18n.ts","../../../projects/ngx-thin-admin/src/lib/shared/category-editor-dialog/category-editor-dialog.ts","../../../projects/ngx-thin-admin/src/lib/shared/category-editor-dialog/category-editor-dialog.html","../../../projects/ngx-thin-admin/src/lib/shared/confirm-dialog/confirm-dialog.ts","../../../projects/ngx-thin-admin/src/lib/shared/confirm-dialog/confirm-dialog.html","../../../projects/ngx-thin-admin/src/lib/shared/error-handler.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/list-category-selector/list-category-selector.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/list-category-selector/list-category-selector.html","../../../projects/ngx-thin-admin/src/lib/shared/csv-export-service.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/category-change-dialog/category-change-dialog.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/category-change-dialog/category-change-dialog.html","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/ngx-thin-admin-list.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-list/ngx-thin-admin-list.html","../../../projects/ngx-thin-admin/src/lib/shared/formly/mat-prefix-addon-wrapper/mat-prefix-addon-wrapper.ts","../../../projects/ngx-thin-admin/src/lib/shared/formly/file-input/file-type.component.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-editor/ngx-thin-admin-editor.ts","../../../projects/ngx-thin-admin/src/lib/ngx-thin-admin-editor/ngx-thin-admin-editor.html","../../../projects/ngx-thin-admin/src/public-api.ts","../../../projects/ngx-thin-admin/src/ngx-thin-admin.ts"],"sourcesContent":["import { InjectionToken, Provider } from '@angular/core';\n\nexport type NgxThinAdminLocale = 'en' | 'ja';\n\nexport type NgxThinAdminI18nKey =\n | 'common.cancel'\n | 'common.ok'\n | 'common.save'\n | 'common.create'\n | 'common.edit'\n | 'common.delete'\n | 'common.back'\n | 'list.defaultTitle'\n | 'list.clearFilters'\n | 'list.searchDefaultPlaceholder'\n | 'list.searchInCategoryPlaceholder'\n | 'list.clearSearchKeyword'\n | 'list.refresh'\n | 'list.exportAsCsv'\n | 'list.exportedFileName'\n | 'list.exportItems'\n | 'editor.titleForCreate'\n | 'editor.titleForEdit'\n | 'editor.idLabel'\n | 'editor.saveChanges'\n | 'editor.errorInvalidInput'\n | 'editor.errorNoSaver'\n | 'editor.successSaved'\n | 'editor.backToList'\n | 'category.defaultSingular'\n | 'category.defaultPlural'\n | 'category.all'\n | 'category.editorDialogTitleForCreate'\n | 'category.editorDialogTitleForEdit'\n | 'category.deletionDialogTitle'\n | 'category.deletionDialogMessage'\n | 'category.errorCouldNotCreate'\n | 'category.errorFailedUpdate'\n | 'category.errorFailedDelete'\n | 'category.errorCouldNotSave'\n | 'category.successCreated'\n | 'category.successUpdated'\n | 'category.successDeleted'\n | 'item.defaultSingular'\n | 'item.deletionDialogTitle'\n | 'item.deletionDialogMessage'\n | 'item.errorFailedDelete'\n | 'item.successDeleted'\n | 'item.changeCategory'\n | 'item.changeCategoryDialogTitle'\n | 'item.changeCategoryDialogMessage'\n | 'item.successCategoryChanged'\n | 'item.errorFailedCategoryChange'\n | 'category.unselected'\n | 'csv.exporting'\n | 'csv.exportCompleted'\n | 'csv.exportCompletedWithErrors'\n | 'csv.errorGenerateFailed';\n\nexport type NgxThinAdminI18nParams = Record<string, string | number | undefined>;\nexport type NgxThinAdminTranslate = (\n key: NgxThinAdminI18nKey,\n params?: NgxThinAdminI18nParams,\n) => string;\n\nexport interface NgxThinAdminI18nConfig {\n locale?: NgxThinAdminLocale;\n messages?: Partial<Record<NgxThinAdminI18nKey, string>>;\n translate?: NgxThinAdminTranslate;\n}\n\nconst messagesEn: Record<NgxThinAdminI18nKey, string> = {\n 'common.cancel': 'Cancel',\n 'common.ok': 'OK',\n 'common.save': 'Save',\n 'common.create': 'Create',\n 'common.edit': 'Edit',\n 'common.delete': 'Delete',\n 'common.back': 'Back',\n 'list.defaultTitle': 'List',\n 'list.clearFilters': 'Clear filters',\n 'list.searchDefaultPlaceholder': 'Search...',\n 'list.searchInCategoryPlaceholder': 'Search in {category}...',\n 'list.clearSearchKeyword': 'Clear search keyword',\n 'list.refresh': 'Refresh',\n 'list.exportAsCsv': 'Export as CSV',\n 'list.exportedFileName': 'exported',\n 'list.exportItems': 'Export {count} items',\n 'editor.titleForCreate': 'Create {itemType}',\n 'editor.titleForEdit': 'Edit {itemType}',\n 'editor.idLabel': 'ID',\n 'editor.saveChanges': 'Save Changes',\n 'editor.errorInvalidInput': 'Invalid input',\n 'editor.errorNoSaver': 'No saver function provided',\n 'editor.successSaved': 'Data saved successfully',\n 'editor.backToList': 'To List',\n 'category.defaultSingular': 'Category',\n 'category.defaultPlural': 'Categories',\n 'category.all': 'All',\n 'category.editorDialogTitleForCreate': 'Create {categoryType}',\n 'category.editorDialogTitleForEdit': 'Edit {categoryType}',\n 'category.deletionDialogTitle': 'Delete {categoryType}',\n 'category.deletionDialogMessage':\n 'Are you sure you want to delete the {categoryType} \"{label}\"? This action cannot be undone.',\n 'category.errorCouldNotCreate': 'Could not create {categoryType}',\n 'category.errorFailedUpdate': 'Failed to update {categoryType} \"{label}\"',\n 'category.errorFailedDelete': 'Failed to delete {categoryType} \"{label}\"',\n 'category.errorCouldNotSave': 'Could not save {categoryType}',\n 'category.successCreated': '{categoryType} \"{label}\" has been created successfully',\n 'category.successUpdated': '{categoryType} \"{label}\" has been updated successfully',\n 'category.successDeleted': '{categoryType} \"{label}\" has been deleted successfully',\n 'item.defaultSingular': 'Item',\n 'item.deletionDialogTitle': 'Delete {itemType}',\n 'item.deletionDialogMessage':\n 'Are you sure you want to delete \"{label}\" ({id})? This action cannot be undone.',\n 'item.errorFailedDelete': 'Failed to delete \"{label}\"',\n 'item.successDeleted': '\"{label}\" has been deleted successfully',\n 'item.changeCategory': 'Change {categoryType}',\n 'item.changeCategoryDialogTitle': 'Change {categoryType}',\n 'item.changeCategoryDialogMessage': 'Select a {categoryType} to move \"{label}\" to.',\n 'item.successCategoryChanged': '{categoryType} changed successfully',\n 'item.errorFailedCategoryChange': 'Failed to change {categoryType} for \"{label}\"',\n 'category.unselected': 'Uncategorized',\n 'csv.exporting': 'Exporting CSV...',\n 'csv.exportCompleted': 'CSV export completed. Exported {count} items.',\n 'csv.exportCompletedWithErrors': 'CSV exported up to {count} items, but errors occurred: {error}',\n 'csv.errorGenerateFailed': 'Failed to generate CSV file.',\n};\n\nconst messagesJa: Record<NgxThinAdminI18nKey, string> = {\n 'common.cancel': 'キャンセル',\n 'common.ok': 'OK',\n 'common.save': '保存',\n 'common.create': '作成',\n 'common.edit': '編集',\n 'common.delete': '削除',\n 'common.back': '戻る',\n 'list.defaultTitle': '一覧',\n 'list.clearFilters': 'フィルターをクリア',\n 'list.searchDefaultPlaceholder': '検索...',\n 'list.searchInCategoryPlaceholder': '{category} 内を検索...',\n 'list.clearSearchKeyword': '検索キーワードをクリア',\n 'list.refresh': '再読み込み',\n 'list.exportAsCsv': 'CSV でエクスポート',\n 'list.exportedFileName': 'exported',\n 'list.exportItems': '{count} 件をエクスポート',\n 'editor.titleForCreate': '{itemType}の作成',\n 'editor.titleForEdit': '{itemType}の編集',\n 'editor.idLabel': 'ID',\n 'editor.saveChanges': '変更を保存',\n 'editor.errorInvalidInput': '入力内容が不正です',\n 'editor.errorNoSaver': '保存処理が設定されていません',\n 'editor.successSaved': '保存しました',\n 'editor.backToList': '一覧へ',\n 'category.defaultSingular': 'カテゴリ',\n 'category.defaultPlural': 'カテゴリ',\n 'category.all': 'すべて',\n 'category.editorDialogTitleForCreate': '{categoryType}の作成',\n 'category.editorDialogTitleForEdit': '{categoryType}の編集',\n 'category.deletionDialogTitle': '{categoryType}の削除',\n 'category.deletionDialogMessage':\n '{categoryType} \"{label}\" を削除しますか?この操作は元に戻せません。',\n 'category.errorCouldNotCreate': '{categoryType} を作成できませんでした',\n 'category.errorFailedUpdate': '{categoryType} \"{label}\" の更新に失敗しました',\n 'category.errorFailedDelete': '{categoryType} \"{label}\" の削除に失敗しました',\n 'category.errorCouldNotSave': '{categoryType} を保存できませんでした',\n 'category.successCreated': '{categoryType} \"{label}\" を作成しました',\n 'category.successUpdated': '{categoryType} \"{label}\" を更新しました',\n 'category.successDeleted': '{categoryType} \"{label}\" を削除しました',\n 'item.defaultSingular': '項目',\n 'item.deletionDialogTitle': '{itemType}の削除',\n 'item.deletionDialogMessage': '\"{label}\" ({id}) を削除しますか?この操作は元に戻せません。',\n 'item.errorFailedDelete': '\"{label}\" の削除に失敗しました',\n 'item.successDeleted': '\"{label}\" を削除しました',\n 'item.changeCategory': '{categoryType}を変更',\n 'item.changeCategoryDialogTitle': '{categoryType}の変更',\n 'item.changeCategoryDialogMessage': '\"{label}\" の移動先を選択してください',\n 'item.successCategoryChanged': '{categoryType}を変更しました',\n 'item.errorFailedCategoryChange': '「{label}」の{categoryType}変更に失敗しました',\n 'category.unselected': '未分類',\n 'csv.exporting': 'CSV をエクスポート中...',\n 'csv.exportCompleted': 'CSV エクスポートが完了しました。{count} 件をエクスポートしました。',\n 'csv.exportCompletedWithErrors':\n '{count} 件までエクスポートしましたが、エラーが発生しました: {error}',\n 'csv.errorGenerateFailed': 'CSV ファイルの生成に失敗しました。',\n};\n\nfunction interpolate(message: string, params?: NgxThinAdminI18nParams): string {\n if (!params) {\n return message;\n }\n\n return message.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const value = params[key];\n return value === undefined ? '' : String(value);\n });\n}\n\nfunction createTranslatorFromMessages(\n baseMessages: Record<NgxThinAdminI18nKey, string>,\n overrides?: Partial<Record<NgxThinAdminI18nKey, string>>,\n): NgxThinAdminTranslate {\n const merged = { ...baseMessages, ...overrides };\n return (key: NgxThinAdminI18nKey, params?: NgxThinAdminI18nParams): string => {\n return interpolate(merged[key] ?? messagesEn[key], params);\n };\n}\n\nexport const NGX_THIN_ADMIN_TRANSLATE = new InjectionToken<NgxThinAdminTranslate>(\n 'NGX_THIN_ADMIN_TRANSLATE',\n {\n providedIn: 'root',\n factory: () => createTranslatorFromMessages(messagesEn),\n },\n);\n\nexport function provideNgxThinAdminI18n(config?: NgxThinAdminI18nConfig): Provider {\n return {\n provide: NGX_THIN_ADMIN_TRANSLATE,\n useFactory: () => {\n if (config?.translate) {\n return config.translate;\n }\n\n const locale = config?.locale ?? 'en';\n const base = locale === 'ja' ? messagesJa : messagesEn;\n return createTranslatorFromMessages(base, config?.messages);\n },\n };\n}\n","import { Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MAT_DIALOG_DATA,\n MatDialogRef,\n} from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { NgxThinAdminCategory, NgxThinAdminCategorySelectorConfig } from '../../interfaces';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\n\nexport interface CategoryEditorDialogData {\n config: NgxThinAdminCategorySelectorConfig;\n editCategory?: NgxThinAdminCategory;\n positiveButtonText?: string;\n cancelButtonText?: string;\n}\n\n@Component({\n selector: 'lib-category-editor-dialog',\n imports: [\n MatFormFieldModule,\n MatInputModule,\n FormsModule,\n MatButtonModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n ],\n templateUrl: './category-editor-dialog.html',\n styleUrl: './category-editor-dialog.scss',\n})\nexport class CategoryEditorDialog {\n readonly dialogRef = inject(MatDialogRef<CategoryEditorDialog>);\n readonly data = inject<CategoryEditorDialogData>(MAT_DIALOG_DATA);\n private readonly translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n categoryLabel?: string;\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n save() {\n if (!this.categoryLabel) {\n return;\n }\n\n this.dialogRef.close({\n label: this.categoryLabel,\n });\n }\n}\n","<h2 mat-dialog-title>\n @if (data.editCategory) {\n {{\n t('category.editorDialogTitleForEdit', {\n categoryType: data.config.singularLabel ?? t('category.defaultSingular'),\n })\n }}\n } @else {\n {{\n t('category.editorDialogTitleForCreate', {\n categoryType: data.config.singularLabel ?? t('category.defaultSingular'),\n })\n }}\n }\n</h2>\n<form (ngSubmit)=\"save()\">\n <mat-dialog-content>\n <mat-form-field>\n <mat-label>{{ data.config.exampleLabel ?? data.config.singularLabel ?? '' }}</mat-label>\n <input\n matInput\n [(ngModel)]=\"categoryLabel\"\n name=\"categoryLabel\"\n cdkFocusInitial\n [value]=\"data.editCategory ? data.editCategory.label : ''\"\n />\n </mat-form-field>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button type=\"button\" class=\"cancel-btn\" matButton [mat-dialog-close]=\"undefined\">\n {{ data.cancelButtonText ?? t('common.cancel') }}\n </button>\n <button type=\"submit\" matButton>{{ data.positiveButtonText ?? t('common.save') }}</button>\n </mat-dialog-actions>\n</form>\n","import { Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MAT_DIALOG_DATA,\n MatDialogRef,\n} from '@angular/material/dialog';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\n\nexport interface ConfirmDialogData {\n title?: string;\n message?: string;\n positiveButtonText?: string;\n cancelButtonText?: string;\n}\n\n@Component({\n selector: 'lib-confirm-dialog',\n imports: [\n FormsModule,\n MatButtonModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n ],\n templateUrl: './confirm-dialog.html',\n styleUrl: './confirm-dialog.scss',\n})\nexport class ConfirmDialog {\n readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);\n readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);\n private readonly translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n}\n","<h2 mat-dialog-title>{{ data.title }}</h2>\n<mat-dialog-content>\n {{ data.message }}\n</mat-dialog-content>\n<mat-dialog-actions>\n <button class=\"cancel-btn\" matButton [mat-dialog-close]=\"undefined\">\n {{ data.cancelButtonText || t('common.cancel') }}\n </button>\n <button matButton [mat-dialog-close]=\"true\" cdkFocusInitial>\n {{ data.positiveButtonText || t('common.ok') }}\n </button>\n</mat-dialog-actions>\n","export function getErrorMessage(error: any): string {\n if (typeof error === 'string') {\n return error;\n } else if (error instanceof Error) {\n return error.message;\n } else if (error?.error?.message) {\n if (Array.isArray(error.error.message)) {\n return error.error.message[0];\n } else {\n return error.error.message;\n }\n } else {\n return 'An unknown error occurred';\n }\n}\n","import {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n inject,\n Input,\n Output,\n SimpleChanges,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatListOption, MatSelectionList } from '@angular/material/list';\nimport {\n NgxThinAdminCategory,\n NgxThinAdminCategoryListResponse,\n NgxThinAdminCategorySelectorConfig,\n} from '../../interfaces';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatMenu, MatMenuContent, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatDialog } from '@angular/material/dialog';\nimport {\n CategoryEditorDialog,\n CategoryEditorDialogData,\n} from '../../shared/category-editor-dialog/category-editor-dialog';\nimport { lastValueFrom, single } from 'rxjs';\nimport { ConfirmDialog, ConfirmDialogData } from '../../shared/confirm-dialog/confirm-dialog';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\nimport { getErrorMessage } from '../../shared/error-handler';\n\n@Component({\n selector: 'lib-list-category-selector',\n imports: [\n FormsModule,\n MatIcon,\n MatIconButton,\n MatSelectionList,\n MatMenu,\n MatMenuItem,\n MatMenuTrigger,\n MatListOption,\n MatMenuContent,\n ],\n templateUrl: './list-category-selector.html',\n styleUrl: './list-category-selector.scss',\n})\nexport class ListCategorySelector {\n /**\n * Config for the category selector\n */\n @Input() config?: NgxThinAdminCategorySelectorConfig;\n\n /**\n * Selected category. This will be updated when the user selects a category from the list.\n */\n @Input()\n selectedCategory?: (NgxThinAdminCategory | undefined)[];\n\n /**\n * Event emitted when the selected category changes.\n */\n @Output()\n selectedCategoryChange = new EventEmitter<(NgxThinAdminCategory | undefined)[]>();\n\n /**\n * Categories to be displayed in the category selector.\n */\n categories: NgxThinAdminCategory[] = [];\n\n /**\n * Services\n */\n private snackbar = inject(MatSnackBar);\n private dialog = inject(MatDialog);\n private cdr = inject(ChangeDetectorRef);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n ngOnChanges(changes: SimpleChanges<ListCategorySelector>) {\n if (\n changes.config &&\n changes.config.currentValue?.fetcher !== changes.config.previousValue?.fetcher\n ) {\n this.fetchCategories();\n }\n }\n\n async fetchCategories() {\n if (!this.config?.fetcher) {\n return;\n } else if (!(this.config.fetcher instanceof Function)) {\n throw new Error('categoryFetcher must be a function');\n }\n\n console.log('Fetching categories');\n try {\n const result = await Promise.resolve(this.config.fetcher());\n console.log(result);\n this.categories = result.categories;\n this.cdr.markForCheck();\n console.log('Fetched categories:', this.categories);\n } catch (e) {\n console.error('Error fetching categories:', e);\n }\n }\n\n async createCategory(categoryLabel: string) {\n if (!this.config?.creator) {\n return;\n }\n\n // Call the category creator function\n try {\n const res = await this.config.creator(categoryLabel);\n if (res && 'ok' in res && !res.ok) {\n const errorMessage = getErrorMessage(res);\n throw new Error(errorMessage);\n }\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${e?.message ?? this.t('category.errorCouldNotCreate', { categoryType: this.config.singularLabel ?? this.t('category.defaultSingular') })}`,\n undefined,\n {\n duration: 3000,\n },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(\n this.t('category.successCreated', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: categoryLabel,\n }),\n undefined,\n {\n duration: 3000,\n },\n );\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async updateCategory(category: NgxThinAdminCategory) {\n if (!this.config?.updater) {\n return;\n }\n\n // Call the category updater function\n try {\n const res = await this.config.updater(category);\n if (res && 'ok' in res && !res.ok) {\n const errorMessage = getErrorMessage(res);\n throw new Error(errorMessage);\n }\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorFailedUpdate', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(\n this.t('category.successUpdated', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n }),\n undefined,\n {\n duration: 3000,\n },\n );\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async deleteCategory(category: NgxThinAdminCategory) {\n if (!this.config?.deleter) {\n return;\n }\n\n // Call the category deleter function\n try {\n const res = await this.config.deleter(category);\n if (res && 'ok' in res && !res.ok) {\n const errorMessage = getErrorMessage(res);\n throw new Error(errorMessage);\n }\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorFailedDelete', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(\n this.t('category.successDeleted', {\n categoryType: this.config.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n }),\n undefined,\n {\n duration: 3000,\n },\n );\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async openCategoryEditorDialog(editCategory: NgxThinAdminCategory | undefined) {\n // Open a dialog for category creation / editing\n const dialogRef = this.dialog.open(CategoryEditorDialog, {\n width: '400px',\n data: {\n config: this.config!,\n editCategory: editCategory,\n positiveButtonText: editCategory ? this.t('common.save') : this.t('common.create'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies CategoryEditorDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result || !result.label) {\n return;\n }\n\n // Call the category creator / updater function\n try {\n if (editCategory) {\n await this.updateCategory({ ...editCategory, label: result.label });\n } else {\n await this.createCategory(result.label);\n }\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorCouldNotSave', {\n categoryType: this.config!.singularLabel ?? this.t('category.defaultSingular'),\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n }\n\n // Refresh category list\n this.fetchCategories();\n }\n\n async openCategoryDeletionDialog(category: NgxThinAdminCategory) {\n // Open a dialog for category deletion\n const dialogRef = this.dialog.open(ConfirmDialog, {\n width: '400px',\n data: {\n title: this.t('category.deletionDialogTitle', {\n categoryType: this.config?.singularLabel ?? this.t('category.defaultSingular'),\n }),\n message: this.t('category.deletionDialogMessage', {\n categoryType: this.config?.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n }),\n positiveButtonText: this.t('common.delete'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies ConfirmDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n // Call the category deleter function\n try {\n await this.deleteCategory(category);\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorFailedDelete', {\n categoryType: this.config?.singularLabel ?? this.t('category.defaultSingular'),\n label: category.label,\n })\n }`,\n undefined,\n {\n duration: 3000,\n },\n );\n }\n\n // Refresh category list\n this.fetchCategories();\n }\n}\n","<header>\n <!-- Category selector title -->\n <span class=\"category-selector-title\">\n {{ config?.title ?? t('category.defaultPlural') }}\n </span>\n <!---->\n\n <!-- Category Creation button -->\n @if (config?.creator) {\n <button\n mat-icon-button\n (click)=\"openCategoryEditorDialog(undefined)\"\n class=\"create-category-button\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n <!---->\n</header>\n\n<mat-selection-list\n #categorySelector\n [multiple]=\"false\"\n [hideSingleSelectionIndicator]=\"true\"\n [(ngModel)]=\"selectedCategory\"\n (selectionChange)=\"this.selectedCategoryChange.emit(selectedCategory)\"\n>\n <!-- \"All\" Category -->\n <mat-list-option\n [value]=\"undefined\"\n [class.active]=\"selectedCategory && selectedCategory[0] === undefined\"\n >\n <div matListItemTitle>\n <!-- Category label -->\n {{ t('category.all') }}&nbsp;\n <!---->\n </div>\n </mat-list-option>\n <!---->\n\n <!-- Each category -->\n @for (category of categories; track category.id) {\n <mat-list-option\n [value]=\"category\"\n [class.active]=\"selectedCategory && selectedCategory[0]?.id === category.id\"\n >\n <div matListItemTitle>\n <!-- Category label -->\n {{ category.label }}&nbsp;\n <!---->\n\n <!-- Count of items in the category -->\n @if (category.itemCount !== undefined) {\n <small> ({{ category.itemCount }}) </small>\n }\n <!---->\n </div>\n\n <!-- Category menu button -->\n @if (\n selectedCategory &&\n selectedCategory[0] !== undefined &&\n selectedCategory[0].id === category.id &&\n (config?.updater || config?.deleter)\n ) {\n <button\n matIconButton\n [matMenuTriggerFor]=\"menu\"\n [matMenuTriggerData]=\"{ category: category }\"\n class=\"category-menu-button\"\n >\n <mat-icon>more_vert</mat-icon>\n </button>\n }\n <!---->\n </mat-list-option>\n }\n <!---->\n</mat-selection-list>\n\n<!-- Category Menu -->\n<mat-menu #menu=\"matMenu\">\n <ng-template matMenuContent let-category=\"category\">\n @if (config?.updater) {\n <button mat-menu-item (click)=\"openCategoryEditorDialog(category)\">\n {{ t('common.edit') }}\n </button>\n }\n @if (config?.deleter) {\n <button mat-menu-item (click)=\"openCategoryDeletionDialog(category)\">\n {{ t('common.delete') }}\n </button>\n }\n </ng-template>\n</mat-menu>\n<!---->\n","import { inject, Injectable } from '@angular/core';\nimport {\n ListFetcher,\n NgxThinAdminListColumn,\n NgxThinAdminListQuery,\n NgxThinAdminListResponse,\n} from '../interfaces';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { ColumnOption, stringify as csvStringify } from 'csv-stringify/browser/esm/sync';\nimport { NGX_THIN_ADMIN_TRANSLATE } from '../i18n';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CsvExportService {\n private snackbar = inject(MatSnackBar);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n\n private encoders: {\n key: string;\n label: string;\n mimeCharset: string;\n encoder: ((input: string) => ArrayBuffer | null) | undefined;\n }[] = [\n {\n key: 'utf8',\n label: 'UTF-8',\n mimeCharset: 'UTF-8',\n encoder: undefined,\n },\n ];\n\n constructor() {\n this.loadOptionalEncoders();\n }\n\n private async loadOptionalEncoders() {\n // Optional charset support for Shift_JIS (commonly used in Japan)\n try {\n // @ts-ignore\n const Encoding = (await import('encoding-japanese')) as any;\n this.encoders.push({\n key: 'sjis',\n label: 'Shift_JIS',\n mimeCharset: 'Shift_JIS',\n encoder: (input: string) => {\n const sjisArrayBuffer = Encoding.convert(input, {\n from: 'UNICODE',\n to: 'SJIS',\n type: 'arraybuffer',\n });\n return new Uint8Array(sjisArrayBuffer).buffer;\n },\n });\n } catch (error) {\n console.error(\n 'Shift_JIS encoder is not available. If you need it, please install \"encoding-japanese\" package.',\n error,\n );\n // Do nothing\n }\n }\n\n getAvailableEncoders() {\n return this.encoders.map((encoder) => ({\n key: encoder.key,\n label: encoder.label,\n }));\n }\n\n async exportListAsCsv(\n encoderKey: string,\n fileNamePrefix: string,\n fetcher: ListFetcher,\n listQuery: Omit<NgxThinAdminListQuery, 'page' | 'perPage'>,\n columns: NgxThinAdminListColumn[],\n ) {\n const CSV_EXPORT_MAX_PAGE_INDEX = 1000;\n const CSV_EXPORT_PAGE_SIZE = 25;\n\n console.log('Starting CSV export', listQuery, encoderKey);\n\n // Get encoder\n const encoderInfo = this.encoders.find((e) => e.key === encoderKey);\n if (!encoderInfo) {\n console.error(`exportListAsCsv - Encoder not found for key: ${encoderKey}`);\n return;\n }\n const mimeCharset = encoderInfo.mimeCharset;\n const encoder = encoderInfo.encoder;\n\n // Initialize\n const items: any[] = [];\n let errorMessage: string | undefined = undefined;\n\n // 処理中メッセージを表示\n const mes = this.snackbar.open(this.translate('csv.exporting'));\n\n // Replace characters in the file name prefix that cannot be used in file names\n fileNamePrefix = fileNamePrefix.replace(/[/¥\\\\*?:\"<>|@\\s;^.]/g, '_');\n\n // Truncate the file name prefix if it is too long\n const FILE_NAME_PREFIX_MAX_LENGTH = 100;\n if (fileNamePrefix.length > FILE_NAME_PREFIX_MAX_LENGTH) {\n fileNamePrefix = fileNamePrefix.substring(0, FILE_NAME_PREFIX_MAX_LENGTH);\n }\n\n // Generate file name\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const date = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n const datetimeString = `${year}${month}${date}_${hours}${minutes}${seconds}`;\n const csvFileName = `${fileNamePrefix}_${datetimeString}.csv`;\n\n // Fetch items page by page\n let numOfExportedItems = 0;\n for (let pageIndex = 0; pageIndex < CSV_EXPORT_MAX_PAGE_INDEX; pageIndex++) {\n const query: NgxThinAdminListQuery = {\n ...listQuery,\n page: pageIndex,\n perPage: CSV_EXPORT_PAGE_SIZE,\n };\n\n let result: NgxThinAdminListResponse;\n try {\n result = await fetcher(query);\n } catch (error: any) {\n console.error(`exportListAsCsv - Error fetching data:`, error);\n errorMessage = error.message || 'Unknown error';\n break;\n }\n\n // Wait for few seconds\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n if (result.items.length === 0) {\n // No items, exit\n break;\n }\n\n // Add fetched items\n items.push(...result.items);\n numOfExportedItems += result.items.length;\n }\n\n // Determine CSV columns\n const csvColumns: ColumnOption[] = columns\n .filter((column) => {\n if (column.type === 'button') {\n // Exclude columns that are buttons\n return false;\n }\n return true;\n })\n .map((column) => {\n // Get the column key (e.g., \"name\")\n const columnKey: string = column.field;\n // Get the column header string (e.g., \"User Name\")\n let columnHeader: string;\n if (typeof column.header === 'string') {\n columnHeader = column.header;\n } else {\n columnHeader = columnKey;\n }\n // Return column information for csv-stringify\n return {\n key: column.field,\n header: columnHeader,\n };\n })\n .filter((column) => column !== null);\n\n // Convert to CSV\n const csv = csvStringify(items, {\n header: true,\n columns: csvColumns,\n });\n\n // Generate Blob\n let blob: Blob | undefined = undefined;\n if (encoder) {\n const encodedData = encoder(csv);\n if (encodedData) {\n blob = new Blob([encodedData], { type: `text/csv; charset=${mimeCharset}` });\n } else {\n console.error(`exportListAsCsv - Encoding failed for encoder: ${encoderKey}`);\n }\n } else {\n blob = new Blob([csv], { type: `text/csv; charset=${mimeCharset}` });\n }\n\n if (!blob) {\n console.error(`exportListAsCsv - Blob is not created`);\n mes.dismiss();\n this.snackbar.open(this.translate('csv.errorGenerateFailed'), undefined, {\n duration: 5000,\n });\n return;\n }\n\n // Download as CSV\n const objectUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.download = csvFileName;\n a.href = objectUrl;\n a.click();\n\n // Revoke object URL after download\n URL.revokeObjectURL(objectUrl);\n\n // Dissmiss processing message\n mes.dismiss();\n\n // 結果メッセージを表示\n if (errorMessage) {\n this.snackbar.open(\n this.translate('csv.exportCompletedWithErrors', {\n count: numOfExportedItems,\n error: errorMessage,\n }),\n undefined,\n {\n duration: 5000,\n },\n );\n } else {\n this.snackbar.open(\n this.translate('csv.exportCompleted', { count: numOfExportedItems }),\n undefined,\n {\n duration: 3000,\n },\n );\n }\n }\n}\n","import { Component, inject, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MAT_DIALOG_DATA,\n MatDialogRef,\n MatDialog,\n} from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { NgxThinAdminCategory, NgxThinAdminCategorySelectorConfig } from '../../interfaces';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../../i18n';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport {\n CategoryEditorDialog,\n CategoryEditorDialogData,\n} from '../../shared/category-editor-dialog/category-editor-dialog';\nimport { lastValueFrom } from 'rxjs';\n\nexport interface CategoryChangeDialogData {\n itemLabel?: string;\n categorySelectorConfig: NgxThinAdminCategorySelectorConfig;\n currentCategoryId?: string;\n positiveButtonText?: string;\n cancelButtonText?: string;\n}\n\n@Component({\n selector: 'lib-category-change-dialog',\n imports: [\n MatFormFieldModule,\n MatSelectModule,\n FormsModule,\n MatButtonModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MatProgressSpinnerModule,\n MatIconModule,\n ],\n templateUrl: './category-change-dialog.html',\n styleUrl: './category-change-dialog.scss',\n})\nexport class CategoryChangeDialog implements OnInit {\n readonly dialogRef = inject(MatDialogRef<CategoryChangeDialog>);\n readonly data = inject<CategoryChangeDialogData>(MAT_DIALOG_DATA);\n private readonly translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly dialog = inject(MatDialog);\n private readonly snackbar = inject(MatSnackBar);\n\n categories: NgxThinAdminCategory[] = [];\n selectedCategoryId?: string;\n isLoading = false;\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n async ngOnInit() {\n this.selectedCategoryId = this.data.currentCategoryId;\n this.isLoading = true;\n this.cdr.markForCheck();\n\n try {\n const result = await Promise.resolve(this.data.categorySelectorConfig.fetcher());\n this.categories = result.categories;\n } catch (e) {\n console.error('Failed to fetch categories:', e);\n } finally {\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n save() {\n this.dialogRef.close({\n categoryId: this.selectedCategoryId,\n });\n }\n\n async createNewCategory() {\n if (!this.data.categorySelectorConfig.creator) return;\n\n const dialogRef = this.dialog.open(CategoryEditorDialog, {\n width: '400px',\n data: {\n config: this.data.categorySelectorConfig,\n editCategory: undefined,\n positiveButtonText: this.t('common.create'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies CategoryEditorDialogData,\n });\n\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result || !result.label) {\n return;\n }\n\n this.isLoading = true;\n this.cdr.markForCheck();\n\n try {\n const newCategory = await Promise.resolve(\n this.data.categorySelectorConfig.creator(result.label),\n );\n\n this.snackbar.open(\n this.t('category.successCreated', {\n categoryType:\n this.data.categorySelectorConfig.singularLabel ?? this.t('category.defaultSingular'),\n label: result.label,\n }),\n undefined,\n { duration: 3000 },\n );\n\n // Re-fetch categories\n const fetchResult = await Promise.resolve(this.data.categorySelectorConfig.fetcher());\n this.categories = fetchResult.categories;\n\n // Auto-select the newly created category\n this.selectedCategoryId = newCategory.id;\n } catch (e: any) {\n this.snackbar.open(\n `Error: ${\n e?.message ??\n this.t('category.errorCouldNotSave', {\n categoryType:\n this.data.categorySelectorConfig.singularLabel ?? this.t('category.defaultSingular'),\n })\n }`,\n undefined,\n { duration: 3000 },\n );\n } finally {\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n }\n}\n","<h2 mat-dialog-title>\n {{\n t('item.changeCategoryDialogTitle', {\n categoryType: data.categorySelectorConfig.singularLabel || t('category.defaultSingular'),\n })\n }}\n</h2>\n\n<mat-dialog-content>\n @if (data.itemLabel) {\n <p style=\"margin-top: 5px; margin-bottom: 1rem\">\n {{\n t('item.changeCategoryDialogMessage', {\n label: data.itemLabel,\n categoryType: data.categorySelectorConfig.singularLabel || t('category.defaultSingular'),\n })\n }}\n </p>\n }\n\n <mat-form-field appearance=\"outline\" style=\"width: 100%; margin-top: 10px\">\n <mat-label>{{\n data.categorySelectorConfig.singularLabel || t('category.defaultSingular')\n }}</mat-label>\n <mat-select [(ngModel)]=\"selectedCategoryId\" [disabled]=\"isLoading\">\n <mat-option [value]=\"undefined\">{{ t('category.unselected') }}</mat-option>\n @for (category of categories; track category.id) {\n <mat-option [value]=\"category.id\">{{ category.label }}</mat-option>\n }\n </mat-select>\n @if (isLoading) {\n <mat-spinner matSuffix diameter=\"20\" style=\"margin-right: 12px\"></mat-spinner>\n }\n </mat-form-field>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n @if (data.categorySelectorConfig.creator) {\n <button mat-button (click)=\"createNewCategory()\" [disabled]=\"isLoading\">\n <mat-icon style=\"margin-right: 4px; font-size: 1.2rem; width: 1.2rem; height: 1.2rem\"\n >add</mat-icon\n >\n <span>{{ t('common.create') }}</span>\n </button>\n }\n\n <span style=\"flex: 1\"></span>\n\n <button mat-button mat-dialog-close>\n {{ data.cancelButtonText || t('common.cancel') }}\n </button>\n <button mat-flat-button color=\"primary\" (click)=\"save()\" [disabled]=\"isLoading\">\n {{ data.positiveButtonText || t('common.save') }}\n </button>\n</mat-dialog-actions>\n","import {\n Component,\n inject,\n Input,\n OnChanges,\n OnInit,\n SimpleChanges,\n TemplateRef,\n ViewChild,\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatInput, MatPrefix, MatSuffix } from '@angular/material/input';\nimport { MatFormField } from '@angular/material/select';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { MtxGridColumn, MtxGridModule } from '@ng-matero/extensions/grid';\nimport {\n NgxThinAdminCategory,\n NgxThinAdminCategorySelectorConfig,\n NgxThinAdminListColumn,\n NgxThinAdminListConfig,\n NgxThinAdminListQuery,\n NgxThinAdminListResponse,\n NgxThinAdminItemDeleterConfig,\n} from '../interfaces';\nimport { FormsModule } from '@angular/forms';\nimport { PageEvent } from '@angular/material/paginator';\nimport { ChangeDetectorRef } from '@angular/core';\nimport { ListCategorySelector } from './list-category-selector/list-category-selector';\nimport { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatListOption } from '@angular/material/list';\nimport { CsvExportService } from '../shared/csv-export-service';\nimport { RouterLink } from '@angular/router';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../i18n';\nimport { MatDialog } from '@angular/material/dialog';\nimport { ConfirmDialog, ConfirmDialogData } from '../shared/confirm-dialog/confirm-dialog';\nimport {\n CategoryChangeDialog,\n CategoryChangeDialogData,\n} from './category-change-dialog/category-change-dialog';\nimport { lastValueFrom } from 'rxjs';\nimport { getErrorMessage } from '../shared/error-handler';\n\n@Component({\n selector: 'ngx-thin-admin-list',\n imports: [\n FormsModule,\n MtxGridModule,\n MatButton,\n MatIcon,\n MatIconButton,\n MatTooltip,\n MatFormField,\n MatInput,\n MatPrefix,\n MatSuffix,\n ListCategorySelector,\n MatMenu,\n MatMenuItem,\n MatMenuTrigger,\n RouterLink,\n ],\n templateUrl: './ngx-thin-admin-list.html',\n styleUrl: './ngx-thin-admin-list.scss',\n})\nexport class NgxThinAdminList<T = any> implements OnChanges, OnInit {\n /**\n * Config for list\n */\n @Input()\n listConfig?: NgxThinAdminListConfig<T>;\n\n /**\n * Config for category selector. If provided, a category selector will be displayed in the UI.\n */\n @Input()\n categorySelectorConfig?: NgxThinAdminCategorySelectorConfig;\n\n /**\n * Config for item deleter (If provided, item deletion feature is enabled)\n * It works by calling openItemDeletionDialog(row) from the click handler of the column definition.\n */\n @Input()\n itemDeleterConfig?: NgxThinAdminItemDeleterConfig;\n\n /**\n * Column schema (extended type of MtxGridColumn)\n * @see https://ng-matero.github.io/extensions/components/grid/api\n */\n @Input()\n listColumns?: (NgxThinAdminListColumn<T> | MtxGridColumn)[];\n\n /**\n * Query (Optional)\n */\n @Input() query: NgxThinAdminListQuery = {\n keyword: '',\n page: 0,\n perPage: 10,\n categoryId: undefined,\n };\n\n /**\n * Fetcher function to retrieve list data.\n * This should be provided as part of listConfig.\n */\n private listFetcher?: (\n query: NgxThinAdminListQuery,\n ) => Promise<NgxThinAdminListResponse> | NgxThinAdminListResponse;\n\n /**\n * Internal state for grid\n */\n isLoading = false;\n gridColumns: MtxGridColumn[] = [];\n gridData: T[] = [];\n totalCount: number = 0;\n\n /**\n * Internal state for category list\n */\n categories: NgxThinAdminCategory[] = [];\n selectedCategory?: NgxThinAdminCategory[] = [];\n\n /**\n * Internal subject to trigger keyword change with debounce\n */\n private keywordChanged$ = new Subject<void>();\n ngOnInit(): void {\n this.keywordChanged$.pipe(debounceTime(500)).subscribe(() => {\n this.fetchList();\n });\n }\n\n /**\n * Template for cells\n */\n @ViewChild('cellTplWithLink', { static: true }) cellTplWithLink!: TemplateRef<any>;\n\n /**\n * Category Selector\n */\n @ViewChild(ListCategorySelector) categorySelector?: ListCategorySelector;\n\n /**\n * Services\n */\n private cdr = inject(ChangeDetectorRef);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n private snackbar = inject(MatSnackBar);\n csvExportService = inject(CsvExportService);\n private dialog = inject(MatDialog);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n ngOnChanges(changes: SimpleChanges<NgxThinAdminList<T>>) {\n // Columns\n if (changes.listColumns?.currentValue || changes.listConfig?.currentValue) {\n this.buildGridColumns();\n }\n\n // List - trigger strictly when listFetcher is newly provided or explicitly changed\n if (changes.listConfig?.currentValue?.fetcher !== changes.listConfig?.previousValue?.fetcher) {\n this.listFetcher = changes.listConfig?.currentValue?.fetcher;\n this.fetchList();\n }\n }\n\n private buildGridColumns() {\n if (!this.listColumns) {\n this.gridColumns = [];\n return;\n }\n\n let columns = this.listColumns.map((col: NgxThinAdminListColumn) => {\n if (col.link || col.routerLink) {\n return { ...col, cellTemplate: this.cellTplWithLink };\n }\n return col;\n });\n\n if (this.listConfig?.categoryChanger && this.categorySelectorConfig) {\n const actionsColIndex = columns.findIndex(\n (col) => col.field === 'actions' && col.type === 'button',\n );\n\n const categoryType =\n this.categorySelectorConfig.singularLabel || this.t('category.defaultSingular');\n const changeCategoryBtn = {\n type: 'icon' as const,\n icon: 'folder_shared',\n tooltip: this.t('item.changeCategory', { categoryType }),\n click: (record: any) => this.openItemCategoryChangeDialog(record),\n };\n\n if (actionsColIndex >= 0) {\n const col = { ...columns[actionsColIndex] };\n const originalButtons = col.buttons;\n if (typeof originalButtons === 'function') {\n col.buttons = (record: any) => [...originalButtons(record), changeCategoryBtn];\n } else {\n col.buttons = [...(originalButtons || []), changeCategoryBtn];\n }\n columns[actionsColIndex] = col;\n } else {\n columns.push({\n header: 'Actions',\n field: 'actions',\n type: 'button',\n buttons: [changeCategoryBtn],\n });\n }\n }\n\n this.gridColumns = columns;\n }\n\n async fetchList() {\n if (!this.listFetcher) {\n return;\n } else if (!(this.listFetcher instanceof Function)) {\n throw new Error('listFetcher must be a function');\n }\n\n console.log('Fetching data with query:', this.query);\n this.isLoading = true;\n\n try {\n const result = await Promise.resolve(this.listFetcher(this.query));\n this.gridData = result.items;\n this.totalCount = result.totalCount;\n } catch (e) {\n console.error('Error fetching list data:', e);\n } finally {\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n clearFilters() {\n this.query.keyword = '';\n this.query.categoryId = undefined;\n this.selectedCategory = [];\n this.fetchList();\n }\n\n onKeywordInput() {\n this.keywordChanged$.next();\n }\n\n async exportAsCsv(encoderKey: 'utf8' | string) {\n if (!this.listFetcher) {\n return;\n }\n\n // Determine file name prefix\n let fileNamePrefix: string = this.listConfig?.title\n ? this.listConfig.title\n : this.t('list.exportedFileName');\n if (this.selectedCategory && this.selectedCategory[0]?.id) {\n // If a category is selected, include the category label in the file name prefix\n fileNamePrefix += `_${this.selectedCategory[0]?.label}`;\n }\n if (this.query.keyword && this.query.keyword.length > 0) {\n // If a search keyword is entered, include it in the file name prefix\n fileNamePrefix += `_${this.query.keyword}`;\n }\n\n // Execute export\n await this.csvExportService.exportListAsCsv(\n encoderKey,\n fileNamePrefix,\n this.listFetcher,\n {\n categoryId: this.selectedCategory ? this.selectedCategory[0]?.id : undefined,\n keyword: this.query.keyword,\n },\n this.listColumns!,\n );\n }\n\n onPageChange(event: PageEvent) {\n this.query.page = event.pageIndex;\n this.query.perPage = event.pageSize;\n this.fetchList();\n }\n\n onSelectedCategoryChange($event: (NgxThinAdminCategory | undefined)[]) {\n console.log('Selected category changed:', $event);\n const categoryId = $event && $event.length >= 1 && $event[0] ? $event[0].id : undefined;\n this.query.categoryId = categoryId;\n this.fetchList();\n }\n\n async openItemDeletionDialog(item: any) {\n if (!this.itemDeleterConfig?.deleter) {\n return;\n }\n\n // Get the label and ID to query in the confirmation dialog\n const idKey = this.listConfig?.idFieldKey;\n const labelKey = this.listConfig?.labelFieldKey;\n const id = idKey ? item[idKey] : (item.id ?? JSON.stringify(item));\n const label = labelKey ? item[labelKey] : id;\n const itemType = this.listConfig?.singularLabel || this.t('item.defaultSingular');\n\n // Open the confirmation dialog\n const dialogRef = this.dialog.open(ConfirmDialog, {\n width: '400px',\n data: {\n title: this.t('item.deletionDialogTitle', { itemType }),\n message: this.t('item.deletionDialogMessage', { label, id }),\n positiveButtonText: this.t('common.delete'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies ConfirmDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n // Execute delete process\n await this.deleteItem(id, label);\n }\n\n async deleteItem(id: string, label: string) {\n if (!this.itemDeleterConfig?.deleter) {\n return;\n }\n\n try {\n await this.itemDeleterConfig.deleter(id);\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(\n `Error: ${errorMessage || this.t('item.errorFailedDelete', { label })}`,\n undefined,\n { duration: 3000 },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(this.t('item.successDeleted', { label }), undefined, {\n duration: 3000,\n });\n\n // Refresh the list after deletion\n this.fetchList();\n }\n\n async openItemCategoryChangeDialog(item: any) {\n if (!this.listConfig?.categoryChanger || !this.categorySelectorConfig) {\n return;\n }\n\n const idKey = this.listConfig?.idFieldKey;\n const labelKey = this.listConfig?.labelFieldKey;\n const id = idKey ? item[idKey] : (item.id ?? JSON.stringify(item));\n const label = labelKey ? item[labelKey] : id;\n\n let currentCategoryId: string | undefined;\n if (typeof this.listConfig.categoryFieldKey === 'function') {\n currentCategoryId = this.listConfig.categoryFieldKey(item);\n } else if (typeof this.listConfig.categoryFieldKey === 'string') {\n currentCategoryId = item[this.listConfig.categoryFieldKey];\n } else {\n currentCategoryId = item.categoryId ?? item.category?.id;\n }\n\n const dialogRef = this.dialog.open(CategoryChangeDialog, {\n width: '400px',\n data: {\n itemLabel: label,\n categorySelectorConfig: this.categorySelectorConfig,\n currentCategoryId: currentCategoryId,\n positiveButtonText: this.t('common.save'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies CategoryChangeDialogData,\n });\n\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n const newCategoryId = result.categoryId;\n const categoryType =\n this.categorySelectorConfig.singularLabel || this.t('category.defaultSingular');\n\n try {\n const res = await this.listConfig.categoryChanger(id, newCategoryId);\n if (res && 'ok' in res && !res.ok) {\n const errorMessage = getErrorMessage(res);\n throw new Error(errorMessage);\n }\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(\n `Error: ${errorMessage || this.t('item.errorFailedCategoryChange', { label, categoryType })}`,\n undefined,\n { duration: 3000 },\n );\n return;\n }\n\n this.snackbar.open(this.t('item.successCategoryChanged', { label, categoryType }), undefined, {\n duration: 3000,\n });\n\n // Refresh the list and category selector\n this.fetchList();\n this.categorySelector?.fetchCategories();\n }\n}\n","<!-- Category Selector -->\n@if (categorySelectorConfig) {\n <lib-list-category-selector\n [config]=\"categorySelectorConfig\"\n [(selectedCategory)]=\"selectedCategory\"\n (selectedCategoryChange)=\"onSelectedCategoryChange($event)\"\n ></lib-list-category-selector>\n}\n<!---->\n\n<!-- Toolbar Template -->\n<ng-template #toolbarTpl>\n <div class=\"custom-toolbar\">\n <!-- List Title -->\n <span class=\"list-title\">\n @if (listConfig?.title; as listTitle) {\n @if (query.keyword || query.categoryId) {\n <!-- Title (with link for reset filter) -->\n <a\n href=\"javascript:void(0)\"\n (click)=\"query.keyword = ''; query.categoryId = undefined; this.fetchList()\"\n [matTooltip]=\"t('list.clearFilters')\"\n >{{ listTitle }}</a\n >\n <!---->\n } @else {\n <!-- Title -->\n {{ listTitle }}\n <!---->\n }\n } @else {\n <!-- Default Title -->\n {{ t('list.defaultTitle') }}\n <!---->\n }\n\n @if (query.categoryId && selectedCategory?.[0]; as categoryLabel) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Category -->\n {{ categoryLabel.label }}\n <!---->\n }\n\n @if (query.keyword) {\n <span class=\"material-icons list-title-separator\"> keyboard_arrow_right </span>\n <!-- Keyword -->\n \"{{ query.keyword }}\"\n <!---->\n }\n </span>\n <!---->\n\n @if (query.keyword || query.categoryId) {\n <span style=\"width: 8px\"></span>\n <!-- Clear Filters Button -->\n <button\n mat-icon-button\n class=\"clear-filters-button\"\n [matTooltip]=\"t('list.clearFilters')\"\n (click)=\"clearFilters()\"\n >\n <mat-icon>filter_alt_off</mat-icon>\n </button>\n <!---->\n }\n\n <span style=\"flex: 1\"></span>\n\n <!-- Create Button -->\n @if (listConfig?.createButton; as createBtn) {\n @if ($any(createBtn).routerLink; as routerLinkUrl) {\n <!-- Create Button with Router Link -->\n <a\n [routerLink]=\"routerLinkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).link; as linkUrl) {\n <!-- Create Button with Link -->\n <a\n [href]=\"linkUrl\"\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </a>\n } @else if ($any(createBtn).click; as handler) {\n <!-- Create Button with Handler -->\n <button\n mat-flat-button\n class=\"create-item-button\"\n style=\"color: white; transform: translateY(-1px)\"\n (click)=\"handler()\"\n >\n {{ createBtn?.label ?? t('common.create') }}\n <mat-icon style=\"margin-bottom: 1px\">add</mat-icon>\n </button>\n }\n }\n <!---->\n\n <span style=\"width: 30px\"></span>\n\n <!-- Search Field -->\n <mat-form-field class=\"search-keyword xs-input\" appearance=\"outline\">\n <mat-icon matPrefix>search</mat-icon>\n <input\n matInput\n [placeholder]=\"\n selectedCategory?.[0]?.label\n ? t('list.searchInCategoryPlaceholder', { category: selectedCategory?.[0]?.label })\n : t('list.searchDefaultPlaceholder')\n \"\n [(ngModel)]=\"query.keyword\"\n (keyup)=\"onKeywordInput()\"\n style=\"padding-top: 3px\"\n />\n\n <!-- Search clear button -->\n <button\n matSuffix\n mat-icon-button\n [attr.aria-label]=\"t('list.clearSearchKeyword')\"\n [matTooltip]=\"t('list.clearSearchKeyword')\"\n (click)=\"query.keyword = ''; this.fetchList()\"\n [style.visibility]=\"query.keyword ? 'visible' : 'hidden'\"\n >\n <mat-icon>highlight_off</mat-icon>\n </button>\n <!---->\n </mat-form-field>\n <!---->\n\n <span style=\"width: 8px\"></span>\n\n <!-- Refresh Button -->\n <button mat-icon-button [matTooltip]=\"t('list.refresh')\" (click)=\"fetchList()\">\n <mat-icon>refresh</mat-icon>\n </button>\n <!---->\n\n <span style=\"width: 5px\"></span>\n\n <!-- CSV Export Button -->\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"csvExportMenu\"\n [matTooltip]=\"t('list.exportAsCsv')\"\n >\n <mat-icon>download</mat-icon>\n </button>\n <!---->\n\n <!-- CSV Export Menu -->\n <mat-menu #csvExportMenu=\"matMenu\">\n @for (encoder of csvExportService.getAvailableEncoders(); track encoder.key) {\n <!-- Export with specific charset -->\n <p style=\"color: #333; font-size: 0.8rem; margin: 1rem 0.75rem 1rem 0.7rem\">\n CSV ({{ encoder.label }})\n </p>\n <button mat-menu-item (click)=\"exportAsCsv(encoder.key)\">\n <mat-icon>download</mat-icon>\n <span>{{ t('list.exportItems', { count: totalCount }) }}</span>\n </button>\n <!---->\n }\n </mat-menu>\n <!---->\n </div>\n</ng-template>\n<!---->\n\n<!-- List (Grid) -->\n<mtx-grid\n [data]=\"gridData\"\n [columns]=\"gridColumns\"\n [showToolbar]=\"true\"\n [toolbarTemplate]=\"toolbarTpl\"\n [length]=\"totalCount\"\n [loading]=\"isLoading\"\n [pageOnFront]=\"false\"\n [pageIndex]=\"query.page\"\n [pageSize]=\"query.perPage\"\n [pageSizeOptions]=\"listConfig?.pageSizes ?? [10, 25, 50, 100]\"\n columnMenuButtonType=\"icon\"\n columnMenuButtonClass=\"column-menu-button\"\n columnMenuButtonIcon=\"view_column\"\n (page)=\"onPageChange($event)\"\n></mtx-grid>\n<!---->\n\n<!-- Cell Template with Link -->\n<ng-template #cellTplWithLink let-row let-index=\"index\" let-col=\"colDef\">\n @if (col.link) {\n <a [href]=\"col.link(row)\">\n {{ row[col.field] }}\n </a>\n } @else if (col.routerLink) {\n <a [routerLink]=\"col.routerLink(row)\">\n {{ row[col.field] }}\n </a>\n } @else {\n {{ row[col.field] }}\n }\n</ng-template>\n<!---->\n","import { Component, TemplateRef, ViewChild, AfterViewInit } from '@angular/core';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatPrefix, MatSuffix } from '@angular/material/input';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { FieldWrapper, FormlyFieldConfig } from '@ngx-formly/core';\n\n@Component({\n selector: 'lib-formly-mat-prefix-addon-wrapper',\n imports: [MatIconButton, MatIcon, MatSuffix, MatTooltip],\n template: `\n <ng-container #fieldComponent></ng-container>\n\n <ng-template #matSuffix>\n @if (props['addonRight']) {\n @if (props['addonRight']['icon']) {\n <button\n mat-icon-button\n matSuffix\n style=\"margin-right: 1rem;\"\n [matTooltip]=\"props['addonRight']['tooltip'] ?? ''\"\n (click)=\"props['addonRight'].onClick ? addonRightClick($event) : null\"\n type=\"button\"\n >\n <mat-icon>{{ props['addonRight']['icon'] }}</mat-icon>\n </button>\n }\n @if (props['addonRight']['text']) {\n <span>{{ props['addonRight']['text'] }}</span>\n }\n }\n </ng-template>\n `,\n})\nexport class FormlyMatPrefixAddonWrapper extends FieldWrapper implements AfterViewInit {\n @ViewChild('matPrefix', { static: true }) matPrefix!: TemplateRef<any>;\n @ViewChild('matSuffix', { static: true }) matSuffix!: TemplateRef<any>;\n\n ngAfterViewInit() {\n if (this.matPrefix) {\n this.props['prefix'] = this.matPrefix;\n }\n\n if (this.matSuffix) {\n this.props['suffix'] = this.matSuffix;\n }\n }\n\n addonRightClick($event: any) {\n if (this.props['addonRight'].onClick) {\n this.props['addonRight'].onClick(this.to, this, $event);\n }\n }\n\n addonLeftClick($event: any) {\n if (this.props['addonLeft'].onClick) {\n this.props['addonLeft'].onClick(this.to, this, $event);\n }\n }\n}\n\nexport function formlyAddonsExtension(field: FormlyFieldConfig) {\n if (!field.props || (field.wrappers && field.wrappers.indexOf('addons') !== -1)) {\n return;\n }\n\n if (field.props['addonLeft'] || field.props['addonRight']) {\n field.wrappers = [...(field.wrappers || []), 'addons'];\n }\n}\n","import { Component } from '@angular/core';\nimport { FormlyAttributes, FieldType, FieldTypeConfig } from '@ngx-formly/core';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport {\n MatFormField,\n MatLabel,\n MatHint,\n MatSuffix,\n} from '@angular/material/form-field';\n\n@Component({\n selector: 'formly-field-file',\n template: `\n <mat-form-field appearance=\"outline\" floatLabel=\"always\" subscriptSizing=\"dynamic\" style=\"width:100%\">\n <!-- Field label -->\n @if (props.label) {\n <mat-label>{{ props.label }}{{ props.required ? ' *' : '' }}</mat-label>\n }\n \n <!-- Choosed file name -->\n <input matInput type=\"text\" readonly [value]=\"fileName\" [formlyAttributes]=\"field\" (click)=\"fileInput.click()\" />\n\n <!-- File choose button -->\n <button mat-icon-button matSuffix style=\"margin-right: 1rem;\" type=\"button\" (click)=\"fileInput.click()\">\n <mat-icon>attach_file</mat-icon>\n </button>\n\n <!-- Actual file input (hidden) -->\n <input\n type=\"file\"\n #fileInput\n style=\"display: none\"\n [attr.accept]=\"props['accept'] ?? null\"\n (change)=\"onFileChange($event)\"\n />\n\n <!-- Field description -->\n @if (props.description) {\n <mat-hint>{{ props.description }}</mat-hint>\n }\n </mat-form-field>\n `,\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormlyAttributes,\n MatInputModule,\n MatIcon,\n MatIconButton,\n MatFormField,\n MatLabel,\n MatHint,\n MatSuffix,\n ],\n})\nexport class FormlyFieldFile extends FieldType<FieldTypeConfig> {\n /** 表示用のファイル名 */\n fileName = '';\n\n /** ファイルが選択されたときの処理 */\n onFileChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0] ?? null;\n\n // formControl に File オブジェクトをセット\n this.formControl.setValue(file);\n this.formControl.markAsDirty();\n\n // 表示用のファイル名を更新\n this.fileName = file?.name ?? '';\n }\n}\n\n","import {\n ChangeDetectorRef,\n Component,\n inject,\n Input,\n OnChanges,\n SimpleChanges,\n} from '@angular/core';\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatCard, MatCardHeader, MatCardContent } from '@angular/material/card';\nimport { FormlyFieldConfig, FormlyForm, provideFormlyCore } from '@ngx-formly/core';\nimport { withFormlyMaterial } from '@ngx-formly/material';\nimport {\n NgxThinAdminEditorConfig,\n NgxThinAdminEditorField,\n NgxThinAdminItemDeleterConfig,\n} from '../interfaces';\nimport { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';\nimport {\n formlyAddonsExtension,\n FormlyMatPrefixAddonWrapper,\n} from '../shared/formly/mat-prefix-addon-wrapper/mat-prefix-addon-wrapper';\nimport { MatProgressBar } from '@angular/material/progress-bar';\nimport { getErrorMessage } from '../shared/error-handler';\nimport { FormlyFieldFile } from '../shared/formly/file-input/file-type.component';\nimport { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminI18nKey } from '../i18n';\nimport { MatDialog } from '@angular/material/dialog';\nimport { ConfirmDialog, ConfirmDialogData } from '../shared/confirm-dialog/confirm-dialog';\nimport { lastValueFrom } from 'rxjs';\nimport { Router, RouterLink } from '@angular/router';\n\n@Component({\n selector: 'ngx-thin-admin-editor',\n imports: [\n ReactiveFormsModule,\n FormlyForm,\n MatButton,\n MatIcon,\n RouterLink,\n MatProgressBar,\n MatCard,\n MatCardHeader,\n MatCardContent,\n ],\n providers: [\n provideFormlyCore(withFormlyMaterial()),\n provideFormlyCore({\n wrappers: [\n {\n name: 'addons',\n component: FormlyMatPrefixAddonWrapper,\n },\n ],\n extensions: [{ name: 'addons', extension: { onPopulate: formlyAddonsExtension } }],\n types: [\n {\n name: 'file',\n component: FormlyFieldFile,\n },\n ],\n }),\n {\n // Apply default appearance and other settings to all Material form fields in this component\n provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,\n useValue: {\n appearance: 'outline',\n floatLabel: 'always',\n subscriptSizing: 'dynamic',\n },\n },\n ],\n templateUrl: './ngx-thin-admin-editor.html',\n styleUrl: './ngx-thin-admin-editor.scss',\n})\nexport class NgxThinAdminEditor<T = any> implements OnChanges {\n /**\n * Config for editor\n */\n @Input()\n editorConfig?: NgxThinAdminEditorConfig<T>;\n\n /**\n * Fields for formly form\n */\n @Input()\n editorFields?: NgxThinAdminEditorField[];\n\n /**\n * Id of the item being edited.\n */\n @Input()\n itemId?: string;\n\n /**\n * Config for item deleter\n */\n @Input()\n itemDeleterConfig?: NgxThinAdminItemDeleterConfig;\n\n /**\n * Internal state for form\n */\n isSaving = false;\n isLoading = false;\n form = new FormGroup({});\n data: Partial<T> = {};\n formData: Partial<T> = {};\n\n /**\n * For history back\n */\n windowHistory = window.history;\n\n /**\n * Services\n */\n private snackbar = inject(MatSnackBar);\n private cdr = inject(ChangeDetectorRef);\n private translate = inject(NGX_THIN_ADMIN_TRANSLATE);\n private dialog = inject(MatDialog);\n private router = inject(Router);\n\n t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string {\n return this.translate(key, params);\n }\n\n get editorItemType(): string {\n return this.editorConfig?.singularLabel || this.t('item.defaultSingular');\n }\n\n ngOnChanges(changes: SimpleChanges<NgxThinAdminEditor<T>>) {\n // Fetcher\n if (\n changes.editorConfig &&\n changes.editorConfig.currentValue?.fetcher !== changes.editorConfig.previousValue?.fetcher\n ) {\n this.fetchItem();\n } else if (changes.itemId && changes.itemId.currentValue !== changes.itemId.previousValue) {\n this.fetchItem();\n }\n\n // Fields\n if (changes.editorFields?.currentValue) {\n this.editorFields = changes.editorFields.currentValue.map((col: NgxThinAdminEditorField) => {\n return this.overwriteFieldProps(col);\n });\n }\n }\n\n overwriteFieldProps(field: NgxThinAdminEditorField) {\n if (!field.props) {\n field.props = {};\n }\n\n // requiredOnCreate\n if (field.props.requiredOnCreate) {\n if (this.itemId === undefined) {\n field.props.required = true;\n } else {\n field.props.required = false;\n }\n }\n\n // disabledOnUpdate\n if (field.props.disabledOnUpdate) {\n if (this.itemId !== undefined) {\n //formControl.disable();\n field.props.disabled = true;\n } else {\n //formControl.enable();\n field.props.disabled = false;\n }\n }\n\n return field;\n }\n\n async fetchItem() {\n if (!this.editorConfig?.fetcher) {\n return;\n } else if (!this.itemId) {\n this.data = {};\n return;\n }\n\n // Set loading state\n this.isLoading = true;\n this.cdr.markForCheck();\n\n // Call the fetcher function to get the item data\n try {\n let res = await this.editorConfig.fetcher(this.itemId);\n\n if (res instanceof Response) {\n if (!res.ok) {\n const data = await res.json();\n throw new Error(\n data.error ?? data.message ?? `Failed to fetch data: ${res.status} ${res.statusText}`,\n );\n }\n res = await res.json();\n }\n\n this.data = { ...res };\n this.formData = { ...res };\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(`Error: ${errorMessage}`, undefined, {\n duration: 3000,\n });\n\n // Reset loading state\n this.isLoading = false;\n this.cdr.markForCheck();\n return;\n }\n\n this.isLoading = false;\n this.cdr.markForCheck();\n }\n\n async save() {\n if (this.form.status === 'INVALID') {\n this.snackbar.open(`Error: ${this.t('editor.errorInvalidInput')}`, undefined, {\n duration: 3000,\n });\n\n // Mark field to show validation errors\n Object.keys(this.form.controls).forEach((key) => {\n const control = this.form.get(key);\n control?.markAsTouched();\n });\n\n return;\n }\n\n if (!this.editorConfig?.saver) {\n this.snackbar.open(`Error: ${this.t('editor.errorNoSaver')}`, undefined, {\n duration: 3000,\n });\n return;\n }\n\n // Disable the form and save button to prevent multiple submissions\n this.form.disable();\n this.isSaving = true;\n\n // Call the saver function\n let result: any;\n try {\n let res: any = await this.editorConfig.saver(this.formData as T, this.itemId);\n\n if (res instanceof Response) {\n if (!res.ok) {\n const data = await res.json();\n throw new Error(\n data.error ?? data.message ?? `Failed to save data: ${res.status} ${res.statusText}`,\n );\n }\n res = await res.json();\n }\n\n result = res;\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(`Error: ${errorMessage}`, undefined, {\n duration: 3000,\n });\n\n // Re-enable the form and save button\n this.form.enable();\n this.isSaving = false;\n\n return;\n }\n\n // Show success message\n this.snackbar.open(this.t('editor.successSaved'), undefined, {\n duration: 3000,\n });\n\n // Update form data with the result from the saver (e.g., to get generated ID)\n this.data = { ...result };\n this.formData = { ...result };\n\n // Re-enable the form and save button\n this.form.enable();\n for (const field of this.editorFields ?? []) {\n this.overwriteFieldProps(field);\n }\n this.isSaving = false;\n }\n\n async openDeletionDialog() {\n if (!this.itemDeleterConfig?.deleter || this.itemId === undefined) {\n return;\n }\n\n // Get the label and ID to query in the confirmation dialog\n const id = this.itemId;\n const label = this.editorConfig?.labelFieldKey\n ? (this.data as any)[this.editorConfig.labelFieldKey]\n : id;\n const itemType = this.editorItemType;\n\n // Open the confirmation dialog\n const dialogRef = this.dialog.open(ConfirmDialog, {\n width: '400px',\n data: {\n title: this.t('item.deletionDialogTitle', { itemType }),\n message: this.t('item.deletionDialogMessage', { label, id }),\n positiveButtonText: this.t('common.delete'),\n cancelButtonText: this.t('common.cancel'),\n } satisfies ConfirmDialogData,\n });\n const result = await lastValueFrom(dialogRef.afterClosed());\n if (!result) {\n return;\n }\n\n // Execute delete process\n await this.deleteItem(id, label);\n }\n\n async deleteItem(id: string, label: string) {\n if (!this.itemDeleterConfig?.deleter) {\n return;\n }\n\n try {\n const res = await this.itemDeleterConfig.deleter(id);\n if (res && 'ok' in res && !res.ok) {\n const errorMessage = getErrorMessage(res);\n throw new Error(errorMessage);\n }\n } catch (e: any) {\n const errorMessage = getErrorMessage(e);\n this.snackbar.open(\n `Error: ${errorMessage || this.t('item.errorFailedDelete', { label })}`,\n undefined,\n { duration: 3000 },\n );\n return;\n }\n\n // Show success message\n this.snackbar.open(this.t('item.successDeleted', { label }), undefined, {\n duration: 3000,\n });\n\n // Subsequence routing\n if (this.itemDeleterConfig.afterDeleteNavigateTo) {\n this.router.navigate([this.itemDeleterConfig.afterDeleteNavigateTo]);\n }\n }\n}\n","<mat-card>\n <mat-card-header style=\"position: relative\">\n <!-- Back button -->\n @if (editorConfig?.backButton) {\n @if ($any(editorConfig?.backButton).historyBack && windowHistory.length > 1) {\n <button mat-button (click)=\"windowHistory.back()\" class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </button>\n } @else if ($any(editorConfig?.backButton).routerLink; as backButtonLink) {\n <a [routerLink]=\"backButtonLink\" mat-button class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </a>\n } @else if ($any(editorConfig?.backButton).link; as backButtonLink) {\n <a [href]=\"backButtonLink\" mat-button class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </a>\n } @else if ($any(editorConfig?.backButton).click; as handler) {\n <button mat-button (click)=\"handler()\" class=\"back-link\">\n <mat-icon>arrow_back_ios_new</mat-icon>\n {{ editorConfig?.backButton?.label ?? t('editor.backToList') }}\n </button>\n }\n }\n <!---->\n\n <!-- Editor title -->\n <h3 style=\"margin: 0\" [style.margin-top]=\"editorConfig?.backButton ? '1rem' : '0'\">\n @if (itemId !== undefined && $any(data); as editItem) {\n @if (editorConfig?.labelFieldKey && editItem[editorConfig!.labelFieldKey!]) {\n <!-- e.g., \"Edit - Taro (taro) \" -->\n {{ t('common.edit') }} &nbsp; <span style=\"color: #aaaaaa\">-</span>\n <span class=\"editor-item-label\">{{ editItem[editorConfig!.labelFieldKey!] }}</span>\n @if (editorConfig?.idFieldKey && editItem[editorConfig!.idFieldKey!]) {\n <small class=\"editor-header-sub\">{{ editItem[editorConfig!.idFieldKey!] }}</small>\n }\n <!---->\n } @else if (editItem.id) {\n <!-- e.g., \"Edit - ID: 123\" -->\n {{ t('common.edit') }} &nbsp; <span style=\"color: #aaaaaa\">-</span>\n {{ t('editor.idLabel') }}:\n <span class=\"editor-item-label\">{{ editItem.id }}</span>\n <!---->\n } @else {\n <!-- e.g., \"Edit Account (123)\" -->\n {{ t('editor.titleForEdit', { itemType: editorItemType }) }}\n @if (editorConfig?.idFieldKey && editItem[editorConfig!.idFieldKey!]) {\n <small class=\"editor-header-sub\">{{ editItem[editorConfig!.idFieldKey!] }}</small>\n }\n <!---->\n }\n } @else {\n <!-- Create Account -->\n {{ t('editor.titleForCreate', { itemType: editorItemType }) }}\n <!---->\n }\n </h3>\n <!---->\n </mat-card-header>\n\n <mat-card-content>\n @if (isLoading || isSaving) {\n <mat-progress-bar mode=\"indeterminate\" style=\"margin-top: 1rem\"></mat-progress-bar>\n }\n\n @if (!isLoading) {\n <form [formGroup]=\"form\" (ngSubmit)=\"save()\">\n <formly-form\n [form]=\"form\"\n [fields]=\"$any(editorFields) ?? []\"\n [model]=\"formData\"\n ></formly-form>\n\n <!-- Button Area -->\n <div\n style=\"\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 0.5rem;\n \"\n >\n <!-- Delete button (visible only in edit mode and if itemDeleterConfig is provided) -->\n @if (itemDeleterConfig?.deleter && itemId !== undefined) {\n <button\n type=\"button\"\n mat-stroked-button\n color=\"warn\"\n (click)=\"openDeletionDialog()\"\n [disabled]=\"isLoading || isSaving\"\n >\n {{ t('common.delete') }}\n </button>\n } @else {\n <span></span>\n }\n <!---->\n\n <!-- Submit button (visible only if saver is provided) -->\n @if (editorConfig?.saver) {\n <button\n type=\"submit\"\n mat-flat-button\n style=\"color: white; transform: translateY(-0.3rem)\"\n >\n @if (itemId !== undefined) {\n {{ t('editor.saveChanges') }}\n } @else {\n {{ t('common.create') }}\n }\n </button>\n }\n <!---->\n </div>\n <!---->\n </form>\n }\n </mat-card-content>\n</mat-card>\n","/*\n * Public API Surface of ngx-thin-admin\n */\n\nexport * from './lib/ngx-thin-admin-list/ngx-thin-admin-list';\nexport * from './lib/ngx-thin-admin-editor/ngx-thin-admin-editor';\nexport * from './lib/interfaces';\nexport * from './lib/i18n';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","csvStringify","i2","MatFormField","MatSuffix"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-thin-admin",
3
- "version": "0.0.0-alpha.6",
3
+ "version": "0.0.0-alpha.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/mugifly/ngx-thin-admin/tree/main/projects/ngx-thin-admin"
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Provider, OnChanges, OnInit, TemplateRef, SimpleChanges } from '@angular/core';
2
+ import { InjectionToken, Provider, EventEmitter, SimpleChanges, OnChanges, OnInit, TemplateRef } from '@angular/core';
3
3
  import { MtxGridColumn } from '@ng-matero/extensions/grid';
4
4
  import { FormlyFieldConfig, FormlyFieldProps } from '@ngx-formly/core';
5
5
  import { PageEvent } from '@angular/material/paginator';
@@ -8,7 +8,7 @@ import { FormGroup } from '@angular/forms';
8
8
  /**
9
9
  * Config for editor
10
10
  */
11
- interface NgxThinAdminEditorConfig {
11
+ interface NgxThinAdminEditorConfig<T = any> {
12
12
  /**
13
13
  * Label for the item
14
14
  * @example "User Account", "Article", etc. (used for singular form in UI)
@@ -31,14 +31,14 @@ interface NgxThinAdminEditorConfig {
31
31
  * @param id
32
32
  * @returns The item data
33
33
  */
34
- fetcher: (id: string) => Promise<any> | any;
34
+ fetcher: (id: string) => Promise<T> | T;
35
35
  /**
36
36
  * Function to create item / save item
37
37
  * @param data
38
38
  * @param id (only for update)
39
39
  * @returns The created/updated item data
40
40
  */
41
- saver?: (data: any, id?: string) => Promise<any> | any;
41
+ saver?: (data: T, id?: string) => Promise<T> | T;
42
42
  /**
43
43
  * Optional config for back button
44
44
  */
@@ -78,14 +78,14 @@ interface NgxThinAdminEditorField extends Omit<NgxThinAdminFieldConfig, 'props'>
78
78
  * Columns for list (extended type of MtxGridColumn)
79
79
  * @see https://ng-matero.github.io/extensions/components/grid/api
80
80
  */
81
- interface NgxThinAdminListColumn extends MtxGridColumn {
82
- link?: (item: any) => string | undefined;
83
- routerLink?: (item: any) => string | undefined;
81
+ interface NgxThinAdminListColumn<T = any> extends MtxGridColumn {
82
+ link?: (item: T) => string | undefined;
83
+ routerLink?: (item: T) => string | undefined;
84
84
  }
85
85
  /**
86
86
  * Config for list
87
87
  */
88
- interface NgxThinAdminListConfig {
88
+ interface NgxThinAdminListConfig<T = any> {
89
89
  /**
90
90
  * Title of the list
91
91
  * @example "User Accounts", "Articles", etc.
@@ -106,7 +106,7 @@ interface NgxThinAdminListConfig {
106
106
  * @param query - The query object containing parameters for fetching the list (e.g., keyword, pagination info).
107
107
  * @returns An array of data to be displayed in the grid.
108
108
  */
109
- fetcher: ListFetcher;
109
+ fetcher: ListFetcher<T>;
110
110
  /**
111
111
  * Optional config for create button. If provided, a create button will be displayed in the UI.
112
112
  */
@@ -133,18 +133,18 @@ interface NgxThinAdminListConfig {
133
133
  * @param id ID of the item
134
134
  * @param categoryId Destination category ID (undefined if moving to "no category")
135
135
  */
136
- categoryChanger?: (id: string, categoryId: string | undefined) => Promise<void> | void;
136
+ categoryChanger?: (id: string, categoryId: string | undefined) => Promise<void> | Promise<any> | void;
137
137
  /**
138
138
  * Field key or function to get the current category ID of an item.
139
139
  * (used to set the initial selected category in the category change dialog)
140
140
  * @example "categoryId", "role", or (item) => item.category?.id
141
141
  */
142
- categoryFieldKey?: string | ((item: any) => string | undefined);
142
+ categoryFieldKey?: string | ((item: T) => string | undefined);
143
143
  }
144
144
  /**
145
145
  * Fetcher function to retrieve list data.
146
146
  */
147
- type ListFetcher = (query: NgxThinAdminListQuery) => Promise<NgxThinAdminListResponse> | NgxThinAdminListResponse;
147
+ type ListFetcher<T = any> = (query: NgxThinAdminListQuery) => Promise<NgxThinAdminListResponse<T>> | NgxThinAdminListResponse<T>;
148
148
  /**
149
149
  * Config for category selector
150
150
  */
@@ -181,13 +181,13 @@ interface NgxThinAdminCategorySelectorConfig {
181
181
  * @param category The category object to be updated.
182
182
  * @returns A promise that resolves with the updated category object.
183
183
  */
184
- updater?: (category: NgxThinAdminCategory) => Promise<NgxThinAdminCategory> | NgxThinAdminCategory;
184
+ updater?: (category: NgxThinAdminCategory) => Promise<void> | Promise<any> | void;
185
185
  /**
186
186
  * Optional function to delete a category. If provided, a category deletion option will be displayed in the category selector.
187
187
  * @param category The category object to be deleted.
188
188
  * @returns A promise that resolves when the category has been deleted.
189
189
  */
190
- deleter?: (category: NgxThinAdminCategory) => Promise<void> | void;
190
+ deleter?: (category: NgxThinAdminCategory) => Promise<void> | Promise<any> | void;
191
191
  }
192
192
  type NgxThinAdminListCreateButtonConfig = {
193
193
  label?: string;
@@ -212,8 +212,8 @@ interface NgxThinAdminListQuery {
212
212
  page: number;
213
213
  perPage: number;
214
214
  }
215
- interface NgxThinAdminListResponse {
216
- items: any[];
215
+ interface NgxThinAdminListResponse<T = any> {
216
+ items: T[];
217
217
  totalCount: number;
218
218
  }
219
219
  interface NgxThinAdminCategory {
@@ -233,7 +233,7 @@ interface NgxThinAdminItemDeleterConfig {
233
233
  * Function to delete an item
234
234
  * @param id ID to be deleted (Value of the field specified by listConfig.idFieldKey or editorConfig.idFieldKey)
235
235
  */
236
- deleter: (id: string) => Promise<void> | void;
236
+ deleter: (id: string) => Promise<void> | Promise<any> | void;
237
237
  /**
238
238
  * Navigate to after deletion (used after deletion in editor screen)
239
239
  * @example "/accounts"
@@ -241,6 +241,54 @@ interface NgxThinAdminItemDeleterConfig {
241
241
  afterDeleteNavigateTo?: string;
242
242
  }
243
243
 
244
+ type NgxThinAdminLocale = 'en' | 'ja';
245
+ type NgxThinAdminI18nKey = 'common.cancel' | 'common.ok' | 'common.save' | 'common.create' | 'common.edit' | 'common.delete' | 'common.back' | 'list.defaultTitle' | 'list.clearFilters' | 'list.searchDefaultPlaceholder' | 'list.searchInCategoryPlaceholder' | 'list.clearSearchKeyword' | 'list.refresh' | 'list.exportAsCsv' | 'list.exportedFileName' | 'list.exportItems' | 'editor.titleForCreate' | 'editor.titleForEdit' | 'editor.idLabel' | 'editor.saveChanges' | 'editor.errorInvalidInput' | 'editor.errorNoSaver' | 'editor.successSaved' | 'editor.backToList' | 'category.defaultSingular' | 'category.defaultPlural' | 'category.all' | 'category.editorDialogTitleForCreate' | 'category.editorDialogTitleForEdit' | 'category.deletionDialogTitle' | 'category.deletionDialogMessage' | 'category.errorCouldNotCreate' | 'category.errorFailedUpdate' | 'category.errorFailedDelete' | 'category.errorCouldNotSave' | 'category.successCreated' | 'category.successUpdated' | 'category.successDeleted' | 'item.defaultSingular' | 'item.deletionDialogTitle' | 'item.deletionDialogMessage' | 'item.errorFailedDelete' | 'item.successDeleted' | 'item.changeCategory' | 'item.changeCategoryDialogTitle' | 'item.changeCategoryDialogMessage' | 'item.successCategoryChanged' | 'item.errorFailedCategoryChange' | 'category.unselected' | 'csv.exporting' | 'csv.exportCompleted' | 'csv.exportCompletedWithErrors' | 'csv.errorGenerateFailed';
246
+ type NgxThinAdminI18nParams = Record<string, string | number | undefined>;
247
+ type NgxThinAdminTranslate = (key: NgxThinAdminI18nKey, params?: NgxThinAdminI18nParams) => string;
248
+ interface NgxThinAdminI18nConfig {
249
+ locale?: NgxThinAdminLocale;
250
+ messages?: Partial<Record<NgxThinAdminI18nKey, string>>;
251
+ translate?: NgxThinAdminTranslate;
252
+ }
253
+ declare const NGX_THIN_ADMIN_TRANSLATE: InjectionToken<NgxThinAdminTranslate>;
254
+ declare function provideNgxThinAdminI18n(config?: NgxThinAdminI18nConfig): Provider;
255
+
256
+ declare class ListCategorySelector {
257
+ /**
258
+ * Config for the category selector
259
+ */
260
+ config?: NgxThinAdminCategorySelectorConfig;
261
+ /**
262
+ * Selected category. This will be updated when the user selects a category from the list.
263
+ */
264
+ selectedCategory?: (NgxThinAdminCategory | undefined)[];
265
+ /**
266
+ * Event emitted when the selected category changes.
267
+ */
268
+ selectedCategoryChange: EventEmitter<(NgxThinAdminCategory | undefined)[]>;
269
+ /**
270
+ * Categories to be displayed in the category selector.
271
+ */
272
+ categories: NgxThinAdminCategory[];
273
+ /**
274
+ * Services
275
+ */
276
+ private snackbar;
277
+ private dialog;
278
+ private cdr;
279
+ private translate;
280
+ t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string;
281
+ ngOnChanges(changes: SimpleChanges<ListCategorySelector>): void;
282
+ fetchCategories(): Promise<void>;
283
+ createCategory(categoryLabel: string): Promise<void>;
284
+ updateCategory(category: NgxThinAdminCategory): Promise<void>;
285
+ deleteCategory(category: NgxThinAdminCategory): Promise<void>;
286
+ openCategoryEditorDialog(editCategory: NgxThinAdminCategory | undefined): Promise<void>;
287
+ openCategoryDeletionDialog(category: NgxThinAdminCategory): Promise<void>;
288
+ static ɵfac: i0.ɵɵFactoryDeclaration<ListCategorySelector, never>;
289
+ static ɵcmp: i0.ɵɵComponentDeclaration<ListCategorySelector, "lib-list-category-selector", never, { "config": { "alias": "config"; "required": false; }; "selectedCategory": { "alias": "selectedCategory"; "required": false; }; }, { "selectedCategoryChange": "selectedCategoryChange"; }, never, never, true, never>;
290
+ }
291
+
244
292
  declare class CsvExportService {
245
293
  private snackbar;
246
294
  private translate;
@@ -256,23 +304,11 @@ declare class CsvExportService {
256
304
  static ɵprov: i0.ɵɵInjectableDeclaration<CsvExportService>;
257
305
  }
258
306
 
259
- type NgxThinAdminLocale = 'en' | 'ja';
260
- type NgxThinAdminI18nKey = 'common.cancel' | 'common.ok' | 'common.save' | 'common.create' | 'common.edit' | 'common.delete' | 'common.back' | 'list.defaultTitle' | 'list.clearFilters' | 'list.searchDefaultPlaceholder' | 'list.searchInCategoryPlaceholder' | 'list.clearSearchKeyword' | 'list.refresh' | 'list.exportAsCsv' | 'list.exportedFileName' | 'list.exportItems' | 'editor.titleForCreate' | 'editor.titleForEdit' | 'editor.idLabel' | 'editor.saveChanges' | 'editor.errorInvalidInput' | 'editor.errorNoSaver' | 'editor.successSaved' | 'editor.backToList' | 'category.defaultSingular' | 'category.defaultPlural' | 'category.all' | 'category.editorDialogTitleForCreate' | 'category.editorDialogTitleForEdit' | 'category.deletionDialogTitle' | 'category.deletionDialogMessage' | 'category.errorCouldNotCreate' | 'category.errorFailedUpdate' | 'category.errorFailedDelete' | 'category.errorCouldNotSave' | 'category.successCreated' | 'category.successUpdated' | 'category.successDeleted' | 'item.defaultSingular' | 'item.deletionDialogTitle' | 'item.deletionDialogMessage' | 'item.errorFailedDelete' | 'item.successDeleted' | 'item.changeCategory' | 'item.changeCategoryDialogTitle' | 'item.changeCategoryDialogMessage' | 'item.successCategoryChanged' | 'item.errorFailedCategoryChange' | 'category.unselected' | 'csv.exporting' | 'csv.exportCompleted' | 'csv.exportCompletedWithErrors' | 'csv.errorGenerateFailed';
261
- type NgxThinAdminI18nParams = Record<string, string | number | undefined>;
262
- type NgxThinAdminTranslate = (key: NgxThinAdminI18nKey, params?: NgxThinAdminI18nParams) => string;
263
- interface NgxThinAdminI18nConfig {
264
- locale?: NgxThinAdminLocale;
265
- messages?: Partial<Record<NgxThinAdminI18nKey, string>>;
266
- translate?: NgxThinAdminTranslate;
267
- }
268
- declare const NGX_THIN_ADMIN_TRANSLATE: InjectionToken<NgxThinAdminTranslate>;
269
- declare function provideNgxThinAdminI18n(config?: NgxThinAdminI18nConfig): Provider;
270
-
271
- declare class NgxThinAdminList implements OnChanges, OnInit {
307
+ declare class NgxThinAdminList<T = any> implements OnChanges, OnInit {
272
308
  /**
273
309
  * Config for list
274
310
  */
275
- listConfig?: NgxThinAdminListConfig;
311
+ listConfig?: NgxThinAdminListConfig<T>;
276
312
  /**
277
313
  * Config for category selector. If provided, a category selector will be displayed in the UI.
278
314
  */
@@ -286,7 +322,7 @@ declare class NgxThinAdminList implements OnChanges, OnInit {
286
322
  * Column schema (extended type of MtxGridColumn)
287
323
  * @see https://ng-matero.github.io/extensions/components/grid/api
288
324
  */
289
- listColumns?: MtxGridColumn[];
325
+ listColumns?: (NgxThinAdminListColumn<T> | MtxGridColumn)[];
290
326
  /**
291
327
  * Query (Optional)
292
328
  */
@@ -301,7 +337,7 @@ declare class NgxThinAdminList implements OnChanges, OnInit {
301
337
  */
302
338
  isLoading: boolean;
303
339
  gridColumns: MtxGridColumn[];
304
- gridData: any[];
340
+ gridData: T[];
305
341
  totalCount: number;
306
342
  /**
307
343
  * Internal state for category list
@@ -317,6 +353,10 @@ declare class NgxThinAdminList implements OnChanges, OnInit {
317
353
  * Template for cells
318
354
  */
319
355
  cellTplWithLink: TemplateRef<any>;
356
+ /**
357
+ * Category Selector
358
+ */
359
+ categorySelector?: ListCategorySelector;
320
360
  /**
321
361
  * Services
322
362
  */
@@ -326,7 +366,7 @@ declare class NgxThinAdminList implements OnChanges, OnInit {
326
366
  csvExportService: CsvExportService;
327
367
  private dialog;
328
368
  t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string;
329
- ngOnChanges(changes: SimpleChanges<NgxThinAdminList>): void;
369
+ ngOnChanges(changes: SimpleChanges<NgxThinAdminList<T>>): void;
330
370
  private buildGridColumns;
331
371
  fetchList(): Promise<void>;
332
372
  clearFilters(): void;
@@ -337,15 +377,15 @@ declare class NgxThinAdminList implements OnChanges, OnInit {
337
377
  openItemDeletionDialog(item: any): Promise<void>;
338
378
  deleteItem(id: string, label: string): Promise<void>;
339
379
  openItemCategoryChangeDialog(item: any): Promise<void>;
340
- static ɵfac: i0.ɵɵFactoryDeclaration<NgxThinAdminList, never>;
341
- static ɵcmp: i0.ɵɵComponentDeclaration<NgxThinAdminList, "ngx-thin-admin-list", never, { "listConfig": { "alias": "listConfig"; "required": false; }; "categorySelectorConfig": { "alias": "categorySelectorConfig"; "required": false; }; "itemDeleterConfig": { "alias": "itemDeleterConfig"; "required": false; }; "listColumns": { "alias": "listColumns"; "required": false; }; "query": { "alias": "query"; "required": false; }; }, {}, never, never, true, never>;
380
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxThinAdminList<any>, never>;
381
+ static ɵcmp: i0.ɵɵComponentDeclaration<NgxThinAdminList<any>, "ngx-thin-admin-list", never, { "listConfig": { "alias": "listConfig"; "required": false; }; "categorySelectorConfig": { "alias": "categorySelectorConfig"; "required": false; }; "itemDeleterConfig": { "alias": "itemDeleterConfig"; "required": false; }; "listColumns": { "alias": "listColumns"; "required": false; }; "query": { "alias": "query"; "required": false; }; }, {}, never, never, true, never>;
342
382
  }
343
383
 
344
- declare class NgxThinAdminEditor implements OnChanges {
384
+ declare class NgxThinAdminEditor<T = any> implements OnChanges {
345
385
  /**
346
386
  * Config for editor
347
387
  */
348
- editorConfig?: NgxThinAdminEditorConfig;
388
+ editorConfig?: NgxThinAdminEditorConfig<T>;
349
389
  /**
350
390
  * Fields for formly form
351
391
  */
@@ -364,8 +404,8 @@ declare class NgxThinAdminEditor implements OnChanges {
364
404
  isSaving: boolean;
365
405
  isLoading: boolean;
366
406
  form: FormGroup<{}>;
367
- data: any;
368
- formData: any;
407
+ data: Partial<T>;
408
+ formData: Partial<T>;
369
409
  /**
370
410
  * For history back
371
411
  */
@@ -380,14 +420,14 @@ declare class NgxThinAdminEditor implements OnChanges {
380
420
  private router;
381
421
  t(key: NgxThinAdminI18nKey, params?: Record<string, string | number | undefined>): string;
382
422
  get editorItemType(): string;
383
- ngOnChanges(changes: SimpleChanges<NgxThinAdminEditor>): void;
423
+ ngOnChanges(changes: SimpleChanges<NgxThinAdminEditor<T>>): void;
384
424
  overwriteFieldProps(field: NgxThinAdminEditorField): NgxThinAdminEditorField;
385
425
  fetchItem(): Promise<void>;
386
426
  save(): Promise<void>;
387
427
  openDeletionDialog(): Promise<void>;
388
428
  deleteItem(id: string, label: string): Promise<void>;
389
- static ɵfac: i0.ɵɵFactoryDeclaration<NgxThinAdminEditor, never>;
390
- static ɵcmp: i0.ɵɵComponentDeclaration<NgxThinAdminEditor, "ngx-thin-admin-editor", never, { "editorConfig": { "alias": "editorConfig"; "required": false; }; "editorFields": { "alias": "editorFields"; "required": false; }; "itemId": { "alias": "itemId"; "required": false; }; "itemDeleterConfig": { "alias": "itemDeleterConfig"; "required": false; }; }, {}, never, never, true, never>;
429
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxThinAdminEditor<any>, never>;
430
+ static ɵcmp: i0.ɵɵComponentDeclaration<NgxThinAdminEditor<any>, "ngx-thin-admin-editor", never, { "editorConfig": { "alias": "editorConfig"; "required": false; }; "editorFields": { "alias": "editorFields"; "required": false; }; "itemId": { "alias": "itemId"; "required": false; }; "itemDeleterConfig": { "alias": "itemDeleterConfig"; "required": false; }; }, {}, never, never, true, never>;
391
431
  }
392
432
 
393
433
  export { NGX_THIN_ADMIN_TRANSLATE, NgxThinAdminEditor, NgxThinAdminList, provideNgxThinAdminI18n };