Foundry Workshop - Prevent duplicate data entry - palantir-foundry

I am building a Workshop App which will be used for data entry by a large number of operational staff members (> 200).
I would like to implement the following set-up:
The staff will enter the data on existing Ontology Objects. To facilitate this, I embedded a Foundry Form into the Object View, and set-up a corresponding write-back data set.
The Ontology Objects in question will be displayed in an Object Table in Workshop.
The staff member will select an Object from the Object Table.
The selected Object will be opened in an Object View.
The staff member will enter data on the Object View (Foundry Form being displayed here).
I need to make sure that no concurrent data entry can/will happen. How can I achieve this?
I am thinking about removing any Object which is opened in the Object View from the Object Table, but I am not sure if this is the best solution to the problem or how to achieve the removal from the table.
I am assuming that this must be a common problem and there would be a Design Pattern/Standard Functionality to solve this.

You'll have the best behavior here if you replace your Foundry Form with Foundry Actions. These actions are defined in the Ontology Management App and provide a more robust security model for managing object edits and are more tightly integrated into the various object-layer tools in Foundry.
Then in your Object View, rather than using the Foundry Forms widget, choose to create a new "Workshop-backed" Object View tab - this option is under the dropdown next to the New Tab button - and within the Workshop module use the Inline Action Form to embed the action form that you've configured in the Ontology Management App, supplying the variable representing the current object as the default for the object parameter in the Action.
With regards to simultaneous edits, in Actions, when the form is populated (i.e. when that tab is opened), the version of the underlying object(s) are registered. When the edit request is submitted, the current version of the object is checked, and if the version is different (i.e. there have been edits applied since the form was loaded) the user will be presented with message to the effect that the object has been updated and the edits will not be applied.
This protects against the case of a user overwriting a near-simultaneous edit without reviewing the changes first and does so at the writeback layer, rather than with logic in your application front-end.
There is not currently an approach to reflect real-time user interaction between two Workshop sessions. For instance, there is no way for the session of User A to "know" that User B has opened Object X in their session and is making a change.
If you wanted to do something for a bit of convenience or display signaling, you could create a small object type related to your main object - something like "Edit Lock" that looks like:
| id | primary_object_id | user_id | timestamp | timeout
And then in your Workshop app, there's a button above the table that says "Edit Selected Object".
When you click this button, you trigger an Action to create a new "edit lock" object populated with the current user and the current timestamp and say a timeout of 15 minutes from now.
Then in the object view for the primary object in question, on the same tab where you have the edit form embedded, you can create a variable that gets the edit locks associated with that object via a search around and use a Function to create a boolean variable if there is an "active" edit lock. And use this to conditionally show a banner to the user or otherwise give them a visual indication that another user has indicated they're making changes.
This won't push to the other session, and it'd be just for display purposes, the real protection still comes from the underlying object versioning that Actions enforces, but it might be a nice user affordance to layer on top if you really expect to commonly run into this situation.

Related

Using state machine to validate a form field

This is my first take on a state machine and got a bit confused about the possible states that i can define while implementing the subject matter.
P.s. (this question is about how to infer states from a problem and not about how to actually implementing it in code. I know and have used xstate lib).
Scenario is simple, a password field with few validation rules.
The states i came up with are
default ( when the form loads or reset button is pressed)
filled ( should this even be a state ?)
valid ( date is present with all rules satisfied)
invalid (data is there but not meeting the rules )
Error message is displayed based on the current state.
For example, in default state, user didn't enter any data yet, so logical it is invalid state.
But we do not want to show errors to the user right away after opening the form (that will be horrible ux, right ?)
So I added a state specifically for that purpose.
Is this right?
Can it be further simplied or is there a state i am missing?
Secondly, there seems to be arbitrary states
Like
validating
submitting
Should these also be in the mix of states?
They look like states to me though.
Lastly, can we say
submitted is also a state ?
invalid after submitted due to error in API call ( maybe API team added a new rule we didn't know).
Million dollar questions are,
am i even thinking in the right direction to implement validation this way?
is there any state i am missing or overdoing?
You've probably already solved this, but just in case somebody else comes across this question and could use some pointers - I found the trick was to keep in mind that even simple elements have often multiple states in parallel, e.g. a button can be disabled and show a loading spinner at the same time, a menu can be open and fetching data, an avatar can be showing a placeholder and fetching an image at the same time etc.
for your example I'd look at it like this:
Field level
If you think in terms of a password field, it actually has multiple parallel states at the same time:
Interaction
Validity
Visibility
All three states exist at the same time and have multiple child states
Interaction
this should probably mirror the default input events and have matching state events (e.g. onChange -> set to changed):
blurred
focussed
changed
...
Validity
probably just two states, potentially three if you need asynchronous validation (e.g. if you need to check if an email already exists). For a password field you'd just use:
valid
invalid
validating (optional)
Visibility
straight forward:
visible
hidden
Form level
You probably end up with two main states with multiple child states:
form
error
Form
Idle
Editing
Validating
Submitting
Error
That could translate into an alert which you show when e.g. an account already exists or the login details can't be verified:
Inactive
Active
Your form state machine would basically handle the input, validation, submission, and form errors, and just communicate the state to individual field machines (field error messages etc). Alternatively, you could pass the validation rules to the field machines and they can execute the field-level validation on i.e. change events. Things like visibility have nothing to do with the form, so you'd manage the state in the field state machine.
I think you were on the right track, you were just thinking a bit too sequential and not considering parallel states. It's just a matter of taking a step back, looking at the form and thinking about everything that can change in it from a UI point of view.

Passing back value from Browse-Child VM chain to caller

MVVMCross
Windows Store
Android
I have a VM that browses a hierarchy (BrowseVm) and supports forward navigation via
ShowViewModel<LeafDetailVM>
to a leaf detail ViewModel (LeafDetailVM).
When the user is on the LeafDetail View they should be able to say "I want this one" and they will be returned to the View that initiated BrowseVm.
I cannot simply Forward Navigate to the Initiator because that would leave me with an invalid back stack. I cannot have the BrowseVM view as a NoHistory page as I need it be in the back stack to support going back from the LeafDetail view.
My plan is to have the initiator start BrowseVm with a GUID. BrowseVm will pass that GUID onto LeafDetailVM.
In the "I want this one" command I will raise a Message, containing the GUID, that both BrowseVM and the initiator are subscribed to. Then I will close LeafDetailVM.
When BrowseVM receives the notification of the message it will compare the GUID and if it matches it will close itself.
When the initiator receives the notification it will deal with the now chosen data.
Does this make sense? Have I missed a much simpler way of doing this?
This is similar to How to pass a parameter from a viewmodel to its parent viewmodel but that does not deal with the back stack.
Thanks
I suggest you try stop mentally coupling how the views work on a platform to the view-models.
With the custom presenter mechanism in MvvmCross, in the app (platform specific code) you can handle navigation to a certain view-model in different ways, including closing views, modify backstack, etc.
You can interpret navigation to a view-model in whatever way you want \ need.
You can for example pass from view-model some parameters in the ShowViewModel request which the view-presenter (IMvxViewPresenter) can interpret in different ways in the Show() to display a view-model.
In your case, you can actually navigate to initiator VM passing the selected info. In the view presenter, you can modify the backstack in the way you need.
On Android, make sure you read and know about all LaunchMode flags, for example LaunchMode.SingleTask which allows you bring the initiator activity to front without creating a new one.
It's not clear to me, is BrowseVm a parent view-model to the LeafDetailVM?
More info would be needed to understand exactly your scenario.

AngularJS form wizard save progress

I have a service in AngularJS that generates all the steps needed, the current state of each step (done, current, show, etc) and an associated directive that actually implements the service and displays the data of the service. But, there are 2 steps that are divided in 4 and 3 steps each:
Step one
Discounts
Activities
Duration
Payment Length
Step two
Identification
Personal data
Payment
How can I "save" the state of my form in case the person leaves the site and comes back later? Is it safe to use localStorage? I'm no providing support for IE6 or 7. I thought of using cookies, but that can end up being weak (or not)
Either local storage or cookies should be fine. I doubt this will be an issue, but keep in mind that both have a size limit. Also, it goes without saying that the form state will only be restored if the user returns on the same browser, and without having deleted cookies / local storage.
Another option could be to save the information server side. If the user is signed in, you can make periodic AJAX calls with the data and store the state on the server. When the user finishes all steps, you can make an AJAX call telling the server to delete any saved data it might have. This allows you to restore state even if the user returns on a different browser, as long as he is signed in.
Regardless of what direction you go with this, you can use jQuery's serialize method to serialize the form into a string and save it using your choice of storage.

Oracle APEX - HTML Links Breaks Session and Requires New Login

Ok so here is what is happening:
I have a client that I am building an application for. My client has a flowchart that they would like posted on the front page of their application. Check. My client then wants this flowchart to be set up as an image map so that a user could click one of the boxes in this flowchart and be taken to a report in another part of the application. Check.
All of that is elementary and, in a technical sense, works. The issue is, and it is an issue I have encountered before with APEX, is that every time a user clicks one of these links it takes them to the login screen. It seems that linking directly to a page's URL breaks the session and requires you to login again, even if you are linking from one page in the application to another in the same application.
I have played with all of the authentication settings in a hopes of fixing this and tried to determine what is breaking the session exactly but with no luck.
Has anyone else had this problem and could share their method for fixing it? I really cant have users logging in every time they click a link and I also cannot simply remove the authentication on the pages. Thanks in advance.
You should pass on the session id in your links. If you don't, then apex will see this as a new session. You can tell from the url: take note of the session id in your url when you are on your image map. When you select an application, take another look at the session id part in the url. If they are different, then you are starting a new session each time.
/apex/f?p=190:90:1674713700462259:::::
190 -> application id
90 -> page id
1674713700462259 -> Session id
To pass on the session, it depends where you construct your links.
In PLSQL, you can find it through :SESSION or :APP_SESSION
For example, in a plsql dynamic region: htp.p('the session id is '||:SESSION);
In javascript code you can use $v("pInstance") to retrieve the value dynamically, or use &APP_SESSION. which will have the value substituted at runtime.
Small example:
function printsome(){
var d = $("<div></div>");
d.text('&APP_SESSION. = ' + $v("pInstance"));
$("body").append(d);
};
So you probably just need to alter the construction of your link somewhat to include the session!
I was assuming the binding variables will do the job. But they were helpless.
Best way is to pass the current session id to an item then use the item value in the link.
f?p=&APP_ID.:32:&P31_SESSION.:::P32_CUSTOMER_ID:#CUSTOMER_ID#

Databinding issue about updating data issue between MySQL database and my devexpress Gauge value?

Background:
Developing a trading system which subscribe to many events which are sent by API of Interactive Brokers. One interesting event is about my trading account value which fluctuates during trading hour so I would prefer to see the information with accountvalueupdate event immediately. I develop this one based on ActiveX api and c# in Visual Studio 2010.
the presentation I wanna check this information is to use a gauge developed by(http://www.devexpress.com/Products/NET/Controls/WinForms/Gauges/). This gauge looks fancy but the principle should be similar to the normal gauge we use in Visual Studio. It seems like I could only update the value of the gauge by databinding since I tried to assign updated account value to this.myGauge.value and failed.
I build up MySql connection between MySql and VS2010. I create only one table in MySQL which is called account. For the sake of simplicity, i only have two column(accountID and accountValue) and one row|(which means when event comes with new accountValue, I just overwrite the value of accountValue last session then the number of row is always one. really simple idea.....).In that Gauge proporties I found databinng option and I setted up by using advanced option to navigate throw available table and bind it to the only useful column accountValue.
Issue:
I set up the default value of the accountValue as 500 as default for test. I build my software. The gauge shows 500 correctly.
Of course, my real account value is not 500, so Now I click one button to connect to API and start listening the event. After few seconds, event arrives since I opened on Console for managing the mysql table and use select * from account to continuously watch the update. I noticed the value of accountValue column(TABLE WORKS RIGHT AND WE ONLY HAVE ONE ROW, OEVERWRITTING MODE) becomes the right one, for example, 35000.
HOWEVER, THE GAUGE DOES NOT CHANGE AT ALL...!! Now If i closed my software and build again, the gauge shows the right value 35000. Now I shut down the api and no coming event and only use commandline of mysql to change the value of accountValue again to 500. NO UPDATING in gauge as well.
It looks like the gauge only read the value of table during the build session or when it starts and never listen to the update of binding databases.
By the way, I tried to set up the biding data mode to either "onValidation" or "onPropertieschanged" but it does not solve although the "onPropertieschanged" looks the right one....
I tried to assign updated account value to this.myGauge.value...
Unfortunately, the information you provided doesn't allow to clearly diagnose this problem. There is no the Value property neither in WinForms GaugeControl nor in CircularGauge (as soon as in Linear/Digital/StateIndicator gauge), but only in ASPxGaugeControl (ASPxGaugeControl.Value). So, please provide a full sample code that doesnot work on your side.
All these properties can be changed manually in code or data-bound to data sources using the standard .NET data-binding mechanism:
The ArcScaleComponent.DataBindings property allows you to data-bind
to the current value of a circular gauge's scale (ArcScale.Value).
The LinearScaleComponent.DataBindings property allows you to
data-bind to the current value of a linear gauge's scale
(LinearScale.Value).
The DigitalGauge.DataBindings property allows you to data-bind to the
text displayed by a digital gauge.
The StateIndicatorComponent.DataBindings property allows you to
data-bind to a state of a state indicator gauge.
Please, review the following articles for more details: Data Binding.
The databinding feature is demonstrated in the Gauge's Main Demo project (the DataBinding module):
this.arcScaleComponent2.DataBindings.Add(
new System.Windows.Forms.Binding("Value", this.productsBindingSource,
"UnitsOnOrder", true, System.Windows.Forms.DataSourceUpdateMode.Never));
P.S. Please use the DevExpress Support Center to ask a questions or report issues, because there is no guarantee of DX involvement when you use the communities, newsgroups or other communication channels.