ui-shared-plugin.module.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import { APP_INITIALIZER, ChangeDetectorRef, Component, NgModule, OnInit } from '@angular/core';
  2. import { FormControl } from '@angular/forms';
  3. import {
  4. AssetPickerDialogComponent,
  5. CustomFieldComponentService,
  6. CustomFieldConfig,
  7. CustomFieldControl,
  8. DataService,
  9. ModalService,
  10. NavBuilderService,
  11. SharedModule,
  12. } from '@vendure/admin-ui/src';
  13. import { unique } from '@vendure/common/lib/unique';
  14. import gql from 'graphql-tag';
  15. import { Observable, of } from 'rxjs';
  16. import { startWith, switchMap } from 'rxjs/operators';
  17. @Component({
  18. template: `
  19. <input
  20. type="range"
  21. [min]="customFieldConfig.intMin"
  22. [max]="customFieldConfig.intMax"
  23. [formControl]="formControl"
  24. />
  25. {{ formControl.value }}
  26. `,
  27. })
  28. export class SliderControl implements CustomFieldControl {
  29. customFieldConfig: CustomFieldConfig;
  30. formControl: FormControl;
  31. }
  32. @Component({
  33. template: `
  34. <div class="featured-asset">
  35. <img
  36. *ngIf="currentAsset$ | async as asset; else placeholder"
  37. [src]="asset!.preview + '?preset=thumb'"
  38. />
  39. <ng-template #placeholder>
  40. <div class="placeholder">
  41. <clr-icon shape="image" size="128"></clr-icon>
  42. <div>{{ 'catalog.no-featured-asset' | translate }}</div>
  43. </div>
  44. </ng-template>
  45. </div>
  46. <button class="btn" (click)="selectAssets()">
  47. <clr-icon shape="attachment"></clr-icon>
  48. {{ 'catalog.add-asset' | translate }}
  49. </button>
  50. `,
  51. })
  52. export class AssetPickerControl implements CustomFieldControl, OnInit {
  53. customFieldConfig: CustomFieldConfig;
  54. formControl: FormControl;
  55. currentAsset$: Observable<any | null>;
  56. constructor(
  57. private changeDetectorRef: ChangeDetectorRef,
  58. private modalService: ModalService,
  59. private dataService: DataService,
  60. ) {}
  61. ngOnInit(): void {
  62. this.currentAsset$ = this.formControl.valueChanges.pipe(
  63. startWith(this.formControl.value),
  64. switchMap(assetId => {
  65. if (!assetId) {
  66. return of(null);
  67. }
  68. return this.dataService
  69. .query(
  70. gql`
  71. query($id: ID!) {
  72. asset(id: $id) {
  73. id
  74. name
  75. preview
  76. width
  77. height
  78. }
  79. }
  80. `,
  81. { id: assetId },
  82. )
  83. .mapStream((data: any) => data.asset);
  84. }),
  85. );
  86. }
  87. selectAssets() {
  88. this.modalService
  89. .fromComponent(AssetPickerDialogComponent, {
  90. size: 'xl',
  91. })
  92. .subscribe((result: any) => {
  93. if (result && result.length) {
  94. this.formControl.setValue(result[0].id);
  95. this.formControl.markAsDirty();
  96. // this.changeDetectorRef.markForCheck();
  97. }
  98. });
  99. }
  100. }
  101. @NgModule({
  102. imports: [SharedModule],
  103. declarations: [SliderControl, AssetPickerControl],
  104. entryComponents: [SliderControl, AssetPickerControl],
  105. providers: [
  106. {
  107. provide: APP_INITIALIZER,
  108. multi: true,
  109. useFactory: addNavItems,
  110. deps: [NavBuilderService],
  111. },
  112. {
  113. provide: APP_INITIALIZER,
  114. multi: true,
  115. useFactory: registerCustomFieldComponents,
  116. deps: [CustomFieldComponentService],
  117. },
  118. ],
  119. })
  120. export class TestSharedModule {}
  121. export function registerCustomFieldComponents(customFieldComponentService: CustomFieldComponentService) {
  122. return () => {
  123. customFieldComponentService.registerCustomFieldComponent('Product', 'length', SliderControl);
  124. customFieldComponentService.registerCustomFieldComponent('ProductVariant', 'length', SliderControl);
  125. customFieldComponentService.registerCustomFieldComponent(
  126. 'Product',
  127. 'offerImageId',
  128. AssetPickerControl,
  129. );
  130. };
  131. }
  132. export function addNavItems(navBuilder: NavBuilderService) {
  133. return () => {
  134. navBuilder.addNavMenuSection(
  135. {
  136. id: 'test-plugin',
  137. label: 'Test Plugin',
  138. items: [
  139. {
  140. id: 'stats',
  141. label: 'Test',
  142. routerLink: ['/extensions/test'],
  143. icon: 'line-chart',
  144. },
  145. ],
  146. },
  147. 'settings',
  148. );
  149. };
  150. }