@haus-tech/badge-plugin 0.1.8 → 0.1.10

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.
@@ -27,7 +27,7 @@ let BadgePlugin = BadgePlugin_1 = class BadgePlugin {
27
27
  if (options) {
28
28
  this.options = options;
29
29
  }
30
- return this;
30
+ return BadgePlugin_1;
31
31
  }
32
32
  static ui = {
33
33
  extensionPath: path_1.default.join(__dirname, 'ui'),
@@ -35,8 +35,19 @@ let BadgePlugin = BadgePlugin_1 = class BadgePlugin {
35
35
  en: path_1.default.join(__dirname, 'ui/translations/en.json'),
36
36
  sv: path_1.default.join(__dirname, 'ui/translations/sv.json'),
37
37
  },
38
- providers: ['providers.ts'],
39
- routes: [{ route: 'badges', filePath: 'routes.ts' }],
38
+ ngModules: [
39
+ {
40
+ type: 'lazy',
41
+ route: 'badges',
42
+ ngModuleFileName: 'badge.module.ts',
43
+ ngModuleName: 'BadgeModule',
44
+ },
45
+ {
46
+ type: 'shared',
47
+ ngModuleFileName: 'badge-nav.module.ts',
48
+ ngModuleName: 'BadgesNavModule',
49
+ },
50
+ ],
40
51
  };
41
52
  };
42
53
  BadgePlugin = BadgePlugin_1 = __decorate([
package/dist/index.d.ts CHANGED
@@ -1,2 +1 @@
1
1
  export * from './badge.plugin';
2
- export * from './ui/gql/graphql';
package/dist/index.js CHANGED
@@ -15,4 +15,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./badge.plugin"), exports);
18
- __exportStar(require("./ui/gql/graphql"), exports);
@@ -0,0 +1,78 @@
1
+ <vdr-page-block style="width: 100%">
2
+ <div class="my-2" style="width: 100%">
3
+ <vdr-page-block>
4
+ <vdr-action-bar>
5
+ <vdr-ab-left></vdr-ab-left>
6
+ <vdr-ab-right>
7
+ <vdr-asset-file-input
8
+ (selectFiles)="filesSelected($event)"
9
+ [uploading]="uploading"
10
+ dropZoneTarget=".content-area"
11
+ ></vdr-asset-file-input>
12
+ </vdr-ab-right>
13
+ </vdr-action-bar>
14
+ </vdr-page-block>
15
+ </div>
16
+ <div class="gallery-wrapper">
17
+ <div class="gallery">
18
+ <div
19
+ class="card"
20
+ *ngFor="let item of items$ | async"
21
+ (click)="toggleSelection(item, $event)"
22
+ [class.selected]="isSelected(item)"
23
+ >
24
+ <div class="card-img">
25
+ <vdr-select-toggle
26
+ [selected]="isSelected(item)"
27
+ [disabled]="true"
28
+ [hiddenWhenOff]="true"
29
+ ></vdr-select-toggle>
30
+ <img class="asset-thumb" [src]="item.asset | assetPreview : 'thumb'" />
31
+ </div>
32
+ <div class="detail">
33
+ <span [title]="item.position">{{ item.position }}</span>
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ <div class="info-bar">
39
+ <div class="card">
40
+ <div class="card-img">
41
+ <div class="placeholder" *ngIf="selectionManager.selection.length === 0">
42
+ <clr-icon shape="image" size="128"></clr-icon>
43
+ <div>{{ 'catalog.no-selection' | translate }}</div>
44
+ </div>
45
+ <img
46
+ class="preview"
47
+ *ngIf="selectionManager.selection.length >= 1"
48
+ [src]="lastSelected().asset.preview + '?preset=medium'"
49
+ />
50
+ </div>
51
+ <div class="card-block details" *ngIf="selectionManager.selection.length >= 1">
52
+ <div *ngIf="selectionManager.selection.length === 1">
53
+ <update-badge
54
+ [badge]="lastSelected()"
55
+ [availablePositions]="config.availablePositions"
56
+ (badgeUpdated)="onBadgeUpdated($event)"
57
+ ></update-badge>
58
+ </div>
59
+ <div *ngIf="canDelete">
60
+ <button (click)="deleteBadges(selectionManager.selection)" class="button-small mt-1">
61
+ <clr-icon shape="trash" class="is-danger"></clr-icon>
62
+ {{ 'common.delete' | translate }}
63
+ </button>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ <div class="card stack" [class.visible]="selectionManager.selection.length > 1"></div>
68
+ <div class="selection-count" [class.visible]="selectionManager.selection.length > 1">
69
+ {{
70
+ 'asset.assets-selected-count' | translate : { count: selectionManager.selection.length }
71
+ }}
72
+ <ul>
73
+ <li *ngFor="let asset of selectionManager.selection">{{ asset.name }}</li>
74
+ </ul>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </vdr-page-block>
@@ -17,7 +17,6 @@ const graphql_1 = require("./gql/graphql");
17
17
  const ngx_translate_extract_marker_1 = require("@biesbjerg/ngx-translate-extract-marker");
18
18
  const rxjs_1 = require("rxjs");
19
19
  const operators_1 = require("rxjs/operators");
20
- const update_badge_component_1 = require("./update-badge.component");
21
20
  const getBadgeListDocument = (0, gql_1.graphql)(`
22
21
  query GetBadges($options: BadgeListOptions) {
23
22
  badges(options: $options) {
@@ -232,8 +231,6 @@ BadgeListComponent = __decorate([
232
231
  templateUrl: './badge-list.component.html',
233
232
  styleUrls: ['./badge-list.component.scss'],
234
233
  changeDetection: core_2.ChangeDetectionStrategy.OnPush,
235
- standalone: true,
236
- imports: [core_1.SharedModule, update_badge_component_1.UpdateBadgeComponent],
237
234
  }),
238
235
  (0, core_2.Injectable)(),
239
236
  __metadata("design:paramtypes", [core_1.NotificationService,
@@ -0,0 +1,139 @@
1
+ @import 'variables';
2
+
3
+ :host {
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: 100%;
7
+ }
8
+
9
+ .gallery-wrapper {
10
+ display: flex;
11
+ flex-direction: column-reverse;
12
+ @media screen and (min-width: $breakpoint-medium) {
13
+ flex-direction: row;
14
+ }
15
+ }
16
+
17
+ .gallery {
18
+ /* autoprefixer: off */
19
+ flex: 1;
20
+ display: grid;
21
+ grid-template-columns: repeat(auto-fill, 150px);
22
+ grid-template-rows: repeat(auto-fill, 180px);
23
+ grid-gap: 10px 20px;
24
+
25
+ .card:hover {
26
+ box-shadow: 0 0.125rem 0 0 var(--color-primary-500);
27
+ border: 1px solid var(--color-primary-500);
28
+ }
29
+ }
30
+
31
+ .card {
32
+ margin-top: 0;
33
+ position: relative;
34
+ }
35
+
36
+ img.asset-thumb {
37
+ aspect-ratio: 1;
38
+ }
39
+
40
+ vdr-select-toggle {
41
+ position: absolute;
42
+ ::ng-deep .toggle {
43
+ box-shadow: 0px 5px 5px -4px rgba(0, 0, 0, 0.75);
44
+ }
45
+ top: -12px;
46
+ left: -12px;
47
+ }
48
+
49
+ .card.selected {
50
+ box-shadow: 0 0.125rem 0 0 var(--color-primary-500);
51
+ border: 1px solid var(--color-primary-500);
52
+
53
+ .selected-checkbox {
54
+ opacity: 1;
55
+ }
56
+ }
57
+
58
+ .detail {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 4px;
62
+ font-size: 12px;
63
+ margin: 3px;
64
+ overflow: hidden;
65
+ white-space: nowrap;
66
+ text-overflow: ellipsis;
67
+ vdr-entity-info {
68
+ height: 16px;
69
+ }
70
+ }
71
+
72
+ .info-bar {
73
+ @media screen and (min-width: $breakpoint-medium) {
74
+ width: 25%;
75
+ }
76
+ padding: 0 6px;
77
+ overflow-y: visible;
78
+
79
+ .card {
80
+ z-index: 1;
81
+ }
82
+
83
+ .stack {
84
+ z-index: 0;
85
+ opacity: 0;
86
+ transform: perspective(500px) translateZ(0px) translateY(-16px);
87
+ height: 16px;
88
+ transition: transform 0.3s, opacity 0s 0.3s;
89
+ background-color: white;
90
+
91
+ &.visible {
92
+ opacity: 1;
93
+ transform: perspective(500px) translateZ(-44px) translateY(0px);
94
+ background-color: var(--color-component-bg-100);
95
+ transition: transform 0.3s, color 0.3s;
96
+ }
97
+ }
98
+
99
+ .selection-count {
100
+ opacity: 0;
101
+ position: relative;
102
+ text-align: center;
103
+ visibility: hidden;
104
+ transition: opacity 0.3s, visibility 0s 0.3s;
105
+ &.visible {
106
+ opacity: 1;
107
+ visibility: visible;
108
+ transition: opacity 0.3s, visibility 0s;
109
+ }
110
+ ul {
111
+ text-align: start;
112
+ list-style-type: none;
113
+ margin-inline-start: 12px;
114
+ li {
115
+ font-size: 12px;
116
+ }
117
+ }
118
+ }
119
+
120
+ .placeholder {
121
+ text-align: center;
122
+ color: var(--color-grey-300);
123
+ }
124
+
125
+ .preview {
126
+ img {
127
+ max-width: 100%;
128
+ }
129
+ }
130
+ .details {
131
+ font-size: 12px;
132
+ word-break: break-all;
133
+ }
134
+ .name {
135
+ line-height: 14px;
136
+ font-weight: bold;
137
+ margin-bottom: 4px;
138
+ }
139
+ }
@@ -0,0 +1,274 @@
1
+ import {
2
+ TypedBaseListComponent,
3
+ NotificationService,
4
+ ModalService,
5
+ SelectionManager,
6
+ } from '@vendure/admin-ui/core'
7
+ import {
8
+ Component,
9
+ Injectable,
10
+ OnInit,
11
+ OnChanges,
12
+ ChangeDetectionStrategy,
13
+ SimpleChanges,
14
+ } from '@angular/core'
15
+ import { graphql } from './gql'
16
+ import { Badge, DeletionResult } from './gql/graphql'
17
+ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
18
+ import { EMPTY } from 'rxjs'
19
+ import { finalize, map, switchMap } from 'rxjs/operators'
20
+ import { Asset } from '@vendure/core'
21
+
22
+ const getBadgeListDocument = graphql(`
23
+ query GetBadges($options: BadgeListOptions) {
24
+ badges(options: $options) {
25
+ items {
26
+ id
27
+ createdAt
28
+ updatedAt
29
+ collection {
30
+ id
31
+ }
32
+ collectionId
33
+ position
34
+ asset {
35
+ id
36
+ name
37
+ type
38
+ mimeType
39
+ width
40
+ height
41
+ fileSize
42
+ source
43
+ preview
44
+ }
45
+ }
46
+ totalItems
47
+ }
48
+ }
49
+ `)
50
+
51
+ const createBadgeDocument = graphql(`
52
+ mutation CreateBadge($input: CreateBadgeInput!) {
53
+ createBadge(input: $input) {
54
+ id
55
+ }
56
+ }
57
+ `)
58
+
59
+ const deleteBadgeDocument = graphql(`
60
+ mutation DeleteBadge($ids: [ID!]!) {
61
+ deleteBadge(ids: $ids) {
62
+ result
63
+ message
64
+ }
65
+ }
66
+ `)
67
+
68
+ const getPluginConfigDocument = graphql(`
69
+ query GetBadgePluginConfig {
70
+ getBadgePluginConfig {
71
+ availablePositions
72
+ }
73
+ }
74
+ `)
75
+
76
+ export interface BadgePluginOptions {
77
+ availablePositions: string[]
78
+ }
79
+
80
+ @Component({
81
+ selector: 'badge-list',
82
+ templateUrl: './badge-list.component.html',
83
+ styleUrls: ['./badge-list.component.scss'],
84
+ changeDetection: ChangeDetectionStrategy.OnPush,
85
+ })
86
+ @Injectable()
87
+ export class BadgeListComponent
88
+ extends TypedBaseListComponent<typeof getBadgeListDocument, 'badges'>
89
+ implements OnInit, OnChanges
90
+ {
91
+ config: BadgePluginOptions
92
+ uploading = false
93
+ canDelete = true
94
+ badges: Badge[]
95
+
96
+ selectionManager = new SelectionManager<Badge>({
97
+ multiSelect: true,
98
+ itemsAreEqual: (a, b) => a.id === b.id,
99
+ additiveMode: false,
100
+ })
101
+
102
+ constructor(
103
+ private notificationService: NotificationService,
104
+ private modalService: ModalService,
105
+ ) {
106
+ super()
107
+ super.configure({
108
+ document: getBadgeListDocument,
109
+ getItems: (data) => {
110
+ this.badges = data.badges.items as Badge[]
111
+ return data.badges
112
+ },
113
+ setVariables: () => ({
114
+ options: {
115
+ skip: 0,
116
+ take: 999,
117
+ },
118
+ }),
119
+ refreshListOnChanges: [],
120
+ })
121
+
122
+ this.dataService
123
+ .query(getPluginConfigDocument)
124
+ .mapSingle((item) => item)
125
+ .subscribe({
126
+ next: (response) => {
127
+ this.config = response.getBadgePluginConfig as BadgePluginOptions
128
+ },
129
+ error: (error) => console.error('Query error:', error),
130
+ })
131
+ }
132
+
133
+ ngOnChanges(changes: SimpleChanges) {
134
+ console.log('changes:', changes)
135
+ if (this.items$) {
136
+ for (const badge of this.selectionManager.selection) {
137
+ // Update any selected assets with any changes
138
+ const match = this.badges.find((a) => a.id === badge.id)
139
+ if (match) {
140
+ Object.assign(badge, match)
141
+ }
142
+ }
143
+ }
144
+ if (changes['badges']) {
145
+ this.selectionManager.setCurrentItems(this.badges)
146
+ }
147
+ }
148
+
149
+ async ngOnInit(): Promise<void> {
150
+ super.ngOnInit()
151
+ }
152
+
153
+ toggleSelection(asset: Badge, event?: any) {
154
+ this.selectionManager.toggleSelection(asset, event)
155
+ }
156
+
157
+ selectMultiple(assets: Badge[]) {
158
+ this.selectionManager.selectMultiple(assets)
159
+ }
160
+
161
+ isSelected(asset: Badge): boolean {
162
+ return this.selectionManager.isSelected(asset)
163
+ }
164
+
165
+ lastSelected(): Badge {
166
+ return this.selectionManager.lastSelected()
167
+ }
168
+
169
+ filesSelected(files: File[]) {
170
+ if (files.length) {
171
+ this.uploading = true
172
+ this.dataService.product
173
+ .createAssets(files)
174
+ .pipe(
175
+ finalize(() => {
176
+ this.uploading = false
177
+ }),
178
+ )
179
+ .subscribe(({ createAssets }) => {
180
+ let successCount = 0
181
+ for (const result of createAssets) {
182
+ switch (result.__typename) {
183
+ case 'Asset':
184
+ successCount++
185
+ break
186
+ case 'MimeTypeError':
187
+ this.notificationService.error(result.message)
188
+ break
189
+ }
190
+ }
191
+ if (0 < successCount) {
192
+ super.refresh()
193
+ this.notificationService.success(_('badge-plugin.notify-create-badges-success'), {
194
+ count: successCount,
195
+ })
196
+ this.createBadges(createAssets as Asset[])
197
+ }
198
+ })
199
+ }
200
+ }
201
+
202
+ async createBadges(assets: Asset[]) {
203
+ for (const asset of assets) {
204
+ await this.dataService
205
+ .mutate(createBadgeDocument, {
206
+ input: {
207
+ assetId: asset.id as string,
208
+ position: this.config.availablePositions[0],
209
+ },
210
+ })
211
+ .toPromise()
212
+ }
213
+ this.refresh()
214
+ }
215
+
216
+ deleteBadges(badges: Badge[]) {
217
+ this.showModalAndDelete(badges.map((a) => a.id))
218
+ .pipe(
219
+ switchMap((response) => {
220
+ if (response.result === DeletionResult.DELETED) {
221
+ return [true]
222
+ } else {
223
+ return this.showModalAndDelete(
224
+ badges.map((a) => a.id),
225
+ response.message || '',
226
+ ).pipe(map((r) => r.result === DeletionResult.DELETED))
227
+ }
228
+ }),
229
+ )
230
+ .subscribe(
231
+ () => {
232
+ this.notificationService.success(_('common.notify-delete-success'), {
233
+ entity: 'Badges',
234
+ })
235
+ this.refresh()
236
+ this.selectionManager.clearSelection()
237
+ },
238
+ () => {
239
+ this.notificationService.error(_('common.notify-delete-error'), {
240
+ entity: 'Badges',
241
+ })
242
+ },
243
+ )
244
+ }
245
+
246
+ onBadgeUpdated() {
247
+ this.refresh()
248
+ }
249
+
250
+ private showModalAndDelete(badgeIds: string[], message?: string) {
251
+ return this.modalService
252
+ .dialog({
253
+ title: _('badge-plugin.confirm-delete-badges'),
254
+ translationVars: {
255
+ count: badgeIds.length,
256
+ },
257
+ body: message,
258
+ buttons: [
259
+ { type: 'secondary', label: _('common.cancel') },
260
+ { type: 'danger', label: _('common.delete'), returnValue: true },
261
+ ],
262
+ })
263
+ .pipe(
264
+ switchMap((res) =>
265
+ res
266
+ ? this.dataService.mutate(deleteBadgeDocument, {
267
+ ids: badgeIds,
268
+ })
269
+ : EMPTY,
270
+ ),
271
+ map((res) => res.deleteBadge),
272
+ )
273
+ }
274
+ }
@@ -0,0 +1,2 @@
1
+ export declare class BadgesNavModule {
2
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BadgesNavModule = void 0;
10
+ const core_1 = require("@angular/core");
11
+ const core_2 = require("@vendure/admin-ui/core");
12
+ let BadgesNavModule = class BadgesNavModule {
13
+ };
14
+ BadgesNavModule = __decorate([
15
+ (0, core_1.NgModule)({
16
+ imports: [core_2.SharedModule],
17
+ providers: [
18
+ (0, core_2.addNavMenuItem)({
19
+ id: 'badges',
20
+ label: 'Badges',
21
+ routerLink: ['/extensions/badges'],
22
+ icon: 'star',
23
+ }, 'catalog'),
24
+ ],
25
+ })
26
+ ], BadgesNavModule);
27
+ exports.BadgesNavModule = BadgesNavModule;
@@ -0,0 +1,18 @@
1
+ import { NgModule } from '@angular/core'
2
+ import { addNavMenuItem, SharedModule } from '@vendure/admin-ui/core'
3
+
4
+ @NgModule({
5
+ imports: [SharedModule],
6
+ providers: [
7
+ addNavMenuItem(
8
+ {
9
+ id: 'badges',
10
+ label: 'Badges',
11
+ routerLink: ['/extensions/badges'],
12
+ icon: 'star',
13
+ },
14
+ 'catalog',
15
+ ),
16
+ ],
17
+ })
18
+ export class BadgesNavModule {}
@@ -0,0 +1,2 @@
1
+ export declare class BadgeModule {
2
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BadgeModule = void 0;
10
+ const core_1 = require("@angular/core");
11
+ const router_1 = require("@angular/router");
12
+ const core_2 = require("@vendure/admin-ui/core");
13
+ const badge_list_component_1 = require("./badge-list.component");
14
+ const update_badge_component_1 = require("./update-badge.component");
15
+ let BadgeModule = class BadgeModule {
16
+ };
17
+ BadgeModule = __decorate([
18
+ (0, core_1.NgModule)({
19
+ imports: [
20
+ core_2.SharedModule,
21
+ router_1.RouterModule.forChild([
22
+ {
23
+ path: '',
24
+ pathMatch: 'full',
25
+ component: badge_list_component_1.BadgeListComponent,
26
+ data: { breadcrumb: 'Badges' },
27
+ },
28
+ ]),
29
+ ],
30
+ providers: [],
31
+ declarations: [badge_list_component_1.BadgeListComponent, update_badge_component_1.UpdateBadgeComponent],
32
+ })
33
+ ], BadgeModule);
34
+ exports.BadgeModule = BadgeModule;
@@ -0,0 +1,22 @@
1
+ import { NgModule } from '@angular/core'
2
+ import { RouterModule } from '@angular/router'
3
+ import { SharedModule } from '@vendure/admin-ui/core'
4
+ import { BadgeListComponent } from './badge-list.component'
5
+ import { UpdateBadgeComponent } from './update-badge.component'
6
+
7
+ @NgModule({
8
+ imports: [
9
+ SharedModule,
10
+ RouterModule.forChild([
11
+ {
12
+ path: '',
13
+ pathMatch: 'full',
14
+ component: BadgeListComponent,
15
+ data: { breadcrumb: 'Badges' },
16
+ },
17
+ ]),
18
+ ],
19
+ providers: [],
20
+ declarations: [BadgeListComponent, UpdateBadgeComponent],
21
+ })
22
+ export class BadgeModule {}