diff --git a/.eslintignore b/.eslintignore index acdb7fe434..d69c3496fb 100755 --- a/.eslintignore +++ b/.eslintignore @@ -78,6 +78,7 @@ src/components/Jobs/Service.ts src/components/Jobs/Utils.ts src/components/LogViewer/LogViewer.tsx src/components/ResourceBrowser/ResourceList/__tests__/Sidebar.test.tsx +src/components/__mocks__/monaco-editor.js src/components/__mocks__/xterm-webfont.js src/components/app/LogFilter.test.ts src/components/app/LogFilter.ts @@ -218,6 +219,7 @@ src/components/ciPipeline/WebhookSelectorCondition.tsx src/components/ciPipeline/ciPipeline.service.ts src/components/ciPipeline/validationRules.ts src/components/cluster/Cluster.tsx +src/components/cluster/ClusterCodeEditor.tsx src/components/cluster/ClusterComponentModal.tsx src/components/cluster/ClusterForm.tsx src/components/cluster/ClusterInfoStepsModal.tsx diff --git a/package.json b/package.json index fc900b6c6b..895fa81093 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "flexsearch": "^0.6.32", "jsonpath-plus": "^10.0.0", "moment": "^2.29.4", + "monaco-editor": "0.44.0", + "monaco-yaml": "5.1.1", "query-string": "^7.1.1", "react": "^17.0.2", "react-csv": "^2.2.2", @@ -31,6 +33,7 @@ "react-ga4": "^1.4.1", "react-gtm-module": "^2.0.11", "react-mde": "^11.5.0", + "react-monaco-editor": "^0.55.0", "react-router-dom": "^5.3.4", "react-select": "5.8.0", "react-virtualized": "^9.22.5", @@ -112,7 +115,6 @@ "husky": "^7.0.4", "jest-extended": "^2.0.0", "jest-junit": "^13.0.0", - "json-schema": "^0.4.0", "lint-staged": "12.5.0", "mock-socket": "^9.2.1", "patch-package": "^8.0.0", @@ -142,7 +144,11 @@ ], "setupFilesAfterEnv": [ "jest-extended" - ] + ], + "moduleNameMapper": { + "monaco-editor": "/node_modules/react-monaco-editor", + "monaco-yaml": "/node_modules/react-monaco-editor" + } }, "resolutions": { "nanoid": "^3.3.8", diff --git a/src/Pages/Applications/DevtronApps/Details/AppConfigurations/MainContent/CompareConfigView.tsx b/src/Pages/Applications/DevtronApps/Details/AppConfigurations/MainContent/CompareConfigView.tsx index 7be5216d87..3bac7e6c46 100644 --- a/src/Pages/Applications/DevtronApps/Details/AppConfigurations/MainContent/CompareConfigView.tsx +++ b/src/Pages/Applications/DevtronApps/Details/AppConfigurations/MainContent/CompareConfigView.tsx @@ -34,6 +34,7 @@ const CompareConfigView = ({ selectedChartVersion, draftChartVersion, isDeleteOverrideView, + editorKey = `${compareFromSelectedOptionValue || 'compare'}-draft-editor-key`, className = '', errorInfo, handleErrorReload, @@ -71,6 +72,7 @@ const CompareConfigView = ({ ) : (
{ } const value = YAMLStringify(newConfig) - setTimeout(() => { - this.setState({ - ssoConfig: { - ...this.state.ssoConfig, - config: { - ...this.state.ssoConfig.config, - config: value, - }, + this.setState({ + ssoConfig: { + ...this.state.ssoConfig, + config: { + ...this.state.ssoConfig.config, + config: value, }, - }) - }, 0) + }, + }) } renderSSOCodeEditor() { @@ -681,20 +678,23 @@ class SSOLogin extends Component { const shebangHtml = this.state.configMap === SwitchItemValues.Configuration ? presetConfig : null + const decorationWidth = this.state.sso !== OIDCType ? 50 : 25 return ( - +
+
{
- +
) } @@ -856,7 +856,7 @@ class SSOLogin extends Component {
) return ( -
+
{renderSSOContent()} {/* Confirmation Modal for SSO Change */} +
{!data.external && data.yamlMode && renderYamlInfoText()} - +
) } diff --git a/src/Pages/Shared/ConfigMapSecret/ConfigMapSecretDryRun.tsx b/src/Pages/Shared/ConfigMapSecret/ConfigMapSecretDryRun.tsx index fe9f4c6f02..44af1a868b 100644 --- a/src/Pages/Shared/ConfigMapSecret/ConfigMapSecretDryRun.tsx +++ b/src/Pages/Shared/ConfigMapSecret/ConfigMapSecretDryRun.tsx @@ -195,12 +195,13 @@ export const ConfigMapSecretDryRun = ({ areScopeVariablesResolving={areScopeVariablesResolving} fallbackMergeStrategy={DEFAULT_MERGE_STRATEGY} /> - {renderExternalInfo( - dryRunConfigMapSecretData.externalType, - dryRunConfigMapSecretData.external, - componentType, - 'mr-16 ml-16', - )} +
+ {renderExternalInfo( + dryRunConfigMapSecretData.externalType, + dryRunConfigMapSecretData.external, + componentType, + )} +
) } @@ -231,7 +232,7 @@ export const ConfigMapSecretDryRun = ({ />
- {renderLHSContent()} +
{renderLHSContent()}
) @@ -251,7 +252,9 @@ export const ConfigMapSecretDryRun = ({ reload: reloadConfigMapSecretManifest, }} > - +
+ +
) diff --git a/src/Pages/Shared/ConfigMapSecret/helpers.tsx b/src/Pages/Shared/ConfigMapSecret/helpers.tsx index 2390599a24..d2c0e6972d 100644 --- a/src/Pages/Shared/ConfigMapSecret/helpers.tsx +++ b/src/Pages/Shared/ConfigMapSecret/helpers.tsx @@ -58,12 +58,11 @@ export const renderExternalInfo = ( externalType: CMSecretExternalType, external: boolean, componentType: CMSecretComponentType, - className?: string, ) => externalType === CMSecretExternalType.KubernetesSecret || (componentType === CMSecretComponentType.ConfigMap && external) ? (

{EXTERNAL_INFO_TEXT[componentType].title}

@@ -91,7 +90,7 @@ export const renderChartVersionBelow3090NotSupportedText = () => ( ) export const renderYamlInfoText = () => ( -

+

GUI Recommended for multi-line data. Boolean and numeric values must be wrapped in double quotes Eg. diff --git a/src/components/CIPipelineN/CustomScript.tsx b/src/components/CIPipelineN/CustomScript.tsx index b298f43263..00cca544a4 100644 --- a/src/components/CIPipelineN/CustomScript.tsx +++ b/src/components/CIPipelineN/CustomScript.tsx @@ -15,7 +15,7 @@ */ import React, { useContext, useEffect, useState } from 'react' -import { ScriptType, CodeEditor, MODES } from '@devtron-labs/devtron-fe-common-lib' +import { ScriptType, CodeEditor } from '@devtron-labs/devtron-fe-common-lib' import { TaskFieldDescription, TaskFieldLabel } from '../ciPipeline/types' import TaskFieldTippyDescription from './TaskFieldTippyDescription' import { ReactComponent as AlertTriangle } from '../../assets/icons/ic-alert-triangle.svg' @@ -44,15 +44,16 @@ const CustomScript = ({ handleScriptChange }: CustomScriptType) => { contentDescription={TaskFieldDescription.SCRIPT} /> )} - +

handleScriptChange({ target: { value } })} + inline height={300} value={editorValue} /> - +
{formDataErrorObj[activeStageName].steps[selectedTaskIndex].inlineStepDetail?.script && diff --git a/src/components/ClusterNodes/ClusterManifest.tsx b/src/components/ClusterNodes/ClusterManifest.tsx index 6af52264e5..b1737f2898 100644 --- a/src/components/ClusterNodes/ClusterManifest.tsx +++ b/src/components/ClusterNodes/ClusterManifest.tsx @@ -14,9 +14,9 @@ * limitations under the License. */ -import { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'react' import YAML from 'yaml' -import { VisibleModal2, YAMLStringify, CodeEditor, AppThemeType } from '@devtron-labs/devtron-fe-common-lib' +import { VisibleModal2, YAMLStringify, CodeEditor, CodeEditorThemesKeys } from '@devtron-labs/devtron-fe-common-lib' import MessageUI, { MsgUIType } from '../v2/common/message.ui' import { getClusterManifest } from './clusterNodes.service' import { ManifestMessaging, MESSAGING_UI, MODES } from '../../config' @@ -138,44 +138,32 @@ export default function ClusterManifest({ } return (
- - {manifestMode === EditModeType.REVIEW && ( - -
- Pod manifest - - - -
-
- - Manifest (Editing) -
-
- )} -
+ {manifestMode === EditModeType.REVIEW && ( +
+
+ Pod manifest + + + +
+
+ Manifest (Editing) +
+
+ )} +
+ +
) } diff --git a/src/components/ClusterNodes/NodeDetails.tsx b/src/components/ClusterNodes/NodeDetails.tsx index 1a0f5e7c35..3131026610 100644 --- a/src/components/ClusterNodes/NodeDetails.tsx +++ b/src/components/ClusterNodes/NodeDetails.tsx @@ -34,8 +34,8 @@ import { ToastManager, ToastVariantType, ResourceDetail, - AppThemeType, noop, + CodeEditorThemesKeys, } from '@devtron-labs/devtron-fe-common-lib' import { useParams, useLocation, useHistory } from 'react-router-dom' import YAML from 'yaml' @@ -906,25 +906,27 @@ const NodeDetails = ({ addTab, lowercaseKindToResourceGroupMap, updateTabUrl }: } } + const getCodeEditorHeight = (): string => { + if (!isReviewState) { + return 'calc(100vh - 115px)' + } + if (isShowWarning) { + return `calc(100vh - 180px)` + } + return `calc(100vh - 148px)` + } + const renderYAMLEditor = (): JSX.Element => { return ( -
+
@@ -935,11 +937,11 @@ const NodeDetails = ({ addTab, lowercaseKindToResourceGroupMap, updateTabUrl }: /> )} {isReviewState && ( - -
+ +
Current node YAML
- + YAML (Editing)
@@ -1046,7 +1048,7 @@ const NodeDetails = ({ addTab, lowercaseKindToResourceGroupMap, updateTabUrl }: } return ( -
+
{loader ? ( ) : ( diff --git a/src/components/ClusterNodes/clusterNodes.scss b/src/components/ClusterNodes/clusterNodes.scss index 79d41f0ab1..0db02caa89 100644 --- a/src/components/ClusterNodes/clusterNodes.scss +++ b/src/components/ClusterNodes/clusterNodes.scss @@ -374,6 +374,11 @@ flex-shrink: 0; } +.cluster-manifest-header { + display: grid; + grid-template-columns: 1fr 1fr 30px; +} + .node-data-container { height: calc(100vh - 84px); overflow: hidden; diff --git a/src/components/ResourceBrowser/ResourceList/CreateResource.tsx b/src/components/ResourceBrowser/ResourceList/CreateResource.tsx index b95d4772f6..0c08e34b25 100644 --- a/src/components/ResourceBrowser/ResourceList/CreateResource.tsx +++ b/src/components/ResourceBrowser/ResourceList/CreateResource.tsx @@ -25,7 +25,7 @@ import { CodeEditor, createNewResource, CreateResourceDTO, - AppThemeType, + CodeEditorThemesKeys, } from '@devtron-labs/devtron-fe-common-lib' import { APP_STATUS_HEADERS, MODES } from '../../../config' import { ReactComponent as CloseIcon } from '../../../assets/icons/ic-cross.svg' @@ -147,14 +147,14 @@ export const CreateResource: React.FC = ({ closePopup, clust Icon={InfoIcon} /> ) @@ -210,8 +210,8 @@ export const CreateResource: React.FC = ({ closePopup, clust } return ( - -
+ +

{CREATE_RESOURCE_MODAL_MESSAGING.title}

-
{renderPageContent()}
+
{renderPageContent()}
{renderFooter()}
diff --git a/src/components/__mocks__/monaco-editor.js b/src/components/__mocks__/monaco-editor.js new file mode 100644 index 0000000000..b1ef70ed1e --- /dev/null +++ b/src/components/__mocks__/monaco-editor.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024. Devtron Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + editor: { + getModelMarkers: jest.fn().mockReturnValue([]), + defineTheme: jest.fn(), + }, + Position: {}, +} diff --git a/src/components/app/details/appDetails/AppDetails.tsx b/src/components/app/details/appDetails/AppDetails.tsx index 2605ef5687..89ef09cafb 100644 --- a/src/components/app/details/appDetails/AppDetails.tsx +++ b/src/components/app/details/appDetails/AppDetails.tsx @@ -203,7 +203,7 @@ export default function AppDetail({ filteredEnvIds }: { filteredEnvIds?: string }, [envList, params.envId]) return ( -
+
{!params.envId && envList.length > 0 && (
( - - - -

Payload

- -
-
-
+
+
+
Payload
+ +
+ +
) const renderTimeStampDetailedDescription = () => ( -
- {renderFilterTable()} - {renderReceivedPayloadCodeEditor()} +
+
+ {renderFilterTable()} +
{renderReceivedPayloadCodeEditor()}
+
) - const renderWebhookPayloadContent = () => - isPayloadLoading ? ( -
{renderWebhookPayloadLoader()}
- ) : ( - renderTimeStampDetailedDescription() - ) + const renderWebhookPayloadContent = () => ( +
+ {isPayloadLoading ? ( +
{renderWebhookPayloadLoader()}
+ ) : ( + renderTimeStampDetailedDescription() + )} +
+ ) if (isWebhookPayloadLoading) { return ( diff --git a/src/components/bulkEdits/BulkEdits.tsx b/src/components/bulkEdits/BulkEdits.tsx index 25a4eb003e..48696e6fc6 100644 --- a/src/components/bulkEdits/BulkEdits.tsx +++ b/src/components/bulkEdits/BulkEdits.tsx @@ -28,7 +28,6 @@ import { ToastManager, ToastVariantType, MarkDown, - MODES, } from '@devtron-labs/devtron-fe-common-lib' import { DOCUMENTATION, SERVER_MODE, ViewType } from '../../config' import { @@ -256,11 +255,11 @@ export default class BulkEdits extends Component renderCodeEditorBody = () => { return ( -
+
{ this.handleConfigChange(event) }} @@ -671,7 +670,7 @@ export default class BulkEdits extends Component renderBulkCodeEditor = () => { return ( -
+
{this.renderCodeEditorHeader()} {this.renderCodeEditorBody()}
@@ -689,9 +688,9 @@ export default class BulkEdits extends Component renderCodeEditorAndReadme = () => { return ( -
- {this.renderBulkCodeEditor()} - {this.renderReadmeSection()} +
+
{this.renderBulkCodeEditor()}
+
{this.renderReadmeSection()}
) } diff --git a/src/components/bulkEdits/bulkEdit.scss b/src/components/bulkEdits/bulkEdit.scss index 00d1320703..855557c016 100644 --- a/src/components/bulkEdits/bulkEdit.scss +++ b/src/components/bulkEdits/bulkEdit.scss @@ -71,6 +71,14 @@ background-color: var(--bg-primary); } +.code-editor-body { + height: calc(100vh - 97px); + background: var(--bg-primary); + .react-monaco-editor-container { + min-height: calc(60vh - 97px); + } +} + .bulk-output-body { letter-spacing: 0.2px; height: calc(40vh - 36px); diff --git a/src/components/cdPipeline/BuildCD.tsx b/src/components/cdPipeline/BuildCD.tsx index defb1821b9..20cb6de1df 100644 --- a/src/components/cdPipeline/BuildCD.tsx +++ b/src/components/cdPipeline/BuildCD.tsx @@ -32,7 +32,6 @@ import { ToastManager, ComponentSizeType, showError, - MODES, TriggerType, } from '@devtron-labs/devtron-fe-common-lib' import { useContext, useState } from 'react' @@ -742,11 +741,13 @@ export default function BuildCD({ handleStrategyChange(event, strategy.deploymentTemplate, 'yaml') } - /> + > + +
)}
diff --git a/src/components/cdPipeline/cdPipeline.scss b/src/components/cdPipeline/cdPipeline.scss index 9da18a0be5..76b4cfa87c 100644 --- a/src/components/cdPipeline/cdPipeline.scss +++ b/src/components/cdPipeline/cdPipeline.scss @@ -30,7 +30,6 @@ border: solid 1px var(--N200); background-color: var(--bg-primary); margin-bottom: 16px; - overflow: hidden; } .set-as-default { diff --git a/src/components/charts/AdvancedConfig.tsx b/src/components/charts/AdvancedConfig.tsx index 7b6a420a31..40da45d596 100644 --- a/src/components/charts/AdvancedConfig.tsx +++ b/src/components/charts/AdvancedConfig.tsx @@ -23,7 +23,6 @@ import { CustomInput, CodeEditor, MarkDown, - MODES, } from '@devtron-labs/devtron-fe-common-lib' import { useHistory } from 'react-router-dom' import { Select, mapByKey, useKeyDown, Info, Pencil } from '../common' @@ -190,7 +189,7 @@ const AdvancedConfig: React.FC = ({ return ( <> -
+

{chartName} @@ -366,7 +365,7 @@ const AdvancedConfig: React.FC = ({

)} - +
= ({ } : () => {} } - mode={MODES.YAML} - height="auto" + mode="yaml" > -
+
{appName.value}.yaml @@ -414,7 +412,7 @@ const AdvancedConfig: React.FC = ({ ) : null} - +
{showReadme && ( @@ -471,7 +469,7 @@ const ReadmeCharts = ({ readme, valuesYaml, onChange, handleClose, chart }) => {

{chart.chartMetaData.chartName}

-
+
Readme.md
{chart?.name?.value}.yaml @@ -485,11 +483,11 @@ const ReadmeCharts = ({ readme, valuesYaml, onChange, handleClose, chart }) => {
{}} + onChange={onChange ? (valuesYaml) => onChange(valuesYaml) : () => {}} />
@@ -565,7 +563,7 @@ const ValuesDiffViewer = ({

{chartName}

{/* TODO: use code editor header */} -
+