-
Notifications
You must be signed in to change notification settings - Fork 8
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
Add standard ensembler UI #37
Add standard ensembler UI #37
Conversation
6a7b396
to
24cad60
Compare
e8b3055
to
968fdde
Compare
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.
LGTM on the whole, left some comments to be addressed, thank you @deadlycoconuts !
ui/src/turing/components/configuration/StandardEnsemblerConfigDetails.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/configuration/standard_ensembler_config/RouteNamePathConfigGroup.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/configuration/standard_ensembler_config/RouteNamePathConfigGroup.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/form/standard_ensembler/LinkedExperimentsContextMenu.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/form/standard_ensembler/LinkedExperimentsContextMenu.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/form/standard_ensembler/RouteNamePathFlyout.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/form/standard_ensembler/LinkedRoutesTable.js
Outdated
Show resolved
Hide resolved
</EuiButtonEmpty> | ||
); | ||
|
||
return isButtonPopoverOpen[item.id] ? ( |
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.
Let's use &&
and not have a ternary that returns null
here.
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.
Thanks for catching that! I've just edited it!
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.
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.
Should be addressed by this suggestion - #37 (comment).
field: "status", | ||
width: "5px", | ||
render: (_, item) => { | ||
const isAssigned = routeToExperimentMappings[item.id] ? |
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.
status
and route_name
column computations seem to be duplicated here. Would it make sense to pre-aggregate all column values prior to passing them into the items
prop of EuiInMemoryTable
?
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.
All the columns (with the exception of status
) actually use multiple column values (of the rows in items
, which represents the routes configured) to render the cells of the table. While it's easy to precompute the cells for status
(isAssigned
is the only value needed to determine status
) and store them as a column, route_name
for example needs both the value of isAssigned
as well as the id
of each route.
This poses a problem because it's not possible to pass 2 (or more) values into the field
prop of EuiTableFieldDataColumnType
for the EuiBasicTable
to extract both values and then pass them as arguments to the function specified in the render
prop. This means that whatever precomputed values aggregated in advance would only be useful for the partially rendering each cell, because the function of the render
prop would still have to access or compute other values from each row on-the-fly to determine how the cell ultimately gets rendered.
That said, I think this makes aggregating the computations in advance less useful than expected, since we aren't just extracting a single value to display for each cell, and still relying on the render
prop to perform the rendering.
On the other hand, I've not tried precomputing each column as a ReactNode
component and then getting the table to extract these values as is (without having to rely on the render
function) i.e. having the field
-s set as "column_1"
, "column_2"
, "column_3"
..., and then having these keys within each of the elements in items
corresponding to <Column1... />
, <Column2... />
, <Column3... />
, ... 🤔
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.
Just a slight update on this, I think we can just use id
in the field
for all of the columns, and then get the render
function to do something with the id
since we're almost always using the routeToExperimentMappings
with the route name.
@@ -13,7 +13,7 @@ export const getExperimentStatus = (experiment) => { | |||
const statusMapping = { | |||
Deactivated: { | |||
label: "Deactivated", | |||
color: "subdued", | |||
color: "#6A717D", |
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.
Fixed this colour which is no longer supported as part of the EUI colour palette; it now needs to be specified manually with a colour hex.
}) => { | ||
const { appConfig } = useConfig(); | ||
|
||
const [isButtonPopoverOpen, setIsButtonPopoverOpen] = useState(routes.reduce((m, r) => {m[r.id] = {running: false, scheduled: false}; return m}, {})); |
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.
Hmmm having this state in the parent component makes the implementation a little more complex and less coupled with the button that it belongs to. Can this be defined directly inside LinkedExperimentsContextMenu
component so that each clickable item has its own state? And can it simply track true/false
? Then, if any of them are true, we can use the routeToExperimentMappings
to list the experiments in the popover, for that specific status - right?
We will be creating more state variables but since they are all lean, I don't think that should be a problem.
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.
I remember making a conscious choice to manage all the states within the parent because creating the individual states within LinkedExperimentsContextMenu
somehow threw some error or minimally a warning regarding the creation of individual states by looping through with the function in render
. I'll try to reproduce the issue again and share that error again.
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.
Okay I can't seem to get the error to reappear, maybe it was something else :/ I've made the changes to track the state of each button within each LinkedExperimentsContextMenu
, and we'll be using useToggle
to get the true/false
state of the button.
ui/src/turing/components/form/standard_ensembler/LinkedRoutesTable.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/form/standard_ensembler/LinkedRoutesTable.js
Outdated
Show resolved
Hide resolved
Thanks everyone for all the comments! I should've most of them covered. There's some significant refactoring done to |
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.
Thanks @deadlycoconuts , PR looks cleaner now! I left some small comments - feel free to merge after addressing them 😄
ui/src/turing/components/form/standard_ensembler/LinkedExperimentsContextMenu.js
Outdated
Show resolved
Hide resolved
ui/src/turing/components/form/standard_ensembler/RouteNamePathFlyout.js
Outdated
Show resolved
Hide resolved
|
||
// this stringified value of routes below allows the React effect below to mimic a deep comparison when changes to the | ||
// array routes are made | ||
const stringifiedRoutes = JSON.stringify(routes) |
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.
Would it be better to use the ids only?
const stringifiedRoutes = routes.map(e => e.id).join()
It seems like all of the issues on this PR has been resolved; I'll be merging this in a short while! Thanks a lot everyone for your time! :) |
What this PR does / why we need it:
With the changes introduced in Turing to support the usage of Standard Ensemblers with Custom Experiment Engines, the Turing Experiments UI has been updated in this PR to expose Standard Ensembler components consumed by the Turing UI.
There are two new components that Turing Experiments UI will now expose -
EditStandardEnsemblerConfig
andStandardEnsemblerConfigDetails
. As their names suggest, they are used respectively for the create/edit router form and the router details view in the Turing UI respectively.StandardEnsemblerConfigDetails
EditStandardEnsemblerConfig
Sample User Workflow
Screen.Recording.2022-09-21.at.5.46.07.PM.mov
In addition, the
appConfig
now has a newrouteNamePathPrefix
field that specifies the path prefix that gets appended to a user-defined treatment configuration. This path prefix reflects the nesting of the treatment configuration within the final response payload that the treatment service, and/or subsequently the Turing Experiments plugin, sends back to the client.For example, if the user-defined treatment configuration is:
and the client response is as follows:
then the path prefix will have to be specified as
treatment.configuration.
(including the final period).Main Modifications
ui/craco.config.js
- Addition of the exposed component paths to be consumed by theModuleFederationPlugin
ui/src/config.js
- Addition of therouteNamePathPrefix
field to theappConfig
ui/src/turing/components/configuration/StandardEnsemblerConfigDetails.js
- Addition of the newStandardEnsemblerConfigDetails
component to be exposedui/src/turing/components/form/EditStandardEnsemblerConfig.js
- Addition of the newEditStandardEnsemblerConfig