ngx-thin-admin 0.0.0-alpha.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-thin-admin.mjs","sources":["../../../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/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/error-handler.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 { 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';\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\n categoryLabel?: string;\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 Edit {{ data.config.singularLabel ?? 'Category' }}: \"{{ data.editCategory.label }}\"\n } @else {\n Create {{ data.config.singularLabel ?? 'Category' }}\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 ?? 'Cancel' }}\n </button>\n <button type=\"submit\" matButton>{{ data.positiveButtonText ?? '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';\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}\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 || 'Cancel' }}\n </button>\n <button matButton [mat-dialog-close]=\"true\" cdkFocusInitial>\n {{ data.positiveButtonText || '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';\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\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(`Error: ${e?.message ?? 'Could not create category'}`, undefined, {\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: ${e?.message ?? `Failed to update category \"${category.label}\"`}`,\n undefined,\n {\n duration: 3000,\n },\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: ${e?.message ?? `Failed to delete category: \"${category.label}\"`}`,\n undefined,\n {\n duration: 3000,\n },\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 ? 'Save' : 'Create',\n cancelButtonText: '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(`Error: ${e?.message ?? 'Could not save category'}`, undefined, {\n duration: 3000,\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: 'Confirm Deletion',\n message: `Are you sure you want to delete the ${this.config?.singularLabel ?? 'category'} \"${category.label}\"? This action cannot be undone.`,\n positiveButtonText: 'Delete',\n cancelButtonText: '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: ${e?.message ?? `Failed to delete category \"${category.label}\"`}`,\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\"> {{ config?.title ?? 'Categories' }} </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 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)\">Edit</button>\n }\n @if (config?.deleter) {\n <button mat-menu-item (click)=\"openCategoryDeletionDialog(category)\">Delete</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';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CsvExportService {\n private snackbar = inject(MatSnackBar);\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 // Show processing message\n const mes = this.snackbar.open('Exporting CSV...');\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(`Failed to generate CSV file.`, 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 // Show result message\n if (errorMessage) {\n this.snackbar.open(\n `CSV exported up to ${numOfExportedItems} items. but errors occurred: ${errorMessage}`,\n undefined,\n {\n duration: 5000,\n },\n );\n } else {\n this.snackbar.open(`CSV export completed. Exported ${numOfExportedItems} items.`, undefined, {\n duration: 3000,\n });\n }\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 { 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} 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';\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 * 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 csvExportService = inject(CsvExportService);\n\n ngOnChanges(changes: SimpleChanges<NgxThinAdminList>) {\n // Columns\n if (changes.listColumns?.currentValue) {\n this.gridColumns = changes.listColumns.currentValue.map((col: NgxThinAdminListColumn) => {\n if (col.link || col.routerLink) {\n return { ...col, cellTemplate: this.cellTplWithLink };\n }\n return col;\n });\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 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 ? this.listConfig.title : 'exported';\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","<!-- 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=\"Reset filters\"\n >{{ listTitle }}</a\n >\n <!---->\n } @else {\n <!-- Title -->\n {{ listTitle }}\n <!---->\n }\n } @else {\n <!-- Default Title -->\n List\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=\"Clear filters\"\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=\"primary-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label }}\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=\"primary-button\"\n style=\"color: white; transform: translateY(-1px)\"\n >\n {{ createBtn.label }}\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=\"primary-button\"\n style=\"color: white; transform: translateY(-1px)\"\n (click)=\"handler()\"\n >\n {{ createBtn?.label }}\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 ? 'Search in ' + selectedCategory?.[0]?.label + '...'\n : 'Search...'\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 aria-label=\"Clear search keyword\"\n matTooltip=\"Clear search keyword\"\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=\"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 mat-icon-button [matMenuTriggerFor]=\"csvExportMenu\" matTooltip=\"Export as CSV\">\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>Export {{ totalCount }} items</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","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 inject,\n Input,\n OnChanges,\n SimpleChanges,\n} from '@angular/core';\nimport { FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { MatButton } from '@angular/material/button';\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 { NgxThinAdminEditorConfig, NgxThinAdminEditorField } 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';\n\n@Component({\n selector: 'ngx-thin-admin-editor',\n imports: [\n ReactiveFormsModule,\n FormlyForm,\n MatButton,\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 }),\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 * Internal state for form\n */\n isSaving = false;\n isLoading = false;\n form = new FormGroup({});\n data: any = {};\n formData: any = {};\n\n /**\n * Services\n */\n private snackbar = inject(MatSnackBar);\n private cdr = inject(ChangeDetectorRef);\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: Invalid input', 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: No saver function provided', 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('Data saved successfully', 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","<mat-card>\n <mat-card-header>\n <h3>\n @if (itemId !== undefined && $any(data); as editItem) {\n @if (editorConfig?.labelFieldKey && editItem[editorConfig!.labelFieldKey!]) {\n <!-- e.g., \"Edit - Taro (taro) \" -->\n 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 Edit &nbsp; <span style=\"color: #aaaaaa\">-</span>\n ID:\n <span class=\"editor-item-label\">{{ editItem.id }}</span>\n <!---->\n } @else {\n <!-- e.g., \"Edit Account (123)\" -->\n Edit\n @if (editorConfig?.singularLabel) {\n {{ editorConfig?.singularLabel }}\n }\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 Create\n @if (editorConfig?.singularLabel) {\n {{ editorConfig?.singularLabel }}\n }\n <!---->\n }\n </h3>\n </mat-card-header>\n\n <mat-card-content>\n @if (isLoading) {\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n } @else {\n <form [formGroup]=\"form\" (ngSubmit)=\"save()\">\n <formly-form\n [form]=\"form\"\n [fields]=\"$any(editorFields) ?? []\"\n [model]=\"formData\"\n ></formly-form>\n\n @if (editorConfig?.saver) {\n <!-- Submit button -->\n <button\n type=\"submit\"\n mat-flat-button\n style=\"color: white; transform: translateY(-0.3rem); float: right\"\n >\n @if (itemId !== undefined) {\n Save Changes\n } @else {\n Create\n }\n </button>\n <!---->\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';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i3","i1","csvStringify","i2"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "ngx-thin-admin",
3
+ "version": "0.0.0-alpha.0",
4
+ "author": {
5
+ "name": "mugifly"
6
+ },
7
+ "repository": {
8
+ "url": "https://github.com/mugifly/ngx-thin-admin/tree/main/projects/ngx-thin-admin"
9
+ },
10
+ "peerDependencies": {
11
+ "@angular/common": "^21.1.0",
12
+ "@angular/core": "^21.1.0",
13
+ "@angular/forms": "^21.1.5",
14
+ "@angular/material": "^21.1.5",
15
+ "@ng-matero/extensions": "^21.1.3",
16
+ "@ngx-formly/core": "^7.1.0",
17
+ "@ngx-formly/material": "^7.1.0",
18
+ "csv-stringify": "^6.6.0"
19
+ },
20
+ "dependencies": {
21
+ "tslib": "^2.3.0"
22
+ },
23
+ "sideEffects": false,
24
+ "module": "fesm2022/ngx-thin-admin.mjs",
25
+ "typings": "types/ngx-thin-admin.d.ts",
26
+ "exports": {
27
+ "./package.json": {
28
+ "default": "./package.json"
29
+ },
30
+ ".": {
31
+ "types": "./types/ngx-thin-admin.d.ts",
32
+ "default": "./fesm2022/ngx-thin-admin.mjs"
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,292 @@
1
+ import * as i0 from '@angular/core';
2
+ import { OnChanges, OnInit, TemplateRef, SimpleChanges } from '@angular/core';
3
+ import { MtxGridColumn } from '@ng-matero/extensions/grid';
4
+ import { FormlyFieldConfig, FormlyFieldProps } from '@ngx-formly/core';
5
+ import { PageEvent } from '@angular/material/paginator';
6
+ import { FormGroup } from '@angular/forms';
7
+
8
+ /**
9
+ * Config for editor
10
+ */
11
+ interface NgxThinAdminEditorConfig {
12
+ /**
13
+ * Label for the item
14
+ * @example "User Account", "Article", etc. (used for singular form in UI)
15
+ */
16
+ singularLabel?: string;
17
+ /**
18
+ * Field key for the item ID
19
+ * (used to identify the item being edited, should match the key in the data returned by fetcher)
20
+ * @example "id", "loginId", "articleId", etc.
21
+ */
22
+ idFieldKey?: string;
23
+ /**
24
+ * Field key for the item label
25
+ * (used to display the item label in the UI, should match the key in the data returned by fetcher)
26
+ * @example "userName", "accountName", "articleTitle", etc.
27
+ */
28
+ labelFieldKey?: string;
29
+ /**
30
+ * Function to fetch item data
31
+ * @param id
32
+ * @returns The item data
33
+ */
34
+ fetcher: (id: string) => Promise<any> | any;
35
+ /**
36
+ * Function to create item / save item
37
+ * @param data
38
+ * @param id (only for update)
39
+ * @returns The created/updated item data
40
+ */
41
+ saver?: (data: any, id?: string) => Promise<any> | any;
42
+ }
43
+ /**
44
+ * Columns for editor (extended type of FormlyFieldConfig)
45
+ */
46
+ interface NgxThinAdminFieldConfig extends FormlyFieldConfig {
47
+ }
48
+ interface NgxThinAdminFieldProps extends FormlyFieldProps {
49
+ requiredOnCreate?: boolean;
50
+ disabledOnUpdate?: boolean;
51
+ }
52
+ interface NgxThinAdminEditorField extends Omit<NgxThinAdminFieldConfig, 'props'> {
53
+ props?: NgxThinAdminFieldProps & {
54
+ [additionalProperties: string]: any;
55
+ } & {};
56
+ }
57
+ /**
58
+ * Columns for list (extended type of MtxGridColumn)
59
+ * @see https://ng-matero.github.io/extensions/components/grid/api
60
+ */
61
+ interface NgxThinAdminListColumn extends MtxGridColumn {
62
+ link?: (item: any) => string | undefined;
63
+ routerLink?: (item: any) => string | undefined;
64
+ }
65
+ /**
66
+ * Config for list
67
+ */
68
+ interface NgxThinAdminListConfig {
69
+ /**
70
+ * Title of the list
71
+ * @example "User Accounts", "Articles", etc.
72
+ */
73
+ title?: string;
74
+ /**
75
+ * Label for each item in the list
76
+ * @example "User Account", "Article", etc. (used for singular form in UI)
77
+ */
78
+ singularLabel?: string;
79
+ /**
80
+ * Page sizes
81
+ * @default [10, 25, 50, 100]
82
+ */
83
+ pageSizes?: number[];
84
+ /**
85
+ * Function to fetch list data. It will be called with a query object when the component initializes and when the fetch() method is called.
86
+ * @param query - The query object containing parameters for fetching the list (e.g., keyword, pagination info).
87
+ * @returns An array of data to be displayed in the grid.
88
+ */
89
+ fetcher: ListFetcher;
90
+ /**
91
+ * Optional config for create button. If provided, a create button will be displayed in the UI.
92
+ */
93
+ createButton?: NgxThinAdminListCreateButtonConfig;
94
+ /**
95
+ * Optional config for CSV export
96
+ */
97
+ csvExportButton?: NgxThinAdminListCsvExportButtonConfig | 'default';
98
+ }
99
+ /**
100
+ * Fetcher function to retrieve list data.
101
+ */
102
+ type ListFetcher = (query: NgxThinAdminListQuery) => Promise<NgxThinAdminListResponse> | NgxThinAdminListResponse;
103
+ /**
104
+ * Config for category selector
105
+ */
106
+ interface NgxThinAdminCategorySelectorConfig {
107
+ /**
108
+ * Title of the category selector
109
+ * @example "Categories", "Tags", etc.
110
+ */
111
+ title?: string;
112
+ /**
113
+ * Label for each category
114
+ * @example "Category", "Tag", etc. (used for singular form in UI)
115
+ */
116
+ singularLabel?: string;
117
+ /**
118
+ * Label for example value
119
+ * @example "Computers", "Smartphones", etc.
120
+ */
121
+ exampleLabel?: string;
122
+ /**
123
+ * Function to fetch category data for the category filter
124
+ * @returns An array of categories to be displayed in the category selector.
125
+ * Each category should have an 'id' and a 'label' property.
126
+ */
127
+ fetcher: () => Promise<NgxThinAdminCategoryListResponse> | NgxThinAdminCategoryListResponse;
128
+ /**
129
+ * Optional function to create a new category. If provided, a category creation UI will be displayed in the category selector.
130
+ * @param categoryLabel The label of the new category to be created.
131
+ * @returns The newly created category object.
132
+ */
133
+ creator?: (categoryLabel: string) => Promise<NgxThinAdminCategory> | NgxThinAdminCategory;
134
+ /**
135
+ * Optional function to update a category. If provided, an option to edit categories will be displayed in the category selector.
136
+ * @param category The category object to be updated.
137
+ * @returns A promise that resolves with the updated category object.
138
+ */
139
+ updater?: (category: NgxThinAdminCategory) => Promise<NgxThinAdminCategory> | NgxThinAdminCategory;
140
+ /**
141
+ * Optional function to delete a category. If provided, a category deletion option will be displayed in the category selector.
142
+ * @param category The category object to be deleted.
143
+ * @returns A promise that resolves when the category has been deleted.
144
+ */
145
+ deleter?: (category: NgxThinAdminCategory) => Promise<void> | void;
146
+ }
147
+ type NgxThinAdminListCreateButtonConfig = {
148
+ label: string;
149
+ click: () => void;
150
+ } | {
151
+ label: string;
152
+ link: string;
153
+ } | {
154
+ label: string;
155
+ routerLink: string;
156
+ };
157
+ interface NgxThinAdminListCsvExportButtonConfig {
158
+ formats: {
159
+ label: string;
160
+ value: string;
161
+ }[];
162
+ exporter?: (format: string, query: NgxThinAdminListQuery) => Promise<void> | void;
163
+ }
164
+ interface NgxThinAdminListQuery {
165
+ keyword?: string;
166
+ categoryId?: string;
167
+ page: number;
168
+ perPage: number;
169
+ }
170
+ interface NgxThinAdminListResponse {
171
+ items: any[];
172
+ totalCount: number;
173
+ }
174
+ interface NgxThinAdminCategory {
175
+ id: string;
176
+ label: string;
177
+ itemCount?: number;
178
+ }
179
+ interface NgxThinAdminCategoryListResponse {
180
+ categories: NgxThinAdminCategory[];
181
+ }
182
+
183
+ declare class CsvExportService {
184
+ private snackbar;
185
+ private encoders;
186
+ constructor();
187
+ private loadOptionalEncoders;
188
+ getAvailableEncoders(): {
189
+ key: string;
190
+ label: string;
191
+ }[];
192
+ exportListAsCsv(encoderKey: string, fileNamePrefix: string, fetcher: ListFetcher, listQuery: Omit<NgxThinAdminListQuery, 'page' | 'perPage'>, columns: NgxThinAdminListColumn[]): Promise<void>;
193
+ static ɵfac: i0.ɵɵFactoryDeclaration<CsvExportService, never>;
194
+ static ɵprov: i0.ɵɵInjectableDeclaration<CsvExportService>;
195
+ }
196
+
197
+ declare class NgxThinAdminList implements OnChanges, OnInit {
198
+ /**
199
+ * Config for list
200
+ */
201
+ listConfig?: NgxThinAdminListConfig;
202
+ /**
203
+ * Config for category selector. If provided, a category selector will be displayed in the UI.
204
+ */
205
+ categorySelectorConfig?: NgxThinAdminCategorySelectorConfig;
206
+ /**
207
+ * Column schema (extended type of MtxGridColumn)
208
+ * @see https://ng-matero.github.io/extensions/components/grid/api
209
+ */
210
+ listColumns?: MtxGridColumn[];
211
+ /**
212
+ * Query (Optional)
213
+ */
214
+ query: NgxThinAdminListQuery;
215
+ /**
216
+ * Fetcher function to retrieve list data.
217
+ * This should be provided as part of listConfig.
218
+ */
219
+ private listFetcher?;
220
+ /**
221
+ * Internal state for grid
222
+ */
223
+ isLoading: boolean;
224
+ gridColumns: MtxGridColumn[];
225
+ gridData: any[];
226
+ totalCount: number;
227
+ /**
228
+ * Internal state for category list
229
+ */
230
+ categories: NgxThinAdminCategory[];
231
+ selectedCategory?: NgxThinAdminCategory[];
232
+ /**
233
+ * Internal subject to trigger keyword change with debounce
234
+ */
235
+ private keywordChanged$;
236
+ ngOnInit(): void;
237
+ /**
238
+ * Template for cells
239
+ */
240
+ cellTplWithLink: TemplateRef<any>;
241
+ /**
242
+ * Services
243
+ */
244
+ private cdr;
245
+ csvExportService: CsvExportService;
246
+ ngOnChanges(changes: SimpleChanges<NgxThinAdminList>): void;
247
+ fetchList(): Promise<void>;
248
+ clearFilters(): void;
249
+ onKeywordInput(): void;
250
+ exportAsCsv(encoderKey: 'utf8' | string): Promise<void>;
251
+ onPageChange(event: PageEvent): void;
252
+ onSelectedCategoryChange($event: (NgxThinAdminCategory | undefined)[]): void;
253
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxThinAdminList, never>;
254
+ static ɵcmp: i0.ɵɵComponentDeclaration<NgxThinAdminList, "ngx-thin-admin-list", never, { "listConfig": { "alias": "listConfig"; "required": false; }; "categorySelectorConfig": { "alias": "categorySelectorConfig"; "required": false; }; "listColumns": { "alias": "listColumns"; "required": false; }; "query": { "alias": "query"; "required": false; }; }, {}, never, never, true, never>;
255
+ }
256
+
257
+ declare class NgxThinAdminEditor implements OnChanges {
258
+ /**
259
+ * Config for editor
260
+ */
261
+ editorConfig?: NgxThinAdminEditorConfig;
262
+ /**
263
+ * Fields for formly form
264
+ */
265
+ editorFields?: NgxThinAdminEditorField[];
266
+ /**
267
+ * Id of the item being edited.
268
+ */
269
+ itemId?: string;
270
+ /**
271
+ * Internal state for form
272
+ */
273
+ isSaving: boolean;
274
+ isLoading: boolean;
275
+ form: FormGroup<{}>;
276
+ data: any;
277
+ formData: any;
278
+ /**
279
+ * Services
280
+ */
281
+ private snackbar;
282
+ private cdr;
283
+ ngOnChanges(changes: SimpleChanges<NgxThinAdminEditor>): void;
284
+ overwriteFieldProps(field: NgxThinAdminEditorField): NgxThinAdminEditorField;
285
+ fetchItem(): Promise<void>;
286
+ save(): Promise<void>;
287
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxThinAdminEditor, never>;
288
+ 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; }; }, {}, never, never, true, never>;
289
+ }
290
+
291
+ export { NgxThinAdminEditor, NgxThinAdminList };
292
+ export type { ListFetcher, NgxThinAdminCategory, NgxThinAdminCategoryListResponse, NgxThinAdminCategorySelectorConfig, NgxThinAdminEditorConfig, NgxThinAdminEditorField, NgxThinAdminFieldConfig, NgxThinAdminFieldProps, NgxThinAdminListColumn, NgxThinAdminListConfig, NgxThinAdminListCreateButtonConfig, NgxThinAdminListCsvExportButtonConfig, NgxThinAdminListQuery, NgxThinAdminListResponse };