Is it possible to override spartacus ngrx effect? - ngrx-effects

I am trying to override ProductReviewEffects.
I don't wan't to execute default ProductActions.POST_PRODUCT_REVIEW_SUCCESS.
#Effect({ dispatch: false })
showGlobalMessageOnPostProductReviewSuccess$ = this.actions$.pipe(
ofType(ProductActions.POST_PRODUCT_REVIEW_SUCCESS),
tap(() => {
this.globalMessageService.add(
{ key: 'productReview.thankYouForReview' },
GlobalMessageType.MSG_TYPE_CONFIRMATION
);
})
);
I created new effect and on POST_PRODUCT_REVIEW_SUCCESS action my code is executing, but how can I cancel Spartacus default behaviour?

I just checked with my colleagues: in principle spartacus effects are not part of public API, they are not something we seem to want to allow. So they could not be overridden.
What is exactly your requirement? Would you like to suppress the "thank you for review" message? If so, there might be some other approaches except for effects override.
Best regards,
Jerry

Related

My useQuery hook is refetching everytime its called. I thought it is suppose to hand back the cache?

I'm a little confused here. I thought react-query, when using useQuery will hand back 'cache' n subsequent calls to the same "useQuery". But everytime I call it it, it refetches and makes the network call.
Is this the "proper way" to do this? I figured it would just auto hand me the "cache" versions. I tried extending staleTime and cacheTime, neither worked. Always made a network call. I also tried initialData with the cache there.. didn't work.
SO, I am doing the following, but seems dirty.
Here is the what I have for the hook:
export default function useProducts ({
queryKey="someDefaultKey", id
}){
const queryClient = useQueryClient();
return useQuery(
[queryKey, id],
async () => {
const cachedData = await queryClient.getQueryData([queryKey, id]);
if (cachedData) return cachedData;
return await products.getOne({ id })
}, {
enabled: !!id
}
);
}
This is initiated like so:
const { refetch, data } = useProducts(
{
id
}
}
);
I call "refetch" with an onclick in two diff locations.. I'd assume after I retrieve the data.. then subsequent clicks will hand back cache?
I’m afraid there are multiple misconceptions here:
react query operates on stale-while-revalidate, so it will give you data from the cache and then refetch in the background. You can customize this behavior by setting staleTime, which will tell the library how long the data can be considered fresh. No background updates will happen.
when you call refetch, it will refetch. It’s an imperative action. If you don’t want it, don’t call refetch.
you don’t need to manually read from the cache in the queryFn - the library will do that for you.

How to override/disable "escapeHandler" of "Dialog" via XML-template in UI5?

I know to override in UI5 the default behavior of sap.m.Dialog's escapeHandler via controller, e.g.:
this._oDialog.setEscapeHandler((oEscapeHandler) => {
oEscapeHandler.reject();
});
The question is it possible to provide an alternative escapeHandler behavior via XML-template without using of setEscapeHandler?
Ideally, it should be something like escapeHandler = "none/customFunction", e.g.:
<Dialog
id = "authDialog"
title = "{i18n>DIALOG_TITLE}"
type = "Message"
escapeHandler = "%CUSTOM_ESCAPE_HANDLER%">
</Dialog>
Particularly, I want to disable a Dialog closing on Esc button press and to do it in an elegant, declarative manner via XML-template, e.g. escapeHandler = "none".
There was a new commit (merged today) that enables assigning controller function to escapeHandler. With that, the below code is now possible:
<Dialog xmlns="sap.m"
id="authDialog"
title="{i18n>DIALOG_TITLE}"
type="Message"
escapeHandler=".handleEscape"
>
handleEscape: function(pEscapePending) {
// Depending on the use case, call pEscapePending.resolve() or pEscapePending.reject() to overwrite the default behavior.
},
The fix should be available with the 1.86 release.
I solved this issue by putting the property escapeHandler = "customFunction" and then having a function with no implementation in the controller. Basically in customFunction I had a comment explaining that this is used to override the default escape behaviour.

How to determine whether user is ready and nonce can be submitted to server?

This is one of many (imho rather incomplete) examples in the docs:
var button = document.querySelector('#submit-button');
braintree.dropin.create({
authorization: 'CLIENT_AUTHORIZATION',
container: '#dropin-container'
}, function (createErr, instance) {
button.addEventListener('click', function () {
instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
// Submit payload.nonce to your server
});
});
});
It's all nice and easy but I don't see how I can change the state of button according to the state of "is the user done with adding a payment method?".
Is this even possible? It seems that the click on the button actually performs the fetching of the nonce (which comes as payload.nonce). However, how can I disable button until the user has finished his conversation with Braintree/PayPal?
And the answer is look in the docs (no not those docs) - those docs.
I still don't know how I found that link.
The dropin instance has a on() function where you can register a callback for certain events (just do it - look at the docs already):
instance.on('paymentMethodRequestable', function(event) {
thiz._logger.info('Payment method is now requestable');
setTimeout(() => thiz.paymentMethodAvailable = true, 400);
});

safari app extensions: broadcast a message to all tabs from swift background process

In a legacy extension it was possible to iterate over safari.application.activeBrowserWindow.tabs to send a message to all tabs registered with the extension.
Is there any equivalent available with the new safari app extensions?
I've been trough the docs but did not find any hints on how to achieve this very basic thing.
A horrible workaround would be to have all tabs ping the Swift background, but really this is such a basic thing it seems absurd that it is not available or covered by the docs, am I missing something?
I also tried keeping a weak map of all "page" instances as seen by "messageReceived" handler in the hope the SFSafariPage reference would be kept until a tab is closed but they are instead lost almost immediately, suggesting they are more message channels than actual Safari pages.
The way should be next:
in injected.js you send the message to your app-ext, e.g.
document.addEventListener("DOMContentLoaded", function (event) {
safari.extension.dispatchMessage('REGISTER_PAGE')
})
And in app-ext handle it with smth like this:
var pages: [SFSafariPage] = []
class SafariExtensionHandler: SFSafariExtensionHandler {
override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
switch messageName {
case "REGISTER_PAGE":
if !pages.contains(page) {
pages.append(page)
}
default:
return
}
}
}
Well, then you can send the message to all opened pages during runtime by smth like this:
for p in pages {
p.dispatchMessageToScript(withName: "message name", userInfo: userInfo)
}
It looks hacky but yet workable. Enjoy :)

Customize or change default message boxes issued by workflow dialogs on errors in Alfresco

Presently, a messagebox appears with the failing class name:
Is it possible to override the default behavior in Alfresco? Could we use forms service to present a different message ?
Additional to zladuric answer,
you can use failureCallback method to show message what you want.
But it is difficult to search failureCallback method of workflow forms for a new one because workflow forms such as "Start Workflow", "Task Edit", "Task Detail" are used form engine.
For example, in "Start Workflow" form, you can add our own successCallBack and failureCallBack by writing onBeforeFormRuntimeInit event handler in start-workflow.js like this.
onBeforeFormRuntimeInit: function StartWorkflow_onBeforeFormRuntimeInit(layer, args)
{
var startWorkflowForm = Dom.get(this.generateId + "-form");
Event.addListener(startWorkflowForm, "submit", this._submitInvoked, this);
args[1].runtime.setAJAXSubmit(true,
{
successCallback:
{
fn: this.onFormSubmitSuccess,
scope: this
},
failureCallback:
{
fn: this.onFormSubmitFailure,
scope: this
}
});
}
onFormSubmitSuccess: function StartWorkflow_onFormSubmitSuccess(response)
{
this.navigateForward(true);
// Show your success message or do something.
}
onFormSubmitFailure: function StartWorkflow_onFormSubmitFailure(response)
{
var msgTitle = this.msg(this.options.failureMessageKey);
var msgBody = this.msg(this.options.failureMessageKey);
// example of showing processing response message
// you can write your own logic
if (response.json && response.json.message)
{
if(response.json.message.indexOf("ConcurrencyFailureException") != -1)
{
msgTitle = this.msg("message.concurrencyFailure");
msgBody = this.msg("message.startedAgain");
}
else
msgBody = response.json.message;
}
Alfresco.util.PopupManager.displayPrompt(
{
title: msgTitle,
text: msgBody
});
}
Since Alfresco.component.StartWorkflow(in start-workflow.js) extends Alfresco.component.ShareFormManager(in alfresco.js). You can override onBeforeFormRuntimeInit event in start-workflow.js. I hope this your help you.
I'm not looking at the code right now, but this looks like a regular YUI dialog. So it's fired by YUI. So this YUI is client side, probably in My-tasks dashlet or my tasks page.
Furthermore, the error message looks like it is a status.message from the failed backend message/service.
You could probably locate that client-side javascript file, find the method that starts the task and see what its' failureCallback handler is. Then edit that failureCallback method and make it show something different then the response.status.message or whatever it is. Perhaps something like this.msg("message.my-custom-error-message"); which you then customize on your own.
Modifying YUI dialog scripts will might affect the other functionalities as well.
If we customize start-workflow. js, its only going to be achieved in start workflow form.
So as generic solution, below is the suggestion.
When alfresco is rendering the workflow form , it is rendering the transition button using the activiti-transition.js file.Basically this buttons are doing nothing more but submitting the workflow form.
So the best way would be , customizing this activiti-transition.ftl and activiti-transition.js file , to make an ajax call and handle the response as we want.
I just had a look on full flow of how this front end error is shown.
activiti-transition is submiting the workflow form.
Using a function named as submitForm which resides inside alfresco.js, it is invoking an submit event of form
Inside the forms-runtime.js file there is one function named as _submitInvoked(handles the submit event of form), which is responsible for making an ajax call and submitting the workflow form.If there is error while submitting , it will display the error which is from backend.