dsh-plugin-container 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +80 -2
- package/cordis.patch.yml +3 -0
- package/docs/ai-chat.png +0 -0
- package/docs/ai-new-session.png +0 -0
- package/docs/apple-container.png +0 -0
- package/docs/attach.png +0 -0
- package/docs/docker-console.png +0 -0
- package/docs/docker-overview.png +0 -0
- package/docs/docker-volumes.png +0 -0
- package/docs/image-architecture.png +0 -0
- package/docs/package-install.png +0 -0
- package/docs/provider-switch.png +0 -0
- package/docs/run-container.png +0 -0
- package/index.js +138 -0
- package/lib/client.js +3560 -0
- package/package.json +62 -4
- package/src/client/api.js +98 -0
- package/src/client/attach.jsx +134 -0
- package/src/client/components.jsx +320 -0
- package/src/client/hooks.js +161 -0
- package/src/client/i18n.js +502 -0
- package/src/client/icons.jsx +227 -0
- package/src/client/index.jsx +76 -0
- package/src/client/page.jsx +782 -0
- package/src/client/run-container.jsx +187 -0
- package/src/client/runs.js +182 -0
- package/src/client/store.js +91 -0
- package/src/client/styles.js +371 -0
- package/src/client/tabs/compose.jsx +94 -0
- package/src/client/tabs/console.jsx +211 -0
- package/src/client/tabs/containers.jsx +148 -0
- package/src/client/tabs/images.jsx +127 -0
- package/src/client/tabs/networks.jsx +91 -0
- package/src/client/tabs/overview.jsx +266 -0
- package/src/client/tabs/volumes.jsx +76 -0
- package/src/host/apple-cli.js +307 -0
- package/src/host/apple.js +471 -0
- package/src/host/attach.js +246 -0
- package/src/host/commands.js +235 -0
- package/src/host/docker-cli.js +405 -0
- package/src/host/jobs.js +245 -0
- package/src/host/parsers.js +484 -0
- package/src/host/runtime.js +285 -0
- package/src/host/service.js +836 -0
- package/src/host/tools.js +198 -0
- package/src/host/util.js +97 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/** Theme-aware styles for the Docker panel. */
|
|
2
|
+
const STYLE_TAG = 'dsh-plugin-container/styles.css'
|
|
3
|
+
|
|
4
|
+
const CSS = `
|
|
5
|
+
.dsh-docker-page {
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
height: 100%;
|
|
8
|
+
min-height: 0;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
color: var(--dsw-alias-label-primary, #17181c);
|
|
12
|
+
background: var(--dsw-alias-bg-base, #fff);
|
|
13
|
+
font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
|
|
14
|
+
font-size: 13px;
|
|
15
|
+
line-height: 1.45;
|
|
16
|
+
}
|
|
17
|
+
.dsh-docker-page *,
|
|
18
|
+
.dsh-docker-page *::before,
|
|
19
|
+
.dsh-docker-page *::after { box-sizing: border-box; }
|
|
20
|
+
[data-platform=darwin] .dsh-docker-page { padding-top: var(--dsh-frame-top-clearance, 0px); }
|
|
21
|
+
|
|
22
|
+
.dsh-docker-header {
|
|
23
|
+
flex: none;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: flex-start;
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
gap: 18px;
|
|
28
|
+
padding: 22px clamp(20px, 3.5vw, 40px) 14px;
|
|
29
|
+
border-bottom: 1px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08));
|
|
30
|
+
}
|
|
31
|
+
.dsh-docker-brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
|
|
32
|
+
.dsh-docker-mark {
|
|
33
|
+
width: 38px; height: 38px; flex: none;
|
|
34
|
+
display: grid; place-items: center;
|
|
35
|
+
border-radius: 11px;
|
|
36
|
+
color: var(--dsw-alias-brand-primary, #4d6bfe);
|
|
37
|
+
background: var(--dsw-alias-bg-layer-2, #f4f5f8);
|
|
38
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08));
|
|
39
|
+
}
|
|
40
|
+
.dsh-docker-heading { min-width: 0; }
|
|
41
|
+
.dsh-docker-title { margin: 0; font-size: 19px; line-height: 26px; font-weight: 600; letter-spacing: -.01em; }
|
|
42
|
+
.dsh-docker-subtitle { margin: 2px 0 0; color: var(--dsw-alias-label-secondary, #60636c); font-size: 12px; line-height: 18px; }
|
|
43
|
+
.dsh-docker-header-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
|
|
44
|
+
.dsh-docker-headmeta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
|
|
45
|
+
|
|
46
|
+
.dsh-docker-status {
|
|
47
|
+
display: inline-flex; align-items: center; gap: 6px;
|
|
48
|
+
height: 26px; padding: 0 10px; border-radius: 999px;
|
|
49
|
+
font-size: 12px; line-height: 1; white-space: nowrap;
|
|
50
|
+
color: var(--dsw-alias-label-secondary, #60636c);
|
|
51
|
+
background: var(--dsw-alias-bg-layer-2, #f4f5f8);
|
|
52
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08));
|
|
53
|
+
}
|
|
54
|
+
.dsh-docker-status[data-state=running] { color: var(--dsw-alias-state-success-primary, #168a4b); background: var(--dsw-alias-state-success-tertiary, rgba(22,138,75,.1)); }
|
|
55
|
+
.dsh-docker-status[data-state=stopped] { color: var(--dsw-alias-label-secondary, #60636c); }
|
|
56
|
+
.dsh-docker-status[data-state=starting] { color: var(--dsw-alias-state-warn-primary, #a35f00); background: var(--dsw-alias-state-warn-tertiary, rgba(163,95,0,.1)); }
|
|
57
|
+
.dsh-docker-status[data-state=error] { color: var(--dsw-alias-label-error, #d33c3c); background: var(--dsw-alias-state-error-primary, rgba(211,60,60,.08)); }
|
|
58
|
+
.dsh-docker-status[data-state=remote] { color: var(--dsw-alias-state-business-primary, #3156c8); }
|
|
59
|
+
.dsh-docker-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
|
|
60
|
+
.dsh-docker-status[data-state=running] .dsh-docker-dot { box-shadow: 0 0 0 3px var(--dsw-alias-state-success-tertiary, rgba(22,138,75,.12)); }
|
|
61
|
+
|
|
62
|
+
.dsh-docker-btn {
|
|
63
|
+
appearance: none; border: 0; cursor: pointer;
|
|
64
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
65
|
+
height: 30px; padding: 0 12px; border-radius: 7px;
|
|
66
|
+
font: inherit; font-size: 12.5px; font-weight: 500; white-space: nowrap;
|
|
67
|
+
color: var(--dsw-alias-label-primary, #17181c);
|
|
68
|
+
background: var(--dsw-alias-bg-layer-2, #f4f5f8);
|
|
69
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08));
|
|
70
|
+
transition: background .12s ease, border-color .12s ease, opacity .12s ease;
|
|
71
|
+
}
|
|
72
|
+
.dsh-docker-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,.045)); }
|
|
73
|
+
.dsh-docker-btn:active { background: var(--dsw-alias-interactive-bg-active, rgba(0,0,0,.08)); }
|
|
74
|
+
.dsh-docker-btn:focus-visible { outline: 2px solid var(--dsw-focus-ring-color, #4d6bfe); outline-offset: 2px; }
|
|
75
|
+
.dsh-docker-btn[disabled] { opacity: .45; cursor: not-allowed; }
|
|
76
|
+
.dsh-docker-btn.dsh-docker-primary {
|
|
77
|
+
color: var(--dsw-alias-label-primary-foreground, #fff);
|
|
78
|
+
background: var(--dsw-alias-button-primary-fill, #3156c8);
|
|
79
|
+
border-color: transparent;
|
|
80
|
+
}
|
|
81
|
+
.dsh-docker-btn.dsh-docker-primary:hover { background: var(--dsw-alias-button-primary-hover, #2848ad); }
|
|
82
|
+
.dsh-docker-btn.dsh-docker-danger { color: var(--dsw-alias-label-error, #d33c3c); }
|
|
83
|
+
.dsh-docker-btn.dsh-docker-danger:hover { background: var(--dsw-alias-interactive-bg-hover-danger, rgba(211,60,60,.09)); }
|
|
84
|
+
.dsh-docker-btn.dsh-docker-danger-solid {
|
|
85
|
+
color: #fff; background: var(--dsw-alias-label-error, #d33c3c); border-color: transparent;
|
|
86
|
+
}
|
|
87
|
+
.dsh-docker-btn.dsh-docker-ghost { background: transparent; border-color: transparent; }
|
|
88
|
+
.dsh-docker-btn.dsh-docker-ghost:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,.045)); }
|
|
89
|
+
.dsh-docker-btn.dsh-docker-sm { height: 26px; padding: 0 9px; font-size: 12px; border-radius: 6px; }
|
|
90
|
+
.dsh-docker-btn.dsh-docker-lg { height: 34px; padding: 0 14px; font-size: 13px; }
|
|
91
|
+
.dsh-docker-icon-btn {
|
|
92
|
+
position: relative;
|
|
93
|
+
appearance: none; border: .5px solid transparent; background: transparent; cursor: pointer;
|
|
94
|
+
width: 30px; height: 30px; border-radius: 7px; padding: 0;
|
|
95
|
+
display: inline-grid; place-items: center;
|
|
96
|
+
color: var(--dsw-alias-label-secondary, #60636c);
|
|
97
|
+
}
|
|
98
|
+
.dsh-docker-icon-btn:hover { color: var(--dsw-alias-label-primary, #17181c); background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,.045)); }
|
|
99
|
+
.dsh-docker-icon-btn:focus-visible { outline: 2px solid var(--dsw-focus-ring-color, #4d6bfe); outline-offset: 2px; }
|
|
100
|
+
.dsh-docker-icon-btn[disabled] { opacity: .4; cursor: not-allowed; }
|
|
101
|
+
.dsh-docker-icon-btn.dsh-docker-sm { width: 26px; height: 26px; }
|
|
102
|
+
|
|
103
|
+
.dsh-docker-tooltip {
|
|
104
|
+
position: fixed; z-index: 10000; transform: translate(-50%, -100%);
|
|
105
|
+
padding: 5px 8px; border-radius: 6px; pointer-events: none; white-space: nowrap;
|
|
106
|
+
color: var(--dsw-alias-label-primary, #fff); background: var(--dsw-alias-bg-inverse, #23252b);
|
|
107
|
+
font-size: 11px; line-height: 1.2; box-shadow: 0 4px 14px rgba(0,0,0,.18);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.dsh-docker-select, .dsh-docker-input {
|
|
111
|
+
appearance: none; -webkit-appearance: none;
|
|
112
|
+
height: 30px; min-width: 0; padding: 0 9px; border-radius: 7px;
|
|
113
|
+
color: var(--dsw-alias-label-primary, #17181c);
|
|
114
|
+
background: var(--dsw-alias-bg-layer-1, #fff);
|
|
115
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.14));
|
|
116
|
+
font: inherit; font-size: 12.5px;
|
|
117
|
+
}
|
|
118
|
+
.dsh-docker-select { padding-right: 26px; background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: calc(100% - 13px) 13px, calc(100% - 9px) 13px; background-size: 4px 4px, 4px 4px; background-repeat: no-repeat; }
|
|
119
|
+
.dsh-docker-select:focus, .dsh-docker-input:focus { outline: 2px solid var(--dsw-focus-ring-color, #4d6bfe); outline-offset: 1px; border-color: transparent; }
|
|
120
|
+
.dsh-docker-input::placeholder, .dsh-docker-select:disabled { color: var(--dsw-alias-label-tertiary, #8a8d96); }
|
|
121
|
+
.dsh-docker-input[disabled] { opacity: .6; }
|
|
122
|
+
|
|
123
|
+
.dsh-docker-banner {
|
|
124
|
+
flex: none; margin: 12px clamp(20px, 3.5vw, 40px) 0;
|
|
125
|
+
display: flex; align-items: flex-start; gap: 11px;
|
|
126
|
+
padding: 12px 14px; border-radius: 10px;
|
|
127
|
+
background: var(--dsw-alias-bg-layer-1, #fff);
|
|
128
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1));
|
|
129
|
+
}
|
|
130
|
+
.dsh-docker-banner[data-tone=warn] { background: var(--dsw-alias-state-warn-tertiary, rgba(163,95,0,.07)); border-color: transparent; }
|
|
131
|
+
.dsh-docker-banner[data-tone=error] { background: var(--dsw-alias-bg-layer-1, #fff); border-color: var(--dsw-alias-label-error, #d33c3c); }
|
|
132
|
+
.dsh-docker-banner[data-tone=info] { background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
|
133
|
+
.dsh-docker-banner-icon { flex: none; margin-top: 1px; color: var(--dsw-alias-label-secondary, #60636c); }
|
|
134
|
+
.dsh-docker-banner[data-tone=warn] .dsh-docker-banner-icon { color: var(--dsw-alias-state-warn-primary, #a35f00); }
|
|
135
|
+
.dsh-docker-banner[data-tone=error] .dsh-docker-banner-icon { color: var(--dsw-alias-label-error, #d33c3c); }
|
|
136
|
+
.dsh-docker-banner-main { min-width: 0; flex: 1; }
|
|
137
|
+
.dsh-docker-banner-title { font-weight: 600; font-size: 12.5px; }
|
|
138
|
+
.dsh-docker-banner-text { margin-top: 2px; color: var(--dsw-alias-label-secondary, #60636c); font-size: 12px; overflow-wrap: anywhere; }
|
|
139
|
+
.dsh-docker-banner-actions { flex: none; display: flex; align-items: center; gap: 6px; }
|
|
140
|
+
|
|
141
|
+
.dsh-docker-tabs {
|
|
142
|
+
flex: none; display: flex; align-items: center; gap: 2px;
|
|
143
|
+
padding: 8px clamp(20px, 3.5vw, 40px) 0;
|
|
144
|
+
overflow-x: auto;
|
|
145
|
+
border-bottom: 1px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08));
|
|
146
|
+
}
|
|
147
|
+
.dsh-docker-tab {
|
|
148
|
+
appearance: none; border: 0; background: transparent; cursor: pointer;
|
|
149
|
+
display: inline-flex; align-items: center; gap: 6px;
|
|
150
|
+
padding: 8px 10px 9px; margin-bottom: -1px;
|
|
151
|
+
color: var(--dsw-alias-label-secondary, #60636c);
|
|
152
|
+
font: inherit; font-size: 12.5px; white-space: nowrap;
|
|
153
|
+
border-bottom: 2px solid transparent;
|
|
154
|
+
}
|
|
155
|
+
.dsh-docker-tab:hover { color: var(--dsw-alias-label-primary, #17181c); }
|
|
156
|
+
.dsh-docker-tab[aria-selected=true] { color: var(--dsw-alias-label-primary, #17181c); border-bottom-color: var(--dsw-alias-brand-primary, #3156c8); font-weight: 600; }
|
|
157
|
+
.dsh-docker-tab:focus-visible { outline: 2px solid var(--dsw-focus-ring-color, #4d6bfe); outline-offset: -2px; border-radius: 4px; }
|
|
158
|
+
.dsh-docker-tab-count {
|
|
159
|
+
min-width: 17px; height: 17px; padding: 0 5px; border-radius: 9px;
|
|
160
|
+
display: inline-grid; place-items: center;
|
|
161
|
+
font-size: 10.5px; font-weight: 500;
|
|
162
|
+
color: var(--dsw-alias-label-secondary, #60636c);
|
|
163
|
+
background: var(--dsw-alias-bg-layer-2, #f1f2f4);
|
|
164
|
+
}
|
|
165
|
+
.dsh-docker-tab[aria-selected=true] .dsh-docker-tab-count { color: var(--dsw-alias-brand-primary, #3156c8); background: var(--dsw-alias-bg-layer-2, #eef1fb); }
|
|
166
|
+
|
|
167
|
+
.dsh-docker-body { flex: 1; min-height: 0; overflow: auto; padding: 20px clamp(20px, 3.5vw, 40px) 36px; }
|
|
168
|
+
.dsh-docker-body.dsh-docker-body-fill { overflow: hidden; padding-bottom: 20px; display: flex; flex-direction: column; }
|
|
169
|
+
.dsh-docker-stack { display: flex; flex-direction: column; gap: 16px; }
|
|
170
|
+
.dsh-docker-grid-2 { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(260px, 1fr); gap: 16px; align-items: start; }
|
|
171
|
+
.dsh-docker-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
|
|
172
|
+
|
|
173
|
+
.dsh-docker-card {
|
|
174
|
+
min-width: 0; border-radius: 11px;
|
|
175
|
+
background: var(--dsw-alias-bg-layer-1, #fff);
|
|
176
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1));
|
|
177
|
+
box-shadow: var(--dsw-elevation-soft, none);
|
|
178
|
+
}
|
|
179
|
+
.dsh-docker-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 16px 0; }
|
|
180
|
+
.dsh-docker-card-title { margin: 0; font-size: 13px; font-weight: 600; }
|
|
181
|
+
.dsh-docker-card-sub { margin: 3px 0 0; color: var(--dsw-alias-label-tertiary, #8a8d96); font-size: 11.5px; }
|
|
182
|
+
.dsh-docker-card-body { padding: 14px 16px; }
|
|
183
|
+
.dsh-docker-card-body.dsh-docker-flush { padding: 0; }
|
|
184
|
+
|
|
185
|
+
.dsh-docker-stats { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px; }
|
|
186
|
+
.dsh-docker-stat {
|
|
187
|
+
min-width: 0; padding: 13px 14px; border-radius: 10px;
|
|
188
|
+
background: var(--dsw-alias-bg-layer-1, #fff);
|
|
189
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1));
|
|
190
|
+
}
|
|
191
|
+
.dsh-docker-stat-label { display: flex; align-items: center; gap: 6px; color: var(--dsw-alias-label-tertiary, #8a8d96); font-size: 11px; white-space: nowrap; }
|
|
192
|
+
.dsh-docker-stat-value { margin-top: 6px; font-size: 21px; line-height: 25px; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
|
|
193
|
+
.dsh-docker-stat-detail { margin-top: 3px; color: var(--dsw-alias-label-secondary, #60636c); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
194
|
+
|
|
195
|
+
.dsh-docker-runtime-head { display: flex; align-items: center; gap: 9px; }
|
|
196
|
+
.dsh-docker-runtime-name { font-weight: 600; font-size: 14px; }
|
|
197
|
+
.dsh-docker-runtime-tag { margin-left: 2px; }
|
|
198
|
+
.dsh-docker-kv { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 7px 12px; margin-top: 12px; font-size: 12px; }
|
|
199
|
+
.dsh-docker-kv-key { color: var(--dsw-alias-label-tertiary, #8a8d96); white-space: nowrap; }
|
|
200
|
+
.dsh-docker-kv-value { min-width: 0; color: var(--dsw-alias-label-primary, #17181c); overflow-wrap: anywhere; }
|
|
201
|
+
.dsh-docker-middle { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
|
|
202
|
+
|
|
203
|
+
.dsh-docker-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
|
|
204
|
+
.dsh-docker-toolbar-left, .dsh-docker-toolbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
|
|
205
|
+
.dsh-docker-search { position: relative; display: flex; align-items: center; }
|
|
206
|
+
.dsh-docker-search .dsh-docker-input { padding-left: 28px; width: 220px; max-width: 100%; }
|
|
207
|
+
.dsh-docker-search-icon { position: absolute; left: 9px; color: var(--dsw-alias-label-tertiary, #8a8d96); pointer-events: none; }
|
|
208
|
+
.dsh-docker-seg { display: inline-flex; padding: 2px; gap: 2px; border-radius: 7px; background: var(--dsw-alias-bg-layer-2, #f1f2f4); }
|
|
209
|
+
.dsh-docker-seg button { appearance: none; border: 0; cursor: pointer; height: 24px; padding: 0 9px; border-radius: 5px; background: transparent; color: var(--dsw-alias-label-secondary, #60636c); font: inherit; font-size: 12px; }
|
|
210
|
+
.dsh-docker-seg button[aria-pressed=true] { background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #17181c); box-shadow: var(--dsw-elevation-soft, 0 1px 2px rgba(0,0,0,.06)); }
|
|
211
|
+
.dsh-docker-provider-switch { flex: 0 0 auto; }
|
|
212
|
+
.dsh-docker-provider-switch button { height: 30px; padding: 0 10px; font-size: 12px; }
|
|
213
|
+
.dsh-docker-provider-switch button:disabled { cursor: not-allowed; opacity: .55; }
|
|
214
|
+
|
|
215
|
+
.dsh-docker-run-form { display: flex; flex-direction: column; gap: 12px; }
|
|
216
|
+
.dsh-docker-image-picker { display: flex; align-items: center; gap: 6px; }
|
|
217
|
+
.dsh-docker-image-picker .dsh-docker-select { flex: 1; min-width: 0; }
|
|
218
|
+
.dsh-docker-run-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
|
219
|
+
.dsh-docker-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
|
|
220
|
+
.dsh-docker-field > span { font-size: 11.5px; color: var(--dsw-alias-label-secondary, #60636c); }
|
|
221
|
+
.dsh-docker-textarea { height: auto; min-height: 72px; padding: 8px 10px; resize: vertical; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); line-height: 1.5; }
|
|
222
|
+
.dsh-docker-form-error { color: var(--dsw-alias-label-error, #d33c3c); font-size: 12px; }
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
.dsh-docker-table-wrap { overflow: auto; border-radius: 0 0 11px 11px; }
|
|
226
|
+
.dsh-docker-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12px; }
|
|
227
|
+
.dsh-docker-table th {
|
|
228
|
+
position: sticky; top: 0; z-index: 1;
|
|
229
|
+
text-align: left; font-weight: 500; color: var(--dsw-alias-label-tertiary, #8a8d96);
|
|
230
|
+
padding: 9px 12px; background: var(--dsw-alias-bg-layer-1, #fff);
|
|
231
|
+
border-bottom: 1px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08));
|
|
232
|
+
white-space: nowrap;
|
|
233
|
+
}
|
|
234
|
+
.dsh-docker-table td { padding: 10px 12px; vertical-align: middle; border-bottom: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.07)); }
|
|
235
|
+
.dsh-docker-table tbody tr:hover td { background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,.025)); }
|
|
236
|
+
.dsh-docker-table tbody tr:last-child td { border-bottom: 0; }
|
|
237
|
+
.dsh-docker-table .dsh-docker-col-actions { width: 1%; white-space: nowrap; text-align: right; }
|
|
238
|
+
.dsh-docker-table .dsh-docker-col-num { text-align: right; font-variant-numeric: tabular-nums; }
|
|
239
|
+
.dsh-docker-row-title { font-weight: 500; color: var(--dsw-alias-label-primary, #17181c); }
|
|
240
|
+
.dsh-docker-row-actions { display: inline-flex; align-items: center; gap: 2px; justify-content: flex-end; }
|
|
241
|
+
.dsh-docker-mono { font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 11.5px; }
|
|
242
|
+
.dsh-docker-muted { color: var(--dsw-alias-label-tertiary, #8a8d96); }
|
|
243
|
+
.dsh-docker-truncate { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
244
|
+
.dsh-docker-chips { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
245
|
+
.dsh-docker-chip {
|
|
246
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
247
|
+
max-width: 240px; padding: 1px 6px; border-radius: 4px;
|
|
248
|
+
color: var(--dsw-alias-label-secondary, #60636c);
|
|
249
|
+
background: var(--dsw-alias-bg-layer-2, #f4f5f8);
|
|
250
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.07));
|
|
251
|
+
font-size: 10.5px; line-height: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
252
|
+
}
|
|
253
|
+
.dsh-docker-chip.dsh-docker-chip-code { font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); }
|
|
254
|
+
.dsh-docker-state { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; font-size: 11.5px; }
|
|
255
|
+
.dsh-docker-state .dsh-docker-dot { width: 6px; height: 6px; }
|
|
256
|
+
.dsh-docker-state[data-state=running] { color: var(--dsw-alias-state-success-primary, #168a4b); }
|
|
257
|
+
.dsh-docker-state[data-state=paused], .dsh-docker-state[data-state=restarting] { color: var(--dsw-alias-state-warn-primary, #a35f00); }
|
|
258
|
+
.dsh-docker-state[data-state=exited], .dsh-docker-state[data-state=dead] { color: var(--dsw-alias-label-tertiary, #8a8d96); }
|
|
259
|
+
.dsh-docker-state[data-state=dead] { color: var(--dsw-alias-label-error, #d33c3c); }
|
|
260
|
+
|
|
261
|
+
.dsh-docker-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 8px; padding: 52px 20px; }
|
|
262
|
+
.dsh-docker-empty-icon { width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; color: var(--dsw-alias-label-tertiary, #8a8d96); background: var(--dsw-alias-bg-layer-2, #f4f5f8); }
|
|
263
|
+
.dsh-docker-empty-title { font-size: 13px; font-weight: 600; }
|
|
264
|
+
.dsh-docker-empty-text { max-width: 420px; color: var(--dsw-alias-label-tertiary, #8a8d96); font-size: 12px; line-height: 19px; }
|
|
265
|
+
.dsh-docker-error { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 44px 20px; }
|
|
266
|
+
.dsh-docker-error-title { font-weight: 600; color: var(--dsw-alias-label-error, #d33c3c); font-size: 13px; }
|
|
267
|
+
.dsh-docker-error-text { max-width: 560px; color: var(--dsw-alias-label-secondary, #60636c); font-size: 12px; overflow-wrap: anywhere; }
|
|
268
|
+
|
|
269
|
+
.dsh-docker-skeleton { display: flex; flex-direction: column; gap: 9px; padding: 16px; }
|
|
270
|
+
.dsh-docker-skel-line { height: 12px; border-radius: 5px; background: linear-gradient(90deg, var(--dsw-alias-bg-layer-2, #f1f2f4), var(--dsw-alias-bg-layer-3, #e7e9ee), var(--dsw-alias-bg-layer-2, #f1f2f4)); background-size: 200% 100%; animation: dsh-docker-shimmer 1.2s ease-in-out infinite; }
|
|
271
|
+
.dsh-docker-skel-line:nth-child(2) { width: 80%; }
|
|
272
|
+
.dsh-docker-skel-line:nth-child(3) { width: 64%; }
|
|
273
|
+
|
|
274
|
+
.dsh-docker-modal-backdrop {
|
|
275
|
+
position: fixed; inset: 0; z-index: 1000;
|
|
276
|
+
display: grid; place-items: center; padding: 24px;
|
|
277
|
+
background: rgba(12, 14, 20, .32);
|
|
278
|
+
backdrop-filter: blur(2px);
|
|
279
|
+
}
|
|
280
|
+
.dsh-docker-modal {
|
|
281
|
+
width: min(560px, 100%); max-height: min(78vh, 720px);
|
|
282
|
+
display: flex; flex-direction: column;
|
|
283
|
+
border-radius: 13px; overflow: hidden;
|
|
284
|
+
background: var(--dsw-alias-bg-layer-1, #fff);
|
|
285
|
+
border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.12));
|
|
286
|
+
box-shadow: var(--dsw-elevation-prominent, 0 20px 60px rgba(0,0,0,.22));
|
|
287
|
+
}
|
|
288
|
+
.dsh-docker-modal.dsh-docker-modal-wide { width: min(820px, 100%); }
|
|
289
|
+
.dsh-docker-modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 16px 18px 12px; border-bottom: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08)); }
|
|
290
|
+
.dsh-docker-modal-title { margin: 0; font-size: 14px; font-weight: 600; }
|
|
291
|
+
.dsh-docker-modal-sub { margin: 3px 0 0; color: var(--dsw-alias-label-tertiary, #8a8d96); font-size: 11.5px; }
|
|
292
|
+
.dsh-docker-modal-body { min-height: 0; overflow: auto; padding: 16px 18px; }
|
|
293
|
+
.dsh-docker-modal-foot { display: flex; justify-content: flex-end; align-items: center; gap: 8px; padding: 12px 18px; border-top: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08)); background: var(--dsw-alias-bg-layer-1, #fff); }
|
|
294
|
+
.dsh-docker-modal-danger { color: var(--dsw-alias-label-error, #d33c3c); background: var(--dsw-alias-bg-layer-2, #fdf3f3); border-radius: 8px; padding: 10px 12px; font-size: 12px; }
|
|
295
|
+
.dsh-docker-json { margin: 0; max-height: 54vh; overflow: auto; white-space: pre; tab-size: 2; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); font-size: 11.5px; line-height: 1.55; padding: 12px; border-radius: 8px; background: var(--dsw-alias-markdown-code-block, #f6f7f9); border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08)); }
|
|
296
|
+
|
|
297
|
+
.dsh-docker-toast-wrap { position: fixed; right: 18px; bottom: 18px; z-index: 1100; display: flex; flex-direction: column; gap: 8px; max-width: min(420px, calc(100vw - 36px)); }
|
|
298
|
+
.dsh-docker-toast { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px; border-radius: 9px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-primary, #17181c); background: var(--dsw-alias-toast-bg, #fff); box-shadow: var(--dsw-elevation-prominent, 0 8px 30px rgba(0,0,0,.18)); border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1)); animation: dsh-docker-toast-in .16s ease-out; }
|
|
299
|
+
.dsh-docker-toast[data-tone=error] { color: var(--dsw-alias-label-error, #d33c3c); }
|
|
300
|
+
.dsh-docker-toast[data-tone=success] { color: var(--dsw-alias-state-success-primary, #168a4b); }
|
|
301
|
+
.dsh-docker-toast-main { flex: 1; min-width: 0; overflow-wrap: anywhere; }
|
|
302
|
+
|
|
303
|
+
.dsh-docker-console { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 12px; }
|
|
304
|
+
.dsh-docker-console-form { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 11px; background: var(--dsw-alias-bg-layer-1, #fff); border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1)); }
|
|
305
|
+
.dsh-docker-console-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
306
|
+
.dsh-docker-console-prompt { flex: none; color: var(--dsw-alias-label-tertiary, #8a8d96); font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); font-size: 12px; }
|
|
307
|
+
.dsh-docker-console-input { flex: 1; height: 34px; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); font-size: 12.5px; }
|
|
308
|
+
.dsh-docker-console-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
309
|
+
.dsh-docker-console-cwd { flex: 1; min-width: 160px; max-width: 420px; height: 28px; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); font-size: 11.5px; }
|
|
310
|
+
.dsh-docker-console-hint { color: var(--dsw-alias-label-tertiary, #8a8d96); font-size: 11px; }
|
|
311
|
+
.dsh-docker-console-output { flex: 1; min-height: 0; display: flex; flex-direction: column; border-radius: 11px; overflow: hidden; background: var(--dsw-alias-markdown-code-block, #f6f7f9); border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1)); }
|
|
312
|
+
.dsh-docker-output-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 12px; border-bottom: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08)); background: var(--dsw-alias-markdown-code-block-banner, rgba(0,0,0,.025)); }
|
|
313
|
+
.dsh-docker-output-title { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 11.5px; color: var(--dsw-alias-label-secondary, #60636c); }
|
|
314
|
+
.dsh-docker-output-cmd { font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); color: var(--dsw-alias-label-primary, #17181c); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
315
|
+
.dsh-docker-output-actions { display: flex; align-items: center; gap: 4px; flex: none; }
|
|
316
|
+
.dsh-docker-output-pre { flex: 1; min-height: 120px; margin: 0; padding: 12px 14px; overflow: auto; white-space: pre-wrap; word-break: break-word; tab-size: 2; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); font-size: 11.5px; line-height: 1.6; color: var(--dsw-alias-label-primary, #17181c); }
|
|
317
|
+
.dsh-docker-output-pre.dsh-docker-no-output { display: grid; place-items: center; color: var(--dsw-alias-label-tertiary, #8a8d96); font-family: var(--dsw-font-family, sans-serif); font-size: 12px; }
|
|
318
|
+
.dsh-docker-run-status { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 12px; border-top: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.08)); color: var(--dsw-alias-label-secondary, #60636c); font-size: 11.5px; }
|
|
319
|
+
.dsh-docker-run-status .dsh-docker-dot { background: var(--dsw-alias-state-success-primary, #168a4b); }
|
|
320
|
+
.dsh-docker-run-status[data-status=failed] .dsh-docker-dot, .dsh-docker-run-status[data-status=timed-out] .dsh-docker-dot { background: var(--dsw-alias-label-error, #d33c3c); }
|
|
321
|
+
.dsh-docker-run-status[data-status=cancelled] .dsh-docker-dot { background: var(--dsw-alias-label-tertiary, #8a8d96); }
|
|
322
|
+
.dsh-docker-run-status[data-status=exited] .dsh-docker-dot { background: var(--dsw-alias-label-tertiary, #8a8d96); }
|
|
323
|
+
.dsh-docker-attach-status { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 2px 0 8px; }
|
|
324
|
+
.dsh-docker-attach-screen { height: 390px; overflow: auto; border-radius: 8px; border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.12)); background: #111318; color: #e8eaf0; padding: 10px 12px; outline: none; cursor: text; }
|
|
325
|
+
.dsh-docker-attach-screen:focus { border-color: var(--dsw-focus-ring-color, #4d6bfe); box-shadow: 0 0 0 1px var(--dsw-focus-ring-color, #4d6bfe); }
|
|
326
|
+
.dsh-docker-attach-pre { margin: 0; padding: 0; white-space: pre-wrap; word-break: break-word; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); font-size: 12px; line-height: 1.5; }
|
|
327
|
+
.dsh-docker-attach-pre.dsh-docker-no-output { color: rgba(232,234,240,.58); font-family: var(--dsw-font-family, sans-serif); font-size: 12px; }
|
|
328
|
+
.dsh-docker-attach-error { color: #ff9b9b; }
|
|
329
|
+
.dsh-docker-attach-loading { display: flex; align-items: center; gap: 8px; color: rgba(232,234,240,.72); font-size: 12px; padding: 4px; }
|
|
330
|
+
|
|
331
|
+
.dsh-docker-kbd { display: inline-flex; align-items: center; height: 18px; padding: 0 5px; border-radius: 4px; border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.14)); color: var(--dsw-alias-label-tertiary, #8a8d96); font-size: 10px; font-family: var(--dsw-font-family, sans-serif); }
|
|
332
|
+
|
|
333
|
+
.dsh-docker-chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
334
|
+
.dsh-docker-quick { appearance: none; cursor: pointer; border: .5px solid var(--dsw-alias-border-l3, rgba(0,0,0,.1)); background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-secondary, #60636c); border-radius: 6px; padding: 4px 8px; font: inherit; font-size: 11px; font-family: var(--dsw-font-markdown-code-font-family, ui-monospace, Menlo, monospace); }
|
|
335
|
+
.dsh-docker-quick:hover { color: var(--dsw-alias-label-primary, #17181c); background: var(--dsw-alias-interactive-bg-hover, rgba(0,0,0,.04)); }
|
|
336
|
+
.dsh-docker-divider { height: 1px; background: var(--dsw-alias-border-l3, rgba(0,0,0,.08)); margin: 12px 0; }
|
|
337
|
+
.dsh-docker-link { color: var(--dsw-alias-link, #3156c8); text-decoration: none; }
|
|
338
|
+
.dsh-docker-link:hover { text-decoration: underline; }
|
|
339
|
+
|
|
340
|
+
.dsh-docker-spinner { display: inline-block; border-radius: 50%; border: 1.6px solid currentColor; border-right-color: transparent; animation: dsh-docker-spin .75s linear infinite; flex: none; }
|
|
341
|
+
@keyframes dsh-docker-spin { to { transform: rotate(360deg); } }
|
|
342
|
+
@keyframes dsh-docker-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
|
|
343
|
+
@keyframes dsh-docker-toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
|
|
344
|
+
|
|
345
|
+
@media (max-width: 1180px) {
|
|
346
|
+
.dsh-docker-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
347
|
+
.dsh-docker-grid-2 { grid-template-columns: minmax(0, 1fr); }
|
|
348
|
+
}
|
|
349
|
+
@media (max-width: 760px) {
|
|
350
|
+
.dsh-docker-header { flex-direction: column; align-items: stretch; }
|
|
351
|
+
.dsh-docker-header-actions, .dsh-docker-headmeta { justify-content: flex-start; }
|
|
352
|
+
.dsh-docker-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
353
|
+
.dsh-docker-grid-3 { grid-template-columns: minmax(0, 1fr); }
|
|
354
|
+
.dsh-docker-search .dsh-docker-input { width: 100%; }
|
|
355
|
+
.dsh-docker-search { flex: 1; }
|
|
356
|
+
.dsh-docker-truncate { max-width: 200px; }
|
|
357
|
+
}
|
|
358
|
+
@media (prefers-reduced-motion: reduce) {
|
|
359
|
+
.dsh-docker-spinner, .dsh-docker-skel-line, .dsh-docker-toast { animation: none; }
|
|
360
|
+
}
|
|
361
|
+
`
|
|
362
|
+
|
|
363
|
+
export function injectStyles() {
|
|
364
|
+
if (typeof document === 'undefined') return
|
|
365
|
+
if (document.querySelector(`style[data-plugin-css=${JSON.stringify(STYLE_TAG)}]`) !== null) return
|
|
366
|
+
const tag = document.createElement('style')
|
|
367
|
+
tag.dataset.plugin = 'dsh-plugin-container'
|
|
368
|
+
tag.dataset.pluginCss = STYLE_TAG
|
|
369
|
+
tag.textContent = CSS
|
|
370
|
+
document.head.appendChild(tag)
|
|
371
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Compose projects are read-only; the command tab owns lifecycle actions. */
|
|
2
|
+
import { useMemo, useState } from 'react'
|
|
3
|
+
|
|
4
|
+
import { Button, CopyButton, EmptyState, ErrorState, LoadingSkeleton, SearchInput, displayValue } from '../components.jsx'
|
|
5
|
+
import { useDockerList } from '../hooks.js'
|
|
6
|
+
import { IconAlert, IconCompose } from '../icons.jsx'
|
|
7
|
+
|
|
8
|
+
function configList(value) {
|
|
9
|
+
if (typeof value !== 'string' || value.trim() === '') return []
|
|
10
|
+
return value.split(',').map((entry) => entry.trim()).filter(Boolean)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function composeCommand(project) {
|
|
14
|
+
const files = configList(project.configFiles)
|
|
15
|
+
return files.length === 0 ? null : `docker compose -f ${JSON.stringify(files[0])}`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function ComposeTab({ t, api, provider, context, status, refreshToken }) {
|
|
19
|
+
const [search, setSearch] = useState('')
|
|
20
|
+
const enabled = status?.daemon?.state === 'running'
|
|
21
|
+
const list = useDockerList(api, provider, 'compose', context, { refreshToken, enabled })
|
|
22
|
+
const items = list.data?.items ?? []
|
|
23
|
+
const filtered = useMemo(() => {
|
|
24
|
+
const needle = search.trim().toLowerCase()
|
|
25
|
+
return needle === '' ? items : items.filter((item) => `${item.name} ${item.status} ${item.configFiles}`.toLowerCase().includes(needle))
|
|
26
|
+
}, [items, search])
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="dsh-docker-stack">
|
|
30
|
+
<div className="dsh-docker-toolbar">
|
|
31
|
+
<div className="dsh-docker-toolbar-left">
|
|
32
|
+
<SearchInput value={search} onChange={setSearch} placeholder={t('search')} label={t('search')} />
|
|
33
|
+
<span className="dsh-docker-muted">{t('composeReadOnly')}</span>
|
|
34
|
+
</div>
|
|
35
|
+
<div className="dsh-docker-toolbar-right">
|
|
36
|
+
<span className="dsh-docker-muted">{filtered.length} / {items.length}</span>
|
|
37
|
+
<Button size="sm" onClick={list.reload} disabled={list.loading}>{t('refresh')}</Button>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
{!enabled && items.length === 0 ? (
|
|
41
|
+
<EmptyState icon={<IconAlert size={20} />} title={t('daemonStopped')} text={t('daemonStoppedBody')} />
|
|
42
|
+
) : list.loading && list.data === null ? (
|
|
43
|
+
<LoadingSkeleton rows={5} />
|
|
44
|
+
) : list.error !== null && list.data === null ? (
|
|
45
|
+
<ErrorState title={t('listFailed')} text={list.error.message} retryLabel={t('retry')} onRetry={list.reload} />
|
|
46
|
+
) : filtered.length === 0 ? (
|
|
47
|
+
<EmptyState icon={<IconCompose size={20} />} title={search === '' ? t('emptyCompose') : t('emptySearch')} text={search === '' ? t('composeReadOnly') : search} />
|
|
48
|
+
) : (
|
|
49
|
+
<section className="dsh-docker-card">
|
|
50
|
+
<div className="dsh-docker-table-wrap">
|
|
51
|
+
<table className="dsh-docker-table">
|
|
52
|
+
<thead>
|
|
53
|
+
<tr>
|
|
54
|
+
<th>{t('project')}</th>
|
|
55
|
+
<th>{t('status')}</th>
|
|
56
|
+
<th>{t('configFiles')}</th>
|
|
57
|
+
<th className="dsh-docker-col-actions">{t('actions')}</th>
|
|
58
|
+
</tr>
|
|
59
|
+
</thead>
|
|
60
|
+
<tbody>
|
|
61
|
+
{filtered.map((item) => {
|
|
62
|
+
const base = composeCommand(item)
|
|
63
|
+
return (
|
|
64
|
+
<tr key={item.name}>
|
|
65
|
+
<td className="dsh-docker-row-title">{item.name}</td>
|
|
66
|
+
<td>{displayValue(item.status)}</td>
|
|
67
|
+
<td>
|
|
68
|
+
<div className="dsh-docker-chips">
|
|
69
|
+
{configList(item.configFiles).map((file) => (
|
|
70
|
+
<span key={file} className="dsh-docker-chip dsh-docker-chip-code" title={file}>{file}</span>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
</td>
|
|
74
|
+
<td className="dsh-docker-col-actions">
|
|
75
|
+
{base !== null ? (
|
|
76
|
+
<span className="dsh-docker-row-actions">
|
|
77
|
+
<CopyButton text={`${base} up -d`} label="up -d" copiedLabel={t('copied')} className="dsh-docker-btn dsh-docker-sm" />
|
|
78
|
+
<CopyButton text={`${base} down`} label="down" copiedLabel={t('copied')} className="dsh-docker-btn dsh-docker-sm" />
|
|
79
|
+
</span>
|
|
80
|
+
) : (
|
|
81
|
+
<span className="dsh-docker-muted">—</span>
|
|
82
|
+
)}
|
|
83
|
+
</td>
|
|
84
|
+
</tr>
|
|
85
|
+
)
|
|
86
|
+
})}
|
|
87
|
+
</tbody>
|
|
88
|
+
</table>
|
|
89
|
+
</div>
|
|
90
|
+
</section>
|
|
91
|
+
)}
|
|
92
|
+
</div>
|
|
93
|
+
)
|
|
94
|
+
}
|