diff --git a/app/assets/css/index.js b/app/assets/css/index.js
index 953c01586..0fe541050 100644
--- a/app/assets/css/index.js
+++ b/app/assets/css/index.js
@@ -2,7 +2,6 @@ import 'bootstrap/dist/css/bootstrap.css';
import 'toastr/build/toastr.css';
import 'xterm/dist/xterm.css';
import 'angularjs-slider/dist/rzslider.css';
-import 'angular-json-tree/dist/angular-json-tree.css';
import 'angular-loading-bar/build/loading-bar.css';
import 'angular-moment-picker/dist/angular-moment-picker.min.css';
import 'spinkit/spinkit.min.css';
diff --git a/app/docker/filters/filters.js b/app/docker/filters/filters.js
index 7c037dd26..6b24f0500 100644
--- a/app/docker/filters/filters.js
+++ b/app/docker/filters/filters.js
@@ -1,5 +1,5 @@
import _ from 'lodash-es';
-import { hideShaSum, joinCommand, nodeStatusBadge, taskStatusBadge, trimSHA, trimVersionTag } from './utils';
+import { hideShaSum, joinCommand, nodeStatusBadge, taskStatusBadge, trimContainerName, trimSHA, trimVersionTag } from './utils';
function includeString(text, values) {
return values.some(function (val) {
@@ -76,15 +76,7 @@ angular
};
})
.filter('nodestatusbadge', () => nodeStatusBadge)
- .filter('trimcontainername', function () {
- 'use strict';
- return function (name) {
- if (name) {
- return name.indexOf('/') === 0 ? name.slice(1) : name;
- }
- return '';
- };
- })
+ .filter('trimcontainername', () => trimContainerName)
.filter('getstatetext', function () {
'use strict';
return function (state) {
diff --git a/app/docker/filters/utils.ts b/app/docker/filters/utils.ts
index a7e35cd89..a5b409d0f 100644
--- a/app/docker/filters/utils.ts
+++ b/app/docker/filters/utils.ts
@@ -83,3 +83,10 @@ export function nodeStatusBadge(text: NodeStatus['State']) {
export function hideShaSum(imageName = '') {
return imageName.split('@sha')[0];
}
+
+export function trimContainerName(name?: string) {
+ if (name) {
+ return name.indexOf('/') === 0 ? name.slice(1) : name;
+ }
+ return '';
+}
diff --git a/app/docker/react/views/containers.ts b/app/docker/react/views/containers.ts
index 6e4bac0a6..9780c0719 100644
--- a/app/docker/react/views/containers.ts
+++ b/app/docker/react/views/containers.ts
@@ -8,6 +8,7 @@ import { withReactQuery } from '@/react-tools/withReactQuery';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { LogView } from '@/react/docker/containers/LogView';
import { CreateView } from '@/react/docker/containers/CreateView';
+import { InspectView } from '@/react/docker/containers/InspectView/InspectView';
export const containersModule = angular
.module('portainer.docker.react.views.containers', [])
@@ -26,7 +27,10 @@ export const containersModule = angular
'containerLogView',
r2a(withUIRouter(withReactQuery(withCurrentUser(LogView))), [])
)
-
+ .component(
+ 'dockerContainerInspectView',
+ r2a(withUIRouter(withReactQuery(withCurrentUser(InspectView))), [])
+ )
.config(config).name;
/* @ngInject */
@@ -95,8 +99,7 @@ function config($stateRegistryProvider: StateRegistry) {
url: '/inspect',
views: {
'content@': {
- templateUrl: '~@/docker/views/containers/inspect/containerinspect.html',
- controller: 'ContainerInspectController',
+ component: 'dockerContainerInspectView',
},
},
});
diff --git a/app/docker/views/containers/inspect/containerInspectController.js b/app/docker/views/containers/inspect/containerInspectController.js
deleted file mode 100644
index 45e8d111a..000000000
--- a/app/docker/views/containers/inspect/containerInspectController.js
+++ /dev/null
@@ -1,27 +0,0 @@
-angular.module('portainer.docker').controller('ContainerInspectController', [
- '$scope',
- '$transition$',
- 'Notifications',
- 'ContainerService',
- 'HttpRequestHelper',
- 'endpoint',
- function ($scope, $transition$, Notifications, ContainerService, HttpRequestHelper, endpoint) {
- $scope.state = {
- DisplayTextView: false,
- };
- $scope.containerInfo = {};
-
- function initView() {
- HttpRequestHelper.setPortainerAgentTargetHeader($transition$.params().nodeName);
- ContainerService.inspect(endpoint.Id, $transition$.params().id)
- .then(function success(d) {
- $scope.containerInfo = d;
- })
- .catch(function error(e) {
- Notifications.error('Failure', e, 'Unable to inspect container');
- });
- }
-
- initView();
- },
-]);
diff --git a/app/docker/views/containers/inspect/containerinspect.html b/app/docker/views/containers/inspect/containerinspect.html
deleted file mode 100644
index fba446693..000000000
--- a/app/docker/views/containers/inspect/containerinspect.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ containerInfo | json: 4 }}
-
-
-
-
-
diff --git a/app/index.js b/app/index.js
index bbb18e5f1..26aab8554 100644
--- a/app/index.js
+++ b/app/index.js
@@ -34,7 +34,6 @@ angular
'ngResource',
'angularUtils.directives.dirPagination',
'LocalStorageModule',
- 'angular-json-tree',
'angular-loading-bar',
'angular-clipboard',
'ngFileSaver',
diff --git a/app/react/components/JsonTree.css b/app/react/components/JsonTree.module.css
similarity index 54%
rename from app/react/components/JsonTree.css
rename to app/react/components/JsonTree.module.css
index 181d93437..f17091906 100644
--- a/app/react/components/JsonTree.css
+++ b/app/react/components/JsonTree.module.css
@@ -1,30 +1,25 @@
/* json-tree override */
-.json-tree,
-json-tree {
+.json-tree {
font-size: 13px;
color: var(--blue-5);
}
-.json-tree .key,
-json-tree .key {
+.json-tree .key {
+ color: var(--text-json-tree-color);
+ padding-right: 4px;
+}
+
+.json-tree .chevronIcon {
color: var(--text-json-tree-color);
}
-json-tree .key {
- padding-right: 5px;
-}
-
-.json-tree .branch-preview,
-json-tree .branch-preview {
+.json-tree .branch-preview {
color: var(--text-json-tree-branch-preview-color);
font-style: normal;
font-size: 11px;
opacity: 0.5;
}
-.json-tree .leaf-value,
-json-tree .leaf-value {
+.json-tree .leaf-value {
color: var(--text-json-tree-leaf-color);
}
-
-/* !json-tree override */
diff --git a/app/react/components/JsonTree.tsx b/app/react/components/JsonTree.tsx
index 4dfc78687..b54095486 100644
--- a/app/react/components/JsonTree.tsx
+++ b/app/react/components/JsonTree.tsx
@@ -3,7 +3,7 @@ import { JsonView, defaultStyles } from 'react-json-view-lite';
import 'react-json-view-lite/dist/index.css';
import clsx from 'clsx';
-import './JsonTree.css';
+import styles from './JsonTree.module.css';
export function JsonTree({ style, ...props }: ComponentProps) {
const currentStyle = getCurrentStyle(style);
@@ -25,17 +25,20 @@ function getCurrentStyle(style: StyleProps | undefined): StyleProps {
return {
...defaultStyles,
- container: 'json-tree',
- booleanValue: 'leaf-value',
- nullValue: 'leaf-value',
- otherValue: 'leaf-value',
- numberValue: 'leaf-value',
- stringValue: 'leaf-value',
- undefinedValue: 'leaf-value',
- label: 'key',
- punctuation: 'leaf-value',
- collapseIcon: clsx(defaultStyles.collapseIcon, 'key'),
- expandIcon: clsx(defaultStyles.expandIcon, 'key'),
- collapsedContent: clsx(defaultStyles.collapsedContent, 'branch-preview'),
+ container: styles.jsonTree,
+ booleanValue: styles.leafValue,
+ nullValue: styles.leafValue,
+ otherValue: styles.leafValue,
+ numberValue: styles.leafValue,
+ stringValue: styles.leafValue,
+ undefinedValue: styles.leafValue,
+ label: styles.key,
+ punctuation: styles.leafValue,
+ collapseIcon: clsx(defaultStyles.collapseIcon, styles.chevronIcon),
+ expandIcon: clsx(defaultStyles.expandIcon, styles.chevronIcon),
+ collapsedContent: clsx(
+ defaultStyles.collapsedContent,
+ styles.branchPreview
+ ),
};
}
diff --git a/app/react/components/form-components/ButtonSelector/ButtonSelector.tsx b/app/react/components/form-components/ButtonSelector/ButtonSelector.tsx
index 23b94d5f8..3974fd892 100644
--- a/app/react/components/form-components/ButtonSelector/ButtonSelector.tsx
+++ b/app/react/components/form-components/ButtonSelector/ButtonSelector.tsx
@@ -1,5 +1,5 @@
import clsx from 'clsx';
-import { PropsWithChildren, ReactNode } from 'react';
+import { ComponentProps, PropsWithChildren, ReactNode } from 'react';
import { AutomationTestingProps } from '@/types';
@@ -12,6 +12,7 @@ export interface Option {
value: T;
label?: ReactNode;
disabled?: boolean;
+ icon?: ComponentProps['icon'];
}
interface Props {
@@ -49,6 +50,7 @@ export function ButtonSelector({
onChange={() => onChange(option.value)}
disabled={disabled || option.disabled}
readOnly={readOnly}
+ icon={option.icon}
>
{option.label || option.value.toString()}
@@ -62,6 +64,7 @@ interface OptionItemProps {
onChange(): void;
disabled?: boolean;
readOnly?: boolean;
+ icon?: ComponentProps['icon'];
}
function OptionItem({
@@ -71,6 +74,7 @@ function OptionItem({
disabled,
readOnly,
'data-cy': dataCy,
+ icon,
}: PropsWithChildren & AutomationTestingProps) {
return (