-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implemented: code to add functionality to subscribe or unsubscribe a webhook(#2ftb11u) #191
Changes from 26 commits
43543b8
939cf6a
4e8d0fe
97f9731
e92f7bf
1f0c930
446957c
96733de
d377c3c
136e593
53e4cc2
0fb3921
f0de5c6
7b17a74
bb29f7c
fa1dc31
898640c
5540e7a
02d5488
9112e6c
4b3f178
45af475
99507bf
93a7e89
4a8b412
9dd3f05
6c0f514
dabd8ec
f645c0d
eb7eda4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import api from '@/api' | ||
|
||
const fetchShopifyWebhooks = async (payload?: any): Promise <any> => { | ||
return api({ | ||
url: "/service/getShopifyWebhooks", | ||
method: "post", | ||
data: payload | ||
}); | ||
} | ||
|
||
const subscribeNewOrderWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: '', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const subscribeCancelledOrderWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: '', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const subscribePaymentStatusWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: '', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const subscribeReturnWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: '', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const subscribeNewProductsWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: '', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const subscribeDeleteProductsWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: 'service/subscribeProductDeleteWebhook', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const subscribeFileStatusUpdateWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: 'service/subscribeFileStatusUpdateWebhook', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
const unsubscribeWebhook = async (payload?: any): Promise <any> => { | ||
return api ({ | ||
url: 'service/removeShopifyWebhook', | ||
method: 'post', | ||
data: payload | ||
}) | ||
} | ||
|
||
export const WebhookService = { | ||
fetchShopifyWebhooks, | ||
subscribeNewOrderWebhook, | ||
subscribeCancelledOrderWebhook, | ||
subscribeFileStatusUpdateWebhook, | ||
subscribePaymentStatusWebhook, | ||
subscribeReturnWebhook, | ||
subscribeNewProductsWebhook, | ||
subscribeDeleteProductsWebhook, | ||
unsubscribeWebhook | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export default interface WebhookState { | ||
cached: any | ||
key: { | ||
topic: string, | ||
list: Array<any> | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,78 @@ | ||||||
import { ActionTree } from "vuex"; | ||||||
import RootState from "@/store/RootState"; | ||||||
import WebhookState from "./WebhookState"; | ||||||
import { WebhookService } from "@/services/WebhookService"; | ||||||
import { hasError, showToast } from "@/utils"; | ||||||
import * as types from './mutations-types' | ||||||
import { translate } from '@/i18n' | ||||||
|
||||||
const actions: ActionTree<WebhookState, RootState> = { | ||||||
async fetchWebhooks({ commit }) { | ||||||
await WebhookService.fetchShopifyWebhooks({ shopifyConfigId: this.state.user.shopifyConfig }).then(resp => { | ||||||
if (resp.status == 200 && resp.data.webhooks?.length > 0 && !hasError(resp)) { | ||||||
const webhooks = resp.data.webhooks; | ||||||
const topics: any = {} | ||||||
webhooks.map((topic: any) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
topics[topic.topic] = topic | ||||||
}) | ||||||
commit(types.WEBHOOK_UPDATED, topics) | ||||||
} | ||||||
}).catch(err => console.error(err)) | ||||||
}, | ||||||
async unsubscribeWebhook({ dispatch }, payload: any) { | ||||||
|
||||||
let resp; | ||||||
|
||||||
try { | ||||||
resp = await WebhookService.unsubscribeWebhook(payload) | ||||||
if (resp.status === 200 && !hasError(resp)) { | ||||||
showToast(translate("Webhook unsubscribed successfully")); | ||||||
} | ||||||
} catch(err) { | ||||||
console.log(err) | ||||||
showToast(translate("Something went wrong")); | ||||||
} finally { | ||||||
dispatch('fetchWebhooks') | ||||||
} | ||||||
}, | ||||||
async subscribeWebhook({ dispatch }, id: string) { | ||||||
|
||||||
// stores the webhook service that needs to be called on the basis of current webhook selected, doing | ||||||
// so as we have defined separate service for different webhook subscription | ||||||
const webhookMethods = { | ||||||
'NEW_ORDERS': WebhookService.subscribeNewOrderWebhook, | ||||||
'CANCELLED_ORDERS': WebhookService.subscribeCancelledOrderWebhook, | ||||||
'PAYMENT_STATUS':WebhookService.subscribePaymentStatusWebhook, | ||||||
'RETURNS': WebhookService.subscribeReturnWebhook, | ||||||
'NEW_PRODUCTS': WebhookService.subscribeNewProductsWebhook, | ||||||
'DELETE_PRODUCTS': WebhookService.subscribeDeleteProductsWebhook, | ||||||
'BULK_OPERATIONS_FINISH': WebhookService.subscribeFileStatusUpdateWebhook | ||||||
} as any | ||||||
const webhookMethod: any = webhookMethods[id]; | ||||||
|
||||||
if (!webhookMethod) { | ||||||
showToast(translate("Configuration missing")); | ||||||
return; | ||||||
} | ||||||
|
||||||
let resp; | ||||||
|
||||||
try { | ||||||
resp = await webhookMethod({ shopifyConfigId: this.state.user.shopifyConfig }) | ||||||
|
||||||
if (resp.status == 200 && !hasError(resp)) { | ||||||
showToast(translate('Webhook subscribed successfully')) | ||||||
} else { | ||||||
showToast(translate('Something went wrong')) | ||||||
console.error(resp) | ||||||
} | ||||||
} catch (err) { | ||||||
showToast(translate('Something went wrong')) | ||||||
console.error(err); | ||||||
} finally { | ||||||
await dispatch('fetchWebhooks') | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
export default actions |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { GetterTree } from "vuex"; | ||
import RootState from "@/store/RootState"; | ||
import WebhookState from "./WebhookState"; | ||
|
||
const getters: GetterTree<WebhookState, RootState> = { | ||
getCachedWebhook: (state) => state.cached | ||
} | ||
|
||
export default getters |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Module } from 'vuex' | ||
import WebhookState from './WebhookState' | ||
import RootState from '@/store/RootState' | ||
import getters from './getters' | ||
import mutations from './mutations' | ||
import actions from './actions' | ||
|
||
const webhookModule: Module<WebhookState, RootState> = { | ||
namespaced: true, | ||
state: { | ||
cached: {}, | ||
key: { | ||
topic: "", | ||
list: [] | ||
}, | ||
}, | ||
getters, | ||
actions, | ||
mutations, | ||
} | ||
|
||
export default webhookModule |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const SN_WEBHOOK = 'webhook' | ||
export const WEBHOOK_UPDATED = SN_WEBHOOK + '/WEBHOOK_UPDATED' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { MutationTree } from "vuex"; | ||
import WebhookState from "./WebhookState"; | ||
import * as types from './mutations-types' | ||
|
||
const mutations: MutationTree<WebhookState> = { | ||
[types.WEBHOOK_UPDATED] (state, payload: any) { | ||
state.cached = payload | ||
} | ||
} | ||
|
||
export default mutations |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,10 @@ | |
<ion-card-header> | ||
<ion-card-title>{{ $t("Process Uploads") }}</ion-card-title> | ||
</ion-card-header> | ||
<ion-item> | ||
<ion-label class="ion-text-wrap">{{ $t("File upload status") }}</ion-label> | ||
<ion-toggle :checked="fileStatusUpdateWebhook" color="secondary" slot="end" @ionChange="updateWebhook($event['detail'].checked, 'BULK_OPERATIONS_FINISH')" /> | ||
</ion-item> | ||
<ion-item> | ||
<ion-label class="ion-text-wrap">{{ $t("Upload Pending Process") }}</ion-label> | ||
<ion-checkbox slot="end" :checked="processPendingUploadsOnShopify" @ionChange="updateJob($event['detail'].checked, jobEnums['UL_PRCS'])"/> | ||
|
@@ -69,6 +73,7 @@ import { | |
IonMenuButton, | ||
IonPage, | ||
IonTitle, | ||
IonToggle, | ||
IonToolbar, | ||
isPlatform | ||
} from '@ionic/vue'; | ||
|
@@ -96,11 +101,13 @@ export default defineComponent({ | |
IonMenuButton, | ||
IonPage, | ||
IonTitle, | ||
IonToggle, | ||
IonToolbar | ||
}, | ||
data() { | ||
return { | ||
jobEnums: JSON.parse(process.env?.VUE_APP_INITIAL_JOB_ENUMS as string) as any, | ||
webhookEnums: JSON.parse(process.env?.VUE_APP_WEBHOOK_ENUMS as string) as any, | ||
currentSelectedJobModal: '', | ||
job: {} as any, | ||
lastShopifyOrderId: '', | ||
|
@@ -115,18 +122,24 @@ export default defineComponent({ | |
"systemJobEnumId_op": "in" | ||
} | ||
}) | ||
this.store.dispatch('webhook/fetchWebhooks') | ||
}, | ||
computed: { | ||
...mapGetters({ | ||
getJobStatus: 'job/getJobStatus', | ||
getJob: 'job/getJob', | ||
shopifyConfigId: 'user/getShopifyConfigId', | ||
currentEComStore: 'user/getCurrentEComStore' | ||
currentEComStore: 'user/getCurrentEComStore', | ||
getCachedWebhook: 'webhook/getCachedWebhook' | ||
}), | ||
fileStatusUpdateWebhook(): boolean { | ||
const webhookTopic = this.webhookEnums['BULK_OPERATIONS_FINISH'] | ||
return this.getCachedWebhook[webhookTopic]?.topic === webhookTopic | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we have topic as key, I think we could skip the comparison There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done Sir |
||
}, | ||
processPendingUploadsOnShopify(): boolean { | ||
const status = this.getJobStatus(this.jobEnums["UL_PRCS"]); | ||
return status && status !== "SERVICE_DRAFT"; | ||
}, | ||
} | ||
}, | ||
methods: { | ||
async updateJob(checked: boolean, id: string, status = 'EVERY_15_MIN') { | ||
|
@@ -181,6 +194,21 @@ export default defineComponent({ | |
emitter.emit('playAnimation'); | ||
this.isJobDetailAnimationCompleted = true; | ||
} | ||
}, | ||
async updateWebhook(checked: boolean, id: string) { | ||
const webhook = this.getCachedWebhook[this.webhookEnums[id]] | ||
|
||
// TODO: added this condition to not call the api when the value of the select automatically changes | ||
// need to handle this properly | ||
if ((checked && webhook) || (!checked && !webhook)) { | ||
return; | ||
} | ||
|
||
if (checked) { | ||
await this.store.dispatch('webhook/subscribeWebhook', id) | ||
} else { | ||
await this.store.dispatch('webhook/unsubscribeWebhook', { webhookId: webhook?.id, shopifyConfigId: this.shopifyConfigId }) | ||
} | ||
} | ||
}, | ||
setup() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sir, removed unwanted state