Skip to content

Commit

Permalink
feat(md): show envs side by side
Browse files Browse the repository at this point in the history
  • Loading branch information
Rani committed Jun 3, 2021
1 parent 8524b0e commit 0187438
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 16 deletions.
35 changes: 35 additions & 0 deletions app/scripts/modules/core/src/managed/Environments2.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@
}
}
}

.env-direction-btn {
display: flex;
flex-direction: row;
align-items: center;
line-height: 1;
padding: var(--xs-spacing);
background-color: transparent;
color: var(--color-dovegray);

> i {
margin-top: 1px;
font-size: 16px;
}

&:focus,
&:active:hover {
outline: none;
}

@media (max-width: 768px) {
display: none;
}
}

.environments-list {
width: 100%;
display: grid;
gap: var(--m-spacing);
align-items: flex-start;

&.side-by-side {
gap: var(--xl-spacing) var(--m-spacing);
}
}
}

.ui-switcher {
Expand Down
3 changes: 2 additions & 1 deletion app/scripts/modules/core/src/managed/Environments2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import { HorizontalTabs } from 'core/presentation/horizontalTabs/HorizontalTabs';
import { logger } from 'core/utils';

import { EnvironmentsDirectionController } from './environmentBaseElements/EnvironmentsRender';
import { Routes } from './managed.states';
import { MD_CATEGORY } from './utils/defaults';

Expand Down Expand Up @@ -61,7 +62,7 @@ const tabs = Object.entries(tabsInternal).map(([key, title]) => ({ title, path:
export const Environments2 = () => {
return (
<div className="vertical Environments2">
<HorizontalTabs tabs={tabs} />
<HorizontalTabs tabs={tabs} rightElement={<EnvironmentsDirectionController />} />
<UIView />
{/* Some padding at the bottom */}
<div style={{ minHeight: 32, minWidth: 32 }} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
@borderRadius: 4px;

.BaseEnvironment {
&:not(:first-of-type) {
margin-top: 16px;
}
width: 100%;
border: 1px solid var(--color-cirrus);
border-radius: @borderRadius;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import classnames from 'classnames';
import { reverse } from 'lodash';
import React from 'react';
import { atom, useRecoilState } from 'recoil';

import { useElementDimensions } from 'core/presentation/hooks/useDimensions.hook';
import { logger } from 'core/utils';

const STORAGE_KEY = 'MD_environmentsDirection';

const DIRECTIONS = ['list', 'sideBySide'] as const;
type Direction = typeof DIRECTIONS[number];

const isDirection = (value: string | null): value is Direction => {
return Boolean(value && DIRECTIONS.includes(value as Direction));
};

const storedDirection = localStorage.getItem(STORAGE_KEY);

const environmentsDirectionState = atom<Direction>({
key: 'environmentsDisplay',
default: isDirection(storedDirection) ? storedDirection : 'list',
});

// The goal of this hook is to store the value in an atom to be shared across the app but also update the local storage
const useEnvironmentDirection = () => {
const [direction, setDirection] = useRecoilState(environmentsDirectionState);
React.useLayoutEffect(() => {
localStorage.setItem(STORAGE_KEY, direction);
}, [direction]);

return { direction, setDirection };
};

export const EnvironmentsDirectionController = () => {
const { direction, setDirection } = useEnvironmentDirection();
return (
<button
type="button"
className="btn env-direction-btn"
onClick={() => setDirection((state) => (state === 'list' ? 'sideBySide' : 'list'))}
>
{direction === 'list' ? 'Grid view' : 'List view'}
<i className={classnames(direction === 'list' ? 'far fa-list-alt' : 'fas fa-columns', 'sp-margin-xs-left')} />
</button>
);
};

const MIN_WIDTH_PER_COLUMN = 500;

interface IEnvironmentsRenderProps {
className?: string;
children: React.ReactElement[];
}

export const EnvironmentsRender = ({ className, children }: IEnvironmentsRenderProps) => {
const { direction } = useEnvironmentDirection();
const ref = React.useRef(null);
const { width } = useElementDimensions({ ref, isActive: direction === 'sideBySide' });
let numEnvironments = 1;
if (Array.isArray(children)) {
numEnvironments = children.length;
} else {
logger.log({
level: 'ERROR',
error: new Error('Environments children should be an array'),
action: 'Environments::Render',
});
}

const numColumns = Math.min(Math.round(width / MIN_WIDTH_PER_COLUMN), numEnvironments);

return (
<div
ref={ref}
className={classnames(className, 'environments-list', { 'side-by-side': direction === 'sideBySide' })}
style={direction === 'sideBySide' ? { gridTemplateColumns: `repeat(${numColumns}, 1fr)` } : undefined}
>
{direction === 'list' && children}
{direction === 'sideBySide' && width > 0 ? reverse(React.Children.toArray(children)) : null}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Resource } from './Resource';
import { Artifact } from './artifact/Artifact';
import { ManagementWarning } from '../config/ManagementWarning';
import { BaseEnvironment } from '../environmentBaseElements/BaseEnvironment';
import { EnvironmentsRender } from '../environmentBaseElements/EnvironmentsRender';
import { useFetchApplicationQuery, useFetchResourceStatusQuery } from '../graphql/graphql-sdk';
import { QueryEnvironment } from './types';
import { OVERVIEW_VERSION_STATUSES } from './utils';
Expand Down Expand Up @@ -40,7 +41,11 @@ export const EnvironmentsOverview = () => {
<div className="EnvironmentsOverview">
<ManagementWarning appName={app.name} />
{environments.length ? (
environments.map((env) => <EnvironmentOverview key={env.name} environment={env} appName={app.name} />)
<EnvironmentsRender>
{environments.map((env) => (
<EnvironmentOverview key={env.name} environment={env} appName={app.name} />
))}
</EnvironmentsRender>
) : (
<div className="error-message">No environments found</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

& > i {
font-size: 14px;
margin-top: 1px;
margin-top: 4px;
align-self: flex-start;
}

.task-metadata {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ import { useApplicationContextSafe } from 'core/presentation';

import { BaseEnvironment } from '../environmentBaseElements/BaseEnvironment';
import { EnvironmentItem } from '../environmentBaseElements/EnvironmentItem';
import { EnvironmentsRender } from '../environmentBaseElements/EnvironmentsRender';
import { useFetchVersionQuery } from '../graphql/graphql-sdk';
import { ArtifactVersionTasks } from '../overview/artifact/ArtifactVersionTasks';
import { Constraints } from '../overview/artifact/Constraints';
import { useCreateVersionActions } from '../overview/artifact/utils';
import { PinnedVersions, VersionData, VersionInEnvironment } from './types';
import { HistoryArtifactVersionExtended, PinnedVersions, VersionData } from './types';
import { toPinnedMetadata, VersionMessageData } from '../versionMetadata/MetadataComponents';
import { getBaseMetadata, VersionMetadata } from '../versionMetadata/VersionMetadata';

import './VersionsHistory.less';

interface IVersionInEnvironmentProps {
environment: string;
version: VersionInEnvironment;
version: HistoryArtifactVersionExtended;
envPinnedVersions?: PinnedVersions[keyof PinnedVersions];
}

Expand Down Expand Up @@ -94,7 +95,7 @@ interface IVersionContentProps {

export const VersionContent = ({ versionData, pinnedVersions }: IVersionContentProps) => {
return (
<React.Fragment>
<EnvironmentsRender>
{Object.entries(versionData.environments).map(([env, { versions }]) => {
return (
<BaseEnvironment key={env} title={env} size="small">
Expand All @@ -109,6 +110,6 @@ export const VersionContent = ({ versionData, pinnedVersions }: IVersionContentP
</BaseEnvironment>
);
})}
</React.Fragment>
</EnvironmentsRender>
);
};
4 changes: 2 additions & 2 deletions app/scripts/modules/core/src/managed/versionsHistory/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type SingleVersionEnvironment = NonNullable<FetchVersionQuery['applicatio
export type SingleVersionArtifact = NonNullable<SingleVersionEnvironment['state']['artifacts']>[number];
export type SingleVersionArtifactVersion = NonNullable<SingleVersionArtifact['versions']>[number];

export interface VersionInEnvironment extends HistoryArtifactVersion {
export interface HistoryArtifactVersionExtended extends HistoryArtifactVersion {
reference: string;
type: string;
}
Expand All @@ -21,7 +21,7 @@ export interface VersionData {
createdAt?: DateTime;
isBaking?: boolean;
isFocused?: boolean;
environments: { [env: string]: { versions: VersionInEnvironment[]; isPinned?: boolean } };
environments: { [env: string]: { versions: HistoryArtifactVersionExtended[]; isPinned?: boolean } };
gitMetadata?: HistoryArtifactVersion['gitMetadata'];
key: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { debounce } from 'lodash';
import React from 'react';

export const useWindowDimensions = ({ delay = 200, isActive = true }: { delay?: number; isActive?: boolean }) => {
const [dimension, setDimension] = React.useState({ width: window.innerWidth, height: window.innerHeight });

React.useLayoutEffect(() => {
const debouncedResizeHandler = debounce(() => {
setDimension({ width: window.innerWidth, height: window.innerHeight });
}, delay);
if (isActive) {
window.addEventListener('resize', debouncedResizeHandler);
return () => window.removeEventListener('resize', debouncedResizeHandler);
} else {
return () => {};
}
}, [delay, isActive]);

React.useLayoutEffect(() => {
if (isActive) {
setDimension({ width: window.innerWidth, height: window.innerHeight });
}
}, [isActive]);

return dimension;
};

const getElementDimensions = (ref: React.RefObject<HTMLElement>) =>
ref.current ? { width: ref.current.offsetWidth, height: ref.current.offsetHeight } : { width: 0, height: 0 };

export const useElementDimensions = ({
ref,
delay = 200,
isActive = true,
}: {
ref: React.RefObject<HTMLElement>;
delay?: number;
isActive?: boolean;
}) => {
const [dimension, setDimension] = React.useState(getElementDimensions(ref));

React.useLayoutEffect(() => {
const debouncedResizeHandler = debounce(() => {
setDimension(getElementDimensions(ref));
}, delay);

if (isActive && ref.current) {
const observer = new ResizeObserver(debouncedResizeHandler);
observer.observe(ref.current);
return () => observer.disconnect();
} else {
return () => {};
}
}, [delay, isActive, ref.current]);

return dimension;
};
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@
border-bottom: @tab-border-width solid var(--color-accent);
color: var(--color-black);
}

.right-element {
margin-left: auto;
align-self: center;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import './HorizontalTabs.less';
export interface IHorizontalTabsProps {
tabs: Array<{ title: string; path: string }>;
className?: string;
style?: React.CSSProperties;
rightElement?: React.ReactElement;
}

export const HorizontalTabs = ({ tabs, className, style }: IHorizontalTabsProps) => {
export const HorizontalTabs = ({ tabs, className, rightElement }: IHorizontalTabsProps) => {
return (
<div className={classnames(className, 'HorizontalTabs')} style={style}>
<div className={classnames(className, 'HorizontalTabs')}>
{tabs.map((tab) => (
<TabTitle key={tab.path} title={tab.title} path={tab.path} />
))}
{rightElement && <div className="right-element">{rightElement}</div>}
</div>
);
};
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
"react-virtualized": "9.18.5",
"react-virtualized-select": "^3.1.3",
"react2angular": "^3.2.1",
"recoil": "^0.0.10",
"recoil": "^0.3.1",
"reflect-metadata": "^0.1.9",
"rxjs": "6.6.7",
"rxjs-compat": "6.6.7",
Expand Down Expand Up @@ -157,6 +157,7 @@
"@types/react-virtualized": "9.7.12",
"@types/react-virtualized-select": "^3.0.4",
"@types/request-promise-native": "^1.0.15",
"@types/resize-observer-browser": "^0.1.5",
"@types/tether": "^1.4.4",
"@types/webpack": "4.4.24",
"@types/webpack-env": "1.13.7",
Expand Down
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4615,6 +4615,11 @@
"@types/node" "*"
"@types/tough-cookie" "*"

"@types/resize-observer-browser@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz#36d897708172ac2380cd486da7a3daf1161c1e23"
integrity sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ==

"@types/source-list-map@*":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
Expand Down Expand Up @@ -10869,6 +10874,11 @@ gzip-size@^3.0.0:
dependencies:
duplexer "^0.1.1"

[email protected]:
version "1.0.2"
resolved "https://registry.yarnpkg.com/hamt_plus/-/hamt_plus-1.0.2.tgz#e21c252968c7e33b20f6a1b094cd85787a265601"
integrity sha1-4hwlKWjH4zsg9qGwlM2FeHomVgE=

handle-thing@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
Expand Down Expand Up @@ -16745,6 +16755,13 @@ recoil@^0.0.10:
resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.0.10.tgz#679ab22306f559f8a63c46fd5ff5241539f9248f"
integrity sha512-+9gRqehw3yKETmoZbhSnWu4GO10HDb5xYf1CjLF1oXGK2uT6GX5Lu9mfTXwjxV/jXxEKx8MIRUUbgPxvbJ8SEw==

recoil@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.3.1.tgz#40ef544160d19d76e25de8929d7e512eace13b90"
integrity sha512-KNA3DRqgxX4rRC8E7fc6uIw7BACmMPuraIYy+ejhE8tsw7w32CetMm8w7AMZa34wzanKKkev3vl3H7Z4s0QSiA==
dependencies:
hamt_plus "1.0.2"

[email protected]:
version "2.2.2"
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f"
Expand Down

0 comments on commit 0187438

Please sign in to comment.