@fleetbase/storefront-engine 0.1.5 → 0.1.7
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/addon/components/modals/add-store-to-category.hbs +5 -0
- package/addon/components/modals/create-network-category.hbs +28 -28
- package/addon/components/modals/share-network.hbs +3 -3
- package/addon/components/modals/store-details.hbs +22 -0
- package/addon/components/modals/store-form.hbs +22 -0
- package/addon/components/modals/store-form.js +21 -0
- package/addon/components/network-category-picker.hbs +40 -0
- package/addon/components/network-category-picker.js +83 -0
- package/addon/components/store-selector.hbs +4 -2
- package/addon/components/widget/orders.js +22 -17
- package/addon/controllers/networks/index/network/index.js +133 -9
- package/addon/controllers/networks/index/network/stores.js +422 -153
- package/addon/controllers/networks/index.js +66 -4
- package/addon/controllers/products/index/category.js +1 -1
- package/addon/controllers/settings/index.js +14 -7
- package/addon/controllers/settings/notifications.js +1 -1
- package/addon/models/store.js +44 -7
- package/addon/routes/networks/index/network/customers.js +4 -1
- package/addon/routes/networks/index/network/orders.js +4 -1
- package/addon/routes/networks/index/network/stores.js +19 -15
- package/addon/serializers/store.js +1 -0
- package/addon/templates/customers/index.hbs +0 -11
- package/addon/templates/networks/index/network/index.hbs +1 -1
- package/addon/templates/networks/index/network/stores.hbs +8 -163
- package/addon/templates/networks/index/network.hbs +2 -3
- package/addon/utils/create-shareable-link.js +21 -0
- package/app/components/modals/add-store-to-category.js +1 -0
- package/app/components/modals/store-details.js +1 -0
- package/app/components/modals/store-form.js +1 -0
- package/app/components/network-category-picker.js +1 -0
- package/app/utils/create-shareable-link.js +1 -0
- package/package.json +3 -4
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
|
|
2
|
+
<div class="modal-body-container">
|
|
3
|
+
<NetworkCategoryPicker @network={{@options.network}} @onSelect={{@options.onSelectCategory}} @onCreateNewCategory={{@options.createNewCategory}} @wrapperClass="mr-2" />
|
|
4
|
+
</div>
|
|
5
|
+
</Modal::Default>
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
|
|
2
2
|
<div class="modal-body-container">
|
|
3
|
+
<InputGroup @name="Parent category" @wrapperClass="border-b border-gray-200 dark:border-gray-700 pb-4 mb-3i">
|
|
4
|
+
<ModelSelect @modelName="category" @query={{hash for="storefront_network" owner_uuid=@options.network.id}} @selectedModel={{@options.parentCategory}} @placeholder="Select a parent category if any" @triggerClass="form-select form-input" @infiniteScroll={{false}} @renderInPlace={{true}} @onChange={{@options.setParentCategory}} as |model|>
|
|
5
|
+
{{model.name}}
|
|
6
|
+
</ModelSelect>
|
|
7
|
+
</InputGroup>
|
|
3
8
|
<InputGroup @name="Category name" @value={{@options.category.name}} @helpText="Enter a name for category" />
|
|
4
9
|
<InputGroup @name="Category description" @value={{@options.category.description}} @helpText="Give your network category a brief description" />
|
|
5
|
-
<InputGroup @name="Category icon type" @wrapperClass="mb-0">
|
|
10
|
+
{{!-- <InputGroup @name="Category icon type" @wrapperClass="mb-0">
|
|
6
11
|
<div class="flex flex-row dark:text-gray-100 mt-4">
|
|
7
12
|
<div class="flex flex-row items-center mr-4">
|
|
8
13
|
<RadioButton @radioClass="focus:ring-blue-500 mr-2" @radioId="image_icon_type" @value="image" @groupValue={{@options.iconType}} @name="icon_type" @changed={{fn (mut @options.iconType)}} />
|
|
@@ -14,35 +19,30 @@
|
|
|
14
19
|
</div>
|
|
15
20
|
</div>
|
|
16
21
|
</InputGroup>
|
|
17
|
-
<div>iconType: {{@options.iconType}}</div>
|
|
18
22
|
<InputGroup @name="Category icon">
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Upload new
|
|
35
|
-
</span>
|
|
36
|
-
{{/if}}
|
|
37
|
-
</a>
|
|
38
|
-
</FileUpload>
|
|
39
|
-
<a href="javascript:;" class="text-danger block mt-2" {{on "click" @options.clearImage}}>
|
|
40
|
-
<FaIcon @icon="times" @prefix="fas" class="mr-1" />
|
|
41
|
-
<span>Remove</span>
|
|
23
|
+
<div class="w-32">
|
|
24
|
+
<img src={{@options.category.icon_url}} alt={{@options.category.name}} class="w-full rounded-md" />
|
|
25
|
+
<FileUpload @name="icons" @accept="image/*" @onFileAdded={{@options.uploadIcon}} as |queue|>
|
|
26
|
+
<a tabindex={{0}} class="flex items-center px-0 mt-2 text-xs no-underline truncate btn btn-sm btn-default">
|
|
27
|
+
{{#if queue.files.length}}
|
|
28
|
+
<Spinner class="mr-1" />
|
|
29
|
+
<span>
|
|
30
|
+
Uploading...
|
|
31
|
+
</span>
|
|
32
|
+
{{else}}
|
|
33
|
+
<FaIcon @icon="image" class="mr-1" />
|
|
34
|
+
<span>
|
|
35
|
+
Upload new
|
|
36
|
+
</span>
|
|
37
|
+
{{/if}}
|
|
42
38
|
</a>
|
|
43
|
-
</
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
</FileUpload>
|
|
40
|
+
<a href="javascript:;" class="text-danger block mt-2" {{on "click" @options.clearImage}}>
|
|
41
|
+
<FaIcon @icon="times" @prefix="fas" class="mr-1" />
|
|
42
|
+
<span>Remove</span>
|
|
43
|
+
</a>
|
|
44
|
+
</div>
|
|
45
|
+
</InputGroup> --}}
|
|
46
46
|
<InputGroup>
|
|
47
47
|
<TranslationsEditor @value={{@options.category.translations}} @defaultKeys={{array "name" "description"}} @onChange={{fn (mut @options.category.translations)}} />
|
|
48
48
|
</InputGroup>
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
|
|
25
25
|
<div class="rounded-md border dark:border-gray-800 dark:bg-gray-800 p-4">
|
|
26
26
|
<h4 class="dark:text-gray-50 mb-4 font-semibold">Get link</h4>
|
|
27
|
-
<div class="input-group mb-
|
|
28
|
-
<
|
|
27
|
+
<div class="input-group mb-0i">
|
|
28
|
+
<Toggle @isToggled={{@options.network.options.shareable_link_enabled}} @onToggle={{@options.toggleShareableLink}} @label="Enable shareable link" @helpText="Anyone with this link is able to join your network" />
|
|
29
29
|
</div>
|
|
30
30
|
{{#if @options.network.options.shareable_link_enabled}}
|
|
31
|
-
<ClickToCopy class="mt-4 rounded-md border dark:border-gray-900 dark:bg-gray-900 truncate
|
|
31
|
+
<ClickToCopy class="mt-4 rounded-md border dark:border-gray-900 dark:bg-gray-900 truncate px-4 py-2.5 text-sm text-green-400 dark:text-green-300 text-center" @value={{@options.shareableLink}} />
|
|
32
32
|
{{/if}}
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
|
|
2
|
+
<div class="modal-body-container">
|
|
3
|
+
<div class="grid grid-cols-1 gap-2 lg:grid-cols-2 lg:gap-4 text-xs dark:text-gray-100">
|
|
4
|
+
<div class="field-info-container">
|
|
5
|
+
<div class="field-name">Name</div>
|
|
6
|
+
<div class="field-value">{{n-a @options.store.name}}</div>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="field-info-container">
|
|
9
|
+
<div class="field-name">Description</div>
|
|
10
|
+
<div class="field-value">{{n-a @options.store.description}}</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="field-info-container">
|
|
13
|
+
<div class="field-name">Tags</div>
|
|
14
|
+
<div class="field-value">{{n-a @options.store.tagsList}}</div>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="field-info-container">
|
|
17
|
+
<div class="field-name">Currency</div>
|
|
18
|
+
<div class="field-value">{{n-a @options.store.currency}}</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</Modal::Default>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
|
|
2
|
+
<div class="modal-body-container">
|
|
3
|
+
<InputGroup @id="storefront_name_input" @name="Name" @value={{@options.store.name}} @placeholder="Storefront Name" @helpText="The name of your store." />
|
|
4
|
+
<InputGroup @name="Description" @value={{@options.store.description}} @placeholder="Storefront Description" @helpText="Give your store a brief description to let users know what you sell." />
|
|
5
|
+
<InputGroup @name="Tags">
|
|
6
|
+
<TagInput class="form-input" @placeholder="Add tags" @allowSpacesInTags={{true}} @tags={{@options.store.tags}} @addTag={{this.addTag}} @removeTagAtIndex={{this.removeTag}} as |tag|>
|
|
7
|
+
{{tag}}
|
|
8
|
+
</TagInput>
|
|
9
|
+
</InputGroup>
|
|
10
|
+
<InputGroup @name="Currency">
|
|
11
|
+
<CurrencySelect @value={{@options.store.currency}} @onSelect={{fn (mut @options.store.currency)}} @triggerClass="w-full form-select" />
|
|
12
|
+
</InputGroup>
|
|
13
|
+
|
|
14
|
+
<div class="store-boolean-settings">
|
|
15
|
+
<div class="input-group">
|
|
16
|
+
<Toggle @isToggled={{@options.store.online}} @onToggle={{fn (mut @options.store.online)}}>
|
|
17
|
+
<FaIcon @icon="plug" class="text-gray-600 dark:text-gray-400 mx-2" /><span class="dark:text-gray-100 text-sm">Online</span>
|
|
18
|
+
</Toggle>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</Modal::Default>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { action } from '@ember/object';
|
|
3
|
+
import { isArray } from '@ember/array';
|
|
4
|
+
|
|
5
|
+
export default class ModalsStoreFormComponent extends Component {
|
|
6
|
+
get activeStore() {
|
|
7
|
+
return this.args.options.store;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@action addTag(tag) {
|
|
11
|
+
if (!isArray(this.activeStore.tags)) {
|
|
12
|
+
this.activeStore.tags = [];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
this.activeStore.tags?.pushObject(tag);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@action removeTag(index) {
|
|
19
|
+
this.activeStore.tags?.removeAt(index);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<DropdownButton @renderInPlace={{true}} @size="xs" @type="magic" @icon="folder-tree" @iconSize="sm" @text={{this.buttonTitle}} @buttonClass={{concat "w-full truncate w-48" " " @buttonClass}} @buttonWrapperClass={{concat "w-full" " " @buttonWrapperClass}} @wrapperClass={{@wrapperClass}} as |dd|>
|
|
2
|
+
<div role="menu" class="store-selector-dropdown-menu next-dd-menu py-1">
|
|
3
|
+
<div role="group" class="px-1 overflow-y-scroll max-h-72">
|
|
4
|
+
{{#if this.isLoading}}
|
|
5
|
+
<div class="text-sm flex flex-row items-center px-3 py-0.5 border-0 my-1">
|
|
6
|
+
<Spinner class="mr-2i" />
|
|
7
|
+
<span class="dark:text-gray-100 test-sm">Loading...</span>
|
|
8
|
+
</div>
|
|
9
|
+
{{else}}
|
|
10
|
+
{{#if this.selectedCategory}}
|
|
11
|
+
<a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" this.loadParentCategories}}>
|
|
12
|
+
<FaIcon @icon="arrow-left" class="mr-2" />
|
|
13
|
+
<span>Back</span>
|
|
14
|
+
</a>
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{#each this.categories as |category|}}
|
|
17
|
+
<a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (fn this.onSelectCategory category)}}>
|
|
18
|
+
{{category.name}}
|
|
19
|
+
</a>
|
|
20
|
+
{{else}}
|
|
21
|
+
<div class="text-sm flex flex-row items-center px-3 py-0.5 border-0 my-1 truncate">
|
|
22
|
+
{{#if this.selectedCategory}}
|
|
23
|
+
<span>No subcategories for {{this.selectedCategory.name}}</span>
|
|
24
|
+
{{else}}
|
|
25
|
+
<span>No categories for this network</span>
|
|
26
|
+
{{/if}}
|
|
27
|
+
</div>
|
|
28
|
+
{{/each}}
|
|
29
|
+
{{/if}}
|
|
30
|
+
</div>
|
|
31
|
+
<div class="px-1">
|
|
32
|
+
<div class="next-dd-menu-seperator"></div>
|
|
33
|
+
<div role="group" class="px-1">
|
|
34
|
+
<a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (dropdown-fn dd this.onCreateNewCategory)}}>
|
|
35
|
+
Create a new category
|
|
36
|
+
</a>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</DropdownButton>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
import isModel from '@fleetbase/ember-core/utils/is-model';
|
|
6
|
+
|
|
7
|
+
export default class NetworkCategoryPickerComponent extends Component {
|
|
8
|
+
@service fetch;
|
|
9
|
+
@service store;
|
|
10
|
+
@service notifications;
|
|
11
|
+
@tracked categories = [];
|
|
12
|
+
@tracked selectedCategory;
|
|
13
|
+
@tracked network;
|
|
14
|
+
@tracked isLoading = false;
|
|
15
|
+
@tracked buttonTitle = null;
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
super(...arguments);
|
|
19
|
+
this.network = this.args.network;
|
|
20
|
+
this.category = this.args.category;
|
|
21
|
+
this.setButtonTitle(this.category);
|
|
22
|
+
this.loadCategories(this.category);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setButtonTitle(selectedCategory) {
|
|
26
|
+
let buttonTitle = this.args.buttonTitle ?? 'Select Category';
|
|
27
|
+
|
|
28
|
+
if (selectedCategory) {
|
|
29
|
+
buttonTitle = selectedCategory.name;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.buttonTitle = buttonTitle;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@action loadCategories(parentCategory) {
|
|
36
|
+
const queryParams = {
|
|
37
|
+
owner_uuid: this.network.id,
|
|
38
|
+
parents_only: parentCategory ? false : true,
|
|
39
|
+
with_subcategories: true,
|
|
40
|
+
for: 'storefront_network',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
if (isModel(parentCategory)) {
|
|
44
|
+
queryParams.parent = parentCategory.id;
|
|
45
|
+
queryParams.with_parent = true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.isLoading = true;
|
|
49
|
+
this.store
|
|
50
|
+
.query('category', queryParams)
|
|
51
|
+
.then((categories) => {
|
|
52
|
+
this.categories = categories.toArray();
|
|
53
|
+
})
|
|
54
|
+
.finally(() => {
|
|
55
|
+
this.isLoading = false;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@action onSelectCategory(category) {
|
|
60
|
+
this.selectedCategory = category;
|
|
61
|
+
this.setButtonTitle(category);
|
|
62
|
+
|
|
63
|
+
if (typeof this.args.onSelect === 'function') {
|
|
64
|
+
this.args.onSelect(category);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.loadCategories(category);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@action onCreateNewCategory() {
|
|
71
|
+
if (typeof this.args.onCreateNewCategory === 'function') {
|
|
72
|
+
this.args.onCreateNewCategory(this, this.selectedCategory);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@action async loadParentCategories() {
|
|
77
|
+
if (this.selectedCategory.parent) {
|
|
78
|
+
return this.onSelectCategory(this.selectedCategory.parent);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.onSelectCategory(null);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{{#if @activeStore}}
|
|
2
2
|
<DropdownButton @renderInPlace={{true}} @size="xs" @type="primary" @icon="store" @iconSize="sm" @text={{@activeStore.name}} @buttonClass={{concat "w-full " @buttonClass}} @buttonWrapperClass={{concat "w-full " @buttonWrapperClass}} @wrapperClass={{@wrapperClass}} as |dd|>
|
|
3
|
-
<div role="menu" class="next-dd-menu py-1">
|
|
4
|
-
<div role="group" class="px-1 overflow-y-scroll
|
|
3
|
+
<div role="menu" class="store-selector-dropdown-menu next-dd-menu py-1">
|
|
4
|
+
<div role="group" class="px-1 overflow-y-scroll max-h-72">
|
|
5
5
|
{{#each @stores as |store|}}
|
|
6
6
|
<a href="javascript:;" class="next-dd-item" role="menuitem" {{on "click" (dropdown-fn dd this.onSwitchStore store)}}>
|
|
7
7
|
{{or store.name "-"}}
|
|
8
8
|
</a>
|
|
9
|
+
{{else}}
|
|
10
|
+
<div class="next-dd-item" role="menuitem">No stores to select</div>
|
|
9
11
|
{{/each}}
|
|
10
12
|
</div>
|
|
11
13
|
<div class="px-1">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
|
-
import { action, computed } from '@ember/object';
|
|
4
|
+
import { action, computed, get } from '@ember/object';
|
|
5
5
|
import { later } from '@ember/runloop';
|
|
6
6
|
|
|
7
7
|
export default class WidgetOrdersComponent extends Component {
|
|
@@ -26,8 +26,15 @@ export default class WidgetOrdersComponent extends Component {
|
|
|
26
26
|
100
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
this.storefront.on('
|
|
29
|
+
// reload orders when new order income
|
|
30
|
+
this.storefront.on('order.broadcasted', () => {
|
|
31
|
+
this.reloadOrders();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// reload orders when store changes
|
|
35
|
+
this.storefront.on('storefront.changed', () => {
|
|
36
|
+
this.reloadOrders();
|
|
37
|
+
});
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
@action async reloadOrders(params = {}) {
|
|
@@ -52,27 +59,25 @@ export default class WidgetOrdersComponent extends Component {
|
|
|
52
59
|
this.isLoading = true;
|
|
53
60
|
|
|
54
61
|
return new Promise((resolve) => {
|
|
55
|
-
const storefront = this.storefront
|
|
62
|
+
const storefront = get(this.storefront, 'activeStore.public_id');
|
|
56
63
|
|
|
57
64
|
if (!storefront) {
|
|
58
65
|
this.isLoading = false;
|
|
59
66
|
return resolve([]);
|
|
60
67
|
}
|
|
61
68
|
|
|
69
|
+
const queryParams = {
|
|
70
|
+
storefront,
|
|
71
|
+
limit: 14,
|
|
72
|
+
sort: '-created_at',
|
|
73
|
+
...params,
|
|
74
|
+
};
|
|
75
|
+
|
|
62
76
|
this.fetch
|
|
63
|
-
.get(
|
|
64
|
-
'
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
limit: 14,
|
|
68
|
-
sort: '-created_at',
|
|
69
|
-
...params,
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
namespace: 'storefront/int/v1',
|
|
73
|
-
normalizeToEmberData: true,
|
|
74
|
-
}
|
|
75
|
-
)
|
|
77
|
+
.get('orders', queryParams, {
|
|
78
|
+
namespace: 'storefront/int/v1',
|
|
79
|
+
normalizeToEmberData: true,
|
|
80
|
+
})
|
|
76
81
|
.then((orders) => {
|
|
77
82
|
this.isLoading = false;
|
|
78
83
|
|
|
@@ -3,27 +3,103 @@ import { tracked } from '@glimmer/tracking';
|
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { alias } from '@ember/object/computed';
|
|
5
5
|
import { action } from '@ember/object';
|
|
6
|
-
import getPodMethods from '@fleetbase/
|
|
6
|
+
import getPodMethods from '@fleetbase/ember-core/utils/get-pod-methods';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* NetworksIndexNetworkIndexController
|
|
10
|
+
*
|
|
11
|
+
* This controller handles the logic for managing networks, gateways, and notification channels.
|
|
12
|
+
*
|
|
13
|
+
* @class NetworksIndexNetworkIndexController
|
|
14
|
+
* @extends Controller
|
|
15
|
+
*/
|
|
8
16
|
export default class NetworksIndexNetworkIndexController extends Controller {
|
|
17
|
+
/**
|
|
18
|
+
* Controller for managing gateways.
|
|
19
|
+
*
|
|
20
|
+
* @property {Controller} gatewaysController
|
|
21
|
+
*/
|
|
9
22
|
@controller('settings.gateways') gatewaysController;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Controller for managing notifications.
|
|
26
|
+
*
|
|
27
|
+
* @property {Controller} notificationsController
|
|
28
|
+
*/
|
|
10
29
|
@controller('settings.notifications') notificationsController;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Notifications service to handle notification logic.
|
|
33
|
+
*
|
|
34
|
+
* @property {Service} notifications
|
|
35
|
+
*/
|
|
11
36
|
@service notifications;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Fetch service to handle file uploads and other network requests.
|
|
40
|
+
*
|
|
41
|
+
* @property {Service} fetch
|
|
42
|
+
*/
|
|
12
43
|
@service fetch;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Proof of delivery methods.
|
|
47
|
+
*
|
|
48
|
+
* @property {Array} podMethods
|
|
49
|
+
*/
|
|
13
50
|
@tracked podMethods = getPodMethods();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Loading state, indicating whether a network request is in progress.
|
|
54
|
+
*
|
|
55
|
+
* @property {Boolean} isLoading
|
|
56
|
+
*/
|
|
14
57
|
@tracked isLoading = false;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Alias for model.gateways, representing the gateways associated with the network.
|
|
61
|
+
*
|
|
62
|
+
* @property {Array} gateways
|
|
63
|
+
*/
|
|
15
64
|
@alias('model.gateways') gateways;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Alias for model.notification_channels, representing the notification channels associated with the network.
|
|
68
|
+
*
|
|
69
|
+
* @property {Array} channels
|
|
70
|
+
*/
|
|
16
71
|
@alias('model.notification_channels') channels;
|
|
17
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Save network settings.
|
|
75
|
+
*
|
|
76
|
+
* @method saveSettings
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
18
79
|
@action saveSettings() {
|
|
19
80
|
this.isLoading = true;
|
|
20
81
|
|
|
21
|
-
this.model
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
82
|
+
this.model
|
|
83
|
+
.save()
|
|
84
|
+
.then(() => {
|
|
85
|
+
this.notifications.success('Changes to network saved.');
|
|
86
|
+
})
|
|
87
|
+
.catch((error) => {
|
|
88
|
+
this.notifications.serverError(error);
|
|
89
|
+
})
|
|
90
|
+
.finally(() => {
|
|
91
|
+
this.isLoading = false;
|
|
92
|
+
});
|
|
25
93
|
}
|
|
26
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Upload a file.
|
|
97
|
+
*
|
|
98
|
+
* @method uploadFile
|
|
99
|
+
* @param {String} type - Type of the file.
|
|
100
|
+
* @param {File} file - File to upload.
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
27
103
|
@action uploadFile(type, file) {
|
|
28
104
|
const prefix = type.replace('storefront_', '');
|
|
29
105
|
|
|
@@ -32,23 +108,29 @@ export default class NetworksIndexNetworkIndexController extends Controller {
|
|
|
32
108
|
{
|
|
33
109
|
path: `uploads/storefront/${this.model.id}/${type}`,
|
|
34
110
|
key_uuid: this.model.id,
|
|
35
|
-
key_type: `network
|
|
111
|
+
key_type: `storefront:network`,
|
|
36
112
|
type,
|
|
37
113
|
},
|
|
38
114
|
(uploadedFile) => {
|
|
39
115
|
this.model.setProperties({
|
|
40
116
|
[`${prefix}_uuid`]: uploadedFile.id,
|
|
41
|
-
[`${prefix}_url`]: uploadedFile.
|
|
117
|
+
[`${prefix}_url`]: uploadedFile.url,
|
|
42
118
|
[prefix]: uploadedFile,
|
|
43
119
|
});
|
|
44
120
|
}
|
|
45
121
|
);
|
|
46
122
|
}
|
|
47
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Create a new payment gateway.
|
|
126
|
+
*
|
|
127
|
+
* @method createGateway
|
|
128
|
+
* @public
|
|
129
|
+
*/
|
|
48
130
|
@action createGateway() {
|
|
49
131
|
const gateway = this.store.createRecord('gateway', {
|
|
50
132
|
owner_uuid: this.model.id,
|
|
51
|
-
owner_type: 'network
|
|
133
|
+
owner_type: 'storefront:network',
|
|
52
134
|
});
|
|
53
135
|
|
|
54
136
|
this.editGateway(gateway, {
|
|
@@ -69,6 +151,14 @@ export default class NetworksIndexNetworkIndexController extends Controller {
|
|
|
69
151
|
});
|
|
70
152
|
}
|
|
71
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Edit a payment gateway.
|
|
156
|
+
*
|
|
157
|
+
* @method editGateway
|
|
158
|
+
* @param {Object} gateway - The gateway object to edit.
|
|
159
|
+
* @param {Object} [options={}] - Optional parameters for editing the gateway.
|
|
160
|
+
* @public
|
|
161
|
+
*/
|
|
72
162
|
@action editGateway(gateway, options = {}) {
|
|
73
163
|
if (options === null) {
|
|
74
164
|
options = {};
|
|
@@ -87,14 +177,26 @@ export default class NetworksIndexNetworkIndexController extends Controller {
|
|
|
87
177
|
return this.gatewaysController.editGateway(gateway, options);
|
|
88
178
|
}
|
|
89
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Delete a payment gateway.
|
|
182
|
+
*
|
|
183
|
+
* @method deleteGateway
|
|
184
|
+
* @public
|
|
185
|
+
*/
|
|
90
186
|
@action deleteGateway() {
|
|
91
187
|
return this.gatewaysController.deleteGateway(...arguments);
|
|
92
188
|
}
|
|
93
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Create a new notification channel.
|
|
192
|
+
*
|
|
193
|
+
* @method createChannel
|
|
194
|
+
* @public
|
|
195
|
+
*/
|
|
94
196
|
@action createChannel() {
|
|
95
197
|
const channel = this.store.createRecord('notification-channel', {
|
|
96
198
|
owner_uuid: this.model.id,
|
|
97
|
-
owner_type: 'network
|
|
199
|
+
owner_type: 'storefront:network',
|
|
98
200
|
});
|
|
99
201
|
|
|
100
202
|
this.editChannel(channel, {
|
|
@@ -115,6 +217,14 @@ export default class NetworksIndexNetworkIndexController extends Controller {
|
|
|
115
217
|
});
|
|
116
218
|
}
|
|
117
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Edit a notification channel.
|
|
222
|
+
*
|
|
223
|
+
* @method editChannel
|
|
224
|
+
* @param {Object} channel - The channel object to edit.
|
|
225
|
+
* @param {Object} [options={}] - Optional parameters for editing the channel.
|
|
226
|
+
* @public
|
|
227
|
+
*/
|
|
118
228
|
@action editChannel(channel, options = {}) {
|
|
119
229
|
if (options === null) {
|
|
120
230
|
options = {};
|
|
@@ -133,10 +243,24 @@ export default class NetworksIndexNetworkIndexController extends Controller {
|
|
|
133
243
|
return this.notificationsController.editChannel(channel, options);
|
|
134
244
|
}
|
|
135
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Delete a notification channel.
|
|
248
|
+
*
|
|
249
|
+
* @method deleteChannel
|
|
250
|
+
* @public
|
|
251
|
+
*/
|
|
136
252
|
@action deleteChannel() {
|
|
137
253
|
return this.notificationsController.deleteChannel(...arguments);
|
|
138
254
|
}
|
|
139
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Make an alertable action.
|
|
258
|
+
*
|
|
259
|
+
* @method makeAlertable
|
|
260
|
+
* @param {String} reason - Reason for the alert.
|
|
261
|
+
* @param {Array} models - Models associated with the alert.
|
|
262
|
+
* @public
|
|
263
|
+
*/
|
|
140
264
|
@action makeAlertable(reason, models) {
|
|
141
265
|
if (!this.model.alertable || !this.model.alertable?.length) {
|
|
142
266
|
this.model.set('alertable', {});
|