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

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