@isoftdata/svelte-ecommerce 1.0.0-beta.0 → 1.0.0-beta.1

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.
@@ -1,263 +1,248 @@
1
- <script lang="ts">
2
- import type { i18n } from 'i18next'
3
-
4
- import { getContext } from 'svelte'
5
- import Table from '@isoftdata/svelte-table'
6
- import klona from 'klona'
7
- import Modal from '@isoftdata/svelte-modal'
8
- import Checkbox from '@isoftdata/svelte-checkbox'
9
- import Button from '@isoftdata/svelte-button'
10
- import Select from '@isoftdata/svelte-select'
11
- import type {
12
- EbayLocation,
13
- EbayPolicy,
14
- EcommerceCondition,
15
- EcommercePartnerConfiguration,
16
- EcommerceStoreConfig,
17
- Store,
18
- EcommerceSharedDefaults,
19
- } from './utils.js'
20
- import EcommerceDefaults from './EcommerceDefaults.svelte'
21
-
22
- import { translate as defaultTranslate } from '@isoftdata/utility-string'
23
- const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
24
-
25
- interface Props {
26
- ebayLocationList?: EbayLocation[]
27
- ebayPolicyList?: EbayPolicy[]
28
- ecommerceConditionList: EcommerceCondition[]
29
- partnerConfigurationList?: EcommercePartnerConfiguration[]
30
- selectedEcommercePartnerId: number
31
- storeList: Store[]
32
- partnerConfigurationChanged: (partnerConfig: EcommercePartnerConfiguration) => Promise<void>
33
- }
34
-
35
- let {
36
- ebayLocationList = [],
37
- ebayPolicyList = [],
38
- ecommerceConditionList = [],
39
- partnerConfigurationList = [],
40
- selectedEcommercePartnerId,
41
- storeList = [],
42
- partnerConfigurationChanged = async (_: EcommercePartnerConfiguration) => {},
43
- }: Props = $props()
44
-
45
- let newStoreConfig: EcommerceStoreConfig = Object.freeze({
46
- active: true,
47
- defaults: {
48
- brandMapping: undefined,
49
- conditionDescription: undefined,
50
- conditionId: undefined,
51
- fulfillmentPolicies: undefined,
52
- fulfillmentTimeUnit: undefined,
53
- fulfillmentTimeValue: undefined,
54
- listingDescriptionTemplate: undefined,
55
- listingDuration: undefined,
56
- listingFormat: undefined,
57
- listingTitleTemplate: undefined,
58
- manufacturerPartNumberMapping: undefined,
59
- oemNumberMapping: undefined,
60
- packageType: undefined,
61
- paymentPolicies: undefined,
62
- pricingModifier: undefined,
63
- returnPolicies: undefined,
64
- shippingLengthUnit: undefined,
65
- shippingWeightUnit: undefined,
66
- storePickupAllowed: undefined,
67
- },
68
- merchantLocationKey: undefined,
69
- name: '',
70
- storeId: 0,
71
- })
72
-
73
- let show = $state(false)
74
- let showAllOption = $state(true)
75
- let selectedStoreConfigRow = $state<EcommerceStoreConfig | null>(null)
76
-
77
- // If we had more than one ecommercepartner, this would change depending on selected partner id
78
- let selectedPartnerConfig = $derived(
79
- partnerConfigurationList.find(row => row.ecommercePartnerId === selectedEcommercePartnerId),
80
- )
81
- // Get the store rows from the partnerconfig row
82
- let selectedPartnerConfigStoreRows = $derived(selectedPartnerConfig?.defaults?.store || [])
83
-
84
- // Filter available ebay locations depending on whether we're adding or editing
85
- let availableLocations = $derived.by(() => {
86
- const configuredEbayLocations = selectedPartnerConfigStoreRows.map(row => row.merchantLocationKey)
87
- const isEditingExisting =
88
- selectedStoreConfigRow?.name !== null &&
89
- configuredEbayLocations.includes(selectedStoreConfigRow?.merchantLocationKey)
90
-
91
- if (isEditingExisting) {
92
- return ebayLocationList
93
- }
94
- return ebayLocationList.filter(location => !configuredEbayLocations.includes(location.ebayName))
95
- })
96
- // Filter available stores based on whether we're adding or editing existing
97
- let availableStores = $derived.by(() => {
98
- if (!selectedStoreConfigRow) return storeList
99
-
100
- // Get the IDs of already configured stores
101
- const configuredStoreIds = selectedPartnerConfigStoreRows.map(row => row.storeId)
102
- const isEditingExisting =
103
- selectedStoreConfigRow.storeId !== null && configuredStoreIds.includes(selectedStoreConfigRow.storeId)
104
-
105
- if (isEditingExisting) {
106
- return storeList
107
- }
108
- // If adding new, filter out already configured stores
109
- return storeList.filter(store => !configuredStoreIds.includes(store.storeId))
110
- })
111
-
112
- async function confirm() {
113
- if (!selectedStoreConfigRow || !selectedStoreConfigRow.storeId) return
114
-
115
- // TODO: Here I am regretting my decision to have JSON sub object business for this
116
- // Copy the store config data for uh state wackiness reasons?
117
- const storeConfigRowCopy = klona(selectedStoreConfigRow)
118
- // Copy the partner config row
119
- const partnerConfigCopy = klona(selectedPartnerConfig)
120
-
121
- // Copy the selectedParnterConfigStoreRows
122
- let updatedStoreRows = klona(selectedPartnerConfigStoreRows || [])
123
-
124
- // If empty, add storeConfigCopy
125
- if (updatedStoreRows.length === 0) {
126
- updatedStoreRows.push(storeConfigRowCopy)
127
- } else {
128
- const existingIndex = updatedStoreRows.findIndex(row => row.storeId === storeConfigRowCopy.storeId)
129
- if (existingIndex === -1) {
130
- updatedStoreRows.push(storeConfigRowCopy)
131
- } else {
132
- updatedStoreRows[existingIndex] = storeConfigRowCopy
133
- }
134
- }
135
- // Still possible to be missing defaults?
136
- if (partnerConfigCopy && partnerConfigCopy.defaults) {
137
- partnerConfigCopy.defaults.store = updatedStoreRows
138
- await partnerConfigurationChanged(partnerConfigCopy)
139
- }
140
- close()
141
- }
142
-
143
- function close() {
144
- selectedStoreConfigRow = newStoreConfig
145
- show = false
146
- }
147
-
148
- function editStoreConfigRow(row?: EcommerceStoreConfig) {
149
- // Set selected row
150
- selectedStoreConfigRow = klona(row || newStoreConfig)
151
-
152
- show = true
153
- }
154
-
155
- async function handleStoreDefaultsChange(newDefaults: EcommerceSharedDefaults) {
156
- // This function is called when the EcommerceDefaults component changes
157
- // The binding will automatically update selectedStoreConfigRow.defaults
158
- // Don't need to do anything here since we're not auto-saving, feels dumb having an empty method
159
- }
160
- </script>
161
-
162
- <div class="card-header">
163
- <h4 class="mb-0">{translate('ecommerce.configuration.storeConfiguration', 'Store Configuration')}</h4>
164
- <p class="text-muted mb-0">
165
- {translate('ecommerce.configuration.configureStoreLevelEbaySettings', 'Configure store level eBay settings')}
166
- </p>
167
- </div>
168
- <div class="card-body">
169
- <div class="mb-3">
170
- <Button
171
- outline
172
- color="success"
173
- size="sm"
174
- iconClass="plus"
175
- onclick={() => editStoreConfigRow()}
176
- disabled={false}
177
- >
178
- {translate('ecommerce.configuration.add', 'Add')}
179
- </Button>
180
- </div>
181
- {#if selectedPartnerConfigStoreRows.length}
182
- <Table
183
- rows={selectedPartnerConfigStoreRows}
184
- responsive
185
- stickyHeader
186
- parentClass="overflow-y-auto mh-400"
187
- columns={[
188
- { property: 'storeId', name: translate('ecommerce.configuration.storeId', 'Store ID') },
189
- { property: 'name', name: translate('ecommerce.configuration.storeName', 'Store Name') },
190
- { property: 'merchantLocationKey', name: translate('ecommerce.configuration.ebayLocation', 'Ebay Location') },
191
- { property: 'active', name: translate('ecommerce.configuration.active', 'Active') },
192
- ]}
193
- >
194
- {#snippet children({ row })}
195
- <tr
196
- onclick={() => editStoreConfigRow(row as EcommerceStoreConfig)}
197
- class="cursor-pointer"
198
- >
199
- <td property="storeId">{row.storeId}</td>
200
- <td property="name">{row.name}</td>
201
- <td property="merchantLocationKey">{row.merchantLocationKey}</td>
202
- <td property="active">{row.active}</td>
203
- </tr>
204
- {/snippet}
205
- </Table>
206
- {/if}
207
- </div>
208
-
209
- <Modal
210
- bind:show
211
- title={translate('ecommerce.configuration.addEditStoreDefaults', 'Add/Edit Store Defaults')}
212
- modalSize="lg"
213
- confirmButtonText={translate('ecommerce.configuration.save', 'Save')}
214
- cancelShown={true}
215
- {confirm}
216
- {close}
217
- >
218
- {#if selectedStoreConfigRow}
219
- <div class="card-body">
220
- <Checkbox
221
- label={translate('ecommerce.configuration.activeOnEbay', 'Active on eBay')}
222
- bind:checked={selectedStoreConfigRow.active}
223
- />
224
-
225
- <Select
226
- label={translate('ecommerce.configuration.store', 'Store')}
227
- showEmptyOption={showAllOption}
228
- emptyValue={null}
229
- emptyText={translate('ecommerce.configuration.selectStore', 'Select Store')}
230
- disabled={false}
231
- bind:value={selectedStoreConfigRow.storeId}
232
- >
233
- {#each availableStores as store}
234
- <option value={store.storeId}>{store.name}</option>
235
- {/each}
236
- </Select>
237
- {#if selectedStoreConfigRow.storeId}
238
- <Select
239
- label={translate('ecommerce.configuration.ebayLocation', 'Ebay Location')}
240
- showEmptyOption={showAllOption}
241
- emptyValue={null}
242
- emptyText={translate('ecommerce.configuration.selectLocation', 'Select Location')}
243
- disabled={false}
244
- bind:value={selectedStoreConfigRow.merchantLocationKey}
245
- >
246
- {#each availableLocations as location}
247
- <option value={location.ebayName}>{location.ebayName}</option>
248
- {/each}
249
- </Select>
250
- {/if}
251
- {#if selectedStoreConfigRow.merchantLocationKey}
252
- <EcommerceDefaults
253
- bind:defaults={selectedStoreConfigRow.defaults}
254
- {ebayPolicyList}
255
- {ecommerceConditionList}
256
- {partnerConfigurationList}
257
- defaultsChanged={handleStoreDefaultsChange}
258
- {selectedEcommercePartnerId}
259
- />
260
- {/if}
261
- </div>
262
- {/if}
263
- </Modal>
1
+ <script lang="ts">
2
+ import type { i18n } from 'i18next'
3
+
4
+ import { getContext } from 'svelte'
5
+ import Table from '@isoftdata/svelte-table'
6
+ import { klona } from 'klona'
7
+ import Modal from '@isoftdata/svelte-modal'
8
+ import Checkbox from '@isoftdata/svelte-checkbox'
9
+ import Button from '@isoftdata/svelte-button'
10
+ import Select from '@isoftdata/svelte-select'
11
+ import type {
12
+ EbayLocation,
13
+ EbayPolicy,
14
+ EcommerceCondition,
15
+ EcommercePartnerConfiguration,
16
+ EcommerceStoreConfig,
17
+ Store,
18
+ } from './utils.js'
19
+ import EcommerceDefaults from './EcommerceDefaults.svelte'
20
+
21
+ import { translate as defaultTranslate } from '@isoftdata/utility-string'
22
+ const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
23
+
24
+ interface Props {
25
+ ebayLocationList?: Array<EbayLocation>
26
+ ebayPolicyList?: Array<EbayPolicy>
27
+ ecommerceConditionList: Array<EcommerceCondition>
28
+ partnerConfigurationList?: Array<EcommercePartnerConfiguration>
29
+ selectedEcommercePartnerId: number
30
+ storeList: Array<Store>
31
+ partnerConfigurationChanged: (partnerConfig: EcommercePartnerConfiguration) => Promise<void>
32
+ }
33
+
34
+ let {
35
+ ebayLocationList = [],
36
+ ebayPolicyList = [],
37
+ ecommerceConditionList = [],
38
+ partnerConfigurationList = [],
39
+ selectedEcommercePartnerId,
40
+ storeList = [],
41
+ partnerConfigurationChanged,
42
+ }: Props = $props()
43
+
44
+ let newStoreConfig: EcommerceStoreConfig = Object.freeze({
45
+ active: true,
46
+ defaults: {
47
+ brandMapping: undefined,
48
+ conditionDescription: undefined,
49
+ conditionId: undefined,
50
+ fulfillmentPolicies: undefined,
51
+ fulfillmentTimeUnit: undefined,
52
+ fulfillmentTimeValue: undefined,
53
+ listingDescriptionTemplate: undefined,
54
+ listingDuration: undefined,
55
+ listingFormat: undefined,
56
+ listingTitleTemplate: undefined,
57
+ manufacturerPartNumberMapping: undefined,
58
+ oemNumberMapping: undefined,
59
+ packageType: undefined,
60
+ paymentPolicies: undefined,
61
+ pricingModifier: undefined,
62
+ returnPolicies: undefined,
63
+ shippingLengthUnit: undefined,
64
+ shippingWeightUnit: undefined,
65
+ storePickupAllowed: undefined,
66
+ },
67
+ merchantLocationKey: undefined,
68
+ name: '',
69
+ storeId: 0,
70
+ })
71
+
72
+ let show = $state(false)
73
+ let selectedStoreConfigRow = $state<EcommerceStoreConfig | null>(null)
74
+
75
+ // If we had more than one ecommercepartner, this would change depending on selected partner id
76
+ let selectedPartnerConfig = $derived(
77
+ partnerConfigurationList.find(row => row.ecommercePartnerId === selectedEcommercePartnerId),
78
+ )
79
+ // Get the store rows from the partnerconfig row
80
+ let selectedPartnerConfigStoreRows = $derived(selectedPartnerConfig?.defaults?.store || [])
81
+
82
+ // Filter available ebay locations depending on whether we're adding or editing
83
+ let availableLocations = $derived.by(() => {
84
+ const configuredEbayLocations = selectedPartnerConfigStoreRows.map(row => row.merchantLocationKey)
85
+ const isEditingExisting =
86
+ selectedStoreConfigRow?.name !== null &&
87
+ configuredEbayLocations.includes(selectedStoreConfigRow?.merchantLocationKey)
88
+
89
+ if (isEditingExisting) {
90
+ return ebayLocationList
91
+ }
92
+ return ebayLocationList.filter(location => !configuredEbayLocations.includes(location.ebayName))
93
+ })
94
+ // Filter available stores based on whether we're adding or editing existing
95
+ let availableStores = $derived.by(() => {
96
+ if (!selectedStoreConfigRow) return storeList
97
+
98
+ // Get the IDs of already configured stores
99
+ const configuredStoreIds = selectedPartnerConfigStoreRows.map(row => row.storeId)
100
+ const isEditingExisting =
101
+ selectedStoreConfigRow.storeId !== null && configuredStoreIds.includes(selectedStoreConfigRow.storeId)
102
+
103
+ if (isEditingExisting) {
104
+ return storeList
105
+ }
106
+ // If adding new, filter out already configured stores
107
+ return storeList.filter(store => !configuredStoreIds.includes(store.storeId))
108
+ })
109
+
110
+ async function confirm() {
111
+ if (!selectedStoreConfigRow || !selectedStoreConfigRow.storeId) return
112
+
113
+ // TODO: Here I am regretting my decision to have JSON sub object business for this
114
+ // Copy the store config data for uh state wackiness reasons?
115
+ const storeConfigRowCopy = klona(selectedStoreConfigRow)
116
+ // Copy the partner config row
117
+ const partnerConfigCopy = klona(selectedPartnerConfig)
118
+
119
+ // Copy the selectedParnterConfigStoreRows
120
+ let updatedStoreRows = klona(selectedPartnerConfigStoreRows)
121
+
122
+ // If empty, add storeConfigCopy
123
+ if (updatedStoreRows.length === 0) {
124
+ updatedStoreRows.push(storeConfigRowCopy)
125
+ } else {
126
+ const existingIndex = updatedStoreRows.findIndex(row => row.storeId === storeConfigRowCopy.storeId)
127
+ if (existingIndex === -1) {
128
+ updatedStoreRows.push(storeConfigRowCopy)
129
+ } else {
130
+ updatedStoreRows[existingIndex] = storeConfigRowCopy
131
+ }
132
+ }
133
+ // Still possible to be missing defaults?
134
+ if (partnerConfigCopy && partnerConfigCopy.defaults) {
135
+ partnerConfigCopy.defaults.store = updatedStoreRows
136
+ await partnerConfigurationChanged(partnerConfigCopy)
137
+ }
138
+ close()
139
+ }
140
+
141
+ function close() {
142
+ selectedStoreConfigRow = newStoreConfig
143
+ show = false
144
+ }
145
+
146
+ function editStoreConfigRow(row?: EcommerceStoreConfig) {
147
+ // Set selected row
148
+ selectedStoreConfigRow = klona(row || newStoreConfig)
149
+
150
+ show = true
151
+ }
152
+ </script>
153
+
154
+ <div class="card">
155
+ <div class="card-header">
156
+ <h4 class="mb-0">{translate('ecommerce.configuration.storeConfiguration', 'Store Configuration')}</h4>
157
+ <p class="text-muted mb-0">
158
+ {translate('ecommerce.configuration.configureStoreLevelEbaySettings', 'Configure store level eBay settings')}
159
+ </p>
160
+ </div>
161
+ <div class="card-body">
162
+ {#if selectedPartnerConfigStoreRows.length}
163
+ <Table
164
+ rows={selectedPartnerConfigStoreRows}
165
+ responsive
166
+ stickyHeader
167
+ parentClass="overflow-y-auto mh-400"
168
+ columns={[
169
+ { property: 'storeId', name: translate('ecommerce.configuration.storeId', 'Store ID') },
170
+ { property: 'name', name: translate('ecommerce.configuration.storeName', 'Store Name') },
171
+ { property: 'merchantLocationKey', name: translate('ecommerce.configuration.ebayLocation', 'Ebay Location') },
172
+ { property: 'active', name: translate('ecommerce.configuration.active', 'Active') },
173
+ ]}
174
+ >
175
+ {#snippet children({ row })}
176
+ <tr
177
+ onclick={() => editStoreConfigRow(row)}
178
+ style="cursor: pointer;"
179
+ >
180
+ <td property="storeId">{row.storeId}</td>
181
+ <td property="name">{row.name}</td>
182
+ <td property="merchantLocationKey">{row.merchantLocationKey}</td>
183
+ <td property="active">{row.active}</td>
184
+ </tr>
185
+ {/snippet}
186
+ </Table>
187
+ {/if}
188
+ </div>
189
+ <div class="card-footer">
190
+ <Button
191
+ outline
192
+ color="success"
193
+ size="sm"
194
+ icon="plus"
195
+ onclick={() => editStoreConfigRow()}
196
+ >
197
+ {translate('common:add', 'Add')}...
198
+ </Button>
199
+ </div>
200
+ </div>
201
+ <Modal
202
+ bind:show
203
+ title={translate('ecommerce.configuration.addEditStoreDefaults', 'Add/Edit Store Defaults')}
204
+ modalSize="lg"
205
+ confirmButtonText={translate('ecommerce.configuration.save', 'Save')}
206
+ cancelShown
207
+ {confirm}
208
+ {close}
209
+ >
210
+ {#if selectedStoreConfigRow}
211
+ <div class="card-body">
212
+ <Checkbox
213
+ label={translate('ecommerce.configuration.activeOnEbay', 'Active on eBay')}
214
+ bind:checked={selectedStoreConfigRow.active}
215
+ />
216
+
217
+ <Select
218
+ label={translate('ecommerce.configuration.store', 'Store')}
219
+ emptyText="-- {translate('ecommerce.configuration.selectStore', 'Select Store')} --"
220
+ bind:value={selectedStoreConfigRow.storeId}
221
+ >
222
+ {#each availableStores as store}
223
+ <option value={store.storeId}>{store.name}</option>
224
+ {/each}
225
+ </Select>
226
+ {#if selectedStoreConfigRow.storeId}
227
+ <Select
228
+ label={translate('ecommerce.configuration.ebayLocation', 'Ebay Location')}
229
+ emptyText="-- {translate('ecommerce.configuration.selectLocation', 'Select Location')} --"
230
+ bind:value={selectedStoreConfigRow.merchantLocationKey}
231
+ >
232
+ {#each availableLocations as location}
233
+ <option value={location.ebayName}>{location.ebayName}</option>
234
+ {/each}
235
+ </Select>
236
+ {/if}
237
+ {#if selectedStoreConfigRow.merchantLocationKey}
238
+ <EcommerceDefaults
239
+ bind:defaults={selectedStoreConfigRow.defaults}
240
+ {ebayPolicyList}
241
+ {ecommerceConditionList}
242
+ {partnerConfigurationList}
243
+ {selectedEcommercePartnerId}
244
+ />
245
+ {/if}
246
+ </div>
247
+ {/if}
248
+ </Modal>
@@ -1,11 +1,11 @@
1
1
  import type { EbayLocation, EbayPolicy, EcommerceCondition, EcommercePartnerConfiguration, Store } from './utils.js';
2
2
  interface Props {
3
- ebayLocationList?: EbayLocation[];
4
- ebayPolicyList?: EbayPolicy[];
5
- ecommerceConditionList: EcommerceCondition[];
6
- partnerConfigurationList?: EcommercePartnerConfiguration[];
3
+ ebayLocationList?: Array<EbayLocation>;
4
+ ebayPolicyList?: Array<EbayPolicy>;
5
+ ecommerceConditionList: Array<EcommerceCondition>;
6
+ partnerConfigurationList?: Array<EcommercePartnerConfiguration>;
7
7
  selectedEcommercePartnerId: number;
8
- storeList: Store[];
8
+ storeList: Array<Store>;
9
9
  partnerConfigurationChanged: (partnerConfig: EcommercePartnerConfiguration) => Promise<void>;
10
10
  }
11
11
  declare const EcommerceStoreConfiguration: import("svelte").Component<Props, {}, "">;