@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.
package/README.md CHANGED
@@ -1,58 +1,56 @@
1
- # create-svelte
2
-
3
- Everything you need to build a Svelte library, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
4
-
5
- Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
-
7
- ## Creating a project
8
-
9
- If you're seeing this, you've probably already done this step. Congrats!
10
-
11
- ```bash
12
- # create a new project in the current directory
13
- npx sv create
14
-
15
- # create a new project in my-app
16
- npx sv create my-app
17
- ```
18
-
19
- ## Developing
20
-
21
- Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
-
23
- ```bash
24
- npm run dev
25
-
26
- # or start the server and open the app in a new browser tab
27
- npm run dev -- --open
28
- ```
29
-
30
- Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
-
32
- ## Building
33
-
34
- To build your library:
35
-
36
- ```bash
37
- npm run package
38
- ```
39
-
40
- To create a production version of your showcase app:
41
-
42
- ```bash
43
- npm run build
44
- ```
45
-
46
- You can preview the production build with `npm run preview`.
47
-
48
- > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49
-
50
- ## Publishing
51
-
52
- Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53
-
54
- To publish your library to [npm](https://www.npmjs.com):
55
-
56
- ```bash
57
- npm publish
58
- ```
1
+ # @isoftdata/svelte-ecommerce
2
+
3
+ A Svelte 5 component library for e-commerce configuration and management.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @isoftdata/svelte-ecommerce
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```svelte
14
+ <script>
15
+ import { EcommerceConfiguration } from '@isoftdata/svelte-ecommerce'
16
+ </script>
17
+
18
+ <EcommerceConfiguration />
19
+ ```
20
+
21
+ ## Available Components
22
+
23
+ - `EcommerceConfiguration` - Main configuration component
24
+ - `EcommerceCategoryMapConfiguration` - Category mapping configuration
25
+ - `EcommerceConditionMapConfiguration` - Condition mapping configuration
26
+ - `EcommerceDefaults` - Default settings configuration
27
+ - `EcommerceListingDetails` - Listing details management
28
+ - `EcommercePartTypeConfig` - Part type configuration
29
+ - `EcommerceStoreConfiguration` - Store configuration
30
+ - `PolicyList` - Policy list management
31
+
32
+ ## Development
33
+
34
+ ```bash
35
+ # Install dependencies
36
+ pnpm install
37
+
38
+ # Start dev server
39
+ pnpm dev
40
+
41
+ # Preview
42
+ pnpm preview
43
+
44
+ # Build library
45
+ pnpm build
46
+
47
+ # Run linter
48
+ pnpm lint
49
+
50
+ # Format code
51
+ pnpm format
52
+ ```
53
+
54
+ ## License
55
+
56
+ MIT
@@ -1,266 +1,251 @@
1
- <script lang="ts">
2
- import type { i18n } from 'i18next'
3
-
4
- import { getContext } from 'svelte'
5
- import Select from '@isoftdata/svelte-select'
6
- import Table from '@isoftdata/svelte-table'
7
- import Button from '@isoftdata/svelte-button'
8
- import Modal from '@isoftdata/svelte-modal'
9
- import type {
10
- EbayCategory,
11
- EbayCategoryMap,
12
- ExtendedEbayCategoryMap,
13
- InventoryType,
14
- SelectedEbayCategoryMapRow,
15
- } from './utils.js'
16
- import klona from 'klona'
17
-
18
- import { translate as defaultTranslate } from '@isoftdata/utility-string'
19
-
20
- const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
21
-
22
- // Just ebay category map table columns
23
- interface Props {
24
- // Props
25
- ebayCategoryList: EbayCategory[] // ebay categories for mapping
26
- ebayCategoryMapList: ExtendedEbayCategoryMap[] // ebay category mappings for itrack categories
27
- inventoryTypeList?: InventoryType[] // inventory types for mapping
28
- selectedPartType?: number | null
29
- categoryMapChanged: (data: EbayCategoryMap) => Promise<void>
30
- selectedEcommerceCategoryMappingRow?: ExtendedEbayCategoryMap | SelectedEbayCategoryMapRow | null
31
- selectedEcommerceCategoryId?: number | null
32
- selectedEbayCategoryType?: string | null
33
- }
34
-
35
- let {
36
- ebayCategoryList = [],
37
- ebayCategoryMapList = $bindable([]),
38
- inventoryTypeList = [],
39
- categoryMapChanged = async (_: EbayCategoryMap) => {},
40
- }: Props = $props()
41
-
42
- // Local state
43
- let editItrackCategoryDisabled = $state(false) // for category mapping, if needed in futur
44
- let editEcommerceCategoryDisabled = false
45
- let isEditingCategoryMap = false
46
- let show = $state(false)
47
- let showAllOption = true
48
- let selectedEbayCategoryType: string | null = $state(null)
49
- let selectedEcommerceCategoryId: number | null = $state(null)
50
- let selectedEcommerceCategoryMappingRow: ExtendedEbayCategoryMap | SelectedEbayCategoryMapRow | null = $state(null)
51
- let selectedPartType: number | null = $state(null) // used in category map config component
52
-
53
- // New empty items
54
- let newCategoryMapping = {
55
- ebayCategoryId: null,
56
- ebayCategoryName: '',
57
- inventoryTypeName: null,
58
- }
59
-
60
- // TODO: saved inventory type doesn't get removed from dropdown after upsert/save
61
- async function confirm() {
62
- if (!selectedEcommerceCategoryMappingRow) return
63
-
64
- const mappingToSave = convertCategoryToSavableFormat(selectedEcommerceCategoryMappingRow)
65
- await categoryMapChanged(mappingToSave)
66
- close()
67
- }
68
-
69
- function close() {
70
- selectedEbayCategoryType = null
71
- selectedEcommerceCategoryId = null
72
- selectedEcommerceCategoryMappingRow = null
73
- selectedPartType = null
74
- show = false
75
- }
76
- function convertCategoryToSavableFormat(row: EbayCategoryMap | SelectedEbayCategoryMapRow): EbayCategoryMap {
77
- const mapping = {
78
- ebayCategoryId: selectedEcommerceCategoryId || row.ebayCategoryId,
79
- vehicleType: 'Car', // Set a default so I stop getting TS warnings
80
- typeNum: selectedPartType || row.typeNum,
81
- }
82
-
83
- const matchingEbayCategoryName = ebayCategoryList.find(row => row.ebayCategoryId === mapping.ebayCategoryId)?.name
84
- if (matchingEbayCategoryName) {
85
- if (matchingEbayCategoryName.includes('Car')) {
86
- mapping.vehicleType = 'Car'
87
- } else if (matchingEbayCategoryName.includes('HeavyTruck')) {
88
- mapping.vehicleType = 'HeavyTruck'
89
- } else if (matchingEbayCategoryName.includes('MotorCycle')) {
90
- mapping.vehicleType = 'MotorCycle'
91
- }
92
- }
93
-
94
- return mapping
95
- }
96
-
97
- // Called on add/edit button click
98
- function editCategoryMapRow(row?: any) {
99
- // Set selected row
100
- selectedEcommerceCategoryMappingRow = klona(row || newCategoryMapping)
101
-
102
- // Update the selected values based on the row being edited
103
- if (row) {
104
- // Set the selectedItrackPartType to match the row's value
105
- selectedPartType = row.typeNum || ''
106
- selectedEcommerceCategoryId = row.ebayCategoryid
107
- // When editing an existing condition, you might want to disable editing the condition
108
- editItrackCategoryDisabled = true
109
- } else {
110
- // For new mappings, reset the selected values
111
- selectedPartType = null
112
- selectedEcommerceCategoryId = null
113
- editItrackCategoryDisabled = false
114
- }
115
- show = true // Show the category mapping edit form
116
- }
117
- // Function to extract unique middle segments from eBay category names
118
- function extractUniqueCategoryTypes(categories: Array<EbayCategory>): Array<string> {
119
- // Set to store unique segments
120
- const uniqueSegments = new Set<string>()
121
-
122
- // Process each category
123
- categories.forEach(category => {
124
- if (!category.name) return
125
- const parts = category.name.split('>')
126
- // Check if there are at least 3 parts (to have a middle segment)
127
- if (parts.length >= 3) {
128
- // Extract the middle segment (index 1) and trim whitespace
129
- const middleSegment = parts[1].trim()
130
- uniqueSegments.add(middleSegment)
131
- }
132
- })
133
-
134
- // Convert Set to Array and sort alphabetically
135
- return Array.from(uniqueSegments).sort()
136
- }
137
- // Inputs
138
-
139
- let filteredEbayCategoriesByType = $derived(
140
- ebayCategoryList.filter(
141
- category => category.name && (selectedEbayCategoryType ? category.name.includes(selectedEbayCategoryType) : true),
142
- ),
143
- )
144
- let uniqueCategoryTypes = $derived(extractUniqueCategoryTypes(ebayCategoryList))
145
- let unmappedPartTypes = $derived(
146
- inventoryTypeList.filter(
147
- partType =>
148
- // Include the part type if it's the one being edited or if it's not already mapped
149
- selectedEcommerceCategoryMappingRow?.inventoryTypeName === partType.name ||
150
- !ebayCategoryMapList.some(mapping => mapping.inventoryTypeName === partType.name),
151
- ),
152
- )
153
- </script>
154
-
155
- <div class="card-header">
156
- <h4 class="mb-0">{translate('configuration.ecommerce.categoryMappings', 'Category Mappings')}</h4>
157
- <p class="text-muted mb-0">
158
- {translate('configuration.ecommerce.categoryMappingsHint', 'Map part types to eBay Categories')}
159
- </p>
160
- </div>
161
- <div class="card-body">
162
- <div class="mb-3">
163
- <Button
164
- outline
165
- color="success"
166
- size="sm"
167
- iconClass="plus"
168
- onclick={() => editCategoryMapRow()}
169
- disabled={isEditingCategoryMap}
170
- >
171
- {translate('configuration.ecommerce.add', 'Add')}
172
- </Button>
173
- </div>
174
- <Table
175
- responsive
176
- stickyHeader
177
- rows={ebayCategoryMapList}
178
- parentClass="overflow-y-auto mh-500"
179
- columns={[
180
- {
181
- property: 'inventoryTypeName',
182
- name: translate('configuration.ecommerce.itrackInventoryType', 'Itrack InventoryType'),
183
- defaultSortColumn: true,
184
- },
185
- { property: 'ebayCategoryName', name: translate('configuration.ecommerce.ebayCategory', 'Ebay Category') },
186
- ]}
187
- >
188
- {#snippet children({ row })}
189
- <tr
190
- onclick={() => editCategoryMapRow(row)}
191
- class="cursor-pointer"
192
- >
193
- <td>{row.inventoryTypeName}</td>
194
- <td>{row.ebayCategoryName}</td>
195
- </tr>
196
- {/snippet}
197
- </Table>
198
- </div>
199
-
200
- <Modal
201
- bind:show
202
- title={translate('configuration.ecommerce.addEditCategoryMapping', 'Add/Edit New Category Mapping')}
203
- modalSize="lg"
204
- confirmButtonText={translate('configuration.ecommerce.save', 'save')}
205
- cancelShown={true}
206
- {confirm}
207
- {close}
208
- >
209
- <div class="card-header">
210
- <h4 class="mb-0">{translate('configuration.ecommerce.categoryMapping', 'Category Mapping')}</h4>
211
- </div>
212
- <div class="card-body">
213
- <Select
214
- label={translate('configuration.ecommerce.partType', 'Part Type')}
215
- showEmptyOption={showAllOption}
216
- emptyValue={null}
217
- emptyText={translate('configuration.ecommerce.selectType', 'Select Type')}
218
- disabled={editItrackCategoryDisabled}
219
- bind:value={selectedPartType}
220
- >
221
- {#each unmappedPartTypes as type}
222
- <option value={type.inventoryTypeId}>{type.inventoryTypeId} - {type.name}</option>
223
- {/each}
224
- {#if selectedEcommerceCategoryMappingRow && selectedEcommerceCategoryMappingRow.typeNum && !unmappedPartTypes.find(t => t.inventoryTypeId === selectedEcommerceCategoryMappingRow?.typeNum)}
225
- <option
226
- value={selectedEcommerceCategoryMappingRow.typeNum}
227
- selected
228
- >
229
- {selectedEcommerceCategoryMappingRow.typeNum} - {selectedEcommerceCategoryMappingRow.inventoryTypeName}
230
- </option>
231
- {/if}
232
- </Select>
233
- <!-- Dropdown for unique category segments -->
234
- <Select
235
- label={translate('ecommerce.configuration.categoryTypeFilter', 'Category Type Filter')}
236
- showEmptyOption={showAllOption}
237
- emptyValue={null}
238
- emptyText={translate('configuration.ecommerce.selectType', 'Select Type')}
239
- bind:value={selectedEbayCategoryType}
240
- >
241
- {#each uniqueCategoryTypes as type}
242
- <option value={type}>{type}</option>
243
- {/each}
244
- </Select>
245
- <Select
246
- label={translate('ecommerce.configuration.ebayCategory', 'Ebay Category')}
247
- showEmptyOption={showAllOption}
248
- emptyValue={null}
249
- emptyText={translate('configuration.ecommerce.selectCategory', 'Select Category')}
250
- disabled={editEcommerceCategoryDisabled}
251
- bind:value={selectedEcommerceCategoryId}
252
- >
253
- {#each filteredEbayCategoriesByType as category}
254
- <option value={category.ebayCategoryId}>{category.name}</option>
255
- {/each}
256
- {#if selectedEcommerceCategoryMappingRow && selectedEcommerceCategoryMappingRow.ebayCategoryId && !ebayCategoryList.find(t => t.ebayCategoryId === selectedEcommerceCategoryMappingRow?.ebayCategoryId)}
257
- <option
258
- value={selectedEcommerceCategoryMappingRow.ebayCategoryId}
259
- selected
260
- >
261
- {selectedEcommerceCategoryMappingRow.ebayCategoryName}
262
- </option>
263
- {/if}
264
- </Select>
265
- </div>
266
- </Modal>
1
+ <script lang="ts">
2
+ import type { i18n } from 'i18next'
3
+
4
+ import { getContext } from 'svelte'
5
+ import Select from '@isoftdata/svelte-select'
6
+ import Table from '@isoftdata/svelte-table'
7
+ import Button from '@isoftdata/svelte-button'
8
+ import Modal from '@isoftdata/svelte-modal'
9
+ import type { EbayCategory, EbayCategoryMap, ExtendedEbayCategoryMap, InventoryType } from './utils.js'
10
+ import type { IndexedRowProps } from '@isoftdata/svelte-table'
11
+ import { klona } from 'klona'
12
+
13
+ import { translate as defaultTranslate } from '@isoftdata/utility-string'
14
+
15
+ const { t: translate } = getContext<i18n>('i18next') || { t: defaultTranslate }
16
+
17
+ type SelectedEbayCategoryMapRow = ExtendedEbayCategoryMap & IndexedRowProps
18
+
19
+ // Just ebay category map table columns
20
+ interface Props {
21
+ // Props
22
+ ebayCategoryList: Array<EbayCategory> // ebay categories for mapping
23
+ ebayCategoryMapList: Array<ExtendedEbayCategoryMap> // ebay category mappings for itrack categories
24
+ inventoryTypeList?: Array<InventoryType> // inventory types for mapping
25
+ selectedPartType?: number | null
26
+ categoryMapChanged: (data: EbayCategoryMap) => Promise<void>
27
+ selectedEcommerceCategoryMappingRow?: ExtendedEbayCategoryMap | SelectedEbayCategoryMapRow | null
28
+ selectedEcommerceCategoryId?: number | null
29
+ selectedEbayCategoryType?: string | null
30
+ }
31
+
32
+ let {
33
+ ebayCategoryList = [],
34
+ ebayCategoryMapList = $bindable([]),
35
+ inventoryTypeList = [],
36
+ categoryMapChanged = async (_: EbayCategoryMap) => {},
37
+ }: Props = $props()
38
+
39
+ // Local state
40
+ let editITrackCategoryDisabled = $state(false) // for category mapping, if needed in future
41
+ let show = $state(false)
42
+ let selectedEbayCategoryType: string | null = $state(null)
43
+ let selectedEcommerceCategoryId: number | null = $state(null)
44
+ let selectedEcommerceCategoryMappingRow: ExtendedEbayCategoryMap | SelectedEbayCategoryMapRow | null = $state(null)
45
+ let selectedPartType: number | null = $state(null) // used in category map config component
46
+
47
+ // New empty items
48
+ let newCategoryMapping = {
49
+ ebayCategoryId: null,
50
+ ebayCategoryName: '',
51
+ inventoryTypeName: null,
52
+ }
53
+
54
+ // TODO: saved inventory type doesn't get removed from dropdown after upsert/save
55
+ async function confirm() {
56
+ if (!selectedEcommerceCategoryMappingRow) return
57
+
58
+ const mappingToSave = convertCategoryToSavableFormat(selectedEcommerceCategoryMappingRow)
59
+ await categoryMapChanged(mappingToSave)
60
+ close()
61
+ }
62
+
63
+ function close() {
64
+ selectedEbayCategoryType = null
65
+ selectedEcommerceCategoryId = null
66
+ selectedEcommerceCategoryMappingRow = null
67
+ selectedPartType = null
68
+ show = false
69
+ }
70
+ function convertCategoryToSavableFormat(row: EbayCategoryMap | SelectedEbayCategoryMapRow): EbayCategoryMap {
71
+ const mapping = {
72
+ ebayCategoryId: selectedEcommerceCategoryId || row.ebayCategoryId,
73
+ vehicleType: 'Car', // Set a default so I stop getting TS warnings
74
+ typeNum: selectedPartType || row.typeNum,
75
+ }
76
+
77
+ const matchingEbayCategoryName = ebayCategoryList.find(row => row.ebayCategoryId === mapping.ebayCategoryId)?.name
78
+ if (matchingEbayCategoryName) {
79
+ if (matchingEbayCategoryName.includes('Car')) {
80
+ mapping.vehicleType = 'Car'
81
+ } else if (matchingEbayCategoryName.includes('HeavyTruck')) {
82
+ mapping.vehicleType = 'HeavyTruck'
83
+ } else if (matchingEbayCategoryName.includes('MotorCycle')) {
84
+ mapping.vehicleType = 'MotorCycle'
85
+ }
86
+ }
87
+
88
+ return mapping
89
+ }
90
+
91
+ // Called on add/edit button click
92
+ function editCategoryMapRow(row?: any) {
93
+ // Set selected row
94
+ selectedEcommerceCategoryMappingRow = klona(row || newCategoryMapping)
95
+
96
+ // Update the selected values based on the row being edited
97
+ if (row) {
98
+ // Set the selectedITrackPartType to match the row's value
99
+ selectedPartType = row.typeNum || ''
100
+ selectedEcommerceCategoryId = row.ebayCategoryid
101
+ // When editing an existing condition, you might want to disable editing the condition
102
+ editITrackCategoryDisabled = true
103
+ } else {
104
+ // For new mappings, reset the selected values
105
+ selectedPartType = null
106
+ selectedEcommerceCategoryId = null
107
+ editITrackCategoryDisabled = false
108
+ }
109
+ show = true // Show the category mapping edit form
110
+ }
111
+ // Function to extract unique middle segments from eBay category names
112
+ function extractUniqueCategoryTypes(categories: Array<EbayCategory>): Array<string> {
113
+ // Set to store unique segments
114
+ const uniqueSegments = new Set<string>()
115
+
116
+ // Process each category
117
+ categories.forEach(category => {
118
+ if (!category.name) return
119
+ const parts = category.name.split('>')
120
+ // Check if there are at least 3 parts (to have a middle segment)
121
+ if (parts.length >= 3) {
122
+ // Extract the middle segment (index 1) and trim whitespace
123
+ const middleSegment = parts[1].trim()
124
+ uniqueSegments.add(middleSegment)
125
+ }
126
+ })
127
+
128
+ // Convert Set to Array and sort alphabetically
129
+ return Array.from(uniqueSegments).sort()
130
+ }
131
+ // Inputs
132
+
133
+ let filteredEbayCategoriesByType = $derived(
134
+ ebayCategoryList.filter(
135
+ category => category.name && (selectedEbayCategoryType ? category.name.includes(selectedEbayCategoryType) : true),
136
+ ),
137
+ )
138
+ let uniqueCategoryTypes = $derived(extractUniqueCategoryTypes(ebayCategoryList))
139
+ let unmappedPartTypes = $derived(
140
+ inventoryTypeList.filter(
141
+ partType =>
142
+ // Include the part type if it's the one being edited or if it's not already mapped
143
+ selectedEcommerceCategoryMappingRow?.inventoryTypeName === partType.name ||
144
+ !ebayCategoryMapList.some(mapping => mapping.inventoryTypeName === partType.name),
145
+ ),
146
+ )
147
+ </script>
148
+
149
+ <div class="card">
150
+ <div class="card-header">
151
+ <h4 class="mb-0">{translate('configuration.ecommerce.categoryMappings', 'Category Mappings')}</h4>
152
+ <p class="text-muted mb-0">
153
+ {translate('configuration.ecommerce.categoryMappingsHint', 'Map part types to eBay Categories')}
154
+ </p>
155
+ </div>
156
+ <div class="card-body">
157
+ <Table
158
+ responsive
159
+ stickyHeader
160
+ rows={ebayCategoryMapList}
161
+ parentClass="overflow-y-auto mh-500"
162
+ columns={[
163
+ {
164
+ property: 'inventoryTypeName',
165
+ name: translate('configuration.ecommerce.itrackInventoryType', '{{product}} Inventory Type', {
166
+ product: 'ITrack',
167
+ }),
168
+ defaultSortColumn: true,
169
+ },
170
+ { property: 'ebayCategoryName', name: translate('configuration.ecommerce.ebayCategory', 'Ebay Category') },
171
+ ]}
172
+ >
173
+ {#snippet children({ row })}
174
+ <tr
175
+ onclick={() => editCategoryMapRow(row)}
176
+ style="cursor: pointer;"
177
+ >
178
+ <td>{row.inventoryTypeName}</td>
179
+ <td>{row.ebayCategoryName}</td>
180
+ </tr>
181
+ {/snippet}
182
+ </Table>
183
+ </div>
184
+ <div class="card-footer">
185
+ <Button
186
+ outline
187
+ color="success"
188
+ size="sm"
189
+ iconClass="plus"
190
+ onclick={() => editCategoryMapRow()}
191
+ >
192
+ {translate('configuration.ecommerce.add', 'Add')}...
193
+ </Button>
194
+ </div>
195
+ </div>
196
+
197
+ <Modal
198
+ bind:show
199
+ title={translate('configuration.ecommerce.addEditCategoryMapping', 'Add/Edit New Category Mapping')}
200
+ modalSize="lg"
201
+ confirmButtonText={translate('configuration.ecommerce.save', 'save')}
202
+ cancelShown
203
+ {confirm}
204
+ {close}
205
+ >
206
+ <Select
207
+ label={translate('configuration.ecommerce.partType', 'Part Type')}
208
+ emptyText="-- {translate('configuration.ecommerce.selectType', 'Select Type')} --"
209
+ disabled={editITrackCategoryDisabled}
210
+ bind:value={selectedPartType}
211
+ >
212
+ {#each unmappedPartTypes as type}
213
+ <option value={type.inventoryTypeId}>{type.inventoryTypeId} - {type.name}</option>
214
+ {/each}
215
+ {#if selectedEcommerceCategoryMappingRow && selectedEcommerceCategoryMappingRow.typeNum && !unmappedPartTypes.find(t => t.inventoryTypeId === selectedEcommerceCategoryMappingRow?.typeNum)}
216
+ <option
217
+ value={selectedEcommerceCategoryMappingRow.typeNum}
218
+ selected
219
+ >
220
+ {selectedEcommerceCategoryMappingRow.typeNum} - {selectedEcommerceCategoryMappingRow.inventoryTypeName}
221
+ </option>
222
+ {/if}
223
+ </Select>
224
+ <!-- Dropdown for unique category segments -->
225
+ <Select
226
+ label={translate('ecommerce.configuration.categoryTypeFilter', 'Category Type Filter')}
227
+ emptyText="-- {translate('configuration.ecommerce.selectType', 'Select Type')} --"
228
+ bind:value={selectedEbayCategoryType}
229
+ >
230
+ {#each uniqueCategoryTypes as type}
231
+ <option value={type}>{type}</option>
232
+ {/each}
233
+ </Select>
234
+ <Select
235
+ label={translate('ecommerce.configuration.ebayCategory', 'Ebay Category')}
236
+ emptyText="-- {translate('configuration.ecommerce.selectCategory', 'Select Category')} --"
237
+ bind:value={selectedEcommerceCategoryId}
238
+ >
239
+ {#each filteredEbayCategoriesByType as category}
240
+ <option value={category.ebayCategoryId}>{category.name}</option>
241
+ {/each}
242
+ {#if selectedEcommerceCategoryMappingRow && selectedEcommerceCategoryMappingRow.ebayCategoryId && !ebayCategoryList.find(t => t.ebayCategoryId === selectedEcommerceCategoryMappingRow?.ebayCategoryId)}
243
+ <option
244
+ value={selectedEcommerceCategoryMappingRow.ebayCategoryId}
245
+ selected
246
+ >
247
+ {selectedEcommerceCategoryMappingRow.ebayCategoryName}
248
+ </option>
249
+ {/if}
250
+ </Select>
251
+ </Modal>