Facebook Flex and feedback from Actions - javascript

I'm playing around with Facebook Flux (I'm using Fluxxor, but I don't think that's really important) with ReactJS, and so far I think they its a great way of working with the data flow in an application. However, there's one thing that I'm really struggling to get my head around. It might be that this is simply something that shouldn't be done with Flex, or that I'm missing something obvious, but hence why I'm asking...
For example, I'm building a system to log in with. Very simple - there's a Login dialog that pops up, and you enter your username and password and press the button. This calls the LoginAction.login(username, password) Action Creator, which sends the LOGIN Event to the Dispatcher and then triggers the API call to authenticate the user and make sure the credentials are correct. If we get a success back from the API then we trigger the LOGIN_SUCCESS Event to the Dispatcher, the SessionStore handles this and stores the fact that we have successfully logged in, and the details of who we are. This then triggers bits of the UI to update - for example the "Log In" button changes to a "Hello Graham" bit of text, and a "Log Out" button instead. That's all really easy and just works and makes sense.
What I'm getting stuck with is when the login fails. If I enter an invalid username/password then I want the Login Dialog to tell the user this, so that they can correct what they entered and try again. The only way that I can think of to achieve this is to send a LOGIN_FAILED Event to the Dispatcher, which is then handled by some Store that stores the last Login errors for the Dialog to display. This just feels weird though, because these errors are not application state but are instead a transitive piece of information about this one request that failed, that the user will then correct and retry.
It feels to me that this transitive state is going to be very common around API calls that might fail because of user input, and so don't belong as part of the application state but instead belong somewhere else. However, I can't work out how Flux allows this transitive state to get back to the UI to be displayed to the user...

SessionStore handles this and stores the fact that we have successfully logged in
In your case you keep information about successful auths. Why not to keep info about unsuccessful once also at store (the same store or independent once which keeps auth state or permissions state for user)?
It's another side of your state. In this case you've just have to dispatch special event on failure (like in you case about successful login) to store(s), save new state and send changes to the UI.
Here is the example which is similar to what i mean. You send a request to the server ant can dispatch an action if login fails.

Related

Bypass/change the 'Changes that you made may not be saved' prompt

I need to log a user out of an application automatically if there is no interaction for a period of time.
However, when I perform the redirect to log the user out, the browser prompts 'Are you sure you want to leave' when changes are made to a Stimulsoft report.
How can I bypass this? If changes are made, then the user forgets to log out and save their changes, a malicious user could just come and press the cancel and have access to all the data in the system without allowing this auto-logout to occur.
Hope that you are fine!
I suggest you to make ajax request to log out link and then refresh the page after success.
$.get('url/of/logout/', function(){location.reload()})
with jquery. You can look for equivalent on axios or ajax primitiv function

Intercepting Actions in React Components

I have a React application that uses Redux.
The application displays the results of some calculations at the top and some of the constituents that go into those calculations at the bottom. The user can click a button which pops up a modal in which the user can add one of these constituents. This will fire off an action during which it will send that new constituent to the backend, which will make those calculations have different results.
As you might expect, what I want is to refresh those results from the server based on the new data. The calculations are quite complex so replicating the calculation in the UI is not an option.
There is a loadConstituents() method which is called by componentWillMount() when the user lands on the page. I basically need to call this method again once the server confirms to the user that the data was received (via a SAVE_SUCCESS action).
How can I intercept an action in my component?
Alternatively, is there a better pattern for achieving this?
The best thing I could think of is passing the loadConstituents() function to the modal, which would pass it to the call, which will execute it once the call is done but passing a function through so many classes as a parameter seems very hacky.

Need to prompt user for text during NetSuite Workflow

Business logic: when an Approver rejects an expense report, an e-mail must be sent to the creator. This e-mail must contain the reason for rejection.
Existing setup: A multi-state workflow has already been set up, that sends the expense report through two separate approvals. Each Approver can approve or reject the workflow. Rejecting the workflow sends it back to the submission state for correction by the creator. My task is to acquire the rejection text and create the outgoing e-mail.
Obvious solutions rejected:
Send Email workflow action-- this WF action allows only boilerplate e-mails to be sent (with some parameterization). Nothing can be customized from the user's perspective.
Workflow Action Script-- this script context does not allow the use of JavaScript dialog presentations, such as window.confirm() or window.prompt(). There are popup parallels in the workflow action palette, but only for confirm() or alert()-- no prompt(). Unfortunately the technical requirements and restrictions for Workflow Action scripts are horribly documented, so this result was learned only after spending a few days researching and writing the script.
Add a tracking field on the expense report that must be filled in before the report can be Rejected. However, this requires unlocking the record, an issue for Audit concerns. It also must be made visible and hidden for appropriate states, and can be adjacent to only one set of action buttons.
The new state is not an end-state, so e-mail generation is not automatic as it is for end-states. We just want similar functionality.
The only other possiblity I see is to target a new page, such as a Suitelet. However, I only need a single string from the user. A Suitelet seems overkill, plus it makes the workflow more complicated to go back to the correct report.
Any insight or ideas that anyone might have would be most helpful.
Well, I've tried several other solutions and none of these seem to work:
Redirect (via nlapiSetRedirectURL() in a WFA script) on state Exit trigger to a Suitelet that takes the parameters passed from the workflow where the user enters the rejection text; then redirect to the expense report. This fails because the report state does not actually change.
Do the same thing, but from the Entry trigger of the new state. Requires some more detailed parameter handling but this also does not work. Apparently redirecting from any part of the UI experience cancels the workflow transition.
Setting the "User Interface" context on the workflow action also does not work; the redirection still kills the transition.
The nlapiTriggerWorkflow() function also does not seem to have an effect, even when the UI context is set on the action. No errors or debug text generated.
The user may just have to accept manual behaviors like, adding a note and sending a canned e-mail. This appears to be a major feature hole, either deliberate or not. Note that there is a Confirm and a Show Message action, but no Prompt. So why not? No details, just deal with it I guess.
Final solution:
A separate workflow state where a script runs. A new button on the workflow redirects to this new state.
A workflow action script in these special state(s) that has parameter settings that are changed depending on where they are in the workflow. This script redirects to the suitelet (next), which interrupts the workflow transition and keeps the item in the same state.
A suitelet that takes the user text in a textarea, and a non-submit action button. Don't want to use a submit button, because that reloads the same page, creating an extra step.
A client script that takes parameters from the suitelet button event, creates the e-mail, and redirects back to the original record (that is in the same workflow state as before).
Of course this is inelegant. The user must press a button to create the e-mail, and a separate button to transition to the correct state. It fulfills the user's needs, but it requires them to remember to press one button to create the e-mail reason text, and another button to actually reject the record.
The need for this convoluted solution is because of all the roadblocks in NetSuite design:
Can't prompt for text from a server-side WF action script. We can confirm() giving a Y/N (Ok / Cancel) answer, but somehow string returns are not allowed.
Can't complete a transition if a WF action script redirects to another page.
Suitelet submit buttons reload the same page, so we need a client script to do the final e-mail creation work.
Feature hole much?
There is a limitation on the workflow that it cannot accept input from the user. Hence, we need to go ahead with a customized solution for this scenario. I have implemented this in multiple NetSuite projects. Here is the solution which works
(1) Have a workflow action script which would call the suitelet. Please see script sample below for workflow action script
define(['N/record','N/runtime','N/redirect'],
function (record,runtime,redirect){
function callSuitelet(context)
{
try {
var currentRecord = context.newRecord;
var vendorId = currentRecord.id;
var vendorNumber = currentRecord.getValue('entityid');
redirect.toSuitelet({
scriptId: 'customscript_call_rejection_reason',
deploymentId: 'customdeploy_call_rejection_reason',
parameters: {'recid':vendorId,'vbTransactionNo':vendorNumber, trantype: context.newRecord.type}
});
}
catch (err) {
log.error("Error while calling Suitelet", err);
throw err;
}
}
return {
onAction: callSuitelet
};
});
(2) Have a suiteLet designed to capture the "Rejection Reason"
(a) Add a field on the suitelet form labelled as "Rejection Reason" (FieldType.TEXTAREA)
(b) Add a "Submit" button which will add the data to the transaction record
(c) Redirect the suitelet back to the transaction record once "submit" button is clicked
This should solve the problem stated above

Populating an ngrx store with data shared between routes

I have a multi-page form spanning over several routes. All of the routes need the same data shared with them from an API. I can store the response of the API inside ngrx/store and trigger the API call using an effect. My question is more about where to initiate the API call. The API call needs to be made once the user is authenticated, which happens on the very first route I hit (before the first part of the multi page form is visited). The two options I've come up with are:
Triggering the effect inside each route's component meaning I'll just have to request the information every time I visit a route. A guard will prevent all pages being accessible while the user isn't authenticated.
Listen to the authenticated success action inside an effect and make the request to the API there.
I'm sure both are perfectly acceptable and have their trade offs. It'd just be good to get a few opinions!
The second would be the best, requesting the information on demand ergo when the user is authentified and its allowed to use it makes more sense. Inside of the guard, as u said, you should dispatch the action to load the information before you return true/of(true) to signalize that the route can be activated. The naive approach for this would trigger an information request everythime that you try to activate the guarded route.

Javascript OnPageUnload - on "leave page" must call additional method

This is the problem: my web application (php) has a wizard feature which gathers customer's data page by page, and stores it in session. If customer tries to navigate away from the page before they have completed the wizard, I would like to display a massage to the effect of "You will lose your data". If the customer chooses to navigate away, the session data should be wiped.
I know that I can intercept this action by binding onpageunload event, but is there a way to then make another call, e.g. ajaxClearWizard() if the customer says "yes"?
PS I can see that, perhaps session shouldn't be used here, but I'm using an existing library, and although this wizard-data-persistence used to be a required feature the business now requires it to be removed :(
Any ideas, alternatives?
Thanks in advance!
window.onbeforeunload = function () {
return 'Your content has not been properly saved yet!';
};
This will make the browser display a confirmation box in middle with above content.

Categories

Resources