@isoftdata/svelte-ecommerce 1.0.0-beta.4 → 1.0.0-beta.6

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,192 +1,192 @@
1
- <script lang="ts">
2
- import type { i18n } from 'i18next'
3
- import { getContext } from 'svelte'
4
- import type { IndexedRowProps, UuidRowProps } from '@isoftdata/svelte-table'
5
-
6
- import Button from '@isoftdata/svelte-button'
7
- import Input from '@isoftdata/svelte-input'
8
- import Select from '@isoftdata/svelte-select'
9
- import Modal from '@isoftdata/svelte-modal'
10
- import { klona } from 'klona'
11
- import Table from '@isoftdata/svelte-table'
12
- import type {
13
- EcommerceCondition,
14
- EcommerceConditionMap,
15
- ExtendedEcommerceConditionMap,
16
- NewConditionMappingState,
17
- } from './utils.js'
18
-
19
- import { translate as defaultTranslate } from '@isoftdata/utility-string'
20
- const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
21
-
22
- interface SelectedEcommerceConditionMapRow extends EcommerceConditionMap, IndexedRowProps {}
23
-
24
- interface Props {
25
- ecommerceConditionMappingList: Array<ExtendedEcommerceConditionMap> // mapping between itrack and ebay conditions
26
- ecommerceConditionList: Array<EcommerceCondition>
27
- inventoryConditionList: Array<string> // unique conditions from inventory table
28
- conditionMapChanged: (data: EcommerceConditionMap) => Promise<void>
29
- }
30
-
31
- let {
32
- ecommerceConditionMappingList = $bindable([]),
33
- ecommerceConditionList = [],
34
- inventoryConditionList = [],
35
- conditionMapChanged = async (_: EcommerceConditionMap) => {},
36
- }: Props = $props()
37
-
38
- // New empty items
39
- let newConditionMapping: NewConditionMappingState = Object.freeze({
40
- itrackCondition: null,
41
- ecommerceConditionId: null,
42
- description: null,
43
- })
44
- // Local state
45
- let selectedEcommerceConditionMappingRow: SelectedEcommerceConditionMapRow | NewConditionMappingState =
46
- $state(newConditionMapping)
47
-
48
- let isEditingConditionMap = $state(false)
49
- let show = $state(false)
50
-
51
- let unmappedConditions = $derived(
52
- inventoryConditionList.filter(
53
- condition =>
54
- selectedEcommerceConditionMappingRow?.itrackCondition === condition ||
55
- !ecommerceConditionMappingList.some(mapping => mapping.itrackCondition === condition),
56
- ),
57
- )
58
-
59
- function editConditionMapRow(row?: ExtendedEcommerceConditionMap) {
60
- // Set selected row
61
- selectedEcommerceConditionMappingRow = klona(row || newConditionMapping)
62
-
63
- show = true
64
- }
65
-
66
- // Add function to convert condtion row to savable format
67
- function convertConditionToSavableFormat(
68
- row: SelectedEcommerceConditionMapRow | NewConditionMappingState,
69
- ): EcommerceConditionMap {
70
- // Handle the case where we have a NewConditionMappingState with null values
71
- if ('ecommerceConditionMapId' in row && row.ecommerceConditionMapId !== undefined) {
72
- // This is an existing record (EcommerceConditionMap or SelectedEcommerceConditionMapRow)
73
- return {
74
- ecommerceConditionMapId: row.ecommerceConditionMapId,
75
- ecommercePartnerId: row.ecommercePartnerId!,
76
- itrackCondition: row.itrackCondition!,
77
- ecommerceConditionId: row.ecommerceConditionId!,
78
- description: row.description || row.itrackCondition!,
79
- }
80
- } else {
81
- // This is a new record - we need to create it without the ID
82
- // The API will assign the ID when creating
83
- // TODO: is there a way to avoid 'any' here?
84
- const newMapping: any = {
85
- ecommercePartnerId: row.ecommercePartnerId || 0, // Default value, should be set by parent
86
- itrackCondition: row.itrackCondition!,
87
- ecommerceConditionId: row.ecommerceConditionId!,
88
- description: row.description || row.itrackCondition!,
89
- }
90
- return newMapping as EcommerceConditionMap
91
- }
92
- }
93
-
94
- async function confirm() {
95
- if (!selectedEcommerceConditionMappingRow) return
96
-
97
- const mappingToSave = convertConditionToSavableFormat(selectedEcommerceConditionMappingRow)
98
-
99
- await conditionMapChanged(mappingToSave)
100
- close()
101
- }
102
- function close() {
103
- // Reset related data and flags
104
- selectedEcommerceConditionMappingRow = newConditionMapping
105
- show = false
106
- }
107
- </script>
108
-
109
- <div class="card">
110
- <div class="card-header">
111
- <h4 class="mb-0">{translate('ecommerce.configuration.conditionMappings', 'Condition Mappings')}</h4>
112
- <p class="text-muted mb-0">
113
- {translate('ecommerce.configuration.mapConditionValues', 'Map condition values to eBay condition values')}
114
- </p>
115
- </div>
116
- <div class="card-body">
117
- <Table
118
- parentClass="overflow-y-auto mh-500"
119
- rows={ecommerceConditionMappingList}
120
- columns={[
121
- {
122
- property: 'itrackCondition',
123
- name: translate('ecommerce.configuration.itrackCondition', 'ITrack Condition'),
124
- defaultSortColumn: true,
125
- },
126
- { property: 'name', name: translate('ecommerce.configuration.ebayCondition', 'Ebay Condition') },
127
- {
128
- property: 'description',
129
- name: translate('ecommerce.configuration.conditionDescription', 'Condition Description'),
130
- },
131
- ]}
132
- stickyHeader
133
- responsive
134
- >
135
- {#snippet children({ row })}
136
- <tr
137
- onclick={() => editConditionMapRow(row as ExtendedEcommerceConditionMap)}
138
- style="cursor: pointer;"
139
- >
140
- <td>{row.itrackCondition}</td>
141
- <td>{row.name}</td>
142
- <td>{row.description}</td>
143
- </tr>
144
- {/snippet}
145
- </Table>
146
- </div>
147
- <div class="card-footer">
148
- <Button
149
- outline
150
- color="success"
151
- size="sm"
152
- iconClass="plus"
153
- onclick={() => editConditionMapRow()}
154
- disabled={isEditingConditionMap}
155
- >
156
- {translate('common:add', 'Add')}...
157
- </Button>
158
- </div>
159
- </div>
160
- <Modal
161
- bind:show
162
- title={translate('ecommerce.configuration.addEditConditionMapping', 'Add/Edit New Condition Mapping')}
163
- modalSize="lg"
164
- confirmButtonText={translate('ecommerce.configuration.save', 'Save')}
165
- cancelShown
166
- {confirm}
167
- {close}
168
- >
169
- <Select
170
- label={translate('ecommerce.configuration.itrackCondition', 'ITrack Condition')}
171
- emptyText="-- {translate('ecommerce.configuration.selectCondition', 'Select Condition')} --"
172
- bind:value={selectedEcommerceConditionMappingRow.itrackCondition}
173
- >
174
- {#each unmappedConditions as itrackCondition}
175
- <option value={itrackCondition}>{itrackCondition}</option>
176
- {/each}
177
- </Select>
178
- <Select
179
- label={translate('ecommerce.configuration.ecommerceCondition', 'Ecommerce Condition')}
180
- emptyText="-- {translate('ecommerce.configuration.selectCondition', 'Select Condition')} --"
181
- bind:value={selectedEcommerceConditionMappingRow.ecommerceConditionId}
182
- >
183
- {#each ecommerceConditionList as ecommerceCondition}
184
- <option value={ecommerceCondition.ecommerceConditionId ?? null}>{ecommerceCondition.name}</option>
185
- {/each}
186
- </Select>
187
- <Input
188
- label={translate('ecommerce.configuration.conditionDescription', 'Condition Description')}
189
- maxlength={1000}
190
- bind:value={selectedEcommerceConditionMappingRow.description}
191
- />
192
- </Modal>
1
+ <script lang="ts">
2
+ import type { i18n } from 'i18next'
3
+ import { getContext } from 'svelte'
4
+ import type { IndexedRowProps, UuidRowProps } from '@isoftdata/svelte-table'
5
+
6
+ import Button from '@isoftdata/svelte-button'
7
+ import Input from '@isoftdata/svelte-input'
8
+ import Select from '@isoftdata/svelte-select'
9
+ import Modal from '@isoftdata/svelte-modal'
10
+ import { klona } from 'klona'
11
+ import Table from '@isoftdata/svelte-table'
12
+ import type {
13
+ EcommerceCondition,
14
+ EcommerceConditionMap,
15
+ ExtendedEcommerceConditionMap,
16
+ NewConditionMappingState,
17
+ } from './utils.js'
18
+
19
+ import { translate as defaultTranslate } from '@isoftdata/utility-string'
20
+ const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
21
+
22
+ interface SelectedEcommerceConditionMapRow extends EcommerceConditionMap, IndexedRowProps {}
23
+
24
+ interface Props {
25
+ ecommerceConditionMappingList: Array<ExtendedEcommerceConditionMap> // mapping between itrack and ebay conditions
26
+ ecommerceConditionList: Array<EcommerceCondition>
27
+ inventoryConditionList: Array<string> // unique conditions from inventory table
28
+ conditionMapChanged: (data: EcommerceConditionMap) => Promise<void>
29
+ }
30
+
31
+ let {
32
+ ecommerceConditionMappingList = $bindable([]),
33
+ ecommerceConditionList = [],
34
+ inventoryConditionList = [],
35
+ conditionMapChanged = async (_: EcommerceConditionMap) => {},
36
+ }: Props = $props()
37
+
38
+ // New empty items
39
+ let newConditionMapping: NewConditionMappingState = Object.freeze({
40
+ itrackCondition: null,
41
+ ecommerceConditionId: null,
42
+ description: null,
43
+ })
44
+ // Local state
45
+ let selectedEcommerceConditionMappingRow: SelectedEcommerceConditionMapRow | NewConditionMappingState =
46
+ $state(newConditionMapping)
47
+
48
+ let isEditingConditionMap = $state(false)
49
+ let show = $state(false)
50
+
51
+ let unmappedConditions = $derived(
52
+ inventoryConditionList.filter(
53
+ condition =>
54
+ selectedEcommerceConditionMappingRow?.itrackCondition === condition ||
55
+ !ecommerceConditionMappingList.some(mapping => mapping.itrackCondition === condition),
56
+ ),
57
+ )
58
+
59
+ function editConditionMapRow(row?: ExtendedEcommerceConditionMap) {
60
+ // Set selected row
61
+ selectedEcommerceConditionMappingRow = klona(row || newConditionMapping)
62
+
63
+ show = true
64
+ }
65
+
66
+ // Add function to convert condtion row to savable format
67
+ function convertConditionToSavableFormat(
68
+ row: SelectedEcommerceConditionMapRow | NewConditionMappingState,
69
+ ): EcommerceConditionMap {
70
+ // Handle the case where we have a NewConditionMappingState with null values
71
+ if ('ecommerceConditionMapId' in row && row.ecommerceConditionMapId !== undefined) {
72
+ // This is an existing record (EcommerceConditionMap or SelectedEcommerceConditionMapRow)
73
+ return {
74
+ ecommerceConditionMapId: row.ecommerceConditionMapId,
75
+ ecommercePartnerId: row.ecommercePartnerId!,
76
+ itrackCondition: row.itrackCondition!,
77
+ ecommerceConditionId: row.ecommerceConditionId!,
78
+ description: row.description || row.itrackCondition!,
79
+ }
80
+ } else {
81
+ // This is a new record - we need to create it without the ID
82
+ // The API will assign the ID when creating
83
+ // TODO: is there a way to avoid 'any' here?
84
+ const newMapping: any = {
85
+ ecommercePartnerId: row.ecommercePartnerId || 0, // Default value, should be set by parent
86
+ itrackCondition: row.itrackCondition!,
87
+ ecommerceConditionId: row.ecommerceConditionId!,
88
+ description: row.description || row.itrackCondition!,
89
+ }
90
+ return newMapping as EcommerceConditionMap
91
+ }
92
+ }
93
+
94
+ async function confirm() {
95
+ if (!selectedEcommerceConditionMappingRow) return
96
+
97
+ const mappingToSave = convertConditionToSavableFormat(selectedEcommerceConditionMappingRow)
98
+
99
+ await conditionMapChanged(mappingToSave)
100
+ close()
101
+ }
102
+ function close() {
103
+ // Reset related data and flags
104
+ selectedEcommerceConditionMappingRow = newConditionMapping
105
+ show = false
106
+ }
107
+ </script>
108
+
109
+ <div class="card">
110
+ <div class="card-header">
111
+ <h4 class="mb-0">{translate('ecommerce.configuration.conditionMappings', 'Condition Mappings')}</h4>
112
+ <p class="text-muted mb-0">
113
+ {translate('ecommerce.configuration.mapConditionValues', 'Map condition values to eBay condition values')}
114
+ </p>
115
+ </div>
116
+ <div class="card-body">
117
+ <Table
118
+ parentClass="overflow-y-auto mh-500"
119
+ rows={ecommerceConditionMappingList}
120
+ columns={[
121
+ {
122
+ property: 'itrackCondition',
123
+ name: translate('ecommerce.configuration.itrackCondition', 'ITrack Condition'),
124
+ defaultSortColumn: true,
125
+ },
126
+ { property: 'name', name: translate('ecommerce.configuration.ebayCondition', 'Ebay Condition') },
127
+ {
128
+ property: 'description',
129
+ name: translate('ecommerce.configuration.conditionDescription', 'Condition Description'),
130
+ },
131
+ ]}
132
+ stickyHeader
133
+ responsive
134
+ >
135
+ {#snippet children({ row })}
136
+ <tr
137
+ onclick={() => editConditionMapRow(row as ExtendedEcommerceConditionMap)}
138
+ style="cursor: pointer;"
139
+ >
140
+ <td>{row.itrackCondition}</td>
141
+ <td>{row.name}</td>
142
+ <td>{row.description}</td>
143
+ </tr>
144
+ {/snippet}
145
+ </Table>
146
+ </div>
147
+ <div class="card-footer">
148
+ <Button
149
+ outline
150
+ color="success"
151
+ size="sm"
152
+ iconClass="plus"
153
+ onclick={() => editConditionMapRow()}
154
+ disabled={isEditingConditionMap}
155
+ >
156
+ {translate('common:add', 'Add')}...
157
+ </Button>
158
+ </div>
159
+ </div>
160
+ <Modal
161
+ bind:show
162
+ title={translate('ecommerce.configuration.addEditConditionMapping', 'Add/Edit New Condition Mapping')}
163
+ modalSize="lg"
164
+ confirmButtonText={translate('ecommerce.configuration.save', 'Save')}
165
+ cancelShown
166
+ {confirm}
167
+ {close}
168
+ >
169
+ <Select
170
+ label={translate('ecommerce.configuration.itrackCondition', 'ITrack Condition')}
171
+ emptyText="-- {translate('ecommerce.configuration.selectCondition', 'Select Condition')} --"
172
+ bind:value={selectedEcommerceConditionMappingRow.itrackCondition}
173
+ >
174
+ {#each unmappedConditions as itrackCondition}
175
+ <option value={itrackCondition}>{itrackCondition}</option>
176
+ {/each}
177
+ </Select>
178
+ <Select
179
+ label={translate('ecommerce.configuration.ecommerceCondition', 'Ecommerce Condition')}
180
+ emptyText="-- {translate('ecommerce.configuration.selectCondition', 'Select Condition')} --"
181
+ bind:value={selectedEcommerceConditionMappingRow.ecommerceConditionId}
182
+ >
183
+ {#each ecommerceConditionList as ecommerceCondition}
184
+ <option value={ecommerceCondition.ecommerceConditionId ?? null}>{ecommerceCondition.name}</option>
185
+ {/each}
186
+ </Select>
187
+ <Input
188
+ label={translate('ecommerce.configuration.conditionDescription', 'Condition Description')}
189
+ maxlength={1000}
190
+ bind:value={selectedEcommerceConditionMappingRow.description}
191
+ />
192
+ </Modal>