cdd-cli 3.0.0 → 3.1.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/.github/workflows/ci.yml +29 -0
- package/CHANGELOG.md +27 -0
- package/CODE_OF_CONDUCT.md +12 -0
- package/CONTRIBUTING.md +22 -0
- package/LICENSE +23 -0
- package/README.md +73 -161
- package/SECURITY.md +5 -0
- package/babel.config.cjs +6 -0
- package/dist/App.js +38 -24
- package/dist/cdd.bundle.js +8 -0
- package/dist/components/ContainerCreationPrompt.js +48 -0
- package/dist/components/ContainerCreator.js +81 -0
- package/dist/components/ContainerList.js +24 -4
- package/dist/components/ContainerRow.js +66 -13
- package/dist/components/ContainerSection.js +14 -0
- package/dist/components/Footer.js +10 -0
- package/dist/components/PromptField.js +20 -0
- package/dist/components/UsageMenu.js +8 -0
- package/dist/helpers/actionHelpers.js +0 -1
- package/dist/helpers/dockerActions.js +13 -0
- package/dist/helpers/dockerService/dockerService.js +5 -0
- package/dist/helpers/dockerService/serviceComponents/containerActions.js +163 -0
- package/dist/helpers/dockerService/serviceComponents/containerList.js +57 -0
- package/dist/helpers/dockerService/serviceComponents/containerLogs.js +24 -0
- package/dist/helpers/dockerService/serviceComponents/containerStats.js +50 -0
- package/dist/helpers/dockerService/serviceComponents/imageUtils.js +52 -0
- package/dist/helpers/dockerService.js +111 -0
- package/dist/helpers/validationHelpers.js +26 -0
- package/dist/hooks/creation/useContainerActions.js +171 -0
- package/dist/hooks/creation/useContainerCreation.js +141 -0
- package/dist/hooks/creation/useLogsViewer.js +62 -0
- package/dist/hooks/useContainers.js +11 -1
- package/dist/hooks/useControls.js +298 -78
- package/dist/hooks/useLogsStream.js +1 -1
- package/dist/index.js +11 -0
- package/esbuild.config.cjs +11 -0
- package/jest.config.cjs +6 -0
- package/package.json +10 -6
- package/src/App.jsx +43 -26
- package/src/components/ContainerCreationPrompt.jsx +37 -0
- package/src/components/ContainerList.jsx +23 -6
- package/src/components/ContainerRow.jsx +36 -19
- package/src/components/ContainerSection.jsx +10 -0
- package/src/components/Footer.jsx +10 -0
- package/src/components/PromptField.jsx +18 -0
- package/src/components/UsageMenu.jsx +17 -0
- package/src/helpers/actionHelpers.js +0 -1
- package/src/helpers/dockerService/dockerService.js +3 -0
- package/src/helpers/dockerService/serviceComponents/containerActions.js +52 -0
- package/src/helpers/dockerService/serviceComponents/containerList.js +26 -0
- package/src/helpers/dockerService/serviceComponents/containerLogs.js +19 -0
- package/src/helpers/dockerService/serviceComponents/containerStats.js +34 -0
- package/src/helpers/dockerService/serviceComponents/imageUtils.js +21 -0
- package/src/helpers/validationHelpers.js +16 -0
- package/src/hooks/creation/useContainerActions.js +68 -0
- package/src/hooks/creation/useContainerCreation.js +104 -0
- package/src/hooks/creation/useLogsViewer.js +50 -0
- package/src/hooks/useContainers.js +11 -1
- package/src/hooks/useControls.js +176 -55
- package/src/hooks/useLogsStream.js +1 -1
- package/src/index.js +13 -0
- package/test/validationHelpers.test.js +28 -0
- package/PLAN_KEYBINDINGS_Y_REALTIME.md +0 -260
- package/src/components/StatsViewer.jsx +0 -0
- package/src/helpers/dockerActions.js +0 -39
- package/src/helpers/dockerService.js +0 -88
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
2
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
3
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
4
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
5
|
+
import { docker } from "../dockerService.js";
|
|
6
|
+
export function imageExists(_x) {
|
|
7
|
+
return _imageExists.apply(this, arguments);
|
|
8
|
+
}
|
|
9
|
+
function _imageExists() {
|
|
10
|
+
_imageExists = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(imageName) {
|
|
11
|
+
var images;
|
|
12
|
+
return _regenerator().w(function (_context) {
|
|
13
|
+
while (1) switch (_context.n) {
|
|
14
|
+
case 0:
|
|
15
|
+
_context.n = 1;
|
|
16
|
+
return docker.listImages();
|
|
17
|
+
case 1:
|
|
18
|
+
images = _context.v;
|
|
19
|
+
return _context.a(2, images.some(function (img) {
|
|
20
|
+
return (img.RepoTags || []).includes(imageName) || (img.RepoDigests || []).some(function (d) {
|
|
21
|
+
return d.includes(imageName);
|
|
22
|
+
});
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
}, _callee);
|
|
26
|
+
}));
|
|
27
|
+
return _imageExists.apply(this, arguments);
|
|
28
|
+
}
|
|
29
|
+
export function pullImage(_x2) {
|
|
30
|
+
return _pullImage.apply(this, arguments);
|
|
31
|
+
}
|
|
32
|
+
function _pullImage() {
|
|
33
|
+
_pullImage = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(imageName) {
|
|
34
|
+
return _regenerator().w(function (_context2) {
|
|
35
|
+
while (1) switch (_context2.n) {
|
|
36
|
+
case 0:
|
|
37
|
+
_context2.n = 1;
|
|
38
|
+
return new Promise(function (resolve, reject) {
|
|
39
|
+
docker.pull(imageName, function (err, stream) {
|
|
40
|
+
if (err) return reject(new Error('Error pulling image: ' + err.message));
|
|
41
|
+
docker.modem.followProgress(stream, function (pullErr) {
|
|
42
|
+
if (pullErr) reject(new Error('Error during pull: ' + pullErr.message));else resolve();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
case 1:
|
|
47
|
+
return _context2.a(2);
|
|
48
|
+
}
|
|
49
|
+
}, _callee2);
|
|
50
|
+
}));
|
|
51
|
+
return _pullImage.apply(this, arguments);
|
|
52
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
1
7
|
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
2
8
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
9
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
@@ -8,6 +14,19 @@ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present,
|
|
|
8
14
|
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
9
15
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
10
16
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
17
|
+
/**
|
|
18
|
+
* Utility to interact with Docker CLI.
|
|
19
|
+
* Utilidad para interactuar con el CLI de Docker.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} cmd - Docker command / Comando Docker
|
|
22
|
+
* @returns {Promise<string>} Output from Docker / Salida de Docker
|
|
23
|
+
* @throws {Error} If command fails / Si el comando falla
|
|
24
|
+
* @example
|
|
25
|
+
* // EN: Run a Docker command
|
|
26
|
+
* // ES: Ejecutar un comando Docker
|
|
27
|
+
* await dockerService('ps -a');
|
|
28
|
+
*/
|
|
29
|
+
|
|
11
30
|
import Docker from "dockerode";
|
|
12
31
|
var docker = new Docker({
|
|
13
32
|
socketPath: "/var/run/docker.sock"
|
|
@@ -129,6 +148,17 @@ function _getContainers() {
|
|
|
129
148
|
export function getStats(_x4) {
|
|
130
149
|
return _getStats.apply(this, arguments);
|
|
131
150
|
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Crea un contenedor Docker de forma robusta.
|
|
154
|
+
* - Valida si la imagen existe localmente, si no, la descarga (pull).
|
|
155
|
+
* - Permite opciones adicionales para el contenedor.
|
|
156
|
+
*
|
|
157
|
+
* @param {string} imageName - Nombre de la imagen Docker
|
|
158
|
+
* @param {object} [options] - Opciones adicionales para el contenedor
|
|
159
|
+
* @returns {Promise<string>} ID del contenedor creado
|
|
160
|
+
* @throws {Error} Si falla la creación o el pull de la imagen
|
|
161
|
+
*/
|
|
132
162
|
function _getStats() {
|
|
133
163
|
_getStats = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(containerId) {
|
|
134
164
|
var container, stream, cpuDelta, systemDelta, cpuPercent, memUsage, memLimit, memPercent, rx, tx;
|
|
@@ -170,4 +200,85 @@ function _getStats() {
|
|
|
170
200
|
}, _callee5);
|
|
171
201
|
}));
|
|
172
202
|
return _getStats.apply(this, arguments);
|
|
203
|
+
}
|
|
204
|
+
export function createContainer(_x5) {
|
|
205
|
+
return _createContainer.apply(this, arguments);
|
|
206
|
+
}
|
|
207
|
+
function _createContainer() {
|
|
208
|
+
_createContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(imageName) {
|
|
209
|
+
var options,
|
|
210
|
+
imageExists,
|
|
211
|
+
images,
|
|
212
|
+
createOpts,
|
|
213
|
+
container,
|
|
214
|
+
_args6 = arguments,
|
|
215
|
+
_t,
|
|
216
|
+
_t2,
|
|
217
|
+
_t3;
|
|
218
|
+
return _regenerator().w(function (_context6) {
|
|
219
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
220
|
+
case 0:
|
|
221
|
+
options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
|
|
222
|
+
// Verifica si la imagen existe localmente
|
|
223
|
+
imageExists = false;
|
|
224
|
+
_context6.p = 1;
|
|
225
|
+
_context6.n = 2;
|
|
226
|
+
return docker.listImages();
|
|
227
|
+
case 2:
|
|
228
|
+
images = _context6.v;
|
|
229
|
+
imageExists = images.some(function (img) {
|
|
230
|
+
return (img.RepoTags || []).includes(imageName) || (img.RepoDigests || []).some(function (d) {
|
|
231
|
+
return d.includes(imageName);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
_context6.n = 4;
|
|
235
|
+
break;
|
|
236
|
+
case 3:
|
|
237
|
+
_context6.p = 3;
|
|
238
|
+
_t = _context6.v;
|
|
239
|
+
throw new Error('Error al listar imágenes locales: ' + _t.message);
|
|
240
|
+
case 4:
|
|
241
|
+
if (imageExists) {
|
|
242
|
+
_context6.n = 8;
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
_context6.p = 5;
|
|
246
|
+
_context6.n = 6;
|
|
247
|
+
return new Promise(function (resolve, reject) {
|
|
248
|
+
docker.pull(imageName, function (err, stream) {
|
|
249
|
+
if (err) return reject(new Error('Error al hacer pull de la imagen: ' + err.message));
|
|
250
|
+
docker.modem.followProgress(stream, function (pullErr) {
|
|
251
|
+
if (pullErr) reject(new Error('Error durante el pull: ' + pullErr.message));else resolve();
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
case 6:
|
|
256
|
+
_context6.n = 8;
|
|
257
|
+
break;
|
|
258
|
+
case 7:
|
|
259
|
+
_context6.p = 7;
|
|
260
|
+
_t2 = _context6.v;
|
|
261
|
+
throw new Error('No se pudo descargar la imagen: ' + _t2.message);
|
|
262
|
+
case 8:
|
|
263
|
+
// Opciones por defecto y merge con las recibidas
|
|
264
|
+
createOpts = _objectSpread({
|
|
265
|
+
Image: imageName,
|
|
266
|
+
Tty: true
|
|
267
|
+
}, options);
|
|
268
|
+
_context6.p = 9;
|
|
269
|
+
_context6.n = 10;
|
|
270
|
+
return docker.createContainer(createOpts);
|
|
271
|
+
case 10:
|
|
272
|
+
container = _context6.v;
|
|
273
|
+
return _context6.a(2, container.id || container.Id);
|
|
274
|
+
case 11:
|
|
275
|
+
_context6.p = 11;
|
|
276
|
+
_t3 = _context6.v;
|
|
277
|
+
throw new Error('Error al crear el contenedor: ' + _t3.message);
|
|
278
|
+
case 12:
|
|
279
|
+
return _context6.a(2);
|
|
280
|
+
}
|
|
281
|
+
}, _callee6, null, [[9, 11], [5, 7], [1, 3]]);
|
|
282
|
+
}));
|
|
283
|
+
return _createContainer.apply(this, arguments);
|
|
173
284
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
// Reusable validations for ports and environment variables
|
|
8
|
+
|
|
9
|
+
export function validatePorts(portInput) {
|
|
10
|
+
var ports = portInput.split(",").map(function (p) {
|
|
11
|
+
return p.trim();
|
|
12
|
+
}).filter(Boolean);
|
|
13
|
+
if (ports.length === 0) return false;
|
|
14
|
+
var invalid = ports.find(function (pair) {
|
|
15
|
+
var _pair$split = pair.split(":"),
|
|
16
|
+
_pair$split2 = _slicedToArray(_pair$split, 2),
|
|
17
|
+
host = _pair$split2[0],
|
|
18
|
+
cont = _pair$split2[1];
|
|
19
|
+
return !host || !cont || isNaN(Number(host)) || isNaN(Number(cont));
|
|
20
|
+
});
|
|
21
|
+
return !invalid;
|
|
22
|
+
}
|
|
23
|
+
export function validateEnvVars(envInput) {
|
|
24
|
+
// Future specific validations
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
2
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
3
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
4
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
5
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
6
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
7
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
8
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
9
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
10
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
11
|
+
import { useState } from "react";
|
|
12
|
+
import { startContainer as svcStartContainer, stopContainer as svcStopContainer, restartContainer as svcRestartContainer, removeContainer as svcRemoveContainer } from "../../helpers/dockerService/serviceComponents/containerActions.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Custom hook to manage container actions (start, stop, restart, remove).
|
|
16
|
+
* Handles feedback messages and exposes helpers for each action.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} params
|
|
19
|
+
* @param {Array} params.containers - List of containers
|
|
20
|
+
* @param {Function} params.onAction - Callback after action is performed
|
|
21
|
+
* @returns {Object} Action helpers and feedback state
|
|
22
|
+
*/
|
|
23
|
+
export function useContainerActions(_ref) {
|
|
24
|
+
var containers = _ref.containers,
|
|
25
|
+
onAction = _ref.onAction;
|
|
26
|
+
var _useState = useState(""),
|
|
27
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
28
|
+
message = _useState2[0],
|
|
29
|
+
setMessage = _useState2[1];
|
|
30
|
+
var _useState3 = useState("yellow"),
|
|
31
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
32
|
+
messageColor = _useState4[0],
|
|
33
|
+
setMessageColor = _useState4[1];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Handles a generic container action and sets feedback.
|
|
37
|
+
* @param {Function} actionFn - The async action function (start, stop, etc)
|
|
38
|
+
* @param {string} actionLabel - Action label for feedback
|
|
39
|
+
* @param {number} selected - Index of selected container
|
|
40
|
+
* @param {Function} [stateCheck] - Optional function to check state before action
|
|
41
|
+
*/
|
|
42
|
+
function handleAction(_x) {
|
|
43
|
+
return _handleAction.apply(this, arguments);
|
|
44
|
+
}
|
|
45
|
+
function _handleAction() {
|
|
46
|
+
_handleAction = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(_ref2) {
|
|
47
|
+
var actionFn, actionLabel, selected, stateCheck, container, checkMsg, _t;
|
|
48
|
+
return _regenerator().w(function (_context5) {
|
|
49
|
+
while (1) switch (_context5.p = _context5.n) {
|
|
50
|
+
case 0:
|
|
51
|
+
actionFn = _ref2.actionFn, actionLabel = _ref2.actionLabel, selected = _ref2.selected, stateCheck = _ref2.stateCheck;
|
|
52
|
+
container = containers[selected];
|
|
53
|
+
if (container) {
|
|
54
|
+
_context5.n = 1;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
return _context5.a(2);
|
|
58
|
+
case 1:
|
|
59
|
+
if (!stateCheck) {
|
|
60
|
+
_context5.n = 2;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
checkMsg = stateCheck(container);
|
|
64
|
+
if (!checkMsg) {
|
|
65
|
+
_context5.n = 2;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
setMessage(checkMsg);
|
|
69
|
+
setMessageColor("yellow");
|
|
70
|
+
return _context5.a(2);
|
|
71
|
+
case 2:
|
|
72
|
+
setMessage("".concat(actionLabel, " container..."));
|
|
73
|
+
setMessageColor("yellow");
|
|
74
|
+
_context5.p = 3;
|
|
75
|
+
_context5.n = 4;
|
|
76
|
+
return actionFn(container.id);
|
|
77
|
+
case 4:
|
|
78
|
+
setMessage("".concat(actionLabel, " container successful."));
|
|
79
|
+
setMessageColor("green");
|
|
80
|
+
if (onAction) onAction();
|
|
81
|
+
_context5.n = 6;
|
|
82
|
+
break;
|
|
83
|
+
case 5:
|
|
84
|
+
_context5.p = 5;
|
|
85
|
+
_t = _context5.v;
|
|
86
|
+
setMessage("Failed to ".concat(actionLabel.toLowerCase(), " container: ").concat(_t.message));
|
|
87
|
+
setMessageColor("red");
|
|
88
|
+
case 6:
|
|
89
|
+
return _context5.a(2);
|
|
90
|
+
}
|
|
91
|
+
}, _callee5, null, [[3, 5]]);
|
|
92
|
+
}));
|
|
93
|
+
return _handleAction.apply(this, arguments);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
message: message,
|
|
97
|
+
setMessage: setMessage,
|
|
98
|
+
messageColor: messageColor,
|
|
99
|
+
setMessageColor: setMessageColor,
|
|
100
|
+
handleAction: handleAction,
|
|
101
|
+
// Expose concrete actions so callers can use actions.startContainer(id)
|
|
102
|
+
startContainer: function () {
|
|
103
|
+
var _startContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(id) {
|
|
104
|
+
return _regenerator().w(function (_context) {
|
|
105
|
+
while (1) switch (_context.n) {
|
|
106
|
+
case 0:
|
|
107
|
+
_context.n = 1;
|
|
108
|
+
return svcStartContainer(id);
|
|
109
|
+
case 1:
|
|
110
|
+
return _context.a(2, _context.v);
|
|
111
|
+
}
|
|
112
|
+
}, _callee);
|
|
113
|
+
}));
|
|
114
|
+
function startContainer(_x2) {
|
|
115
|
+
return _startContainer.apply(this, arguments);
|
|
116
|
+
}
|
|
117
|
+
return startContainer;
|
|
118
|
+
}(),
|
|
119
|
+
stopContainer: function () {
|
|
120
|
+
var _stopContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(id) {
|
|
121
|
+
return _regenerator().w(function (_context2) {
|
|
122
|
+
while (1) switch (_context2.n) {
|
|
123
|
+
case 0:
|
|
124
|
+
_context2.n = 1;
|
|
125
|
+
return svcStopContainer(id);
|
|
126
|
+
case 1:
|
|
127
|
+
return _context2.a(2, _context2.v);
|
|
128
|
+
}
|
|
129
|
+
}, _callee2);
|
|
130
|
+
}));
|
|
131
|
+
function stopContainer(_x3) {
|
|
132
|
+
return _stopContainer.apply(this, arguments);
|
|
133
|
+
}
|
|
134
|
+
return stopContainer;
|
|
135
|
+
}(),
|
|
136
|
+
restartContainer: function () {
|
|
137
|
+
var _restartContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(id) {
|
|
138
|
+
return _regenerator().w(function (_context3) {
|
|
139
|
+
while (1) switch (_context3.n) {
|
|
140
|
+
case 0:
|
|
141
|
+
_context3.n = 1;
|
|
142
|
+
return svcRestartContainer(id);
|
|
143
|
+
case 1:
|
|
144
|
+
return _context3.a(2, _context3.v);
|
|
145
|
+
}
|
|
146
|
+
}, _callee3);
|
|
147
|
+
}));
|
|
148
|
+
function restartContainer(_x4) {
|
|
149
|
+
return _restartContainer.apply(this, arguments);
|
|
150
|
+
}
|
|
151
|
+
return restartContainer;
|
|
152
|
+
}(),
|
|
153
|
+
removeContainer: function () {
|
|
154
|
+
var _removeContainer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(id) {
|
|
155
|
+
return _regenerator().w(function (_context4) {
|
|
156
|
+
while (1) switch (_context4.n) {
|
|
157
|
+
case 0:
|
|
158
|
+
_context4.n = 1;
|
|
159
|
+
return svcRemoveContainer(id);
|
|
160
|
+
case 1:
|
|
161
|
+
return _context4.a(2, _context4.v);
|
|
162
|
+
}
|
|
163
|
+
}, _callee4);
|
|
164
|
+
}));
|
|
165
|
+
function removeContainer(_x5) {
|
|
166
|
+
return _removeContainer.apply(this, arguments);
|
|
167
|
+
}
|
|
168
|
+
return removeContainer;
|
|
169
|
+
}()
|
|
170
|
+
};
|
|
171
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { validatePorts, validateEnvVars } from "../../helpers/validationHelpers.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook to manage the container creation flow, step by step.
|
|
12
|
+
* Handles input, validation, and feedback for each creation step.
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} params
|
|
15
|
+
* @param {Function} params.onCreate - Callback when creation is confirmed
|
|
16
|
+
* @param {Function} params.onCancel - Callback when creation is cancelled
|
|
17
|
+
* @param {Array<string>} params.dbImages - List of DB image names for env var warning
|
|
18
|
+
* @returns {Object} Creation state, setters, and helpers
|
|
19
|
+
*/
|
|
20
|
+
export function useContainerCreation(_ref) {
|
|
21
|
+
var onCreate = _ref.onCreate,
|
|
22
|
+
onCancel = _ref.onCancel,
|
|
23
|
+
_ref$dbImages = _ref.dbImages,
|
|
24
|
+
dbImages = _ref$dbImages === void 0 ? [] : _ref$dbImages;
|
|
25
|
+
var _useState = useState(0),
|
|
26
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
27
|
+
step = _useState2[0],
|
|
28
|
+
setStep = _useState2[1]; // 0: image, 1: name, 2: ports, 3: env
|
|
29
|
+
var _useState3 = useState(""),
|
|
30
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
31
|
+
imageName = _useState4[0],
|
|
32
|
+
setImageName = _useState4[1];
|
|
33
|
+
var _useState5 = useState(""),
|
|
34
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
35
|
+
containerName = _useState6[0],
|
|
36
|
+
setContainerName = _useState6[1];
|
|
37
|
+
var _useState7 = useState(""),
|
|
38
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
39
|
+
portInput = _useState8[0],
|
|
40
|
+
setPortInput = _useState8[1];
|
|
41
|
+
var _useState9 = useState(""),
|
|
42
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
43
|
+
envInput = _useState0[0],
|
|
44
|
+
setEnvInput = _useState0[1];
|
|
45
|
+
var _useState1 = useState(""),
|
|
46
|
+
_useState10 = _slicedToArray(_useState1, 2),
|
|
47
|
+
message = _useState10[0],
|
|
48
|
+
setMessage = _useState10[1];
|
|
49
|
+
var _useState11 = useState("yellow"),
|
|
50
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
51
|
+
messageColor = _useState12[0],
|
|
52
|
+
setMessageColor = _useState12[1];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Advances to the next step, with validation and feedback.
|
|
56
|
+
*/
|
|
57
|
+
function nextStep() {
|
|
58
|
+
if (step === 0) {
|
|
59
|
+
if (!imageName.trim()) {
|
|
60
|
+
setMessage("Image name cannot be empty.");
|
|
61
|
+
setMessageColor("red");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
setStep(1);
|
|
65
|
+
setMessage("Optional: Enter container name or leave empty and press Enter");
|
|
66
|
+
setMessageColor("yellow");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (step === 1) {
|
|
70
|
+
setStep(2);
|
|
71
|
+
setMessage("Optional: Enter ports (format 8080:80,443:443) or leave empty and press Enter");
|
|
72
|
+
setMessageColor("yellow");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (step === 2) {
|
|
76
|
+
if (!portInput.trim()) {
|
|
77
|
+
setMessage("You must specify at least one port to expose (e.g. 8080:80)");
|
|
78
|
+
setMessageColor("red");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!validatePorts(portInput)) {
|
|
82
|
+
setMessage("Port format must be host:container and both must be numbers (e.g. 8080:80)");
|
|
83
|
+
setMessageColor("red");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setStep(3);
|
|
87
|
+
var isDb = dbImages.some(function (db) {
|
|
88
|
+
return imageName.trim().toLowerCase().includes(db);
|
|
89
|
+
});
|
|
90
|
+
if (isDb) {
|
|
91
|
+
setMessage("Warning: This image usually requires environment variables (e.g. MYSQL_ROOT_PASSWORD=my-secret-pw for MySQL, POSTGRES_PASSWORD=yourpassword for Postgres). Enter them as VAR=val,VAR2=val2 or leave empty and press Enter.");
|
|
92
|
+
setMessageColor("yellow");
|
|
93
|
+
} else {
|
|
94
|
+
setMessage("Optional: Enter environment variables (format VAR1=val1,VAR2=val2) or leave empty and press Enter");
|
|
95
|
+
setMessageColor("yellow");
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (step === 3) {
|
|
100
|
+
// Final step: call onCreate with all data
|
|
101
|
+
onCreate({
|
|
102
|
+
imageName: imageName,
|
|
103
|
+
containerName: containerName,
|
|
104
|
+
portInput: portInput,
|
|
105
|
+
envInput: envInput
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Cancels the creation process and resets state.
|
|
112
|
+
*/
|
|
113
|
+
function cancelCreation() {
|
|
114
|
+
setStep(0);
|
|
115
|
+
setImageName("");
|
|
116
|
+
setContainerName("");
|
|
117
|
+
setPortInput("");
|
|
118
|
+
setEnvInput("");
|
|
119
|
+
setMessage("");
|
|
120
|
+
setMessageColor("yellow");
|
|
121
|
+
if (onCancel) onCancel();
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
step: step,
|
|
125
|
+
setStep: setStep,
|
|
126
|
+
imageName: imageName,
|
|
127
|
+
setImageName: setImageName,
|
|
128
|
+
containerName: containerName,
|
|
129
|
+
setContainerName: setContainerName,
|
|
130
|
+
portInput: portInput,
|
|
131
|
+
setPortInput: setPortInput,
|
|
132
|
+
envInput: envInput,
|
|
133
|
+
setEnvInput: setEnvInput,
|
|
134
|
+
message: message,
|
|
135
|
+
setMessage: setMessage,
|
|
136
|
+
messageColor: messageColor,
|
|
137
|
+
setMessageColor: setMessageColor,
|
|
138
|
+
nextStep: nextStep,
|
|
139
|
+
cancelCreation: cancelCreation
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
import { useState, useRef } from "react";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Custom hook to manage the logs viewer state and stream reference.
|
|
11
|
+
* Handles showing/hiding logs and storing log lines.
|
|
12
|
+
*
|
|
13
|
+
* @returns {Object} Logs viewer state and helpers
|
|
14
|
+
* @property {boolean} showLogs - Whether the logs viewer is open
|
|
15
|
+
* @property {function} setShowLogs - Setter for showLogs
|
|
16
|
+
* @property {Array<string>} logs - Array of log lines
|
|
17
|
+
* @property {function} setLogs - Setter for logs
|
|
18
|
+
* @property {object} logsStreamRef - Ref to the logs stream (for cleanup)
|
|
19
|
+
* @property {function} openLogs - Helper to open logs for a container
|
|
20
|
+
* @property {function} closeLogs - Helper to close logs and cleanup
|
|
21
|
+
*/
|
|
22
|
+
export function useLogsViewer() {
|
|
23
|
+
var _useState = useState(false),
|
|
24
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
25
|
+
showLogs = _useState2[0],
|
|
26
|
+
setShowLogs = _useState2[1];
|
|
27
|
+
var _useState3 = useState([]),
|
|
28
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
29
|
+
logs = _useState4[0],
|
|
30
|
+
setLogs = _useState4[1];
|
|
31
|
+
var logsStreamRef = useRef(null);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Opens the logs viewer and resets logs.
|
|
35
|
+
*/
|
|
36
|
+
function openLogs() {
|
|
37
|
+
setShowLogs(true);
|
|
38
|
+
setLogs([]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Closes the logs viewer and cleans up the stream.
|
|
43
|
+
*/
|
|
44
|
+
function closeLogs() {
|
|
45
|
+
setShowLogs(false);
|
|
46
|
+
setLogs([]);
|
|
47
|
+
if (logsStreamRef.current) {
|
|
48
|
+
var _logsStreamRef$curren, _logsStreamRef$curren2;
|
|
49
|
+
(_logsStreamRef$curren = (_logsStreamRef$curren2 = logsStreamRef.current).destroy) === null || _logsStreamRef$curren === void 0 || _logsStreamRef$curren.call(_logsStreamRef$curren2);
|
|
50
|
+
logsStreamRef.current = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
showLogs: showLogs,
|
|
55
|
+
setShowLogs: setShowLogs,
|
|
56
|
+
logs: logs,
|
|
57
|
+
setLogs: setLogs,
|
|
58
|
+
logsStreamRef: logsStreamRef,
|
|
59
|
+
openLogs: openLogs,
|
|
60
|
+
closeLogs: closeLogs
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -8,8 +8,18 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
|
|
|
8
8
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
9
9
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
10
10
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
11
|
+
/**
|
|
12
|
+
* React hook to manage Docker containers state.
|
|
13
|
+
* Hook de React para gestionar el estado de contenedores Docker.
|
|
14
|
+
*
|
|
15
|
+
* @returns {[Array, Function]} [containers, refresh] / [contenedores, refrescar]
|
|
16
|
+
* @example
|
|
17
|
+
* // EN: Use in a component
|
|
18
|
+
* // ES: Usar en un componente
|
|
19
|
+
* const [containers, refresh] = useContainers();
|
|
20
|
+
*/
|
|
11
21
|
import React, { useState, useEffect } from "react";
|
|
12
|
-
import { getContainers } from "../helpers/dockerService.js";
|
|
22
|
+
import { getContainers } from "../helpers/dockerService/serviceComponents/containerList.js";
|
|
13
23
|
export function useContainers() {
|
|
14
24
|
var _useState = useState([]),
|
|
15
25
|
_useState2 = _slicedToArray(_useState, 2),
|