@onemrvapublic/design-system-demos 21.1.1 → 21.2.0-develop.1
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.
- package/assets/codes.json +1 -1
- package/assets/json/panel.json +1 -1
- package/assets/json/table.json +1 -1
- package/main.js +5 -5
- package/package.json +1 -1
- package/assets/json/vertical-stepper.json +0 -1
package/assets/codes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
["address","address-input","autocomplete","avatar","bank-input","bce-pipe","birthplace-input","breadcrumb","button","button-loading","button-toggle","card","card-table","carousel","checkbox","chips","chips-input","choice-chips","copy-to-clipboard","country-input","datepicker","datepicker-luxon","datepicker-month-year","daterangepicker","dialog","dialog-content","digit-only","drag-and-drop","drawer","empty","enterprise-number-input","error","error-handler","expansion","fab","file-panel","file-upload","file-upload-manual","form","grid","horizontal-stepper","icon","icon-button","if-width-is","jsonform","language-switcher","layout","link","mask","menu","message-box","multiselect","niss-pipe","not-found","notification","overlay","paginator","palette","panel","phone-input","pop-over","progress-bar","radio","rxjs-combine-operators","rxjs-complex-case","rxjs-flattening-operators","rxjs-observable","rxjs-subject","select","selectable-box","selectable-box-large","side-menu","skeleton","slide-toggle","spacing","spinner","sticker","summary-stepper","tab","table","table-dialog-content","task-list","text-input","textarea","timepicker","toast","toc","toolbar","tooltip","typography","validators"
|
|
1
|
+
["address","address-input","autocomplete","avatar","bank-input","bce-pipe","birthplace-input","breadcrumb","button","button-loading","button-toggle","card","card-table","carousel","checkbox","chips","chips-input","choice-chips","copy-to-clipboard","country-input","datepicker","datepicker-luxon","datepicker-month-year","daterangepicker","dialog","dialog-content","digit-only","drag-and-drop","drawer","empty","enterprise-number-input","error","error-handler","expansion","fab","file-panel","file-upload","file-upload-manual","form","grid","horizontal-stepper","icon","icon-button","if-width-is","jsonform","language-switcher","layout","link","mask","menu","message-box","multiselect","niss-pipe","not-found","notification","overlay","paginator","palette","panel","phone-input","pop-over","progress-bar","radio","rxjs-combine-operators","rxjs-complex-case","rxjs-flattening-operators","rxjs-observable","rxjs-subject","select","selectable-box","selectable-box-large","side-menu","skeleton","slide-toggle","spacing","spinner","sticker","summary-stepper","tab","table","table-dialog-content","task-list","text-input","textarea","timepicker","toast","toc","toolbar","tooltip","typography","validators"]
|
package/assets/json/panel.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"demo-panel.component.html":"<onemrva-mat-panel\n [color]=\"color()\"\n [expandable]=\"expandable()\"\n [expanded]=\"expanded\"\n (expandedChange)=\"onExpandedChange($event)\"\n>\n <onemrva-mat-panel-title>\n Employee\n <onemrva-mat-sticker [color]=\"'warn'\">In Progress</onemrva-mat-sticker>\n </onemrva-mat-panel-title>\n <onemrva-mat-panel-content>\n <p>\n Kamino neimoidia calrissian quarren darth raymus. Unduli mon luuke\n sal-solo tierce. Quelli desann dash veila galen kushiban sesswenna\n thistleborn. Kota terrik vuffi nadon kwi bibble anomid max moore. Ansion\n trandoshan bib pa'lowick thennqora gilad zhell. Tenel anzati secura rom\n isolder. Haruun karrde lahara frozarns wroonian bimm skakoan gallia\n zuckuss. Nien wicket balosar bardan gen'dai kor-uj aka mod. B'omarr hssis\n priapulin ogemite. Zuggs drovian h'nemthean keyan shmi vulptereen amanin\n cal. Thistleborn gilad airen wookiee.\n </p>\n <button mat-stroked-button color=\"primary\" class=\"small\">\n <mat-icon>edit</mat-icon>Edit\n </button>\n </onemrva-mat-panel-content>\n</onemrva-mat-panel>\n","demo-panel.component.ts":"import { Component, input, ViewEncapsulation } from '@angular/core';\n\nimport { OnemrvaMatStickerComponent } from '@onemrvapublic/design-system/mat-sticker';\nimport { OnemrvaMatPanelModule } from '@onemrvapublic/design-system/mat-panel';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { OnemrvaMatColor } from '@onemrvapublic/design-system/utils';\nimport { OnemRvaColorDirective } from '@onemrvapublic/design-system/shared';\nimport { DemoComponentBase } from '../../_demo/demo-component-base';\n\n@Component({\n selector: 'app-demo-panel',\n\n standalone: true,\n imports: [\n OnemrvaMatPanelModule,\n MatButtonModule,\n MatIconModule,\n OnemRvaColorDirective,\n OnemrvaMatStickerComponent,\n ],\n templateUrl: 'demo-panel.component.html',\n encapsulation: ViewEncapsulation.None,\n})\nexport class DemoPanelComponent extends DemoComponentBase {\n color = input<OnemrvaMatColor>(OnemrvaMatColor.NONE);\n expandable = input(true);\n\n expanded = false;\n\n onExpandedChange(expanded: boolean) {\n console.log('expanded logged:', expanded);\n }\n}\n"}
|
|
1
|
+
{"demo-panel.component.html":"<onemrva-mat-panel\n [color]=\"color()\"\n [expandable]=\"expandable()\"\n [expanded]=\"expanded\"\n (expandedChange)=\"onExpandedChange($event)\"\n>\n <onemrva-mat-panel-title>\n Employee\n <onemrva-mat-sticker [color]=\"'warn'\">In Progress</onemrva-mat-sticker>\n </onemrva-mat-panel-title>\n <onemrva-mat-panel-content customNgClass=\"is-expandable\">\n <p>\n Kamino neimoidia calrissian quarren darth raymus. Unduli mon luuke\n sal-solo tierce. Quelli desann dash veila galen kushiban sesswenna\n thistleborn. Kota terrik vuffi nadon kwi bibble anomid max moore. Ansion\n trandoshan bib pa'lowick thennqora gilad zhell. Tenel anzati secura rom\n isolder. Haruun karrde lahara frozarns wroonian bimm skakoan gallia\n zuckuss. Nien wicket balosar bardan gen'dai kor-uj aka mod. B'omarr hssis\n priapulin ogemite. Zuggs drovian h'nemthean keyan shmi vulptereen amanin\n cal. Thistleborn gilad airen wookiee.\n </p>\n <button mat-stroked-button color=\"primary\" class=\"small\">\n <mat-icon>edit</mat-icon>Edit\n </button>\n </onemrva-mat-panel-content>\n</onemrva-mat-panel>\n\n<onemrva-mat-panel [color]=\"color()\" [expandable]=\"false\" class=\"mt-m\">\n <onemrva-mat-panel-content customNgClass=\"remove-margin-empty\">\n <p>\n Kamino neimoidia calrissian quarren darth raymus. Unduli mon luuke\n sal-solo tierce. Quelli desann dash veila galen kushiban sesswenna\n thistleborn. Kota terrik vuffi nadon kwi bibble anomid max moore. Ansion\n trandoshan bib pa'lowick thennqora gilad zhell. Tenel anzati secura rom\n isolder. Haruun karrde lahara frozarns wroonian bimm skakoan gallia\n zuckuss. Nien wicket balosar bardan gen'dai kor-uj aka mod. B'omarr hssis\n priapulin ogemite. Zuggs drovian h'nemthean keyan shmi vulptereen amanin\n cal. Thistleborn gilad airen wookiee.\n </p>\n <button mat-stroked-button color=\"primary\" class=\"small\">\n <mat-icon>edit</mat-icon>Edit\n </button>\n </onemrva-mat-panel-content>\n</onemrva-mat-panel>\n","demo-panel.component.ts":"import { Component, input, ViewEncapsulation } from '@angular/core';\n\nimport { OnemrvaMatStickerComponent } from '@onemrvapublic/design-system/mat-sticker';\nimport { OnemrvaMatPanelModule } from '@onemrvapublic/design-system/mat-panel';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { OnemrvaMatColor } from '@onemrvapublic/design-system/utils';\nimport { OnemRvaColorDirective } from '@onemrvapublic/design-system/shared';\nimport { DemoComponentBase } from '../../_demo/demo-component-base';\n\n@Component({\n selector: 'app-demo-panel',\n\n standalone: true,\n imports: [\n OnemrvaMatPanelModule,\n MatButtonModule,\n MatIconModule,\n OnemRvaColorDirective,\n OnemrvaMatStickerComponent,\n ],\n styles: [\n `\n .remove-margin-empty {\n margin-top: 0 !important;\n }\n\n p {\n margin-top: 0;\n }\n `,\n ],\n templateUrl: 'demo-panel.component.html',\n encapsulation: ViewEncapsulation.None,\n})\nexport class DemoPanelComponent extends DemoComponentBase {\n color = input<OnemrvaMatColor>(OnemrvaMatColor.NONE);\n expandable = input(true);\n\n expanded = false;\n\n onExpandedChange(expanded: boolean) {\n console.log('expanded logged:', expanded);\n }\n}\n"}
|
package/assets/json/table.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"demo-table-datasource.ts":"import { DataSource } from '@angular/cdk/collections';\nimport { MatSort } from '@angular/material/sort';\nimport { map, tap } from 'rxjs/operators';\nimport {\n BehaviorSubject,\n merge,\n Observable,\n startWith,\n Subject,\n switchMap,\n} from 'rxjs';\nimport { OnemrvaMatPaginatorComponent } from '@onemrvapublic/design-system/mat-paginator';\nimport { FormControl } from '@angular/forms';\nimport { ElementsService, ListItem } from '../../_services/elements.service';\n\n/**\n * Data source for the List view. This class should\n * encapsulate all logic for fetching and manipulating the displayed data\n * (including sorting, pagination, and filtering).\n */\nexport class ListDataSource extends DataSource<ListItem> {\n paginator!: OnemrvaMatPaginatorComponent;\n search!: FormControl;\n sort: MatSort | undefined;\n data$: BehaviorSubject<ListItem[]> = new BehaviorSubject<ListItem[]>([]);\n prevSearch = '';\n refresh$ = new Subject();\n\n constructor(private elementsService: ElementsService) {\n super();\n }\n\n /**\n * Connect this data source to the table. The table will only update when\n * the returned stream emits new items.\n * @returns A stream of the items to be rendered.\n */\n connect(): Observable<ListItem[]> {\n if (this.sort) {\n // Combine everything that affects the rendered data into one update\n // stream for the data-table to consume.\n return merge(\n this.sort.sortChange, // we listen to sort change\n this.search.valueChanges, // we listen to filter change\n this.paginator.pageSize$, // we listen to page size change\n this.paginator.pageIndex$, // we listen to page index change\n this.refresh$, // used to force a refresh\n ).pipe(\n startWith({}),\n tap(() => {\n // if search changed, we reset the pageIndex\n if (\n this.search.getRawValue().trim() !== '' &&\n this.search.getRawValue() !== this.prevSearch\n ) {\n this.paginator.resetPageIndex();\n this.prevSearch = this.search.getRawValue();\n }\n }),\n switchMap(() => {\n const active: keyof ListItem =\n (this.sort?.active as keyof ListItem) || 'id';\n const direction = this.sort?.direction || 'asc';\n // We return the api call observable called with the correct parameters\n return this.elementsService\n .getElementsList(\n active,\n direction,\n this.paginator.pageIndex,\n this.paginator.pageSize,\n this.search.getRawValue(),\n )\n .pipe(\n // We map the response to the Interface we need/want\n map(response => {\n this.paginator.length = response.length;\n this.paginator.pageIndex = response.page;\n this.paginator.pageSize = response.pageSize;\n return response.list;\n }),\n );\n }),\n );\n } else {\n throw Error('Please set the sort on the data source before connecting.');\n }\n }\n\n /**\n * Called when the table is being destroyed. Use this function, to clean up\n * any open connections or free any held resources that were set up during connect.\n */\n disconnect(): void {\n console.log('disconnect');\n }\n\n /**\n * If user click on select all items (outside current page),\n * this service functions returns the IDs of all items in datasource\n */\n all() {\n return this.elementsService.getAllElementsIds(this.search.getRawValue());\n }\n\n /**\n * If user click to delete an item, we tell the api and then refresh the list.\n * @param id\n */\n delete(id: number) {\n this.elementsService.deleteElement(id);\n this.refresh$.next('');\n }\n}\n","demo-table.component.html":"<h1>Table</h1>\n<mat-form-field class=\"search\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"search\" />\n @if (search.getRawValue()) {\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"clear()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n</mat-form-field>\n<p><a tabindex=\"0\" (click)=\"showHideColumns()\">Hide/Show column</a></p>\n<table mat-table class=\"full-width-table\" matSort aria-label=\"Elements\">\n <tr mat-header-row *matHeaderRowDef=\"allColumns\"></tr>\n <tr mat-header-row class=\"compact\" *matHeaderRowDef=\"['delay', 'days']\"></tr>\n\n <!-- Notice Row -->\n <tr\n mat-header-row\n class=\"onemrva-notice-row\"\n [class]=\"showNotice() ? '' : 'hidden'\"\n *matHeaderRowDef=\"showNotice() ? ['notice'] : []\"\n ></tr>\n @if (showNotice()) {\n <ng-container matColumnDef=\"notice\">\n <th *matHeaderCellDef colspan=\"7\">\n You have selected {{ checkboxes.length }} items. \n @if (checkboxes.length < paginator.length) {\n <a tabindex=\"0\" (click)=\"selectAll()\"\n >Select {{ paginator.length }} items</a\n > \n }\n @if (checkboxes.length >= 0) {\n <a tabindex=\"0\" (click)=\"deSelectAll()\"\n >Deselect {{ checkboxes.length }} items</a\n >\n }\n </th>\n </ng-container>\n }\n <!-- Notice Row -->\n\n <tr mat-row *matRowDef=\"let row; columns: allSubColumns\"></tr>\n\n <tr *matNoDataRow class=\"noresult\">\n <td colspan=\"7\">\n <onemrva-mat-empty-row (clear)=\"clear()\" />\n </td>\n </tr>\n\n <!-- checkbox Column -->\n <ng-container matColumnDef=\"check\">\n <th mat-header-cell *matHeaderCellDef [attr.rowspan]=\"2\">\n <div>\n <mat-checkbox\n aria-label=\"Check All\"\n value=\"toggleAll\"\n [checked]=\"checked\"\n [indeterminate]=\"undetermined\"\n (change)=\"toggleAllVisible($event)\"\n />\n </div>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n #checkboxes\n aria-label=\"Check row {{ row.id }}\"\n [value]=\"row.id\"\n [checked]=\"isChecked(row.id)\"\n (change)=\"toggleOne($event, row.id)\"\n />\n </td>\n </ng-container>\n\n <!-- Id Column -->\n @if (columnIsVisible('id')) {\n <ng-container matColumnDef=\"id\" sticky>\n <th\n mat-header-cell\n class=\"compact\"\n *matHeaderCellDef\n mat-sort-header\n [attr.rowspan]=\"2\"\n >\n Id\n </th>\n <td mat-cell class=\"compact\" *matCellDef=\"let row\">\n {{ row.id }}\n </td>\n </ng-container>\n }\n\n <!-- Name Column -->\n @if (columnIsVisible('name')) {\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header [attr.rowspan]=\"2\">\n Name\n </th>\n <td id=\"{{ row.name }}\" mat-cell *matCellDef=\"let row\">\n <a href=\"/#table\">{{ row.name }}</a>\n </td>\n </ng-container>\n }\n\n <!-- Description Column -->\n @if (columnIsVisible('description')) {\n <ng-container matColumnDef=\"description\">\n <th\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header=\"description\"\n [attr.rowspan]=\"2\"\n class=\"d-table-cell-large description-cell\"\n >\n Description\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"d-table-cell-large description-cell\"\n >\n <span></span>\n {{ row.description }}\n </td></ng-container\n >\n }\n @if (columnIsVisible('suspension')) {\n <!-- Suspension Column -->\n <ng-container matColumnDef=\"suspension\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [attr.colspan]=\"2\"\n class=\"align-center compact\"\n >\n Suspension\n </th>\n <!-- This column doesn't generate <td> items, so no need to add a definition for them -->\n </ng-container>\n }\n\n @if (subColumnIsVisible('delay')) {\n <!-- Delay Column -->\n <ng-container matColumnDef=\"delay\">\n <th mat-header-cell *matHeaderCellDef class=\"compact align-center\">\n Delay\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"align-center\">1</td>\n </ng-container>\n }\n\n @if (subColumnIsVisible('days')) {\n <!-- Days Column -->\n <ng-container matColumnDef=\"days\">\n <th mat-header-cell *matHeaderCellDef class=\"compact align-center\">\n Days\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"align-center\">2</td>\n </ng-container>\n }\n\n @if (columnIsVisible('more')) {\n <!-- Menu Column -->\n <ng-container matColumnDef=\"more\">\n <th mat-header-cell class=\"compact\" *matHeaderCellDef [attr.rowspan]=\"2\">\n Menu\n </th>\n <td mat-cell class=\"compact align-right\" *matCellDef=\"let row\">\n <button mat-icon-button [matMenuTriggerFor]=\"menu\" aria-label=\"More\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"edit(row)\" aria-label=\"Edit\">\n <mat-icon>edit</mat-icon>\n Edit\n </button>\n <button mat-menu-item (click)=\"delete(row)\" aria-label=\"Delete\">\n <mat-icon>delete</mat-icon>\n Delete\n </button>\n <button mat-menu-item (click)=\"share(row)\" aria-label=\"Share\">\n <mat-icon>share</mat-icon>\n Share\n </button>\n </mat-menu>\n </td>\n </ng-container>\n }\n</table>\n<div class=\"my-m\">\n <onemrva-mat-paginator\n [pageSizeSelector]=\"true\"\n [pageSizeOptions]=\"[5, 10, 20, 50]\"\n [pageSizeDefaultOption]=\"5\"\n [pageSize]=\"5\"\n previousKey=\"Previous\"\n nextKey=\"Next\"\n (page)=\"changePage($event)\"\n #paginator\n />\n</div>\n","demo-table.component.scss":"table {\n // Medium media query of material\n // the initial is display: table, but it doesn't show responsive on larger screens\n @media (max-width: 1279.98px) {\n // Block is required for the scroll overflow!\n display: block;\n overflow: auto;\n width: 100%;\n }\n\n .description-cell {\n min-width: 500px;\n }\n}\n","demo-table.component.ts":"import {\n AfterViewInit,\n Component,\n inject,\n ViewEncapsulation,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { MatSort, MatSortModule } from '@angular/material/sort';\nimport { MatTable, MatTableModule } from '@angular/material/table';\nimport { ListDataSource } from './demo-table-datasource';\nimport { PageEvent } from '@angular/material/paginator';\nimport { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox';\n\nimport { MatChipsModule } from '@angular/material/chips';\nimport { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatIconButton } from '@angular/material/button';\nimport {\n OnemrvaMatPaginatorComponent,\n OnemrvaMatPaginatorModule,\n} from '@onemrvapublic/design-system/mat-paginator';\nimport {\n MatFormField,\n MatLabel,\n MatSuffix,\n} from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { OnemrvaMatEmptyRowComponent } from '@onemrvapublic/design-system/mat-empty-row';\nimport { ElementsService, ListItem } from '../../_services/elements.service';\nimport { OnemrvaMatMessageBoxModule } from '@onemrvapublic/design-system/mat-message-box';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { take } from 'rxjs';\nimport { MatDialog, MatDialogModule } from '@angular/material/dialog';\nimport { DemoTableDialogContentComponent } from '../table-dialog-content';\nimport { MatIcon } from '@angular/material/icon';\nimport { DemoComponentBase } from '../../_demo/demo-component-base';\n\n@Component({\n selector: 'app-demo-table',\n templateUrl: './demo-table.component.html',\n styleUrls: ['./demo-table.component.scss'],\n\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormsModule,\n MatCheckbox,\n MatChipsModule,\n MatFormField,\n MatIconButton,\n MatInput,\n MatLabel,\n MatMenu,\n MatMenuTrigger,\n MatSortModule,\n MatSuffix,\n MatTableModule,\n MatDialogModule,\n MatIcon,\n OnemrvaMatPaginatorModule,\n OnemrvaMatEmptyRowComponent,\n OnemrvaMatMessageBoxModule,\n OnemrvaMatPaginatorComponent,\n MatMenuItem,\n ],\n encapsulation: ViewEncapsulation.None,\n})\nexport class DemoTableComponent\n extends DemoComponentBase\n implements AfterViewInit\n{\n readonly paginator = viewChild.required(OnemrvaMatPaginatorComponent);\n\n readonly sort = viewChild.required(MatSort);\n\n readonly table = viewChild.required(MatTable);\n\n readonly matCheckboxes = viewChildren<MatCheckbox>('checkboxes');\n\n dataSource: ListDataSource;\n\n // Checked checkbox values' list\n public checkboxes: number[] = [];\n\n // Check all checkbox statuses\n public undetermined = false;\n public checked = false;\n\n // all columns first level\n allColumns = ['check', 'id', 'name', 'description', 'suspension', 'more'];\n // all columns second level\n allSubColumns = [\n 'check',\n 'id',\n 'name',\n 'description',\n 'delay',\n 'days',\n 'more',\n ];\n // removable columns\n columns = ['id', 'name', 'description'];\n\n // Filter form control\n search: FormControl = new FormControl('');\n\n dialog = inject(MatDialog);\n elementsService = inject(ElementsService);\n\n constructor() {\n super();\n // Create a new DataSource\n this.dataSource = new ListDataSource(this.elementsService);\n\n // When user start filtering, we need to update the master checkbox\n this.search.valueChanges.pipe(takeUntilDestroyed()).subscribe(search => {\n console.log(search);\n setTimeout(() => {\n this.updateToggleAllStatus();\n }, 100);\n });\n }\n\n /**\n *\n */\n showHideColumns() {\n const panelClass: string[] = ['large'];\n const dialogRef = this.dialog.open(DemoTableDialogContentComponent, {\n data: {\n allColumns: this.allColumns,\n allSubColumns: this.allSubColumns,\n columns: this.columns,\n },\n panelClass,\n });\n dialogRef\n .afterClosed()\n .pipe(take(1))\n .subscribe((values: boolean[]) => {\n if (values !== undefined) {\n this.allColumns = ['check'];\n this.allSubColumns = ['check'];\n values.forEach((value, index) => {\n if (value) {\n this.allColumns.push(this.columns[index]);\n this.allSubColumns.push(this.columns[index]);\n }\n });\n this.allColumns.push('suspension');\n this.allColumns.push('more');\n this.allSubColumns.push('delay');\n this.allSubColumns.push('days');\n this.allSubColumns.push('more');\n }\n });\n }\n\n /**\n * We set the datasource and paginator\n */\n ngAfterViewInit(): void {\n this.dataSource.sort = this.sort();\n this.dataSource.paginator = this.paginator();\n this.dataSource.search = this.search;\n this.table().dataSource = this.dataSource;\n }\n\n /**\n * returns the column visible state\n * @param column\n */\n columnIsVisible(column: string) {\n return this.allColumns.includes(column);\n }\n /**\n * returns the column visible state\n * @param column\n */\n subColumnIsVisible(column: string) {\n return this.allSubColumns.includes(column);\n }\n\n /**\n * Edit row action\n * @param row\n */\n edit(row: ListItem) {\n alert(`Edit row n°${row.id}: ${row.name}`);\n }\n\n /**\n * Delete row action\n * @param row\n */\n delete(row: ListItem) {\n this.dataSource.delete(row.id);\n }\n\n /**\n * Share row action\n * @param row\n */\n share(row: ListItem) {\n alert(`Share row n°${row.id}: ${row.name}`);\n }\n\n /**\n * clear search\n */\n clear() {\n this.search.setValue('');\n }\n\n /**\n * paginator changes page\n * @param event\n */\n changePage(event: PageEvent) {\n console.log(event);\n // timeout necessary to take the changes in account\n setTimeout(() => {\n this.updateToggleAllStatus();\n }, 100);\n }\n\n /**\n * Is the notice visible\n */\n showNotice() {\n return this.checkboxes.length > 0;\n }\n\n /**\n * is a checkbox checked\n * @param id\n */\n isChecked(id: number) {\n return this.checkboxes.includes(id);\n }\n\n /**\n * Toggle One checkbox\n * @param $event\n * @param id\n */\n toggleOne($event: MatCheckboxChange, id: number) {\n const checked = $event.checked;\n this.toggleCheckBox(id, checked);\n this.updateToggleAllStatus();\n }\n\n /**\n * toggle the checkbox with checks\n * @param id\n * @param checked\n * @private\n */\n private toggleCheckBox(id: number, checked: boolean) {\n if (checked) {\n if (!this.checkboxes.includes(id)) {\n this.checkboxes.push(id);\n }\n } else {\n this.checkboxes.splice(this.checkboxes.indexOf(id), 1);\n }\n }\n\n /**\n * Toggle all visible checkboxes\n * @param $event\n */\n toggleAllVisible($event: MatCheckboxChange) {\n const checked = $event.checked;\n this.checked = checked;\n\n this.matCheckboxes().forEach(matCheckbox => {\n const id = parseInt(matCheckbox.value);\n this.toggleCheckBox(id, checked);\n });\n this.updateToggleAllStatus();\n }\n\n /**\n * Update the status of the toggle all checkbox to reflect on what is checked (checked, unchecked, undetermined)\n */\n updateToggleAllStatus() {\n this.undetermined = false;\n this.checked = false;\n let cnt = 0;\n\n this.matCheckboxes().forEach(matCheckbox => {\n const id = parseInt(matCheckbox.value);\n if (this.checkboxes.includes(id)) {\n cnt++;\n }\n });\n if (cnt > 0) {\n if (cnt === this.matCheckboxes().length) {\n this.checked = true;\n } else {\n this.undetermined = true;\n }\n }\n }\n\n /**\n * Select all checkbox in the full datasource's list\n */\n selectAll() {\n this.dataSource\n .all()\n .pipe(take(1))\n .subscribe(ids => {\n this.checkboxes = ids;\n this.updateToggleAllStatus();\n });\n }\n\n /**\n * Deselect all checkboxes\n */\n deSelectAll() {\n this.checkboxes = [];\n this.updateToggleAllStatus();\n }\n}\n"}
|
|
1
|
+
{"demo-table-datasource.ts":"import { DataSource } from '@angular/cdk/collections';\nimport { MatSort } from '@angular/material/sort';\nimport { map, tap } from 'rxjs/operators';\nimport {\n BehaviorSubject,\n merge,\n Observable,\n startWith,\n Subject,\n switchMap,\n} from 'rxjs';\nimport { OnemrvaMatPaginatorComponent } from '@onemrvapublic/design-system/mat-paginator';\nimport { FormControl } from '@angular/forms';\nimport { ElementsService, ListItem } from '../../_services/elements.service';\n\n/**\n * Data source for the List view. This class should\n * encapsulate all logic for fetching and manipulating the displayed data\n * (including sorting, pagination, and filtering).\n */\nexport class ListDataSource extends DataSource<ListItem> {\n paginator!: OnemrvaMatPaginatorComponent;\n search!: FormControl;\n sort: MatSort | undefined;\n data$: BehaviorSubject<ListItem[]> = new BehaviorSubject<ListItem[]>([]);\n prevSearch = '';\n refresh$ = new Subject();\n\n constructor(private elementsService: ElementsService) {\n super();\n }\n\n /**\n * Connect this data source to the table. The table will only update when\n * the returned stream emits new items.\n * @returns A stream of the items to be rendered.\n */\n connect(): Observable<ListItem[]> {\n if (this.sort) {\n // Combine everything that affects the rendered data into one update\n // stream for the data-table to consume.\n return merge(\n this.sort.sortChange, // we listen to sort change\n this.search.valueChanges, // we listen to filter change\n this.paginator.pageSize$, // we listen to page size change\n this.paginator.pageIndex$, // we listen to page index change\n this.refresh$, // used to force a refresh\n ).pipe(\n startWith({}),\n tap(() => {\n // if search changed, we reset the pageIndex\n if (\n this.search.getRawValue().trim() !== '' &&\n this.search.getRawValue() !== this.prevSearch\n ) {\n this.paginator.resetPageIndex();\n this.prevSearch = this.search.getRawValue();\n }\n }),\n switchMap(() => {\n const active: keyof ListItem =\n (this.sort?.active as keyof ListItem) || 'id';\n const direction = this.sort?.direction || 'asc';\n // We return the api call observable called with the correct parameters\n return this.elementsService\n .getElementsList(\n active,\n direction,\n this.paginator.pageIndex,\n this.paginator.pageSize,\n this.search.getRawValue(),\n )\n .pipe(\n // We map the response to the Interface we need/want\n map(response => {\n this.paginator.length = response.length;\n this.paginator.pageIndex = response.page;\n this.paginator.pageSize = response.pageSize;\n return response.list;\n }),\n );\n }),\n );\n } else {\n throw Error('Please set the sort on the data source before connecting.');\n }\n }\n\n /**\n * Called when the table is being destroyed. Use this function, to clean up\n * any open connections or free any held resources that were set up during connect.\n */\n disconnect(): void {\n console.log('disconnect');\n }\n\n /**\n * If user click on select all items (outside current page),\n * this service functions returns the IDs of all items in datasource\n */\n all() {\n return this.elementsService.getAllElementsIds(this.search.getRawValue());\n }\n\n /**\n * If user click to delete an item, we tell the api and then refresh the list.\n * @param id\n */\n delete(id: number) {\n this.elementsService.deleteElement(id);\n this.refresh$.next('');\n }\n}\n","demo-table.component.html":"<h1>Table</h1>\n<mat-form-field class=\"search\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"search\" />\n @if (search.getRawValue()) {\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"clear()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n</mat-form-field>\n<p><a tabindex=\"0\" (click)=\"showHideColumns()\">Hide/Show column</a></p>\n<table mat-table class=\"full-width-table\" matSort aria-label=\"Elements\">\n <tr mat-header-row *matHeaderRowDef=\"allColumns\"></tr>\n <tr mat-header-row class=\"compact\" *matHeaderRowDef=\"['delay', 'days']\"></tr>\n\n <!-- Notice Row -->\n <tr\n mat-header-row\n class=\"onemrva-notice-row\"\n [class]=\"showNotice() ? '' : 'hidden'\"\n *matHeaderRowDef=\"showNotice() ? ['notice'] : []\"\n ></tr>\n @if (showNotice()) {\n <ng-container matColumnDef=\"notice\">\n <th *matHeaderCellDef colspan=\"7\">\n You have selected {{ checkboxes.length }} items. \n @if (checkboxes.length < paginator.length) {\n <a tabindex=\"0\" (click)=\"selectAll()\"\n >Select {{ paginator.length }} items</a\n > \n }\n @if (checkboxes.length >= 0) {\n <a tabindex=\"0\" (click)=\"deSelectAll()\"\n >Deselect {{ checkboxes.length }} items</a\n >\n }\n </th>\n </ng-container>\n }\n <!-- Notice Row -->\n\n <tr mat-row *matRowDef=\"let _; columns: allSubColumns\"></tr>\n\n <tr *matNoDataRow class=\"noresult\">\n <td colspan=\"7\">\n <onemrva-mat-empty-row (clear)=\"clear()\" />\n </td>\n </tr>\n\n <!-- checkbox Column -->\n <ng-container matColumnDef=\"check\">\n <th mat-header-cell *matHeaderCellDef [attr.rowspan]=\"2\">\n <div>\n <mat-checkbox\n aria-label=\"Check All\"\n value=\"toggleAll\"\n [checked]=\"checked\"\n [indeterminate]=\"undetermined\"\n (change)=\"toggleAllVisible($event)\"\n />\n </div>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n #checkboxes\n aria-label=\"Check row {{ row.id }}\"\n [value]=\"row.id\"\n [checked]=\"isChecked(row.id)\"\n (change)=\"toggleOne($event, row.id)\"\n />\n </td>\n </ng-container>\n\n <!-- Id Column -->\n @if (columnIsVisible('id')) {\n <ng-container matColumnDef=\"id\" sticky>\n <th\n mat-header-cell\n class=\"compact\"\n *matHeaderCellDef\n mat-sort-header\n [attr.rowspan]=\"2\"\n >\n Id\n </th>\n <td mat-cell class=\"compact\" *matCellDef=\"let row\">\n {{ row.id }}\n </td>\n </ng-container>\n }\n\n <!-- Name Column -->\n @if (columnIsVisible('name')) {\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header [attr.rowspan]=\"2\">\n Name\n </th>\n <td id=\"{{ row.name }}\" mat-cell *matCellDef=\"let row\">\n <a href=\"/#table\">{{ row.name }}</a>\n </td>\n </ng-container>\n }\n\n <!-- Description Column -->\n @if (columnIsVisible('description')) {\n <ng-container matColumnDef=\"description\">\n <th\n mat-header-cell\n *matHeaderCellDef\n mat-sort-header=\"description\"\n [attr.rowspan]=\"2\"\n class=\"d-table-cell-large description-cell\"\n >\n Description\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"d-table-cell-large description-cell\"\n >\n <span></span>\n {{ row.description }}\n </td></ng-container\n >\n }\n @if (columnIsVisible('suspension')) {\n <!-- Suspension Column -->\n <ng-container matColumnDef=\"suspension\">\n <th\n mat-header-cell\n *matHeaderCellDef\n [attr.colspan]=\"2\"\n class=\"align-center compact\"\n >\n Suspension\n </th>\n <!-- This column doesn't generate <td> items, so no need to add a definition for them -->\n </ng-container>\n }\n\n @if (subColumnIsVisible('delay')) {\n <!-- Delay Column -->\n <ng-container matColumnDef=\"delay\">\n <th mat-header-cell *matHeaderCellDef class=\"compact align-center\">\n Delay\n </th>\n <td mat-cell *matCellDef=\"let _\" class=\"align-center\">1</td>\n </ng-container>\n }\n\n @if (subColumnIsVisible('days')) {\n <!-- Days Column -->\n <ng-container matColumnDef=\"days\">\n <th mat-header-cell *matHeaderCellDef class=\"compact align-center\">\n Days\n </th>\n <td mat-cell *matCellDef=\"let _\" class=\"align-center\">2</td>\n </ng-container>\n }\n\n @if (columnIsVisible('more')) {\n <!-- Menu Column -->\n <ng-container matColumnDef=\"more\">\n <th mat-header-cell class=\"compact\" *matHeaderCellDef [attr.rowspan]=\"2\">\n Menu\n </th>\n <td mat-cell class=\"compact align-right\" *matCellDef=\"let row\">\n <button mat-icon-button [matMenuTriggerFor]=\"menu\" aria-label=\"More\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menu=\"matMenu\">\n <button mat-menu-item (click)=\"edit(row)\" aria-label=\"Edit\">\n <mat-icon>edit</mat-icon>\n Edit\n </button>\n <button mat-menu-item (click)=\"delete(row)\" aria-label=\"Delete\">\n <mat-icon>delete</mat-icon>\n Delete\n </button>\n <button mat-menu-item (click)=\"share(row)\" aria-label=\"Share\">\n <mat-icon>share</mat-icon>\n Share\n </button>\n </mat-menu>\n </td>\n </ng-container>\n }\n</table>\n<div class=\"my-m\">\n <onemrva-mat-paginator\n [pageSizeSelector]=\"true\"\n [pageSizeOptions]=\"[5, 10, 20, 50]\"\n [pageSizeDefaultOption]=\"5\"\n [pageSize]=\"5\"\n previousKey=\"Previous\"\n nextKey=\"Next\"\n (page)=\"changePage($event)\"\n #paginator\n />\n</div>\n","demo-table.component.scss":"table {\n // Medium media query of material\n // the initial is display: table, but it doesn't show responsive on larger screens\n @media (max-width: 1279.98px) {\n // Block is required for the scroll overflow!\n display: block;\n overflow: auto;\n width: 100%;\n }\n\n .description-cell {\n min-width: 500px;\n }\n}\n","demo-table.component.ts":"import {\n AfterViewInit,\n Component,\n inject,\n ViewEncapsulation,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { MatSort, MatSortModule } from '@angular/material/sort';\nimport { MatTable, MatTableModule } from '@angular/material/table';\nimport { ListDataSource } from './demo-table-datasource';\nimport { PageEvent } from '@angular/material/paginator';\nimport { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { MatCheckbox, MatCheckboxChange } from '@angular/material/checkbox';\n\nimport { MatChipsModule } from '@angular/material/chips';\nimport { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatIconButton } from '@angular/material/button';\nimport {\n OnemrvaMatPaginatorComponent,\n OnemrvaMatPaginatorModule,\n} from '@onemrvapublic/design-system/mat-paginator';\nimport {\n MatFormField,\n MatLabel,\n MatSuffix,\n} from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { OnemrvaMatEmptyRowComponent } from '@onemrvapublic/design-system/mat-empty-row';\nimport { ElementsService, ListItem } from '../../_services/elements.service';\nimport { OnemrvaMatMessageBoxModule } from '@onemrvapublic/design-system/mat-message-box';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { take } from 'rxjs';\nimport { MatDialog, MatDialogModule } from '@angular/material/dialog';\nimport { DemoTableDialogContentComponent } from '../table-dialog-content';\nimport { MatIcon } from '@angular/material/icon';\nimport { DemoComponentBase } from '../../_demo/demo-component-base';\n\n@Component({\n selector: 'app-demo-table',\n templateUrl: './demo-table.component.html',\n styleUrls: ['./demo-table.component.scss'],\n\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormsModule,\n MatCheckbox,\n MatChipsModule,\n MatFormField,\n MatIconButton,\n MatInput,\n MatLabel,\n MatMenu,\n MatMenuTrigger,\n MatSortModule,\n MatSuffix,\n MatTableModule,\n MatDialogModule,\n MatIcon,\n OnemrvaMatPaginatorModule,\n OnemrvaMatEmptyRowComponent,\n OnemrvaMatMessageBoxModule,\n OnemrvaMatPaginatorComponent,\n MatMenuItem,\n ],\n encapsulation: ViewEncapsulation.None,\n})\nexport class DemoTableComponent\n extends DemoComponentBase\n implements AfterViewInit\n{\n readonly paginator = viewChild.required(OnemrvaMatPaginatorComponent);\n\n readonly sort = viewChild.required(MatSort);\n\n readonly table = viewChild.required(MatTable);\n\n readonly matCheckboxes = viewChildren<MatCheckbox>('checkboxes');\n\n dataSource: ListDataSource;\n\n // Checked checkbox values' list\n public checkboxes: number[] = [];\n\n // Check all checkbox statuses\n public undetermined = false;\n public checked = false;\n\n // all columns first level\n allColumns = ['check', 'id', 'name', 'description', 'suspension', 'more'];\n // all columns second level\n allSubColumns = [\n 'check',\n 'id',\n 'name',\n 'description',\n 'delay',\n 'days',\n 'more',\n ];\n // removable columns\n columns = ['id', 'name', 'description'];\n\n // Filter form control\n search: FormControl = new FormControl('');\n\n dialog = inject(MatDialog);\n elementsService = inject(ElementsService);\n\n constructor() {\n super();\n // Create a new DataSource\n this.dataSource = new ListDataSource(this.elementsService);\n\n // When user start filtering, we need to update the master checkbox\n this.search.valueChanges.pipe(takeUntilDestroyed()).subscribe(search => {\n console.log(search);\n setTimeout(() => {\n this.updateToggleAllStatus();\n }, 100);\n });\n }\n\n /**\n *\n */\n showHideColumns() {\n const panelClass: string[] = ['large'];\n const dialogRef = this.dialog.open(DemoTableDialogContentComponent, {\n data: {\n allColumns: this.allColumns,\n allSubColumns: this.allSubColumns,\n columns: this.columns,\n },\n panelClass,\n });\n dialogRef\n .afterClosed()\n .pipe(take(1))\n .subscribe((values: boolean[]) => {\n if (values !== undefined) {\n this.allColumns = ['check'];\n this.allSubColumns = ['check'];\n values.forEach((value, index) => {\n if (value) {\n this.allColumns.push(this.columns[index]);\n this.allSubColumns.push(this.columns[index]);\n }\n });\n this.allColumns.push('suspension');\n this.allColumns.push('more');\n this.allSubColumns.push('delay');\n this.allSubColumns.push('days');\n this.allSubColumns.push('more');\n }\n });\n }\n\n /**\n * We set the datasource and paginator\n */\n ngAfterViewInit(): void {\n this.dataSource.sort = this.sort();\n this.dataSource.paginator = this.paginator();\n this.dataSource.search = this.search;\n this.table().dataSource = this.dataSource;\n }\n\n /**\n * returns the column visible state\n * @param column\n */\n columnIsVisible(column: string) {\n return this.allColumns.includes(column);\n }\n /**\n * returns the column visible state\n * @param column\n */\n subColumnIsVisible(column: string) {\n return this.allSubColumns.includes(column);\n }\n\n /**\n * Edit row action\n * @param row\n */\n edit(row: ListItem) {\n alert(`Edit row n°${row.id}: ${row.name}`);\n }\n\n /**\n * Delete row action\n * @param row\n */\n delete(row: ListItem) {\n this.dataSource.delete(row.id);\n }\n\n /**\n * Share row action\n * @param row\n */\n share(row: ListItem) {\n alert(`Share row n°${row.id}: ${row.name}`);\n }\n\n /**\n * clear search\n */\n clear() {\n this.search.setValue('');\n }\n\n /**\n * paginator changes page\n * @param event\n */\n changePage(event: PageEvent) {\n console.log(event);\n // timeout necessary to take the changes in account\n setTimeout(() => {\n this.updateToggleAllStatus();\n }, 100);\n }\n\n /**\n * Is the notice visible\n */\n showNotice() {\n return this.checkboxes.length > 0;\n }\n\n /**\n * is a checkbox checked\n * @param id\n */\n isChecked(id: number) {\n return this.checkboxes.includes(id);\n }\n\n /**\n * Toggle One checkbox\n * @param $event\n * @param id\n */\n toggleOne($event: MatCheckboxChange, id: number) {\n const checked = $event.checked;\n this.toggleCheckBox(id, checked);\n this.updateToggleAllStatus();\n }\n\n /**\n * toggle the checkbox with checks\n * @param id\n * @param checked\n * @private\n */\n private toggleCheckBox(id: number, checked: boolean) {\n if (checked) {\n if (!this.checkboxes.includes(id)) {\n this.checkboxes.push(id);\n }\n } else {\n this.checkboxes.splice(this.checkboxes.indexOf(id), 1);\n }\n }\n\n /**\n * Toggle all visible checkboxes\n * @param $event\n */\n toggleAllVisible($event: MatCheckboxChange) {\n const checked = $event.checked;\n this.checked = checked;\n\n this.matCheckboxes().forEach(matCheckbox => {\n const id = parseInt(matCheckbox.value);\n this.toggleCheckBox(id, checked);\n });\n this.updateToggleAllStatus();\n }\n\n /**\n * Update the status of the toggle all checkbox to reflect on what is checked (checked, unchecked, undetermined)\n */\n updateToggleAllStatus() {\n this.undetermined = false;\n this.checked = false;\n let cnt = 0;\n\n this.matCheckboxes().forEach(matCheckbox => {\n const id = parseInt(matCheckbox.value);\n if (this.checkboxes.includes(id)) {\n cnt++;\n }\n });\n if (cnt > 0) {\n if (cnt === this.matCheckboxes().length) {\n this.checked = true;\n } else {\n this.undetermined = true;\n }\n }\n }\n\n /**\n * Select all checkbox in the full datasource's list\n */\n selectAll() {\n this.dataSource\n .all()\n .pipe(take(1))\n .subscribe(ids => {\n this.checkboxes = ids;\n this.updateToggleAllStatus();\n });\n }\n\n /**\n * Deselect all checkboxes\n */\n deSelectAll() {\n this.checkboxes = [];\n this.updateToggleAllStatus();\n }\n}\n"}
|