Skip to content
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

Merged
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5feb2ac
Add standard ensembler component
deadlycoconuts Sep 16, 2022
b8cbf82
Simplify react effects used in affected routes list panel
deadlycoconuts Sep 18, 2022
d0b8b0a
Add popover to list the affected experiments
deadlycoconuts Sep 18, 2022
2f3ea20
Fix empty titles in EuiDescriptionList
deadlycoconuts Sep 19, 2022
b8365fb
Add context menu to display affected experiments
deadlycoconuts Sep 19, 2022
bb4ace6
Fix styles in prop passing
deadlycoconuts Sep 19, 2022
a7de94a
Add tooltip and color to affected experiments menu
deadlycoconuts Sep 20, 2022
7429a77
Add standard ensembler config view
deadlycoconuts Sep 20, 2022
4289b85
Fix lint comments
deadlycoconuts Sep 21, 2022
9e56ccb
Add help flyout to explain route name path prefix
deadlycoconuts Sep 21, 2022
2762412
Update deprecated subdued EUI colour with colour hex
deadlycoconuts Sep 22, 2022
6e5cddf
Rename affected experiments and routes component to linked experiment…
deadlycoconuts Sep 22, 2022
9dd11c7
Reword route path prefix explanation
deadlycoconuts Sep 22, 2022
968fdde
Fix lint comments
deadlycoconuts Sep 22, 2022
0017478
Fix incorrect language type specified for code block
deadlycoconuts Sep 23, 2022
23ad1a4
Replace style used to pass items to the list in RouteNamePathConfigGroup
deadlycoconuts Sep 23, 2022
0dd528c
Rename misleading variable names and remove redundant tags
deadlycoconuts Sep 23, 2022
a71f04e
Replace relative import path with absolute path
deadlycoconuts Sep 23, 2022
7dc089e
Replace colour hexes corresponding to subdued to default
deadlycoconuts Sep 23, 2022
73d673f
Refactor experiments loading into a context provider
deadlycoconuts Sep 23, 2022
6234f6d
Standardise naming of all providers to be singular wherever logical
deadlycoconuts Sep 23, 2022
caa20c7
Make popover management distributed across each component
deadlycoconuts Sep 23, 2022
7005210
Refactor LinkedRoutesTable to utilise id from list of routes to rende…
deadlycoconuts Sep 23, 2022
584c0e3
Revert incorrect edit made to docstrings
deadlycoconuts Sep 23, 2022
fd79dbf
Refactor LinkedRoutesTable
deadlycoconuts Sep 26, 2022
6f82e3e
Consume route name path in flyout from config
deadlycoconuts Sep 26, 2022
5f8d17f
Simplify effect dependency on routes in LinkedRoutesTable
deadlycoconuts Sep 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ui/craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ module.exports = ({ }) => ({
"./EditExperimentEngineConfig": "./src/turing/components/form/EditExperimentEngineConfig",
"./ExperimentEngineConfigDetails": "./src/turing/components/configuration/ExperimentEngineConfigDetails",
"./ExperimentsLandingPage": "./src/experiments/ExperimentsLandingPage",
"./EditStandardEnsemblerConfig": "./src/turing/components/form/EditStandardEnsemblerConfig",
"./StandardEnsemblerConfigDetails": "./src/turing/components/configuration/StandardEnsemblerConfigDetails"
},
filename: "remoteEntry.js",
shared: {
Expand Down
1 change: 1 addition & 0 deletions ui/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const appConfig = {
// Padding of page template
paddingSize: "none",
},
routeNamePathPrefix: "treatment.configuration."
};

const sentryConfig = {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/services/experiment/ExperimentStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const getExperimentStatus = (experiment) => {
const statusMapping = {
Deactivated: {
label: "Deactivated",
color: "subdued",
color: "default",
iconType: "cross",
},
Completed: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from "react";
import { ConfigProvider, useConfig } from "config";
import { EuiFlexGroup, EuiFlexItem } from "@elastic/eui";
import { ConfigSectionPanel } from "components/config_section/ConfigSectionPanel";
import { LinkedRoutesTable } from "turing/components/form/standard_ensembler/LinkedRoutesTable";
import { RouteNamePathConfigGroup } from "./standard_ensembler_config/RouteNamePathConfigGroup";
import { ProjectContextProvider } from "providers/project/context";

const StandardEnsemblerConfigDetailsComponent = ({ projectId, routes, routeNamePath }) => {
const { appConfig: { routeNamePathPrefix } } = useConfig();

return (
<ConfigProvider>
<EuiFlexGroup direction="row" wrap>
<EuiFlexItem grow={1} className="euiFlexItem--smallPanel">
<ConfigSectionPanel title="Route Selection" className="experimentSummaryPanel">
<RouteNamePathConfigGroup routeNamePath={routeNamePath} />
</ConfigSectionPanel>
</EuiFlexItem>

<EuiFlexItem grow={2} className="euiFlexItem--smallPanel">
<ConfigSectionPanel title="Linked Routes" className="linkedRoutesPanel">
<LinkedRoutesTable
projectId={projectId}
routes={routes}
treatmentConfigRouteNamePath={routeNamePath.slice(routeNamePathPrefix.length)}
/>
</ConfigSectionPanel>
</EuiFlexItem>
</EuiFlexGroup>
</ConfigProvider>
);
};

const StandardEnsemblerConfigDetails = (props) => {
return (
<ConfigProvider>
<ProjectContextProvider>
<StandardEnsemblerConfigDetailsComponent {...props} />
</ProjectContextProvider>
</ConfigProvider>
)
};

export default StandardEnsemblerConfigDetails;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";

import {
EuiDescriptionList,
EuiTitle,
} from "@elastic/eui";

export const RouteNamePathConfigGroup = ({ routeNamePath }) => {
return (
<EuiTitle size="xs">
<EuiDescriptionList
compressed
textStyle="reverse"
type="responsiveColumn"
listItems={[
{
title: "Route Name Path",
description: routeNamePath,
},
]}
titleProps={{ style: { width: "30%" } }}
descriptionProps={{ style: { width: "70%" } }}
/>
</EuiTitle>
);
};
80 changes: 80 additions & 0 deletions ui/src/turing/components/form/EditStandardEnsemblerConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { useContext, useRef } from "react";

import { EuiCallOut, EuiFlexItem, EuiLoadingChart, EuiHorizontalRule } from "@elastic/eui";
import { OverlayMask } from "@gojek/mlp-ui";

import { Panel } from "components/panel/Panel";
import { ConfigProvider, useConfig } from "config";
import ProjectContext, { ProjectContextProvider } from "providers/project/context";
import { SettingsContextProvider } from "providers/settings/context";
import { LinkedRoutesTable } from "./standard_ensembler/LinkedRoutesTable";
import { RouteNamePathRow } from "./standard_ensembler/RouteNamePathRow";

const EditStandardEnsemblerConfigComponent = ({
projectId,
routes,
routeNamePath = "",
onChange,
errors,
}) => {
const { appConfig: { routeNamePathPrefix } } = useConfig();

const { isProjectOnboarded, isLoaded } = useContext(ProjectContext);
const overlayRef = useRef();

return (
<EuiFlexItem grow={false}>
{isLoaded ? (
isProjectOnboarded(projectId) ? (
<SettingsContextProvider projectId={projectId}>
<Panel title={"Route Selection"}>
<RouteNamePathRow
routeNamePath={routeNamePath}
routeNamePathPrefix={routeNamePathPrefix}
onChange={onChange}
errors={errors}
/>

<EuiHorizontalRule />

<LinkedRoutesTable
projectId={projectId}
routes={routes}
treatmentConfigRouteNamePath={routeNamePath.slice(routeNamePathPrefix.length)}
/>
</Panel>
</SettingsContextProvider>
) : (
<Panel title={"Configuration"}>
<EuiCallOut
title={"Project not onboarded to Experiments"}
color={"danger"}
iconType={"alert"}>
<p>
{"Please complete onboarding to Turing experiments to configure the standard ensembler."}
</p>
</EuiCallOut>
</Panel>
)
) : (
<div ref={overlayRef}>
<OverlayMask parentRef={overlayRef} opacity={0.4}>
<EuiLoadingChart size={"xl"} mono />
</OverlayMask>
</div>
)}
</EuiFlexItem>
);
};

const EditStandardEnsemblerConfig = (props) => {
return (
<ConfigProvider>
<ProjectContextProvider>
<EditStandardEnsemblerConfigComponent {...props} />
</ProjectContextProvider>
</ConfigProvider>
)
};

export default EditStandardEnsemblerConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from "react";

import {
EuiContextMenu,
EuiPopover,
EuiButtonEmpty,
EuiLink,
EuiIcon
} from "@elastic/eui";

export const LinkedExperimentsContextMenu = ({
item,
projectId,
routeToExperimentMappings,
isButtonPopoverOpen,
setIsButtonPopoverOpen,
experimentStatus
}) => {
let numExperiments = routeToExperimentMappings[item.id] ? Object.keys(routeToExperimentMappings[item.id][experimentStatus]).length : 0;

const onButtonClick = () => {
let newIsButtonPopoverOpen = { ...isButtonPopoverOpen };
newIsButtonPopoverOpen[item.id][experimentStatus] = !isButtonPopoverOpen[item.id][experimentStatus];
setIsButtonPopoverOpen(newIsButtonPopoverOpen);
};

const closePopover = () => {
let newIsButtonPopoverOpen = { ...isButtonPopoverOpen };
newIsButtonPopoverOpen[item.id][experimentStatus] = false;
setIsButtonPopoverOpen(newIsButtonPopoverOpen);
};

const button = (
<EuiButtonEmpty
size={"s"}
iconType={"arrowRight"}
iconSide={"right"}
color={"primary"}
onClick={onButtonClick}
isDisabled={numExperiments === 0}
>
{numExperiments}
</EuiButtonEmpty>
);

return isButtonPopoverOpen[item.id] && (
<EuiPopover
button={button}
isOpen={isButtonPopoverOpen[item.id][experimentStatus]}
closePopover={closePopover}
panelPaddingSize={"none"}
anchorPosition={"rightCenter"}
>
<EuiContextMenu
initialPanelId={0}
panels={
[
{
id: 0,
title: `Linked ${experimentStatus[0].toUpperCase() + experimentStatus.slice(1)} Experiments`,
items: Object.values(routeToExperimentMappings[item.id][experimentStatus]).map(e => (
{
name: (
<EuiLink href={`/turing/projects/${projectId}/experiments/${e.id}/details`} external={false} target={"_blank"}>
{e.name}
</EuiLink>
),
icon: <EuiIcon type={"popout"} size={"m"} color={"primary"} />,
size: "s",
toolTipContent: "Open experiment details page",
toolTipPosition: "right",
}
))
}
]
}
/>
</EuiPopover>
);
};
Loading