ui-shared-plugin.module.ts 5.0 KB

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