phetsims / joist

Joist is the main framework for PhET Interactive Simulations. Joist creates and displays the simulation content, home screen, navigation bar, About dialog, enables switching between tabs, and other framework-related features.
MIT License
8 stars 6 forks source link

Provide a UI for setting query parameters for a simulation #576

Open samreid opened 5 years ago

samreid commented 5 years ago

In https://github.com/phetsims/energy-forms-and-changes/issues/216 we discussed a new feature which would show a user interface for selecting query parameters for the simulation.

From the notes, @chrisklus remarked:

We will investigate adding a pre-launch dialog to select which elements you want to include, then update the model to respect those query params. These query params would actually remove items when setting up the sim at startup, not just hide them.

@zepumph suggested moving this customization as an optional menu dialog located in the sim along with a button to relaunch the sim once the customizations are applied. This would allow for the customization to be confined to one place, instead of every entry point for the sim. In Studio, we would need to find a way to relaunch Studio, not just the sim itself.

This pattern would also make customizing for phet brand simpler, because the website's sim page wouldn't need to know about which query params are available for a given sim version.

We'll bring this up in design meeting and discuss further.

There were a few more comments in https://github.com/phetsims/energy-forms-and-changes/issues/216#issuecomment-533355597 and below which culminated in the suggestion that each sim have a separate HTML page for the customization UI (reachable from outside the sim). It's unclear how that would work with PhET-iO.

zepumph commented 5 years ago

In what way would you like my assistance in this issue? It sounds mainly like a space for design and prototyping the UI of the auxiliary html page.

Ideas about the page: We could outfit queryStringMachine to accept the public/private aspect of the query parameters into its schema. Then in the Web page we could load separate copies of init globals to get a list of the public ones. (one bad way would be to load dependencies.json and from that get the right Sha and request init globals from github). We could also keep a separate list the is filled in during the build. It would be annoying to have to build this page though.

For phetio, the base feature could be to also include phetio query parameters in this page, and have it load the standalone version. Then those query parameters can be copied into launching another wrapper, or copied into the launchSim option if creating a wrapper.

samreid commented 5 years ago

The next step for this issue is discussion at an upcoming PhET-iO team meeting, I've marked it in the next agenda. Unassigning until then.

chrisklus commented 5 years ago

Notes from 09/26/19 design meeting:

We are likely not going to hard code this feature right into Studio, but @samreid, @zepumph, and @chrisklus are going to investigate implementing something that is able to be versioned with sims.

We are also open to making this a feature for phet-brand in the future, perhaps by adding a link on sim pages that opens a customization dialog before launching the sim. Adding this functionality to the app was also mentioned. For now, we are going to focus on getting a proof of concept working for just phet-io.

samreid commented 5 years ago

We also discussed that it seems reasonable to build this as a separate HTML page during the build. This page should be able to pass-through to studio or to the sim itself.

zepumph commented 5 years ago

@samreid, @chrisklus, and I spoke about this today from an implementation standpoint. The main tenants we were thinking about are to have an HTML file built with the sim that is some sort of form that gives you the proper query string or URL from the output of the form.

To get this, we need a way to access all query parameter schemas from the build process. Ideally this wouldn't be puppeteer, as adding that will greatly increase the time of the build. So then we thought that making all query parameter files preloads, to be available from the build and from the sim runtime made sense.

We are not certain about anything yet, here is just some output from investigation:

    cuvetteSnapInterval: {
      type: 'number',
      defaultValue: BLLConstants.DEFAULT_CUVETTE_SNAP_INTERVAL,
      isValidValue: function( value ) {
        return value >= 0;
      }

This is annoying to convert to JSON/js preload because the default value is a sim constant. It is really nice to have defaultValues coming from the sim

const defaultElements = [ EFACConstants.IRON_KEY, EFACConstants.BRICK_KEY, EFACConstants.WATER_KEY, EFACConstants.OLIVE_OIL_KEY ];
. . . 
    elements: {
      type: 'array',
      defaultValue: defaultElements,
      elementSchema: { type: 'string' },
      isValidValue: values => _.difference( values, defaultElements ).length === 0 &&
                              values.length <= EFACConstants.MAX_NUMBER_OF_INTRO_ELEMENTS
    }

For the same reason as with cuvetteSnapInterval, this isValidValue function from EFAC is nice in the sim because it uses the sim value. Also note too the defaultValue is a constant created during requirejs.

Perhaps simple isValidValue functions, like isValidValue: value => value >= 0, could be covered by some JSON syntax? Or is we use js preload, this is a non-issue


One thing we could do to handle elements that can't be a js preload, is to fill in pieces of the schema in the requirejs step before getting the QP. This feels gross in a variety of ways, not least of which is that now in the preload schema, we have no idea what valid values are for the elements below. How would we write an HTML component to choose the appropriate value for that that was not manual? Here is what the query parameters file could then look like.


  const schema = window.EFAC.preloads.queryParametersSchema;

  // constants
  const defaultElements = [ EFACConstants.IRON_KEY, EFACConstants.BRICK_KEY, EFACConstants.WATER_KEY, EFACConstants.OLIVE_OIL_KEY ];

  schema.elements.defaultValue = defaultElements;
  schema.elements.isValidValue = values => _.difference( values, defaultElements ).length === 0 &&
                                           values.length <= EFACConstants.MAX_NUMBER_OF_INTRO_ELEMENTS

  const EFACQueryParameters = QueryStringMachine.getAll( schema );
samreid commented 5 years ago

Another possibility would be to load just the sim query parameters in requirejs mode. For instance, change:

Index: js/energy-forms-and-changes-config.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- js/energy-forms-and-changes-config.js   (revision 027bbf5e6c0c1faa2872d287822616af95080b63)
+++ js/energy-forms-and-changes-config.js   (date 1569623317020)
@@ -10,7 +10,7 @@

 require.config( {

-  deps: [ 'energy-forms-and-changes-main' ],
+  deps: [ 'common/EFACQueryParameters' ],

   paths: {

Then load the sim, and you will have access to the query parameters via phet.energyFormsAndChanges.EFACQueryParameters. This could likely be evaluated in Node instead of puppeteer, and would likely be very fast.

samreid commented 5 years ago

From slack:

We could harvest the query parameters and output a JSON file or HTML file during grunt update

samreid commented 5 years ago

Could this replace some of the functionality in phetmarks?

image

samreid commented 5 years ago

Some notes from discussion with @zepumph and @chrisklus

Should we move everything to the PhET-iO API? Do some things have to remain as query parameters?

If some features are buried in query parameters, how can we API validate them?

If the query-parameter-free version is a superset, we should be ok. If a query parameter adds a new tandem, that will not be API validate-able

In the future, we want to make phet brand customizable.

investigation: EFAC QP should subset, not change

Wouldn't it be better to (a) have one way of doing things? (b) be able to validate the API?

Those suggest we should do everything from phetio-api/studio and not so much from query parameters.

But aren't query parameters sometimes easier than developing the PhET-iO API for this?

Yes, but this must be weighed against the cost of (a) and (b)

Maybe GroupIO should have a remove method, which is leveraged in studio.

samreid commented 5 years ago

Best of both worlds, use Groups to power everything in implementation, and QP as a way to specify it on startup?

Maybe schedule group as primary objective, and plan on not using query parameters. We will eventually want a QP UI for phet-brand sims.

samreid commented 5 years ago

If we come back to wanting a query parameter page for each sim, I think the first version should be handcrafted rather than harvested from query string machine schemas.

samreid commented 4 years ago

Discussion from slack today:

Chris Malley 12:57 PM
Ariel has stated several times that there's work being done on Studio to add a query parameter UI.  This was in the context of Natural Selection design, where query parameters are part of client requirements. Is there an issue for that work?

Sam Reid 12:58 PM
https://github.com/phetsims/joist/issues/576

Chris Malley 12:58 PM
Ah... So it's not specific to Studio?
Or PhET-iO?  (not labeled as phet-io)

Sam Reid 12:59 PM
Eventually we want to support it for PhET Brand too

Chris Malley 12:59 PM
I think there's an expectation that "eventually" is a requirement for Natural Selection 1.0.0.

Sam Reid 12:59 PM
What is the specific requirement for NS1.0?

Chris Malley 1:00 PM
So far... Specifying the initial population, and hiding alleles.  https://github.com/phetsims/natural-selection/issues/9, https://github.com/phetsims/natural-selection/issues/24 (edited) 

Sam Reid 1:01 PM
For PhET Brand or PhET-iO brand only?

Chris Malley 1:01 PM
Both, for 1.0

Sam Reid 1:03 PM
Is there a mock-up of what the PhET brand UI should look like for it?

Chris Malley 1:04 PM
That's what I was asking you.  I'm not involved in creating this UI.  I've been told that the PhET-iO team is working on it. (edited) 

Sam Reid 1:05 PM
We worked on it and realized a few things:
The first version should be hand-crafted, rather than harvested from QueryStringMachine options
We should have a designer involved in creating what it should look like and what the flow should be
We would like the query parameters to leverage the PhET-iO API or PhET brand API, not change it, and hence be validate-able
(edited)
new messages

Chris Malley 1:07 PM
What is the timeframe for completing it?

Sam Reid 1:08 PM
That would be a great discussion for Thursday! I’ll mark #576 for discusison
pixelzoom commented 4 years ago

FYI, Natural Selection 1.0 will be specifying query parameters manually in the URL.

samreid commented 4 years ago

I summarized that since Query Parameter features must be backed by PhET-iO features so they can be API-trackable, adding a separate UI seems less important since the studio API will already work.

@chrisklus reported that this is working well in EFAC.

@kathy-phet reports that this issue can be deferred. It's not high priority.