* feat: 🎸 initial secret editor * feat: 🎸 Create Secret Editor for JSON Credentials ✅ Closes: ICU-6680 * style: 💄 Fix sass lint errors * style: 💄 Appease sass-lint rule for using --size in stylesheet * refactor: 💡 Set Icon size via component attribute * refactor: 💡 remove computed decorators for Secret Editor * refactor: 💡 update editor styles to using sizing variables * refactor: 💡 update styles and add comments * refactor: 💡 clean up styling for secret editor * refactor: 💡 update class names to be more verbose * chore: 🤖 move jsonlint import to rose index.js * refactor: 💡 remove duplicate margin style for skeleton body * refactor: 💡 add comments to SecretEditor component class * refactor: 💡 large updates to secret json editor * refactor: 💡 Move JSON Secret to form/field/ directory * style: 💄 fix padding for Secret Editor line numbers * chore: 🤖 disable property-sort-oder in .sasslintrc * refactor: 💡 reorder app.scss styles * test: 💍 Add integration tests for JSON Secret and Skeleton
603 lines
11 KiB
SCSS
603 lines
11 KiB
SCSS
// sass-lint:disable no-color-literals class-name-format
|
|
@use 'rose/variables/sizing';
|
|
@use 'rose/variables/media';
|
|
@use 'rose/utilities/type';
|
|
|
|
@import 'rose';
|
|
@import 'notify';
|
|
|
|
.rose-layout-global {
|
|
.rose-layout-global-body {
|
|
justify-content: center;
|
|
}
|
|
}
|
|
|
|
.rose-layout-centered {
|
|
> .rose-layout-page {
|
|
width: sizing.rems(l) * 18;
|
|
}
|
|
|
|
@media (max-width: media.width(small)) {
|
|
display: block;
|
|
|
|
> .rose-layout-page {
|
|
width: auto;
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-nav-sidebar {
|
|
margin-top: sizing.rems(xxl);
|
|
|
|
& + .rose-nav-sidebar {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.rose-icon {
|
|
margin-right: sizing.rems(xs);
|
|
}
|
|
}
|
|
|
|
.rose-form {
|
|
&:not(.full-width) {
|
|
width: 66%;
|
|
}
|
|
|
|
.rose-form-input {
|
|
width: 100%;
|
|
|
|
.rose-form-input-field {
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
.rose-dropdown {
|
|
$icon-width: sizing.rems(m) + sizing.rems(s);
|
|
$indent: $icon-width + sizing.rems(xs);
|
|
|
|
.rose-form-radio-label {
|
|
display: flex;
|
|
|
|
.rose-icon {
|
|
padding-right: sizing.rems(xxs);
|
|
}
|
|
}
|
|
|
|
.indent-label-1 {
|
|
.rose-form-radio-label,
|
|
.rose-form-checkbox-label {
|
|
padding-left: $indent;
|
|
}
|
|
}
|
|
|
|
.indent-label-2 {
|
|
.rose-form-radio-label,
|
|
.rose-form-checkbox-label {
|
|
padding-left: $indent + $icon-width;
|
|
}
|
|
}
|
|
|
|
.is-project {
|
|
.rose-icon {
|
|
visibility: hidden;
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-form-fieldset {
|
|
.rose-table {
|
|
.rose-form-label {
|
|
left: -9999px;
|
|
position: absolute;
|
|
top: -9999px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-table {
|
|
p {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.rose-table-header-cell {
|
|
p {
|
|
color: var(--ui-gray-subtler-1);
|
|
font-weight: normal;
|
|
}
|
|
}
|
|
|
|
.rose-form-checkbox {
|
|
margin-bottom: 0;
|
|
|
|
.rose-form-checkbox-label-text {
|
|
color: var(--stark);
|
|
text-decoration: underline;
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-header {
|
|
position: relative;
|
|
|
|
.logotype {
|
|
display: none;
|
|
}
|
|
|
|
.rose-dropdown {
|
|
.rose-icon {
|
|
transform: scale(0.7);
|
|
}
|
|
}
|
|
|
|
&.loading {
|
|
&::after {
|
|
// animation: gradient 1s linear infinite;
|
|
// background: repeating-linear-gradient(
|
|
// to right,
|
|
// var(--subtle),
|
|
// var(--subtle),
|
|
// var(--info),
|
|
// var(--subtle),
|
|
// var(--subtle)
|
|
// );
|
|
background-position: -100% 0;
|
|
background-size: 200% auto;
|
|
content: ' ';
|
|
height: 3px;
|
|
left: 0;
|
|
position: absolute;
|
|
right: 0;
|
|
top: 100%;
|
|
|
|
@keyframes gradient {
|
|
0% {
|
|
background-position: -100% 0;
|
|
}
|
|
|
|
100% {
|
|
background-position: -200% 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-frame {
|
|
.rose-form-actions {
|
|
.rose-button-primary {
|
|
display: block;
|
|
margin: 0;
|
|
width: 100%;
|
|
|
|
.rose-button-wrapper {
|
|
display: inline;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-dialog-cover {
|
|
svg {
|
|
max-width: 20rem;
|
|
}
|
|
}
|
|
|
|
.copyable {
|
|
white-space: nowrap;
|
|
|
|
.copyable-button {
|
|
margin: 0;
|
|
padding: 0 sizing.rems(xxs);
|
|
position: relative;
|
|
top: -2px;
|
|
}
|
|
|
|
mark {
|
|
animation: fadeBackground 0.75s linear;
|
|
background-color: transparent;
|
|
color: inherit;
|
|
|
|
@keyframes fadeBackground {
|
|
0% {
|
|
background-color: var(--action-subtler-1);
|
|
}
|
|
|
|
100% {
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[class*='session-status-'] {
|
|
color: var(--ui-gray-subtler-2);
|
|
}
|
|
|
|
.session-status-active {
|
|
color: var(--success);
|
|
}
|
|
|
|
.nowrap {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
// Spinning animation for refresh button icon
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
.is-loading {
|
|
.rose-icon {
|
|
@keyframes hds-flight-icon-animation-rotation {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
> svg {
|
|
animation: hds-flight-icon-animation-rotation 0.7s linear infinite;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//onboarding quick setup styles
|
|
.choose-path {
|
|
display: block;
|
|
width: sizing.rems(xl) * 15;
|
|
}
|
|
|
|
.choose-path-cards {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.create-resources {
|
|
display: block;
|
|
width: sizing.rems(xl) * 15;
|
|
|
|
.rose-form-fieldset {
|
|
margin-top: sizing.rems(xl);
|
|
}
|
|
|
|
.rose-frame-body {
|
|
p {
|
|
color: var(--ui-gray);
|
|
}
|
|
}
|
|
}
|
|
|
|
.create-resource-cards {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
.rose-form-input {
|
|
width: sizing.rems(xl) * 6;
|
|
}
|
|
}
|
|
|
|
.onboarding-quick-setup-success {
|
|
display: block;
|
|
width: min-content;
|
|
|
|
.rose-frame-header {
|
|
padding: sizing.rems(l);
|
|
}
|
|
|
|
h2 {
|
|
font-weight: 700;
|
|
line-height: 24px;
|
|
margin: 0;
|
|
}
|
|
|
|
h4 {
|
|
font-weight: 700;
|
|
line-height: 19px;
|
|
}
|
|
|
|
a {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
line-height: 16px;
|
|
}
|
|
}
|
|
|
|
.onboarding-quick-setup-success-role {
|
|
span {
|
|
display: flex;
|
|
}
|
|
|
|
h3 {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
letter-spacing: -0.5px;
|
|
line-height: 24px;
|
|
margin-left: sizing.rems(xs);
|
|
margin-top: 0;
|
|
}
|
|
|
|
.rose-icon {
|
|
color: var(--success);
|
|
}
|
|
}
|
|
|
|
.onboarding-quick-setup-success-sub-title {
|
|
display: inline-flex;
|
|
|
|
h3 {
|
|
font-weight: 600;
|
|
letter-spacing: -0.5px;
|
|
line-height: 24px;
|
|
margin-left: sizing.rems(xs);
|
|
margin-top: sizing.rems(xxs);
|
|
}
|
|
|
|
.rose-icon {
|
|
margin-bottom: sizing.rems(xs);
|
|
}
|
|
}
|
|
|
|
.onboarding-quick-setup-success-link {
|
|
display: block;
|
|
margin-top: sizing.rems(xs);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.onboarding-quick-setup-success-image {
|
|
margin-bottom: sizing.rems(xl);
|
|
margin-top: sizing.rems(l);
|
|
}
|
|
|
|
.onboarding-quick-setup-success-button {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-bottom: 0;
|
|
margin-top: sizing.rems(xl);
|
|
width: 100%;
|
|
}
|
|
|
|
.onboarding-quick-setup-success-controller {
|
|
margin-top: sizing.rems(l);
|
|
|
|
h4 {
|
|
font-weight: 600;
|
|
line-height: 18px;
|
|
margin-bottom: sizing.rems(xxs);
|
|
}
|
|
|
|
p {
|
|
color: var(--ui-gray);
|
|
margin-bottom: sizing.rems(xxs);
|
|
}
|
|
}
|
|
|
|
.onboarding-quick-setup-success-controller-url {
|
|
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
|
|
border-radius: sizing.rems(xxxs);
|
|
color: var(--action);
|
|
height: (sizing.rems(xs) * 5);
|
|
|
|
.copyable {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: sizing.rems(s);
|
|
}
|
|
|
|
.rose-icon {
|
|
margin: 0;
|
|
}
|
|
|
|
.copyable-button {
|
|
top: -4px;
|
|
}
|
|
}
|
|
|
|
.onboarding-quick-setup-success-developers {
|
|
p {
|
|
margin-bottom: sizing.rems(s);
|
|
margin-top: sizing.rems(xs);
|
|
}
|
|
}
|
|
|
|
.worker-create-section {
|
|
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-3);
|
|
border-radius: sizing.rems(xxs);
|
|
margin-bottom: sizing.rems(xl);
|
|
padding: sizing.rems(l);
|
|
|
|
> div {
|
|
margin-bottom: sizing.rems(l);
|
|
}
|
|
|
|
> code {
|
|
background-color: var(--ui-gray-subtler-5);
|
|
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
|
|
color: var(--failure);
|
|
}
|
|
|
|
.worker-auth-token {
|
|
align-items: flex-end;
|
|
display: flex;
|
|
gap: sizing.rems(m); // sass-lint:disable-line no-misspelled-properties
|
|
}
|
|
|
|
.worker-success {
|
|
align-items: center;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
> div {
|
|
align-items: center;
|
|
display: flex;
|
|
gap: sizing.rems(xs); // sass-lint:disable-line no-misspelled-properties
|
|
|
|
p {
|
|
margin-bottom: sizing.rems(xxs);
|
|
}
|
|
|
|
&:first-child {
|
|
width: 40%;
|
|
|
|
p {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
&:last-child {
|
|
p {
|
|
color: var(--success);
|
|
}
|
|
}
|
|
}
|
|
|
|
.rose-icon {
|
|
color: var(--success);
|
|
}
|
|
}
|
|
}
|
|
|
|
.info-field {
|
|
.hds-form-field--layout-vertical {
|
|
grid-template-areas: 'label' 'helper-text' 'text-input';
|
|
|
|
.hds-form-label {
|
|
font-size: sizing.rems(m);
|
|
grid-area: label;
|
|
line-height: sizing.rems(m) + sizing.rems(xxs);
|
|
}
|
|
|
|
.hds-form-helper-text {
|
|
color: var(--token-form-label-color);
|
|
font-size: sizing.rems(m);
|
|
grid-area: helper-text;
|
|
}
|
|
|
|
.hds-form-text-input {
|
|
background-color: transparent;
|
|
border: 0;
|
|
grid-area: text-input;
|
|
line-height: sizing.rems(m) + sizing.rems(xxs);
|
|
margin-top: sizing.rems(xs);
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
&.has-icon {
|
|
.flight-icon {
|
|
position: absolute;
|
|
transform: translatey(sizing.rems(xl) - sizing.rems(s));
|
|
}
|
|
|
|
.hds-form-helper-text,
|
|
.hds-form-text-input {
|
|
margin-left: sizing.rems(l) + sizing.rems(xs);
|
|
}
|
|
}
|
|
}
|
|
|
|
// json secret editor
|
|
.secret-editor {
|
|
// Secret Editor body and gutter colors are based on the Monokai color template
|
|
// and are used for both the Editor and the Skeleton views
|
|
--button-shadow: #000004;
|
|
--secret-editor-body: #272822; // body and button background
|
|
--secret-editor-gutter: #31332b; // gutter background
|
|
--secret-editor-height: 210px;
|
|
|
|
background: var(--secret-editor-body);
|
|
border-radius: sizing.rems(xxs);
|
|
height: var(--secret-editor-height);
|
|
margin-bottom: sizing.rems(l);
|
|
|
|
.secret-editor-json {
|
|
.CodeMirror {
|
|
border-radius: sizing.rems(xxs);
|
|
height: var(--secret-editor-height);
|
|
}
|
|
|
|
.CodeMirror-gutters {
|
|
background: var(--secret-editor-gutter);
|
|
}
|
|
|
|
// override CodeMirror padding to add padding to left of line numbers
|
|
.CodeMirror-linenumber {
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
.secret-editor-skeleton-wrapper {
|
|
// using ui-gray directly so it does not change when
|
|
// user is in dark mode since the secret editor
|
|
// does not change theme colors between light and dark
|
|
color: #{color(ui-gray)};
|
|
display: flex;
|
|
height: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
.secret-editor-skeleton-gutter {
|
|
background: var(--secret-editor-gutter);
|
|
border-radius: sizing.rems(xxs) 0 0 sizing.rems(xxs);
|
|
width: sizing.rems(xxl) + sizing.rems(xxs); // 52
|
|
}
|
|
|
|
.secret-editor-skeleton-body {
|
|
width: 100%;
|
|
|
|
// skeleton text rows for detail and edit views
|
|
// applies general styles to child div of skeleton-body
|
|
// then adds dynamic width to each child
|
|
// depending on the class (e.g., s, m, l)
|
|
> div {
|
|
background: var(--secret-editor-gutter);
|
|
border-radius: sizing.rems(m);
|
|
height: sizing.rems(xs);
|
|
margin: sizing.rems(s) - sizing.rems(xxxxs); // 11
|
|
|
|
&:first-child {
|
|
margin-top: sizing.rems(m);
|
|
}
|
|
|
|
&.s {
|
|
width: 5%;
|
|
}
|
|
|
|
&.m {
|
|
width: 10%;
|
|
}
|
|
|
|
&.l {
|
|
width: 15%;
|
|
}
|
|
|
|
&.xl {
|
|
width: 20%;
|
|
}
|
|
}
|
|
}
|
|
|
|
.secret-editor-skeleton-message {
|
|
font-size: sizing.rems(s) + sizing.rems(xxxs); // 14
|
|
left: 50%;
|
|
position: absolute;
|
|
top: 50%;
|
|
// centers message with editor body and gutter
|
|
transform: translate(-50%, -50%);
|
|
z-index: 1;
|
|
}
|
|
|
|
.rose-button-secret-editor-skeleton-button {
|
|
background: var(--secret-editor-body);
|
|
border: sizing.rems(xxxxs) solid var(--ui-gray);
|
|
border-radius: sizing.rems(xxxs);
|
|
box-shadow: 0 sizing.rems(xxs) sizing.rems(xxs) var(--button-shadow);
|
|
// using ui-gray directly so it does not change when
|
|
// user is in dark mode since the secret editor
|
|
// does not change theme colors between light and dark
|
|
color: #{color(ui-gray, 050)};
|
|
font-size: sizing.rems(s) + sizing.rems(xxxs); // 14
|
|
height: sizing.rems(xl);
|
|
padding: 0 sizing.rems(l);
|
|
}
|
|
}
|