diff --git a/changelog/30188.txt b/changelog/30188.txt
new file mode 100644
index 0000000000..9664a244d0
--- /dev/null
+++ b/changelog/30188.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+ui: Use the Helios Design System Code Block component for all readonly code editors and use its Code Editor component for all other code editors
+```
\ No newline at end of file
diff --git a/ui/app/components/generate-credentials.js b/ui/app/components/generate-credentials.js
index a69286538e..77794cf7bc 100644
--- a/ui/app/components/generate-credentials.js
+++ b/ui/app/components/generate-credentials.js
@@ -143,12 +143,12 @@ export default class GenerateCredentials extends Component {
}
@action
- codemirrorUpdated(attr, val, codemirror) {
- codemirror.performLint();
- const hasErrors = codemirror.state.lint.marked.length > 0;
-
- if (!hasErrors) {
+ editorUpdated(attr, val) {
+ // wont set invalid JSON to the model
+ try {
this.model[attr] = JSON.parse(val);
+ } catch {
+ // linting is handled by the component
}
}
diff --git a/ui/app/components/policy-form.hbs b/ui/app/components/policy-form.hbs
index 19f5170f2a..10d6b1785e 100644
--- a/ui/app/components/policy-form.hbs
+++ b/ui/app/components/policy-form.hbs
@@ -23,13 +23,7 @@
{{/if}}
- {{#unless this.showFileUpload}}
-
- You can use Alt+Tab (Option+Tab on MacOS) in the code editor to skip to the next field.
-
- {{/unless}}
- Policy
{{#if @renderPolicyExampleModal}}
{{! only true in policy create and edit routes }}
@@ -43,9 +37,8 @@
/>
{{/if}}
-
-
- {{#if @model.isNew}}
+ {{#if @model.isNew}}
+
Upload file
- {{else}}
- {{! EDITING - no file upload toggle}}
-
- {{/if}}
-
+
+ {{/if}}
{{#if this.showFileUpload}}
@@ -80,7 +61,6 @@
{{else}}
{{/if}}
-
{{#each @model.additionalAttrs as |attr|}}
diff --git a/ui/app/components/role-aws-edit.js b/ui/app/components/role-aws-edit.js
index 5423cc8859..8cbb530b74 100644
--- a/ui/app/components/role-aws-edit.js
+++ b/ui/app/components/role-aws-edit.js
@@ -43,12 +43,12 @@ export default RoleEdit.extend({
});
},
- codemirrorUpdated(attr, val, codemirror) {
- codemirror.performLint();
- const hasErrors = codemirror.state.lint.marked.length > 0;
-
- if (!hasErrors) {
- set(this.model, attr, val);
+ editorUpdated(attr, val) {
+ // wont set invalid JSON to the model
+ try {
+ set(this.model, attr, JSON.parse(val));
+ } catch {
+ // linting is handled by the component
}
},
},
diff --git a/ui/app/components/role-edit.js b/ui/app/components/role-edit.js
index a53601ecf8..b81088c6b8 100644
--- a/ui/app/components/role-edit.js
+++ b/ui/app/components/role-edit.js
@@ -102,12 +102,12 @@ export default Component.extend(FocusOnInsertMixin, {
});
},
- codemirrorUpdated(attr, val, codemirror) {
- codemirror.performLint();
- const hasErrors = codemirror.state.lint.marked.length > 0;
-
- if (!hasErrors) {
+ editorUpdated(attr, val) {
+ // wont set invalid JSON to the model
+ try {
set(this.model, attr, JSON.parse(val));
+ } catch {
+ // linting is handled by the component
}
},
},
diff --git a/ui/app/components/secret-create-or-update.js b/ui/app/components/secret-create-or-update.js
index 1bc1e02acb..37d9ac4274 100644
--- a/ui/app/components/secret-create-or-update.js
+++ b/ui/app/components/secret-create-or-update.js
@@ -42,7 +42,7 @@ const LIST_ROOT_ROUTE = 'vault.cluster.secrets.backend.list-root';
const SHOW_ROUTE = 'vault.cluster.secrets.backend.show';
export default class SecretCreateOrUpdate extends Component {
- @tracked codemirrorString = null;
+ @tracked editorString = null;
@tracked error = null;
@tracked secretPaths = null;
@tracked pathWhiteSpaceWarning = false;
@@ -58,7 +58,7 @@ export default class SecretCreateOrUpdate extends Component {
@action
setup(elem, [secretData, mode]) {
- this.codemirrorString = secretData.toJSONString();
+ this.editorString = secretData.toJSONString();
this.validationMessages = {
path: '',
};
@@ -160,21 +160,19 @@ export default class SecretCreateOrUpdate extends Component {
}
this.checkRows();
}
+
@action
- codemirrorUpdated(val, codemirror) {
- this.error = null;
- codemirror.performLint();
- const noErrors = codemirror.state.lint.marked.length === 0;
- if (noErrors) {
- try {
- this.args.secretData.fromJSONString(val);
- set(this.args.modelForData, 'secretData', this.args.secretData.toJSON());
- } catch (e) {
- this.error = e.message;
- }
+ editorUpdated(val) {
+ try {
+ this.args.secretData.fromJSONString(val);
+ set(this.args.modelForData, 'secretData', this.args.secretData.toJSON());
+ } catch (e) {
+ this.error = e.message;
}
- this.codemirrorString = val;
+
+ this.editorString = val;
}
+
@action
createOrUpdateKey(type, event) {
event.preventDefault();
@@ -204,21 +202,25 @@ export default class SecretCreateOrUpdate extends Component {
this.checkRows();
this.handleChange();
}
+
@action
formatJSON() {
- this.codemirrorString = this.args.secretData.toJSONString(true);
+ this.editorString = this.args.secretData.toJSONString(true);
}
+
@action
handleMaskedInputChange(secret, index, value) {
const row = { ...secret, value };
set(this.args.secretData, index, row);
this.handleChange();
}
+
@action
handleChange() {
- this.codemirrorString = this.args.secretData.toJSONString(true);
+ this.editorString = this.args.secretData.toJSONString(true);
set(this.args.modelForData, 'secretData', this.args.secretData.toJSON());
}
+
@action
updateValidationErrorCount(errorCount) {
this.validationErrorCount = errorCount;
diff --git a/ui/app/components/secret-edit.js b/ui/app/components/secret-edit.js
index efb3058496..ec7e5bdf02 100644
--- a/ui/app/components/secret-edit.js
+++ b/ui/app/components/secret-edit.js
@@ -35,13 +35,13 @@ export default class SecretEdit extends Component {
@service store;
@tracked secretData = null;
- @tracked codemirrorString = null;
+ @tracked editorString = null;
// fired on did-insert from render modifier
@action
createKvData(elem, [model]) {
this.secretData = KVObject.create({ content: [] }).fromJSON(model.secretData);
- this.codemirrorString = this.secretData.toJSONString();
+ this.editorString = this.secretData.toJSONString();
}
// TODO move this to the secret model
@maybeQueryRecord(
diff --git a/ui/app/components/tools/wrap.hbs b/ui/app/components/tools/wrap.hbs
index 80ed1eb15b..21c60899f3 100644
--- a/ui/app/components/tools/wrap.hbs
+++ b/ui/app/components/tools/wrap.hbs
@@ -53,7 +53,7 @@
@title="Data to wrap"
@subTitle="json-formatted"
@value={{this.stringifiedWrapData}}
- @valueUpdated={{this.codemirrorUpdated}}
+ @valueUpdated={{this.editorUpdated}}
/>
{{else}}
0;
- if (!this.hasLintingErrors) this.wrapData = JSON.parse(val);
+ editorUpdated(val: string) {
+ this.hasLintingErrors = false;
+
+ try {
+ this.wrapData = JSON.parse(val);
+ } catch {
+ this.hasLintingErrors = true;
+ }
}
@action
diff --git a/ui/app/controllers/vault/cluster/secrets/backend/sign.js b/ui/app/controllers/vault/cluster/secrets/backend/sign.js
index c25b9512e2..0a90d06d2e 100644
--- a/ui/app/controllers/vault/cluster/secrets/backend/sign.js
+++ b/ui/app/controllers/vault/cluster/secrets/backend/sign.js
@@ -19,12 +19,12 @@ export default Controller.extend({
});
},
- codemirrorUpdated(attr, val, codemirror) {
- codemirror.performLint();
- const hasErrors = codemirror.state.lint.marked.length > 0;
-
- if (!hasErrors) {
+ editorUpdated(attr, val) {
+ // wont set invalid JSON to the model
+ try {
set(this.model, attr, JSON.parse(val));
+ } catch {
+ // linting is handled by the component
}
},
diff --git a/ui/app/styles/components/codemirror.scss b/ui/app/styles/components/codemirror.scss
deleted file mode 100644
index f336410447..0000000000
--- a/ui/app/styles/components/codemirror.scss
+++ /dev/null
@@ -1,195 +0,0 @@
-@use 'sass:color';
-@use '../utils/color_variables';
-@use '../utils/font_variables';
-@use 'calendar-widget';
-
-/**
- * Copyright (c) HashiCorp, Inc.
- * SPDX-License-Identifier: BUSL-1.1
- */
-
-$light-grey: #dde3e7;
-$light-gray: #a4a4a4;
-$light-grey-blue: #6c7b81;
-$dark-grey: #788290;
-$faded-gray: #eaeaea;
-// Product colors
-$atlas: #127eff;
-$vagrant: #2f88f7;
-$consul: #69499a;
-$terraform: #822ff7;
-$serf: #dd4e58;
-$packer: #1ddba3;
-
-// Our colors
-$gray: color.adjust(color_variables.$black, $lightness: 89%);
-color_variables.$red: #ff3d3d;
-color_variables.$green: #39b54a;
-calendar-widget.$dark-gray: #535f73;
-
-$gutter-grey: #2a2f36;
-
-.CodeMirror-lint-tooltip {
- background-color: #f9f9fa;
- border: 1px solid $light-gray;
- border-radius: 0;
- color: color.adjust(color_variables.$black, $lightness: 13%);
- font-family: font_variables.$family-monospace;
- font-size: 13px;
- padding: 7px 8px 9px;
-}
-
-.cm-s-hashi-read-only {
- &.CodeMirror {
- background-color: color_variables.$grey-lightest;
- border: none;
- color: color_variables.$ui-gray-600;
- font-family: font_variables.$family-monospace;
- -webkit-font-smoothing: auto;
- line-height: 1.4;
- }
-
- span.cm-string,
- span.cm-string-2 {
- color: $packer;
- }
- span.cm-property {
- color: color.adjust($consul, $lightness: 20%);
- }
-}
-
-.cm-s-hashi {
- &.CodeMirror {
- background-color: color_variables.$black !important;
- resize: vertical;
- color: #cfd2d1 !important;
- border: none;
- font-family: font_variables.$family-monospace;
- -webkit-font-smoothing: auto;
- line-height: 1.4;
- }
-
- .CodeMirror-gutters {
- color: $dark-grey;
- background-color: $gutter-grey;
- border: none;
- }
-
- .CodeMirror-cursor {
- border-left: solid thin #f8f8f0;
- }
-
- .CodeMirror-linenumber {
- color: #6d8a88;
- }
-
- div.CodeMirror-selected {
- background: rgb(33, 66, 131);
- }
-
- &.CodeMirror-focused div.CodeMirror-selected {
- background: rgb(33, 66, 131);
- }
-
- .CodeMirror-line::selection,
- .CodeMirror-line > span::selection,
- .CodeMirror-line > span > span::selection {
- background: rgb(33, 66, 131);
- }
-
- .CodeMirror-line::-moz-selection,
- .CodeMirror-line > span::-moz-selection,
- .CodeMirror-line > span > span::-moz-selection {
- background: rgb(33, 66, 131);
- }
-
- span.cm-comment {
- color: $light-grey;
- }
-
- span.cm-string,
- span.cm-string-2 {
- color: $packer;
- }
-
- span.cm-number {
- color: $serf;
- }
-
- span.cm-variable {
- color: color.adjust($consul, $lightness: 20%);
- }
-
- span.cm-variable-2 {
- color: color.adjust($consul, $lightness: 20%);
- }
-
- span.cm-def {
- color: $packer;
- }
-
- span.cm-operator {
- color: $gray;
- }
- span.cm-keyword {
- color: color_variables.$yellow;
- }
-
- span.cm-atom {
- color: $serf;
- }
-
- span.cm-meta {
- color: $packer;
- }
-
- span.cm-tag {
- color: $packer;
- }
-
- span.cm-attribute {
- color: #9fca56;
- }
-
- span.cm-qualifier {
- color: #9fca56;
- }
-
- span.cm-property {
- color: color.adjust($consul, $lightness: 20%);
- }
-
- span.cm-variable-3 {
- color: #9fca56;
- }
-
- span.cm-builtin {
- color: #9fca56;
- }
-
- .CodeMirror-activeline-background {
- background: #101213;
- }
-
- .CodeMirror-matchingbracket {
- text-decoration: underline;
- color: white !important;
- }
-}
-
-.readonly-codemirror {
- .CodeMirror-code {
- cursor: default;
- }
- .CodeMirror-cursor {
- // https://github.com/codemirror/CodeMirror/issues/1099
- display: none;
- }
-}
-.cm-s-auto-height.CodeMirror {
- height: auto;
-}
-
-.cm-s-short.CodeMirror {
- height: 100px;
-}
diff --git a/ui/app/styles/components/console-ui-panel.scss b/ui/app/styles/components/console-ui-panel.scss
index 75c1c67ae9..6244c1a9d2 100644
--- a/ui/app/styles/components/console-ui-panel.scss
+++ b/ui/app/styles/components/console-ui-panel.scss
@@ -46,17 +46,6 @@ $console-close-height: 35px;
font-size: size_variables.$size-7;
min-height: 2rem;
padding: 0;
-
- &:not(.console-ui-command):not(.CodeMirror-line) {
- padding-left: size_variables.$spacing-20;
- }
- }
-
- .cm-s-hashi.CodeMirror {
- background-color: rgba(color_variables.$black, 0.5) !important;
- font-weight: font_variables.$font-weight-normal;
- margin-left: size_variables.$spacing-20;
- padding: size_variables.$spacing-12 size_variables.$spacing-20;
}
.console-ui-panel-intro {
diff --git a/ui/app/styles/core.scss b/ui/app/styles/core.scss
index 2bc6fcad1f..703e3bb6a1 100644
--- a/ui/app/styles/core.scss
+++ b/ui/app/styles/core.scss
@@ -59,7 +59,6 @@
@use 'components/chart-container';
@use 'components/clients-date-range';
@use 'components/cluster-banners';
-@use 'components/codemirror';
@use 'components/console-ui-panel';
@use 'components/control-group';
@use 'components/doc-link';
diff --git a/ui/app/templates/components/console/log-json.hbs b/ui/app/templates/components/console/log-json.hbs
index 0a414890a1..48aa860223 100644
--- a/ui/app/templates/components/console/log-json.hbs
+++ b/ui/app/templates/components/console/log-json.hbs
@@ -4,15 +4,7 @@
}}
-
+
-
+
{{/if}}
\ No newline at end of file
diff --git a/ui/app/templates/components/oidc/scope-form.hbs b/ui/app/templates/components/oidc/scope-form.hbs
index 14b36c92aa..6b194e3241 100644
--- a/ui/app/templates/components/oidc/scope-form.hbs
+++ b/ui/app/templates/components/oidc/scope-form.hbs
@@ -44,10 +44,6 @@
{{#each @model.formFields as |field|}}
{{/each}}
-
- You can use Alt+Tab (Option+Tab on MacOS) in the code editor to skip to the next field. Click 'How to write JSON
- template for scopes' to view an example.
-
{{else}}
@@ -150,9 +150,9 @@
{{else}}
diff --git a/ui/app/templates/components/secret-edit.hbs b/ui/app/templates/components/secret-edit.hbs
index 598e7222d2..a9cd9587ca 100644
--- a/ui/app/templates/components/secret-edit.hbs
+++ b/ui/app/templates/components/secret-edit.hbs
@@ -51,7 +51,7 @@
@showAdvancedMode={{this.showAdvancedMode}}
@modelForData={{this.modelForData}}
@canUpdateSecret={{this.canUpdateSecret}}
- @codemirrorString={{this.codemirrorString}}
+ @editorString={{this.editorString}}
@editActions={{hash toggleAdvanced=(action "toggleAdvanced") refresh=(action "refresh")}}
/>
diff --git a/ui/app/templates/components/secret-form-show.hbs b/ui/app/templates/components/secret-form-show.hbs
index 8e034022cf..70bef51507 100644
--- a/ui/app/templates/components/secret-form-show.hbs
+++ b/ui/app/templates/components/secret-form-show.hbs
@@ -12,7 +12,7 @@
{{else}}
{{#if @showAdvancedMode}}
-
+
{{else}}
diff --git a/ui/app/templates/components/transit-key-action/hmac.hbs b/ui/app/templates/components/transit-key-action/hmac.hbs
index 2622febdc6..ee0524b69f 100644
--- a/ui/app/templates/components/transit-key-action/hmac.hbs
+++ b/ui/app/templates/components/transit-key-action/hmac.hbs
@@ -46,7 +46,7 @@