This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
.provider-mapping-step {
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.provider-mapping-step__intro {
|
||||
margin: var(--space-2) 0 0;
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import ProviderMappingStep from './ProviderMappingStep.vue';
|
||||
|
||||
export default { title: 'Molecules/ProviderMappingStep', component: ProviderMappingStep };
|
||||
|
||||
export const Empty = {
|
||||
args: {
|
||||
productId: '', providerId: '', mappingType: 'PRODUCT', externalIdentifier: '', searchQuery: '',
|
||||
products: [{ id: 'product-1', name: 'Charizard ex #199/165' }],
|
||||
},
|
||||
};
|
||||
|
||||
export const SearchMapping = {
|
||||
args: {
|
||||
productId: 'product-1', providerId: 'ebay', mappingType: 'SEARCH', externalIdentifier: '', searchQuery: 'Charizard ex 199/165 near mint',
|
||||
products: [{ id: 'product-1', name: 'Charizard ex #199/165' }],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
productId: { type: String, required: true },
|
||||
providerId: { type: String, required: true },
|
||||
mappingType: { type: String, required: true },
|
||||
externalIdentifier: { type: String, required: true },
|
||||
searchQuery: { type: String, required: true },
|
||||
products: { type: Array, required: true },
|
||||
isSaving: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
defineEmits([
|
||||
'update:productId',
|
||||
'update:providerId',
|
||||
'update:mappingType',
|
||||
'update:externalIdentifier',
|
||||
'update:searchQuery',
|
||||
'product-change',
|
||||
'submit',
|
||||
]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form id="workflow-mapping" class="showcase-panel provider-mapping-step" @submit.prevent="$emit('submit')">
|
||||
<div>
|
||||
<p class="catalog-kicker">Step 2</p>
|
||||
<h2>Link Market Sources</h2>
|
||||
<p class="provider-mapping-step__intro">Connect a provider product or search so future copies can reuse the source.</p>
|
||||
</div>
|
||||
<label class="fixture-label" for="mapping-product">Product</label>
|
||||
<select
|
||||
id="mapping-product"
|
||||
:value="productId"
|
||||
class="fixture-input"
|
||||
required
|
||||
@change="$emit('update:productId', $event.target.value); $emit('product-change', $event.target.value)"
|
||||
>
|
||||
<option value="" disabled>Select a product</option>
|
||||
<option v-for="product in products" :key="product.id" :value="product.id">
|
||||
{{ product.name }}
|
||||
</option>
|
||||
</select>
|
||||
<label class="fixture-label" for="mapping-provider">Provider ID</label>
|
||||
<input id="mapping-provider" :value="providerId" class="fixture-input" required placeholder="ebay" @input="$emit('update:providerId', $event.target.value)" />
|
||||
<label class="fixture-label" for="mapping-type">Mapping type</label>
|
||||
<select id="mapping-type" :value="mappingType" class="fixture-input" @change="$emit('update:mappingType', $event.target.value)">
|
||||
<option value="PRODUCT">Product</option>
|
||||
<option value="SEARCH">Search</option>
|
||||
</select>
|
||||
<label class="fixture-label" for="mapping-external">External identifier</label>
|
||||
<input id="mapping-external" :value="externalIdentifier" class="fixture-input" @input="$emit('update:externalIdentifier', $event.target.value)" />
|
||||
<label class="fixture-label" for="mapping-query">Search query</label>
|
||||
<input id="mapping-query" :value="searchQuery" class="fixture-input" @input="$emit('update:searchQuery', $event.target.value)" />
|
||||
<button class="button button--primary" type="submit" :disabled="isSaving">Save provider mapping</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use './ProviderMappingStep.scss';
|
||||
</style>
|
||||
@@ -6,6 +6,7 @@ import { useAuth } from "@/composables/useAuth.js";
|
||||
import AdminListingStatus from "@/components/molecules/AdminListingStatus.vue";
|
||||
import InventoryWorkflowStepper from "@/components/molecules/InventoryWorkflowStepper.vue";
|
||||
import ProductIdentityStep from "@/components/molecules/ProductIdentityStep.vue";
|
||||
import ProviderMappingStep from "@/components/molecules/ProviderMappingStep.vue";
|
||||
import {
|
||||
createAdminInventory,
|
||||
createAdminProduct,
|
||||
@@ -685,60 +686,22 @@ onMounted(load);
|
||||
@update:category-id="categoryId = $event"
|
||||
@submit="createProduct"
|
||||
/>
|
||||
<form id="workflow-mapping" class="showcase-panel" @submit.prevent="createProviderMapping">
|
||||
<h2>Link provider mapping</h2>
|
||||
<label class="fixture-label" for="mapping-product">Product</label>
|
||||
<select
|
||||
id="mapping-product"
|
||||
v-model="mappingProductId"
|
||||
class="fixture-input"
|
||||
required
|
||||
@change="loadProviderMappings()"
|
||||
>
|
||||
<option value="" disabled>Select a product</option>
|
||||
<option
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:value="product.id"
|
||||
>
|
||||
{{ product.name }}
|
||||
</option>
|
||||
</select>
|
||||
<label class="fixture-label" for="mapping-provider">Provider ID</label>
|
||||
<input
|
||||
id="mapping-provider"
|
||||
v-model="mappingProviderId"
|
||||
class="fixture-input"
|
||||
required
|
||||
placeholder="ebay"
|
||||
<ProviderMappingStep
|
||||
:product-id="mappingProductId"
|
||||
:provider-id="mappingProviderId"
|
||||
:mapping-type="mappingType"
|
||||
:external-identifier="mappingExternalIdentifier"
|
||||
:search-query="mappingSearchQuery"
|
||||
:products="products"
|
||||
:is-saving="isSaving"
|
||||
@update:product-id="mappingProductId = $event"
|
||||
@update:provider-id="mappingProviderId = $event"
|
||||
@update:mapping-type="mappingType = $event"
|
||||
@update:external-identifier="mappingExternalIdentifier = $event"
|
||||
@update:search-query="mappingSearchQuery = $event"
|
||||
@product-change="loadProviderMappings($event)"
|
||||
@submit="createProviderMapping"
|
||||
/>
|
||||
<label class="fixture-label" for="mapping-type">Mapping type</label>
|
||||
<select id="mapping-type" v-model="mappingType" class="fixture-input">
|
||||
<option value="PRODUCT">Product</option>
|
||||
<option value="SEARCH">Search</option>
|
||||
</select>
|
||||
<label class="fixture-label" for="mapping-external"
|
||||
>External identifier</label
|
||||
>
|
||||
<input
|
||||
id="mapping-external"
|
||||
v-model="mappingExternalIdentifier"
|
||||
class="fixture-input"
|
||||
/>
|
||||
<label class="fixture-label" for="mapping-query">Search query</label>
|
||||
<input
|
||||
id="mapping-query"
|
||||
v-model="mappingSearchQuery"
|
||||
class="fixture-input"
|
||||
/>
|
||||
<button
|
||||
class="button button--primary"
|
||||
type="submit"
|
||||
:disabled="isSaving"
|
||||
>
|
||||
Save provider mapping
|
||||
</button>
|
||||
</form>
|
||||
<form id="workflow-inventory" class="showcase-panel" @submit.prevent="createInventory">
|
||||
<h2>Add inventory copy</h2>
|
||||
<label class="fixture-label" for="inventory-product">Product</label>
|
||||
|
||||
@@ -168,6 +168,7 @@ Remaining roadmap areas are approved external provider credentials/adapters, bro
|
||||
- Public catalog filtering now supports explicit Available, Pending, Sold, and All status modes plus a 30-day Newly added toggle through the shared search API and atomic controls.
|
||||
- The admin workspace now includes a responsive guided inventory workflow stepper linking Product, Sources, Copy, Images, Pricing, and List stages, with progress derived from loaded admin state.
|
||||
- Product identification is now an extracted `ProductIdentityStep` molecule with empty/filled Storybook states, while preserving the existing create-product API workflow.
|
||||
- Source mapping is now an extracted `ProviderMappingStep` molecule with Product/Provider/PRODUCT-vs-SEARCH mapping states, while preserving existing mapping loading and save behavior.
|
||||
- Public catalog sorting now supports latest manual/calculated market value low-to-high and high-to-low, with null values placed last.
|
||||
- Public catalog filters now collapse behind an accessible mobile disclosure, show an active-filter count, and provide a reset action while preserving URL synchronization.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user