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

feat: Added YAMLBuilder Component #4150

Merged
merged 10 commits into from
Sep 5, 2023
23 changes: 23 additions & 0 deletions chaoscenter/web/config/webpack.common.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const path = require('path');

const { DefinePlugin } = require('webpack');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const { GenerateStringTypesPlugin } = require('../scripts/GenerateStringTypesPlugin');
Expand Down Expand Up @@ -111,6 +112,11 @@ module.exports = {
{
test: /\.(jpg|jpeg|png|svg|gif)$/,
type: 'asset'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
include: /node_modules/
}
]
},
Expand All @@ -134,6 +140,23 @@ module.exports = {
new RetryChunkLoadPlugin({
retryDelay: 1000,
maxRetries: 5
}),
new MonacoWebpackPlugin({
// Available options: https://github.com/microsoft/monaco-editor/tree/main/webpack-plugin#options
languages: ['json', 'yaml', 'shell', 'powershell', 'python'],
// This will define a global monaco object that is used in editor components.
globalAPI: true,
filename: '[name].worker.[contenthash:6].js',
customLanguages: [
{
label: 'yaml',
entry: 'monaco-yaml',
worker: {
id: 'monaco-yaml/yamlWorker',
entry: 'monaco-yaml/yaml.worker'
}
}
]
})
]
};
8 changes: 6 additions & 2 deletions chaoscenter/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"@visx/scale": "^2.2.2",
"@visx/shape": "^2.10.0",
"@visx/xychart": "1.7.2",
"ajv": "^8.12.0",
"anser": "2.0.1",
"argo-ui": "https://github.com/argoproj/argo-ui.git#v2.5.0",
"axios": "^0.26.1",
Expand All @@ -97,14 +98,16 @@
"marked": "4.0",
"masonry-layout": "^4.2.2",
"moment": "^2.25.3",
"monaco-editor": "^0.41.0",
"monaco-yaml": "^5.0.0",
"normalize.css": "^8.0.1",
"prompts": "^2.4.2",
"qs": "^6.9.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-draggable": "^4.4.2",
"react-error-boundary": "^3.1.4",
"react-monaco-editor": "^0.49.0",
"react-monaco-editor": "^0.54.0",
"react-popper": "^2.3.0",
"react-router-dom": "^5.3.0",
"react-spring": "8.0.27",
Expand Down Expand Up @@ -159,6 +162,7 @@
"jest-sonar-reporter": "^2.0.0",
"lint-staged": "^11.2.3",
"mini-css-extract-plugin": "^2.4.2",
"monaco-editor-webpack-plugin": "^7.1.0",
"mustache": "4.0.1",
"pem": "^1.14.4",
"prettier": "^2.4.1",
Expand All @@ -173,7 +177,7 @@
"webpack": "^5.58.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.3.1",
"webpack-merge": "^5.8.0",
"webpack-merge": "^5.9.0",
"webpack-retry-chunk-load-plugin": "^3.1.1",
"yaml-jest": "^1.2.0",
"yaml-loader": "^0.6.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function ChaosInfrastructureTypeThumbnail({
const { getString } = useStrings();
const updateSearchParams = useUpdateSearchParams();
const { experimentKey } = useParams<{ experimentKey: string }>();
const experimentHandler = experimentYamlService.getInfrastructureTypeHandler();
const experimentHandler = experimentYamlService.getInfrastructureTypeHandler(InfrastructureType.KUBERNETES);

const ChaosInfrastructureTypeThumbnailData: Array<ChaosInfrastructureTypeThumbnailData> = [
{
Expand Down
2 changes: 1 addition & 1 deletion chaoscenter/web/src/components/Drawer/Drawer.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ $top-offset: 110px;
overflow: auto;
margin-top: -57px !important;
font-style: normal;
background: #00467b !important;
background: var(--primary-9) !important;
color: var(--white) !important;
}

Expand Down
81 changes: 81 additions & 0 deletions chaoscenter/web/src/components/MonacoEditor/MonacoEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { editor } from 'monaco-editor';
import React from 'react';
import ReactMonacoEditor, {
ChangeHandler,
EditorDidMount,
EditorWillMount,
MonacoEditorProps
} from 'react-monaco-editor';
import { setForwardedRef } from '@utils';

export type MonacoCodeEditorRef = editor.IStandaloneCodeEditor;

export interface ExtendedMonacoEditorProps extends MonacoEditorProps {
name?: string;
setLineCount?: (line: number) => void;
'data-testid'?: string;
alwaysShowDarkTheme?: boolean;
}

const MonacoEditor = React.forwardRef<MonacoCodeEditorRef, ExtendedMonacoEditorProps>((props, ref) => {
const _ref = React.useRef<MonacoCodeEditorRef | null>(null);

const editorWillMount: EditorWillMount = monaco => {
monaco?.editor?.defineTheme('disable-theme', {
base: 'vs',
inherit: true,
rules: [{ background: 'f3f3fa', token: '' }],
colors: {
'editor.background': '#fafafa'
}
});

props.editorWillMount?.(monaco);
};

const editorDidMount: EditorDidMount = (editor, monaco) => {
_ref.current = editor;
setForwardedRef(ref, editor);

const model = editor.getModel();
if (model) {
props.setLineCount?.(model.getLineCount());
}

const remeasureFonts = (): void => monaco?.editor?.remeasureFonts();
const loaded = document.fonts.check('1em Roboto Mono');

if (loaded) {
remeasureFonts();
} else {
document.fonts.ready.then(remeasureFonts);
}

props.editorDidMount?.(editor, monaco);
};

const onChange: ChangeHandler = (value, event) => {
const model = _ref.current?.getModel();
if (model) {
props.setLineCount?.(model.getLineCount());
}

props.onChange?.(value, event);
};

const theme = props.alwaysShowDarkTheme ? 'vs-dark' : props.options?.readOnly ? 'disable-theme' : 'vs';

return (
<ReactMonacoEditor
{...props}
theme={theme}
editorWillMount={editorWillMount}
editorDidMount={editorDidMount}
onChange={onChange}
/>
);
});

MonacoEditor.displayName = 'MonacoEditor';

export default MonacoEditor;
3 changes: 3 additions & 0 deletions chaoscenter/web/src/components/MonacoEditor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import MonacoEditor from './MonacoEditor';

export default MonacoEditor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.main {
z-index: 1;
}

.text {
margin: var(--spacing-small) var(--spacing-small) var(--spacing-xsmall) var(--spacing-medium) !important;
padding: var(--spacing-small) var(--spacing-medium) !important;
color: var(--white) !important;
opacity: 0.7;
text-transform: uppercase;
letter-spacing: 1px !important;
cursor: pointer;

span[class*='bp3-icon'] {
color: inherit !important;
}

&:hover {
opacity: 1;
}
}

.border {
margin: var(--spacing-small) var(--spacing-xlarge) var(--spacing-xsmall) var(--spacing-xxlarge) !important;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare namespace NavExpandableModuleScssNamespace {
export interface INavExpandableModuleScss {
border: string;
main: string;
text: string;
}
}

declare const NavExpandableModuleScssModule: NavExpandableModuleScssNamespace.INavExpandableModuleScss;

export = NavExpandableModuleScssModule;
66 changes: 66 additions & 0 deletions chaoscenter/web/src/components/NavExpandable/NavExpandable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useState } from 'react';
import cx from 'classnames';
import { useLocation, matchPath } from 'react-router-dom';
import { Layout, Text } from '@harnessio/uicore';
import type { IconName } from '@harnessio/icons';
import css from './NavExpandable.module.scss';

interface NavExpandableProps {
title: string;
route: string;
className?: string;
withoutBorder?: boolean;
defaultExpanded?: boolean;
}

const NavExpandable: React.FC<React.PropsWithChildren<NavExpandableProps>> = ({
title,
route,
children,
className,
withoutBorder = false,
defaultExpanded = false
}) => {
const [isExpanded, setIsExpanded] = useState<boolean>(defaultExpanded);
const { pathname } = useLocation();
const isSelected = matchPath(pathname, route);
const timerRef = React.useRef<number | null>(null);

const handleMouseEvent = (val: boolean): void => {
if (defaultExpanded) {
return;
}
if (timerRef.current) window.clearTimeout(timerRef.current);
timerRef.current = window.setTimeout(() => {
setIsExpanded(val);
}, 300);
};

let rightIcon: IconName | undefined;
if (!defaultExpanded) {
rightIcon = isSelected || isExpanded ? 'chevron-up' : 'chevron-down';
}

return (
<div>
{!withoutBorder && <div className={css.border} />}
<Layout.Vertical
className={cx(className, css.main)}
onMouseEnter={() => handleMouseEvent(true)}
onMouseLeave={() => handleMouseEvent(false)}
>
<Text
rightIcon={rightIcon}
className={css.text}
font="xsmall"
flex={{ alignItems: 'flex-start', justifyContent: 'space-between' }}
>
{title}
</Text>
{isSelected || isExpanded ? children : null}
</Layout.Vertical>
</div>
);
};

export default NavExpandable;
3 changes: 3 additions & 0 deletions chaoscenter/web/src/components/NavExpandable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import NavExpandable from './NavExpandable';

export default NavExpandable;
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('Predefined Experiment Card', () => {
});

test('should navigate to Chaos Studio on launching experiment', async () => {
Object.assign(location, { host: 'www.harness.com', pathname: 'chaos' });
Object.assign(location, { host: 'www.litmuschaos.io', pathname: 'chaos' });

const { getByTestId } = render(
<TestWrapper>
Expand Down
9 changes: 6 additions & 3 deletions chaoscenter/web/src/components/SideNav/SideNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Classes, Position, PopoverInteractionKind } from '@blueprintjs/core';
import { useRouteWithBaseUrl } from '@hooks';
import { useStrings } from '@strings';
import ProjectSelectorController from '@controllers/ProjectSelector';
import NavExpandable from '@components/NavExpandable';
import css from './SideNav.module.scss';

interface SidebarLinkProps extends NavLinkProps {
Expand Down Expand Up @@ -96,9 +97,11 @@ export default function SideNav(): ReactElement {
<SidebarLink label={'Chaos Experiments'} to={paths.toExperiments()} />
<SidebarLink label={'ChaosHubs'} to={paths.toChaosHubs()} />
<SidebarLink label={'Environments'} to={paths.toEnvironments()} />
<SidebarLink label={'Gitops'} to={paths.toGitops()} />
<SidebarLink label={'Image Registry'} to={paths.toImageRegistry()} />
<SidebarLink label={'Members'} to={paths.toProjectMembers()} />
<NavExpandable title="Project Setup" route={paths.toProjectSetup()}>
<SidebarLink label={'Members'} to={paths.toProjectMembers()} />
<SidebarLink label={'Gitops'} to={paths.toGitops()} />
<SidebarLink label={'Image Registry'} to={paths.toImageRegistry()} />
</NavExpandable>
</Layout.Vertical>
</div>
<Container className={css.bottomContainer}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
declare namespace YamlBuilderModuleScssNamespace {
export interface IYamlBuilderModuleScss {
borderWithPluginsPanel: string;
darkBg: string;
details: string;
editor: string;
entityTag: string;
errorList: string;
errorSummary: string;
filePath: string;
flexCenter: string;
header: string;
headerBorder: string;
invalidYaml: string;
item: string;
layout: string;
lightBg: string;
main: string;
pluginDecorator: string;
resizeIcon: string;
splitPanel: string;
summaryPopover: string;
validationIcon: string;
validationStatus: string;
}
}

declare const YamlBuilderModuleScssModule: YamlBuilderModuleScssNamespace.IYamlBuilderModuleScss;

export = YamlBuilderModuleScssModule;
Loading
Loading