diff --git a/frontend/src/component/playground/Playground/AdvancedPlayground.tsx b/frontend/src/component/playground/Playground/AdvancedPlayground.tsx index c3b1e6edae..ff1142a930 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlayground.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlayground.tsx @@ -24,7 +24,7 @@ import { AdvancedPlaygroundResponseSchema } from 'openapi'; export const AdvancedPlayground: VFC<{}> = () => { const { environments: availableEnvironments } = useEnvironments(); const theme = useTheme(); - const matches = useMediaQuery(theme.breakpoints.down('lg')); + const matches = true; const [environments, setEnvironments] = useState([]); const [projects, setProjects] = useState([]); diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx new file mode 100644 index 0000000000..ab6969be96 --- /dev/null +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx @@ -0,0 +1,76 @@ +import { Link, Popover, styled, Typography, useTheme } from '@mui/material'; +import { flexRow } from '../../../../../themes/themeStyles'; +import React, { useState } from 'react'; +import { + AdvancedPlaygroundEnvironmentFeatureSchema, + AdvancedPlaygroundFeatureSchemaEnvironments, +} from 'openapi'; +import { PlaygroundEnvironmentTable } from '../../PlaygroundEnvironmentTable/PlaygroundEnvironmentTable'; +import { PlaygroundEnvironmentDiffTable } from '../../PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable'; + +const StyledContainer = styled( + 'div', + {} +)(({ theme }) => ({ + flexGrow: 0, + ...flexRow, + justifyContent: 'flex-start', + margin: theme.spacing(0, 1.5), +})); + +const StyledButton = styled(Link)(({ theme }) => ({ + textAlign: 'left', + textDecorationStyle: 'dotted', + textUnderlineOffset: theme.spacing(0.75), + color: theme.palette.neutral.dark, +})); + +export interface IAdvancedPlaygroundEnvironmentCellProps { + value: AdvancedPlaygroundFeatureSchemaEnvironments; +} + +export const AdvancedPlaygroundEnvironmentDiffCell = ({ + value, +}: IAdvancedPlaygroundEnvironmentCellProps) => { + const theme = useTheme(); + const [anchor, setAnchorEl] = useState(null); + + const onOpen = (event: React.MouseEvent) => + setAnchorEl(event.currentTarget); + + const onClose = () => setAnchorEl(null); + + const open = Boolean(anchor); + + return ( + + <> + + Preview diff + + + + + Environments diff + + + + + + ); +}; diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx index ef0daea09d..2c3d78db30 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx @@ -34,6 +34,7 @@ import { AdvancedPlaygroundFeatureSchema, } from 'openapi'; import { capitalizeFirst } from 'utils/capitalizeFirst'; +import { AdvancedPlaygroundEnvironmentDiffCell } from './AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell'; const defaultSort: SortingRule = { id: 'name' }; const { value, setValue } = createLocalStorage( @@ -111,7 +112,9 @@ export const AdvancedPlaygroundResultsTable = ({ id: 'diff', align: 'left', Cell: ({ row }: any) => ( - Preview diff + ), }, ]; diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx new file mode 100644 index 0000000000..5ef68dab71 --- /dev/null +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx @@ -0,0 +1,101 @@ +import React, { useMemo, useRef } from 'react'; +import { + useFlexLayout, + useGlobalFilter, + useSortBy, + useTable, +} from 'react-table'; + +import { VirtualizedTable } from 'component/common/Table'; +import { sortTypes } from 'utils/sortTypes'; +import { AdvancedPlaygroundFeatureSchemaEnvironments } from 'openapi'; +import { Box } from '@mui/material'; +import { FeatureStatusCell } from '../PlaygroundResultsTable/FeatureStatusCell/FeatureStatusCell'; +import { HighlightCell } from '../../../common/Table/cells/HighlightCell/HighlightCell'; +import { capitalizeFirst } from 'utils/capitalizeFirst'; + +interface IPlaygroundEnvironmentTableProps { + features: AdvancedPlaygroundFeatureSchemaEnvironments; +} + +export const PlaygroundEnvironmentDiffTable = ({ + features, +}: IPlaygroundEnvironmentTableProps) => { + const environments = Object.keys(features); + const firstEnvFeatures = features[environments[0]]; + const firstContext = firstEnvFeatures[0].context; + + const data = useMemo( + () => + firstEnvFeatures.map((item, index) => ({ + ...Object.fromEntries( + environments.map(env => [env, features[env][index]]) + ), + })), + [JSON.stringify(features)] + ); + type RowType = typeof data[0]; + + const contextFieldsHeaders = Object.keys(firstContext).map( + contextField => ({ + Header: capitalizeFirst(contextField), + accessor: `${environments[0]}.context.${contextField}`, + minWidth: 160, + Cell: HighlightCell, + }) + ); + + const environmentHeaders = environments.map(environment => ({ + Header: environment, + accessor: (row: RowType) => + row[environment]?.isEnabled + ? 'true' + : row[environment]?.strategies?.result === 'unknown' + ? 'unknown' + : 'false', + Cell: ({ row }: { row: { original: RowType } }) => { + return ; + }, + sortType: 'playgroundResultState', + maxWidth: 120, + })); + + const COLUMNS = useMemo(() => { + return [...contextFieldsHeaders, ...environmentHeaders]; + }, []); + + const { headerGroups, rows, prepareRow } = useTable( + { + columns: COLUMNS as any[], + data, + sortTypes, + autoResetGlobalFilter: false, + autoResetHiddenColumns: false, + autoResetSortBy: false, + disableSortRemove: true, + disableMultiSort: true, + }, + useGlobalFilter, + useFlexLayout, + useSortBy + ); + + const parentRef = useRef(null); + + return ( + + + + ); +}; diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx index 85b1e8aa84..3b6c9a1ac7 100644 --- a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx @@ -42,5 +42,5 @@ test('should render environment table', async () => { expect(screen.getByText('clientA')).toBeInTheDocument(); expect(screen.getByText('variantName')).toBeInTheDocument(); expect(screen.getByText('False')).toBeInTheDocument(); - expect(screen.queryByText('myapp')).not.toBeInTheDocument(); + expect(screen.getByText('myapp')).toBeInTheDocument(); }); diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx index 61d5dfc703..5a55afa49f 100644 --- a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx @@ -30,14 +30,14 @@ export const PlaygroundEnvironmentTable = ({ const theme = useTheme(); const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); - const dynamicHeaders = Object.keys(features[0].context) - .filter(contextField => contextField !== 'appName') - .map(contextField => ({ + const dynamicHeaders = Object.keys(features[0].context).map( + contextField => ({ Header: capitalizeFirst(contextField), accessor: `context.${contextField}`, minWidth: 160, Cell: HighlightCell, - })); + }) + ); const COLUMNS = useMemo(() => { return [ @@ -108,6 +108,11 @@ export const PlaygroundEnvironmentTable = ({ columns: COLUMNS as any, data: features, sortTypes, + autoResetGlobalFilter: false, + autoResetHiddenColumns: false, + autoResetSortBy: false, + disableSortRemove: true, + disableMultiSort: true, }, useGlobalFilter, useFlexLayout,