1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-25 00:09:40 +02:00

fix(ui): fix ui bugs [EE-3847] (#7453)

This commit is contained in:
Chaim Lev-Ari 2022-08-12 06:47:56 +03:00 committed by GitHub
parent dd372637cb
commit 95fb5a4baa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 246 additions and 448 deletions

View file

@ -40,6 +40,12 @@ body,
position: relative; position: relative;
} }
.logo {
display: inline;
max-width: 155px;
max-height: 55px;
}
.white-space-normal { .white-space-normal {
white-space: normal !important; white-space: normal !important;
} }
@ -76,10 +82,6 @@ body,
font-size: 18px; font-size: 18px;
} }
.header_title_content {
margin-left: 5px;
}
.form-section-title { .form-section-title {
@apply text-gray-9; @apply text-gray-9;
@apply th-dark:text-gray-5; @apply th-dark:text-gray-5;

View file

@ -329,25 +329,6 @@ input:checked + .slider:before {
border: 0px; border: 0px;
} }
/* Databatle Setting Menu */
.tableMenu {
border: 1px solid var(--border-bootbox);
border-radius: 8px;
}
[data-reach-menu-list],
[data-reach-menu-items] {
background: none;
}
.dropdown-menu {
border-radius: 8px;
}
.dropdown-menu .tableMenu {
border: 0px;
}
/* Status Indicator Inside Table Section Label Style */ /* Status Indicator Inside Table Section Label Style */
.table .label { .table .label {
border-radius: 8px !important; border-radius: 8px !important;

View file

@ -1,17 +1,24 @@
.btn { .btn {
@apply disabled:opacity-60;
@apply !outline-none; @apply !outline-none;
@apply border border-solid border-transparent; @apply border border-solid border-transparent;
border-radius: 5px; border-radius: 8px;
display: inline-flex; display: inline-flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
} }
.btn-group { .btn.disabled,
display: inline-flex; .btn[disabled],
fieldset[disabled] .btn {
@apply opacity-40;
pointer-events: none;
touch-action: none;
}
.btn:hover {
color: var(--text-button-hover-color);
} }
.btn.active { .btn.active {
@ -19,12 +26,11 @@
} }
.btn-primary { .btn-primary {
@apply bg-blue-8 border-blue-8; @apply text-white bg-blue-8 border-blue-8;
@apply hover:bg-blue-9 hover:border-blue-9; @apply hover:text-white hover:bg-blue-9 hover:border-blue-9;
@apply th-dark:hover:bg-blue-7 th-dark:hover:border-blue-7; @apply th-dark:hover:bg-blue-7 th-dark:hover:border-blue-7;
} }
.btn-primary:focus,
.btn-primary:active, .btn-primary:active,
.btn-primary.active, .btn-primary.active,
.open > .dropdown-toggle.btn-primary { .open > .dropdown-toggle.btn-primary {
@ -40,20 +46,17 @@
/* Button Secondary */ /* Button Secondary */
.btn-secondary { .btn-secondary {
@apply border border-solid; @apply border border-solid;
@apply disabled:border-transparent;
@apply text-blue-9 bg-blue-2 border-blue-8; @apply text-blue-9 bg-blue-2 border-blue-8;
@apply hover:bg-blue-3 focus:bg-blue-3; @apply hover:bg-blue-3;
@apply th-dark:text-blue-3 th-dark:bg-gray-10 th-dark:border-blue-7; @apply th-dark:text-blue-3 th-dark:bg-gray-10 th-dark:border-blue-7;
@apply th-dark:hover:bg-blue-11; @apply th-dark:hover:bg-blue-11;
@apply th-dark:focus:bg-gray-10 th-dark:focus:border-blue-5;
} }
.btn-danger { .btn-danger {
@apply bg-error-8 border-error-8; @apply bg-error-8 border-error-8;
@apply hover:bg-error-7 hover:border-error-7 hover:text-white; @apply hover:bg-error-7 hover:border-error-7 hover:text-white;
@apply focus:bg-error-8 focus:text-white focus:border-blue-5;
} }
.btn-danger:active, .btn-danger:active,
@ -68,19 +71,25 @@
@apply hover:bg-error-2 th-dark:hover:bg-error-11; @apply hover:bg-error-2 th-dark:hover:bg-error-11;
@apply border-error-5 th-dark:border-error-7 th-highcontrast:border-error-7; @apply border-error-5 th-dark:border-error-7 th-highcontrast:border-error-7;
@apply border border-solid; @apply border border-solid;
@apply focus:border-blue-5;
} }
.btn-success { .btn-success {
background-color: var(--ui-success-7); background-color: var(--ui-success-7);
} }
.btn-success:hover {
color: var(--white-color);
}
/* secondary-grey */
.btn-default,
.btn-light { .btn-light {
@apply hover:bg-gray-2 th-dark:hover:bg-gray-9; @apply bg-white border-gray-5 text-gray-9;
background-color: var(--bg-button-group-color); @apply hover:bg-gray-3 hover:border-gray-5 hover:text-gray-10;
border: 1px solid var(--border-button-group);
color: var(--text-button-group-color); /* dark mode */
@apply th-dark:bg-gray-warm-10 th-dark:border-gray-warm-7 th-dark:text-gray-warm-4;
@apply th-dark:hover:bg-gray-warm-9 th-dark:hover:border-gray-6 th-dark:hover:text-gray-warm-4;
} }
.btn-light:active, .btn-light:active,
@ -89,15 +98,51 @@
background-color: var(--ui-gray-3); background-color: var(--ui-gray-3);
} }
form a,
.form-group a,
.hyperlink { .hyperlink {
color: var(--ui-blue-8); color: var(--ui-blue-8);
} }
form a:hover,
.form-group a:hover,
.hyperlink:hover { .hyperlink:hover {
text-decoration: underline; text-decoration: underline;
color: var(--ui-blue-9); color: var(--ui-blue-9);
} }
.btn-group {
display: inline-flex;
}
.input-group-btn .btn.active,
.btn-group .btn.active {
@apply bg-blue-2 text-blue-10 border-blue-5;
@apply th-dark:bg-blue-11 th-dark:text-blue-2 th-dark:border-blue-9;
}
/* focus */
.btn-primary:focus,
.btn-secondary:focus,
.btn-light:focus {
@apply border-blue-5;
}
.btn-danger:focus,
.btn-dangerlight:focus {
@apply border-blue-6;
}
.btn-primary:focus,
.btn-secondary:focus,
.btn-light:focus,
.btn-danger:focus,
.btn-dangerlight:focus {
--btn-focus-color: var(--ui-blue-3);
box-shadow: 0px 0px 0px 4px var(--btn-focus-color);
}
[theme='dark'] .btn-primary:focus,
[theme='dark'] .btn-secondary:focus,
[theme='dark'] .btn-light:focus,
[theme='dark'] .btn-danger:focus,
[theme='dark'] .btn-dangerlight:focus {
--btn-focus-color: var(--ui-blue-11);
}

View file

@ -93,10 +93,9 @@
--bg-main-color: var(--white-color); --bg-main-color: var(--white-color);
--bg-body-color: var(--grey-9); --bg-body-color: var(--grey-9);
--bg-checkbox-border-color: var(--grey-49); --bg-checkbox-border-color: var(--grey-49);
--bg-sidebar-header-color: var(--grey-37);
--bg-widget-color: var(--white-color); --bg-widget-color: var(--white-color);
--bg-widget-header-color: var(--grey-10); --bg-widget-header-color: var(--grey-10);
--bg-widget-table-color: var(--grey-13); --bg-widget-table-color: var(--ui-gray-3);
--bg-header-color: var(--white-color); --bg-header-color: var(--white-color);
--bg-hover-table-color: var(--grey-14); --bg-hover-table-color: var(--grey-14);
--bg-switch-box-color: var(--ui-gray-5); --bg-switch-box-color: var(--ui-gray-5);
@ -111,6 +110,7 @@
--bg-navtabs-color: var(--white-color); --bg-navtabs-color: var(--white-color);
--bg-navtabs-hover-color: var(--grey-16); --bg-navtabs-hover-color: var(--grey-16);
--bg-table-selected-color: var(--grey-14); --bg-table-selected-color: var(--grey-14);
--bg-codemirror-color: var(--white-color);
--bg-codemirror-gutters-color: var(--grey-17); --bg-codemirror-gutters-color: var(--grey-17);
--bg-dropdown-menu-color: var(--white-color); --bg-dropdown-menu-color: var(--white-color);
--bg-log-viewer-color: var(--white-color); --bg-log-viewer-color: var(--white-color);
@ -126,11 +126,7 @@
--bg-motd-body-color: var(--grey-20); --bg-motd-body-color: var(--grey-20);
--bg-item-highlighted-color: var(--grey-21); --bg-item-highlighted-color: var(--grey-21);
--bg-item-highlighted-null-color: var(--grey-14); --bg-item-highlighted-null-color: var(--grey-14);
--bg-row-header-color: var(--white-color);
--bg-image-multiselect-button: linear-gradient(var(--white-color), var(--grey-17));
--bg-multiselect-checkbox-color: var(--white-color);
--bg-panel-body-color: var(--white-color); --bg-panel-body-color: var(--white-color);
--bg-codemirror-color: var(--white-color);
--bg-codemirror-selected-color: var(--grey-22); --bg-codemirror-selected-color: var(--grey-22);
--bg-tooltip-color: var(--ui-gray-11); --bg-tooltip-color: var(--ui-gray-11);
--bg-input-sm-color: var(--white-color); --bg-input-sm-color: var(--white-color);
@ -149,8 +145,6 @@
--bg-btn-focus: var(--grey-59); --bg-btn-focus: var(--grey-59);
--bg-boxselector-disabled-color: var(--white-color); --bg-boxselector-disabled-color: var(--white-color);
--bg-small-select-color: var(--white-color); --bg-small-select-color: var(--white-color);
--bg-app-datatable-thead: var(--grey-23);
--bg-app-datatable-tbody: var(--grey-24);
--bg-stepper-item-active: var(--white-color); --bg-stepper-item-active: var(--white-color);
--bg-stepper-item-counter: var(--grey-61); --bg-stepper-item-counter: var(--grey-61);
--bg-sortbutton-color: var(--white-color); --bg-sortbutton-color: var(--white-color);
@ -176,7 +170,6 @@
--text-link-color: var(--blue-2); --text-link-color: var(--blue-2);
--text-link-hover-color: var(--blue-4); --text-link-hover-color: var(--blue-4);
--text-input-group-addon-color: var(--grey-25); --text-input-group-addon-color: var(--grey-25);
--text-btn-default-color: var(--grey-6);
--text-blocklist-hover-color: var(--grey-37); --text-blocklist-hover-color: var(--grey-37);
--text-dashboard-item-color: var(--grey-32); --text-dashboard-item-color: var(--grey-32);
--text-danger-color: var(--red-1); --text-danger-color: var(--red-1);
@ -230,23 +223,18 @@
--border-md-checkbox-color: var(--grey-19); --border-md-checkbox-color: var(--grey-19);
--border-modal-header-color: var(--grey-45); --border-modal-header-color: var(--grey-45);
--border-navtabs-color: var(--ui-white); --border-navtabs-color: var(--ui-white);
--border-form-section-title-color: var(--grey-33);
--border-codemirror-cursor-color: var(--black-color); --border-codemirror-cursor-color: var(--black-color);
--border-codemirror-gutters-color: var(--grey-19);
--border-pre-color: var(--grey-43); --border-pre-color: var(--grey-43);
--border-blocklist-item-selected-color: var(--grey-46); --border-blocklist-item-selected-color: var(--grey-46);
--border-pagination-color: var(--ui-white);
--border-pagination-span-color: var(--ui-white); --border-pagination-span-color: var(--ui-white);
--border-pagination-hover-color: var(--ui-white); --border-pagination-hover-color: var(--ui-white);
--border-multiselect-button-color: var(--grey-48);
--border-searchbar-color: var(--grey-10);
--border-panel-color: var(--white-color); --border-panel-color: var(--white-color);
--border-input-sm-color: var(--grey-47);
--border-daterangepicker-color: var(--grey-19); --border-daterangepicker-color: var(--grey-19);
--border-calendar-table: var(--white-color); --border-calendar-table: var(--white-color);
--border-daterangepicker: var(--grey-19); --border-daterangepicker: var(--grey-19);
--border-pre-next-month: var(--black-color); --border-pre-next-month: var(--black-color);
--border-daterangepicker-after: var(--white-color); --border-daterangepicker-after: var(--white-color);
--border-tooltip-color: var(--grey-47);
--border-modal: 0px; --border-modal: 0px;
--border-sortbutton: var(--grey-8); --border-sortbutton: var(--grey-8);
--border-bootbox: var(--ui-gray-5); --border-bootbox: var(--ui-gray-5);
@ -261,7 +249,6 @@
--button-close-color: var(--black-color); --button-close-color: var(--black-color);
--button-opacity: 0.2; --button-opacity: 0.2;
--button-opacity-hover: 0.5; --button-opacity-hover: 0.5;
--bg-boxselector-wrapper-color: var(--grey-6);
--bg-image-multiselect: linear-gradient(var(--blue-2), var(--blue-2)); --bg-image-multiselect: linear-gradient(var(--blue-2), var(--blue-2));
--bg-image-multiselect-button: linear-gradient(var(--white-color), var(--grey-17)); --bg-image-multiselect-button: linear-gradient(var(--white-color), var(--grey-17));
@ -286,33 +273,27 @@
--text-button-group: var(--ui-gray-9); --text-button-group: var(--ui-gray-9);
} }
/* Dark Theme */
[theme='dark'] { [theme='dark'] {
--bg-card-color: var(--grey-1);
--bg-main-color: var(--grey-2);
--bg-body-color: var(--grey-2); --bg-body-color: var(--grey-2);
--bg-btn-default-color: var(--grey-3); --bg-btn-default-color: var(--grey-3);
--bg-blocklist-hover-color: var(--grey-iron-10); --bg-blocklist-hover-color: var(--ui-gray-iron-10);
--bg-boxselector-color: var(--grey-iron-10); --bg-boxselector-color: var(--ui-gray-iron-10);
--bg-blocklist-item-selected-color: var(--grey-3); --bg-blocklist-item-selected-color: var(--grey-3);
--bg-boxselector-wrapper-disabled-color: var(--grey-39);
--bg-card-color: var(--grey-1); --bg-card-color: var(--grey-1);
--bg-checkbox-border-color: var(--grey-8); --bg-checkbox-border-color: var(--grey-8);
--bg-code-color: var(--ui-gray-warm-11); --bg-code-color: var(--ui-gray-warm-11);
--bg-codemirror-color: var(--ui-gray-warm-11); --bg-codemirror-color: var(--ui-gray-warm-11);
--bg-codemirror-gutters-color: var(--ui-gray-warm-8); --bg-codemirror-gutters-color: var(--ui-gray-warm-8);
--bg-codemirror-selected-color: var(--ui-gray-warm-7); --bg-codemirror-selected-color: var(--ui-gray-warm-7);
--bg-dropdown-menu-color: var(--grey-1); --bg-dropdown-menu-color: var(--ui-gray-7);
--bg-main-color: var(--grey-2); --bg-main-color: var(--grey-2);
--bg-widget-color: var(--ui-gray-warm-10); --bg-widget-color: var(--ui-gray-warm-10);
--bg-widget-header-color: var(--grey-1); --bg-widget-header-color: var(--grey-1);
--bg-widget-table-color: var(--grey-1); --bg-widget-table-color: var(--ui-gray-warm-9);
--bg-header-color: var(--grey-2); --bg-header-color: var(--grey-2);
--bg-hover-table-color: var(--grey-3); --bg-hover-table-color: var(--grey-3);
--bg-switch-box-color: var(--grey-53); --bg-switch-box-color: var(--grey-53);
--bg-input-group-addon-color: var(--grey-3);
--bg-btn-default-color: var(--grey-3);
--bg-blocklist-hover-color: var(--grey-3);
--bg-boxselector-color: var(--grey-54);
--bg-table-color: var(--grey-1); --bg-table-color: var(--grey-1);
--bg-md-checkbox-color: var(--grey-31); --bg-md-checkbox-color: var(--grey-31);
--bg-form-control-disabled-color: var(--grey-3); --bg-form-control-disabled-color: var(--grey-3);
@ -320,14 +301,9 @@
--bg-navtabs-color: var(--ui-gray-warm-11); --bg-navtabs-color: var(--ui-gray-warm-11);
--bg-navtabs-hover-color: var(--grey-3); --bg-navtabs-hover-color: var(--grey-3);
--bg-table-selected-color: var(--grey-3); --bg-table-selected-color: var(--grey-3);
--bg-codemirror-color: var(--ui-gray-warm-11);
--bg-codemirror-gutters-color: var(--ui-gray-warm-8);
--bg-codemirror-selected-color: var(--ui-gray-warm-7);
--bg-dropdown-menu-color: var(--grey-1);
--bg-log-viewer-color: var(--grey-2); --bg-log-viewer-color: var(--grey-2);
--bg-log-line-selected-color: var(--grey-3); --bg-log-line-selected-color: var(--grey-3);
--bg-pre-color: var(--grey-2); --bg-pre-color: var(--grey-2);
--bg-blocklist-item-selected-color: var(--grey-3);
--bg-progress-color: var(--grey-3); --bg-progress-color: var(--grey-3);
--bg-pagination-color: var(--grey-3); --bg-pagination-color: var(--grey-3);
--bg-pagination-span-color: var(--grey-1); --bg-pagination-span-color: var(--grey-1);
@ -336,13 +312,15 @@
--bg-motd-body-color: var(--grey-1); --bg-motd-body-color: var(--grey-1);
--bg-item-highlighted-color: var(--grey-2); --bg-item-highlighted-color: var(--grey-2);
--bg-item-highlighted-null-color: var(--grey-2); --bg-item-highlighted-null-color: var(--grey-2);
--bg-row-header-color: var(--grey-2);
--bg-multiselect-button-color: var(--grey-3);
--bg-image-multiselect-button: none !important;
--bg-multiselect-checkbox-color: var(--grey-3);
--bg-panel-body-color: var(--grey-1); --bg-panel-body-color: var(--grey-1);
--bg-boxselector-wrapper-disabled-color: var(--grey-39); --bg-input-group-addon-color: var(--grey-3);
--bg-sidebar-header-color: var(--grey-1); --bg-tooltip-color: var(--grey-3);
--bg-input-sm-color: var(--grey-1);
--bg-service-datatable-thead: var(--grey-1);
--bg-inner-datatable-thead: var(--grey-1);
--bg-app-datatable-thead: var(--grey-1);
--bg-service-datatable-tbody: var(--grey-1);
--bg-app-datatable-tbody: var(--grey-1);
--bg-multiselect-color: var(--grey-1); --bg-multiselect-color: var(--grey-1);
--bg-daterangepicker-color: var(--grey-3); --bg-daterangepicker-color: var(--grey-3);
--bg-calendar-color: var(--grey-3); --bg-calendar-color: var(--grey-3);
@ -351,19 +329,16 @@
--bg-daterangepicker-hover: var(--grey-4); --bg-daterangepicker-hover: var(--grey-4);
--bg-daterangepicker-in-range: var(--ui-gray-warm-11); --bg-daterangepicker-in-range: var(--ui-gray-warm-11);
--bg-daterangepicker-active: var(--blue-14); --bg-daterangepicker-active: var(--blue-14);
--bg-tooltip-color: var(--grey-3);
--bg-input-autofill-color: var(--grey-2); --bg-input-autofill-color: var(--grey-2);
--bg-btn-default-hover-color: var(--grey-3); --bg-btn-default-hover-color: var(--grey-3);
--bg-btn-focus: var(--grey-3); --bg-btn-focus: var(--grey-3);
--bg-boxselector-disabled-color: var(--grey-54); --bg-boxselector-disabled-color: var(--grey-54);
--bg-small-select-color: var(--grey-2); --bg-small-select-color: var(--grey-2);
--bg-app-datatable-thead: var(--grey-1);
--bg-app-datatable-tbody: var(--grey-1);
--bg-stepper-item-active: var(--grey-1); --bg-stepper-item-active: var(--grey-1);
--bg-stepper-item-counter: var(--grey-7); --bg-stepper-item-counter: var(--grey-7);
--bg-sortbutton-color: var(--grey-1); --bg-sortbutton-color: var(--grey-1);
--bg-dashboard-item: var(--grey-3); --bg-dashboard-item: var(--grey-3);
--bg-searchbar: var(--grey-2); --bg-searchbar: var(--ui-grey-warm-11);
--bg-inputbox: var(--grey-2); --bg-inputbox: var(--grey-2);
--bg-dropdown-hover: var(--grey-3); --bg-dropdown-hover: var(--grey-3);
--bg-webeditor-color: var(--ui-gray-warm-9); --bg-webeditor-color: var(--ui-gray-warm-9);
@ -383,7 +358,6 @@
--text-link-color: var(--blue-9); --text-link-color: var(--blue-9);
--text-link-hover-color: var(--blue-2); --text-link-hover-color: var(--blue-2);
--text-input-group-addon-color: var(--grey-8); --text-input-group-addon-color: var(--grey-8);
--text-btn-default-color: var(--grey-8);
--text-blocklist-hover-color: var(--white-color); --text-blocklist-hover-color: var(--white-color);
--text-dashboard-item-color: var(--blue-2); --text-dashboard-item-color: var(--blue-2);
--text-danger-color: var(--red-4); --text-danger-color: var(--red-4);
@ -408,14 +382,13 @@
--text-ui-select-color: var(--white-color); --text-ui-select-color: var(--white-color);
--text-ui-select-hover-color: var(--white-color); --text-ui-select-hover-color: var(--white-color);
--text-summary-color: var(--white-color); --text-summary-color: var(--white-color);
--text-multiselect-button-color: var(--white-color);
--text-multiselect-item-color: var(--white-color);
--text-boxselector-wrapper-color: var(--white-color); --text-boxselector-wrapper-color: var(--white-color);
--text-tooltip-color: var(--white-color);
--text-rzslider-color: var(--white-color);
--text-rzslider-limit-color: var(--white-color);
--text-daterangepicker-end-date: var(--grey-7); --text-daterangepicker-end-date: var(--grey-7);
--text-daterangepicker-in-range: var(--white-color); --text-daterangepicker-in-range: var(--white-color);
--text-daterangepicker-active: var(--white-color); --text-daterangepicker-active: var(--white-color);
--text-tooltip-color: var(--white-color);
--text-btn-default-color: var(--white-color);
--text-input-autofill-color: var(--grey-8); --text-input-autofill-color: var(--grey-8);
--text-button-hover-color: var(--white-color); --text-button-hover-color: var(--white-color);
--text-small-select-color: var(--grey-7); --text-small-select-color: var(--grey-7);
@ -439,21 +412,18 @@
--border-md-checkbox-color: var(--grey-41); --border-md-checkbox-color: var(--grey-41);
--border-modal-header-color: var(--grey-1); --border-modal-header-color: var(--grey-1);
--border-navtabs-color: var(--grey-38); --border-navtabs-color: var(--grey-38);
--border-form-section-title-color: var(--grey-8);
--border-codemirror-cursor-color: var(--white-color); --border-codemirror-cursor-color: var(--white-color);
--border-codemirror-gutters-color: var(--grey-26);
--border-pre-color: var(--grey-3); --border-pre-color: var(--grey-3);
--border-blocklist-item-selected-color: var(--grey-38); --border-blocklist-item-selected-color: var(--grey-38);
--border-pagination-span-color: var(--grey-1); --border-pagination-span-color: var(--grey-1);
--border-pagination-hover-color: var(--grey-3); --border-pagination-hover-color: var(--grey-3);
--border-boxselector-wrapper-hover: 3px solid var(--blue-8);
--border-panel-color: var(--grey-2); --border-panel-color: var(--grey-2);
--border-input-sm-color: var(--grey-3);
--border-daterangepicker-color: var(--grey-3); --border-daterangepicker-color: var(--grey-3);
--border-calendar-table: var(--grey-3); --border-calendar-table: var(--grey-3);
--border-daterangepicker: var(--grey-4); --border-daterangepicker: var(--grey-4);
--border-pre-next-month: var(--white-color); --border-pre-next-month: var(--white-color);
--border-daterangepicker-after: var(--grey-3); --border-daterangepicker-after: var(--grey-3);
--border-tooltip-color: var(--grey-3);
--border-modal: 0px; --border-modal: 0px;
--border-sortbutton: var(--grey-3); --border-sortbutton: var(--grey-3);
--border-bootbox: var(--ui-gray-9); --border-bootbox: var(--ui-gray-9);
@ -486,12 +456,13 @@
--sort-icon: var(--ui-gray-3); --sort-icon: var(--ui-gray-3);
--border-checkbox: var(--ui-gray-5); --border-checkbox: var(--ui-gray-5);
--bg-checkbox: var(--white-color); --bg-checkbox: var(--white-color);
--border-searchbar: var(--grey-54); --border-searchbar: var(--ui-gray-warm-9);
--bg-button-group: var(--white-color); --bg-button-group: var(--white-color);
--border-button-group: var(--ui-gray-5); --border-button-group: var(--ui-gray-5);
--text-button-group: var(--ui-gray-9); --text-button-group: var(--ui-gray-9);
} }
/* High Contrast Theme */
[theme='highcontrast'] { [theme='highcontrast'] {
--bg-card-color: var(--black-color); --bg-card-color: var(--black-color);
--bg-main-color: var(--black-color); --bg-main-color: var(--black-color);
@ -504,10 +475,8 @@
--bg-hover-table-color: var(--grey-3); --bg-hover-table-color: var(--grey-3);
--bg-switch-box-color: var(--grey-53); --bg-switch-box-color: var(--grey-53);
--bg-panel-body-color: var(--black-color); --bg-panel-body-color: var(--black-color);
--bg-boxselector-wrapper-disabled-color: var(--grey-39);
--bg-dropdown-menu-color: var(--black-color); --bg-dropdown-menu-color: var(--black-color);
--bg-codemirror-selected-color: var(--grey-3); --bg-codemirror-selected-color: var(--grey-3);
--bg-row-header-color: var(--black-color);
--bg-motd-body-color: var(--black-color); --bg-motd-body-color: var(--black-color);
--bg-blocklist-hover-color: var(--black-color); --bg-blocklist-hover-color: var(--black-color);
--bg-blocklist-item-selected-color: var(--black-color); --bg-blocklist-item-selected-color: var(--black-color);
@ -518,11 +487,15 @@
--bg-codemirror-selected-color: var(--grey-3); --bg-codemirror-selected-color: var(--grey-3);
--bg-log-viewer-color: var(--black-color); --bg-log-viewer-color: var(--black-color);
--bg-log-line-selected-color: var(--grey-3); --bg-log-line-selected-color: var(--grey-3);
--bg-sidebar-header-color: var(--black-color);
--bg-modal-content-color: var(--black-color); --bg-modal-content-color: var(--black-color);
--bg-form-control-disabled-color: var(--grey-1); --bg-form-control-disabled-color: var(--grey-1);
--bg-input-sm-color: var(--black-color); --bg-input-sm-color: var(--black-color);
--bg-item-highlighted-color: var(--black-color); --bg-item-highlighted-color: var(--black-color);
--bg-service-datatable-thead: var(--black-color);
--bg-inner-datatable-thead: var(--black-color);
--bg-app-datatable-thead: var(--black-color);
--bg-service-datatable-tbody: var(--black-color);
--bg-app-datatable-tbody: var(--black-color);
--bg-pagination-color: var(--grey-3); --bg-pagination-color: var(--grey-3);
--bg-pagination-span-color: var(--ui-black); --bg-pagination-span-color: var(--ui-black);
--bg-multiselect-color: var(--grey-1); --bg-multiselect-color: var(--grey-1);
@ -548,8 +521,6 @@
--bg-boxselector-color: var(--black-color); --bg-boxselector-color: var(--black-color);
--bg-boxselector-disabled-color: var(--black-color); --bg-boxselector-disabled-color: var(--black-color);
--bg-small-select-color: var(--black-color); --bg-small-select-color: var(--black-color);
--bg-app-datatable-thead: var(--black-color);
--bg-app-datatable-tbody: var(--black-color);
--bg-stepper-item-active: var(--black-color); --bg-stepper-item-active: var(--black-color);
--bg-stepper-item-counter: var(--grey-3); --bg-stepper-item-counter: var(--grey-3);
--bg-sortbutton-color: var(--grey-1); --bg-sortbutton-color: var(--grey-1);
@ -591,7 +562,6 @@
--text-daterangepicker-in-range: var(--white-color); --text-daterangepicker-in-range: var(--white-color);
--text-daterangepicker-active: var(--white-color); --text-daterangepicker-active: var(--white-color);
--text-ui-select-color: var(--white-color); --text-ui-select-color: var(--white-color);
--text-btn-default-color: var(--white-color);
--text-json-tree-color: var(--white-color); --text-json-tree-color: var(--white-color);
--text-json-tree-leaf-color: var(--white-color); --text-json-tree-leaf-color: var(--white-color);
--text-json-tree-branch-preview-color: var(--white-color); --text-json-tree-branch-preview-color: var(--white-color);
@ -600,9 +570,7 @@
--text-input-autofill-color: var(--white-color); --text-input-autofill-color: var(--white-color);
--text-navtabs-color: var(--white-color); --text-navtabs-color: var(--white-color);
--text-button-hover-color: var(--white-color); --text-button-hover-color: var(--white-color);
--text-btn-default-color: var(--white-color);
--text-small-select-color: var(--white-color); --text-small-select-color: var(--white-color);
--text-multiselect-item-color: var(--white-color);
--text-pagination-span-color: var(--ui-white); --text-pagination-span-color: var(--ui-white);
--text-bootbox: var(--white-color); --text-bootbox: var(--white-color);
--text-pagination-span-hover-color: var(--ui-white); --text-pagination-span-hover-color: var(--ui-white);
@ -618,8 +586,6 @@
--border-datatable-top-color: var(--grey-55); --border-datatable-top-color: var(--grey-55);
--border-sidebar-high-contrast: 1px solid var(--blue-9); --border-sidebar-high-contrast: 1px solid var(--blue-9);
--border-code-high-contrast: 1px solid var(--white-color); --border-code-high-contrast: 1px solid var(--white-color);
--border-boxselector-wrapper: 3px solid var(--blue-2);
--border-boxselector-wrapper-hover: 3px solid var(--blue-8);
--border-panel-color: var(--white-color); --border-panel-color: var(--white-color);
--border-input-group-addon-color: var(--grey-54); --border-input-group-addon-color: var(--grey-54);
--border-modal-header-color: var(--grey-3); --border-modal-header-color: var(--grey-3);
@ -631,7 +597,6 @@
--border-daterangepicker: var(--black-color); --border-daterangepicker: var(--black-color);
--border-pre-next-month: var(--white-color); --border-pre-next-month: var(--white-color);
--border-daterangepicker-after: var(--black-color); --border-daterangepicker-after: var(--black-color);
--border-tooltip-color: var(--white-color);
--border-pre-color: var(--grey-3); --border-pre-color: var(--grey-3);
--border-codemirror-cursor-color: var(--white-color); --border-codemirror-cursor-color: var(--white-color);
--border-modal: 1px solid var(--white-color); --border-modal: 1px solid var(--white-color);

View file

@ -48,12 +48,6 @@ a:focus {
border: 1px solid var(--border-input-group-addon-color); border: 1px solid var(--border-input-group-addon-color);
} }
.btn-default {
color: var(--text-btn-default-color);
background-color: var(--bg-btn-default-color);
border-color: var(--border-btn-default-color);
}
.text-danger { .text-danger {
color: var(--ui-error-9); color: var(--ui-error-9);
} }
@ -207,6 +201,7 @@ code {
.dropdown-menu { .dropdown-menu {
background: var(--bg-dropdown-menu-color); background: var(--bg-dropdown-menu-color);
border-radius: 8px;
} }
.dropdown-menu > li > a { .dropdown-menu > li > a {
@ -397,31 +392,8 @@ input:-webkit-autofill {
-webkit-text-fill-color: var(--text-input-autofill-color) !important; -webkit-text-fill-color: var(--text-input-autofill-color) !important;
} }
.btn:hover {
color: var(--text-button-hover-color);
}
.btn-default:hover {
background-color: var(--bg-btn-default-hover-color);
}
.btn-primary:hover {
color: var(--white-color) !important;
}
.btn-success:hover {
color: var(--white-color);
}
/* Overide Vendor CSS */ /* Overide Vendor CSS */
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
pointer-events: none;
touch-action: none;
}
.multiSelect.inlineBlock button { .multiSelect.inlineBlock button {
margin: 0; margin: 0;
} }

View file

@ -48,19 +48,11 @@
<li><a ng-click="$ctrl.forceRemoveAction($ctrl.state.selectedItems, true)" ng-disabled="$ctrl.state.selectedItemCount === 0">Force Remove</a></li> <li><a ng-click="$ctrl.forceRemoveAction($ctrl.state.selectedItems, true)" ng-disabled="$ctrl.state.selectedItemCount === 0">Force Remove</a></li>
</ul> </ul>
</div> </div>
<button
type="button"
class="btn btn-sm btn-primary h-fit vertical-center !ml-0"
ui-sref="docker.images.build"
authorization="DockerImageBuild"
data-cy="image-buildImageButton"
>
<pr-icon icon="'plus'" feather="true"></pr-icon>Build a new image
</button>
<div class="btn-group"> <div class="btn-group">
<button <button
type="button" type="button"
class="btn btn-sm btn-secondary h-fit" class="btn btn-sm btn-light h-fit"
ui-sref="docker.images.import" ui-sref="docker.images.import"
authorization="DockerImageLoad" authorization="DockerImageLoad"
ng-disabled="$ctrl.exportInProgress" ng-disabled="$ctrl.exportInProgress"
@ -70,7 +62,7 @@
</button> </button>
<button <button
type="button" type="button"
class="btn btn-sm btn-secondary h-fit" class="btn btn-sm btn-light h-fit"
ng-disabled="$ctrl.state.selectedItemCount === 0 || $ctrl.exportInProgress" ng-disabled="$ctrl.state.selectedItemCount === 0 || $ctrl.exportInProgress"
ng-click="$ctrl.downloadAction($ctrl.state.selectedItems)" ng-click="$ctrl.downloadAction($ctrl.state.selectedItems)"
button-spinner="$ctrl.exportInProgress" button-spinner="$ctrl.exportInProgress"
@ -82,6 +74,16 @@
<span ng-show="$ctrl.exportInProgress">Export in progress...</span> <span ng-show="$ctrl.exportInProgress">Export in progress...</span>
</button> </button>
</div> </div>
<button
type="button"
class="btn btn-sm btn-primary h-fit vertical-center !ml-0"
ui-sref="docker.images.build"
authorization="DockerImageBuild"
data-cy="image-buildImageButton"
>
<pr-icon icon="'plus'" feather="true"></pr-icon>Build a new image
</button>
</div> </div>
<div class="settings"> <div class="settings">
<span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open"> <span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open">

View file

@ -2,8 +2,8 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Placement constraints"> <rd-widget-header icon="list" feather-icon="true" title-text="Placement constraints">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addPlacementConstraint(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating || addPlacementConstraint(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> placement constraint <pr-icon icon="'plus'" feather="true"></pr-icon> placement constraint
</a> </a>
</div> </div>
</rd-widget-header> </rd-widget-header>

View file

@ -2,7 +2,7 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Container labels"> <rd-widget-header icon="list" feather-icon="true" title-text="Container labels">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addContainerLabel(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating ||addContainerLabel(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> container label <pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> container label
</a> </a>
</div> </div>

View file

@ -2,7 +2,7 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Environment variables"> <rd-widget-header icon="list" feather-icon="true" title-text="Environment variables">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addEnvironmentVariable(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating || addEnvironmentVariable(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> environment variable <pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> environment variable
</a> </a>
</div> </div>

View file

@ -2,8 +2,8 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Hosts file entries"> <rd-widget-header icon="list" feather-icon="true" title-text="Hosts file entries">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addHostsEntry(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating ||addHostsEntry(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> add host entry <pr-icon icon="'plus'" feather="true"></pr-icon> add host entry
</a> </a>
</div> </div>
</rd-widget-header> </rd-widget-header>

View file

@ -2,7 +2,7 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Mounts"> <rd-widget-header icon="list" feather-icon="true" title-text="Mounts">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addMount(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating ||addMount(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> mount <pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> mount
</a> </a>
</div> </div>

View file

@ -2,8 +2,8 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Networks"> <rd-widget-header icon="list" feather-icon="true" title-text="Networks">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addNetwork(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating || addNetwork(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> network <pr-icon icon="'plus'" feather="true"></pr-icon> network
</a> </a>
</div> </div>
</rd-widget-header> </rd-widget-header>

View file

@ -2,8 +2,8 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Placement preferences"> <rd-widget-header icon="list" feather-icon="true" title-text="Placement preferences">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addPlacementPreference(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating || addPlacementPreference(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> placement preference <pr-icon icon="'plus'" feather="true"></pr-icon> placement preference
</a> </a>
</div> </div>
</rd-widget-header> </rd-widget-header>

View file

@ -2,8 +2,8 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Published ports"> <rd-widget-header icon="list" feather-icon="true" title-text="Published ports">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addPublishedPort(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating ||addPublishedPort(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> port mapping <pr-icon icon="'plus'" feather="true"></pr-icon> port mapping
</a> </a>
</div> </div>
</rd-widget-header> </rd-widget-header>

View file

@ -2,8 +2,8 @@
<rd-widget> <rd-widget>
<rd-widget-header icon="list" feather-icon="true" title-text="Service labels"> <rd-widget-header icon="list" feather-icon="true" title-text="Service labels">
<div class="nopadding" authorization="DockerServiceUpdate"> <div class="nopadding" authorization="DockerServiceUpdate">
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addLabel(service)" ng-disabled="isUpdating"> <a class="btn btn-secondary btn-sm pull-right" ng-click="isUpdating || addLabel(service)" ng-disabled="isUpdating">
<pr-icon icon="'plus'" mode="'alt'" feather="true"></pr-icon> label <pr-icon icon="'plus'" feather="true"></pr-icon> label
</a> </a>
</div> </div>
</rd-widget-header> </rd-widget-header>

View file

@ -1,4 +0,0 @@
<div class="row header">
<div id="loadingbar-placeholder"></div>
<div class="col-xs-12"> <div class="meta" ng-transclude></div></div>
</div>

View file

@ -1,4 +0,0 @@
export const Header = {
transclude: true,
templateUrl: './HeaderContainer.html',
};

View file

@ -1,15 +0,0 @@
export default class HeaderContentController {
/* @ngInject */
constructor(Authentication) {
this.Authentication = Authentication;
this.display = !window.ddExtension;
this.username = null;
}
$onInit() {
const userDetails = this.Authentication.getUserDetails();
if (userDetails) {
this.username = userDetails.username;
}
}
}

View file

@ -1,3 +0,0 @@
<div class="breadcrumb-links">
<div class="pull-left" ng-transclude></div>
</div>

View file

@ -1,8 +0,0 @@
import controller from './HeaderContent.controller';
export const HeaderContent = {
requires: '^rdHeader',
transclude: true,
templateUrl: './HeaderContent.html',
controller,
};

View file

@ -1,15 +0,0 @@
export default class HeaderTitle {
/* @ngInject */
constructor(Authentication) {
this.Authentication = Authentication;
this.display = !window.ddExtension;
this.username = null;
}
$onInit() {
const userDetails = this.Authentication.getUserDetails();
if (userDetails) {
this.username = userDetails.username;
}
}
}

View file

@ -1,20 +0,0 @@
<div class="page white-space-normal">
{{ $ctrl.titleText }}
<span class="header_title_content" ng-transclude></span>
</div>
<span class="pull-right myaccount-container" uib-dropdown on-toggle="toggled(open)">
<a href class="myaccount-dropdown" uib-dropdown-toggle data-cy="userMenu-button" aria-label="User menu toggle">
<span class="pull-right user-box" ng-if="$ctrl.username">
<i class="fa fa-user-circle" aria-hidden="true"></i> {{ $ctrl.username }} <i class="fa fa-angle-down myaccount-icon" aria-hidden="true"></i>
</span>
</a>
<ul class="dropdown-menu" uib-dropdown-menu aria-label="User Menu" data-cy="userMenu">
<li>
<a ui-sref="portainer.account" data-cy="userMenu-myAccount">My account</a>
</li>
<li>
<a ui-sref="portainer.logout({performApiLogout: true})" data-cy="userMenu-logOut">Log out</a>
</li>
</ul>
</span>

View file

@ -1,11 +0,0 @@
import controller from './HeaderTitle.controller';
export const HeaderTitle = {
requires: '^rdHeader',
bindings: {
titleText: '@',
},
transclude: true,
templateUrl: './HeaderTitle.html',
controller,
};

View file

@ -1,12 +0,0 @@
import angular from 'angular';
import { Header } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
import { HeaderTitle } from './HeaderTitle';
export const pageHeaderModule = angular
.module('portainer.app.components.header', [])
.component('rdHeader', Header)
.component('rdHeaderContent', HeaderContent)
.component('rdHeaderTitle', HeaderTitle).name;

View file

@ -39,12 +39,12 @@
@apply text-blue-7; @apply text-blue-7;
} }
.datatable tr > td a { .datatable tr > td a:not(.btn) {
color: var(--ui-blue-8); color: var(--ui-blue-8);
} }
.datatable tr > td a:hover, .datatable tr > td a:not(.btn):hover,
.datatable tr > td a:focus { .datatable tr > td a:not(.btn):focus {
text-decoration: underline; text-decoration: underline;
} }
@ -84,10 +84,13 @@
.datatable .searchBar input[type='text'] { .datatable .searchBar input[type='text'] {
border: 0px !important; border: 0px !important;
@apply placeholder:text-gray-7;
@apply th-dark:placeholder:text-gray-warm-7;
} }
.datatable .searchIcon { .datatable .searchIcon {
color: #767676; @apply text-gray-7;
@apply th-dark:text-gray-warm-5;
margin-right: 5px; margin-right: 5px;
} }
@ -165,31 +168,6 @@
vertical-align: middle; vertical-align: middle;
} }
[data-reach-menu-list],
[data-reach-menu-items] {
padding: 0px;
border: 1px var(--bg-dropdown-menu-color);
}
.tableMenu {
color: #767676;
padding: 15px;
background-color: var(--bg-dropdown-menu-color) !important;
}
.tableMenu .menuHeader {
font-size: 16px;
}
.tableMenu .menuContent {
font-size: 12px;
margin: 10px 0;
}
.tableMenu .menuContent .md-radio:first-child {
margin: 0;
}
.datatable thead tr > th { .datatable thead tr > th {
white-space: nowrap; white-space: nowrap;
vertical-align: middle; vertical-align: middle;
@ -362,3 +340,37 @@
border-radius: 8px; border-radius: 8px;
flex-grow: 2; flex-grow: 2;
} }
/* Databatle Setting Menu */
.tableMenu {
border: 1px solid var(--border-bootbox);
border-radius: 8px;
color: var(--text-dropdown-menu-color);
padding: 15px;
background-color: var(--bg-dropdown-menu-color) !important;
}
[data-reach-menu-list],
[data-reach-menu-items] {
padding: 0px;
border: 1px var(--bg-dropdown-menu-color);
}
.dropdown-menu .tableMenu {
border: 0px;
}
.tableMenu .menuHeader {
font-size: 16px;
}
.tableMenu .menuContent {
font-size: 12px;
margin: 10px 0;
}
.tableMenu .menuContent .md-radio:first-child {
margin: 0;
}

View file

@ -5,12 +5,11 @@ import gitFormModule from './forms/git-form';
import porAccessManagementModule from './accessManagement'; import porAccessManagementModule from './accessManagement';
import widgetModule from './widget'; import widgetModule from './widget';
import { boxSelectorModule } from './BoxSelector'; import { boxSelectorModule } from './BoxSelector';
import { pageHeaderModule } from './PageHeader';
import { beFeatureIndicator } from './BEFeatureIndicator'; import { beFeatureIndicator } from './BEFeatureIndicator';
import { InformationPanelAngular } from './InformationPanel'; import { InformationPanelAngular } from './InformationPanel';
export default angular export default angular
.module('portainer.app.components', [pageHeaderModule, boxSelectorModule, widgetModule, gitFormModule, porAccessManagementModule, formComponentsModule]) .module('portainer.app.components', [boxSelectorModule, widgetModule, gitFormModule, porAccessManagementModule, formComponentsModule])
.component('informationPanel', InformationPanelAngular) .component('informationPanel', InformationPanelAngular)
.component('beFeatureIndicator', beFeatureIndicator).name; .component('beFeatureIndicator', beFeatureIndicator).name;

View file

@ -12,8 +12,3 @@
flex-direction: column; flex-direction: column;
} }
} }
.row.header {
background-color: var(--bg-body-color) !important;
margin-bottom: 5px !important;
}

View file

@ -1,12 +0,0 @@
.breadcrumb-links {
font-size: 10px;
}
.breadcrumb-links a {
color: var(--ui-blue-8);
}
.breadcrumb-links a:hover {
text-decoration: underline;
color: var(--ui-blue-9);
}

View file

@ -8,8 +8,9 @@ test('should display a Breadcrumbs, breadcrumbs should be separated by >', async
{ label: 'bread2' }, { label: 'bread2' },
{ label: 'bread3' }, { label: 'bread3' },
]; ];
const { queryByText } = render(<Breadcrumbs breadcrumbs={breadcrumbs} />); const { container } = render(<Breadcrumbs breadcrumbs={breadcrumbs} />);
const heading = queryByText(breadcrumbs.map((b) => b.label).join(' > ')); expect(container.firstChild?.textContent).toEqual(
expect(heading).toBeVisible(); breadcrumbs.map((b) => b.label).join('>')
);
}); });

View file

@ -2,8 +2,6 @@ import { Fragment } from 'react';
import { Link } from '@@/Link'; import { Link } from '@@/Link';
import './Breadcrumbs.css';
export interface Crumb { export interface Crumb {
label: string; label: string;
link?: string; link?: string;
@ -19,11 +17,11 @@ export function Breadcrumbs({ breadcrumbs }: Props) {
: [breadcrumbs]; : [breadcrumbs];
return ( return (
<div className="breadcrumb-links"> <div className="text-sm font-medium text-gray-7 th-dark:text-gray-5 th-highcontrast:text-white space-x-2">
{breadcrumbsArray.map((crumb, index) => ( {breadcrumbsArray.map((crumb, index) => (
<Fragment key={index}> <Fragment key={index}>
{renderCrumb(crumb)} <span>{renderCrumb(crumb)}</span>
{index !== breadcrumbsArray.length - 1 ? ' > ' : ''} {index !== breadcrumbsArray.length - 1 && <span>&gt;</span>}
</Fragment> </Fragment>
))} ))}
</div> </div>
@ -44,7 +42,7 @@ function renderCrumb(crumb: Crumb | string) {
<Link <Link
to={crumb.link} to={crumb.link}
params={crumb.linkParams} params={crumb.linkParams}
className="text-blue-9 hover:underline" className="text-blue-9 hover:underline hover:text-blue-11 th-dark:text-blue-7 th-dark:hover:text-blue-9 th-highcontrast:text-blue-5"
> >
{crumb.label} {crumb.label}
</Link> </Link>

View file

@ -1,33 +1,29 @@
.row.header .meta .page { .header {
padding-top: 7px; min-height: 60px;
margin-bottom: 15px;
background-color: var(--bg-body-color);
margin-bottom: 5px !important;
} }
.row.header { .header > div:last-child {
min-height: 60px;
background: var(--bg-row-header-color);
margin-bottom: 15px;
}
.row.header > div:last-child {
padding-right: 0; padding-right: 0;
} }
.row.header .meta .page {
font-size: 17px;
padding-top: 11px;
}
.row.header .meta div { .header .meta div {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.row.header .login a {
.header .login a {
padding: 18px; padding: 18px;
display: block; display: block;
} }
.row.header .user { .header .user {
min-width: 130px; min-width: 130px;
} }
.row.header .user > .item { .header .user > .item {
width: 65px; width: 65px;
height: 60px; height: 60px;
float: right; float: right;
@ -35,36 +31,36 @@
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
} }
.row.header .user > .item a { .header .user > .item a {
color: #919191; color: #919191;
display: block; display: block;
} }
.row.header .user > .item i { .header .user > .item i {
font-size: 20px; font-size: 20px;
line-height: 55px; line-height: 55px;
} }
.row.header .user > .item img { .header .user > .item img {
width: 40px; width: 40px;
height: 40px; height: 40px;
margin-top: 10px; margin-top: 10px;
border-radius: 2px; border-radius: 2px;
} }
.row.header .user > .item ul.dropdown-menu { .header .user > .item ul.dropdown-menu {
border-radius: 2px; border-radius: 2px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05); -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.05);
} }
.row.header .user > .item ul.dropdown-menu .dropdown-header { .header .user > .item ul.dropdown-menu .dropdown-header {
text-align: center; text-align: center;
} }
.row.header .user > .item ul.dropdown-menu li.link { .header .user > .item ul.dropdown-menu li.link {
text-align: left; text-align: left;
} }
.row.header .user > .item ul.dropdown-menu li.link a { .header .user > .item ul.dropdown-menu li.link a {
padding-left: 7px; padding-left: 7px;
padding-right: 7px; padding-right: 7px;
} }
.row.header .user > .item ul.dropdown-menu:before { .header .user > .item ul.dropdown-menu:before {
position: absolute; position: absolute;
top: -7px; top: -7px;
right: 23px; right: 23px;
@ -74,7 +70,7 @@
border-left: 7px solid transparent; border-left: 7px solid transparent;
content: ''; content: '';
} }
.row.header .user > .item ul.dropdown-menu:after { .header .user > .item ul.dropdown-menu:after {
position: absolute; position: absolute;
top: -6px; top: -6px;
right: 24px; right: 24px;

View file

@ -7,7 +7,6 @@ import { UserViewModel } from '@/portainer/models/user';
import { HeaderContainer } from './HeaderContainer'; import { HeaderContainer } from './HeaderContainer';
import { Breadcrumbs } from './Breadcrumbs'; import { Breadcrumbs } from './Breadcrumbs';
import { HeaderTitle } from './HeaderTitle'; import { HeaderTitle } from './HeaderTitle';
import { HeaderContent } from './HeaderContent';
export default { export default {
component: HeaderContainer, component: HeaderContainer,
@ -28,14 +27,13 @@ function Template({ title }: StoryProps) {
<UserContext.Provider value={state}> <UserContext.Provider value={state}>
<HeaderContainer> <HeaderContainer>
<HeaderTitle title={title} /> <HeaderTitle title={title} />
<HeaderContent>
<Breadcrumbs <Breadcrumbs
breadcrumbs={[ breadcrumbs={[
{ link: 'example', label: 'crumb1' }, { link: 'example', label: 'crumb1' },
{ label: 'crumb2' }, { label: 'crumb2' },
]} ]}
/> />
</HeaderContent>
</HeaderContainer> </HeaderContainer>
</UserContext.Provider> </UserContext.Provider>
); );

View file

@ -1,6 +1,7 @@
import { PropsWithChildren, createContext, useContext } from 'react'; import { PropsWithChildren, createContext, useContext } from 'react';
import clsx from 'clsx';
import './HeaderContainer.css'; import styles from './HeaderContainer.module.css';
const Context = createContext<null | boolean>(null); const Context = createContext<null | boolean>(null);
@ -15,10 +16,10 @@ export function useHeaderContext() {
export function HeaderContainer({ children }: PropsWithChildren<unknown>) { export function HeaderContainer({ children }: PropsWithChildren<unknown>) {
return ( return (
<Context.Provider value> <Context.Provider value>
<div className="row header"> <div className={clsx('row', styles.header)}>
<div id="loadingbar-placeholder" /> <div id="loadingbar-placeholder" />
<div className="col-xs-12"> <div className="col-xs-12">
<div className="meta">{children}</div> <div className={styles.meta}>{children}</div>
</div> </div>
</div> </div>
</Context.Provider> </Context.Provider>

View file

@ -1,31 +0,0 @@
import { renderWithQueryClient } from '@/react-tools/test-utils';
import { HeaderContainer } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
test('should not render without a wrapping HeaderContainer', async () => {
const consoleErrorFn = jest
.spyOn(console, 'error')
.mockImplementation(() => jest.fn());
function renderComponent() {
return renderWithQueryClient(<HeaderContent />);
}
expect(renderComponent).toThrowErrorMatchingSnapshot();
consoleErrorFn.mockRestore();
});
test('should display a HeaderContent', async () => {
const content = 'content';
const { queryByText } = renderWithQueryClient(
<HeaderContainer>
<HeaderContent>{content}</HeaderContent>
</HeaderContainer>
);
const contentElement = queryByText(content);
expect(contentElement).toBeVisible();
});

View file

@ -1,13 +0,0 @@
import { PropsWithChildren } from 'react';
import { useHeaderContext } from './HeaderContainer';
export function HeaderContent({ children }: PropsWithChildren<unknown>) {
useHeaderContext();
return (
<div className="breadcrumb-links">
<div className="pull-left">{children}</div>
</div>
);
}

View file

@ -24,13 +24,17 @@ export function HeaderTitle({ title, children }: PropsWithChildren<Props>) {
const { user } = useUser(); const { user } = useUser();
return ( return (
<div className="page white-space-normal"> <div className="flex justify-between whitespace-normal pt-3">
{title} <div className="flex items-center gap-2">
<span className="header_title_content">{children}</span> <div className="font-medium text-3xl text-gray-11 th-dark:text-white th-highcontrast:text-white">
{title}
</div>
{children && <span>{children}</span>}
</div>
<Menu> <Menu>
<MenuButton <MenuButton
className={clsx( className={clsx(
'pull-right flex items-center gap-1', 'ml-auto flex items-center gap-1 self-start',
styles.menuButton styles.menuButton
)} )}
data-cy="userMenu-button" data-cy="userMenu-button"

View file

@ -6,7 +6,6 @@ import { Button } from '../buttons';
import { Breadcrumbs } from './Breadcrumbs'; import { Breadcrumbs } from './Breadcrumbs';
import { Crumb } from './Breadcrumbs/Breadcrumbs'; import { Crumb } from './Breadcrumbs/Breadcrumbs';
import { HeaderContainer } from './HeaderContainer'; import { HeaderContainer } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
import { HeaderTitle } from './HeaderTitle'; import { HeaderTitle } from './HeaderTitle';
import styles from './PageHeader.module.css'; import styles from './PageHeader.module.css';
@ -33,9 +32,8 @@ export function PageHeader({
return ( return (
<HeaderContainer> <HeaderContainer>
<HeaderContent> <Breadcrumbs breadcrumbs={breadcrumbs} />
<Breadcrumbs breadcrumbs={breadcrumbs} />
</HeaderContent>
<HeaderTitle title={title}> <HeaderTitle title={title}>
{reload && ( {reload && (
<Button <Button

View file

@ -1,3 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should not render without a wrapping HeaderContainer 1`] = `"Should be nested inside a HeaderContainer component"`;

View file

@ -1,7 +1 @@
import { Breadcrumbs } from './Breadcrumbs'; export { PageHeader } from './PageHeader';
import { PageHeader } from './PageHeader';
import { HeaderContainer } from './HeaderContainer';
import { HeaderContent } from './HeaderContent';
import { HeaderTitle } from './HeaderTitle';
export { PageHeader, Breadcrumbs, HeaderContainer, HeaderContent, HeaderTitle };

View file

@ -13,10 +13,8 @@ export function DifferentTheme() {
const colors = [ const colors = [
'primary', 'primary',
'secondary', 'secondary',
'success',
'danger', 'danger',
'dangerlight', 'dangerlight',
'warning',
'light', 'light',
'link', 'link',
] as const; ] as const;
@ -97,22 +95,6 @@ export function Disabled() {
); );
} }
export function Warning() {
return (
<Button color="warning" onClick={() => {}}>
Warning Button
</Button>
);
}
export function Success() {
return (
<Button color="success" onClick={() => {}}>
Success Button
</Button>
);
}
export function Danger() { export function Danger() {
return ( return (
<Button color="danger" onClick={() => {}}> <Button color="danger" onClick={() => {}}>

View file

@ -17,8 +17,6 @@ type Color =
| 'default' | 'default'
| 'primary' | 'primary'
| 'secondary' | 'secondary'
| 'success'
| 'warning'
| 'danger' | 'danger'
| 'link' | 'link'
| 'light' | 'light'

View file

@ -14,7 +14,7 @@ function Template({
}: JSX.IntrinsicAttributes & PropsWithChildren<Props>) { }: JSX.IntrinsicAttributes & PropsWithChildren<Props>) {
return ( return (
<ButtonGroup size={size}> <ButtonGroup size={size}>
<Button color="success" onClick={() => {}}> <Button color="primary" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
@ -50,7 +50,7 @@ Primary.args = {
export function Xsmall() { export function Xsmall() {
return ( return (
<ButtonGroup size="xsmall"> <ButtonGroup size="xsmall">
<Button color="success" onClick={() => {}}> <Button color="primary" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
@ -58,7 +58,7 @@ export function Xsmall() {
<i className="fa fa-stop space-right" aria-hidden="true" /> <i className="fa fa-stop space-right" aria-hidden="true" />
Stop Stop
</Button> </Button>
<Button color="success" onClick={() => {}}> <Button color="primary" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
@ -73,7 +73,7 @@ export function Xsmall() {
export function Small() { export function Small() {
return ( return (
<ButtonGroup size="small"> <ButtonGroup size="small">
<Button color="success" onClick={() => {}}> <Button color="primary" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
@ -81,7 +81,7 @@ export function Small() {
<i className="fa fa-stop space-right" aria-hidden="true" /> <i className="fa fa-stop space-right" aria-hidden="true" />
Stop Stop
</Button> </Button>
<Button color="success" onClick={() => {}}> <Button color="primary" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
@ -96,7 +96,7 @@ export function Small() {
export function Large() { export function Large() {
return ( return (
<ButtonGroup size="large"> <ButtonGroup size="large">
<Button color="success" onClick={() => {}}> <Button color="primary" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
@ -104,7 +104,7 @@ export function Large() {
<i className="fa fa-stop space-right" aria-hidden="true" /> <i className="fa fa-stop space-right" aria-hidden="true" />
Stop Stop
</Button> </Button>
<Button color="success" onClick={() => {}}> <Button color="light" onClick={() => {}}>
<i className="fa fa-play space-right" aria-hidden="true" /> <i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>

View file

@ -1,4 +1,13 @@
import { useRouter } from '@uirouter/react'; import { useRouter } from '@uirouter/react';
import {
Pause,
Play,
Plus,
RefreshCw,
Slash,
Square,
Trash2,
} from 'react-feather';
import * as notifications from '@/portainer/services/notifications'; import * as notifications from '@/portainer/services/notifications';
import { useAuthorizations, Authorized } from '@/portainer/hooks/useUser'; import { useAuthorizations, Authorized } from '@/portainer/hooks/useUser';
@ -84,8 +93,8 @@ export function ContainersDatatableActions({
color="light" color="light"
onClick={() => onStartClick(selectedItems)} onClick={() => onStartClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasStoppedItemsSelected} disabled={selectedItemCount === 0 || !hasStoppedItemsSelected}
icon={Play}
> >
<i className="fa fa-play space-right" aria-hidden="true" />
Start Start
</Button> </Button>
</Authorized> </Authorized>
@ -95,8 +104,8 @@ export function ContainersDatatableActions({
color="light" color="light"
onClick={() => onStopClick(selectedItems)} onClick={() => onStopClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasRunningItemsSelected} disabled={selectedItemCount === 0 || !hasRunningItemsSelected}
icon={Square}
> >
<i className="fa fa-stop space-right" aria-hidden="true" />
Stop Stop
</Button> </Button>
</Authorized> </Authorized>
@ -106,8 +115,8 @@ export function ContainersDatatableActions({
color="light" color="light"
onClick={() => onKillClick(selectedItems)} onClick={() => onKillClick(selectedItems)}
disabled={selectedItemCount === 0 || hasStoppedItemsSelected} disabled={selectedItemCount === 0 || hasStoppedItemsSelected}
icon={Slash}
> >
<i className="fa fa-bomb space-right" aria-hidden="true" />
Kill Kill
</Button> </Button>
</Authorized> </Authorized>
@ -117,8 +126,8 @@ export function ContainersDatatableActions({
color="light" color="light"
onClick={() => onRestartClick(selectedItems)} onClick={() => onRestartClick(selectedItems)}
disabled={selectedItemCount === 0} disabled={selectedItemCount === 0}
icon={RefreshCw}
> >
<i className="fa fa-sync space-right" aria-hidden="true" />
Restart Restart
</Button> </Button>
</Authorized> </Authorized>
@ -128,8 +137,8 @@ export function ContainersDatatableActions({
color="light" color="light"
onClick={() => onPauseClick(selectedItems)} onClick={() => onPauseClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasRunningItemsSelected} disabled={selectedItemCount === 0 || !hasRunningItemsSelected}
icon={Pause}
> >
<i className="fa fa-pause space-right" aria-hidden="true" />
Pause Pause
</Button> </Button>
</Authorized> </Authorized>
@ -139,8 +148,8 @@ export function ContainersDatatableActions({
color="light" color="light"
onClick={() => onResumeClick(selectedItems)} onClick={() => onResumeClick(selectedItems)}
disabled={selectedItemCount === 0 || !hasPausedItemsSelected} disabled={selectedItemCount === 0 || !hasPausedItemsSelected}
icon={Play}
> >
<i className="fa fa-play space-right" aria-hidden="true" />
Resume Resume
</Button> </Button>
</Authorized> </Authorized>
@ -150,8 +159,8 @@ export function ContainersDatatableActions({
color="dangerlight" color="dangerlight"
onClick={() => onRemoveClick(selectedItems)} onClick={() => onRemoveClick(selectedItems)}
disabled={selectedItemCount === 0} disabled={selectedItemCount === 0}
icon={Trash2}
> >
<i className="fa fa-trash-alt space-right" aria-hidden="true" />
Remove Remove
</Button> </Button>
</Authorized> </Authorized>
@ -160,10 +169,7 @@ export function ContainersDatatableActions({
{isAddActionVisible && ( {isAddActionVisible && (
<Authorized authorizations="DockerContainerCreate"> <Authorized authorizations="DockerContainerCreate">
<Link to="docker.containers.new" className="space-left"> <Link to="docker.containers.new" className="space-left">
<Button> <Button icon={Plus}>Add container</Button>
<i className="fa fa-plus space-right" aria-hidden="true" />
Add container
</Button>
</Link> </Link>
</Authorized> </Authorized>
)} )}