Compare commits
24 Commits
fix/ee-350
...
2.14.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14b998d270 | ||
|
|
605ff8c1da | ||
|
|
13f93f4262 | ||
|
|
16be5ed329 | ||
|
|
c6612898f3 | ||
|
|
564f34b0ba | ||
|
|
392fbdb4a7 | ||
|
|
a826c78786 | ||
|
|
a35f0607f1 | ||
|
|
081d32af0d | ||
|
|
4cc0b1f567 | ||
|
|
d4da7e1760 | ||
|
|
aced418880 | ||
|
|
614f42fe5a | ||
|
|
58736fe93b | ||
|
|
b78330b10d | ||
|
|
eed4a92ca8 | ||
|
|
0e7468a1e8 | ||
|
|
b807481f1c | ||
|
|
da27de2154 | ||
|
|
6743e4fbb2 | ||
|
|
b489ffaa63 | ||
|
|
6e12499d61 | ||
|
|
f7acbe16ba |
@@ -31,12 +31,7 @@ rules:
|
||||
[
|
||||
'error',
|
||||
{
|
||||
pathGroups:
|
||||
[
|
||||
{ pattern: '@@/**', group: 'internal', position: 'after' },
|
||||
{ pattern: '@/**', group: 'internal' },
|
||||
{ pattern: '{Kubernetes,Portainer,Agent,Azure,Docker}/**', group: 'internal' },
|
||||
],
|
||||
pathGroups: [{ pattern: '@/**', group: 'internal' }, { pattern: '{Kubernetes,Portainer,Agent,Azure,Docker}/**', group: 'internal' }],
|
||||
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
|
||||
pathGroupsExcludedImportTypes: ['internal'],
|
||||
},
|
||||
@@ -46,7 +41,6 @@ settings:
|
||||
'import/resolver':
|
||||
alias:
|
||||
map:
|
||||
- ['@@', './app/react/components']
|
||||
- ['@', './app']
|
||||
extensions: ['.js', '.ts', '.tsx']
|
||||
|
||||
@@ -58,7 +52,6 @@ overrides:
|
||||
parser: '@typescript-eslint/parser'
|
||||
plugins:
|
||||
- '@typescript-eslint'
|
||||
- 'regex'
|
||||
extends:
|
||||
- airbnb
|
||||
- airbnb-typescript
|
||||
@@ -75,14 +68,7 @@ overrides:
|
||||
version: 'detect'
|
||||
rules:
|
||||
import/order:
|
||||
[
|
||||
'error',
|
||||
{
|
||||
pathGroups: [{ pattern: '@@/**', group: 'internal', position: 'after' }, { pattern: '@/**', group: 'internal' }],
|
||||
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
|
||||
'newlines-between': 'always',
|
||||
},
|
||||
]
|
||||
['error', { pathGroups: [{ pattern: '@/**', group: 'internal' }], groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], 'newlines-between': 'always' }]
|
||||
func-style: [error, 'declaration']
|
||||
import/prefer-default-export: off
|
||||
no-use-before-define: ['error', { functions: false }]
|
||||
@@ -104,7 +90,6 @@ overrides:
|
||||
'react/jsx-no-bind': off
|
||||
'no-await-in-loop': 'off'
|
||||
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }]
|
||||
'regex/invalid': ['error', [{ 'regex': 'data-feather="(.*)"', 'message': 'Please use `react-feather` package instead' }]]
|
||||
- files:
|
||||
- app/**/*.test.*
|
||||
extends:
|
||||
|
||||
@@ -22,7 +22,7 @@ Please note that the public demo cluster is **reset every 15min**.
|
||||
|
||||
Portainer CE is updated regularly. We aim to do an update release every couple of months.
|
||||
|
||||
**The latest version of Portainer is 2.13.x**.
|
||||
**The latest version of Portainer is 2.9.x**. Portainer is on version 2, the second number denotes the month of release.
|
||||
|
||||
## Getting started
|
||||
|
||||
|
||||
@@ -910,7 +910,7 @@
|
||||
],
|
||||
"version": {
|
||||
"DB_UPDATING": "false",
|
||||
"DB_VERSION": "60",
|
||||
"DB_VERSION": "50",
|
||||
"INSTANCE_ID": "null"
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ type Handler struct {
|
||||
}
|
||||
|
||||
// @title PortainerCE API
|
||||
// @version 2.15.0
|
||||
// @version 2.14.0
|
||||
// @description.markdown api-description.md
|
||||
// @termsOfService
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ func parseRegToken(registry *portainer.Registry) (username, password string, err
|
||||
func EnsureRegTokenValid(dataStore dataservices.DataStore, registry *portainer.Registry) (err error) {
|
||||
if registry.Type == portainer.EcrRegistry {
|
||||
if isRegTokenValid(registry) {
|
||||
log.Println("[DEBUG] [registry, GetEcrAccessToken] [message: current ECR token is still valid]")
|
||||
log.Println("[DEBUG] [registry, GetEcrAccessToken] [message: curretn ECR token is still valid]")
|
||||
} else {
|
||||
err = doGetRegToken(dataStore, registry)
|
||||
if err != nil {
|
||||
|
||||
@@ -1385,9 +1385,9 @@ type (
|
||||
|
||||
const (
|
||||
// APIVersion is the version number of the Portainer API
|
||||
APIVersion = "2.15.0"
|
||||
APIVersion = "2.14.0"
|
||||
// DBVersion is the version number of the Portainer database
|
||||
DBVersion = 60
|
||||
DBVersion = 50
|
||||
// ComposeSyntaxMaxVersion is a maximum supported version of the docker compose syntax
|
||||
ComposeSyntaxMaxVersion = "3.9"
|
||||
// AssetsServerURL represents the URL of the Portainer asset server
|
||||
|
||||
14
app/app.js
14
app/app.js
@@ -1,5 +1,4 @@
|
||||
import $ from 'jquery';
|
||||
import feather from 'feather-icons';
|
||||
import { PortainerEndpointTypes } from 'Portainer/models/endpoint/models';
|
||||
|
||||
/* @ngInject */
|
||||
@@ -7,14 +6,7 @@ export function onStartupAngular($rootScope, $state, $interval, LocalStorage, En
|
||||
EndpointProvider.initialize();
|
||||
|
||||
$rootScope.$state = $state;
|
||||
const defaultTitle = document.title;
|
||||
|
||||
$transitions.onEnter({}, () => {
|
||||
const endpoint = EndpointProvider.currentEndpoint();
|
||||
if (endpoint) {
|
||||
document.title = `${defaultTitle} | ${endpoint.Name}`;
|
||||
}
|
||||
});
|
||||
$rootScope.defaultTitle = document.title;
|
||||
|
||||
// Workaround to prevent the loading bar from going backward
|
||||
// https://github.com/chieffancypants/angular-loading-bar/issues/273
|
||||
@@ -29,10 +21,6 @@ export function onStartupAngular($rootScope, $state, $interval, LocalStorage, En
|
||||
HttpRequestHelper.resetAgentHeaders();
|
||||
});
|
||||
|
||||
$transitions.onSuccess({}, () => {
|
||||
feather.replace();
|
||||
});
|
||||
|
||||
// Keep-alive Edge endpoints by sending a ping request every minute
|
||||
$interval(() => {
|
||||
ping(EndpointProvider, SystemService);
|
||||
|
||||
@@ -2,27 +2,8 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../fonts/Inter-VariableFont.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
}
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
select {
|
||||
font-family: Inter, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--bg-body-color);
|
||||
font-family: 'Inter';
|
||||
color: var(--text-body-color) !important;
|
||||
}
|
||||
|
||||
html,
|
||||
@@ -86,6 +67,7 @@ body,
|
||||
}
|
||||
|
||||
.form-section-title {
|
||||
border-bottom: 1px solid var(--border-form-section-title-color);
|
||||
margin-top: 5px;
|
||||
margin-bottom: 15px;
|
||||
color: var(--text-form-section-title-color);
|
||||
@@ -167,7 +149,7 @@ a[ng-click] {
|
||||
}
|
||||
|
||||
.fa.red-icon {
|
||||
color: #f04438;
|
||||
color: #ae2323;
|
||||
}
|
||||
|
||||
.fa.orange-icon {
|
||||
@@ -239,13 +221,12 @@ a[ng-click] {
|
||||
}
|
||||
|
||||
.blocklist-item {
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
margin-bottom: 7px;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--border-blocklist);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-blocklist-color);
|
||||
border-radius: 2px;
|
||||
box-shadow: var(--shadow-box-color);
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.blocklist-item--disabled {
|
||||
@@ -260,8 +241,6 @@ a[ng-click] {
|
||||
}
|
||||
|
||||
.blocklist-item:hover {
|
||||
@apply border border-blue-7;
|
||||
|
||||
background-color: var(--bg-blocklist-hover-color);
|
||||
color: var(--text-blocklist-hover-color);
|
||||
}
|
||||
@@ -400,13 +379,12 @@ a[ng-click] {
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
padding: 30px 25px;
|
||||
background-color: var(--white-color);
|
||||
border-radius: 8px;
|
||||
padding-top: 30px;
|
||||
background-color: var(--white-color) fff;
|
||||
}
|
||||
|
||||
.user-box {
|
||||
margin-right: 15px;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.select-endpoint {
|
||||
@@ -829,12 +807,11 @@ json-tree .branch-preview {
|
||||
}
|
||||
/* !spinkit override */
|
||||
|
||||
/* uib-typeahead override */
|
||||
#scrollable-dropdown-menu .dropdown-menu {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
.kubectl-shell {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
/* !uib-typeahead override */
|
||||
|
||||
.no-margin {
|
||||
margin: 0 !important;
|
||||
@@ -858,12 +835,3 @@ json-tree .branch-preview {
|
||||
.form-check.radio {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.inline-text {
|
||||
display: inline;
|
||||
position: absolute;
|
||||
font-family: 'Montserrat';
|
||||
font-size: smaller;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
468
app/assets/css/bootstrap-override.css
vendored
468
app/assets/css/bootstrap-override.css
vendored
@@ -1,468 +0,0 @@
|
||||
/* Main Color UI Override*/
|
||||
|
||||
.blue {
|
||||
background: var(--bg-dashboard-item) !important;
|
||||
}
|
||||
|
||||
/* Button */
|
||||
.btn {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--ui-blue-8);
|
||||
}
|
||||
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus,
|
||||
.btn-primary:active .active {
|
||||
background-color: var(--ui-blue-2);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: var(--ui-error-8);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background-color: var(--ui-success-7);
|
||||
}
|
||||
|
||||
/* Toggle switch */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 42px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Toggle */
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--bg-switch-box-color);
|
||||
-webkit-transition: 0.4s;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
height: 19px;
|
||||
width: 19px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background-color: var(--white-color);
|
||||
-webkit-transition: 0.4s;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: var(--ui-blue-8);
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px var(--ui-blue-8);
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(17px);
|
||||
-ms-transform: translateX(17px);
|
||||
transform: translateX(17px);
|
||||
}
|
||||
|
||||
.slider.round {
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Checkbox */
|
||||
|
||||
.md-checkbox input[type='checkbox']:enabled + label:before {
|
||||
background-color: var(--bg-checkbox) !important;
|
||||
border: 1px solid var(--border-checkbox) !important;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.md-checkbox input[type='checkbox']:disabled + label:before {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.md-checkbox input[type='checkbox']:checked + label:before {
|
||||
background-color: var(--ui-blue-8) !important;
|
||||
color: var(--ui-blue-8) !important;
|
||||
border: 1px solid var(--ui-blue-8) !important;
|
||||
}
|
||||
|
||||
.md-checkbox input[type='checkbox']:checked + .checkmark {
|
||||
border-color: var(--grey-6);
|
||||
background-color: var(--bg-checkbox);
|
||||
}
|
||||
|
||||
/* Slider */
|
||||
|
||||
.rzslider .rz-pointer {
|
||||
background-color: var(--white-color);
|
||||
border: 3px solid var(--ui-blue-8);
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
top: -10px;
|
||||
}
|
||||
|
||||
.rzslider .rz-bar {
|
||||
background-color: var(--ui-gray-5);
|
||||
height: 8px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.rzslider .rz-selection {
|
||||
background-color: var(--ui-blue-8);
|
||||
}
|
||||
|
||||
.rzslider .rz-pointer:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Datatable */
|
||||
|
||||
.datatable .searchBar {
|
||||
border: 1px solid var(--border-searchbar);
|
||||
padding: 5px;
|
||||
background: var(--bg-searchbar) !important;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.datatable .searchBar input[type='text'] {
|
||||
border: 0px !important;
|
||||
}
|
||||
|
||||
.datatable .toolBar {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.datatable .footer {
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.datatable .toolBar {
|
||||
padding-top: 20px !important;
|
||||
padding-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.toolBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.toolBar > .toolBarTitle {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.toolBar > .searchBar {
|
||||
flex: right;
|
||||
margin-right: 10px;
|
||||
width: 500px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.datatable .searchBar {
|
||||
padding: 4px 10px !important;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.toolBar > .actionBar {
|
||||
flex: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.datatable .actionBar {
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.toolBar > .settings {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.datatable .toolBar .settings {
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
|
||||
/* Widget */
|
||||
|
||||
.widget .widget-icon i {
|
||||
color: var(--ui-blue-8);
|
||||
}
|
||||
|
||||
.widget .widget-body table thead {
|
||||
border-top: 1px solid var(--border-table-color);
|
||||
}
|
||||
|
||||
/* Button Group */
|
||||
.input-group-addon:first-child {
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
.input-group .form-control:not(:first-child):not(:last-child) {
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
.input-group-btn:last-child .btn {
|
||||
margin-left: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
|
||||
background-color: var(--bg-button-group);
|
||||
border: 1px solid var(--border-button-group);
|
||||
color: var(--text-button-group);
|
||||
}
|
||||
|
||||
.btn-group .btn-light {
|
||||
background-color: var(--bg-button-group);
|
||||
border: 1px solid var(--border-button-group);
|
||||
color: var(--text-button-group);
|
||||
}
|
||||
|
||||
.btn-group .btn-dangerlight {
|
||||
background-color: var(--ui-error-2);
|
||||
border: 1px solid var(--border-button-group);
|
||||
color: var(--ui-error-8);
|
||||
}
|
||||
|
||||
.btn.active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Toaster */
|
||||
|
||||
#toast-container > .toast-success {
|
||||
background-image: url(../images/icon-success.svg) !important;
|
||||
background-position: top 20px left 20px;
|
||||
}
|
||||
|
||||
#toast-container > .toast-error {
|
||||
background-image: url(../images/icon-error.svg) !important;
|
||||
background-position: top 20px left 20px;
|
||||
}
|
||||
|
||||
#toast-container > .toast-warning {
|
||||
background-image: url(../images/icon-warning.svg) !important;
|
||||
}
|
||||
|
||||
.toast-success .toast-progress {
|
||||
background-color: var(--ui-success-7);
|
||||
}
|
||||
.toast-warning .toast-progress {
|
||||
background-color: var(--ui-warning-6);
|
||||
}
|
||||
.toast-error .toast-progress {
|
||||
background-color: var(--ui-error-8);
|
||||
}
|
||||
|
||||
#toast-container > div {
|
||||
color: var(--ui-gray-7);
|
||||
background-color: var(--white-color);
|
||||
border-radius: 8px;
|
||||
padding: 20px 20px 20px 80px;
|
||||
width: 300px;
|
||||
opacity: 1;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
|
||||
#toast-container > div:hover {
|
||||
-moz-box-shadow: 0 0 12px var(--ui-gray-7);
|
||||
-webkit-box-shadow: 0 0 12px var(--ui-gray-7);
|
||||
box-shadow: 0 0 12px var(--ui-gray-7);
|
||||
}
|
||||
|
||||
.toast-close-button {
|
||||
color: var(--black-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
opacity: 0.4;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
|
||||
.toast-close-button:hover,
|
||||
.toast-close-button:focus {
|
||||
color: var(--black-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=60);
|
||||
filter: alpha(opacity=60);
|
||||
}
|
||||
|
||||
.toast-title {
|
||||
color: var(--black-color);
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
|
||||
.modal-dialog {
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
padding: 55px 20px 20px 20px;
|
||||
background-image: url(../images/icon-warning.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top 10px left 10px;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 10px 0px 10px 0px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.modal-header .close {
|
||||
margin-top: -40px;
|
||||
}
|
||||
|
||||
.modal-header .modal-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 10px 0px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.modal-body .bootbox-body {
|
||||
font-size: 12px;
|
||||
color: var(--text-bootbox);
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 10px 0px;
|
||||
border-top: none;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal-footer .bootbox-cancel {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.modal-footer .bootbox-accept {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bootbox-checkbox-list {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
/* Boxselector */
|
||||
|
||||
.boxselector_wrapper input[type='radio']:checked + label,
|
||||
.box-selector-item input[type='radio']:checked + label {
|
||||
background: var(--ui-blue-3) !important;
|
||||
color: black !important;
|
||||
border-radius: 8px;
|
||||
border-color: var(--ui-blue-7);
|
||||
padding: 15px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.boxselector_wrapper input[type='radio']:not(:disabled) + label,
|
||||
.box-selector-item input[type='radio']:not(:disabled) + label {
|
||||
background: var(--ui-gray-2);
|
||||
color: var(--black-color) !important;
|
||||
border-radius: 8px;
|
||||
border-color: var(--ui-gray-5);
|
||||
padding: 15px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.row.header {
|
||||
background-color: var(--bg-body-color) !important;
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Myaccount Dropdown Menu */
|
||||
|
||||
.myaccount-dropdown {
|
||||
color: var(--text-body-color);
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.myaccount-container {
|
||||
margin-top: -25px;
|
||||
}
|
||||
|
||||
.myaccount-icon {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.myaccount-link {
|
||||
display: inline;
|
||||
border: 0px;
|
||||
background: none;
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
/* Status Indicator Label Style */
|
||||
.label {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.label-danger {
|
||||
background-color: var(--ui-error-8);
|
||||
}
|
||||
|
||||
.label-success {
|
||||
background-color: var(--ui-success-7);
|
||||
}
|
||||
|
||||
/* Feather Icon */
|
||||
|
||||
.feather {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
margin-right: 5px;
|
||||
color: var(--text-body-color);
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
{
|
||||
"black": "#000000",
|
||||
"white": "#ffffff",
|
||||
"gray": {
|
||||
"1": "#fcfcfd",
|
||||
"2": "#f9fafb",
|
||||
"3": "#f2f4f7",
|
||||
"4": "#eaecf0",
|
||||
"5": "#d0d5dd",
|
||||
"6": "#98a2b3",
|
||||
"7": "#667085",
|
||||
"8": "#475467",
|
||||
"9": "#344054",
|
||||
"10": "#1d2939",
|
||||
"11": "#101828"
|
||||
},
|
||||
"blue": {
|
||||
"1": "#f5fbff",
|
||||
"2": "#f0f9ff",
|
||||
"3": "#e0f2fe",
|
||||
"4": "#b9e6fe",
|
||||
"5": "#7cd4fd",
|
||||
"6": "#36bffa",
|
||||
"7": "#0ba5ec",
|
||||
"8": "#0086c9",
|
||||
"9": "#026aa2",
|
||||
"10": "#065986",
|
||||
"11": "#0b4a6f"
|
||||
},
|
||||
"error": {
|
||||
"1": "#fffbfa",
|
||||
"2": "#fef3f2",
|
||||
"3": "#fee4e2",
|
||||
"4": "#fecdca",
|
||||
"5": "#fda29b",
|
||||
"6": "#f97066",
|
||||
"7": "#f04438",
|
||||
"8": "#d92d20",
|
||||
"9": "#b42318",
|
||||
"10": "#912018",
|
||||
"11": "#7a271a"
|
||||
},
|
||||
"warning": {
|
||||
"1": "#fffcf5",
|
||||
"2": "#fffaeb",
|
||||
"3": "#fef0c7",
|
||||
"4": "#fedf89",
|
||||
"5": "#fec84b",
|
||||
"6": "#fdb022",
|
||||
"7": "#f79009",
|
||||
"8": "#dc6803",
|
||||
"9": "#b54708",
|
||||
"10": "#93370d",
|
||||
"11": "#7a2e0e"
|
||||
},
|
||||
"success": {
|
||||
"1": "#f6fef9",
|
||||
"2": "#ecfdf3",
|
||||
"3": "#d1fadf",
|
||||
"4": "#a6f4c5",
|
||||
"5": "#6ce9a6",
|
||||
"6": "#32d583",
|
||||
"7": "#12b76a",
|
||||
"8": "#039855",
|
||||
"9": "#027a48",
|
||||
"10": "#05603a",
|
||||
"11": "#054f31"
|
||||
},
|
||||
"gray-blue": {
|
||||
"1": "#fcfcfd",
|
||||
"2": "#f8f9fc",
|
||||
"3": "#eaecf5",
|
||||
"4": "#d5d9eb",
|
||||
"5": "#b3b8db",
|
||||
"6": "#717bbc",
|
||||
"7": "#4e5ba6",
|
||||
"8": "#3e4784",
|
||||
"9": "#363f72",
|
||||
"10": "#293056",
|
||||
"11": "#293056"
|
||||
},
|
||||
"gray-cool": {
|
||||
"1": "#fcfcfd",
|
||||
"2": "#f9f9fb",
|
||||
"3": "#eff1f5",
|
||||
"4": "#dcdfea",
|
||||
"5": "#b9c0d4",
|
||||
"6": "#7d89b0",
|
||||
"7": "#5d6b98",
|
||||
"8": "#4a5578",
|
||||
"9": "#404968",
|
||||
"10": "#30374f",
|
||||
"11": "#111322"
|
||||
},
|
||||
"gray-modern": {
|
||||
"1": "#fcfcfd",
|
||||
"2": "#f8fafc",
|
||||
"3": "#eef2f6",
|
||||
"4": "#e3e8ef",
|
||||
"5": "#cdd5df",
|
||||
"6": "#9aa4b2",
|
||||
"7": "#697586",
|
||||
"8": "#4b5565",
|
||||
"9": "#364152",
|
||||
"10": "#202939",
|
||||
"11": "#121926"
|
||||
},
|
||||
"gray-neutral": {
|
||||
"1": "#fcfcfd",
|
||||
"2": "#f9fafb",
|
||||
"3": "#f3f4f6",
|
||||
"4": "#e5e7eb",
|
||||
"5": "#d2d6db",
|
||||
"6": "#9da4ae",
|
||||
"7": "#6c737f",
|
||||
"8": "#4d5761",
|
||||
"9": "#384250",
|
||||
"10": "#1f2a37",
|
||||
"11": "#111927"
|
||||
},
|
||||
"gray-iron": {
|
||||
"1": "#fcfcfc",
|
||||
"2": "#fafafa",
|
||||
"3": "#f4f4f5",
|
||||
"4": "#e4e4e7",
|
||||
"5": "#d1d1d6",
|
||||
"6": "#d1d1d6",
|
||||
"7": "#70707b",
|
||||
"8": "#51525c",
|
||||
"9": "#3f3f46",
|
||||
"10": "#26272b",
|
||||
"11": "#18181b"
|
||||
},
|
||||
"gray-true": {
|
||||
"1": "#fcfcfc",
|
||||
"2": "#fafafa",
|
||||
"3": "#f5f5f5",
|
||||
"4": "#e5e5e5",
|
||||
"5": "#d6d6d6",
|
||||
"6": "#a3a3a3",
|
||||
"7": "#737373",
|
||||
"8": "#525252",
|
||||
"9": "#424242",
|
||||
"10": "#292929",
|
||||
"11": "#141414"
|
||||
},
|
||||
"gray-warm": {
|
||||
"1": "#fdfdfc",
|
||||
"2": "#fafaf9",
|
||||
"3": "#f5f5f4",
|
||||
"4": "#e7e5e4",
|
||||
"5": "#d7d3d0",
|
||||
"6": "#d7d3d0",
|
||||
"7": "#79716b",
|
||||
"8": "#57534e",
|
||||
"9": "#44403c",
|
||||
"10": "#292524",
|
||||
"11": "#1c1917"
|
||||
},
|
||||
"moss": {
|
||||
"1": "#fafdf7",
|
||||
"2": "#f5fbee",
|
||||
"3": "#e6f4d7",
|
||||
"4": "#ceeab0",
|
||||
"5": "#acdc79",
|
||||
"6": "#86cb3c",
|
||||
"7": "#669f2a",
|
||||
"8": "#4f7a21",
|
||||
"9": "#3f621a",
|
||||
"10": "#335015",
|
||||
"11": "#2b4212"
|
||||
},
|
||||
"green-light": {
|
||||
"1": "#fafef5",
|
||||
"2": "#f3fee7",
|
||||
"3": "#e4fbcc",
|
||||
"4": "#d0f8ab",
|
||||
"5": "#a6ef67",
|
||||
"6": "#85e13a",
|
||||
"7": "#66c61c",
|
||||
"8": "#4ca30d",
|
||||
"9": "#3b7c0f",
|
||||
"10": "#326212",
|
||||
"11": "#2b5314"
|
||||
},
|
||||
"green": {
|
||||
"1": "#f6fef9",
|
||||
"2": "#edfcf2",
|
||||
"3": "#d3f8df",
|
||||
"4": "#aaf0c4",
|
||||
"5": "#73e2a3",
|
||||
"6": "#73e2a3",
|
||||
"7": "#16b364",
|
||||
"8": "#099250",
|
||||
"9": "#087443",
|
||||
"10": "#095c37",
|
||||
"11": "#084c2e"
|
||||
},
|
||||
"teal": {
|
||||
"1": "#f6fefc",
|
||||
"2": "#f0fdf9",
|
||||
"3": "#ccfbef",
|
||||
"4": "#99f6e0",
|
||||
"5": "#5fe9d0",
|
||||
"6": "#2ed3b7",
|
||||
"7": "#15b79e",
|
||||
"8": "#0e9384",
|
||||
"9": "#107569",
|
||||
"10": "#125d56",
|
||||
"11": "#134e48"
|
||||
},
|
||||
"cyan": {
|
||||
"1": "#f5feff",
|
||||
"2": "#ecfdff",
|
||||
"3": "#cff9fe",
|
||||
"4": "#a5f0fc",
|
||||
"5": "#67e3f9",
|
||||
"6": "#22ccee",
|
||||
"7": "#06aed4",
|
||||
"8": "#088ab2",
|
||||
"9": "#0e7090",
|
||||
"10": "#155b75",
|
||||
"11": "#164c63"
|
||||
},
|
||||
"blue-dark": {
|
||||
"1": "#f5f8ff",
|
||||
"2": "#eff4ff",
|
||||
"3": "#d1e0ff",
|
||||
"4": "#b2ccff",
|
||||
"5": "#84adff",
|
||||
"6": "#528bff",
|
||||
"7": "#2970ff",
|
||||
"8": "#155eef",
|
||||
"9": "#004eeb",
|
||||
"10": "#0040c1",
|
||||
"11": "#00359e"
|
||||
},
|
||||
"indigo": {
|
||||
"1": "#f5f8ff",
|
||||
"2": "#eef4ff",
|
||||
"3": "#e0eaff",
|
||||
"4": "#c7d7fe",
|
||||
"5": "#a4bcfd",
|
||||
"6": "#8098f9",
|
||||
"7": "#8098f9",
|
||||
"8": "#444ce7",
|
||||
"9": "#3538cd",
|
||||
"10": "#2d31a6",
|
||||
"11": "#2d3282"
|
||||
},
|
||||
"violet": {
|
||||
"1": "#fbfaff",
|
||||
"2": "#f5f3ff",
|
||||
"3": "#ece9fe",
|
||||
"4": "#ddd6fe",
|
||||
"5": "#c3b5fd",
|
||||
"6": "#a48afb",
|
||||
"7": "#875bf7",
|
||||
"8": "#7839ee",
|
||||
"9": "#6927da",
|
||||
"10": "#5720b7",
|
||||
"11": "#491c96"
|
||||
},
|
||||
"purple": {
|
||||
"1": "#fafaff",
|
||||
"2": "#f4f3ff",
|
||||
"3": "#ebe9fe",
|
||||
"4": "#d9d6fe",
|
||||
"5": "#bdb4fe",
|
||||
"6": "#9b8afb",
|
||||
"7": "#7a5af8",
|
||||
"8": "#6938ef",
|
||||
"9": "#5925dc",
|
||||
"10": "#4a1fb8",
|
||||
"11": "#3e1c96"
|
||||
},
|
||||
"fuchsia": {
|
||||
"1": "#fefaff",
|
||||
"2": "#fdf4ff",
|
||||
"3": "#fbe8ff",
|
||||
"4": "#f6d0fe",
|
||||
"5": "#eeaafd",
|
||||
"6": "#e478fa",
|
||||
"7": "#d444f1",
|
||||
"8": "#ba24d5",
|
||||
"9": "#9f1ab1",
|
||||
"10": "#821890",
|
||||
"11": "#6f1877"
|
||||
},
|
||||
"pink": {
|
||||
"1": "#fef6fb",
|
||||
"2": "#fdf2fa",
|
||||
"3": "#fce7f6",
|
||||
"4": "#fce7f6",
|
||||
"5": "#faa7e0",
|
||||
"6": "#f670c7",
|
||||
"7": "#ee46bc",
|
||||
"8": "#dd2590",
|
||||
"9": "#c11574",
|
||||
"10": "#9e165f",
|
||||
"11": "#851651"
|
||||
},
|
||||
"rose": {
|
||||
"1": "#fff5f6",
|
||||
"2": "#fff1f3",
|
||||
"3": "#ffe4e8",
|
||||
"4": "#fecdd6",
|
||||
"5": "#fea3b4",
|
||||
"6": "#fd6f8e",
|
||||
"7": "#f63d68",
|
||||
"8": "#e31b54",
|
||||
"9": "#c01048",
|
||||
"10": "#a11043",
|
||||
"11": "#89123e"
|
||||
},
|
||||
"orange-dark": {
|
||||
"1": "#fff9f5",
|
||||
"2": "#fff4ed",
|
||||
"3": "#ffe6d5",
|
||||
"4": "#ffd6ae",
|
||||
"5": "#ff9c66",
|
||||
"6": "#ff692e",
|
||||
"7": "#ff4405",
|
||||
"8": "#e62e05",
|
||||
"9": "#bc1b06",
|
||||
"10": "#97180c",
|
||||
"11": "#771a0d"
|
||||
},
|
||||
"orange": {
|
||||
"1": "#fefaf5",
|
||||
"2": "#fef6ee",
|
||||
"3": "#fdead7",
|
||||
"4": "#f9dbaf",
|
||||
"5": "#f7b27a",
|
||||
"6": "#f38744",
|
||||
"7": "#ef6820",
|
||||
"8": "#e04f16",
|
||||
"9": "#b93815",
|
||||
"10": "#932f19",
|
||||
"11": "#772917"
|
||||
},
|
||||
"yellow": {
|
||||
"1": "#fefdf0",
|
||||
"2": "#fefbe8",
|
||||
"3": "#fef7c3",
|
||||
"4": "#feee95",
|
||||
"5": "#feee95",
|
||||
"6": "#fac515",
|
||||
"7": "#eaaa08",
|
||||
"8": "#ca8504",
|
||||
"9": "#a15c07",
|
||||
"10": "#854a0e",
|
||||
"11": "#713b12"
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import colors from './colors.json';
|
||||
|
||||
const element = document.createElement('style');
|
||||
|
||||
element.innerHTML = `:root {
|
||||
${Object.entries(colors)
|
||||
.map(([color, hex]) => {
|
||||
if (typeof hex === 'string') {
|
||||
return `--ui-${color}: ${hex}`;
|
||||
}
|
||||
|
||||
return Object.entries(hex)
|
||||
.map(([key, value]) => `--ui-${color}-${key}: ${value}`)
|
||||
.join(';\n');
|
||||
})
|
||||
.join(';\n')}
|
||||
}`;
|
||||
|
||||
document.head.prepend(element);
|
||||
@@ -15,12 +15,9 @@ import 'angular-multiselect/isteven-multi-select.css';
|
||||
import 'spinkit/spinkit.min.css';
|
||||
import '@reach/menu-button/styles.css';
|
||||
|
||||
import './colors';
|
||||
|
||||
import './rdash.css';
|
||||
import './app.css';
|
||||
|
||||
import './theme.css';
|
||||
import './vendor-override.css';
|
||||
import '../fonts/nomad-icon.css';
|
||||
import './bootstrap-override.css';
|
||||
|
||||
@@ -4,6 +4,49 @@
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
@media only screen and (min-width: 561px) {
|
||||
#page-wrapper.open {
|
||||
padding-left: 250px;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 560px) {
|
||||
#page-wrapper.open {
|
||||
padding-left: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hamburg Menu
|
||||
* When the class of 'hamburg' is applied to the body tag of the document,
|
||||
* the sidebar changes it's style to attempt to mimic a menu on a phone app,
|
||||
* where the content is overlaying the content, rather than push it.
|
||||
*/
|
||||
@media only screen and (max-width: 560px) {
|
||||
body.hamburg #page-wrapper {
|
||||
padding-left: 0;
|
||||
}
|
||||
body.hamburg #page-wrapper:not(.open) #sidebar-wrapper {
|
||||
position: absolute;
|
||||
left: -100px;
|
||||
}
|
||||
body.hamburg #page-wrapper:not(.open) ul.sidebar .sidebar-title.separator {
|
||||
display: none;
|
||||
}
|
||||
body.hamburg #page-wrapper.open #sidebar-wrapper {
|
||||
position: fixed;
|
||||
}
|
||||
body.hamburg #page-wrapper.open #sidebar-wrapper ul.sidebar li.sidebar-main {
|
||||
margin-left: 0px;
|
||||
}
|
||||
body.hamburg #sidebar-wrapper ul.sidebar li.sidebar-main,
|
||||
body.hamburg .row.header .meta {
|
||||
margin-left: 70px;
|
||||
}
|
||||
body.hamburg #sidebar-wrapper ul.sidebar li.sidebar-main,
|
||||
body.hamburg #page-wrapper.open #sidebar-wrapper ul.sidebar li.sidebar-main {
|
||||
transition: margin-left 0.4s ease 0s;
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
width: 40px;
|
||||
@@ -49,6 +92,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Fonts */
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('../fonts/montserrat-regular-webfont.eot');
|
||||
src: url('../fonts/montserrat-regular-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/montserrat-regular-webfont.woff') format('woff'),
|
||||
url('../fonts/montserrat-regular-webfont.ttf') format('truetype'), url('../fonts/montserrat-regular-webfont.svg#montserratregular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('../fonts/montserrat-regular-webfont.svg') format('svg');
|
||||
}
|
||||
select {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
}
|
||||
/* Base */
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
body {
|
||||
background: var(--bg-body-color);
|
||||
font-family: 'Montserrat';
|
||||
color: var(--text-body-color) !important;
|
||||
}
|
||||
.row {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
@@ -59,7 +129,22 @@
|
||||
.alerts-container .alert:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#page-wrapper {
|
||||
padding-left: 70px;
|
||||
height: 100%;
|
||||
}
|
||||
#sidebar-wrapper {
|
||||
margin-left: -150px;
|
||||
left: -30px;
|
||||
width: 250px;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
z-index: 999;
|
||||
}
|
||||
#page-wrapper,
|
||||
#sidebar-wrapper {
|
||||
transition: all 0.4s ease 0s;
|
||||
}
|
||||
.green {
|
||||
background: #23ae89 !important;
|
||||
}
|
||||
@@ -87,8 +172,9 @@ div.input-mask {
|
||||
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||
background: var(--bg-widget-color);
|
||||
border: 1px solid var(--border-widget);
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
border-color: var(--border-widget-color);
|
||||
}
|
||||
.widget .widget-header .pagination,
|
||||
.widget .widget-footer .pagination {
|
||||
@@ -96,7 +182,9 @@ div.input-mask {
|
||||
}
|
||||
.widget .widget-header {
|
||||
color: var(--text-widget-header-color);
|
||||
background-color: var(--bg-widget-header-color);
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid var(--border-widget-color);
|
||||
line-height: 30px;
|
||||
}
|
||||
.widget .widget-header i {
|
||||
@@ -104,7 +192,6 @@ div.input-mask {
|
||||
}
|
||||
.widget .widget-body {
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.widget .widget-body table thead {
|
||||
background: var(--bg-widget-table-color);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/* Color Variable */
|
||||
:root {
|
||||
--black-color: var(--ui-black);
|
||||
--white-color: var(--ui-white);
|
||||
html {
|
||||
--black-color: #000;
|
||||
--white-color: #fff;
|
||||
|
||||
--grey-1: #212121;
|
||||
--grey-2: #181818;
|
||||
--grey-3: #383838;
|
||||
--grey-4: #585858;
|
||||
--grey-5: #323c48;
|
||||
--grey-6: #333333;
|
||||
--grey-7: #767676;
|
||||
--grey-8: #aaa;
|
||||
@@ -34,6 +35,7 @@
|
||||
--grey-30: #444;
|
||||
--grey-31: #868686;
|
||||
--grey-32: #65798e;
|
||||
--grey-34: #314252;
|
||||
--grey-35: #546477;
|
||||
--grey-36: #55637d;
|
||||
--grey-37: #2d3e63;
|
||||
@@ -51,12 +53,15 @@
|
||||
--grey-49: rgba(0, 0, 0, 0.54);
|
||||
--grey-50: rgba(161, 170, 166, 0.5);
|
||||
--grey-51: rgba(0, 0, 0, 0.15);
|
||||
--grey-52: rgba(255, 255, 255, 0.3);
|
||||
--grey-53: rgba(255, 255, 255, 0.6);
|
||||
--grey-54: rgb(54, 54, 54);
|
||||
--grey-55: rgba(255, 255, 255, 0.8);
|
||||
--grey-56: #b2bfdc;
|
||||
--grey-57: #999;
|
||||
--grey-58: #ebf4f8;
|
||||
--grey-59: #e6e6e6;
|
||||
--grey-60: #cacaca;
|
||||
--grey-61: rgb(231, 231, 231);
|
||||
|
||||
--blue-1: #219;
|
||||
@@ -71,6 +76,7 @@
|
||||
--blue-10: #61b6ff;
|
||||
--blue-11: #3ea5ff;
|
||||
--blue-12: #41a6ff;
|
||||
--blue-13: #2361ae;
|
||||
--blue-14: #357ebd;
|
||||
|
||||
--red-1: #a94442;
|
||||
@@ -78,6 +84,7 @@
|
||||
--red-3: #a11;
|
||||
--red-4: #d9534f;
|
||||
--red-5: #ff2727;
|
||||
--red-6: #ff00e0;
|
||||
--red-7: #f00;
|
||||
|
||||
--green-1: #164;
|
||||
@@ -87,22 +94,25 @@
|
||||
--orange-1: #e86925;
|
||||
|
||||
--BE-only: var(--orange-1);
|
||||
}
|
||||
|
||||
/* Default Theme */
|
||||
--bg-card-color: var(--white-color);
|
||||
/* Default Theme */
|
||||
:root {
|
||||
--bg-card-color: var(--grey-10);
|
||||
--bg-main-color: var(--white-color);
|
||||
--bg-body-color: var(--grey-9);
|
||||
--bg-checkbox-border-color: var(--grey-49);
|
||||
--bg-sidebar-color: var(--grey-37);
|
||||
--bg-sidebar-header-color: var(--grey-37);
|
||||
--bg-widget-color: var(--white-color);
|
||||
--bg-widget-header-color: var(--grey-10);
|
||||
--bg-widget-table-color: var(--grey-13);
|
||||
--bg-header-color: var(--white-color);
|
||||
--bg-hover-table-color: var(--grey-14);
|
||||
--bg-switch-box-color: var(--ui-gray-5);
|
||||
--bg-input-group-addon-color: var(--ui-gray-3);
|
||||
--bg-switch-box-color: var(--white-color);
|
||||
--bg-input-group-addon-color: var(--grey-11);
|
||||
--bg-btn-default-color: var(--white-color);
|
||||
--bg-blocklist-hover-color: var(--ui-blue-3);
|
||||
--bg-blocklist-hover-color: var(--grey-12);
|
||||
--bg-boxselector-color: var(--white-color);
|
||||
--bg-table-color: var(--white-color);
|
||||
--bg-md-checkbox-color: var(--grey-12);
|
||||
@@ -129,16 +139,10 @@
|
||||
--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-sidebar-wrapper-color: var(--blue-5);
|
||||
--bg-panel-body-color: var(--white-color);
|
||||
--bg-codemirror-color: var(--white-color);
|
||||
--bg-codemirror-selected-color: var(--grey-22);
|
||||
--bg-tooltip-color: var(--ui-gray-11);
|
||||
--bg-input-sm-color: var(--white-color);
|
||||
--bg-service-datatable-thead: var(--grey-23);
|
||||
--bg-app-datatable-thead: var(--grey-23);
|
||||
--bg-inner-datatable-thead: var(--grey-23);
|
||||
--bg-service-datatable-tbody: var(--grey-24);
|
||||
--bg-app-datatable-tbody: var(--grey-24);
|
||||
--bg-multiselect-color: var(--white-color);
|
||||
--bg-daterangepicker-color: var(--white-color);
|
||||
--bg-calendar-color: var(--white-color);
|
||||
@@ -158,10 +162,6 @@
|
||||
--bg-stepper-item-active: var(--white-color);
|
||||
--bg-stepper-item-counter: var(--grey-61);
|
||||
--bg-sortbutton-color: var(--white-color);
|
||||
--bg-dashboard-item: var(--ui-blue-3);
|
||||
--bg-searchbar: var(--ui-gray-2);
|
||||
--bg-inputbox: var(--ui-gray-2);
|
||||
--bg-dropdown-hover: var(--ui-gray-3);
|
||||
|
||||
--text-main-color: var(--grey-7);
|
||||
--text-body-color: var(--grey-6);
|
||||
@@ -193,21 +193,23 @@
|
||||
--text-blocklist-item-selected-color: var(--grey-37);
|
||||
--text-progress-bar-color: var(--grey-27);
|
||||
--text-pagination-color: var(--grey-26);
|
||||
--text-pagination-span-color: var(--ui-gray-3);
|
||||
--text-pagination-span-color: var(--blue-2);
|
||||
--text-pagination-span-hover-color: var(--blue-4);
|
||||
--text-ui-select-color: var(--grey-6);
|
||||
--text-ui-select-hover-color: var(--grey-28);
|
||||
--text-summary-color: var(--black-color);
|
||||
--text-tooltip-color: var(--white-color);
|
||||
--text-multiselect-button-color: var(--grey-29);
|
||||
--text-multiselect-item-color: var(--grey-30);
|
||||
--text-sidebar-list-color: var(--grey-56);
|
||||
--text-rzslider-color: var(--grey-36);
|
||||
--text-rzslider-limit-color: var(--grey-36);
|
||||
--text-daterangepicker-end-date: var(--grey-57);
|
||||
--text-daterangepicker-in-range: var(--black-color);
|
||||
--text-daterangepicker-active: var(--white-color);
|
||||
--text-tooltip-color: var(--grey-6);
|
||||
--text-input-autofill-color: var(--black-color);
|
||||
--text-button-hover-color: var(--grey-6);
|
||||
--text-small-select-color: var(--grey-25);
|
||||
--text-bootbox: var(--ui-gray-7);
|
||||
|
||||
--border-color: var(--grey-42);
|
||||
--border-widget-color: var(--grey-43);
|
||||
@@ -242,10 +244,8 @@
|
||||
--border-tooltip-color: var(--grey-47);
|
||||
--border-modal: 0px;
|
||||
--border-sortbutton: var(--grey-8);
|
||||
--border-bootbox: var(--ui-gray-5);
|
||||
--border-blocklist: var(--ui-gray-5);
|
||||
--border-widget: var(--ui-gray-5);
|
||||
|
||||
--hover-sidebar-color: var(--grey-37);
|
||||
--shadow-box-color: 0 3px 10px -2px var(--grey-50);
|
||||
--shadow-boxselector-color: 0 3px 10px -2px var(--grey-50);
|
||||
--blue-color: var(--blue-13);
|
||||
@@ -265,13 +265,9 @@
|
||||
--text-multiselect-item: var(--grey-30);
|
||||
--bg-multiselect-helpercontainer: var(--white-color);
|
||||
--text-input-textarea: var(--white-color);
|
||||
|
||||
--border-checkbox: var(--ui-gray-5);
|
||||
--bg-checkbox: var(--white-color);
|
||||
--border-searchbar: var(--ui-gray-5);
|
||||
--bg-button-group: var(--white-color);
|
||||
--border-button-group: var(--ui-gray-5);
|
||||
--text-button-group: var(--ui-gray-9);
|
||||
--bg-service-datatable-thead: var(--grey-23);
|
||||
--bg-inner-datatable-thead: var(--grey-23);
|
||||
--bg-service-datatable-tbody: var(--grey-24);
|
||||
}
|
||||
|
||||
:root[theme='dark'] {
|
||||
@@ -279,6 +275,7 @@
|
||||
--bg-main-color: var(--grey-2);
|
||||
--bg-body-color: var(--grey-2);
|
||||
--bg-checkbox-border-color: var(--grey-8);
|
||||
--bg-sidebar-color: var(--grey-3);
|
||||
--bg-widget-color: var(--grey-1);
|
||||
--bg-widget-header-color: var(--grey-1);
|
||||
--bg-widget-table-color: var(--grey-1);
|
||||
@@ -316,6 +313,7 @@
|
||||
--bg-multiselect-button-color: var(--grey-3);
|
||||
--bg-image-multiselect-button: none !important;
|
||||
--bg-multiselect-checkbox-color: var(--grey-3);
|
||||
--bg-sidebar-wrapper-color: var(--grey-1);
|
||||
--bg-panel-body-color: var(--grey-1);
|
||||
--bg-boxselector-wrapper-disabled-color: var(--grey-39);
|
||||
--bg-codemirror-selected-color: var(--grey-3);
|
||||
@@ -339,10 +337,6 @@
|
||||
--bg-stepper-item-active: var(--grey-1);
|
||||
--bg-stepper-item-counter: var(--grey-7);
|
||||
--bg-sortbutton-color: var(--grey-1);
|
||||
--bg-dashboard-item: var(--grey-3);
|
||||
--bg-searchbar: var(--grey-1);
|
||||
--bg-inputbox: var(--grey-2);
|
||||
--bg-dropdown-hover: var(--grey-3);
|
||||
|
||||
--text-main-color: var(--white-color);
|
||||
--text-body-color: var(--white-color);
|
||||
@@ -374,13 +368,14 @@
|
||||
--text-blocklist-item-selected-color: var(--white-color);
|
||||
--text-progress-bar-color: var(--white-color);
|
||||
--text-pagination-color: var(--white-color);
|
||||
--text-pagination-span-color: var(--ui-gray-3);
|
||||
--text-pagination-span-color: var(--blue-2);
|
||||
--text-pagination-span-hover-color: var(--white-color);
|
||||
--text-ui-select-color: var(--white-color);
|
||||
--text-ui-select-hover-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-sidebar-list-color: var(--white-color);
|
||||
--text-boxselector-wrapper-color: var(--white-color);
|
||||
--text-daterangepicker-end-date: var(--grey-7);
|
||||
--text-daterangepicker-in-range: var(--white-color);
|
||||
@@ -390,7 +385,6 @@
|
||||
--text-input-autofill-color: var(--grey-8);
|
||||
--text-button-hover-color: var(--white-color);
|
||||
--text-small-select-color: var(--grey-7);
|
||||
--text-bootbox: var(--white-color);
|
||||
|
||||
--border-color: var(--grey-3);
|
||||
--border-widget-color: var(--grey-1);
|
||||
@@ -414,7 +408,9 @@
|
||||
--border-pagination-color: var(--grey-3);
|
||||
--border-pagination-span-color: var(--grey-3);
|
||||
--border-pagination-hover-color: var(--grey-3);
|
||||
--border-boxselector-wrapper-hover: 3px solid var(--blue-8);
|
||||
--border-pagination-hover-color: var(--grey-3);
|
||||
--border-multiselect-button-color: var(--grey-3);
|
||||
--border-searchbar-color: var(--grey-1);
|
||||
--border-panel-color: var(--grey-2);
|
||||
--border-daterangepicker-color: var(--grey-3);
|
||||
--border-calendar-table: var(--grey-3);
|
||||
@@ -424,10 +420,8 @@
|
||||
--border-tooltip-color: var(--grey-3);
|
||||
--border-modal: 0px;
|
||||
--border-sortbutton: var(--grey-3);
|
||||
--border-bootbox: var(--ui-gray-9);
|
||||
--border-blocklist: var(--ui-gray-9);
|
||||
--border-widget: var(--ui-gray-9);
|
||||
|
||||
--hover-sidebar-color: var(--grey-3);
|
||||
--blue-color: var(--blue-2);
|
||||
--button-close-color: var(--white-color);
|
||||
--button-opacity: 0.6;
|
||||
@@ -445,13 +439,9 @@
|
||||
--text-multiselect-item: var(--white-color);
|
||||
--bg-multiselect-helpercontainer: var(--grey-1);
|
||||
--text-input-textarea: var(--grey-1);
|
||||
|
||||
--border-checkbox: var(--ui-gray-5);
|
||||
--bg-checkbox: var(--white-color);
|
||||
--border-searchbar: var(--ui-gray-5);
|
||||
--bg-button-group: var(--white-color);
|
||||
--border-button-group: var(--ui-gray-5);
|
||||
--text-button-group: var(--ui-gray-9);
|
||||
--bg-service-datatable-thead: var(--grey-1);
|
||||
--bg-inner-datatable-thead: var(--grey-1);
|
||||
--bg-service-datatable-tbody: var(--grey-1);
|
||||
}
|
||||
|
||||
:root[theme='highcontrast'] {
|
||||
@@ -459,6 +449,7 @@
|
||||
--bg-main-color: var(--black-color);
|
||||
--bg-body-color: var(--black-color);
|
||||
--bg-checkbox-border-color: var(--grey-8);
|
||||
--bg-sidebar-color: var(--black-color);
|
||||
--bg-widget-color: var(--black-color);
|
||||
--bg-widget-header-color: var(--black-color);
|
||||
--bg-widget-table-color: var(--black-color);
|
||||
@@ -470,10 +461,11 @@
|
||||
--bg-dropdown-menu-color: var(--black-color);
|
||||
--bg-codemirror-selected-color: var(--grey-3);
|
||||
--bg-row-header-color: var(--black-color);
|
||||
--bg-sidebar-wrapper-color: var(--black-color);
|
||||
--bg-motd-body-color: var(--black-color);
|
||||
--bg-blocklist-hover-color: var(--black-color);
|
||||
--bg-blocklist-item-selected-color: var(--black-color);
|
||||
--bg-input-group-addon-color: var(--grey-3);
|
||||
--bg-input-group-addon-color: var(--grey-1);
|
||||
--bg-table-color: var(--black-color);
|
||||
--bg-codemirror-gutters-color: var(--black-color);
|
||||
--bg-codemirror-color: var(--black-color);
|
||||
@@ -520,9 +512,6 @@
|
||||
--bg-stepper-item-active: var(--black-color);
|
||||
--bg-stepper-item-counter: var(--grey-3);
|
||||
--bg-sortbutton-color: var(--grey-1);
|
||||
--bg-inputbox: var(--black-color);
|
||||
--bg-searchbar: var(--black-color);
|
||||
--bg-dropdown-hover: var(--black-color);
|
||||
|
||||
--text-main-color: var(--white-color);
|
||||
--text-body-color: var(--white-color);
|
||||
@@ -551,6 +540,7 @@
|
||||
--text-daterangepicker-end-date: var(--grey-7);
|
||||
--text-daterangepicker-in-range: var(--white-color);
|
||||
--text-daterangepicker-active: var(--white-color);
|
||||
--text-sidebar-list-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);
|
||||
@@ -564,8 +554,7 @@
|
||||
--text-btn-default-color: var(--white-color);
|
||||
--text-small-select-color: var(--white-color);
|
||||
--text-multiselect-item-color: var(--white-color);
|
||||
--text-pagination-span-color: var(--ui-gray-3);
|
||||
--text-bootbox: var(--white-color);
|
||||
--text-pagination-span-color: var(--blue-2);
|
||||
|
||||
--border-color: var(--grey-55);
|
||||
--border-widget-color: var(--white-color);
|
||||
@@ -595,10 +584,9 @@
|
||||
--border-modal: 1px solid var(--white-color);
|
||||
--border-blocklist-color: var(--white-color);
|
||||
--border-sortbutton: var(--black-color);
|
||||
--border-bootbox: var(--black-color);
|
||||
--border-blocklist: var(--white-color);
|
||||
--border-widget: var(--white-color);
|
||||
|
||||
--hover-sidebar-color: var(--blue-9);
|
||||
--hover-sidebar-color: var(--black-color);
|
||||
--shadow-box-color: none;
|
||||
--shadow-boxselector-color: none;
|
||||
|
||||
@@ -617,11 +605,4 @@
|
||||
--text-cm-meta-color: var(--white-color);
|
||||
--text-cm-string-color: var(--red-7);
|
||||
--text-progress-bar-color: var(--black-color);
|
||||
|
||||
--border-checkbox: var(--ui-gray-5);
|
||||
--bg-checkbox: var(--white-color);
|
||||
--border-searchbar: var(--ui-gray-5);
|
||||
--bg-button-group: var(--white-color);
|
||||
--border-button-group: var(--ui-gray-5);
|
||||
--text-button-group: var(--ui-gray-9);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Overide Vendor CSS */
|
||||
.form-control {
|
||||
background-color: var(--bg-main-color) !important;
|
||||
border: 1px solid var(--border-form-control-color);
|
||||
background-color: var(--bg-inputbox);
|
||||
color: var(--text-form-control-color);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
}
|
||||
|
||||
.table > thead > tr > th {
|
||||
border-bottom: 1px solid var(--border-table-color);
|
||||
border-bottom: 2px solid var(--border-table-color);
|
||||
}
|
||||
|
||||
.table-hover > tbody > tr:hover {
|
||||
@@ -243,10 +243,6 @@ json-tree .branch-preview {
|
||||
.panel {
|
||||
border: 1px solid var(--border-panel-color);
|
||||
background-color: var(--bg-panel-body-color);
|
||||
border-radius: 8px;
|
||||
-webkit-box-shadow: 0 4px 4px rgba(0, 0, 0, 0.05);
|
||||
-moz-box-shadow: 0 4px 4px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 4px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.theme-information .col-sm-12 {
|
||||
@@ -385,10 +381,3 @@ fieldset[disabled] .btn {
|
||||
.multiSelect.inlineBlock button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-tabs > li.active > a {
|
||||
border-top: 0px;
|
||||
border-left: 0px;
|
||||
border-right: 0px;
|
||||
border-bottom: 3px solid red;
|
||||
}
|
||||
|
||||
Binary file not shown.
BIN
app/assets/fonts/montserrat-regular-webfont.eot
Normal file
BIN
app/assets/fonts/montserrat-regular-webfont.eot
Normal file
Binary file not shown.
1317
app/assets/fonts/montserrat-regular-webfont.svg
Normal file
1317
app/assets/fonts/montserrat-regular-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 86 KiB |
BIN
app/assets/fonts/montserrat-regular-webfont.ttf
Normal file
BIN
app/assets/fonts/montserrat-regular-webfont.ttf
Normal file
Binary file not shown.
BIN
app/assets/fonts/montserrat-regular-webfont.woff
Normal file
BIN
app/assets/fonts/montserrat-regular-webfont.woff
Normal file
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="3" width="40" height="40" rx="20" fill="#FEE4E2"/>
|
||||
<path d="M23 19.6667V23M23 26.3333H23.0083M31.3333 23C31.3333 27.6024 27.6024 31.3333 23 31.3333C18.3976 31.3333 14.6667 27.6024 14.6667 23C14.6667 18.3976 18.3976 14.6667 23 14.6667C27.6024 14.6667 31.3333 18.3976 31.3333 23Z" stroke="#D92D20" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="3" y="3" width="40" height="40" rx="20" stroke="#FEF3F2" stroke-width="6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 571 B |
@@ -1,5 +0,0 @@
|
||||
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="3" width="40" height="40" rx="20" fill="#D1FADF"/>
|
||||
<path d="M31.3333 22.2333V23C31.3323 24.797 30.7504 26.5456 29.6744 27.9849C28.5985 29.4241 27.0861 30.4771 25.3628 30.9866C23.6395 31.4961 21.7977 31.4349 20.112 30.8122C18.4264 30.1894 16.9872 29.0384 16.0091 27.5309C15.031 26.0234 14.5665 24.2401 14.6847 22.4469C14.803 20.6538 15.4977 18.9469 16.6652 17.5809C17.8328 16.2148 19.4106 15.2628 21.1635 14.8668C22.9163 14.4708 24.7502 14.6519 26.3917 15.3833M31.3333 16.3333L23 24.675L20.5 22.175" stroke="#039855" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="3" y="3" width="40" height="40" rx="20" stroke="#ECFDF3" stroke-width="6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 791 B |
@@ -1,5 +0,0 @@
|
||||
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="3" width="40" height="40" rx="20" fill="#FEF0C7"/>
|
||||
<path d="M22.9998 19.6667V23M22.9998 26.3333H23.0081M21.5748 15.3833L14.5165 27.1667C14.3709 27.4187 14.2939 27.7044 14.2931 27.9954C14.2923 28.2864 14.3677 28.5726 14.5118 28.8254C14.6559 29.0783 14.8637 29.2889 15.1146 29.4365C15.3654 29.5841 15.6505 29.6635 15.9415 29.6667H30.0581C30.3491 29.6635 30.6342 29.5841 30.885 29.4365C31.1359 29.2889 31.3437 29.0783 31.4878 28.8254C31.6319 28.5726 31.7073 28.2864 31.7065 27.9954C31.7057 27.7044 31.6287 27.4187 31.4831 27.1667L24.4248 15.3833C24.2762 15.1384 24.0671 14.9359 23.8175 14.7954C23.5679 14.6549 23.2863 14.581 22.9998 14.581C22.7134 14.581 22.4317 14.6549 22.1821 14.7954C21.9325 14.9359 21.7234 15.1384 21.5748 15.3833Z" stroke="#DC6803" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="3" y="3" width="40" height="40" rx="20" stroke="#FFFAEB" stroke-width="6"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1,9 +1,5 @@
|
||||
import { UserContext } from '@/portainer/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { render, within } from '@/react-tools/test-utils';
|
||||
|
||||
import { TestSidebarProvider } from '../useSidebarState';
|
||||
|
||||
import { AzureSidebar } from './AzureSidebar';
|
||||
|
||||
test('dashboard items should render correctly', () => {
|
||||
@@ -13,28 +9,26 @@ test('dashboard items should render correctly', () => {
|
||||
expect(dashboardItem).toHaveTextContent('Dashboard');
|
||||
|
||||
const dashboardItemElements = within(dashboardItem);
|
||||
expect(
|
||||
dashboardItemElements.getByRole('img', { hidden: true })
|
||||
).toBeVisible();
|
||||
expect(dashboardItemElements.getByLabelText('itemIcon')).toBeVisible();
|
||||
expect(dashboardItemElements.getByLabelText('itemIcon')).toHaveClass(
|
||||
'fa-tachometer-alt',
|
||||
'fa-fw'
|
||||
);
|
||||
|
||||
const containerInstancesItem = getByLabelText(/Container Instances/i);
|
||||
const containerInstancesItem = getByLabelText('ContainerInstances');
|
||||
expect(containerInstancesItem).toBeVisible();
|
||||
expect(containerInstancesItem).toHaveTextContent('Container instances');
|
||||
|
||||
const containerInstancesItemElements = within(containerInstancesItem);
|
||||
expect(
|
||||
containerInstancesItemElements.getByRole('img', { hidden: true })
|
||||
containerInstancesItemElements.getByLabelText('itemIcon')
|
||||
).toBeVisible();
|
||||
expect(containerInstancesItemElements.getByLabelText('itemIcon')).toHaveClass(
|
||||
'fa-cubes',
|
||||
'fa-fw'
|
||||
);
|
||||
});
|
||||
|
||||
function renderComponent() {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
|
||||
return render(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<TestSidebarProvider>
|
||||
<AzureSidebar environmentId={1} />
|
||||
</TestSidebarProvider>
|
||||
</UserContext.Provider>
|
||||
);
|
||||
return render(<AzureSidebar environmentId={1} />);
|
||||
}
|
||||
36
app/azure/AzureSidebar/AzureSidebar.tsx
Normal file
36
app/azure/AzureSidebar/AzureSidebar.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
import { SidebarMenuItem } from '@/portainer/components/sidebar/SidebarMenuItem';
|
||||
import type { EnvironmentId } from '@/portainer/environments/types';
|
||||
|
||||
interface Props {
|
||||
environmentId: EnvironmentId;
|
||||
}
|
||||
|
||||
export function AzureSidebar({ environmentId }: Props) {
|
||||
return (
|
||||
<>
|
||||
<SidebarMenuItem
|
||||
path="azure.dashboard"
|
||||
pathParams={{ endpointId: environmentId }}
|
||||
iconClass="fa-tachometer-alt fa-fw"
|
||||
className="sidebar-list"
|
||||
itemName="Dashboard"
|
||||
data-cy="azureSidebar-dashboard"
|
||||
>
|
||||
Dashboard
|
||||
</SidebarMenuItem>
|
||||
<SidebarMenuItem
|
||||
path="azure.containerinstances"
|
||||
pathParams={{ endpointId: environmentId }}
|
||||
iconClass="fa-cubes fa-fw"
|
||||
className="sidebar-list"
|
||||
itemName="ContainerInstances"
|
||||
data-cy="azureSidebar-containerInstances"
|
||||
>
|
||||
Container instances
|
||||
</SidebarMenuItem>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const AzureSidebarAngular = r2a(AzureSidebar, ['environmentId']);
|
||||
1
app/azure/AzureSidebar/index.ts
Normal file
1
app/azure/AzureSidebar/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { AzureSidebar, AzureSidebarAngular } from './AzureSidebar';
|
||||
@@ -1,17 +1,16 @@
|
||||
import { Field, Form, Formik } from 'formik';
|
||||
import { useCurrentStateAndParams, useRouter } from '@uirouter/react';
|
||||
|
||||
import { FormControl } from '@/portainer/components/form-components/FormControl';
|
||||
import { Input, Select } from '@/portainer/components/form-components/Input';
|
||||
import { FormSectionTitle } from '@/portainer/components/form-components/FormSectionTitle';
|
||||
import { LoadingButton } from '@/portainer/components/Button/LoadingButton';
|
||||
import { InputListError } from '@/portainer/components/form-components/InputList/InputList';
|
||||
import { ContainerInstanceFormValues } from '@/azure/types';
|
||||
import * as notifications from '@/portainer/services/notifications';
|
||||
import { useUser } from '@/portainer/hooks/useUser';
|
||||
import { AccessControlForm } from '@/portainer/access-control/AccessControlForm';
|
||||
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
import { Input, Select } from '@@/form-components/Input';
|
||||
import { FormSectionTitle } from '@@/form-components/FormSectionTitle';
|
||||
import { LoadingButton } from '@@/buttons/LoadingButton';
|
||||
import { InputListError } from '@@/form-components/InputList/InputList';
|
||||
|
||||
import { validationSchema } from './CreateContainerInstanceForm.validation';
|
||||
import { PortMapping, PortsMappingField } from './PortsMappingField';
|
||||
import { useLoadFormState } from './useLoadFormState';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ButtonSelector } from '@@/form-components/ButtonSelector/ButtonSelector';
|
||||
import { FormError } from '@@/form-components/FormError';
|
||||
import { InputGroup } from '@@/form-components/InputGroup';
|
||||
import { InputList } from '@@/form-components/InputList';
|
||||
import { ButtonSelector } from '@/portainer/components/form-components/ButtonSelector/ButtonSelector';
|
||||
import { FormError } from '@/portainer/components/form-components/FormError';
|
||||
import { InputGroup } from '@/portainer/components/form-components/InputGroup';
|
||||
import { InputList } from '@/portainer/components/form-components/InputList';
|
||||
import {
|
||||
InputListError,
|
||||
ItemProps,
|
||||
} from '@@/form-components/InputList/InputList';
|
||||
} from '@/portainer/components/form-components/InputList/InputList';
|
||||
|
||||
import styles from './PortsMappingField.module.css';
|
||||
|
||||
|
||||
@@ -4,14 +4,13 @@ import { useEffect } from 'react';
|
||||
import * as notifications from '@/portainer/services/notifications';
|
||||
import PortainerError from '@/portainer/error';
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
import { Option } from '@/portainer/components/form-components/Input/Select';
|
||||
import { getResourceGroups } from '@/azure/services/resource-groups.service';
|
||||
import { getSubscriptions } from '@/azure/services/subscription.service';
|
||||
import { getContainerInstanceProvider } from '@/azure/services/provider.service';
|
||||
import { ContainerInstanceFormValues, Subscription } from '@/azure/types';
|
||||
import { parseAccessControlFormData } from '@/portainer/access-control/utils';
|
||||
|
||||
import { Option } from '@@/form-components/Input/Select';
|
||||
|
||||
import {
|
||||
getSubscriptionLocations,
|
||||
getSubscriptionResourceGroups,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { PageHeader } from '@/portainer/components/PageHeader';
|
||||
import { Widget, WidgetBody } from '@/portainer/components/widget';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
import { Widget, WidgetBody } from '@@/Widget';
|
||||
|
||||
import { CreateContainerInstanceForm } from './CreateContainerInstanceForm';
|
||||
|
||||
export function CreateContainerInstanceView() {
|
||||
|
||||
@@ -24,9 +24,7 @@ test('dashboard items should render correctly', async () => {
|
||||
|
||||
const subscriptionElements = within(subscriptionsItem);
|
||||
expect(subscriptionElements.getByLabelText('value')).toBeVisible();
|
||||
expect(subscriptionElements.getByRole('img', { hidden: true })).toHaveClass(
|
||||
'fa-th-list'
|
||||
);
|
||||
expect(subscriptionElements.getByLabelText('icon')).toHaveClass('fa-th-list');
|
||||
expect(subscriptionElements.getByLabelText('resourceType')).toHaveTextContent(
|
||||
'Subscriptions'
|
||||
);
|
||||
@@ -36,7 +34,7 @@ test('dashboard items should render correctly', async () => {
|
||||
|
||||
const resourceGroupElements = within(resourceGroupsItem);
|
||||
expect(resourceGroupElements.getByLabelText('value')).toBeVisible();
|
||||
expect(resourceGroupElements.getByRole('img', { hidden: true })).toHaveClass(
|
||||
expect(resourceGroupElements.getByLabelText('icon')).toHaveClass(
|
||||
'fa-th-list'
|
||||
);
|
||||
expect(
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { useEnvironmentId } from '@/portainer/hooks/useEnvironmentId';
|
||||
import { PageHeader } from '@/portainer/components/PageHeader';
|
||||
import { DashboardItem } from '@/portainer/components/Dashboard/DashboardItem';
|
||||
import { error as notifyError } from '@/portainer/services/notifications';
|
||||
import PortainerError from '@/portainer/error';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
||||
import { DashboardItem } from '@@/DashboardItem';
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
|
||||
import { useResourceGroups, useSubscriptions } from '../queries';
|
||||
|
||||
export function DashboardView() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { AzureSidebarAngular } from './AzureSidebar/AzureSidebar';
|
||||
import { DashboardViewAngular } from './Dashboard/DashboardView';
|
||||
import { containerInstancesModule } from './ContainerInstances';
|
||||
import { reactModule } from './react';
|
||||
@@ -83,4 +84,5 @@ angular
|
||||
$stateRegistryProvider.register(dashboard);
|
||||
},
|
||||
])
|
||||
.component('azureSidebar', AzureSidebarAngular)
|
||||
.component('dashboardView', DashboardViewAngular);
|
||||
|
||||
@@ -3,8 +3,11 @@ import angular from 'angular';
|
||||
import { EnvironmentStatus } from '@/portainer/environments/types';
|
||||
|
||||
import { reactModule } from './react';
|
||||
import containersModule from './containers';
|
||||
import { componentsModule } from './components';
|
||||
import { networksModule } from './networks';
|
||||
|
||||
angular.module('portainer.docker', ['portainer.app', reactModule]).config([
|
||||
angular.module('portainer.docker', ['portainer.app', containersModule, componentsModule, networksModule, reactModule]).config([
|
||||
'$stateRegistryProvider',
|
||||
function ($stateRegistryProvider) {
|
||||
'use strict';
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { DockerContainerStatus } from '@/react/docker/containers/types';
|
||||
import { Authorized } from '@/portainer/hooks/useUser';
|
||||
import { Link } from '@/portainer/components/Link';
|
||||
import { react2angular } from '@/react-tools/react2angular';
|
||||
|
||||
import { Link } from '@@/Link';
|
||||
import { DockerContainerStatus } from '@/docker/containers/types';
|
||||
|
||||
import styles from './ContainerQuickActions.module.css';
|
||||
|
||||
@@ -3,35 +3,9 @@
|
||||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div class="toolBarTitle"> <i class="fa" ng-class="$ctrl.titleIcon" aria-hidden="true" style="margin-right: 2px"></i> {{ $ctrl.titleText }} </div>
|
||||
<div class="searchBar">
|
||||
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="actionBar" ng-if="!$ctrl.offlineMode" authorization="DockerNetworkDelete, DockerNetworkCreate">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-danger"
|
||||
authorization="DockerNetworkDelete"
|
||||
ng-disabled="$ctrl.state.selectedItemCount === 0"
|
||||
ng-click="$ctrl.removeAction($ctrl.state.selectedItems)"
|
||||
>
|
||||
<i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" ui-sref="docker.networks.new" authorization="DockerNetworkCreate">
|
||||
<i class="fa fa-plus space-right" aria-hidden="true"></i>Add network
|
||||
</button>
|
||||
</div>
|
||||
<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 uib-dropdown-toggle aria-label="Settings"><i class="fa fa-cog" aria-hidden="true"></i></span>
|
||||
<span uib-dropdown-toggle><i class="fa fa-cog" aria-hidden="true"></i> Settings</span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
<div class="tableMenu">
|
||||
<div class="menuHeader"> Table settings </div>
|
||||
@@ -64,6 +38,32 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actionBar" ng-if="!$ctrl.offlineMode" authorization="DockerNetworkDelete, DockerNetworkCreate">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-danger"
|
||||
authorization="DockerNetworkDelete"
|
||||
ng-disabled="$ctrl.state.selectedItemCount === 0"
|
||||
ng-click="$ctrl.removeAction($ctrl.state.selectedItems)"
|
||||
>
|
||||
<i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" ui-sref="docker.networks.new" authorization="DockerNetworkCreate">
|
||||
<i class="fa fa-plus space-right" aria-hidden="true"></i>Add network
|
||||
</button>
|
||||
</div>
|
||||
<div class="searchBar">
|
||||
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover nowrap-cells">
|
||||
<thead>
|
||||
|
||||
186
app/docker/components/docker-sidebar/docker-sidebar.html
Normal file
186
app/docker/components/docker-sidebar/docker-sidebar.html
Normal file
@@ -0,0 +1,186 @@
|
||||
<sidebar-menu-item
|
||||
path="docker.dashboard"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-tachometer-alt fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-dashboard"
|
||||
title="Dashboard"
|
||||
>
|
||||
Dashboard
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu
|
||||
ng-if="!$ctrl.offlineMode"
|
||||
label="App Templates"
|
||||
icon-class="fa-rocket fa-fw"
|
||||
path="docker.templates"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
is-sidebar-open="$ctrl.isSidebarOpen"
|
||||
children-paths="[]"
|
||||
>
|
||||
<sidebar-menu-item
|
||||
path="docker.templates.custom"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
class-name="sidebar-sublist"
|
||||
data-cy="dockerSidebar-customTemplates"
|
||||
title="Custom Templates"
|
||||
>
|
||||
Custom Templates
|
||||
</sidebar-menu-item>
|
||||
</sidebar-menu>
|
||||
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.showStacks"
|
||||
path="docker.stacks"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-th-list fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-stacks"
|
||||
title="Stacks"
|
||||
>
|
||||
Stacks
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.swarmManagement"
|
||||
path="docker.services"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-list-alt fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-services"
|
||||
title="Services"
|
||||
>
|
||||
Services
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
path="docker.containers"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-cubes fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-containers"
|
||||
title="Containers"
|
||||
>
|
||||
Containers
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
path="docker.images"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-clone fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-images"
|
||||
title="Images"
|
||||
>
|
||||
Images
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
path="docker.networks"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-sitemap fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-networks"
|
||||
title="Networks"
|
||||
>
|
||||
Networks
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
path="docker.volumes"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-hdd fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-volumes"
|
||||
title="Volumes"
|
||||
>
|
||||
Volumes
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.endpointApiVersion >= 1.3 && $ctrl.swarmManagement"
|
||||
path="docker.configs"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-file-code fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-configs"
|
||||
title="Configs"
|
||||
>
|
||||
Configs
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.endpointApiVersion >= 1.25 && $ctrl.swarmManagement"
|
||||
path="docker.secrets"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-user-secret fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-secrets"
|
||||
title="Secrets"
|
||||
>
|
||||
Secrets
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.standaloneManagement && $ctrl.adminAccess && !$ctrl.offlineMode"
|
||||
path="docker.events"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
icon-class="fa-history fa-fw"
|
||||
class-name="sidebar-list"
|
||||
data-cy="dockerSidebar-events"
|
||||
title="Events"
|
||||
>
|
||||
Events
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu
|
||||
ng-if="$ctrl.standaloneManagement"
|
||||
label="Host"
|
||||
icon-class="fa-th fa-fw"
|
||||
path="docker.host"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
is-sidebar-open="$ctrl.isSidebarOpen"
|
||||
children-paths="['docker.registries', 'docker.registries.access', 'docker.featuresConfiguration']"
|
||||
>
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.adminAccess"
|
||||
authorization="PortainerEndpointUpdateSettings"
|
||||
path="docker.featuresConfiguration"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
class-name="sidebar-sublist"
|
||||
data-cy="dockerSidebar-setup"
|
||||
title="Setup"
|
||||
>
|
||||
Setup
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item path="docker.registries" path-params="{ endpointId: $ctrl.endpointId }" class-name="sidebar-sublist" data-cy="dockerSidebar-registries" title="Registries">
|
||||
Registries
|
||||
</sidebar-menu-item>
|
||||
</sidebar-menu>
|
||||
|
||||
<sidebar-menu
|
||||
ng-if="$ctrl.swarmManagement"
|
||||
label="Swarm"
|
||||
icon-class="fa-object-group fa-fw"
|
||||
path="docker.swarm"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
is-sidebar-open="$ctrl.isSidebarOpen"
|
||||
children-paths="['docker.registries', 'docker.registries.access', 'docker.featuresConfiguration']"
|
||||
>
|
||||
<sidebar-menu-item
|
||||
ng-if="$ctrl.adminAccess"
|
||||
authorization="PortainerEndpointUpdateSettings"
|
||||
path="docker.featuresConfiguration"
|
||||
path-params="{ endpointId: $ctrl.endpointId }"
|
||||
class-name="sidebar-sublist"
|
||||
data-cy="swarmSidebar-setup"
|
||||
title="Setup"
|
||||
>
|
||||
Setup
|
||||
</sidebar-menu-item>
|
||||
|
||||
<sidebar-menu-item path="docker.registries" path-params="{ endpointId: $ctrl.endpointId }" class-name="sidebar-sublist" data-cy="swarmSidebar-registries" title="Registries">
|
||||
Registries
|
||||
</sidebar-menu-item>
|
||||
</sidebar-menu>
|
||||
15
app/docker/components/docker-sidebar/docker-sidebar.js
Normal file
15
app/docker/components/docker-sidebar/docker-sidebar.js
Normal file
@@ -0,0 +1,15 @@
|
||||
angular.module('portainer.docker').component('dockerSidebar', {
|
||||
templateUrl: './docker-sidebar.html',
|
||||
bindings: {
|
||||
isSidebarOpen: '<',
|
||||
|
||||
endpointApiVersion: '<',
|
||||
swarmManagement: '<',
|
||||
standaloneManagement: '<',
|
||||
adminAccess: '<',
|
||||
offlineMode: '<',
|
||||
currentRouteName: '<',
|
||||
endpointId: '<',
|
||||
showStacks: '<',
|
||||
},
|
||||
});
|
||||
7
app/docker/components/index.ts
Normal file
7
app/docker/components/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { ContainerQuickActionsAngular } from './container-quick-actions';
|
||||
|
||||
export const componentsModule = angular
|
||||
.module('portainer.docker.components', [])
|
||||
.component('containerQuickActions', ContainerQuickActionsAngular).name;
|
||||
@@ -9,18 +9,11 @@ import {
|
||||
} from 'react-table';
|
||||
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||
|
||||
import { useDebounce } from '@/portainer/hooks/useDebounce';
|
||||
import type {
|
||||
ContainersTableSettings,
|
||||
DockerContainer,
|
||||
} from '@/react/docker/containers/types';
|
||||
import { useEnvironment } from '@/portainer/environments/useEnvironment';
|
||||
|
||||
import { PaginationControls } from '@@/PaginationControls';
|
||||
import { PaginationControls } from '@/portainer/components/pagination-controls';
|
||||
import {
|
||||
QuickActionsSettings,
|
||||
buildAction,
|
||||
} from '@@/datatables/QuickActionsSettings';
|
||||
} from '@/portainer/components/datatables/components/QuickActionsSettings';
|
||||
import {
|
||||
Table,
|
||||
TableActions,
|
||||
@@ -30,16 +23,25 @@ import {
|
||||
TableSettingsMenu,
|
||||
TableTitle,
|
||||
TableTitleActions,
|
||||
} from '@@/datatables';
|
||||
import { multiple } from '@@/datatables/filter-types';
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
import { ColumnVisibilityMenu } from '@@/datatables/ColumnVisibilityMenu';
|
||||
import { useRepeater } from '@@/datatables/useRepeater';
|
||||
import { SearchBar, useSearchBarState } from '@@/datatables/SearchBar';
|
||||
import { useRowSelect } from '@@/datatables/useRowSelect';
|
||||
import { Checkbox } from '@@/form-components/Checkbox';
|
||||
import { TableFooter } from '@@/datatables/TableFooter';
|
||||
import { SelectedRowsCount } from '@@/datatables/SelectedRowsCount';
|
||||
} from '@/portainer/components/datatables/components';
|
||||
import { multiple } from '@/portainer/components/datatables/components/filter-types';
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { ColumnVisibilityMenu } from '@/portainer/components/datatables/components/ColumnVisibilityMenu';
|
||||
import { useRepeater } from '@/portainer/components/datatables/components/useRepeater';
|
||||
import { useDebounce } from '@/portainer/hooks/useDebounce';
|
||||
import {
|
||||
SearchBar,
|
||||
useSearchBarState,
|
||||
} from '@/portainer/components/datatables/components/SearchBar';
|
||||
import type {
|
||||
ContainersTableSettings,
|
||||
DockerContainer,
|
||||
} from '@/docker/containers/types';
|
||||
import { useEnvironment } from '@/portainer/environments/useEnvironment';
|
||||
import { useRowSelect } from '@/portainer/components/datatables/components/useRowSelect';
|
||||
import { Checkbox } from '@/portainer/components/form-components/Checkbox';
|
||||
import { TableFooter } from '@/portainer/components/datatables/components/TableFooter';
|
||||
import { SelectedRowsCount } from '@/portainer/components/datatables/components/SelectedRowsCount';
|
||||
|
||||
import { ContainersDatatableActions } from './ContainersDatatableActions';
|
||||
import { ContainersDatatableSettings } from './ContainersDatatableSettings';
|
||||
@@ -141,14 +143,6 @@ export function ContainersDatatable({
|
||||
return (
|
||||
<TableContainer>
|
||||
<TableTitle icon="fa-cubes" label="Containers">
|
||||
<SearchBar value={searchBarValue} onChange={handleSearchBarChange} />
|
||||
<TableActions>
|
||||
<ContainersDatatableActions
|
||||
selectedItems={selectedFlatRows.map((row) => row.original)}
|
||||
isAddActionVisible={isAddActionVisible}
|
||||
endpointId={endpoint.Id}
|
||||
/>
|
||||
</TableActions>
|
||||
<TableTitleActions>
|
||||
<ColumnVisibilityMenu<DockerContainer>
|
||||
columns={columnsToHide}
|
||||
@@ -164,6 +158,16 @@ export function ContainersDatatable({
|
||||
</TableTitleActions>
|
||||
</TableTitle>
|
||||
|
||||
<TableActions>
|
||||
<ContainersDatatableActions
|
||||
selectedItems={selectedFlatRows.map((row) => row.original)}
|
||||
isAddActionVisible={isAddActionVisible}
|
||||
endpointId={endpoint.Id}
|
||||
/>
|
||||
</TableActions>
|
||||
|
||||
<SearchBar value={searchBarValue} onChange={handleSearchBarChange} />
|
||||
|
||||
<Table
|
||||
className={tableProps.className}
|
||||
role={tableProps.role}
|
||||
@@ -2,12 +2,10 @@ import { useRouter } from '@uirouter/react';
|
||||
|
||||
import * as notifications from '@/portainer/services/notifications';
|
||||
import { useAuthorizations, Authorized } from '@/portainer/hooks/useUser';
|
||||
import { Link } from '@/portainer/components/Link';
|
||||
import { confirmContainerDeletion } from '@/portainer/services/modal.service/prompt';
|
||||
import { setPortainerAgentTargetHeader } from '@/portainer/services/http-request.helper';
|
||||
import type {
|
||||
ContainerId,
|
||||
DockerContainer,
|
||||
} from '@/react/docker/containers/types';
|
||||
import type { ContainerId, DockerContainer } from '@/docker/containers/types';
|
||||
import {
|
||||
killContainer,
|
||||
pauseContainer,
|
||||
@@ -16,11 +14,9 @@ import {
|
||||
resumeContainer,
|
||||
startContainer,
|
||||
stopContainer,
|
||||
} from '@/react/docker/containers/containers.service';
|
||||
} from '@/docker/containers/containers.service';
|
||||
import type { EnvironmentId } from '@/portainer/environments/types';
|
||||
|
||||
import { Link } from '@@/Link';
|
||||
import { ButtonGroup, Button } from '@@/buttons';
|
||||
import { ButtonGroup, Button } from '@/portainer/components/Button';
|
||||
|
||||
type ContainerServiceAction = (
|
||||
endpointId: EnvironmentId,
|
||||
@@ -71,7 +67,7 @@ export function ContainersDatatableActions({
|
||||
<ButtonGroup>
|
||||
<Authorized authorizations="DockerContainerStart">
|
||||
<Button
|
||||
color="light"
|
||||
color="success"
|
||||
onClick={() => onStartClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0 || !hasStoppedItemsSelected}
|
||||
>
|
||||
@@ -82,7 +78,7 @@ export function ContainersDatatableActions({
|
||||
|
||||
<Authorized authorizations="DockerContainerStop">
|
||||
<Button
|
||||
color="light"
|
||||
color="danger"
|
||||
onClick={() => onStopClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0 || !hasRunningItemsSelected}
|
||||
>
|
||||
@@ -93,7 +89,7 @@ export function ContainersDatatableActions({
|
||||
|
||||
<Authorized authorizations="DockerContainerKill">
|
||||
<Button
|
||||
color="light"
|
||||
color="danger"
|
||||
onClick={() => onKillClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0}
|
||||
>
|
||||
@@ -104,7 +100,6 @@ export function ContainersDatatableActions({
|
||||
|
||||
<Authorized authorizations="DockerContainerRestart">
|
||||
<Button
|
||||
color="light"
|
||||
onClick={() => onRestartClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0}
|
||||
>
|
||||
@@ -115,7 +110,6 @@ export function ContainersDatatableActions({
|
||||
|
||||
<Authorized authorizations="DockerContainerPause">
|
||||
<Button
|
||||
color="light"
|
||||
onClick={() => onPauseClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0 || !hasRunningItemsSelected}
|
||||
>
|
||||
@@ -126,7 +120,6 @@ export function ContainersDatatableActions({
|
||||
|
||||
<Authorized authorizations="DockerContainerUnpause">
|
||||
<Button
|
||||
color="light"
|
||||
onClick={() => onResumeClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0 || !hasPausedItemsSelected}
|
||||
>
|
||||
@@ -137,7 +130,7 @@ export function ContainersDatatableActions({
|
||||
|
||||
<Authorized authorizations="DockerContainerDelete">
|
||||
<Button
|
||||
color="dangerlight"
|
||||
color="danger"
|
||||
onClick={() => onRemoveClick(selectedItems)}
|
||||
disabled={selectedItemCount === 0}
|
||||
>
|
||||
@@ -1,8 +1,8 @@
|
||||
import { react2angular } from '@/react-tools/react2angular';
|
||||
import { EnvironmentProvider } from '@/portainer/environments/useEnvironment';
|
||||
import { TableSettingsProvider } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import type { Environment } from '@/portainer/environments/types';
|
||||
|
||||
import { TableSettingsProvider } from '@@/datatables/useTableSettings';
|
||||
|
||||
import {
|
||||
ContainersDatatable,
|
||||
ContainerTableProps,
|
||||
@@ -35,3 +35,15 @@ export function ContainersDatatableContainer({
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export const ContainersDatatableAngular = react2angular(
|
||||
ContainersDatatableContainer,
|
||||
[
|
||||
'endpoint',
|
||||
'isAddActionVisible',
|
||||
'dataset',
|
||||
'onRefresh',
|
||||
'isHostColumnVisible',
|
||||
'tableKey',
|
||||
]
|
||||
);
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { ContainersTableSettings } from '@/react/docker/containers/types';
|
||||
|
||||
import { TableSettingsMenuAutoRefresh } from '@@/datatables/TableSettingsMenuAutoRefresh';
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
import { Checkbox } from '@@/form-components/Checkbox';
|
||||
import { TableSettingsMenuAutoRefresh } from '@/portainer/components/datatables/components/TableSettingsMenuAutoRefresh';
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { Checkbox } from '@/portainer/components/form-components/Checkbox';
|
||||
import type { ContainersTableSettings } from '@/docker/containers/types';
|
||||
|
||||
interface Props {
|
||||
isRefreshVisible: boolean;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Column } from 'react-table';
|
||||
|
||||
import { isoDateFromTimestamp } from '@/portainer/filters/filters';
|
||||
import type { DockerContainer } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer } from '@/docker/containers/types';
|
||||
|
||||
export const created: Column<DockerContainer> = {
|
||||
Header: 'Created',
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Column } from 'react-table';
|
||||
|
||||
import type { DockerContainer } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer } from '@/docker/containers/types';
|
||||
|
||||
export const host: Column<DockerContainer> = {
|
||||
Header: 'Host',
|
||||
@@ -3,7 +3,7 @@ import { useSref } from '@uirouter/react';
|
||||
|
||||
import { useEnvironment } from '@/portainer/environments/useEnvironment';
|
||||
import { EnvironmentStatus } from '@/portainer/environments/types';
|
||||
import type { DockerContainer } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer } from '@/docker/containers/types';
|
||||
|
||||
export const image: Column<DockerContainer> = {
|
||||
Header: 'Image',
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Column } from 'react-table';
|
||||
|
||||
import type { DockerContainer } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer } from '@/docker/containers/types';
|
||||
|
||||
export const ip: Column<DockerContainer> = {
|
||||
Header: 'IP Address',
|
||||
@@ -3,12 +3,11 @@ import _ from 'lodash';
|
||||
import { useSref } from '@uirouter/react';
|
||||
|
||||
import { useEnvironment } from '@/portainer/environments/useEnvironment';
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import type {
|
||||
ContainersTableSettings,
|
||||
DockerContainer,
|
||||
} from '@/react/docker/containers/types';
|
||||
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
} from '@/docker/containers/types';
|
||||
|
||||
export const name: Column<DockerContainer> = {
|
||||
Header: 'Name',
|
||||
@@ -2,7 +2,7 @@ import { Column } from 'react-table';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { ownershipIcon } from '@/portainer/filters/filters';
|
||||
import type { DockerContainer } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer } from '@/docker/containers/types';
|
||||
import { ResourceControlOwnership } from '@/portainer/access-control/types';
|
||||
|
||||
export const ownership: Column<DockerContainer> = {
|
||||
@@ -2,7 +2,7 @@ import { Column } from 'react-table';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { useEnvironment } from '@/portainer/environments/useEnvironment';
|
||||
import type { DockerContainer, Port } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer, Port } from '@/docker/containers/types';
|
||||
|
||||
export const ports: Column<DockerContainer> = {
|
||||
Header: 'Published Ports',
|
||||
@@ -1,16 +1,15 @@
|
||||
import { CellProps, Column } from 'react-table';
|
||||
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { useEnvironment } from '@/portainer/environments/useEnvironment';
|
||||
import { useAuthorizations } from '@/portainer/hooks/useUser';
|
||||
import { ContainerQuickActions } from '@/react/docker/containers/components/ContainerQuickActions/ContainerQuickActions';
|
||||
import { ContainerQuickActions } from '@/docker/components/container-quick-actions/ContainerQuickActions';
|
||||
import type {
|
||||
ContainersTableSettings,
|
||||
DockerContainer,
|
||||
} from '@/react/docker/containers/types';
|
||||
} from '@/docker/containers/types';
|
||||
import { EnvironmentStatus } from '@/portainer/environments/types';
|
||||
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
|
||||
export const quickActions: Column<DockerContainer> = {
|
||||
Header: 'Quick Actions',
|
||||
id: 'actions',
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Column } from 'react-table';
|
||||
|
||||
import type { DockerContainer } from '@/react/docker/containers/types';
|
||||
import type { DockerContainer } from '@/docker/containers/types';
|
||||
|
||||
export const stack: Column<DockerContainer> = {
|
||||
Header: 'Stack',
|
||||
@@ -2,12 +2,11 @@ import { Column } from 'react-table';
|
||||
import clsx from 'clsx';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { DefaultFilter } from '@/portainer/components/datatables/components/Filter';
|
||||
import type {
|
||||
DockerContainer,
|
||||
DockerContainerStatus,
|
||||
} from '@/react/docker/containers/types';
|
||||
|
||||
import { DefaultFilter } from '@@/datatables/Filter';
|
||||
} from '@/docker/containers/types';
|
||||
|
||||
export const state: Column<DockerContainer> = {
|
||||
Header: 'State',
|
||||
@@ -1,9 +1,9 @@
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
import PortainerError from '@/portainer/error';
|
||||
import axios from '@/portainer/services/axios';
|
||||
import { genericHandler } from '@/docker/rest/response/handlers';
|
||||
|
||||
import { NetworkId } from '../networks/types';
|
||||
import { genericHandler } from '../rest/response/handlers';
|
||||
|
||||
import { ContainerId, DockerContainer } from './types';
|
||||
|
||||
7
app/docker/containers/index.ts
Normal file
7
app/docker/containers/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { ContainersDatatableAngular } from './components/ContainersDatatable/ContainersDatatableContainer';
|
||||
|
||||
export default angular
|
||||
.module('portainer.docker.containers', [])
|
||||
.component('containersDatatable', ContainersDatatableAngular).name;
|
||||
@@ -1,12 +1,11 @@
|
||||
import { ResourceControlViewModel } from '@/portainer/access-control/models/ResourceControlViewModel';
|
||||
|
||||
import {
|
||||
PaginationTableSettings,
|
||||
RefreshableTableSettings,
|
||||
SettableColumnsTableSettings,
|
||||
SettableQuickActionsTableSettings,
|
||||
SortableTableSettings,
|
||||
} from '@@/datatables/types';
|
||||
} from '@/portainer/components/datatables/types';
|
||||
|
||||
export type DockerContainerStatus =
|
||||
| 'paused'
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@/portainer/components/widget';
|
||||
import { DetailsTable } from '@/portainer/components/DetailsTable';
|
||||
import { Button } from '@/portainer/components/Button';
|
||||
import { Authorized } from '@/portainer/hooks/useUser';
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||
import { DetailsTable } from '@@/DetailsTable';
|
||||
import { Button } from '@@/buttons';
|
||||
import { Link } from '@@/Link';
|
||||
import { Link } from '@/portainer/components/Link';
|
||||
|
||||
import { NetworkContainer, NetworkId } from '../types';
|
||||
import { useDisconnectContainer } from '../queries';
|
||||
@@ -66,7 +65,7 @@ export function NetworkContainersTable({
|
||||
<td>
|
||||
<Authorized authorizations="DockerNetworkDisconnect">
|
||||
<Button
|
||||
data-cy={`networkDetails-disconnect${container.Name}`}
|
||||
dataCy={`networkDetails-disconnect${container.Name}`}
|
||||
size="xsmall"
|
||||
color="danger"
|
||||
onClick={() => {
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Fragment } from 'react';
|
||||
import DockerNetworkHelper from 'Docker/helpers/networkHelper';
|
||||
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@/portainer/components/widget';
|
||||
import { DetailsTable } from '@/portainer/components/DetailsTable';
|
||||
import { Button } from '@/portainer/components/Button';
|
||||
import { Authorized } from '@/portainer/hooks/useUser';
|
||||
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||
import { DetailsTable } from '@@/DetailsTable';
|
||||
import { Button } from '@@/buttons';
|
||||
|
||||
import { isSystemNetwork } from '../network.helper';
|
||||
import { DockerNetwork, IPConfig } from '../types';
|
||||
|
||||
@@ -41,7 +40,7 @@ export function NetworkDetailsTable({
|
||||
{allowRemoveNetwork && (
|
||||
<Authorized authorizations="DockerNetworkDelete">
|
||||
<Button
|
||||
data-cy="networkDetails-deleteNetwork"
|
||||
dataCy="networkDetails-deleteNetwork"
|
||||
size="xsmall"
|
||||
color="danger"
|
||||
onClick={() => onRemoveNetworkClicked()}
|
||||
@@ -4,24 +4,23 @@ import { useQueryClient } from 'react-query';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { useEnvironmentId } from '@/portainer/hooks/useEnvironmentId';
|
||||
import { PageHeader } from '@/portainer/components/PageHeader';
|
||||
import { confirmDeletionAsync } from '@/portainer/services/modal.service/confirm';
|
||||
import { AccessControlPanel } from '@/portainer/access-control/AccessControlPanel/AccessControlPanel';
|
||||
import { ResourceControlType } from '@/portainer/access-control/types';
|
||||
import { DockerContainer } from '@/react/docker/containers/types';
|
||||
import { DockerContainer } from '@/docker/containers/types';
|
||||
import { ResourceControlViewModel } from '@/portainer/access-control/models/ResourceControlViewModel';
|
||||
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
|
||||
import { useNetwork, useDeleteNetwork } from '../queries';
|
||||
import { isSystemNetwork } from '../network.helper';
|
||||
import { DockerNetwork, NetworkContainer } from '../types';
|
||||
import { useContainers } from '../../containers/queries';
|
||||
import { DockerNetwork, NetworkContainer } from '../types';
|
||||
|
||||
import { NetworkDetailsTable } from './NetworkDetailsTable';
|
||||
import { NetworkOptionsTable } from './NetworkOptionsTable';
|
||||
import { NetworkContainersTable } from './NetworkContainersTable';
|
||||
|
||||
export function ItemView() {
|
||||
export function NetworkDetailsView() {
|
||||
const router = useRouter();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
|
||||
import { DetailsTable } from '@@/DetailsTable';
|
||||
import { Widget, WidgetBody, WidgetTitle } from '@/portainer/components/widget';
|
||||
import { DetailsTable } from '@/portainer/components/DetailsTable';
|
||||
|
||||
import { NetworkOptions } from '../types';
|
||||
|
||||
5
app/docker/networks/edit/index.ts
Normal file
5
app/docker/networks/edit/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { react2angular } from '@/react-tools/react2angular';
|
||||
|
||||
import { NetworkDetailsView } from './NetworkDetailsView';
|
||||
|
||||
export const NetworkDetailsViewAngular = react2angular(NetworkDetailsView, []);
|
||||
7
app/docker/networks/index.ts
Normal file
7
app/docker/networks/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { NetworkDetailsViewAngular } from './edit';
|
||||
|
||||
export const networksModule = angular
|
||||
.module('portainer.docker.networks', [])
|
||||
.component('networkDetailsView', NetworkDetailsViewAngular).name;
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ContainerId } from '@/react/docker/containers/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
|
||||
import { ContainerId } from '../containers/types';
|
||||
|
||||
import { NetworkId, DockerNetwork } from './types';
|
||||
|
||||
type NetworkAction = 'connect' | 'disconnect' | 'create';
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
error as notifyError,
|
||||
success as notifySuccess,
|
||||
} from '@/portainer/services/notifications';
|
||||
import { ContainerId } from '@/react/docker/containers/types';
|
||||
|
||||
import { ContainerId } from '../containers/types';
|
||||
|
||||
import {
|
||||
getNetwork,
|
||||
@@ -1,29 +1,6 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
import { ContainersDatatableContainer } from '@/react/docker/containers/ListView/ContainersDatatable/ContainersDatatableContainer';
|
||||
import { ContainerQuickActions } from '@/react/docker/containers/components/ContainerQuickActions';
|
||||
|
||||
export const componentsModule = angular
|
||||
.module('portainer.docker.react.components', [])
|
||||
.component(
|
||||
'containersDatatable',
|
||||
r2a(ContainersDatatableContainer, [
|
||||
'endpoint',
|
||||
'isAddActionVisible',
|
||||
'dataset',
|
||||
'onRefresh',
|
||||
'isHostColumnVisible',
|
||||
'tableKey',
|
||||
])
|
||||
)
|
||||
.component(
|
||||
'containerQuickActions',
|
||||
r2a(ContainerQuickActions, [
|
||||
'containerId',
|
||||
'nodeName',
|
||||
'state',
|
||||
'status',
|
||||
'taskId',
|
||||
])
|
||||
).name;
|
||||
export const componentsModule = angular.module(
|
||||
'portainer.docker.react.components',
|
||||
[]
|
||||
).name;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import angular from 'angular';
|
||||
|
||||
import { ItemView } from '@/react/docker/networks/ItemView';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
||||
export const viewsModule = angular
|
||||
.module('portainer.docker.react.views', [])
|
||||
.component('networkDetailsView', r2a(ItemView, [])).name;
|
||||
export const viewsModule = angular.module(
|
||||
'portainer.docker.react.views',
|
||||
[]
|
||||
).name;
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
resumeContainer,
|
||||
startContainer,
|
||||
stopContainer,
|
||||
} from '@/react/docker/containers/containers.service';
|
||||
} from '@/docker/containers/containers.service';
|
||||
import { ContainerDetailsViewModel, ContainerStatsViewModel, ContainerViewModel } from '../models/container';
|
||||
|
||||
angular.module('portainer.docker').factory('ContainerService', ContainerServiceFactory);
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
export interface VersionResponse {
|
||||
ApiVersion: string;
|
||||
}
|
||||
|
||||
export async function getVersion(environmentId: EnvironmentId) {
|
||||
try {
|
||||
const { data } = await axios.get<VersionResponse>(
|
||||
buildUrl(environmentId, 'version')
|
||||
);
|
||||
return data;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err as Error, 'Unable to retrieve version');
|
||||
}
|
||||
}
|
||||
|
||||
export interface InfoResponse {
|
||||
Swarm?: {
|
||||
NodeID: string;
|
||||
ControlAvailable: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export async function getInfo(environmentId: EnvironmentId) {
|
||||
try {
|
||||
const { data } = await axios.get<InfoResponse>(
|
||||
buildUrl(environmentId, 'info')
|
||||
);
|
||||
return data;
|
||||
} catch (err) {
|
||||
throw parseAxiosError(err as Error, 'Unable to retrieve version');
|
||||
}
|
||||
}
|
||||
|
||||
function buildUrl(
|
||||
environmentId: EnvironmentId,
|
||||
action: string,
|
||||
subAction = ''
|
||||
) {
|
||||
let url = `/endpoints/${environmentId}/docker/${action}`;
|
||||
|
||||
if (subAction) {
|
||||
url += `/${subAction}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function useInfo<TSelect = InfoResponse>(
|
||||
environmentId: EnvironmentId,
|
||||
select?: (info: InfoResponse) => TSelect
|
||||
) {
|
||||
return useQuery(
|
||||
['environment', environmentId, 'docker', 'info'],
|
||||
() => getInfo(environmentId),
|
||||
{
|
||||
select,
|
||||
}
|
||||
);
|
||||
}
|
||||
export function useVersion<TSelect = VersionResponse>(
|
||||
environmentId: EnvironmentId,
|
||||
select?: (info: VersionResponse) => TSelect
|
||||
) {
|
||||
return useQuery(
|
||||
['environment', environmentId, 'docker', 'version'],
|
||||
() => getVersion(environmentId),
|
||||
{
|
||||
select,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -13,7 +13,6 @@ angular.module('portainer.docker').controller('ContainerConsoleController', [
|
||||
'HttpRequestHelper',
|
||||
'LocalStorage',
|
||||
'CONSOLE_COMMANDS_LABEL_PREFIX',
|
||||
'SidebarService',
|
||||
function (
|
||||
$scope,
|
||||
$state,
|
||||
@@ -25,8 +24,7 @@ angular.module('portainer.docker').controller('ContainerConsoleController', [
|
||||
ExecService,
|
||||
HttpRequestHelper,
|
||||
LocalStorage,
|
||||
CONSOLE_COMMANDS_LABEL_PREFIX,
|
||||
SidebarService
|
||||
CONSOLE_COMMANDS_LABEL_PREFIX
|
||||
) {
|
||||
var socket, term;
|
||||
|
||||
@@ -191,7 +189,7 @@ angular.module('portainer.docker').controller('ContainerConsoleController', [
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
$scope.$watch(SidebarService.isSidebarOpen, function () {
|
||||
$scope.$watch('toggle', function () {
|
||||
setTimeout(resizefun, 400);
|
||||
});
|
||||
|
||||
|
||||
@@ -14,29 +14,29 @@
|
||||
<rd-widget-header icon="fa-cogs" title-text="Actions"></rd-widget-header>
|
||||
<rd-widget-body classes="padding">
|
||||
<div class="btn-group" role="group" aria-label="...">
|
||||
<button authorization="DockerContainerStart" class="btn btn-light btn-sm" ng-click="start()" ng-disabled="container.State.Running || container.IsPortainer"
|
||||
<button authorization="DockerContainerStart" class="btn btn-success btn-sm" ng-click="start()" ng-disabled="container.State.Running || container.IsPortainer"
|
||||
><i class="fa fa-play space-right" aria-hidden="true"></i>Start</button
|
||||
>
|
||||
<button authorization="DockerContainerStop" class="btn btn-light btn-sm" ng-click="stop()" ng-disabled="!container.State.Running || container.IsPortainer"
|
||||
<button authorization="DockerContainerStop" class="btn btn-danger btn-sm" ng-click="stop()" ng-disabled="!container.State.Running || container.IsPortainer"
|
||||
><i class="fa fa-stop space-right" aria-hidden="true"></i>Stop</button
|
||||
>
|
||||
<button authorization="DockerContainerKill" class="btn btn-light btn-sm" ng-click="kill()" ng-disabled="!container.State.Running || container.IsPortainer"
|
||||
<button authorization="DockerContainerKill" class="btn btn-danger btn-sm" ng-click="kill()" ng-disabled="!container.State.Running || container.IsPortainer"
|
||||
><i class="fa fa-bomb space-right" aria-hidden="true"></i>Kill</button
|
||||
>
|
||||
<button authorization="DockerContainerRestart" class="btn btn-light btn-sm" ng-click="restart()" ng-disabled="!container.State.Running || container.IsPortainer"
|
||||
<button authorization="DockerContainerRestart" class="btn btn-primary btn-sm" ng-click="restart()" ng-disabled="!container.State.Running || container.IsPortainer"
|
||||
><i class="fa fa-sync space-right" aria-hidden="true"></i>Restart</button
|
||||
>
|
||||
<button
|
||||
authorization="DockerContainerPause"
|
||||
class="btn btn-light btn-sm"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-click="pause()"
|
||||
ng-disabled="!container.State.Running || container.State.Paused || container.IsPortainer"
|
||||
><i class="fa fa-pause space-right" aria-hidden="true"></i>Pause</button
|
||||
>
|
||||
<button authorization="DockerContainerUnpause" class="btn btn-light btn-sm" ng-click="unpause()" ng-disabled="!container.State.Paused || container.IsPortainer"
|
||||
<button authorization="DockerContainerUnpause" class="btn btn-primary btn-sm" ng-click="unpause()" ng-disabled="!container.State.Paused || container.IsPortainer"
|
||||
><i class="fa fa-play space-right" aria-hidden="true"></i>Resume</button
|
||||
>
|
||||
<button authorization="DockerContainerDelete" class="btn btn-dangerlight btn-sm" ng-click="confirmRemove()" ng-disabled="container.IsPortainer"
|
||||
<button authorization="DockerContainerDelete" class="btn btn-danger btn-sm" ng-click="confirmRemove()" ng-disabled="container.IsPortainer"
|
||||
><i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove</button
|
||||
>
|
||||
</div>
|
||||
@@ -51,7 +51,7 @@
|
||||
<span ng-hide="state.recreateContainerInProgress"><i class="fa fa-sync space-right" aria-hidden="true"></i>Recreate</span>
|
||||
<span ng-show="state.recreateContainerInProgress">Recreation in progress...</span>
|
||||
</button>
|
||||
<a class="btn btn-light btn-sm" type="button" ui-sref="docker.containers.new({ from: container.Id, nodeName: nodeName })" ng-disabled="container.IsPortainer"
|
||||
<a class="btn btn-primary btn-sm" type="button" ui-sref="docker.containers.new({ from: container.Id, nodeName: nodeName })" ng-disabled="container.IsPortainer"
|
||||
><i class="fa fa-copy space-right" aria-hidden="true"></i>Duplicate/Edit</a
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -372,8 +372,7 @@ angular.module('portainer.docker').controller('ContainerController', [
|
||||
}
|
||||
|
||||
$scope.recreate = function () {
|
||||
const cannotPullImage = !$scope.container.Config.Image || $scope.container.Config.Image.toLowerCase().startsWith('sha256');
|
||||
ModalService.confirmContainerRecreation(cannotPullImage, function (result) {
|
||||
ModalService.confirmContainerRecreation(function (result) {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,6 @@ function BuildImageController($scope, $async, $window, ModalService, BuildServic
|
||||
$scope.state.isEditorDirty = false;
|
||||
});
|
||||
|
||||
$scope.checkName = function (name) {
|
||||
const parts = name.split('/');
|
||||
const repository = parts[parts.length - 1];
|
||||
const repositoryRegExp = RegExp('^[a-z0-9-_]{2,255}(:[A-Za-z0-9-_.]{1,128})?$');
|
||||
return repositoryRegExp.test(repository);
|
||||
};
|
||||
|
||||
$scope.addImageName = function () {
|
||||
$scope.formValues.ImageNames.push({ Name: '' });
|
||||
};
|
||||
@@ -99,16 +92,13 @@ function BuildImageController($scope, $async, $window, ModalService, BuildServic
|
||||
}
|
||||
|
||||
$scope.validImageNames = function () {
|
||||
if ($scope.formValues.ImageNames.length == 0) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < $scope.formValues.ImageNames.length; i++) {
|
||||
var item = $scope.formValues.ImageNames[i];
|
||||
if (!$scope.checkName(item.Name)) {
|
||||
return false;
|
||||
if (item.Name !== '') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.editorUpdate = function (cm) {
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<span class="input-group-addon">name</span>
|
||||
<input type="text" class="form-control" ng-model="item.Name" placeholder="e.g. my-image:my-tag" auto-focus />
|
||||
<span class="input-group-addon"
|
||||
><i ng-class="{ true: 'fa fa-check green-icon', false: 'fa fa-times red-icon' }[checkName(item.Name)]" aria-hidden="true"></i
|
||||
><i ng-class="{ true: 'fa fa-check green-icon', false: 'fa fa-times red-icon' }[item.Name !== '']" aria-hidden="true"></i
|
||||
></span>
|
||||
</div>
|
||||
<!-- !name-input -->
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { usePagination, useTable } from 'react-table';
|
||||
|
||||
import {
|
||||
Table,
|
||||
TableContainer,
|
||||
TableHeaderRow,
|
||||
TableRow,
|
||||
} from '@/portainer/components/datatables/components';
|
||||
import { InnerDatatable } from '@/portainer/components/datatables/components/InnerDatatable';
|
||||
import { Device } from '@/portainer/hostmanagement/open-amt/model';
|
||||
import { useAMTDevices } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/useAMTDevices';
|
||||
import { RowProvider } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/columns/RowContext';
|
||||
import { EnvironmentId } from '@/portainer/environments/types';
|
||||
import PortainerError from '@/portainer/error';
|
||||
|
||||
import { InnerDatatable } from '@@/datatables/InnerDatatable';
|
||||
import { Table, TableContainer, TableHeaderRow, TableRow } from '@@/datatables';
|
||||
|
||||
import { useColumns } from './columns';
|
||||
|
||||
export interface AMTDevicesTableProps {
|
||||
|
||||
@@ -4,12 +4,11 @@ import { MenuItem, MenuLink } from '@reach/menu-button';
|
||||
import { useQueryClient } from 'react-query';
|
||||
|
||||
import { Device } from '@/portainer/hostmanagement/open-amt/model';
|
||||
import { ActionsMenu } from '@/portainer/components/datatables/components/ActionsMenu';
|
||||
import { confirmAsync } from '@/portainer/services/modal.service/confirm';
|
||||
import { executeDeviceAction } from '@/portainer/hostmanagement/open-amt/open-amt.service';
|
||||
import * as notifications from '@/portainer/services/notifications';
|
||||
|
||||
import { ActionsMenu } from '@@/datatables/ActionsMenu';
|
||||
import { ActionsMenuTitle } from '@@/datatables/ActionsMenuTitle';
|
||||
import { ActionsMenuTitle } from '@/portainer/components/datatables/components/ActionsMenuTitle';
|
||||
|
||||
import { useRowContext } from './RowContext';
|
||||
|
||||
|
||||
@@ -3,10 +3,7 @@ import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { AMTDevicesDatatable } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/AMTDevicesDatatable';
|
||||
import { EnvironmentGroup } from '@/portainer/environment-groups/types';
|
||||
|
||||
import { PaginationControls } from '@@/PaginationControls';
|
||||
import { PaginationControls } from '@/portainer/components/pagination-controls';
|
||||
import {
|
||||
Table,
|
||||
TableActions,
|
||||
@@ -16,15 +13,17 @@ import {
|
||||
TableSettingsMenu,
|
||||
TableTitle,
|
||||
TableTitleActions,
|
||||
} from '@@/datatables';
|
||||
import { multiple } from '@@/datatables/filter-types';
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
import { ColumnVisibilityMenu } from '@@/datatables/ColumnVisibilityMenu';
|
||||
import { SearchBar } from '@@/datatables/SearchBar';
|
||||
import { useRowSelect } from '@@/datatables/useRowSelect';
|
||||
import { TableFooter } from '@@/datatables/TableFooter';
|
||||
import { SelectedRowsCount } from '@@/datatables/SelectedRowsCount';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
} from '@/portainer/components/datatables/components';
|
||||
import { multiple } from '@/portainer/components/datatables/components/filter-types';
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { ColumnVisibilityMenu } from '@/portainer/components/datatables/components/ColumnVisibilityMenu';
|
||||
import { SearchBar } from '@/portainer/components/datatables/components/SearchBar';
|
||||
import { useRowSelect } from '@/portainer/components/datatables/components/useRowSelect';
|
||||
import { TableFooter } from '@/portainer/components/datatables/components/TableFooter';
|
||||
import { SelectedRowsCount } from '@/portainer/components/datatables/components/SelectedRowsCount';
|
||||
import { AMTDevicesDatatable } from '@/edge/EdgeDevices/EdgeDevicesView/AMTDevicesDatatable/AMTDevicesDatatable';
|
||||
import { TextTip } from '@/portainer/components/Tip/TextTip';
|
||||
import { EnvironmentGroup } from '@/portainer/environment-groups/types';
|
||||
|
||||
import { EdgeDevicesDatatableActions } from './EdgeDevicesDatatableActions';
|
||||
import { EdgeDevicesDatatableSettings } from './EdgeDevicesDatatableSettings';
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { useRouter } from '@uirouter/react';
|
||||
|
||||
import type { Environment } from '@/portainer/environments/types';
|
||||
import { Button } from '@/portainer/components/Button';
|
||||
import { confirmAsync } from '@/portainer/services/modal.service/confirm';
|
||||
import { promptAsync } from '@/portainer/services/modal.service/prompt';
|
||||
import * as notifications from '@/portainer/services/notifications';
|
||||
import { activateDevice } from '@/portainer/hostmanagement/open-amt/open-amt.service';
|
||||
import { deleteEndpoint } from '@/portainer/environments/environment.service';
|
||||
|
||||
import { Button } from '@@/buttons';
|
||||
import { Link } from '@@/Link';
|
||||
import { Link } from '@/portainer/components/Link';
|
||||
|
||||
interface Props {
|
||||
selectedItems: Environment[];
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useEnvironmentList } from '@/portainer/environments/queries/useEnvironmentList';
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { useDebounce } from '@/portainer/hooks/useDebounce';
|
||||
|
||||
import { useSearchBarState } from '@@/datatables/SearchBar';
|
||||
import {
|
||||
TableSettingsProvider,
|
||||
useTableSettings,
|
||||
} from '@@/datatables/useTableSettings';
|
||||
} from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { useEnvironmentList } from '@/portainer/environments/queries/useEnvironmentList';
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { useSearchBarState } from '@/portainer/components/datatables/components/SearchBar';
|
||||
import { useDebounce } from '@/portainer/hooks/useDebounce';
|
||||
|
||||
import {
|
||||
EdgeDevicesDatatable,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TableSettingsMenuAutoRefresh } from '@@/datatables/TableSettingsMenuAutoRefresh';
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
import { TableSettingsMenuAutoRefresh } from '@/portainer/components/datatables/components/TableSettingsMenuAutoRefresh';
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
|
||||
import { EdgeDeviceTableSettings } from './types';
|
||||
|
||||
|
||||
@@ -3,12 +3,11 @@ import { MenuItem, MenuLink } from '@reach/menu-button';
|
||||
import { useRouter, useSref } from '@uirouter/react';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { ActionsMenu } from '@/portainer/components/datatables/components/ActionsMenu';
|
||||
import { snapshotEndpoint } from '@/portainer/environments/environment.service';
|
||||
import * as notifications from '@/portainer/services/notifications';
|
||||
import { getRoute } from '@/portainer/environments/utils';
|
||||
|
||||
import { ActionsMenu } from '@@/datatables/ActionsMenu';
|
||||
|
||||
export const actions: Column<Environment> = {
|
||||
Header: 'Actions',
|
||||
accessor: () => 'actions',
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Column } from 'react-table';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
|
||||
import { DefaultFilter } from '@@/datatables/Filter';
|
||||
import { DefaultFilter } from '@/portainer/components/datatables/components/Filter';
|
||||
|
||||
import { useRowContext } from './RowContext';
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { CellProps, Column } from 'react-table';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
|
||||
import { Link } from '@@/Link';
|
||||
import { ExpandingCell } from '@@/datatables/ExpandingCell';
|
||||
import { Link } from '@/portainer/components/Link';
|
||||
import { ExpandingCell } from '@/portainer/components/datatables/components/ExpandingCell';
|
||||
|
||||
import { useRowContext } from './RowContext';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
RefreshableTableSettings,
|
||||
SettableColumnsTableSettings,
|
||||
SortableTableSettings,
|
||||
} from '@@/datatables/types';
|
||||
} from '@/portainer/components/datatables/types';
|
||||
|
||||
export interface Pagination {
|
||||
pageLimit: number;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { PageHeader } from '@/portainer/components/PageHeader';
|
||||
import { useSettings } from '@/portainer/settings/queries';
|
||||
import { useGroups } from '@/portainer/environment-groups/queries';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
import { ViewLoading } from '@@/ViewLoading';
|
||||
import { ViewLoading } from '@/portainer/components/ViewLoading';
|
||||
|
||||
import { EdgeDevicesDatatableContainer } from './EdgeDevicesDatatable/EdgeDevicesDatatableContainer';
|
||||
|
||||
|
||||
@@ -8,16 +8,18 @@ import {
|
||||
} from 'react-table';
|
||||
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||
|
||||
import { Button } from '@/portainer/components/Button';
|
||||
import { Table } from '@/portainer/components/datatables/components';
|
||||
import {
|
||||
SearchBar,
|
||||
useSearchBarState,
|
||||
} from '@/portainer/components/datatables/components/SearchBar';
|
||||
import { SelectedRowsCount } from '@/portainer/components/datatables/components/SelectedRowsCount';
|
||||
import { PaginationControls } from '@/portainer/components/pagination-controls';
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { useTableSettings } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { notifySuccess } from '@/portainer/services/notifications';
|
||||
|
||||
import { Button } from '@@/buttons';
|
||||
import { Table } from '@@/datatables';
|
||||
import { SearchBar, useSearchBarState } from '@@/datatables/SearchBar';
|
||||
import { SelectedRowsCount } from '@@/datatables/SelectedRowsCount';
|
||||
import { PaginationControls } from '@@/PaginationControls';
|
||||
import { useTableSettings } from '@@/datatables/useTableSettings';
|
||||
|
||||
import { useAssociateDeviceMutation } from '../queries';
|
||||
|
||||
import { TableSettings } from './types';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
PaginationTableSettings,
|
||||
SortableTableSettings,
|
||||
} from '@@/datatables/types';
|
||||
} from '@/portainer/components/datatables/types';
|
||||
|
||||
export interface TableSettings
|
||||
extends SortableTableSettings,
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { useRouter } from '@uirouter/react';
|
||||
|
||||
import { TableSettingsProvider } from '@/portainer/components/datatables/components/useTableSettings';
|
||||
import { PageHeader } from '@/portainer/components/PageHeader';
|
||||
import { useEnvironmentList } from '@/portainer/environments/queries/useEnvironmentList';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
||||
import { InformationPanel } from '@@/InformationPanel';
|
||||
import { TextTip } from '@@/Tip/TextTip';
|
||||
import { TableSettingsProvider } from '@@/datatables/useTableSettings';
|
||||
import { PageHeader } from '@@/PageHeader';
|
||||
import { InformationPanel } from '@/portainer/components/InformationPanel';
|
||||
import { TextTip } from '@/portainer/components/Tip/TextTip';
|
||||
|
||||
import { DataTable } from './Datatable/Datatable';
|
||||
import { TableSettings } from './Datatable/types';
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { FormControl } from '@/portainer/components/form-components/FormControl';
|
||||
import { Select } from '@/portainer/components/form-components/Input';
|
||||
import { useSettings } from '@/portainer/settings/queries';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
import { Select } from '@@/form-components/Input';
|
||||
|
||||
interface Props {
|
||||
value: number;
|
||||
onChange(value: number): void;
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
<rd-header-content>Edge Jobs</rd-header-content>
|
||||
</rd-header>
|
||||
|
||||
<information-panel title-text="Information">
|
||||
<span class="small">
|
||||
<p class="text-muted">Edge Jobs requires Docker Standalone and a cron implementation that reads jobs from <code>/etc/cron.d</code></p>
|
||||
</span>
|
||||
</information-panel>
|
||||
<beta-panel></beta-panel>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
|
||||
22
app/global.d.ts
vendored
22
app/global.d.ts
vendored
@@ -5,13 +5,6 @@ declare module '*.png' {
|
||||
export default '' as string;
|
||||
}
|
||||
|
||||
type SvgrComponent = React.StatelessComponent<React.SVGAttributes<SVGElement>>;
|
||||
|
||||
declare module '*.svg?c' {
|
||||
const value: SvgrComponent;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module '*.css';
|
||||
|
||||
declare module '@open-amt-cloud-toolkit/ui-toolkit-react/reactjs/src/kvm.bundle';
|
||||
@@ -27,18 +20,5 @@ declare module 'axios-progress-bar' {
|
||||
}
|
||||
|
||||
interface Window {
|
||||
/**
|
||||
* will be true if portainer is run as a Docker Desktop Extension
|
||||
*/
|
||||
ddExtension?: boolean;
|
||||
}
|
||||
|
||||
declare module 'process' {
|
||||
global {
|
||||
namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
PORTAINER_EDITION: 'BE' | 'CE';
|
||||
}
|
||||
}
|
||||
}
|
||||
ddExtension: boolean;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user