From fe0445ea1658b9346ecd4e6a9c9a2f4a53a5e17a Mon Sep 17 00:00:00 2001 From: develite98 Date: Fri, 27 Oct 2023 09:59:51 +0700 Subject: [PATCH] feat() update filter --- .../database-data-form.component.ts | 2 - .../database-data.component.html | 143 ++++++----- .../database-data/database-data.component.ts | 9 +- .../post/post-detail/post-detail.component.ts | 2 +- .../portal/task-manage/store/task.store.ts | 2 +- .../mix-cms/src/app/stores/base-crud.store.ts | 226 ------------------ .../src/app/stores/database-data.store.ts | 4 +- apps/mix-cms/src/app/stores/database.store.ts | 2 +- apps/mix-cms/src/app/stores/discount.store.ts | 2 +- apps/mix-cms/src/app/stores/module.store.ts | 2 +- apps/mix-cms/src/app/stores/order.store.ts | 2 +- apps/mix-cms/src/app/stores/page.store.ts | 2 +- .../src/app/stores/permission.store.ts | 2 +- apps/mix-cms/src/app/stores/post.store.ts | 2 +- .../mix-cms/src/app/stores/promotion.store.ts | 2 +- apps/mix-cms/src/app/stores/roles.store.ts | 2 +- .../mix-cms/src/app/stores/user-info.store.ts | 2 +- apps/mix-cms/src/app/stores/user.store.ts | 2 +- .../basic-mix-filter.component.html | 27 --- .../basic-mix-filter.component.scss | 4 - .../basic-mix-filter.component.ts | 57 ----- .../basic-mix-filter.component.html | 27 --- .../basic-mix-filter.component.scss | 4 - .../basic-mix-filter.component.ts | 57 ----- libs/mix-lib/src/model/core/database.model.ts | 1 - .../src/model/pagination-request.model.ts | 13 + .../basic-mix-filter.component.html | 0 .../basic-mix-filter.component.scss | 0 .../basic-mix-filter.component.ts | 0 libs/mix-share/src/components/index.ts | 1 + .../dynamic-filter.component.html | 46 +--- .../dynamic-filter.component.scss | 15 -- .../dynamic-filter.component.ts | 57 ++--- .../filter-input/filter-input.component.html | 1 + .../filter-input/filter-input.component.scss | 0 .../filter-input/filter-input.component.ts | 12 + .../filter-item/filter-item.component.html | 15 ++ .../filter-item/filter-item.component.scss | 5 + .../filter-item/filter-item.component.ts | 69 ++++++ libs/mix-ui/src/select/select.component.ts | 16 -- 40 files changed, 256 insertions(+), 581 deletions(-) delete mode 100644 apps/mix-cms/src/app/stores/base-crud.store.ts delete mode 100644 apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.html delete mode 100644 apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.scss delete mode 100644 apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.ts delete mode 100644 apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.html delete mode 100644 apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.scss delete mode 100644 apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.ts rename {apps/mix-cms/src/app => libs/mix-share/src}/components/basic-mix-filter/basic-mix-filter.component.html (100%) rename {apps/mix-cms/src/app => libs/mix-share/src}/components/basic-mix-filter/basic-mix-filter.component.scss (100%) rename {apps/mix-cms/src/app => libs/mix-share/src}/components/basic-mix-filter/basic-mix-filter.component.ts (100%) create mode 100644 libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.html create mode 100644 libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.scss create mode 100644 libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.ts create mode 100644 libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.html create mode 100644 libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.scss create mode 100644 libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.ts diff --git a/apps/mix-cms/src/app/pages/portal/database-data/database-data-form/database-data-form.component.ts b/apps/mix-cms/src/app/pages/portal/database-data/database-data-form/database-data-form.component.ts index 23058899..e321b404 100644 --- a/apps/mix-cms/src/app/pages/portal/database-data/database-data-form/database-data-form.component.ts +++ b/apps/mix-cms/src/app/pages/portal/database-data/database-data-form/database-data-form.component.ts @@ -19,7 +19,6 @@ import { TuiLoaderModule, TuiScrollbarModule } from '@taiga-ui/core'; import { TuiFileLike, TuiTabsModule, TuiToggleModule } from '@taiga-ui/kit'; import { combineLatest, debounceTime, forkJoin, of, switchMap } from 'rxjs'; import { CMS_ROUTES } from '../../../../app.routes'; -import { BasicMixFilterComponent } from '../../../../components/basic-mix-filter/basic-mix-filter.component'; import { DynamicDbListComponent } from '../../../../components/dynamic-db-list/dynamic-db-list.component'; import { MixSubToolbarComponent } from '../../../../components/sub-toolbar/sub-toolbar.component'; import { FormlyMixModule } from '../../../../shares/kits/formly-mix.module'; @@ -39,7 +38,6 @@ import { FormlyMixModule } from '../../../../shares/kits/formly-mix.module'; FormlyMixModule, MixSubToolbarComponent, DynamicDbListComponent, - BasicMixFilterComponent, ], templateUrl: './database-data-form.component.html', styleUrls: ['./database-data-form.component.scss'], diff --git a/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.html b/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.html index 99944171..ec97052a 100644 --- a/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.html +++ b/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.html @@ -1,82 +1,108 @@ -
+
- +
-
- No data found +
+ No data found

Please choose a Database to view result

- +
- +
- + - + Columns ({{ displayColumns.length || 0 }}/{{ columnNames.length || 0 }}) - - + + + + - - code  API Document + + code  API Document
-
- +
+
@@ -89,7 +115,8 @@
- Something error when try to load data, your table may not be migrate to single table. + Something error when try to load data, your table may not be + migrate to single table.
@@ -101,9 +128,11 @@ Page size: {{ vm.pageInfo.pageSize || '0' }}
- +
diff --git a/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.ts b/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.ts index 3396a096..545a02a6 100644 --- a/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.ts +++ b/apps/mix-cms/src/app/pages/portal/database-data/database-data.component.ts @@ -9,9 +9,11 @@ import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { MixDatabase, MixDynamicData } from '@mixcore/lib/model'; import { MixApiFacadeService } from '@mixcore/share/api'; +import { BasicMixFilterComponent } from '@mixcore/share/components'; import { DomHelper, toastObserverProcessing } from '@mixcore/share/helper'; import { RelativeTimeSpanPipe } from '@mixcore/share/pipe'; import { MixButtonComponent } from '@mixcore/ui/button'; +import { DynamicFilterComponent } from '@mixcore/ui/filter'; import { MixInputComponent } from '@mixcore/ui/input'; import { ModalService } from '@mixcore/ui/modal'; import { SkeletonLoadingComponent } from '@mixcore/ui/skeleton'; @@ -37,7 +39,6 @@ import { } from 'rxjs'; import { CMS_ROUTES } from '../../../app.routes'; import { ActionCollapseComponent } from '../../../components/action-collapse/action-collapse.component'; -import { BasicMixFilterComponent } from '../../../components/basic-mix-filter/basic-mix-filter.component'; import { DatabaseSelectComponent } from '../../../components/database-select/database-select.component'; import { RecordFormComponent } from '../../../components/record-form/record-form.component'; import { MixStatusIndicatorComponent } from '../../../components/status-indicator/mix-status-indicator.component'; @@ -70,6 +71,7 @@ import { CustomHeaderComponent } from './components/custom-header/custom-header. TuiReorderModule, TippyDirective, ReactiveFormsModule, + DynamicFilterComponent, ], templateUrl: './database-data.component.html', styleUrls: ['./database-data.component.scss'], @@ -355,7 +357,10 @@ export class DatabaseDataComponent }); dialogRef.afterClosed$.subscribe((value) => { - if (value) this.store.updateData(dataIndex, value); + if (value) { + this.store.updateData(dataIndex, value); + this.gridApi.refreshCells(); + } }); }); } diff --git a/apps/mix-cms/src/app/pages/portal/post/post-detail/post-detail.component.ts b/apps/mix-cms/src/app/pages/portal/post/post-detail/post-detail.component.ts index 87cf0b8c..75642a03 100644 --- a/apps/mix-cms/src/app/pages/portal/post/post-detail/post-detail.component.ts +++ b/apps/mix-cms/src/app/pages/portal/post/post-detail/post-detail.component.ts @@ -26,6 +26,7 @@ import { PaginationRequestModel, RelationShipType, } from '@mixcore/lib/model'; +import { BasicMixFilterComponent } from '@mixcore/share/components'; import { FormHelper } from '@mixcore/share/form'; import { Utils } from '@mixcore/share/utils'; import { MixArrayMediaComponent } from '@mixcore/ui/array-media'; @@ -59,7 +60,6 @@ import { TuiToggleModule, } from '@taiga-ui/kit'; import { Observable, combineLatest, forkJoin, takeUntil } from 'rxjs'; -import { BasicMixFilterComponent } from '../../../../components/basic-mix-filter/basic-mix-filter.component'; import { DynamicDbListComponent } from '../../../../components/dynamic-db-list/dynamic-db-list.component'; import { MetadataAssociationComponent } from '../../../../components/metadata-association/metadata-association.component'; import { RelatedPostComponent } from '../../../../components/related-post/related-post.component'; diff --git a/apps/mix-cms/src/app/pages/portal/task-manage/store/task.store.ts b/apps/mix-cms/src/app/pages/portal/task-manage/store/task.store.ts index 52dd5fe2..9e040723 100644 --- a/apps/mix-cms/src/app/pages/portal/task-manage/store/task.store.ts +++ b/apps/mix-cms/src/app/pages/portal/task-manage/store/task.store.ts @@ -4,9 +4,9 @@ import { PaginationRequestModel, TaskStatus, } from '@mixcore/lib/model'; +import { BaseCRUDStore } from '@mixcore/share/base'; import { map } from 'rxjs'; import { MixSystemDbName } from '../../../../shares/consts/system-database-name'; -import { BaseCRUDStore } from '../../../../stores/base-crud.store'; @Injectable({ providedIn: 'root' }) export class TaskStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/base-crud.store.ts b/apps/mix-cms/src/app/stores/base-crud.store.ts deleted file mode 100644 index 29132d14..00000000 --- a/apps/mix-cms/src/app/stores/base-crud.store.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { Injectable, inject } from '@angular/core'; - -import { Router } from '@angular/router'; -import { - MixContentStatus, - MixFilter, - PaginationModel, - PaginationRequestModel, - PaginationResultModel, - SearchMethod, - buildCacheKey, -} from '@mixcore/lib/model'; -import { MixApiFacadeService } from '@mixcore/share/api'; -import { ComponentStore, tapResponse } from '@ngrx/component-store'; -import { - BehaviorSubject, - Observable, - Subscription, - of, - switchMap, - tap, -} from 'rxjs'; -import { CacheService } from '../shares/services/cached.service'; - -export interface BaseState { - data: T[]; - request: PaginationRequestModel; - pageInfo: PaginationModel; - status: 'Loading' | 'Error' | 'Pending' | 'Success'; -} - -export const DEFAULT_DATA = { - items: [], - pagingData: { - pageIndex: 0, - pageSize: 30, - }, -}; - -@Injectable() -export class BaseCRUDStore extends ComponentStore> { - public mixApi = inject(MixApiFacadeService); - public router = inject(Router); - public cacheService = inject(CacheService); - - public requestName = ''; - public status$ = this.selectSignal((s) => s.status); - public request$ = this.selectSignal((s) => s.request); - public data$ = this.selectSignal((s) => s.data); - - public request$$ = this.select((s) => s.request); - public vm$ = this.request$$.pipe( - tap((r) => this.loadData(r)), - switchMap(() => this.select((s) => s)) - ); - - public cachePool$ = new BehaviorSubject>( - DEFAULT_DATA - ); - public columns = ''; - - public cacheKey = ''; - public isSilentlyLoading = false; - public requestObserver!: Subscription; - public searchColumns: string[] = []; - public searchColumnsDict: { [key: string]: string } = {}; - - public requestFn!: ( - request: PaginationRequestModel - ) => Observable>; - - public loadData = this.effect( - (request$: Observable) => - request$.pipe( - switchMap((request) => { - this.cacheKey = buildCacheKey(request, this.requestName); - if (!this.cacheService.has(this.cacheKey)) { - this.patchState((s) => ({ ...s, status: 'Loading' })); - } - - return of(request); - }), - switchMap((request) => this.silentFetchData(request)), - tapResponse( - (result) => { - this.cacheService.delete(this.cacheKey); - this.cacheService.set(this.cacheKey, result); - - this.patchState({ - data: result.items, - pageInfo: result.pagingData, - }); - }, - () => this.patchState({ status: 'Error' }) - ) - ) - ); - - public reload() { - this.patchState((s) => ({ ...s, status: 'Loading' })); - this.loadData(this.request$()); - } - - public silentFetchData( - request: PaginationRequestModel - ): Observable> { - if (this.cacheService.has(this.cacheKey)) { - const cachedResponse = this.cacheService.get(this.cacheKey); - this.cachePool$.next(cachedResponse); - } - - if (this.requestFn) { - if (this.requestObserver) { - this.requestObserver.unsubscribe(); - } - - this.requestObserver = this.requestFn(request).subscribe((result) => { - this.patchState({ status: 'Success' }); - this.cachePool$.next(result); - }); - } - - return this.cachePool$.asObservable(); - } - - public changePage(index: number) { - this.patchState((s) => ({ - ...s, - request: { - ...s.request, - pageIndex: index, - }, - })); - } - - public searchChange( - searchText: string, - searchColumns: string, - method: SearchMethod = 'Like' - ) { - this.patchState((s) => ({ - ...s, - request: { - ...s.request, - keyword: searchText, - searchColumns: searchColumns, - pageIndex: 0, - searchMethod: method, - }, - })); - } - - public metadataChange(key: string, metadata: MixFilter[]) { - const request = this.request$(); - if (!metadata) return; - - request.metadataQueries = request.metadataQueries?.filter( - (e) => e.fieldName !== key - ); - request.metadataQueries = request.metadataQueries?.concat(metadata); - - this.patchState((s) => ({ - ...s, - request: { - ...request, - pageIndex: 0, - }, - })); - } - - public filterChange(filter: Record) { - this.patchState((s) => ({ - ...s, - request: { - ...s.request, - ...filter, - pageIndex: 0, - }, - })); - } - - public queryChange(queries: MixFilter[]) { - this.patchState((s) => ({ - ...s, - request: { - ...s.request, - queries: queries, - pageIndex: 0, - }, - })); - } - - public search(searchText: string, searchColumns: string[]) { - const trueSearchCols = searchColumns.map((f) => this.searchColumnsDict[f]); - const searchColText = trueSearchCols.join(', '); - - this.patchState((s) => ({ - ...s, - request: { - ...s.request, - keyword: searchText, - searchColumns: searchColText, - pageIndex: 0, - searchMethod: 'Like', - }, - })); - } - - constructor() { - super({ - status: 'Pending', - request: { - pageIndex: 0, - pageSize: 30, - direction: 'Desc', - status: MixContentStatus.Published, - searchMethod: 'Like', - columns: '', - orderBy: 'createdDateTime', - metadataQueries: [], - }, - data: DEFAULT_DATA.items, - pageInfo: DEFAULT_DATA.pagingData, - }); - } -} diff --git a/apps/mix-cms/src/app/stores/database-data.store.ts b/apps/mix-cms/src/app/stores/database-data.store.ts index f92f1ada..6340d097 100644 --- a/apps/mix-cms/src/app/stores/database-data.store.ts +++ b/apps/mix-cms/src/app/stores/database-data.store.ts @@ -8,9 +8,9 @@ import { STRING_DATA_TYPE, } from '@mixcore/lib/model'; import { MixApiFacadeService } from '@mixcore/share/api'; +import { BaseState } from '@mixcore/share/base'; import { ComponentStore } from '@ngrx/component-store'; import { catchError, filter, forkJoin, of } from 'rxjs'; -import { BaseState } from './base-crud.store'; export interface DatabaseDataState extends BaseState { dbSysName?: string; @@ -180,7 +180,7 @@ export class DatabaseDataStore extends ComponentStore { return { ...s, - data: current, + data: [...current], }; }); } diff --git a/apps/mix-cms/src/app/stores/database.store.ts b/apps/mix-cms/src/app/stores/database.store.ts index 577819db..914aa1b6 100644 --- a/apps/mix-cms/src/app/stores/database.store.ts +++ b/apps/mix-cms/src/app/stores/database.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixDatabase, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class DatabaseStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/discount.store.ts b/apps/mix-cms/src/app/stores/discount.store.ts index 6d1bafc1..1bd4a45a 100644 --- a/apps/mix-cms/src/app/stores/discount.store.ts +++ b/apps/mix-cms/src/app/stores/discount.store.ts @@ -4,8 +4,8 @@ import { MixPost, PaginationRequestModel, } from '@mixcore/lib/model'; +import { BaseCRUDStore } from '@mixcore/share/base'; import { forkJoin, map, of, switchMap } from 'rxjs'; -import { BaseCRUDStore } from './base-crud.store'; @Injectable({ providedIn: 'root' }) export class DiscountStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/module.store.ts b/apps/mix-cms/src/app/stores/module.store.ts index 015834fb..16faa483 100644 --- a/apps/mix-cms/src/app/stores/module.store.ts +++ b/apps/mix-cms/src/app/stores/module.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixModule, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class ModuleStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/order.store.ts b/apps/mix-cms/src/app/stores/order.store.ts index b45c9a9b..48dbf772 100644 --- a/apps/mix-cms/src/app/stores/order.store.ts +++ b/apps/mix-cms/src/app/stores/order.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixOrder, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class OrderStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/page.store.ts b/apps/mix-cms/src/app/stores/page.store.ts index 7b573660..93824a7e 100644 --- a/apps/mix-cms/src/app/stores/page.store.ts +++ b/apps/mix-cms/src/app/stores/page.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixPage, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class PageStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/permission.store.ts b/apps/mix-cms/src/app/stores/permission.store.ts index 160df291..27192de9 100644 --- a/apps/mix-cms/src/app/stores/permission.store.ts +++ b/apps/mix-cms/src/app/stores/permission.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixPermission, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class PermissionsStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/post.store.ts b/apps/mix-cms/src/app/stores/post.store.ts index bca13509..223e4e78 100644 --- a/apps/mix-cms/src/app/stores/post.store.ts +++ b/apps/mix-cms/src/app/stores/post.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixPost, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class PostStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/promotion.store.ts b/apps/mix-cms/src/app/stores/promotion.store.ts index 807c45ac..d44dd4d9 100644 --- a/apps/mix-cms/src/app/stores/promotion.store.ts +++ b/apps/mix-cms/src/app/stores/promotion.store.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { MixPromotion, PaginationRequestModel } from '@mixcore/lib/model'; +import { BaseCRUDStore } from '@mixcore/share/base'; import { MixSystemDbName } from '../shares/consts/system-database-name'; -import { BaseCRUDStore } from './base-crud.store'; @Injectable({ providedIn: 'root' }) export class PromotionStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/roles.store.ts b/apps/mix-cms/src/app/stores/roles.store.ts index e5a0a8a7..a673a1d1 100644 --- a/apps/mix-cms/src/app/stores/roles.store.ts +++ b/apps/mix-cms/src/app/stores/roles.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { MixRole, PaginationRequestModel } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class RolesStore extends BaseCRUDStore { diff --git a/apps/mix-cms/src/app/stores/user-info.store.ts b/apps/mix-cms/src/app/stores/user-info.store.ts index 4050676c..39bb91b2 100644 --- a/apps/mix-cms/src/app/stores/user-info.store.ts +++ b/apps/mix-cms/src/app/stores/user-info.store.ts @@ -2,9 +2,9 @@ import { Injectable, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { PaginationRequestModel, UserListVm } from '@mixcore/lib/model'; import { MixApiFacadeService } from '@mixcore/share/api'; +import { BaseState, DEFAULT_DATA } from '@mixcore/share/base'; import { ComponentStore } from '@ngrx/component-store'; import { filter, map, switchMap, tap } from 'rxjs'; -import { BaseState, DEFAULT_DATA } from './base-crud.store'; @Injectable({ providedIn: 'root' }) export class UserInfoStore extends ComponentStore> { diff --git a/apps/mix-cms/src/app/stores/user.store.ts b/apps/mix-cms/src/app/stores/user.store.ts index 2c80e011..f7a4d0da 100644 --- a/apps/mix-cms/src/app/stores/user.store.ts +++ b/apps/mix-cms/src/app/stores/user.store.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { PaginationRequestModel, UserListVm } from '@mixcore/lib/model'; -import { BaseCRUDStore } from './base-crud.store'; +import { BaseCRUDStore } from '@mixcore/share/base'; @Injectable({ providedIn: 'root' }) export class UserStore extends BaseCRUDStore { diff --git a/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.html b/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.html deleted file mode 100644 index cbf801ba..00000000 --- a/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
-
Status
- - -
From Date
- - -
To Date
- - -
Sort By
- - -
Order By
- - *Hint: order by priority to manage order -
diff --git a/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.scss b/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.scss deleted file mode 100644 index 669be340..00000000 --- a/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -:host { - width: 100%; - display: block; -} diff --git a/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.ts b/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.ts deleted file mode 100644 index 18ddb639..00000000 --- a/apps/mix-database/src/app/components/basic-mix-filter/basic-mix-filter.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { - MixContentStatus, - MixFilter, - MixOrderBy, - OrderDisplay, - PaginationRequestModel, -} from '@mixcore/lib/model'; -import { MixDatePickerComponent } from '@mixcore/ui/date-picker'; -import { MixSelectComponent } from '@mixcore/ui/select'; - -@Component({ - selector: 'mix-basic-mix-filter', - standalone: true, - imports: [ - CommonModule, - ReactiveFormsModule, - MixSelectComponent, - MixDatePickerComponent, - ], - templateUrl: './basic-mix-filter.component.html', - styleUrls: ['./basic-mix-filter.component.scss'], -}) -export class BasicMixFilterComponent implements OnInit { - @Input() public value: Partial = {}; - @Output() public valueChange: EventEmitter = - new EventEmitter(); - - filterForm = new FormGroup({ - status: new FormControl(), - fromDate: new FormControl(), - toDate: new FormControl(), - direction: new FormControl(), - orderBy: new FormControl(), - }); - - filterOptions: string[] = [ - MixContentStatus.Draft, - MixContentStatus.Published, - MixContentStatus.Preview, - MixContentStatus.Deleted, - ]; - - orderByOptions: string[] = [MixOrderBy.Priority, MixOrderBy.CreatedDateTime]; - directionOptions: string[] = ['Asc', 'Desc']; - stringify = (value: MixOrderBy) => OrderDisplay[value]; - stringifyMetadata = (value: MixFilter) => value?.displayName ?? ''; - - ngOnInit() { - this.filterForm.patchValue(this.value); - this.filterForm.valueChanges.subscribe((v) => { - this.valueChange.emit(v); - }); - } -} diff --git a/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.html b/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.html deleted file mode 100644 index cbf801ba..00000000 --- a/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
-
Status
- - -
From Date
- - -
To Date
- - -
Sort By
- - -
Order By
- - *Hint: order by priority to manage order -
diff --git a/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.scss b/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.scss deleted file mode 100644 index 669be340..00000000 --- a/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -:host { - width: 100%; - display: block; -} diff --git a/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.ts b/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.ts deleted file mode 100644 index 18ddb639..00000000 --- a/apps/mix-kanban/src/app/components/basic-mix-filter/basic-mix-filter.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { - MixContentStatus, - MixFilter, - MixOrderBy, - OrderDisplay, - PaginationRequestModel, -} from '@mixcore/lib/model'; -import { MixDatePickerComponent } from '@mixcore/ui/date-picker'; -import { MixSelectComponent } from '@mixcore/ui/select'; - -@Component({ - selector: 'mix-basic-mix-filter', - standalone: true, - imports: [ - CommonModule, - ReactiveFormsModule, - MixSelectComponent, - MixDatePickerComponent, - ], - templateUrl: './basic-mix-filter.component.html', - styleUrls: ['./basic-mix-filter.component.scss'], -}) -export class BasicMixFilterComponent implements OnInit { - @Input() public value: Partial = {}; - @Output() public valueChange: EventEmitter = - new EventEmitter(); - - filterForm = new FormGroup({ - status: new FormControl(), - fromDate: new FormControl(), - toDate: new FormControl(), - direction: new FormControl(), - orderBy: new FormControl(), - }); - - filterOptions: string[] = [ - MixContentStatus.Draft, - MixContentStatus.Published, - MixContentStatus.Preview, - MixContentStatus.Deleted, - ]; - - orderByOptions: string[] = [MixOrderBy.Priority, MixOrderBy.CreatedDateTime]; - directionOptions: string[] = ['Asc', 'Desc']; - stringify = (value: MixOrderBy) => OrderDisplay[value]; - stringifyMetadata = (value: MixFilter) => value?.displayName ?? ''; - - ngOnInit() { - this.filterForm.patchValue(this.value); - this.filterForm.valueChanges.subscribe((v) => { - this.valueChange.emit(v); - }); - } -} diff --git a/libs/mix-lib/src/model/core/database.model.ts b/libs/mix-lib/src/model/core/database.model.ts index 74e0397e..6b1bdf63 100644 --- a/libs/mix-lib/src/model/core/database.model.ts +++ b/libs/mix-lib/src/model/core/database.model.ts @@ -48,7 +48,6 @@ export interface MixRelationShip { export enum RelationShipType { OneToMany = 'OneToMany', } - export class MixColumn { systemName!: string; displayName!: string; diff --git a/libs/mix-lib/src/model/pagination-request.model.ts b/libs/mix-lib/src/model/pagination-request.model.ts index 382a7a64..319bafaf 100644 --- a/libs/mix-lib/src/model/pagination-request.model.ts +++ b/libs/mix-lib/src/model/pagination-request.model.ts @@ -36,6 +36,19 @@ export type CompareOperator = | 'NotContain' | 'InRange'; +export const CompareOperatorDisplay: Record = { + Like: 'Like', + InRange: 'In Range', + Equal: 'Equal', + NotEqual: 'Not Equal', + LessThanOrEqual: 'Less Than Or Equal', + LessThan: 'Less Than', + GreaterThan: 'Greater Than', + GreaterThanOrEqual: 'Greater Than Or Equal', + Contain: 'Contain', + NotContain: 'Not Contain', +}; + export interface MixFilter { fieldName: string; value: string | number | null | Date; diff --git a/apps/mix-cms/src/app/components/basic-mix-filter/basic-mix-filter.component.html b/libs/mix-share/src/components/basic-mix-filter/basic-mix-filter.component.html similarity index 100% rename from apps/mix-cms/src/app/components/basic-mix-filter/basic-mix-filter.component.html rename to libs/mix-share/src/components/basic-mix-filter/basic-mix-filter.component.html diff --git a/apps/mix-cms/src/app/components/basic-mix-filter/basic-mix-filter.component.scss b/libs/mix-share/src/components/basic-mix-filter/basic-mix-filter.component.scss similarity index 100% rename from apps/mix-cms/src/app/components/basic-mix-filter/basic-mix-filter.component.scss rename to libs/mix-share/src/components/basic-mix-filter/basic-mix-filter.component.scss diff --git a/apps/mix-cms/src/app/components/basic-mix-filter/basic-mix-filter.component.ts b/libs/mix-share/src/components/basic-mix-filter/basic-mix-filter.component.ts similarity index 100% rename from apps/mix-cms/src/app/components/basic-mix-filter/basic-mix-filter.component.ts rename to libs/mix-share/src/components/basic-mix-filter/basic-mix-filter.component.ts diff --git a/libs/mix-share/src/components/index.ts b/libs/mix-share/src/components/index.ts index daf1e17d..2f647cce 100644 --- a/libs/mix-share/src/components/index.ts +++ b/libs/mix-share/src/components/index.ts @@ -3,6 +3,7 @@ export * from './main-side-menu/main-side-menu.component'; export * from './main-toolbar/main-toolbar.component'; export * from './action-collapse/action-collapse.component'; +export * from './basic-mix-filter/basic-mix-filter.component'; export * from './compress-image/compress-image.component'; export * from './database-select/database-select.component'; export * from './dynamic-db-list/dynamic-db-list.component'; diff --git a/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.html b/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.html index 795a6988..0bbc13e4 100644 --- a/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.html +++ b/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.html @@ -1,48 +1,22 @@ - + filter_alt  Filter(s) - +
-

Set filters

+

Filter Record(s)

-
Default Filter
- - -
-
-
{{ filter.displayName }}
-
- -
-
{{ filter.compareOperator }}
- - -
Popover title
-

And here's some amazing content. It's very engaging. Right?

-
-
- -
-
{{ filter.displayName }}
-
-
+ + -
Advanced Filter
- -
diff --git a/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.scss b/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.scss index a9b7828e..a4cdfc18 100644 --- a/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.scss +++ b/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.scss @@ -6,20 +6,5 @@ display: flex; width: 100%; gap: 4px; - justify-content: flex-end; - } - - &__item { - display: flex; - align-items: center; - width: 100%; - border: 1px solid var(--border-color-default); - border-radius: 4px; - padding: 8px 4px; - cursor: pointer; - - &:hover { - border-color: var(--primary-color); - } } } diff --git a/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.ts b/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.ts index 5b055136..50f07809 100644 --- a/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.ts +++ b/libs/mix-ui/src/dynamic-filter/dynamic-filter.component.ts @@ -1,62 +1,49 @@ import { CommonModule } from '@angular/common'; import { Component, + Input, TemplateRef, ViewEncapsulation, inject, } from '@angular/core'; -import { CompareOperator, DataType, MixFilter } from '@mixcore/lib/model'; +import { FormControl } from '@angular/forms'; +import { MixColumn } from '@mixcore/lib/model'; import { MixButtonComponent } from '@mixcore/ui/button'; import { DialogService } from '@ngneat/dialog'; import { TippyDirective } from '@ngneat/helipopper'; +import { FilterItemComponent } from './filter-item/filter-item.component'; export interface DynamicFilterValue { - value: string | number | null | Date; - compareOperator: CompareOperator; -} - -export interface DynamicFilter { - displayName: string; - systemName: string; - dataType: DataType; - value: DynamicFilterValue[]; + column?: MixColumn; } @Component({ selector: 'mix-dynamic-filter', standalone: true, - imports: [CommonModule, MixButtonComponent, TippyDirective], + imports: [ + CommonModule, + MixButtonComponent, + TippyDirective, + FilterItemComponent, + ], templateUrl: './dynamic-filter.component.html', styleUrls: ['./dynamic-filter.component.scss'], encapsulation: ViewEncapsulation.None, }) export class DynamicFilterComponent { + @Input() public size: 's' | 'm' = 's'; + @Input() columns: MixColumn[] = []; + public dialog = inject(DialogService); - public defaultMixFilters: MixFilter[] = [ - { - fieldName: 'status', - value: null, - compareOperator: 'GreaterThanOrEqual', - displayName: 'Status', - type: 'select', - }, - { - fieldName: 'createdDateTime', - value: null, - compareOperator: 'GreaterThanOrEqual', - displayName: 'Created Date', - type: 'date', - }, - { - fieldName: 'updatedDateTime', - value: null, - compareOperator: 'GreaterThanOrEqual', - displayName: 'Updated Date', - type: 'date', - }, - ]; + public filters: DynamicFilterValue[] = []; - open(tpl: TemplateRef) { + public control = new FormControl(); + + public open(tpl: TemplateRef) { this.dialog.open(tpl, { resizable: true, draggable: true }); } + + public add() { + this.filters.push({}); + } } diff --git a/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.html b/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.html new file mode 100644 index 00000000..9e633b41 --- /dev/null +++ b/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.html @@ -0,0 +1 @@ +

filter-input works!

diff --git a/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.scss b/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.ts b/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.ts new file mode 100644 index 00000000..c310c783 --- /dev/null +++ b/libs/mix-ui/src/dynamic-filter/filter-input/filter-input.component.ts @@ -0,0 +1,12 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MixInputComponent } from '../../input/input.component'; + +@Component({ + selector: 'mix-filter-input', + standalone: true, + imports: [CommonModule, MixInputComponent], + templateUrl: './filter-input.component.html', + styleUrls: ['./filter-input.component.scss'], +}) +export class FilterInputComponent {} diff --git a/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.html b/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.html new file mode 100644 index 00000000..5701a8e6 --- /dev/null +++ b/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.html @@ -0,0 +1,15 @@ +
+ + + + + +
diff --git a/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.scss b/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.scss new file mode 100644 index 00000000..5ff02f3e --- /dev/null +++ b/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.scss @@ -0,0 +1,5 @@ +.filter-item { + display: grid; + grid-template-columns: 120px 150px auto; + grid-gap: 4px; +} diff --git a/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.ts b/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.ts new file mode 100644 index 00000000..44465a60 --- /dev/null +++ b/libs/mix-ui/src/dynamic-filter/filter-item/filter-item.component.ts @@ -0,0 +1,69 @@ +import { CommonModule } from '@angular/common'; +import { Component, Input, inject } from '@angular/core'; +import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; +import { + CompareOperator, + CompareOperatorDisplay, + MixColumn, +} from '@mixcore/lib/model'; +import { MixInputComponent } from '@mixcore/ui/input'; +import { MixSelectComponent } from '@mixcore/ui/select'; +import { FilterInputComponent } from '../filter-input/filter-input.component'; + +@Component({ + selector: 'mix-filter-item', + standalone: true, + imports: [ + CommonModule, + MixSelectComponent, + MixInputComponent, + ReactiveFormsModule, + FilterInputComponent, + ], + templateUrl: './filter-item.component.html', + styleUrls: ['./filter-item.component.scss'], +}) +export class FilterItemComponent { + @Input() columns: MixColumn[] = []; + public columnLabel = (col: MixColumn) => (col ? col.displayName : ''); + + @Input() public operators = Object.keys(CompareOperatorDisplay); + public operatorLabel = (opr: CompareOperator) => + opr ? CompareOperatorDisplay[opr] : ''; + + // public valueData = {}; + // public fields: FormlyFieldConfig[] = []; + // public valueForm = inject(FormBuilder).group({ + // value: null, + // }); + public form = inject(FormBuilder).group({ + column: {}, + operator: {}, + }); + + constructor() { + // this.form.controls.column.valueChanges + // .pipe(takeUntilDestroyed()) + // .subscribe((col: MixColumn | null) => { + // if (!col) return; + // this.valueData = Utils.initFormFieldDefaultValue( + // col.dataType, + // this.valueData + // ); + // this.fields = [ + // { + // key: 'value', + // type: col.dataType, + // props: { + // label: 'Value', + // }, + // }, + // ]; + // }); + } + + ngOnInit() { + this.form.controls.column.patchValue(this.columns[0]); + this.form.controls.operator.patchValue(this.operators[0]); + } +} diff --git a/libs/mix-ui/src/select/select.component.ts b/libs/mix-ui/src/select/select.component.ts index 95f1578a..689a5cc4 100644 --- a/libs/mix-ui/src/select/select.component.ts +++ b/libs/mix-ui/src/select/select.component.ts @@ -18,22 +18,6 @@ import { } from '@taiga-ui/kit'; import { takeUntil } from 'rxjs'; -export function buildSelectOption( - items: object[], - label: string, - value: string | undefined = undefined -): SelectOption[] { - return items.map((i: unknown) => ({ - label: (i as any)[label], - value: value ? (i as any)[value] : i, - })); -} - -export interface SelectOption { - value: object; - label: string; -} - @Component({ selector: 'mix-select', standalone: true,