@vendure/admin-ui 2.0.0-next.11 → 2.0.0-next.12
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/catalog/components/generate-product-variants/generate-product-variants.component.d.ts +3 -3
- package/catalog/components/option-value-input/option-value-input.component.d.ts +21 -9
- package/catalog/components/product-variants-editor/product-variants-editor.component.d.ts +10 -3
- package/core/common/generated-types.d.ts +242 -127
- package/core/common/utilities/configurable-operation-utils.d.ts +4 -2
- package/core/common/version.d.ts +1 -1
- package/core/data/definitions/order-definitions.d.ts +2 -0
- package/core/data/definitions/product-definitions.d.ts +1 -0
- package/core/data/providers/order-data.service.d.ts +1 -0
- package/core/data/providers/product-data.service.d.ts +1 -0
- package/esm2020/catalog/components/generate-product-variants/generate-product-variants.component.mjs +12 -4
- package/esm2020/catalog/components/option-value-input/option-value-input.component.mjs +65 -11
- package/esm2020/catalog/components/product-variants-editor/product-variants-editor.component.mjs +107 -12
- package/esm2020/core/common/generated-types.mjs +2 -1
- package/esm2020/core/common/introspection-result.mjs +191 -255
- package/esm2020/core/common/utilities/configurable-operation-utils.mjs +11 -8
- package/esm2020/core/common/version.mjs +2 -2
- package/esm2020/core/data/definitions/order-definitions.mjs +39 -25
- package/esm2020/core/data/definitions/product-definitions.mjs +743 -735
- package/esm2020/core/data/providers/order-data.service.mjs +7 -2
- package/esm2020/core/data/providers/product-data.service.mjs +5 -2
- package/esm2020/order/components/fulfill-order-dialog/fulfill-order-dialog.component.mjs +6 -2
- package/esm2020/order/components/fulfillment-detail/fulfillment-detail.component.mjs +8 -17
- package/esm2020/order/components/line-fulfillment/line-fulfillment.component.mjs +7 -21
- package/esm2020/order/components/order-detail/order-detail.component.mjs +48 -20
- package/esm2020/order/components/order-payment-card/order-payment-card.component.mjs +2 -2
- package/fesm2015/vendure-admin-ui-catalog.mjs +186 -22
- package/fesm2015/vendure-admin-ui-catalog.mjs.map +1 -1
- package/fesm2015/vendure-admin-ui-core.mjs +937 -967
- package/fesm2015/vendure-admin-ui-core.mjs.map +1 -1
- package/fesm2015/vendure-admin-ui-order.mjs +68 -58
- package/fesm2015/vendure-admin-ui-order.mjs.map +1 -1
- package/fesm2020/vendure-admin-ui-catalog.mjs +179 -22
- package/fesm2020/vendure-admin-ui-catalog.mjs.map +1 -1
- package/fesm2020/vendure-admin-ui-core.mjs +937 -967
- package/fesm2020/vendure-admin-ui-core.mjs.map +1 -1
- package/fesm2020/vendure-admin-ui-order.mjs +66 -57
- package/fesm2020/vendure-admin-ui-order.mjs.map +1 -1
- package/package.json +2 -2
- package/static/i18n-messages/cs.json +2 -1
- package/static/i18n-messages/de.json +2 -1
- package/static/i18n-messages/en.json +3 -1
- package/static/i18n-messages/es.json +2 -1
- package/static/i18n-messages/fr.json +2 -1
- package/static/i18n-messages/it.json +2 -1
- package/static/i18n-messages/pl.json +2 -1
- package/static/i18n-messages/pt_BR.json +2 -1
- package/static/i18n-messages/pt_PT.json +2 -1
- package/static/i18n-messages/ru.json +2 -1
- package/static/i18n-messages/uk.json +2 -1
- package/static/i18n-messages/zh_Hans.json +2 -1
- package/static/i18n-messages/zh_Hant.json +2 -1
- package/static/styles/global/_utilities.scss +1 -0
- package/static/theme.min.css +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, ChangeDetectionStrategy, EventEmitter, Input, HostBinding, Output, TemplateRef, ContentChild, ViewChild, Injectable, SkipSelf, Optional, forwardRef, NgModule } from '@angular/core';
|
|
2
|
+
import { Component, ChangeDetectionStrategy, EventEmitter, Input, HostBinding, Output, TemplateRef, ContentChild, ViewChild, Injectable, SkipSelf, Optional, forwardRef, ElementRef, ViewChildren, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/router';
|
|
4
4
|
import { RouterModule } from '@angular/router';
|
|
5
5
|
import * as i1$1 from '@vendure/admin-ui/core';
|
|
6
6
|
import { BaseDetailComponent, BaseListComponent, SortOrder, LogicalOperator, DeletionResult, AssetPickerDialogComponent, AssetPreviewDialogComponent, Permission, unicodePatternValidator, findTranslation, getConfigArgValue, createUpdatedTranslatable, encodeConfigArgValue, FacetValueSelectorComponent, GlobalFlag, flattenFacetValues, JobState, getDefaultUiLanguage, BaseEntityResolver, AssetType, createResolveData, CanDeactivateDetailGuard, detailBreadcrumb, SharedModule } from '@vendure/admin-ui/core';
|
|
7
7
|
import { marker } from '@biesbjerg/ngx-translate-extract-marker';
|
|
8
|
-
import { map, debounceTime, takeUntil, finalize, switchMap, startWith, distinctUntilChanged, tap, filter, catchError, take, mergeMap, shareReplay, mapTo, skipUntil, skip, withLatestFrom, delay } from 'rxjs/operators';
|
|
8
|
+
import { map, debounceTime, takeUntil, finalize, switchMap, startWith, distinctUntilChanged, tap, filter, catchError, take, mergeMap, shareReplay, mapTo, skipUntil, skip, withLatestFrom, delay, defaultIfEmpty } from 'rxjs/operators';
|
|
9
9
|
import * as i4 from '@angular/forms';
|
|
10
10
|
import { FormGroup, FormControl, Validators, NG_VALUE_ACCESSOR, FormArray } from '@angular/forms';
|
|
11
11
|
import * as i5 from '@angular/common';
|
|
@@ -1774,10 +1774,18 @@ class OptionValueInputComponent {
|
|
|
1774
1774
|
constructor(changeDetector) {
|
|
1775
1775
|
this.changeDetector = changeDetector;
|
|
1776
1776
|
this.groupName = '';
|
|
1777
|
+
this.add = new EventEmitter();
|
|
1778
|
+
this.remove = new EventEmitter();
|
|
1779
|
+
this.edit = new EventEmitter();
|
|
1777
1780
|
this.disabled = false;
|
|
1778
1781
|
this.input = '';
|
|
1779
1782
|
this.isFocussed = false;
|
|
1780
1783
|
this.lastSelected = false;
|
|
1784
|
+
this.editingIndex = -1;
|
|
1785
|
+
}
|
|
1786
|
+
get optionValues() {
|
|
1787
|
+
var _a, _b;
|
|
1788
|
+
return (_b = (_a = this.formValue) !== null && _a !== void 0 ? _a : this.options) !== null && _b !== void 0 ? _b : [];
|
|
1781
1789
|
}
|
|
1782
1790
|
registerOnChange(fn) {
|
|
1783
1791
|
this.onChangeFn = fn;
|
|
@@ -1790,15 +1798,42 @@ class OptionValueInputComponent {
|
|
|
1790
1798
|
this.changeDetector.markForCheck();
|
|
1791
1799
|
}
|
|
1792
1800
|
writeValue(obj) {
|
|
1793
|
-
this.
|
|
1801
|
+
this.formValue = obj || [];
|
|
1794
1802
|
}
|
|
1795
1803
|
focus() {
|
|
1796
1804
|
this.textArea.nativeElement.focus();
|
|
1797
1805
|
}
|
|
1806
|
+
editName(index, event) {
|
|
1807
|
+
var _a;
|
|
1808
|
+
const optionValue = this.optionValues[index];
|
|
1809
|
+
if (!optionValue.locked && !optionValue.id) {
|
|
1810
|
+
event.cancelBubble = true;
|
|
1811
|
+
this.editingIndex = index;
|
|
1812
|
+
const input = (_a = this.nameInputs.get(index)) === null || _a === void 0 ? void 0 : _a.nativeElement;
|
|
1813
|
+
setTimeout(() => input === null || input === void 0 ? void 0 : input.focus());
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
updateOption(index, event) {
|
|
1817
|
+
const optionValue = this.optionValues[index];
|
|
1818
|
+
const newName = event.target.value;
|
|
1819
|
+
if (optionValue) {
|
|
1820
|
+
if (newName) {
|
|
1821
|
+
optionValue.name = newName;
|
|
1822
|
+
this.edit.emit({ index, option: optionValue });
|
|
1823
|
+
}
|
|
1824
|
+
this.editingIndex = -1;
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1798
1827
|
removeOption(option) {
|
|
1828
|
+
var _a;
|
|
1799
1829
|
if (!option.locked) {
|
|
1800
|
-
|
|
1801
|
-
|
|
1830
|
+
if (this.formValue) {
|
|
1831
|
+
this.formValue = (_a = this.formValue) === null || _a === void 0 ? void 0 : _a.filter(o => o.name !== option.name);
|
|
1832
|
+
this.onChangeFn(this.formValue);
|
|
1833
|
+
}
|
|
1834
|
+
else {
|
|
1835
|
+
this.remove.emit(option);
|
|
1836
|
+
}
|
|
1802
1837
|
}
|
|
1803
1838
|
}
|
|
1804
1839
|
handleKey(event) {
|
|
@@ -1826,9 +1861,17 @@ class OptionValueInputComponent {
|
|
|
1826
1861
|
this.addOptionValue();
|
|
1827
1862
|
}
|
|
1828
1863
|
addOptionValue() {
|
|
1829
|
-
|
|
1864
|
+
const options = this.parseInputIntoOptions(this.input);
|
|
1865
|
+
if (!this.formValue && this.options) {
|
|
1866
|
+
for (const option of options) {
|
|
1867
|
+
this.add.emit(option);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
else {
|
|
1871
|
+
this.formValue = unique([...this.formValue, ...options]);
|
|
1872
|
+
this.onChangeFn(this.formValue);
|
|
1873
|
+
}
|
|
1830
1874
|
this.input = '';
|
|
1831
|
-
this.onChangeFn(this.options);
|
|
1832
1875
|
}
|
|
1833
1876
|
parseInputIntoOptions(input) {
|
|
1834
1877
|
return input
|
|
@@ -1838,21 +1881,35 @@ class OptionValueInputComponent {
|
|
|
1838
1881
|
.map(s => ({ name: s, locked: false }));
|
|
1839
1882
|
}
|
|
1840
1883
|
removeLastOption() {
|
|
1841
|
-
if (
|
|
1842
|
-
|
|
1884
|
+
if (this.optionValues.length) {
|
|
1885
|
+
const option = this.optionValues[this.optionValues.length - 1];
|
|
1886
|
+
this.removeOption(option);
|
|
1843
1887
|
}
|
|
1844
1888
|
}
|
|
1845
1889
|
}
|
|
1846
1890
|
OptionValueInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: OptionValueInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1847
|
-
OptionValueInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: OptionValueInputComponent, selector: "vdr-option-value-input", inputs: { groupName: "groupName" }, providers: [OPTION_VALUE_INPUT_VALUE_ACCESSOR], viewQueries: [{ propertyName: "textArea", first: true, predicate: ["textArea"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"input-wrapper\" [class.focus]=\"isFocussed\" (click)=\"textArea.focus()\">\r\n <div class=\"chips\" *ngIf=\"0 <
|
|
1891
|
+
OptionValueInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: OptionValueInputComponent, selector: "vdr-option-value-input", inputs: { groupName: "groupName", options: "options", disabled: "disabled" }, outputs: { add: "add", remove: "remove", edit: "edit" }, providers: [OPTION_VALUE_INPUT_VALUE_ACCESSOR], viewQueries: [{ propertyName: "textArea", first: true, predicate: ["textArea"], descendants: true, static: true }, { propertyName: "nameInputs", predicate: ["editNameInput"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"input-wrapper\" [class.focus]=\"isFocussed\" (click)=\"textArea.focus()\">\r\n <div class=\"chips\" *ngIf=\"0 < optionValues.length\">\r\n <vdr-chip\r\n *ngFor=\"let option of optionValues; last as isLast; index as i\"\r\n [icon]=\"option.locked ? 'lock' : 'times'\"\r\n [class.selected]=\"isLast && lastSelected\"\r\n [class.locked]=\"option.locked\"\r\n [colorFrom]=\"groupName\"\r\n (iconClick)=\"removeOption(option)\"\r\n >\r\n <span [hidden]=\"editingIndex !== i\">\r\n <input\r\n #editNameInput\r\n type=\"text\"\r\n [ngModel]=\"option.name\"\r\n (blur)=\"updateOption(i, $event)\"\r\n (click)=\"$event.cancelBubble = true\"\r\n />\r\n </span>\r\n <span\r\n class=\"option-name\"\r\n [class.editable]=\"!option.locked && !option.id\"\r\n (click)=\"editName(i, $event)\" [hidden]=\"editingIndex === i\">{{ option.name }}</span>\r\n </vdr-chip>\r\n </div>\r\n <textarea\r\n #textArea\r\n (keyup)=\"handleKey($event)\"\r\n (focus)=\"isFocussed = true\"\r\n (blur)=\"handleBlur()\"\r\n [(ngModel)]=\"input\"\r\n [disabled]=\"disabled\"\r\n ></textarea>\r\n</div>\r\n", styles: [".input-wrapper{background-color:#fff;border-radius:3px!important;border:1px solid var(--color-grey-300)!important;cursor:text}.input-wrapper.focus{border-color:var(--color-primary-500)!important;box-shadow:0 0 1px 1px var(--color-primary-100)}.input-wrapper .chips{padding:5px}.input-wrapper textarea{border:none;width:100%;height:24px;margin-top:3px;padding:0 6px}.input-wrapper textarea:focus{outline:none}.input-wrapper textarea:disabled{background-color:var(--color-component-bg-100)}vdr-chip ::ng-deep .wrapper{margin:0 3px}vdr-chip.locked{opacity:.8}vdr-chip.selected ::ng-deep .wrapper{border-color:var(--color-warning-500)!important;box-shadow:0 0 1px 1px var(--color-warning-400);opacity:.6}vdr-chip .option-name.editable:hover{outline:1px solid var(--color-component-bg-300);outline-offset:1px;border-radius:1px}vdr-chip input{padding:0!important;margin-top:-2px;margin-bottom:-2px}\n"], components: [{ type: i1$1.ChipComponent, selector: "vdr-chip", inputs: ["icon", "invert", "colorFrom", "colorType"], outputs: ["iconClick"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.FormFieldControlDirective, selector: "input, textarea, select" }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
1848
1892
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: OptionValueInputComponent, decorators: [{
|
|
1849
1893
|
type: Component,
|
|
1850
|
-
args: [{ selector: 'vdr-option-value-input', changeDetection: ChangeDetectionStrategy.Default, providers: [OPTION_VALUE_INPUT_VALUE_ACCESSOR], template: "<div class=\"input-wrapper\" [class.focus]=\"isFocussed\" (click)=\"textArea.focus()\">\r\n <div class=\"chips\" *ngIf=\"0 <
|
|
1894
|
+
args: [{ selector: 'vdr-option-value-input', changeDetection: ChangeDetectionStrategy.Default, providers: [OPTION_VALUE_INPUT_VALUE_ACCESSOR], template: "<div class=\"input-wrapper\" [class.focus]=\"isFocussed\" (click)=\"textArea.focus()\">\r\n <div class=\"chips\" *ngIf=\"0 < optionValues.length\">\r\n <vdr-chip\r\n *ngFor=\"let option of optionValues; last as isLast; index as i\"\r\n [icon]=\"option.locked ? 'lock' : 'times'\"\r\n [class.selected]=\"isLast && lastSelected\"\r\n [class.locked]=\"option.locked\"\r\n [colorFrom]=\"groupName\"\r\n (iconClick)=\"removeOption(option)\"\r\n >\r\n <span [hidden]=\"editingIndex !== i\">\r\n <input\r\n #editNameInput\r\n type=\"text\"\r\n [ngModel]=\"option.name\"\r\n (blur)=\"updateOption(i, $event)\"\r\n (click)=\"$event.cancelBubble = true\"\r\n />\r\n </span>\r\n <span\r\n class=\"option-name\"\r\n [class.editable]=\"!option.locked && !option.id\"\r\n (click)=\"editName(i, $event)\" [hidden]=\"editingIndex === i\">{{ option.name }}</span>\r\n </vdr-chip>\r\n </div>\r\n <textarea\r\n #textArea\r\n (keyup)=\"handleKey($event)\"\r\n (focus)=\"isFocussed = true\"\r\n (blur)=\"handleBlur()\"\r\n [(ngModel)]=\"input\"\r\n [disabled]=\"disabled\"\r\n ></textarea>\r\n</div>\r\n", styles: [".input-wrapper{background-color:#fff;border-radius:3px!important;border:1px solid var(--color-grey-300)!important;cursor:text}.input-wrapper.focus{border-color:var(--color-primary-500)!important;box-shadow:0 0 1px 1px var(--color-primary-100)}.input-wrapper .chips{padding:5px}.input-wrapper textarea{border:none;width:100%;height:24px;margin-top:3px;padding:0 6px}.input-wrapper textarea:focus{outline:none}.input-wrapper textarea:disabled{background-color:var(--color-component-bg-100)}vdr-chip ::ng-deep .wrapper{margin:0 3px}vdr-chip.locked{opacity:.8}vdr-chip.selected ::ng-deep .wrapper{border-color:var(--color-warning-500)!important;box-shadow:0 0 1px 1px var(--color-warning-400);opacity:.6}vdr-chip .option-name.editable:hover{outline:1px solid var(--color-component-bg-300);outline-offset:1px;border-radius:1px}vdr-chip input{padding:0!important;margin-top:-2px;margin-bottom:-2px}\n"] }]
|
|
1851
1895
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { groupName: [{
|
|
1852
1896
|
type: Input
|
|
1853
1897
|
}], textArea: [{
|
|
1854
1898
|
type: ViewChild,
|
|
1855
1899
|
args: ['textArea', { static: true }]
|
|
1900
|
+
}], nameInputs: [{
|
|
1901
|
+
type: ViewChildren,
|
|
1902
|
+
args: ['editNameInput', { read: ElementRef }]
|
|
1903
|
+
}], options: [{
|
|
1904
|
+
type: Input
|
|
1905
|
+
}], add: [{
|
|
1906
|
+
type: Output
|
|
1907
|
+
}], remove: [{
|
|
1908
|
+
type: Output
|
|
1909
|
+
}], edit: [{
|
|
1910
|
+
type: Output
|
|
1911
|
+
}], disabled: [{
|
|
1912
|
+
type: Input
|
|
1856
1913
|
}] } });
|
|
1857
1914
|
|
|
1858
1915
|
const DEFAULT_VARIANT_CODE = '__DEFAULT_VARIANT__';
|
|
@@ -1871,6 +1928,12 @@ class GenerateProductVariantsComponent {
|
|
|
1871
1928
|
}
|
|
1872
1929
|
addOption() {
|
|
1873
1930
|
this.optionGroups.push({ name: '', values: [] });
|
|
1931
|
+
const index = this.optionGroups.length - 1;
|
|
1932
|
+
setTimeout(() => {
|
|
1933
|
+
var _a;
|
|
1934
|
+
const input = (_a = this.groupNameInputs.get(index)) === null || _a === void 0 ? void 0 : _a.nativeElement;
|
|
1935
|
+
input === null || input === void 0 ? void 0 : input.focus();
|
|
1936
|
+
});
|
|
1874
1937
|
}
|
|
1875
1938
|
removeOption(name) {
|
|
1876
1939
|
this.optionGroups = this.optionGroups.filter(g => g.name !== name);
|
|
@@ -1917,12 +1980,15 @@ class GenerateProductVariantsComponent {
|
|
|
1917
1980
|
}
|
|
1918
1981
|
}
|
|
1919
1982
|
GenerateProductVariantsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: GenerateProductVariantsComponent, deps: [{ token: i1$1.DataService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1920
|
-
GenerateProductVariantsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: GenerateProductVariantsComponent, selector: "vdr-generate-product-variants", outputs: { variantsChange: "variantsChange" }, ngImport: i0, template: "<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input\r\n placeholder=\"e.g. Size\"\r\n clrInput\r\n [(ngModel)]=\"group.name\"\r\n name=\"name\"\r\n required\r\n (keydown.enter)=\"handleEnter($event, optionValueInputComponent)\"\r\n />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [(ngModel)]=\"group.values\"\r\n (ngModelChange)=\"generateVariants()\"\r\n [groupName]=\"group.name\"\r\n [disabled]=\"group.name === ''\"\r\n ></vdr-option-value-input>\r\n </div>\r\n <div class=\"remove-group\">\r\n <button\r\n class=\"btn btn-icon btn-warning-outline\"\r\n [title]=\"'catalog.remove-option' | translate\"\r\n (click)=\"removeOption(group.name)\"\r\n >\r\n <clr-icon shape=\"trash\"></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<button class=\"btn btn-primary-outline btn-sm\" (click)=\"addOption()\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-option' | translate }}\r\n</button>\r\n\r\n<div class=\"variants-preview\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"1 < variants.length\">{{ 'common.create' | translate }}</th>\r\n <th *ngIf=\"1 < variants.length\">{{ 'catalog.variant' | translate }}</th>\r\n <th>{{ 'catalog.sku' | translate }}</th>\r\n <th>{{ 'catalog.price' | translate }}</th>\r\n <th>{{ 'catalog.stock-on-hand' | translate }}</th>\r\n </tr>\r\n </thead>\r\n <tr\r\n *ngFor=\"let variant of variants; trackBy: trackByFn\"\r\n [class.disabled]=\"!variantFormValues[variant.id].enabled\"\r\n >\r\n <td *ngIf=\"1 < variants.length\">\r\n <input\r\n type=\"checkbox\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].enabled\"\r\n clrCheckbox\r\n />\r\n </td>\r\n <td *ngIf=\"1 < variants.length\">\r\n {{ variant.values.join(' ') }}\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"text\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].sku\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <vdr-currency-input\r\n clrInput\r\n [(ngModel)]=\"variantFormValues[variant.id].price\"\r\n (ngModelChange)=\"onFormChange()\"\r\n [currencyCode]=\"currencyCode\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [(ngModel)]=\"variantFormValues[variant.id].stock\"\r\n (change)=\"onFormChange()\"\r\n min=\"0\"\r\n step=\"1\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n", styles: [":host{display:block;margin-bottom:120px}.option-groups{display:flex}.values{flex:1;margin:0 6px}.remove-group{padding-top:18px}.variants-preview tr.disabled td{background-color:var(--color-component-bg-100);color:var(--color-grey-400)}\n"], components: [{ type: OptionValueInputComponent, selector: "vdr-option-value-input", inputs: ["groupName"] }, { type: i2.ClrInputContainer, selector: "clr-input-container" }, { type: i1$1.CurrencyInputComponent, selector: "vdr-currency-input", inputs: ["disabled", "readonly", "value", "currencyCode"], outputs: ["valueChange"] }], directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.ClrLabel, selector: "label", inputs: ["for"] }, { type: i1$1.FormFieldControlDirective, selector: "input, textarea, select" }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.ClrInput, selector: "[clrInput]" }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i2.ClrIconCustomTag, selector: "clr-icon" }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ClrDatagridItemsTrackBy, selector: "[ngForTrackBy]", inputs: ["ngForTrackBy"] }, { type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i2.ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { type: i4.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }], pipes: { "translate": i5$1.TranslatePipe } });
|
|
1983
|
+
GenerateProductVariantsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: GenerateProductVariantsComponent, selector: "vdr-generate-product-variants", outputs: { variantsChange: "variantsChange" }, viewQueries: [{ propertyName: "groupNameInputs", predicate: ["optionGroupName"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input\r\n #optionGroupName\r\n placeholder=\"e.g. Size\"\r\n clrInput\r\n [(ngModel)]=\"group.name\"\r\n name=\"name\"\r\n required\r\n (keydown.enter)=\"handleEnter($event, optionValueInputComponent)\"\r\n />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [(ngModel)]=\"group.values\"\r\n (ngModelChange)=\"generateVariants()\"\r\n (edit)=\"generateVariants()\"\r\n [groupName]=\"group.name\"\r\n [disabled]=\"group.name === ''\"\r\n ></vdr-option-value-input>\r\n </div>\r\n <div class=\"remove-group\">\r\n <button\r\n class=\"btn btn-icon btn-warning-outline\"\r\n [title]=\"'catalog.remove-option' | translate\"\r\n (click)=\"removeOption(group.name)\"\r\n >\r\n <clr-icon shape=\"trash\"></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<button class=\"btn btn-primary-outline btn-sm\" (click)=\"addOption()\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-option' | translate }}\r\n</button>\r\n\r\n<div class=\"variants-preview\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"1 < variants.length\">{{ 'common.create' | translate }}</th>\r\n <th *ngIf=\"1 < variants.length\">{{ 'catalog.variant' | translate }}</th>\r\n <th>{{ 'catalog.sku' | translate }}</th>\r\n <th>{{ 'catalog.price' | translate }}</th>\r\n <th>{{ 'catalog.stock-on-hand' | translate }}</th>\r\n </tr>\r\n </thead>\r\n <tr\r\n *ngFor=\"let variant of variants; trackBy: trackByFn\"\r\n [class.disabled]=\"!variantFormValues[variant.id].enabled\"\r\n >\r\n <td *ngIf=\"1 < variants.length\">\r\n <input\r\n type=\"checkbox\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].enabled\"\r\n clrCheckbox\r\n />\r\n </td>\r\n <td *ngIf=\"1 < variants.length\">\r\n {{ variant.values.join(' ') }}\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"text\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].sku\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <vdr-currency-input\r\n clrInput\r\n [(ngModel)]=\"variantFormValues[variant.id].price\"\r\n (ngModelChange)=\"onFormChange()\"\r\n [currencyCode]=\"currencyCode\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [(ngModel)]=\"variantFormValues[variant.id].stock\"\r\n (change)=\"onFormChange()\"\r\n min=\"0\"\r\n step=\"1\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n", styles: [":host{display:block;margin-bottom:120px}.option-groups{display:flex}.values{flex:1;margin:0 6px}.remove-group{padding-top:18px}.variants-preview tr.disabled td{background-color:var(--color-component-bg-100);color:var(--color-grey-400)}\n"], components: [{ type: OptionValueInputComponent, selector: "vdr-option-value-input", inputs: ["groupName", "options", "disabled"], outputs: ["add", "remove", "edit"] }, { type: i2.ClrInputContainer, selector: "clr-input-container" }, { type: i1$1.CurrencyInputComponent, selector: "vdr-currency-input", inputs: ["disabled", "readonly", "value", "currencyCode"], outputs: ["valueChange"] }], directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.ClrLabel, selector: "label", inputs: ["for"] }, { type: i1$1.FormFieldControlDirective, selector: "input, textarea, select" }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.ClrInput, selector: "[clrInput]" }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i2.ClrIconCustomTag, selector: "clr-icon" }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ClrDatagridItemsTrackBy, selector: "[ngForTrackBy]", inputs: ["ngForTrackBy"] }, { type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i2.ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { type: i4.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }], pipes: { "translate": i5$1.TranslatePipe } });
|
|
1921
1984
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: GenerateProductVariantsComponent, decorators: [{
|
|
1922
1985
|
type: Component,
|
|
1923
|
-
args: [{ selector: 'vdr-generate-product-variants', template: "<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input\r\n placeholder=\"e.g. Size\"\r\n clrInput\r\n [(ngModel)]=\"group.name\"\r\n name=\"name\"\r\n required\r\n (keydown.enter)=\"handleEnter($event, optionValueInputComponent)\"\r\n />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [(ngModel)]=\"group.values\"\r\n (ngModelChange)=\"generateVariants()\"\r\n [groupName]=\"group.name\"\r\n [disabled]=\"group.name === ''\"\r\n ></vdr-option-value-input>\r\n </div>\r\n <div class=\"remove-group\">\r\n <button\r\n class=\"btn btn-icon btn-warning-outline\"\r\n [title]=\"'catalog.remove-option' | translate\"\r\n (click)=\"removeOption(group.name)\"\r\n >\r\n <clr-icon shape=\"trash\"></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<button class=\"btn btn-primary-outline btn-sm\" (click)=\"addOption()\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-option' | translate }}\r\n</button>\r\n\r\n<div class=\"variants-preview\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"1 < variants.length\">{{ 'common.create' | translate }}</th>\r\n <th *ngIf=\"1 < variants.length\">{{ 'catalog.variant' | translate }}</th>\r\n <th>{{ 'catalog.sku' | translate }}</th>\r\n <th>{{ 'catalog.price' | translate }}</th>\r\n <th>{{ 'catalog.stock-on-hand' | translate }}</th>\r\n </tr>\r\n </thead>\r\n <tr\r\n *ngFor=\"let variant of variants; trackBy: trackByFn\"\r\n [class.disabled]=\"!variantFormValues[variant.id].enabled\"\r\n >\r\n <td *ngIf=\"1 < variants.length\">\r\n <input\r\n type=\"checkbox\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].enabled\"\r\n clrCheckbox\r\n />\r\n </td>\r\n <td *ngIf=\"1 < variants.length\">\r\n {{ variant.values.join(' ') }}\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"text\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].sku\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <vdr-currency-input\r\n clrInput\r\n [(ngModel)]=\"variantFormValues[variant.id].price\"\r\n (ngModelChange)=\"onFormChange()\"\r\n [currencyCode]=\"currencyCode\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [(ngModel)]=\"variantFormValues[variant.id].stock\"\r\n (change)=\"onFormChange()\"\r\n min=\"0\"\r\n step=\"1\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n", styles: [":host{display:block;margin-bottom:120px}.option-groups{display:flex}.values{flex:1;margin:0 6px}.remove-group{padding-top:18px}.variants-preview tr.disabled td{background-color:var(--color-component-bg-100);color:var(--color-grey-400)}\n"] }]
|
|
1986
|
+
args: [{ selector: 'vdr-generate-product-variants', template: "<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input\r\n #optionGroupName\r\n placeholder=\"e.g. Size\"\r\n clrInput\r\n [(ngModel)]=\"group.name\"\r\n name=\"name\"\r\n required\r\n (keydown.enter)=\"handleEnter($event, optionValueInputComponent)\"\r\n />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [(ngModel)]=\"group.values\"\r\n (ngModelChange)=\"generateVariants()\"\r\n (edit)=\"generateVariants()\"\r\n [groupName]=\"group.name\"\r\n [disabled]=\"group.name === ''\"\r\n ></vdr-option-value-input>\r\n </div>\r\n <div class=\"remove-group\">\r\n <button\r\n class=\"btn btn-icon btn-warning-outline\"\r\n [title]=\"'catalog.remove-option' | translate\"\r\n (click)=\"removeOption(group.name)\"\r\n >\r\n <clr-icon shape=\"trash\"></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<button class=\"btn btn-primary-outline btn-sm\" (click)=\"addOption()\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-option' | translate }}\r\n</button>\r\n\r\n<div class=\"variants-preview\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"1 < variants.length\">{{ 'common.create' | translate }}</th>\r\n <th *ngIf=\"1 < variants.length\">{{ 'catalog.variant' | translate }}</th>\r\n <th>{{ 'catalog.sku' | translate }}</th>\r\n <th>{{ 'catalog.price' | translate }}</th>\r\n <th>{{ 'catalog.stock-on-hand' | translate }}</th>\r\n </tr>\r\n </thead>\r\n <tr\r\n *ngFor=\"let variant of variants; trackBy: trackByFn\"\r\n [class.disabled]=\"!variantFormValues[variant.id].enabled\"\r\n >\r\n <td *ngIf=\"1 < variants.length\">\r\n <input\r\n type=\"checkbox\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].enabled\"\r\n clrCheckbox\r\n />\r\n </td>\r\n <td *ngIf=\"1 < variants.length\">\r\n {{ variant.values.join(' ') }}\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"text\"\r\n (change)=\"onFormChange()\"\r\n [(ngModel)]=\"variantFormValues[variant.id].sku\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <vdr-currency-input\r\n clrInput\r\n [(ngModel)]=\"variantFormValues[variant.id].price\"\r\n (ngModelChange)=\"onFormChange()\"\r\n [currencyCode]=\"currencyCode\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n </td>\r\n <td>\r\n <clr-input-container>\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [(ngModel)]=\"variantFormValues[variant.id].stock\"\r\n (change)=\"onFormChange()\"\r\n min=\"0\"\r\n step=\"1\"\r\n />\r\n </clr-input-container>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n", styles: [":host{display:block;margin-bottom:120px}.option-groups{display:flex}.values{flex:1;margin:0 6px}.remove-group{padding-top:18px}.variants-preview tr.disabled td{background-color:var(--color-component-bg-100);color:var(--color-grey-400)}\n"] }]
|
|
1924
1987
|
}], ctorParameters: function () { return [{ type: i1$1.DataService }]; }, propDecorators: { variantsChange: [{
|
|
1925
1988
|
type: Output
|
|
1989
|
+
}], groupNameInputs: [{
|
|
1990
|
+
type: ViewChildren,
|
|
1991
|
+
args: ['optionGroupName', { read: ElementRef }]
|
|
1926
1992
|
}] } });
|
|
1927
1993
|
|
|
1928
1994
|
class ProductVariantsTableComponent {
|
|
@@ -3106,6 +3172,7 @@ class ProductVariantsEditorComponent {
|
|
|
3106
3172
|
this.notificationService = notificationService;
|
|
3107
3173
|
this.modalService = modalService;
|
|
3108
3174
|
this.formValueChanged = false;
|
|
3175
|
+
this.optionsChanged = false;
|
|
3109
3176
|
this.generatedVariants = [];
|
|
3110
3177
|
}
|
|
3111
3178
|
ngOnInit() {
|
|
@@ -3131,16 +3198,105 @@ class ProductVariantsEditorComponent {
|
|
|
3131
3198
|
? marker('catalog.default-variant')
|
|
3132
3199
|
: variant.options.map(o => o.name).join(' ');
|
|
3133
3200
|
}
|
|
3134
|
-
|
|
3201
|
+
addOptionGroup() {
|
|
3135
3202
|
this.optionGroups.push({
|
|
3136
3203
|
isNew: true,
|
|
3204
|
+
locked: false,
|
|
3137
3205
|
name: '',
|
|
3138
3206
|
values: [],
|
|
3139
3207
|
});
|
|
3208
|
+
this.optionsChanged = true;
|
|
3209
|
+
}
|
|
3210
|
+
removeOptionGroup(optionGroup) {
|
|
3211
|
+
const id = optionGroup.id;
|
|
3212
|
+
if (optionGroup.isNew) {
|
|
3213
|
+
this.optionGroups = this.optionGroups.filter(og => og !== optionGroup);
|
|
3214
|
+
this.generateVariants();
|
|
3215
|
+
this.optionsChanged = true;
|
|
3216
|
+
}
|
|
3217
|
+
else if (id) {
|
|
3218
|
+
this.modalService
|
|
3219
|
+
.dialog({
|
|
3220
|
+
title: marker('catalog.confirm-delete-product-option-group'),
|
|
3221
|
+
translationVars: { name: optionGroup.name },
|
|
3222
|
+
buttons: [
|
|
3223
|
+
{ type: 'secondary', label: marker('common.cancel') },
|
|
3224
|
+
{ type: 'danger', label: marker('common.delete'), returnValue: true },
|
|
3225
|
+
],
|
|
3226
|
+
})
|
|
3227
|
+
.pipe(switchMap(val => {
|
|
3228
|
+
if (val) {
|
|
3229
|
+
return this.dataService.product.removeOptionGroupFromProduct({
|
|
3230
|
+
optionGroupId: id,
|
|
3231
|
+
productId: this.product.id,
|
|
3232
|
+
});
|
|
3233
|
+
}
|
|
3234
|
+
else {
|
|
3235
|
+
return EMPTY;
|
|
3236
|
+
}
|
|
3237
|
+
}))
|
|
3238
|
+
.subscribe(({ removeOptionGroupFromProduct }) => {
|
|
3239
|
+
var _a;
|
|
3240
|
+
if (removeOptionGroupFromProduct.__typename === 'Product') {
|
|
3241
|
+
this.notificationService.success(marker('common.notify-delete-success'), {
|
|
3242
|
+
entity: 'ProductOptionGroup',
|
|
3243
|
+
});
|
|
3244
|
+
this.initOptionsAndVariants();
|
|
3245
|
+
this.optionsChanged = true;
|
|
3246
|
+
}
|
|
3247
|
+
else if (removeOptionGroupFromProduct.__typename === 'ProductOptionInUseError') {
|
|
3248
|
+
this.notificationService.error((_a = removeOptionGroupFromProduct.message) !== null && _a !== void 0 ? _a : '');
|
|
3249
|
+
}
|
|
3250
|
+
});
|
|
3251
|
+
}
|
|
3140
3252
|
}
|
|
3141
|
-
|
|
3142
|
-
|
|
3253
|
+
addOption(groupId, optionName) {
|
|
3254
|
+
var _a;
|
|
3255
|
+
(_a = this.optionGroups.find(g => g.id === groupId)) === null || _a === void 0 ? void 0 : _a.values.push({ name: optionName, locked: false });
|
|
3143
3256
|
this.generateVariants();
|
|
3257
|
+
this.optionsChanged = true;
|
|
3258
|
+
}
|
|
3259
|
+
removeOption(groupId, { id, name }) {
|
|
3260
|
+
const optionGroup = this.optionGroups.find(g => g.id === groupId);
|
|
3261
|
+
if (optionGroup) {
|
|
3262
|
+
if (!id) {
|
|
3263
|
+
optionGroup.values = optionGroup.values.filter(v => v.name !== name);
|
|
3264
|
+
this.generateVariants();
|
|
3265
|
+
}
|
|
3266
|
+
else {
|
|
3267
|
+
this.modalService
|
|
3268
|
+
.dialog({
|
|
3269
|
+
title: marker('catalog.confirm-delete-product-option'),
|
|
3270
|
+
translationVars: { name },
|
|
3271
|
+
buttons: [
|
|
3272
|
+
{ type: 'secondary', label: marker('common.cancel') },
|
|
3273
|
+
{ type: 'danger', label: marker('common.delete'), returnValue: true },
|
|
3274
|
+
],
|
|
3275
|
+
})
|
|
3276
|
+
.pipe(switchMap(val => {
|
|
3277
|
+
if (val) {
|
|
3278
|
+
return this.dataService.product.deleteProductOption(id);
|
|
3279
|
+
}
|
|
3280
|
+
else {
|
|
3281
|
+
return EMPTY;
|
|
3282
|
+
}
|
|
3283
|
+
}))
|
|
3284
|
+
.subscribe(({ deleteProductOption }) => {
|
|
3285
|
+
var _a;
|
|
3286
|
+
if (deleteProductOption.result === DeletionResult.DELETED) {
|
|
3287
|
+
this.notificationService.success(marker('common.notify-delete-success'), {
|
|
3288
|
+
entity: 'ProductOption',
|
|
3289
|
+
});
|
|
3290
|
+
optionGroup.values = optionGroup.values.filter(v => v.id !== id);
|
|
3291
|
+
this.generateVariants();
|
|
3292
|
+
this.optionsChanged = true;
|
|
3293
|
+
}
|
|
3294
|
+
else {
|
|
3295
|
+
this.notificationService.error((_a = deleteProductOption.message) !== null && _a !== void 0 ? _a : '');
|
|
3296
|
+
}
|
|
3297
|
+
});
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3144
3300
|
}
|
|
3145
3301
|
generateVariants() {
|
|
3146
3302
|
const groups = this.optionGroups.map(g => g.values);
|
|
@@ -3182,10 +3338,11 @@ class ProductVariantsEditorComponent {
|
|
|
3182
3338
|
stock: 0,
|
|
3183
3339
|
};
|
|
3184
3340
|
}
|
|
3185
|
-
deleteVariant(id) {
|
|
3341
|
+
deleteVariant(id, options) {
|
|
3186
3342
|
this.modalService
|
|
3187
3343
|
.dialog({
|
|
3188
3344
|
title: marker('catalog.confirm-delete-product-variant'),
|
|
3345
|
+
translationVars: { name: options.map(o => o.name).join(' ') },
|
|
3189
3346
|
buttons: [
|
|
3190
3347
|
{ type: 'secondary', label: marker('common.cancel') },
|
|
3191
3348
|
{ type: 'danger', label: marker('common.delete'), returnValue: true },
|
|
@@ -3220,12 +3377,14 @@ class ProductVariantsEditorComponent {
|
|
|
3220
3377
|
count: variants.length,
|
|
3221
3378
|
});
|
|
3222
3379
|
this.initOptionsAndVariants();
|
|
3380
|
+
this.optionsChanged = false;
|
|
3223
3381
|
},
|
|
3224
3382
|
});
|
|
3225
3383
|
}
|
|
3226
3384
|
checkUniqueSkus() {
|
|
3227
3385
|
const withDuplicateSkus = this.generatedVariants.filter((variant, index) => {
|
|
3228
|
-
return
|
|
3386
|
+
return (variant.enabled &&
|
|
3387
|
+
this.generatedVariants.find(gv => gv.sku.trim() === variant.sku.trim() && gv !== variant));
|
|
3229
3388
|
});
|
|
3230
3389
|
if (withDuplicateSkus.length) {
|
|
3231
3390
|
return this.modalService
|
|
@@ -3308,7 +3467,7 @@ class ProductVariantsEditorComponent {
|
|
|
3308
3467
|
return forkJoin(groupsIds.map(id => this.dataService.product
|
|
3309
3468
|
.getProductOptionGroup(id)
|
|
3310
3469
|
.mapSingle(data => data.productOptionGroup)
|
|
3311
|
-
.pipe(filter(notNullOrUndefined))));
|
|
3470
|
+
.pipe(filter(notNullOrUndefined)))).pipe(defaultIfEmpty([]));
|
|
3312
3471
|
}
|
|
3313
3472
|
createNewProductVariants(groups) {
|
|
3314
3473
|
const options = groups
|
|
@@ -3356,15 +3515,20 @@ class ProductVariantsEditorComponent {
|
|
|
3356
3515
|
.mapSingle(({ product }) => product)
|
|
3357
3516
|
.subscribe(p => {
|
|
3358
3517
|
this.product = p;
|
|
3518
|
+
const allUsedOptionIds = p.variants.map(v => v.options.map(option => option.id)).flat();
|
|
3519
|
+
const allUsedOptionGroupIds = p.variants
|
|
3520
|
+
.map(v => v.options.map(option => option.groupId))
|
|
3521
|
+
.flat();
|
|
3359
3522
|
this.optionGroups = p.optionGroups.map(og => {
|
|
3360
3523
|
return {
|
|
3361
3524
|
id: og.id,
|
|
3362
3525
|
isNew: false,
|
|
3363
3526
|
name: og.name,
|
|
3527
|
+
locked: allUsedOptionGroupIds.includes(og.id),
|
|
3364
3528
|
values: og.options.map(o => ({
|
|
3365
3529
|
id: o.id,
|
|
3366
3530
|
name: o.name,
|
|
3367
|
-
locked:
|
|
3531
|
+
locked: allUsedOptionIds.includes(o.id),
|
|
3368
3532
|
})),
|
|
3369
3533
|
};
|
|
3370
3534
|
});
|
|
@@ -3385,10 +3549,10 @@ class ProductVariantsEditorComponent {
|
|
|
3385
3549
|
}
|
|
3386
3550
|
}
|
|
3387
3551
|
ProductVariantsEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: ProductVariantsEditorComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1$1.DataService }, { token: ProductDetailService }, { token: i1$1.NotificationService }, { token: i1$1.ModalService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3388
|
-
ProductVariantsEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: ProductVariantsEditorComponent, selector: "vdr-product-variants-editor", ngImport: i0, template: "<vdr-action-bar>\r\n <vdr-ab-right>\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"!formValueChanged || getVariantsToAdd().length === 0\"\r\n >\r\n {{ 'common.add-new-variants' | translate: { count: getVariantsToAdd().length } }}\r\n </button>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input clrInput [(ngModel)]=\"group.name\" name=\"name\" [readonly]=\"!group.isNew\" />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [
|
|
3552
|
+
ProductVariantsEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: ProductVariantsEditorComponent, selector: "vdr-product-variants-editor", ngImport: i0, template: "<vdr-action-bar>\r\n <vdr-ab-right>\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"(!formValueChanged && !optionsChanged) || getVariantsToAdd().length === 0\"\r\n >\r\n {{ 'common.add-new-variants' | translate: { count: getVariantsToAdd().length } }}\r\n </button>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input clrInput [(ngModel)]=\"group.name\" name=\"name\" [readonly]=\"!group.isNew\" />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [options]=\"group.values\"\r\n [groupName]=\"group.name\"\r\n [disabled]=\"group.name === ''\"\r\n (add)=\"addOption(group.id, $event.name)\"\r\n (remove)=\"removeOption(group.id, $event)\"\r\n ></vdr-option-value-input>\r\n </div>\r\n <div>\r\n <button\r\n [disabled]=\"group.locked\"\r\n class=\"btn btn-icon btn-danger-outline mt5\" (click)=\"removeOptionGroup(group)\">\r\n <clr-icon shape=\"trash\"></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<button class=\"btn btn-primary-outline btn-sm\" (click)=\"addOptionGroup()\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-option' | translate }}\r\n</button>\r\n\r\n<div class=\"variants-preview\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>{{ 'catalog.variant' | translate }}</th>\r\n <th>{{ 'catalog.sku' | translate }}</th>\r\n <th>{{ 'catalog.price' | translate }}</th>\r\n <th>{{ 'catalog.stock-on-hand' | translate }}</th>\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tr *ngFor=\"let variant of generatedVariants\" [class.disabled]=\"!variant.enabled || variant.existing\">\r\n <td class=\"left\">\r\n <clr-checkbox-wrapper *ngIf=\"!variant.existing\">\r\n <input\r\n type=\"checkbox\"\r\n [(ngModel)]=\"variant.enabled\"\r\n name=\"enabled\"\r\n clrCheckbox\r\n (ngModelChange)=\"formValueChanged = true\"\r\n />\r\n <label>{{ 'common.create' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n </td>\r\n <td>\r\n {{ getVariantName(variant) | translate }}\r\n </td>\r\n <td>\r\n <div class=\"flex center\">\r\n <clr-input-container *ngIf=\"!variant.existing\">\r\n <input\r\n clrInput\r\n type=\"text\"\r\n [(ngModel)]=\"variant.sku\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n name=\"sku\"\r\n required\r\n (ngModelChange)=\"onFormChanged(variant)\"\r\n />\r\n </clr-input-container>\r\n <span *ngIf=\"variant.existing\">{{ variant.sku }}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"flex center\">\r\n <clr-input-container *ngIf=\"!variant.existing\">\r\n <vdr-currency-input\r\n clrInput\r\n [(ngModel)]=\"variant.price\"\r\n name=\"price\"\r\n [currencyCode]=\"currencyCode\"\r\n (ngModelChange)=\"onFormChanged(variant)\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n <span *ngIf=\"variant.existing\">{{ variant.price | localeCurrency: currencyCode }}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"flex center\">\r\n <clr-input-container *ngIf=\"!variant.existing\">\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [(ngModel)]=\"variant.stock\"\r\n name=\"stock\"\r\n min=\"0\"\r\n step=\"1\"\r\n (ngModelChange)=\"onFormChanged(variant)\"\r\n />\r\n </clr-input-container>\r\n <span *ngIf=\"variant.existing\">{{ variant.stock }}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <vdr-dropdown *ngIf=\"variant.productVariantId as productVariantId\">\r\n <button class=\"icon-button\" vdrDropdownTrigger>\r\n <clr-icon shape=\"ellipsis-vertical\"></clr-icon>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <button\r\n type=\"button\"\r\n class=\"delete-button\"\r\n (click)=\"deleteVariant(productVariantId, variant.options)\"\r\n vdrDropdownItem\r\n >\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon>\r\n {{ 'common.delete' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n", styles: [".option-groups{display:flex}.option-groups:first-of-type{margin-top:24px}.values{flex:1;margin:0 6px}.variants-preview tr.disabled td{background-color:var(--color-component-bg-100);color:var(--color-grey-400)}\n"], components: [{ type: i1$1.ActionBarComponent, selector: "vdr-action-bar" }, { type: i1$1.ActionBarRightComponent, selector: "vdr-ab-right", inputs: ["grow"] }, { type: OptionValueInputComponent, selector: "vdr-option-value-input", inputs: ["groupName", "options", "disabled"], outputs: ["add", "remove", "edit"] }, { type: i2.ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper" }, { type: i2.ClrInputContainer, selector: "clr-input-container" }, { type: i1$1.CurrencyInputComponent, selector: "vdr-currency-input", inputs: ["disabled", "readonly", "value", "currencyCode"], outputs: ["valueChange"] }, { type: i1$1.DropdownComponent, selector: "vdr-dropdown", inputs: ["manualToggle"] }, { type: i1$1.DropdownMenuComponent, selector: "vdr-dropdown-menu", inputs: ["vdrPosition"] }], directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.ClrLabel, selector: "label", inputs: ["for"] }, { type: i1$1.FormFieldControlDirective, selector: "input, textarea, select" }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.ClrInput, selector: "[clrInput]" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i2.ClrIconCustomTag, selector: "clr-icon" }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i2.ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i4.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i1$1.DropdownTriggerDirective, selector: "[vdrDropdownTrigger]" }, { type: i1$1.DropdownItemDirective, selector: "[vdrDropdownItem]" }], pipes: { "translate": i5$1.TranslatePipe, "localeCurrency": i1$1.LocaleCurrencyPipe }, changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
3389
3553
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: ProductVariantsEditorComponent, decorators: [{
|
|
3390
3554
|
type: Component,
|
|
3391
|
-
args: [{ selector: 'vdr-product-variants-editor', changeDetection: ChangeDetectionStrategy.Default, template: "<vdr-action-bar>\r\n <vdr-ab-right>\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"!formValueChanged || getVariantsToAdd().length === 0\"\r\n >\r\n {{ 'common.add-new-variants' | translate: { count: getVariantsToAdd().length } }}\r\n </button>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input clrInput [(ngModel)]=\"group.name\" name=\"name\" [readonly]=\"!group.isNew\" />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [
|
|
3555
|
+
args: [{ selector: 'vdr-product-variants-editor', changeDetection: ChangeDetectionStrategy.Default, template: "<vdr-action-bar>\r\n <vdr-ab-right>\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"save()\"\r\n [disabled]=\"(!formValueChanged && !optionsChanged) || getVariantsToAdd().length === 0\"\r\n >\r\n {{ 'common.add-new-variants' | translate: { count: getVariantsToAdd().length } }}\r\n </button>\r\n </vdr-ab-right>\r\n</vdr-action-bar>\r\n\r\n<div *ngFor=\"let group of optionGroups\" class=\"option-groups\">\r\n <div class=\"name\">\r\n <label>{{ 'catalog.option' | translate }}</label>\r\n <input clrInput [(ngModel)]=\"group.name\" name=\"name\" [readonly]=\"!group.isNew\" />\r\n </div>\r\n <div class=\"values\">\r\n <label>{{ 'catalog.option-values' | translate }}</label>\r\n <vdr-option-value-input\r\n #optionValueInputComponent\r\n [options]=\"group.values\"\r\n [groupName]=\"group.name\"\r\n [disabled]=\"group.name === ''\"\r\n (add)=\"addOption(group.id, $event.name)\"\r\n (remove)=\"removeOption(group.id, $event)\"\r\n ></vdr-option-value-input>\r\n </div>\r\n <div>\r\n <button\r\n [disabled]=\"group.locked\"\r\n class=\"btn btn-icon btn-danger-outline mt5\" (click)=\"removeOptionGroup(group)\">\r\n <clr-icon shape=\"trash\"></clr-icon>\r\n </button>\r\n </div>\r\n</div>\r\n<button class=\"btn btn-primary-outline btn-sm\" (click)=\"addOptionGroup()\">\r\n <clr-icon shape=\"plus\"></clr-icon>\r\n {{ 'catalog.add-option' | translate }}\r\n</button>\r\n\r\n<div class=\"variants-preview\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>{{ 'catalog.variant' | translate }}</th>\r\n <th>{{ 'catalog.sku' | translate }}</th>\r\n <th>{{ 'catalog.price' | translate }}</th>\r\n <th>{{ 'catalog.stock-on-hand' | translate }}</th>\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tr *ngFor=\"let variant of generatedVariants\" [class.disabled]=\"!variant.enabled || variant.existing\">\r\n <td class=\"left\">\r\n <clr-checkbox-wrapper *ngIf=\"!variant.existing\">\r\n <input\r\n type=\"checkbox\"\r\n [(ngModel)]=\"variant.enabled\"\r\n name=\"enabled\"\r\n clrCheckbox\r\n (ngModelChange)=\"formValueChanged = true\"\r\n />\r\n <label>{{ 'common.create' | translate }}</label>\r\n </clr-checkbox-wrapper>\r\n </td>\r\n <td>\r\n {{ getVariantName(variant) | translate }}\r\n </td>\r\n <td>\r\n <div class=\"flex center\">\r\n <clr-input-container *ngIf=\"!variant.existing\">\r\n <input\r\n clrInput\r\n type=\"text\"\r\n [(ngModel)]=\"variant.sku\"\r\n [placeholder]=\"'catalog.sku' | translate\"\r\n name=\"sku\"\r\n required\r\n (ngModelChange)=\"onFormChanged(variant)\"\r\n />\r\n </clr-input-container>\r\n <span *ngIf=\"variant.existing\">{{ variant.sku }}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"flex center\">\r\n <clr-input-container *ngIf=\"!variant.existing\">\r\n <vdr-currency-input\r\n clrInput\r\n [(ngModel)]=\"variant.price\"\r\n name=\"price\"\r\n [currencyCode]=\"currencyCode\"\r\n (ngModelChange)=\"onFormChanged(variant)\"\r\n ></vdr-currency-input>\r\n </clr-input-container>\r\n <span *ngIf=\"variant.existing\">{{ variant.price | localeCurrency: currencyCode }}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"flex center\">\r\n <clr-input-container *ngIf=\"!variant.existing\">\r\n <input\r\n clrInput\r\n type=\"number\"\r\n [(ngModel)]=\"variant.stock\"\r\n name=\"stock\"\r\n min=\"0\"\r\n step=\"1\"\r\n (ngModelChange)=\"onFormChanged(variant)\"\r\n />\r\n </clr-input-container>\r\n <span *ngIf=\"variant.existing\">{{ variant.stock }}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <vdr-dropdown *ngIf=\"variant.productVariantId as productVariantId\">\r\n <button class=\"icon-button\" vdrDropdownTrigger>\r\n <clr-icon shape=\"ellipsis-vertical\"></clr-icon>\r\n </button>\r\n <vdr-dropdown-menu vdrPosition=\"bottom-right\">\r\n <button\r\n type=\"button\"\r\n class=\"delete-button\"\r\n (click)=\"deleteVariant(productVariantId, variant.options)\"\r\n vdrDropdownItem\r\n >\r\n <clr-icon shape=\"trash\" class=\"is-danger\"></clr-icon>\r\n {{ 'common.delete' | translate }}\r\n </button>\r\n </vdr-dropdown-menu>\r\n </vdr-dropdown>\r\n </td>\r\n </tr>\r\n </table>\r\n</div>\r\n", styles: [".option-groups{display:flex}.option-groups:first-of-type{margin-top:24px}.values{flex:1;margin:0 6px}.variants-preview tr.disabled td{background-color:var(--color-component-bg-100);color:var(--color-grey-400)}\n"] }]
|
|
3392
3556
|
}], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i1$1.DataService }, { type: ProductDetailService }, { type: i1$1.NotificationService }, { type: i1$1.ModalService }]; } });
|
|
3393
3557
|
|
|
3394
3558
|
class AssetResolver extends BaseEntityResolver {
|