Skip to content

Commit ec1161f

Browse files
Merge pull request #572 from OneSila/development
Hotfix related usage count being pulled when it sohuldn't
2 parents 8ff0d7e + b8015f3 commit ec1161f

File tree

11 files changed

+254
-67
lines changed

11 files changed

+254
-67
lines changed

src/core/products/products/product-show/containers/tabs/variations/VariationsView.vue

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { ref, computed } from 'vue';
2+
import { ref, computed, watch, onMounted } from 'vue';
33
import { Product } from "../../../../configs";
44
import TabContentTemplate from "../TabContentTemplate.vue";
55
import { SearchConfig } from "../../../../../../../shared/components/organisms/general-search/searchConfig";
@@ -19,15 +19,19 @@ import VariationsEbayBulkEdit from "./containers/variations-ebay-bulk-edit/Varia
1919
import { useI18n } from 'vue-i18n';
2020
import Swal from 'sweetalert2';
2121
import { injectAuth } from "../../../../../../../shared/modules/auth";
22+
import { useRoute, useRouter } from "vue-router";
2223
2324
2425
const props = defineProps<{ product: Product }>();
2526
const { t } = useI18n();
2627
const auth = injectAuth();
28+
const route = useRoute();
29+
const router = useRouter();
2730
const ids = ref([]);
2831
const refetchNeeded = ref(false);
2932
type Mode = 'list' | 'editContent' | 'editProperties' | 'editPrices' | 'editImages' | 'editAmazon' | 'editShein' | 'editEbay' | 'editGeneral';
3033
const mode = ref<Mode>('list');
34+
const modeQueryKey = 'variationView';
3135
const bulkEditRef = ref<InstanceType<typeof VariationsBulkEdit> | null>(null);
3236
const contentEditRef = ref<InstanceType<typeof VariationsContentBulkEdit> | null>(null);
3337
const priceEditRef = ref<InstanceType<typeof VariationsPricesBulkEdit> | null>(null);
@@ -105,6 +109,7 @@ const tabs = computed<{ key: Mode; label: string; icon: string }[]>(() => {
105109
106110
return items;
107111
});
112+
const availableModes = computed<Mode[]>(() => tabs.value.map(tab => tab.key));
108113
109114
const searchConfig: SearchConfig = {
110115
search: true,
@@ -172,9 +177,86 @@ const changeMode = async (newMode: Mode) => {
172177
return;
173178
}
174179
}
175-
mode.value = newMode;
180+
181+
const normalizedMode = availableModes.value.includes(newMode) ? newMode : 'list';
182+
if (normalizedMode === mode.value) {
183+
return;
184+
}
185+
186+
mode.value = normalizedMode;
187+
await updateModeQuery(normalizedMode);
176188
};
177189
190+
const getModeFromQuery = (queryMode: unknown): Mode => {
191+
const candidate = Array.isArray(queryMode) ? queryMode[0] : queryMode;
192+
if (typeof candidate !== 'string') {
193+
return 'list';
194+
}
195+
196+
return availableModes.value.includes(candidate as Mode) ? candidate as Mode : 'list';
197+
};
198+
199+
const updateModeQuery = async (newMode: Mode, replace: boolean = false) => {
200+
if (route.query[modeQueryKey] === newMode) {
201+
return;
202+
}
203+
204+
const nextQuery = {
205+
...route.query,
206+
[modeQueryKey]: newMode,
207+
};
208+
209+
if (replace) {
210+
await router.replace({ query: nextQuery });
211+
return;
212+
}
213+
214+
await router.push({ query: nextQuery });
215+
};
216+
217+
onMounted(async () => {
218+
const initialMode = getModeFromQuery(route.query[modeQueryKey]);
219+
if (mode.value !== initialMode) {
220+
mode.value = initialMode;
221+
}
222+
223+
if (route.query[modeQueryKey] !== initialMode) {
224+
await updateModeQuery(initialMode, true);
225+
}
226+
});
227+
228+
watch(
229+
() => route.query[modeQueryKey],
230+
async (queryMode) => {
231+
const nextMode = getModeFromQuery(queryMode);
232+
if (nextMode === mode.value) {
233+
if (queryMode !== nextMode) {
234+
await updateModeQuery(nextMode, true);
235+
}
236+
return;
237+
}
238+
239+
const currentMode = mode.value;
240+
await changeMode(nextMode);
241+
242+
if (mode.value !== nextMode) {
243+
await updateModeQuery(currentMode, true);
244+
}
245+
}
246+
);
247+
248+
watch(
249+
availableModes,
250+
async () => {
251+
if (availableModes.value.includes(mode.value)) {
252+
return;
253+
}
254+
255+
mode.value = 'list';
256+
await updateModeQuery('list', true);
257+
}
258+
);
259+
178260
defineExpose({ hasUnsavedChanges });
179261
180262
</script>

src/core/properties/product-properties-rule/product-properties-rule-edit/ProductPropertiesRuleEditController.vue

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ import {PrimaryButton} from "../../../../shared/components/atoms/button-primary"
1212
import {SecondaryButton} from "../../../../shared/components/atoms/button-secondary";
1313
import {Toast} from "../../../../shared/modules/toast";
1414
import apolloClient from "../../../../../apollo-client";
15-
import { getProductPropertiesRuleQuery, productPropertiesRulesQuery } from "../../../../shared/api/queries/properties.js";
15+
import { getProductPropertiesRuleQuery, productPropertiesRulesWithUsageCountQuery } from "../../../../shared/api/queries/properties.js";
1616
import { completeCreateProductPropertiesRuleMutation, completeUpdateProductPropertiesRuleMutation, deleteProductPropertiesRuleMutation } from "../../../../shared/api/mutations/properties.js";
1717
import { integrationsQuery } from "../../../../shared/api/queries/integrations.js";
1818
import {DangerButton} from "../../../../shared/components/atoms/button-danger";
1919
import {FormType} from "../../../../shared/components/organisms/general-form/formConfig";
2020
import {ApolloAlertMutation} from "../../../../shared/components/molecules/apollo-alert-mutation";
2121
import { Property } from "../../../../shared/components/organisms/product-properties-configurator/ProductPropertiesConfigurator.vue";
22-
import {Loader} from "../../../../shared/components/atoms/loader";
2322
import {Link} from "../../../../shared/components/atoms/link";
2423
import {Button} from "../../../../shared/components/atoms/button";
24+
import { LocalLoader } from "../../../../shared/components/atoms/local-loader";
2525
import Swal, { SweetAlertOptions } from "sweetalert2";
2626
2727
interface Item {
@@ -55,7 +55,9 @@ const initialProductType = ref<{ id: string; value: string } | null>(null);
5555
const initialItems: Ref<Property[]> = ref([]);
5656
const updatedAddedProperties: Ref<Property[]> = ref([]);
5757
const propertiesItemsMap: Ref<Record<string, Item>> = ref({});
58-
const loading = ref(false);
58+
const integrationsLoading = ref(false);
59+
const rightLoading = ref(false);
60+
const saveLoading = ref(false);
5961
const requireEanCode = ref(false);
6062
const selectedSalesChannel = ref<'default' | string>('default');
6163
const previousSalesChannel = ref<'default' | string>('default');
@@ -76,6 +78,10 @@ const secondaryButtonLabel = computed(() =>
7678
t(currentRuleId.value ? 'shared.button.saveAndContinue' : 'shared.button.createAndContinue')
7779
);
7880
81+
const disableActions = computed(() =>
82+
integrationsLoading.value || rightLoading.value || saveLoading.value
83+
);
84+
7985
const getCacheKey = (salesChannelId: string | null | undefined) =>
8086
salesChannelId ?? 'default';
8187
@@ -207,7 +213,7 @@ const fetchRuleBySalesChannel = async (channelKey: string): Promise<RuleCacheEnt
207213
}
208214
209215
const { data } = await apolloClient.query({
210-
query: productPropertiesRulesQuery,
216+
query: productPropertiesRulesWithUsageCountQuery,
211217
variables: { filter, first: 1 },
212218
fetchPolicy: 'network-only',
213219
});
@@ -233,6 +239,7 @@ const ensureDefaultRule = async () => {
233239
};
234240
235241
const loadSalesChannels = async () => {
242+
integrationsLoading.value = true;
236243
try {
237244
const { data } = await apolloClient.query({ query: integrationsQuery, fetchPolicy: 'cache-first' });
238245
const nodes = data?.integrations?.edges?.map((edge: any) => edge.node) ?? [];
@@ -263,6 +270,8 @@ const loadSalesChannels = async () => {
263270
rawSalesChannels.value = Array.from(optionsMap.values());
264271
} catch (_error) {
265272
rawSalesChannels.value = [...rawSalesChannels.value];
273+
} finally {
274+
integrationsLoading.value = false;
266275
}
267276
};
268277
@@ -322,6 +331,10 @@ const hasUnsavedChanges = computed(() => {
322331
});
323332
324333
const handleSalesChannelUpdated = async (newValue: string) => {
334+
if (disableActions.value) {
335+
return;
336+
}
337+
325338
const normalizedValue = newValue && newValue !== '' ? newValue : 'default';
326339
327340
if (normalizedValue === selectedSalesChannel.value) {
@@ -362,7 +375,8 @@ const handleSalesChannelUpdated = async (newValue: string) => {
362375
selectedSalesChannel.value = normalizedValue;
363376
previousSalesChannel.value = normalizedValue;
364377
365-
loading.value = true;
378+
integrationsLoading.value = true;
379+
rightLoading.value = true;
366380
try {
367381
let entry: RuleCacheEntry | null = rulesCache.value[normalizedValue] ?? null;
368382
if (!entry) {
@@ -404,7 +418,8 @@ const handleSalesChannelUpdated = async (newValue: string) => {
404418
await updateRouteId(entry.id);
405419
}
406420
} finally {
407-
loading.value = false;
421+
integrationsLoading.value = false;
422+
rightLoading.value = false;
408423
}
409424
};
410425
@@ -467,7 +482,7 @@ const persistRule = async (): Promise<RuleCacheEntry | null> => {
467482
};
468483
469484
const fetchData = async () => {
470-
loading.value = true;
485+
rightLoading.value = true;
471486
propertiesItemsMap.value = {};
472487
initialItems.value = [];
473488
updatedAddedProperties.value = [];
@@ -497,33 +512,41 @@ const fetchData = async () => {
497512
await ensureDefaultRule();
498513
}
499514
} finally {
500-
loading.value = false;
515+
rightLoading.value = false;
501516
}
502517
};
503518
504519
const handleSave = () => saveMutations(false);
505520
const handleSaveAndContinue = () => saveMutations(true);
506521
const saveMutations = async (continueEditing = false) => {
522+
if (disableActions.value) {
523+
return;
524+
}
507525
508526
if (initialProductType.value == null) {
509527
Toast.error(t('properties.rule.error.noProductType'));
510528
return
511529
}
512530
513-
const isCreateAction = !currentRuleId.value;
514-
const entry = await persistRule();
531+
saveLoading.value = true;
532+
try {
533+
const isCreateAction = !currentRuleId.value;
534+
const entry = await persistRule();
515535
516-
if (!entry) {
517-
Toast.error(t('shared.alert.toast.unexpectedResult'));
518-
return;
519-
}
536+
if (!entry) {
537+
Toast.error(t('shared.alert.toast.unexpectedResult'));
538+
return;
539+
}
520540
521-
Toast.success(t(isCreateAction ? 'properties.rule.alert.createSuccess' : 'properties.rule.alert.updateSuccess'))
522-
if (continueEditing) {
523-
return
524-
}
541+
Toast.success(t(isCreateAction ? 'properties.rule.alert.createSuccess' : 'properties.rule.alert.updateSuccess'))
542+
if (continueEditing) {
543+
return
544+
}
525545
526-
router.push({name: 'properties.rule.list'});
546+
router.push({name: 'properties.rule.list'});
547+
} finally {
548+
saveLoading.value = false;
549+
}
527550
528551
};
529552
@@ -575,27 +598,31 @@ watch(
575598
{ path: { name: 'properties.rule.edit' }, name: t('properties.rule.edit.title') }]" />
576599
</template>
577600

578-
<template v-slot:content>
601+
<template v-slot:content>
579602
<Card class="mt-2 p-4">
580-
<Loader :loading="loading" />
603+
<div v-if="!initialProductType" class="py-12 flex items-center justify-center">
604+
<LocalLoader :loading="rightLoading || integrationsLoading" />
605+
</div>
581606
<ProductPropertiesConfigurator
582607
v-if="initialProductType"
583608
:added-properties="initialItems"
584609
:product-type="initialProductType"
585610
:require-ean-code="requireEanCode"
586611
:sales-channel-options="salesChannelOptions"
587612
:selected-sales-channel="selectedSalesChannel"
613+
:integrations-loading="integrationsLoading"
614+
:right-loading="rightLoading || saveLoading"
588615
@update:added-properties="handleAddedProperties"
589616
@update:require-ean-code="handleRequireEanCodeUpdated"
590617
@update:sales-channel="handleSalesChannelUpdated"
591618
/>
592619

593620
<div class="flex items-center justify-end gap-x-3 border-t border-gray-900/10 px-4 py-4 sm:px-8">
594-
<CancelButton @click="() => router.push({ name: 'properties.rule.list' })">
621+
<CancelButton :disabled="disableActions" @click="() => router.push({ name: 'properties.rule.list' })">
595622
{{ t('shared.button.cancel') }}
596623
</CancelButton>
597624
<Link v-if="currentRuleId" :path="{ name: 'properties.rule.show', params: { id: currentRuleId } }">
598-
<Button type="button" class="button rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm btn-info ">
625+
<Button type="button" :disabled="disableActions" class="button rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm btn-info ">
599626
{{ t('shared.button.show') }}
600627
</Button>
601628
</Link>
@@ -606,13 +633,13 @@ watch(
606633
@done="handleDelete"
607634
>
608635
<template v-slot="{ loading: deleting, confirmAndMutate }">
609-
<DangerButton ref="deleteButtonRef" :disabled="deleting" @click="confirmAndMutate">{{ t('shared.button.delete') }}</DangerButton>
636+
<DangerButton ref="deleteButtonRef" :disabled="deleting || disableActions" @click="confirmAndMutate">{{ t('shared.button.delete') }}</DangerButton>
610637
</template>
611638
</ApolloAlertMutation>
612-
<SecondaryButton @click="handleSaveAndContinue">
639+
<SecondaryButton :disabled="disableActions" :loading="saveLoading" @click="handleSaveAndContinue">
613640
{{ secondaryButtonLabel }}
614641
</SecondaryButton>
615-
<PrimaryButton @click="handleSave">
642+
<PrimaryButton :disabled="disableActions" :loading="saveLoading" @click="handleSave">
616643
{{ primaryButtonLabel }}
617644
</PrimaryButton>
618645
</div>

src/core/properties/properties/configs.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,6 @@ export const showConfigConstructor = (t: Function, id): ShowConfig => ({
287287
type: FieldType.Badge,
288288
badgeMap: getPropertyTypeBadgeMap(t)
289289
},
290-
{
291-
label: t('properties.properties.labels.usageCount'),
292-
name: 'usageCount',
293-
type: FieldType.Text
294-
},
295290
{
296291
label: t('properties.properties.labels.isPublicInformation'),
297292
name: 'isPublicInformation',

src/core/properties/property-select-values/configs.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,6 @@ export const showConfigConstructor = (t: Function, id): ShowConfig => ({
356356
label: t('properties.values.show.title'),
357357
name: 'value',
358358
type: FieldType.Text
359-
},
360-
{
361-
label: t('properties.values.labels.usageCount'),
362-
name: 'usageCount',
363-
type: FieldType.Text
364359
}
365360
]
366361
});

src/locale/de.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,13 +1882,17 @@
18821882
"rule": {
18831883
"labels": {
18841884
"usageCount": "",
1885+
"usageCountPending": "",
18851886
"salesChannel": "",
18861887
"defaultSalesChannel": "",
18871888
"unknownSalesChannel": ""
18881889
},
18891890
"placeholders": {
18901891
"salesChannel": ""
18911892
},
1893+
"tooltips": {
1894+
"usageCountPending": ""
1895+
},
18921896
"messages": {
18931897
"unsavedChanges": ""
18941898
}

src/locale/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3257,6 +3257,7 @@
32573257
},
32583258
"labels": {
32593259
"usageCount": "Usage count",
3260+
"usageCountPending": "Pending",
32603261
"type": "Rule Type",
32613262
"propertyType": "Property Type",
32623263
"salesChannel": "Sales Channel",
@@ -3270,6 +3271,9 @@
32703271
"help": {
32713272
"type": "Select how this property should be handled for the product."
32723273
},
3274+
"tooltips": {
3275+
"usageCountPending": "Usage count is recalculated after saving this rule."
3276+
},
32733277
"preview": {
32743278
"previewTitle": "Preview of Configuration",
32753279
"productText": "Configuration of {name} products will look like:",

0 commit comments

Comments
 (0)