@jfvilas/plugin-kwirth-fileman 0.13.10 → 0.14.1

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/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # Backstage frontend KwirthFileman plugin
2
- This package is a Backstage frontend plugin for **managing Kubernetes containers' filesystems** in real-time via Kwirth.
2
+ This package is a Backstage frontend plugin for **managing Kubernetes containers' filesystems visually** in real-time via Kwirth.
3
3
 
4
- This Backstage plugin allows you to use a file-explorer-like plugin for navigating through the filesystem, allowing users to examine the content, and also perform file operations like rename, delete, copy, move, copy/cut/paste...
4
+ KwirthFileman plugin allows you to use a file-explorer-like plugin for navigating through the filesystem, allowing users to examine the content, and also perform file operations like rename, delete, copy, move, copy/cut/paste...
5
5
 
6
6
  In addtion users can also download files (or folders), upload files and even preview file content.
7
7
 
8
8
  - You need to install the Kwirth [Backstage backend plugin](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend).
9
9
  - You need to install Kwirth on your Kubernetes cluster, that is, this plugin is just another frontend for [Kwirth](https://jfvilas.github.io/kwirth).
10
10
 
11
- Kwirth is a really-easy-to-use data-exporting system for Kubernetes that runs in only one pod (*no database is needed*). Refer to Kwirth GitHub project for [info on installation](https://github.com/jfvilas/kwirth?tab=readme-ov-file#installation). Kwirth installation is *one command away* from you.
11
+ Kwirth is a really-easy-to-use data-exporting system for Kubernetes that runs in only one pod (*no database is needed*), in your Desktop with a GUI or in a Docker container. Refer to Kwirth GitHub project for [info on installation](https://github.com/jfvilas/kwirth?tab=readme-ov-file#installation). Kwirth installation is *one command away* from you.
12
12
 
13
13
  You can access [Kwirth project here](https://github.com/jfvilas/kwirth).
14
14
 
@@ -18,22 +18,22 @@ Following table shows version compatibility between this Kwirth Backstage plugin
18
18
 
19
19
  | Plugin Kwirth version | Kwirth version |
20
20
  |-|-|
21
- |0.13.5|0.4.131|
21
+ |0.14.1|0.5.21|
22
22
 
23
23
 
24
24
  ## What is this plugin for?
25
- This Backstage plugin adds Backstage a feature for working with Kubernetes containers filesystems and manage container data as user would do with a Gnome, the Windows file explorer or an Apple file manager.
25
+ This Backstage plugin adds Backstage a powerful feature for working with Kubernetes containers' filesystems and manage container data as users would do with a Gnome, the Windows file explorer or an Apple file manager.
26
26
 
27
27
  When KwirthFileman is correctly installed and configured, it is possible to manage Kubernetes containers filesystems like this:
28
28
 
29
29
  ![kwirth-running](https://raw.githubusercontent.com/jfvilas/plugin-kwirth-fileman/master/images/kwirthfileman-running.png)
30
30
 
31
- This frontend plugin includes just the visualization of filesystems. All needed configuration, and specially **permission settings**, are done in the backend plugin and the app-config.yaml. You can restrict access to pods, namespaces, clusters, etc... by configuring permissions to be applied on the backend plugin.
31
+ This frontend plugin includes the visualization of filesystems. All needed configuration, and specially **permission settings**, are done in the backend plugin and the app-config.yaml. You can restrict access to pods, namespaces, clusters, containers, etc... by configuring permissions to be applied on the backend plugin.
32
32
 
33
33
  ## How does it work?
34
34
  Let's explain this by following a user working sequence:
35
35
 
36
- 1. A Backstage user searchs for an entity in the Backstage.
36
+ 1. A Backstage user searchs for an entity in the Backstage instance.
37
37
  2. In the entity page there will be a new tab named 'KWIRTHFILEMAN'.
38
38
  3. When the user clicks on KWIRTHFILEMAN the frontend plugin sends a request to the backend Kwirth plugin asking for containers information on all Kubernetes clusters available.
39
39
  4. Next step is to identify the Kubernetes objects that match requested entity. As well as it occurs with other Backstage Kwirth plugins, Kwirth implements two strategies for getting the list of kubernetes objects that match:
@@ -43,7 +43,7 @@ Let's explain this by following a user working sequence:
43
43
  6. With the final pod list, the backend plugin sends requests to the Kwirth instances on the clusters asking for API Keys specific for accessing containers filesystems.
44
44
  7. With all this information, the backend builds a unique response containing all the pods the user have access to, and all the API keys needed to access the filesystems.
45
45
 
46
- If everyting is correctly configured and tagged, the user should see a list of clusters. When selecting a cluster, the user should see a control for starting and stoppingthe file system browser. When th euser clicks PLAY (on the right upper side), the file browser appears.
46
+ If everyting is correctly configured and tagged, the user should see a list of clusters. When selecting a cluster, the user should see a control for starting and stopping the file system browser. When the user clicks PLAY (on the right upper side), the file browser appears.
47
47
 
48
48
 
49
49
  ## Installation
@@ -51,22 +51,19 @@ It's very simple and straightforward, it is in fact very similar to any other fr
51
51
 
52
52
  1. Install corresponding Backstage backend plugin [more information here](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend).
53
53
  2. Install this Backstage frontend plugin:
54
-
55
- ```sh
56
- # From your Backstage root directory
57
- yarn --cwd packages/app add @jfvilas/plugin-kwirth-fileman @jfvilas/plugin-kwirth-frontend @jfvilas/plugin-kwirth-common @jfvilas/kwirth-common
58
- ```
59
-
54
+ ```sh
55
+ # From your Backstage root directory
56
+ yarn --cwd packages/app add @jfvilas/plugin-kwirth-fileman @jfvilas/plugin-kwirth-frontend @jfvilas/plugin-kwirth-common @jfvilas/kwirth-common
57
+ ```
60
58
  3. Make sure the [Kwirth backend plugin](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend#configure) is installed and configured.
61
-
62
59
  4. Restart your Backstage instance.
63
60
 
64
61
 
65
62
  ## Configuration: Entity Pages
66
63
  For Kwirth plugin to be usable on the frontend, you must tailor your Entity Page to include the Kwirth components.
67
64
 
68
- #### 1. Add the plugin as a tab in your Entity pages:
69
65
 
66
+ #### 1. Add the plugin as a tab in your Entity pages:
70
67
  Firstly, import the plugin module.
71
68
 
72
69
  ```typescript
@@ -109,11 +106,11 @@ Use one of these strategies:
109
106
 
110
107
  - **Strategy 1: one-to-one**. Add `backstage.io/kubernetes-id` annotation to your `catalog-info.yaml` for the entities deployed to Kubernetes you want to work with on Backstage. This is the same annotation that the Kubernetes core plugin uses, so, maybe you already have added it to your components. Exmaple:
111
108
 
112
- ```yaml
113
- metadata:
114
- annotations:
115
- backstage.io/kubernetes-id: entity001
116
- ```
109
+ ```yaml
110
+ metadata:
111
+ annotations:
112
+ backstage.io/kubernetes-id: entity001
113
+ ```
117
114
 
118
115
  - **Strategy 2: use selectors**. Add `backstage.io/kubernetes-label-selector` annotation to your `catalog-info.yaml` for the entities you want to work with. This is the same annotation that the Kubernetes core plugin uses, so, maybe you already have added it to your components. The label selector value follows Kubernetes [label selector semantics](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/). Example:
119
116
 
@@ -6,7 +6,7 @@ import { useApi, alertApiRef } from '@backstage/core-plugin-api';
6
6
  import { isKwirthAvailable, ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR, getPodList, getContainerList } from '@jfvilas/plugin-kwirth-common';
7
7
  import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
8
8
  import { kwirthFilemanApiRef } from '../api/types.esm.js';
9
- import { SignalMessageLevelEnum, accessKeySerialize, InstanceMessageTypeEnum, InstanceMessageActionEnum, InstanceMessageFlowEnum, InstanceConfigViewEnum, InstanceConfigObjectEnum, SignalMessageEventEnum } from '@jfvilas/kwirth-common';
9
+ import { ESignalMessageLevel, accessKeySerialize, EInstanceMessageType, EInstanceMessageAction, EInstanceMessageFlow, EInstanceConfigView, EInstanceConfigObject, ESignalMessageEvent } from '@jfvilas/kwirth-common';
10
10
  import { ComponentNotFound, ErrorType, ClusterList, KwirthNews, StatusLog } from '@jfvilas/plugin-kwirth-frontend';
11
11
  import { FileManager } from '@jfvilas/react-file-manager';
12
12
  import { VERSION } from '../version.esm.js';
@@ -48,7 +48,7 @@ const EntityKwirthFilemanContent = (props) => {
48
48
  const [statusMessages, setStatusMessages] = useState([]);
49
49
  const [webSocket, setWebSocket] = useState();
50
50
  const [showStatusDialog, setShowStatusDialog] = useState(false);
51
- const [statusLevel, setStatusLevel] = useState(SignalMessageLevelEnum.INFO);
51
+ const [statusLevel, setStatusLevel] = useState(ESignalMessageLevel.INFO);
52
52
  const [backendVersion, setBackendVersion] = useState("");
53
53
  const [backendInfo, setBackendInfo] = useState();
54
54
  const instance = useRef();
@@ -64,6 +64,7 @@ const EntityKwirthFilemanContent = (props) => {
64
64
  });
65
65
  const filemanBoxRef = useRef(null);
66
66
  const [filemanBoxTop, setFilemanBoxTop] = useState(0);
67
+ const [runningInstance, setRunningInstance] = useState();
67
68
  let permissions = {
68
69
  create: true,
69
70
  delete: true,
@@ -85,7 +86,7 @@ const EntityKwirthFilemanContent = (props) => {
85
86
  let accessKey = cluster.accessKeys.get("fileman$read");
86
87
  if (accessKey) {
87
88
  fileUploadConfig = {
88
- url: `${cluster.url}/channel/fileman/upload?key=${instance.current}`,
89
+ url: `${cluster.url}/${runningInstance}/channel/fileman/upload?key=${instance.current}`,
89
90
  method: "POST",
90
91
  headers: {
91
92
  "Authorization": "Bearer " + accessKeySerialize(accessKey)
@@ -165,10 +166,10 @@ const EntityKwirthFilemanContent = (props) => {
165
166
  const processFilemanMessage = (wsEvent) => {
166
167
  let msg = JSON.parse(wsEvent.data);
167
168
  switch (msg.type) {
168
- case InstanceMessageTypeEnum.DATA: {
169
+ case EInstanceMessageType.DATA: {
169
170
  let response = JSON.parse(wsEvent.data);
170
171
  switch (response.action) {
171
- case InstanceMessageActionEnum.COMMAND:
172
+ case EInstanceMessageAction.COMMAND:
172
173
  {
173
174
  switch (response.command) {
174
175
  case "home" /* HOME */:
@@ -215,13 +216,13 @@ const EntityKwirthFilemanContent = (props) => {
215
216
  }
216
217
  setStateFiles([...files.current]);
217
218
  } else {
218
- addMessage(SignalMessageLevelEnum.ERROR, content.text || content.message);
219
+ addMessage(ESignalMessageLevel.ERROR, content.text || content.message);
219
220
  }
220
221
  break;
221
222
  case "rename" /* RENAME */:
222
223
  {
223
224
  let content2 = JSON.parse(response.data);
224
- if (content2.status !== "Success") addMessage(SignalMessageLevelEnum.ERROR, content2.text || content2.message);
225
+ if (content2.status !== "Success") addMessage(ESignalMessageLevel.ERROR, content2.text || content2.message);
225
226
  }
226
227
  break;
227
228
  case "delete" /* DELETE */: {
@@ -232,7 +233,7 @@ const EntityKwirthFilemanContent = (props) => {
232
233
  files.current = files.current.filter((f) => !f.path.startsWith(fname + "/"));
233
234
  setStateFiles([...files.current]);
234
235
  } else {
235
- addMessage(SignalMessageLevelEnum.ERROR, content2.text || content2.message);
236
+ addMessage(ESignalMessageLevel.ERROR, content2.text || content2.message);
236
237
  }
237
238
  break;
238
239
  }
@@ -252,7 +253,7 @@ const EntityKwirthFilemanContent = (props) => {
252
253
  files.current.push(f);
253
254
  setStateFiles([...files.current]);
254
255
  } else {
255
- addMessage(SignalMessageLevelEnum.ERROR, content2.text || content2.message);
256
+ addMessage(ESignalMessageLevel.ERROR, content2.text || content2.message);
256
257
  }
257
258
  break;
258
259
  }
@@ -262,26 +263,44 @@ const EntityKwirthFilemanContent = (props) => {
262
263
  }
263
264
  break;
264
265
  }
265
- case InstanceMessageTypeEnum.SIGNAL:
266
+ case EInstanceMessageType.SIGNAL:
266
267
  let signalMessage = JSON.parse(wsEvent.data);
267
- if (signalMessage.flow === InstanceMessageFlowEnum.RESPONSE) {
268
- if (signalMessage.action === InstanceMessageActionEnum.START) {
269
- if (signalMessage.text) addMessage(SignalMessageLevelEnum.INFO, signalMessage.text);
270
- instance.current = signalMessage.instance;
271
- } else {
272
- addMessage(SignalMessageLevelEnum.ERROR, wsEvent.data);
268
+ if (signalMessage.flow === EInstanceMessageFlow.RESPONSE) {
269
+ switch (signalMessage.action) {
270
+ case EInstanceMessageAction.START:
271
+ if (signalMessage.text) addMessage(ESignalMessageLevel.INFO, signalMessage.text);
272
+ instance.current = signalMessage.instance;
273
+ break;
274
+ case EInstanceMessageAction.RI:
275
+ setRunningInstance(signalMessage.data);
276
+ console.log(signalMessage.data);
277
+ break;
278
+ case EInstanceMessageAction.COMMAND:
279
+ if (signalMessage.text) addMessage(signalMessage.level, signalMessage.text);
280
+ break;
281
+ default:
282
+ addMessage(ESignalMessageLevel.ERROR, wsEvent.data);
283
+ break;
273
284
  }
274
- } else if (signalMessage.flow === InstanceMessageFlowEnum.UNSOLICITED) {
285
+ } else if (signalMessage.flow === EInstanceMessageFlow.UNSOLICITED) {
275
286
  let cluster2 = validClusters.find((cluster3) => cluster3.name === selectedClusterName);
276
287
  if (cluster2) {
277
288
  let accessKey = cluster2.accessKeys.get("fileman$read");
278
289
  if (accessKey && instance?.current) {
279
- if (signalMessage.event === SignalMessageEventEnum.ADD) {
290
+ if (signalMessage.event === ESignalMessageEvent.ADD) {
291
+ let instanceConfig = {
292
+ action: EInstanceMessageAction.RI,
293
+ channel: "fileman",
294
+ flow: EInstanceMessageFlow.REQUEST,
295
+ type: EInstanceMessageType.SIGNAL,
296
+ instance: instance.current
297
+ };
298
+ wsEvent.target.send(JSON.stringify(instanceConfig));
280
299
  let filemanMessage = {
281
- flow: InstanceMessageFlowEnum.REQUEST,
282
- action: InstanceMessageActionEnum.COMMAND,
300
+ flow: EInstanceMessageFlow.REQUEST,
301
+ action: EInstanceMessageAction.COMMAND,
283
302
  channel: "fileman",
284
- type: InstanceMessageTypeEnum.DATA,
303
+ type: EInstanceMessageType.DATA,
285
304
  accessKey: accessKeySerialize(accessKey),
286
305
  instance: instance.current,
287
306
  id: v4(),
@@ -295,13 +314,13 @@ const EntityKwirthFilemanContent = (props) => {
295
314
  };
296
315
  let payload = JSON.stringify(filemanMessage);
297
316
  wsEvent.target.send(payload);
298
- if (signalMessage.text) addMessage(SignalMessageLevelEnum.INFO, signalMessage.text);
317
+ if (signalMessage.text) addMessage(ESignalMessageLevel.INFO, signalMessage.text);
299
318
  }
300
319
  } else {
301
- addMessage(SignalMessageLevelEnum.INFO, "Have no instance/accessKey");
320
+ addMessage(ESignalMessageLevel.INFO, "Have no instance/accessKey");
302
321
  }
303
322
  } else {
304
- addMessage(SignalMessageLevelEnum.INFO, "Have no cluster");
323
+ addMessage(ESignalMessageLevel.INFO, "Have no cluster");
305
324
  }
306
325
  }
307
326
  break;
@@ -315,7 +334,7 @@ const EntityKwirthFilemanContent = (props) => {
315
334
  setStatusMessages((prev) => [...prev, {
316
335
  level: level2,
317
336
  text,
318
- type: InstanceMessageTypeEnum.SIGNAL
337
+ type: EInstanceMessageType.SIGNAL
319
338
  }]);
320
339
  };
321
340
  const websocketOnMessage = (wsEvent) => {
@@ -332,8 +351,8 @@ const EntityKwirthFilemanContent = (props) => {
332
351
  processFilemanMessage(wsEvent);
333
352
  break;
334
353
  default:
335
- addMessage(SignalMessageLevelEnum.ERROR, "Invalid channel in message: " + instanceMessage.channel);
336
- addMessage(SignalMessageLevelEnum.ERROR, "Invalid message: " + JSON.stringify(instanceMessage));
354
+ addMessage(ESignalMessageLevel.ERROR, "Invalid channel in message: " + instanceMessage.channel);
355
+ addMessage(ESignalMessageLevel.ERROR, "Invalid message: " + JSON.stringify(instanceMessage));
337
356
  break;
338
357
  }
339
358
  };
@@ -341,12 +360,12 @@ const EntityKwirthFilemanContent = (props) => {
341
360
  setWebSocket(ws);
342
361
  let cluster2 = validClusters.find((cluster3) => cluster3.name === selectedClusterName);
343
362
  if (!cluster2) {
344
- addMessage(SignalMessageLevelEnum.ERROR, "No cluster selected");
363
+ addMessage(ESignalMessageLevel.ERROR, "No cluster selected");
345
364
  return;
346
365
  }
347
366
  let pods = cluster2.pods.filter((p2) => selectedNamespaces.includes(p2.namespace));
348
367
  if (!pods) {
349
- addMessage(SignalMessageLevelEnum.ERROR, "No pods found");
368
+ addMessage(ESignalMessageLevel.ERROR, "No pods found");
350
369
  return;
351
370
  }
352
371
  console.log(`WS connected`);
@@ -362,30 +381,30 @@ const EntityKwirthFilemanContent = (props) => {
362
381
  }
363
382
  let iConfig = {
364
383
  channel: "fileman",
365
- objects: InstanceConfigObjectEnum.PODS,
366
- action: InstanceMessageActionEnum.START,
367
- flow: InstanceMessageFlowEnum.REQUEST,
384
+ objects: EInstanceConfigObject.PODS,
385
+ action: EInstanceMessageAction.START,
386
+ flow: EInstanceMessageFlow.REQUEST,
368
387
  instance: "",
369
388
  accessKey: accessKeySerialize(accessKey),
370
389
  scope: "fileman$read",
371
- view: selectedContainerNames.length > 0 ? InstanceConfigViewEnum.CONTAINER : InstanceConfigViewEnum.POD,
390
+ view: selectedContainerNames.length > 0 ? EInstanceConfigView.CONTAINER : EInstanceConfigView.POD,
372
391
  namespace: selectedNamespaces.join(","),
373
392
  group: "",
374
393
  pod: selectedPodNames.map((p2) => p2).join(","),
375
394
  container: containers.join(","),
376
395
  data: {},
377
- type: InstanceMessageTypeEnum.SIGNAL
396
+ type: EInstanceMessageType.SIGNAL
378
397
  };
379
398
  ws.send(JSON.stringify(iConfig));
380
399
  } else {
381
- addMessage(SignalMessageLevelEnum.ERROR, "No accessKey for starting fileman streaming");
400
+ addMessage(ESignalMessageLevel.ERROR, "No accessKey for starting fileman streaming");
382
401
  return;
383
402
  }
384
403
  };
385
404
  const startFilemanViewer = () => {
386
405
  let cluster2 = validClusters.find((cluster3) => cluster3.name === selectedClusterName);
387
406
  if (!cluster2) {
388
- addMessage(SignalMessageLevelEnum.ERROR, "No cluster selected");
407
+ addMessage(ESignalMessageLevel.ERROR, "No cluster selected");
389
408
  return;
390
409
  }
391
410
  try {
@@ -422,14 +441,14 @@ const EntityKwirthFilemanContent = (props) => {
422
441
  const prepareText = (txt) => {
423
442
  return txt ? txt.length > 25 ? txt.substring(0, 25) + "..." : txt : "N/A";
424
443
  };
425
- return /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "row" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, prepareText(title))), /* @__PURE__ */ React.createElement(Grid, { item: true, style: { marginTop: "-8px" } }, /* @__PURE__ */ React.createElement(IconButton, { title: "info", disabled: !statusMessages.some((m) => m.type === InstanceMessageTypeEnum.SIGNAL && m.level === SignalMessageLevelEnum.INFO), onClick: () => show(SignalMessageLevelEnum.INFO) }, /* @__PURE__ */ React.createElement(InfoIcon, { style: { color: statusMessages.some((m) => m.type === InstanceMessageTypeEnum.SIGNAL && m.level === SignalMessageLevelEnum.INFO) ? "blue" : "#BDBDBD" } })), /* @__PURE__ */ React.createElement(IconButton, { title: "warning", disabled: !statusMessages.some((m) => m.type === InstanceMessageTypeEnum.SIGNAL && m.level === SignalMessageLevelEnum.WARNING), onClick: () => show(SignalMessageLevelEnum.WARNING), style: { marginLeft: "-16px" } }, /* @__PURE__ */ React.createElement(WarningIcon, { style: { color: statusMessages.some((m) => m.type === InstanceMessageTypeEnum.SIGNAL && m.level === SignalMessageLevelEnum.WARNING) ? "orange" : "#BDBDBD" } })), /* @__PURE__ */ React.createElement(IconButton, { title: "error", disabled: !statusMessages.some((m) => m.type === InstanceMessageTypeEnum.SIGNAL && m.level === SignalMessageLevelEnum.ERROR), onClick: () => show(SignalMessageLevelEnum.ERROR), style: { marginLeft: "-16px" } }, /* @__PURE__ */ React.createElement(ErrorIcon, { style: { color: statusMessages.some((m) => m.type === InstanceMessageTypeEnum.SIGNAL && m.level === SignalMessageLevelEnum.ERROR) ? "red" : "#BDBDBD" } }))));
444
+ return /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "row" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, prepareText(title))), /* @__PURE__ */ React.createElement(Grid, { item: true, style: { marginTop: "-8px" } }, /* @__PURE__ */ React.createElement(IconButton, { title: "info", disabled: !statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.INFO), onClick: () => show(ESignalMessageLevel.INFO) }, /* @__PURE__ */ React.createElement(InfoIcon, { style: { color: statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.INFO) ? "blue" : "#BDBDBD" } })), /* @__PURE__ */ React.createElement(IconButton, { title: "warning", disabled: !statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.WARNING), onClick: () => show(ESignalMessageLevel.WARNING), style: { marginLeft: "-16px" } }, /* @__PURE__ */ React.createElement(WarningIcon, { style: { color: statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.WARNING) ? "orange" : "#BDBDBD" } })), /* @__PURE__ */ React.createElement(IconButton, { title: "error", disabled: !statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.ERROR), onClick: () => show(ESignalMessageLevel.ERROR), style: { marginLeft: "-16px" } }, /* @__PURE__ */ React.createElement(ErrorIcon, { style: { color: statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.ERROR) ? "red" : "#BDBDBD" } }))));
426
445
  };
427
446
  const statusClear = (level2) => {
428
447
  setStatusMessages(statusMessages.filter((m) => m.level !== level2));
429
448
  setShowStatusDialog(false);
430
449
  };
431
450
  const onError = (error2, _file) => {
432
- addMessage(SignalMessageLevelEnum.ERROR, error2.message);
451
+ addMessage(ESignalMessageLevel.ERROR, error2.message);
433
452
  };
434
453
  const onRename = (file, newName) => {
435
454
  let [namespace, pod, container] = file.path.split("/").slice(1);
@@ -452,10 +471,10 @@ const EntityKwirthFilemanContent = (props) => {
452
471
  if (accessKey && instance?.current && webSocket) {
453
472
  let [namespace, pod, container] = folder.split("/").slice(1);
454
473
  let filemanMessage = {
455
- flow: InstanceMessageFlowEnum.REQUEST,
456
- action: InstanceMessageActionEnum.COMMAND,
474
+ flow: EInstanceMessageFlow.REQUEST,
475
+ action: EInstanceMessageAction.COMMAND,
457
476
  channel: "fileman",
458
- type: InstanceMessageTypeEnum.DATA,
477
+ type: EInstanceMessageType.DATA,
459
478
  accessKey: accessKeySerialize(accessKey),
460
479
  instance: instance.current,
461
480
  id: v4(),
@@ -478,10 +497,10 @@ const EntityKwirthFilemanContent = (props) => {
478
497
  let accessKey = cluster2.accessKeys.get("fileman$read");
479
498
  if (accessKey && instance?.current && webSocket) {
480
499
  let filemanMessage = {
481
- flow: InstanceMessageFlowEnum.REQUEST,
482
- action: InstanceMessageActionEnum.COMMAND,
500
+ flow: EInstanceMessageFlow.REQUEST,
501
+ action: EInstanceMessageAction.COMMAND,
483
502
  channel: "fileman",
484
- type: InstanceMessageTypeEnum.DATA,
503
+ type: EInstanceMessageType.DATA,
485
504
  accessKey: accessKeySerialize(accessKey),
486
505
  instance: instance.current,
487
506
  id: v4(),
@@ -496,10 +515,10 @@ const EntityKwirthFilemanContent = (props) => {
496
515
  let payload = JSON.stringify(filemanMessage);
497
516
  webSocket.send(payload);
498
517
  } else {
499
- addMessage(SignalMessageLevelEnum.ERROR, "Have no instance/accessKey");
518
+ addMessage(ESignalMessageLevel.ERROR, "Have no instance/accessKey");
500
519
  }
501
520
  } else {
502
- addMessage(SignalMessageLevelEnum.ERROR, "Have no cluster");
521
+ addMessage(ESignalMessageLevel.ERROR, "Have no cluster");
503
522
  }
504
523
  };
505
524
  const onDelete = async (filesToDelete) => {
@@ -518,7 +537,7 @@ const EntityKwirthFilemanContent = (props) => {
518
537
  let accessKey = cluster2.accessKeys.get("fileman$read");
519
538
  if (accessKey) {
520
539
  for (let file of filesToDownload) {
521
- const url = `${cluster2.url}/channel/fileman/download?key=${instance.current}&filename=${file.path}`;
540
+ const url = `${cluster2.url}/${runningInstance}/channel/fileman/download?key=${instance.current}&filename=${file.path}`;
522
541
  try {
523
542
  const response = await fetch(url, { headers: { "Authorization": "Bearer " + accessKeySerialize(accessKey) } });
524
543
  if (response.ok) {
@@ -533,18 +552,18 @@ const EntityKwirthFilemanContent = (props) => {
533
552
  URL.revokeObjectURL(link.href);
534
553
  } else {
535
554
  console.error(`Error downloading file: ${file.path}`);
536
- addMessage(SignalMessageLevelEnum.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`);
555
+ addMessage(ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`);
537
556
  }
538
557
  } catch (error2) {
539
558
  console.error(`Error downloading file: ${file.path}`, error2);
540
- addMessage(SignalMessageLevelEnum.ERROR, `Error downloading file ${file.path}: ${error2}`);
559
+ addMessage(ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: ${error2}`);
541
560
  }
542
561
  }
543
562
  } else {
544
- addMessage(SignalMessageLevelEnum.ERROR, "Have no instance/accessKey");
563
+ addMessage(ESignalMessageLevel.ERROR, "Have no instance/accessKey");
545
564
  }
546
565
  } else {
547
- addMessage(SignalMessageLevelEnum.ERROR, "Have no cluster");
566
+ addMessage(ESignalMessageLevel.ERROR, "Have no cluster");
548
567
  }
549
568
  };
550
569
  const onPaste = (filesToPaste, destFolder, operation) => {
@@ -593,7 +612,9 @@ const EntityKwirthFilemanContent = (props) => {
593
612
  onDownload,
594
613
  enableFilePreview: false,
595
614
  initialPath: "",
596
- permissions
615
+ permissions,
616
+ maxNavigationPaneLevel: 3,
617
+ showBreadcrumb: true
597
618
  }
598
619
  ))))), showStatusDialog && /* @__PURE__ */ React.createElement(StatusLog, { level: statusLevel, onClose: () => setShowStatusDialog(false), statusMessages, onClear: statusClear }));
599
620
  };
@@ -1 +1 @@
1
- {"version":3,"file":"EntityKwirthFilemanContent.esm.js","sources":["../../src/components/EntityKwirthFilemanContent.tsx"],"sourcesContent":["/*\r\nCopyright 2025 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React, { useEffect, useRef, useState } from 'react'\r\nimport { v4 as uuid } from 'uuid'\r\nimport useAsync from 'react-use/esm/useAsync'\r\n\r\nimport { Progress, WarningPanel } from '@backstage/core-components'\r\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api'\r\nimport { ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR, isKwirthAvailable, ClusterValidPods, IStatusLine, getPodList, getContainerList, IBackendInfo } from '@jfvilas/plugin-kwirth-common'\r\nimport { MissingAnnotationEmptyState, useEntity } from '@backstage/plugin-catalog-react'\r\n\r\n// kwirth\r\nimport { kwirthFilemanApiRef } from '../api'\r\nimport { accessKeySerialize, InstanceMessageActionEnum, InstanceConfigViewEnum, IInstanceMessage, InstanceMessageTypeEnum, SignalMessageLevelEnum, InstanceConfigObjectEnum, IInstanceConfig, InstanceMessageFlowEnum, SignalMessageEventEnum, ISignalMessage } from '@jfvilas/kwirth-common'\r\n\r\n// kwirth fileman components\r\nimport { KwirthNews, ComponentNotFound, StatusLog, ClusterList, ErrorType } from '@jfvilas/plugin-kwirth-frontend'\r\nimport { FileManager, IError, IFileData } from '@jfvilas/react-file-manager'\r\nimport { VERSION } from '../version'\r\n\r\n// Material-UI\r\nimport { Grid, Card, CardHeader, Box, IconButton, Typography } from '@material-ui/core'\r\n\r\n// styles\r\nimport '@jfvilas/react-file-manager/dist/style.css'\r\nimport styles from './custom-fm.module.css'\r\n\r\n// Icons\r\nimport PlayIcon from '@material-ui/icons/PlayArrow'\r\nimport PauseIcon from '@material-ui/icons/Pause'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport WarningIcon from '@material-ui/icons/Warning'\r\nimport ErrorIcon from '@material-ui/icons/Error'\r\nimport LogoIcon from '../assets/kwirthfileman-logo.svg'\r\nimport SvgIconNamespace from'./icons/ns.svg'\r\nimport SvgIconPod from'./icons/pod.svg'\r\nimport SvgIconContainer from'./icons/docker-mark-blue.svg'\r\n\r\nexport interface IEntityKwirthFilemanProps {\r\n hideVersion?: boolean\r\n excludeContainers?: string[]\r\n}\r\n\r\n\r\nconst NamespaceIcon = (props: {height?:number}) => { return <img src={SvgIconNamespace} alt='ns' height={`${props.height||16}px`}/> }\r\nconst PodIcon = (props: {height?:number}) => { return <img src={SvgIconPod} alt='pod' height={`${props.height||16}px`}/> }\r\nconst ContainerIcon = (props: {height?:number}) => { return <img src={SvgIconContainer} height={`${props.height||16}px`}/> }\r\n\r\nexport const EntityKwirthFilemanContent: React.FC<IEntityKwirthFilemanProps> = (props:IEntityKwirthFilemanProps) => { \r\n const { entity } = useEntity()\r\n const kwirthFilemanApi = useApi(kwirthFilemanApiRef)\r\n const alertApi = useApi(alertApiRef)\r\n const [validClusters, setResources] = useState<ClusterValidPods[]>([])\r\n const [selectedClusterName, setSelectedClusterName] = useState('')\r\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([])\r\n const [selectedPodNames, setSelectedPodNames] = useState<string[]>([])\r\n const [selectedContainerNames, setSelectedContainerNames] = useState<string[]>([])\r\n const [started, setStarted] = useState(false)\r\n const [stopped, setStopped] = useState(true)\r\n const paused=useRef<boolean>(false)\r\n const [statusMessages, setStatusMessages] = useState<IStatusLine[]>([])\r\n const [webSocket, setWebSocket] = useState<WebSocket>()\r\n const [showStatusDialog, setShowStatusDialog] = useState(false)\r\n const [statusLevel, setStatusLevel] = useState<SignalMessageLevelEnum>(SignalMessageLevelEnum.INFO)\r\n const [ backendVersion, setBackendVersion ] = useState<string>('')\r\n const [ backendInfo, setBackendInfo ] = useState<IBackendInfo>()\r\n const instance = useRef<string>()\r\n const [ stateFiles, setStateFiles ] = useState<IFileData[]>([])\r\n const files = useRef<IFileData[]>([])\r\n const [ currentPath, setCurrentPath] = useState('')\r\n const { loading, error } = useAsync ( async () => {\r\n if (backendVersion==='') setBackendVersion(await kwirthFilemanApi.getVersion())\r\n if (!backendInfo) setBackendInfo(await kwirthFilemanApi.getInfo())\r\n let reqScopes = ['fileman$read']\r\n let data:ClusterValidPods[] = await kwirthFilemanApi.requestAccess(entity, 'fileman', reqScopes)\r\n setResources(data)\r\n })\r\n const filemanBoxRef = useRef<HTMLDivElement | null>(null)\r\n const [filemanBoxTop, setFilemanBoxTop] = useState(0)\r\n let permissions={\r\n create: true,\r\n delete: true,\r\n download: true,\r\n copy: true,\r\n move: true,\r\n rename: true,\r\n upload: true\r\n }\r\n\r\n let icons = new Map()\r\n icons.set('namespace', { open:<NamespaceIcon height={18}/>, closed:<NamespaceIcon height={18}/>, grid:<NamespaceIcon height={40}/>, list:<NamespaceIcon height={18}/>, default:<NamespaceIcon height={18}/> })\r\n icons.set('pod', { open:<PodIcon height={18}/>, closed:<PodIcon height={18}/>, grid:<PodIcon height={40}/>, list:<PodIcon height={18}/>, default:<PodIcon height={18}/> })\r\n icons.set('container', { open:<ContainerIcon/>, closed:<ContainerIcon/>, grid:<ContainerIcon height={34}/>, list:<ContainerIcon height={16}/>, default:<ContainerIcon height={16}/> })\r\n\r\n interface IFileUploadConfig { \r\n url: string\r\n method?: \"POST\" | \"PUT\"\r\n headers?: { [key: string]: string }\r\n }\r\n let fileUploadConfig:IFileUploadConfig= {\r\n url: ''\r\n }\r\n\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n fileUploadConfig = {\r\n url: `${cluster.url}/channel/fileman/upload?key=${instance.current}`,\r\n method:'POST',\r\n headers: {\r\n 'Authorization': 'Bearer '+ accessKeySerialize(accessKey)\r\n }\r\n }\r\n }\r\n }\r\n \r\n let level = currentPath.split('/').length - 1\r\n if (level<3) {\r\n permissions = {\r\n create: false,\r\n delete: false,\r\n download: false,\r\n copy: false,\r\n move: false,\r\n rename: false,\r\n upload: false\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (filemanBoxRef.current) setFilemanBoxTop(filemanBoxRef.current.getBoundingClientRect().top)\r\n })\r\n\r\n const clickStart = () => {\r\n if (!paused.current) {\r\n setStarted(true)\r\n paused.current=false\r\n setStopped(false)\r\n startFilemanViewer()\r\n }\r\n else {\r\n paused.current=false\r\n setStarted(true)\r\n }\r\n }\r\n\r\n const onClickPause = () => {\r\n setStarted(false)\r\n paused.current=true\r\n }\r\n\r\n const onClickStop = () => {\r\n setStarted(false)\r\n setStopped(true)\r\n paused.current=false\r\n stopFilemanViewer()\r\n }\r\n\r\n const onSelectCluster = (clusterName:string|undefined) => {\r\n if (started) onClickStop()\r\n if (clusterName) {\r\n setSelectedClusterName(clusterName)\r\n setSelectedPodNames([])\r\n setSelectedContainerNames([])\r\n setStatusMessages([])\r\n let cluster = validClusters.find(cluster => cluster.name === clusterName)\r\n\r\n if (cluster && cluster.pods) {\r\n let validNamespaces = Array.from(new Set(cluster.pods.map(pod => pod.namespace)))\r\n if (validNamespaces.length === 1) {\r\n setSelectedNamespaces(validNamespaces)\r\n let podList = getPodList (cluster.pods, validNamespaces)\r\n setSelectedPodNames(podList.map(pod => pod.name))\r\n setSelectedContainerNames(getContainerList(cluster.pods, validNamespaces, podList.map(pod => pod.name), props.excludeContainers || []))\r\n }\r\n else {\r\n setSelectedNamespaces([])\r\n }\r\n }\r\n }\r\n }\r\n\r\n enum FilemanCommandEnum {\r\n HOME = 'home',\r\n DIR = 'dir',\r\n CREATE = 'create',\r\n RENAME = 'rename',\r\n DELETE = 'delete',\r\n MOVE = 'move',\r\n COPY = 'copy',\r\n UPLOAD = 'upload',\r\n DOWNLOAD = 'download'\r\n }\r\n\r\n interface IFilemanMessage extends IInstanceMessage {\r\n msgtype: 'filemanmessage'\r\n id: string\r\n accessKey: string\r\n instance: string\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n command: FilemanCommandEnum\r\n params?: string[]\r\n }\r\n\r\n interface IFilemanMessageResponse extends IInstanceMessage {\r\n msgtype: 'filemanmessageresponse'\r\n id: string\r\n command: FilemanCommandEnum\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n data?: any\r\n }\r\n\r\n const processFilemanMessage = (wsEvent:any) => {\r\n let msg:IFilemanMessage = JSON.parse(wsEvent.data)\r\n\r\n switch (msg.type) {\r\n case InstanceMessageTypeEnum.DATA: {\r\n let response = JSON.parse(wsEvent.data) as IFilemanMessageResponse\r\n switch(response.action) {\r\n case InstanceMessageActionEnum.COMMAND: {\r\n switch(response.command) {\r\n case FilemanCommandEnum.HOME:\r\n let data = response.data as string[]\r\n let nss = Array.from (new Set (data.map(n => n.split('/')[0])))\r\n nss.map(ns => {\r\n if (!files.current.some(f => f.path === '/'+ ns)) {\r\n files.current.push ({ name: ns, isDirectory: true, path: '/'+ ns, class:'namespace' }) \r\n }\r\n let podNames = Array.from (new Set (data.filter(a => a.split('/')[0]===ns).map(o => o.split('/')[1])))\r\n podNames.map(p => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p)) {\r\n files.current.push ({ name: p, isDirectory: true, path: '/'+ns+'/'+p, class:'pod' })\r\n }\r\n let containers = Array.from (new Set (data.filter(a => a.split('/')[0]===ns && a.split('/')[1]===p).map(o => o.split('/')[2])))\r\n containers = containers.filter(c => !props.excludeContainers?.includes(c))\r\n containers.map(c => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p+'/'+c)) {\r\n files.current.push ({ name: c, isDirectory: true, path: '/'+ns+'/'+p+'/'+c, class:'container' })\r\n }\r\n })\r\n })\r\n })\r\n setStateFiles([...files.current])\r\n break\r\n case FilemanCommandEnum.DIR:\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n for (let o of content.metadata.object) {\r\n let name = o.name.split('/')[o.name.split('/').length-1]\r\n let e = {\r\n name,\r\n isDirectory: (o.type===1),\r\n path: o.name,\r\n updatedAt: new Date(+o.time).toISOString(),\r\n size: +o.size,\r\n ...(o.type===0? {class:'file'}:{})\r\n }\r\n let i = files.current.findIndex(f => f.path === e.path)\r\n if (i>=0)\r\n files.current[i]=e\r\n else\r\n files.current.push(e)\r\n }\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.RENAME: {\r\n let content = JSON.parse(response.data)\r\n if (content.status!=='Success') addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.DELETE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n let fname = content.metadata.object\r\n files.current = files.current.filter(f => f.path !== fname)\r\n files.current = files.current.filter(f => !f.path.startsWith(fname+'/'))\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n case FilemanCommandEnum.MOVE:\r\n case FilemanCommandEnum.COPY:\r\n case FilemanCommandEnum.CREATE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n //filemanData.files = filemanData.files.filter(f => f.path !== content.metadata.object)\r\n let f = { \r\n name: (content.metadata.object as string).split('/').slice(-1)[0],\r\n isDirectory: (content.metadata.type===1),\r\n path: content.metadata.object,\r\n updatedAt: new Date(+content.metadata.time).toISOString(), \r\n size: +content.metadata.size,\r\n ...(content.metadata.type.type===0? {class:'file'}:{})\r\n }\r\n files.current.push(f)\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n }\r\n }\r\n break\r\n }\r\n break\r\n }\r\n case InstanceMessageTypeEnum.SIGNAL:\r\n let signalMessage = JSON.parse(wsEvent.data) as ISignalMessage\r\n if (signalMessage.flow === InstanceMessageFlowEnum.RESPONSE) {\r\n if (signalMessage.action === InstanceMessageActionEnum.START) {\r\n if (signalMessage.text) addMessage(SignalMessageLevelEnum.INFO, signalMessage.text)\r\n instance.current = signalMessage.instance\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, wsEvent.data)\r\n }\r\n }\r\n else if (signalMessage.flow === InstanceMessageFlowEnum.UNSOLICITED) {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current) {\r\n if (signalMessage.event === SignalMessageEventEnum.ADD) {\r\n let filemanMessage:IFilemanMessage = {\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n action: InstanceMessageActionEnum.COMMAND,\r\n channel: 'fileman',\r\n type: InstanceMessageTypeEnum.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.HOME,\r\n namespace: signalMessage.namespace!,\r\n group: '',\r\n pod: signalMessage.pod!,\r\n container: signalMessage.container!,\r\n params: [],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n wsEvent.target.send(payload)\r\n if (signalMessage.text) addMessage( SignalMessageLevelEnum.INFO, signalMessage.text)\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.INFO, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.INFO, 'Have no cluster')\r\n }\r\n }\r\n break\r\n\r\n default:\r\n console.log(`Invalid message type ${msg.type}`)\r\n break\r\n }\r\n }\r\n\r\n const addMessage = (level:SignalMessageLevelEnum, text:string) => {\r\n alertApi.post({ message: text, severity: level, display:'transient' }) \r\n setStatusMessages ((prev) => [...prev, {\r\n level,\r\n text,\r\n type: InstanceMessageTypeEnum.SIGNAL,\r\n }])\r\n }\r\n\r\n const websocketOnMessage = (wsEvent:any) => {\r\n let instanceMessage:IInstanceMessage\r\n try {\r\n instanceMessage = JSON.parse(wsEvent.data) as IInstanceMessage\r\n }\r\n catch (err) {\r\n console.log(err)\r\n console.log(wsEvent.data)\r\n return\r\n }\r\n\r\n switch(instanceMessage.channel) {\r\n case 'fileman':\r\n processFilemanMessage(wsEvent)\r\n break\r\n default:\r\n addMessage (SignalMessageLevelEnum.ERROR, 'Invalid channel in message: '+instanceMessage.channel)\r\n addMessage (SignalMessageLevelEnum.ERROR, 'Invalid message: '+JSON.stringify(instanceMessage))\r\n break\r\n }\r\n }\r\n\r\n const websocketOnOpen = (ws:WebSocket) => {\r\n setWebSocket(ws)\r\n let cluster=validClusters.find(cluster => cluster.name === selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No cluster selected')\r\n return\r\n }\r\n let pods = cluster.pods.filter(p => selectedNamespaces.includes(p.namespace))\r\n if (!pods) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No pods found')\r\n return\r\n }\r\n console.log(`WS connected`)\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n let containers:string[] = []\r\n if (selectedContainerNames.length>0) {\r\n for(var p of selectedPodNames) {\r\n for (var c of selectedContainerNames) {\r\n containers.push(p+'+'+c)\r\n }\r\n }\r\n }\r\n let iConfig:IInstanceConfig = {\r\n channel: 'fileman',\r\n objects: InstanceConfigObjectEnum.PODS,\r\n action: InstanceMessageActionEnum.START,\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n instance: '',\r\n accessKey: accessKeySerialize(accessKey),\r\n scope: 'fileman$read',\r\n view: (selectedContainerNames.length > 0 ? InstanceConfigViewEnum.CONTAINER : InstanceConfigViewEnum.POD),\r\n namespace: selectedNamespaces.join(','),\r\n group: '',\r\n pod: selectedPodNames.map(p => p).join(','),\r\n container: containers.join(','),\r\n data: {},\r\n type: InstanceMessageTypeEnum.SIGNAL\r\n }\r\n ws.send(JSON.stringify(iConfig))\r\n }\r\n else {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No accessKey for starting fileman streaming')\r\n return\r\n }\r\n }\r\n\r\n const startFilemanViewer = () => {\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName);\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No cluster selected')\r\n return\r\n }\r\n\r\n try {\r\n let ws = new WebSocket(cluster.url)\r\n ws.onopen = () => websocketOnOpen(ws)\r\n ws.onmessage = (event) => websocketOnMessage(event)\r\n ws.onclose = (event) => websocketOnClose(event)\r\n setWebSocket(ws)\r\n }\r\n catch (err) {\r\n }\r\n\r\n }\r\n\r\n const websocketOnClose = (_event:any) => {\r\n console.log(`WS disconnected`)\r\n setStarted(false)\r\n paused.current=false\r\n setStopped(true)\r\n }\r\n\r\n const stopFilemanViewer = () => {\r\n webSocket?.close()\r\n }\r\n\r\n const actionButtons = () => {\r\n let hasKey=false\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n hasKey = Boolean(cluster.accessKeys.get('fileman$read'))\r\n }\r\n\r\n return <>\r\n <IconButton onClick={() => clickStart()} title=\"Play\" disabled={started || !paused || selectedPodNames.length === 0 || !hasKey}>\r\n <PlayIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickPause} title=\"Pause\" disabled={!((started && !paused.current) && selectedPodNames.length > 0)}>\r\n <PauseIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickStop} title=\"Stop\" disabled={stopped || selectedPodNames.length === 0}>\r\n <StopIcon />\r\n </IconButton>\r\n </>\r\n }\r\n\r\n const statusButtons = (title:string) => {\r\n const show = (level:SignalMessageLevelEnum) => {\r\n setShowStatusDialog(true)\r\n setStatusLevel(level)\r\n }\r\n\r\n const prepareText = (txt:string|undefined) => {\r\n return txt? (txt.length>25? txt.substring(0,25)+\"...\":txt) : 'N/A'\r\n }\r\n\r\n return (\r\n <Grid container direction='row' >\r\n <Grid item>\r\n <Typography variant='h5'>{prepareText(title)}</Typography>\r\n </Grid>\r\n <Grid item style={{marginTop:'-8px'}}>\r\n <IconButton title=\"info\" disabled={!statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)} onClick={() => show(SignalMessageLevelEnum.INFO)}>\r\n <InfoIcon style={{ color:statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)?'blue':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"warning\" disabled={!statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)} onClick={() => show(SignalMessageLevelEnum.WARNING)} style={{marginLeft:'-16px'}}>\r\n <WarningIcon style={{ color:statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)?'orange':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"error\" disabled={!statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)} onClick={() => show(SignalMessageLevelEnum.ERROR)} style={{marginLeft:'-16px'}}>\r\n <ErrorIcon style={{ color:statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)?'red':'#BDBDBD'}}/>\r\n </IconButton>\r\n </Grid>\r\n </Grid>\r\n )\r\n }\r\n\r\n const statusClear = (level: SignalMessageLevelEnum) => {\r\n setStatusMessages(statusMessages.filter(m=> m.level!==level))\r\n setShowStatusDialog(false)\r\n }\r\n\r\n const onError = (error: IError, _file: IFileData) => {\r\n addMessage( SignalMessageLevelEnum.ERROR, error.message)\r\n }\r\n\r\n const onRename\t= (file: IFileData, newName: string) => {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n //filemanData.files = filemanData.files.filter (f => f.path!==file.path)\r\n files.current = files.current.filter (f => f.path!==file.path)\r\n setStateFiles([...files.current])\r\n sendCommand(FilemanCommandEnum.RENAME, namespace, pod, container, [file.path, newName])\r\n }\r\n\r\n const onRefresh = () => {\r\n if (level >= 3) {\r\n files.current = files.current.filter ( f => !f.path.startsWith(currentPath+'/'))\r\n //files.current = files.current.filter ( f => f.path!==currentPath)\r\n getLocalDir(currentPath+'/')\r\n }\r\n else {\r\n sendCommand(FilemanCommandEnum.HOME, '', '', '', [])\r\n }\r\n\r\n }\r\n \r\n const getLocalDir = (folder:string) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) {\r\n let [namespace,pod,container] = folder.split('/').slice(1)\r\n let filemanMessage:IFilemanMessage = {\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n action: InstanceMessageActionEnum.COMMAND,\r\n channel: 'fileman',\r\n type: InstanceMessageTypeEnum.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.DIR,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: [folder],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify(filemanMessage)\r\n webSocket.send(payload)\r\n }\r\n }\r\n }\r\n\r\n const sendCommand = (command: FilemanCommandEnum, namespace:string, pod:string, container:string, params:string[]) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) { \r\n let filemanMessage:IFilemanMessage = {\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n action: InstanceMessageActionEnum.COMMAND,\r\n channel: 'fileman',\r\n type: InstanceMessageTypeEnum.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: command,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: params,\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n webSocket.send(payload)\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onDelete = async (filesToDelete: IFileData[]) => {\r\n for (let file of filesToDelete) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.DELETE, namespace, pod, container, [file.path])\r\n }\r\n }\r\n\r\n const onCreateFolder = async (name: string, parentFolder: IFileData) => {\r\n let [namespace,pod,container] = parentFolder.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.CREATE, namespace, pod, container, [parentFolder.path + '/' + name])\r\n }\r\n\r\n const onDownload = async (filesToDownload: Array<IFileData>) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n\r\n for (let file of filesToDownload) {\r\n const url = `${cluster.url}/channel/fileman/download?key=${instance.current}&filename=${file.path}`\r\n \r\n try {\r\n const response = await fetch(url, { headers: { 'Authorization': 'Bearer '+ accessKeySerialize(accessKey) } })\r\n\r\n if (response.ok) {\r\n const blob = await response.blob()\r\n\r\n const link = document.createElement('a')\r\n link.href = URL.createObjectURL(blob)\r\n link.download = file.path.split('/').slice(-1)[0]\r\n if (file.isDirectory) link.download += '.tar.gz'\r\n document.body.appendChild(link)\r\n link.click()\r\n document.body.removeChild(link)\r\n URL.revokeObjectURL(link.href)\r\n }\r\n else {\r\n console.error(`Error downloading file: ${file.path}`)\r\n addMessage( SignalMessageLevelEnum.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`)\r\n }\r\n }\r\n catch (error) {\r\n console.error(`Error downloading file: ${file.path}`, error)\r\n addMessage( SignalMessageLevelEnum.ERROR, `Error downloading file ${file.path}: ${error}`)\r\n }\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onPaste = (filesToPaste: Array<IFileData>, destFolder:IFileData, operation:string) => {\r\n let command = operation==='move'? FilemanCommandEnum.MOVE : FilemanCommandEnum.COPY\r\n for (let file of filesToPaste) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(command, namespace, pod, container, [file.path, destFolder.path])\r\n } \r\n }\r\n\r\n const onFolderChange = (folder:string) => {\r\n setCurrentPath(folder)\r\n folder +='/'\r\n let level = folder.split('/').length - 1\r\n if (level > 3) getLocalDir(folder)\r\n }\r\n\r\n const onFileUploading = (file: IFileData, _parentFolder: IFileData) => { \r\n return { filename: currentPath + '/' + file.name }\r\n }\r\n\r\n return (<>\r\n\r\n { loading && <Progress/> }\r\n\r\n {!isKwirthAvailable(entity) && !loading && error && (\r\n <WarningPanel title={'An error has ocurred while obtaining data from kuebernetes clusters.'} message={error?.message} />\r\n )}\r\n\r\n {!isKwirthAvailable(entity) && !loading && (\r\n <MissingAnnotationEmptyState readMoreUrl='https://github.com/jfvilas/plugin-kwirth-fileman' annotation={[ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR]}/>\r\n )}\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length===0 &&\r\n <ComponentNotFound error={ErrorType.NO_CLUSTERS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)===0 &&\r\n <ComponentNotFound error={ErrorType.NO_PODS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)>0 &&\r\n <Box sx={{ display: 'flex', height:'100%'}}>\r\n <Box sx={{ width: '200px', maxWidth:'200px'}}>\r\n <Grid container direction='column'>\r\n <Grid item> \r\n <Card>\r\n <ClusterList resources={validClusters} selectedClusterName={selectedClusterName} onSelect={onSelectCluster}/>\r\n </Card>\r\n </Grid>\r\n {!props.hideVersion &&\r\n <Grid item>\r\n <Card>\r\n <KwirthNews latestVersions={backendInfo} backendVersion={backendVersion} ownVersion={VERSION}/>\r\n </Card>\r\n </Grid>\r\n }\r\n </Grid>\r\n </Box>\r\n\r\n <Box sx={{ flexGrow: 1, flex:1, overflow:'hidden', p:1, marginLeft:'8px' }}>\r\n\r\n { !selectedClusterName && \r\n <img src={LogoIcon} style={{ left:'40%', marginTop:'10%', width:'20%', position:'relative' }} />\r\n }\r\n\r\n { selectedClusterName && <>\r\n <Card style={{ marginTop:-8, marginBottom:'8px' }}>\r\n <CardHeader\r\n title={statusButtons(selectedClusterName)}\r\n style={{marginTop:-4, marginBottom:4, flexShrink:0}}\r\n action={actionButtons()}\r\n />\r\n </Card>\r\n { started && <Grid ref={filemanBoxRef} style={{height: `calc(100vh - ${filemanBoxTop}px - 35px)`}}>\r\n <FileManager \r\n className={styles.customFm}\r\n files={stateFiles}\r\n filePreviewPath='http://avoid-console-error'\r\n primaryColor='#1976d2'\r\n fontFamily='\"Helvetica Neue\", Helvetica, Roboto, Arial, sans-serif'\r\n height='100%'\r\n actions={new Map()}\r\n icons={icons} \r\n fileUploadConfig={fileUploadConfig}\r\n onCreateFolder={onCreateFolder}\r\n onError={onError}\r\n onRename={onRename}\r\n onPaste={onPaste}\r\n onDelete={onDelete}\r\n onFolderChange={onFolderChange}\r\n onRefresh={onRefresh}\r\n onFileUploading={onFileUploading}\r\n onDownload={onDownload}\r\n enableFilePreview={false}\r\n initialPath={''}\r\n permissions={permissions}\r\n />\r\n </Grid>}\r\n </>}\r\n </Box>\r\n </Box>\r\n }\r\n { showStatusDialog && <StatusLog level={statusLevel} onClose={() => setShowStatusDialog(false)} statusMessages={statusMessages} onClear={statusClear}/>}\r\n </>)\r\n}\r\n"],"names":["cluster","FilemanCommandEnum","content","uuid","level","p","error"],"mappings":"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"}
1
+ {"version":3,"file":"EntityKwirthFilemanContent.esm.js","sources":["../../src/components/EntityKwirthFilemanContent.tsx"],"sourcesContent":["/*\r\nCopyright 2025 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React, { useEffect, useRef, useState } from 'react'\r\nimport { v4 as uuid } from 'uuid'\r\nimport useAsync from 'react-use/esm/useAsync'\r\n\r\nimport { Progress, WarningPanel } from '@backstage/core-components'\r\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api'\r\nimport { ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR, isKwirthAvailable, ClusterValidPods, IStatusLine, getPodList, getContainerList, IBackendInfo } from '@jfvilas/plugin-kwirth-common'\r\nimport { MissingAnnotationEmptyState, useEntity } from '@backstage/plugin-catalog-react'\r\n\r\n// kwirth\r\nimport { kwirthFilemanApiRef } from '../api'\r\nimport { accessKeySerialize, IInstanceMessage, IInstanceConfig, ISignalMessage, EInstanceMessageType, EInstanceMessageAction, EInstanceMessageFlow, ESignalMessageEvent, EInstanceConfigObject, EInstanceConfigView, ESignalMessageLevel } from '@jfvilas/kwirth-common'\r\n\r\n// kwirth fileman components\r\nimport { KwirthNews, ComponentNotFound, StatusLog, ClusterList, ErrorType } from '@jfvilas/plugin-kwirth-frontend'\r\nimport { FileManager, IError, IFileData } from '@jfvilas/react-file-manager'\r\nimport { VERSION } from '../version'\r\n\r\n// Material-UI\r\nimport { Grid, Card, CardHeader, Box, IconButton, Typography } from '@material-ui/core'\r\n\r\n// styles\r\nimport '@jfvilas/react-file-manager/dist/style.css'\r\nimport styles from './custom-fm.module.css'\r\n\r\n// Icons\r\nimport PlayIcon from '@material-ui/icons/PlayArrow'\r\nimport PauseIcon from '@material-ui/icons/Pause'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport WarningIcon from '@material-ui/icons/Warning'\r\nimport ErrorIcon from '@material-ui/icons/Error'\r\nimport LogoIcon from '../assets/kwirthfileman-logo.svg'\r\nimport SvgIconNamespace from'./icons/ns.svg'\r\nimport SvgIconPod from'./icons/pod.svg'\r\nimport SvgIconContainer from'./icons/docker-mark-blue.svg'\r\n\r\nexport interface IEntityKwirthFilemanProps {\r\n hideVersion?: boolean\r\n excludeContainers?: string[]\r\n}\r\n\r\n\r\nconst NamespaceIcon = (props: {height?:number}) => { return <img src={SvgIconNamespace} alt='ns' height={`${props.height||16}px`}/> }\r\nconst PodIcon = (props: {height?:number}) => { return <img src={SvgIconPod} alt='pod' height={`${props.height||16}px`}/> }\r\nconst ContainerIcon = (props: {height?:number}) => { return <img src={SvgIconContainer} height={`${props.height||16}px`}/> }\r\n\r\nexport const EntityKwirthFilemanContent: React.FC<IEntityKwirthFilemanProps> = (props:IEntityKwirthFilemanProps) => { \r\n const { entity } = useEntity()\r\n const kwirthFilemanApi = useApi(kwirthFilemanApiRef)\r\n const alertApi = useApi(alertApiRef)\r\n const [validClusters, setResources] = useState<ClusterValidPods[]>([])\r\n const [selectedClusterName, setSelectedClusterName] = useState('')\r\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([])\r\n const [selectedPodNames, setSelectedPodNames] = useState<string[]>([])\r\n const [selectedContainerNames, setSelectedContainerNames] = useState<string[]>([])\r\n const [started, setStarted] = useState(false)\r\n const [stopped, setStopped] = useState(true)\r\n const paused=useRef<boolean>(false)\r\n const [statusMessages, setStatusMessages] = useState<IStatusLine[]>([])\r\n const [webSocket, setWebSocket] = useState<WebSocket>()\r\n const [showStatusDialog, setShowStatusDialog] = useState(false)\r\n const [statusLevel, setStatusLevel] = useState<ESignalMessageLevel>(ESignalMessageLevel.INFO)\r\n const [ backendVersion, setBackendVersion ] = useState<string>('')\r\n const [ backendInfo, setBackendInfo ] = useState<IBackendInfo>()\r\n const instance = useRef<string>()\r\n const [ stateFiles, setStateFiles ] = useState<IFileData[]>([])\r\n const files = useRef<IFileData[]>([])\r\n const [ currentPath, setCurrentPath] = useState('')\r\n const { loading, error } = useAsync ( async () => {\r\n if (backendVersion==='') setBackendVersion(await kwirthFilemanApi.getVersion())\r\n if (!backendInfo) setBackendInfo(await kwirthFilemanApi.getInfo())\r\n let reqScopes = ['fileman$read']\r\n let data:ClusterValidPods[] = await kwirthFilemanApi.requestAccess(entity, 'fileman', reqScopes)\r\n setResources(data)\r\n })\r\n const filemanBoxRef = useRef<HTMLDivElement | null>(null)\r\n const [filemanBoxTop, setFilemanBoxTop] = useState(0)\r\n const [ runningInstance, setRunningInstance] = useState<string|undefined>()\r\n let permissions={\r\n create: true,\r\n delete: true,\r\n download: true,\r\n copy: true,\r\n move: true,\r\n rename: true,\r\n upload: true\r\n }\r\n\r\n let icons = new Map()\r\n icons.set('namespace', { open:<NamespaceIcon height={18}/>, closed:<NamespaceIcon height={18}/>, grid:<NamespaceIcon height={40}/>, list:<NamespaceIcon height={18}/>, default:<NamespaceIcon height={18}/> })\r\n icons.set('pod', { open:<PodIcon height={18}/>, closed:<PodIcon height={18}/>, grid:<PodIcon height={40}/>, list:<PodIcon height={18}/>, default:<PodIcon height={18}/> })\r\n icons.set('container', { open:<ContainerIcon/>, closed:<ContainerIcon/>, grid:<ContainerIcon height={34}/>, list:<ContainerIcon height={16}/>, default:<ContainerIcon height={16}/> })\r\n\r\n interface IFileUploadConfig { \r\n url: string\r\n method?: \"POST\" | \"PUT\"\r\n headers?: { [key: string]: string }\r\n }\r\n let fileUploadConfig:IFileUploadConfig= {\r\n url: ''\r\n }\r\n\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n fileUploadConfig = {\r\n url: `${cluster.url}/${runningInstance}/channel/fileman/upload?key=${instance.current}`,\r\n method:'POST',\r\n headers: {\r\n 'Authorization': 'Bearer '+ accessKeySerialize(accessKey)\r\n }\r\n }\r\n }\r\n }\r\n \r\n let level = currentPath.split('/').length - 1\r\n if (level<3) {\r\n permissions = {\r\n create: false,\r\n delete: false,\r\n download: false,\r\n copy: false,\r\n move: false,\r\n rename: false,\r\n upload: false\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (filemanBoxRef.current) setFilemanBoxTop(filemanBoxRef.current.getBoundingClientRect().top)\r\n })\r\n\r\n const clickStart = () => {\r\n if (!paused.current) {\r\n setStarted(true)\r\n paused.current=false\r\n setStopped(false)\r\n startFilemanViewer()\r\n }\r\n else {\r\n paused.current=false\r\n setStarted(true)\r\n }\r\n }\r\n\r\n const onClickPause = () => {\r\n setStarted(false)\r\n paused.current=true\r\n }\r\n\r\n const onClickStop = () => {\r\n setStarted(false)\r\n setStopped(true)\r\n paused.current=false\r\n stopFilemanViewer()\r\n }\r\n\r\n const onSelectCluster = (clusterName:string|undefined) => {\r\n if (started) onClickStop()\r\n if (clusterName) {\r\n setSelectedClusterName(clusterName)\r\n setSelectedPodNames([])\r\n setSelectedContainerNames([])\r\n setStatusMessages([])\r\n let cluster = validClusters.find(cluster => cluster.name === clusterName)\r\n\r\n if (cluster && cluster.pods) {\r\n let validNamespaces = Array.from(new Set(cluster.pods.map(pod => pod.namespace)))\r\n if (validNamespaces.length === 1) {\r\n setSelectedNamespaces(validNamespaces)\r\n let podList = getPodList (cluster.pods, validNamespaces)\r\n setSelectedPodNames(podList.map(pod => pod.name))\r\n setSelectedContainerNames(getContainerList(cluster.pods, validNamespaces, podList.map(pod => pod.name), props.excludeContainers || []))\r\n }\r\n else {\r\n setSelectedNamespaces([])\r\n }\r\n }\r\n }\r\n }\r\n\r\n enum FilemanCommandEnum {\r\n HOME = 'home',\r\n DIR = 'dir',\r\n CREATE = 'create',\r\n RENAME = 'rename',\r\n DELETE = 'delete',\r\n MOVE = 'move',\r\n COPY = 'copy',\r\n UPLOAD = 'upload',\r\n DOWNLOAD = 'download'\r\n }\r\n\r\n interface IFilemanMessage extends IInstanceMessage {\r\n msgtype: 'filemanmessage'\r\n id: string\r\n accessKey: string\r\n instance: string\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n command: FilemanCommandEnum\r\n params?: string[]\r\n }\r\n\r\n interface IFilemanMessageResponse extends IInstanceMessage {\r\n msgtype: 'filemanmessageresponse'\r\n id: string\r\n command: FilemanCommandEnum\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n data?: any\r\n }\r\n\r\n const processFilemanMessage = (wsEvent:any) => {\r\n let msg:IFilemanMessage = JSON.parse(wsEvent.data)\r\n\r\n switch (msg.type) {\r\n case EInstanceMessageType.DATA: {\r\n let response = JSON.parse(wsEvent.data) as IFilemanMessageResponse\r\n switch(response.action) {\r\n case EInstanceMessageAction.COMMAND: {\r\n switch(response.command) {\r\n case FilemanCommandEnum.HOME:\r\n let data = response.data as string[]\r\n let nss = Array.from (new Set (data.map(n => n.split('/')[0])))\r\n nss.map(ns => {\r\n if (!files.current.some(f => f.path === '/'+ ns)) {\r\n files.current.push ({ name: ns, isDirectory: true, path: '/'+ ns, class:'namespace' }) \r\n }\r\n let podNames = Array.from (new Set (data.filter(a => a.split('/')[0]===ns).map(o => o.split('/')[1])))\r\n podNames.map(p => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p)) {\r\n files.current.push ({ name: p, isDirectory: true, path: '/'+ns+'/'+p, class:'pod' })\r\n }\r\n let containers = Array.from (new Set (data.filter(a => a.split('/')[0]===ns && a.split('/')[1]===p).map(o => o.split('/')[2])))\r\n containers = containers.filter(c => !props.excludeContainers?.includes(c))\r\n containers.map(c => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p+'/'+c)) {\r\n files.current.push ({ name: c, isDirectory: true, path: '/'+ns+'/'+p+'/'+c, class:'container' })\r\n }\r\n })\r\n })\r\n })\r\n setStateFiles([...files.current])\r\n break\r\n case FilemanCommandEnum.DIR:\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n for (let o of content.metadata.object) {\r\n let name = o.name.split('/')[o.name.split('/').length-1]\r\n let e = {\r\n name,\r\n isDirectory: (o.type===1),\r\n path: o.name,\r\n updatedAt: new Date(+o.time).toISOString(),\r\n size: +o.size,\r\n ...(o.type===0? {class:'file'}:{})\r\n }\r\n let i = files.current.findIndex(f => f.path === e.path)\r\n if (i>=0)\r\n files.current[i]=e\r\n else\r\n files.current.push(e)\r\n }\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.RENAME: {\r\n let content = JSON.parse(response.data)\r\n if (content.status!=='Success') addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.DELETE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n let fname = content.metadata.object\r\n files.current = files.current.filter(f => f.path !== fname)\r\n files.current = files.current.filter(f => !f.path.startsWith(fname+'/'))\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n case FilemanCommandEnum.MOVE:\r\n case FilemanCommandEnum.COPY:\r\n case FilemanCommandEnum.CREATE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n //filemanData.files = filemanData.files.filter(f => f.path !== content.metadata.object)\r\n let f = { \r\n name: (content.metadata.object as string).split('/').slice(-1)[0],\r\n isDirectory: (content.metadata.type===1),\r\n path: content.metadata.object,\r\n updatedAt: new Date(+content.metadata.time).toISOString(), \r\n size: +content.metadata.size,\r\n ...(content.metadata.type.type===0? {class:'file'}:{})\r\n }\r\n files.current.push(f)\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n }\r\n }\r\n break\r\n }\r\n break\r\n }\r\n case EInstanceMessageType.SIGNAL:\r\n let signalMessage = JSON.parse(wsEvent.data) as ISignalMessage\r\n if (signalMessage.flow === EInstanceMessageFlow.RESPONSE) {\r\n switch(signalMessage.action) {\r\n case EInstanceMessageAction.START:\r\n if (signalMessage.text) addMessage(ESignalMessageLevel.INFO, signalMessage.text)\r\n instance.current = signalMessage.instance\r\n break\r\n case EInstanceMessageAction.RI:\r\n setRunningInstance(signalMessage.data)\r\n console.log(signalMessage.data)\r\n break\r\n case EInstanceMessageAction.COMMAND:\r\n if (signalMessage.text) addMessage(signalMessage.level, signalMessage.text)\r\n break\r\n default:\r\n addMessage( ESignalMessageLevel.ERROR, wsEvent.data)\r\n break\r\n }\r\n }\r\n else if (signalMessage.flow === EInstanceMessageFlow.UNSOLICITED) {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current) {\r\n if (signalMessage.event === ESignalMessageEvent.ADD) {\r\n // request a RI id\r\n let instanceConfig:IInstanceMessage = {\r\n action: EInstanceMessageAction.RI,\r\n channel: 'fileman',\r\n flow: EInstanceMessageFlow.REQUEST,\r\n type: EInstanceMessageType.SIGNAL,\r\n instance: instance.current\r\n }\r\n wsEvent.target.send(JSON.stringify( instanceConfig ))\r\n\r\n // request HOME dir\r\n let filemanMessage:IFilemanMessage = {\r\n flow: EInstanceMessageFlow.REQUEST,\r\n action: EInstanceMessageAction.COMMAND,\r\n channel: 'fileman',\r\n type: EInstanceMessageType.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.HOME,\r\n namespace: signalMessage.namespace!,\r\n group: '',\r\n pod: signalMessage.pod!,\r\n container: signalMessage.container!,\r\n params: [],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n wsEvent.target.send(payload)\r\n if (signalMessage.text) addMessage( ESignalMessageLevel.INFO, signalMessage.text)\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.INFO, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.INFO, 'Have no cluster')\r\n }\r\n }\r\n break\r\n\r\n default:\r\n console.log(`Invalid message type ${msg.type}`)\r\n break\r\n }\r\n }\r\n\r\n const addMessage = (level:ESignalMessageLevel, text:string) => {\r\n alertApi.post({ message: text, severity: level, display:'transient' }) \r\n setStatusMessages ((prev) => [...prev, {\r\n level,\r\n text,\r\n type: EInstanceMessageType.SIGNAL,\r\n }])\r\n }\r\n\r\n const websocketOnMessage = (wsEvent:any) => {\r\n let instanceMessage:IInstanceMessage\r\n try {\r\n instanceMessage = JSON.parse(wsEvent.data) as IInstanceMessage\r\n }\r\n catch (err) {\r\n console.log(err)\r\n console.log(wsEvent.data)\r\n return\r\n }\r\n\r\n switch(instanceMessage.channel) {\r\n case 'fileman':\r\n processFilemanMessage(wsEvent)\r\n break\r\n default:\r\n addMessage (ESignalMessageLevel.ERROR, 'Invalid channel in message: '+instanceMessage.channel)\r\n addMessage (ESignalMessageLevel.ERROR, 'Invalid message: '+JSON.stringify(instanceMessage))\r\n break\r\n }\r\n }\r\n\r\n const websocketOnOpen = (ws:WebSocket) => {\r\n setWebSocket(ws)\r\n let cluster=validClusters.find(cluster => cluster.name === selectedClusterName)\r\n if (!cluster) {\r\n addMessage(ESignalMessageLevel.ERROR,'No cluster selected')\r\n return\r\n }\r\n let pods = cluster.pods.filter(p => selectedNamespaces.includes(p.namespace))\r\n if (!pods) {\r\n addMessage(ESignalMessageLevel.ERROR,'No pods found')\r\n return\r\n }\r\n console.log(`WS connected`)\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n let containers:string[] = []\r\n if (selectedContainerNames.length>0) {\r\n for(var p of selectedPodNames) {\r\n for (var c of selectedContainerNames) {\r\n containers.push(p+'+'+c)\r\n }\r\n }\r\n }\r\n let iConfig:IInstanceConfig = {\r\n channel: 'fileman',\r\n objects: EInstanceConfigObject.PODS,\r\n action: EInstanceMessageAction.START,\r\n flow: EInstanceMessageFlow.REQUEST,\r\n instance: '',\r\n accessKey: accessKeySerialize(accessKey),\r\n scope: 'fileman$read',\r\n view: (selectedContainerNames.length > 0 ? EInstanceConfigView.CONTAINER : EInstanceConfigView.POD),\r\n namespace: selectedNamespaces.join(','),\r\n group: '',\r\n pod: selectedPodNames.map(p => p).join(','),\r\n container: containers.join(','),\r\n data: {},\r\n type: EInstanceMessageType.SIGNAL\r\n }\r\n ws.send(JSON.stringify(iConfig))\r\n }\r\n else {\r\n addMessage(ESignalMessageLevel.ERROR,'No accessKey for starting fileman streaming')\r\n return\r\n }\r\n }\r\n\r\n const startFilemanViewer = () => {\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName);\r\n if (!cluster) {\r\n addMessage(ESignalMessageLevel.ERROR,'No cluster selected')\r\n return\r\n }\r\n\r\n try {\r\n let ws = new WebSocket(cluster.url)\r\n ws.onopen = () => websocketOnOpen(ws)\r\n ws.onmessage = (event) => websocketOnMessage(event)\r\n ws.onclose = (event) => websocketOnClose(event)\r\n setWebSocket(ws)\r\n }\r\n catch (err) {\r\n }\r\n\r\n }\r\n\r\n const websocketOnClose = (_event:any) => {\r\n console.log(`WS disconnected`)\r\n setStarted(false)\r\n paused.current=false\r\n setStopped(true)\r\n }\r\n\r\n const stopFilemanViewer = () => {\r\n webSocket?.close()\r\n }\r\n\r\n const actionButtons = () => {\r\n let hasKey=false\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n hasKey = Boolean(cluster.accessKeys.get('fileman$read'))\r\n }\r\n\r\n return <>\r\n <IconButton onClick={() => clickStart()} title=\"Play\" disabled={started || !paused || selectedPodNames.length === 0 || !hasKey}>\r\n <PlayIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickPause} title=\"Pause\" disabled={!((started && !paused.current) && selectedPodNames.length > 0)}>\r\n <PauseIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickStop} title=\"Stop\" disabled={stopped || selectedPodNames.length === 0}>\r\n <StopIcon />\r\n </IconButton>\r\n </>\r\n }\r\n\r\n const statusButtons = (title:string) => {\r\n const show = (level:ESignalMessageLevel) => {\r\n setShowStatusDialog(true)\r\n setStatusLevel(level)\r\n }\r\n\r\n const prepareText = (txt:string|undefined) => {\r\n return txt? (txt.length>25? txt.substring(0,25)+\"...\":txt) : 'N/A'\r\n }\r\n\r\n return (\r\n <Grid container direction='row' >\r\n <Grid item>\r\n <Typography variant='h5'>{prepareText(title)}</Typography>\r\n </Grid>\r\n <Grid item style={{marginTop:'-8px'}}>\r\n <IconButton title=\"info\" disabled={!statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.INFO)} onClick={() => show(ESignalMessageLevel.INFO)}>\r\n <InfoIcon style={{ color:statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.INFO)?'blue':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"warning\" disabled={!statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.WARNING)} onClick={() => show(ESignalMessageLevel.WARNING)} style={{marginLeft:'-16px'}}>\r\n <WarningIcon style={{ color:statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.WARNING)?'orange':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"error\" disabled={!statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.ERROR)} onClick={() => show(ESignalMessageLevel.ERROR)} style={{marginLeft:'-16px'}}>\r\n <ErrorIcon style={{ color:statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.ERROR)?'red':'#BDBDBD'}}/>\r\n </IconButton>\r\n </Grid>\r\n </Grid>\r\n )\r\n }\r\n\r\n const statusClear = (level: ESignalMessageLevel) => {\r\n setStatusMessages(statusMessages.filter(m=> m.level!==level))\r\n setShowStatusDialog(false)\r\n }\r\n\r\n const onError = (error: IError, _file: IFileData) => {\r\n addMessage( ESignalMessageLevel.ERROR, error.message)\r\n }\r\n\r\n const onRename\t= (file: IFileData, newName: string) => {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n //filemanData.files = filemanData.files.filter (f => f.path!==file.path)\r\n files.current = files.current.filter (f => f.path!==file.path)\r\n setStateFiles([...files.current])\r\n sendCommand(FilemanCommandEnum.RENAME, namespace, pod, container, [file.path, newName])\r\n }\r\n\r\n const onRefresh = () => {\r\n if (level >= 3) {\r\n files.current = files.current.filter ( f => !f.path.startsWith(currentPath+'/'))\r\n getLocalDir(currentPath+'/')\r\n }\r\n else {\r\n sendCommand(FilemanCommandEnum.HOME, '', '', '', [])\r\n }\r\n\r\n }\r\n \r\n const getLocalDir = (folder:string) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) {\r\n let [namespace,pod,container] = folder.split('/').slice(1)\r\n let filemanMessage:IFilemanMessage = {\r\n flow: EInstanceMessageFlow.REQUEST,\r\n action: EInstanceMessageAction.COMMAND,\r\n channel: 'fileman',\r\n type: EInstanceMessageType.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.DIR,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: [folder],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify(filemanMessage)\r\n webSocket.send(payload)\r\n }\r\n }\r\n }\r\n\r\n const sendCommand = (command: FilemanCommandEnum, namespace:string, pod:string, container:string, params:string[]) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) { \r\n let filemanMessage:IFilemanMessage = {\r\n flow: EInstanceMessageFlow.REQUEST,\r\n action: EInstanceMessageAction.COMMAND,\r\n channel: 'fileman',\r\n type: EInstanceMessageType.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: command,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: params,\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n webSocket.send(payload)\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onDelete = async (filesToDelete: IFileData[]) => {\r\n for (let file of filesToDelete) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.DELETE, namespace, pod, container, [file.path])\r\n }\r\n }\r\n\r\n const onCreateFolder = async (name: string, parentFolder: IFileData) => {\r\n let [namespace,pod,container] = parentFolder.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.CREATE, namespace, pod, container, [parentFolder.path + '/' + name])\r\n }\r\n\r\n const onDownload = async (filesToDownload: Array<IFileData>) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n\r\n for (let file of filesToDownload) {\r\n const url = `${cluster.url}/${runningInstance}/channel/fileman/download?key=${instance.current}&filename=${file.path}`\r\n \r\n try {\r\n const response = await fetch(url, { headers: { 'Authorization': 'Bearer '+ accessKeySerialize(accessKey) } })\r\n\r\n if (response.ok) {\r\n const blob = await response.blob()\r\n\r\n const link = document.createElement('a')\r\n link.href = URL.createObjectURL(blob)\r\n link.download = file.path.split('/').slice(-1)[0]\r\n if (file.isDirectory) link.download += '.tar.gz'\r\n document.body.appendChild(link)\r\n link.click()\r\n document.body.removeChild(link)\r\n URL.revokeObjectURL(link.href)\r\n }\r\n else {\r\n console.error(`Error downloading file: ${file.path}`)\r\n addMessage( ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`)\r\n }\r\n }\r\n catch (error) {\r\n console.error(`Error downloading file: ${file.path}`, error)\r\n addMessage( ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: ${error}`)\r\n }\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onPaste = (filesToPaste: Array<IFileData>, destFolder:IFileData, operation:string) => {\r\n let command = operation==='move'? FilemanCommandEnum.MOVE : FilemanCommandEnum.COPY\r\n for (let file of filesToPaste) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(command, namespace, pod, container, [file.path, destFolder.path])\r\n } \r\n }\r\n\r\n const onFolderChange = (folder:string) => {\r\n setCurrentPath(folder)\r\n folder +='/'\r\n let level = folder.split('/').length - 1\r\n if (level > 3) getLocalDir(folder)\r\n }\r\n\r\n const onFileUploading = (file: IFileData, _parentFolder: IFileData) => { \r\n return { filename: currentPath + '/' + file.name }\r\n }\r\n\r\n return (<>\r\n\r\n { loading && <Progress/> }\r\n\r\n {!isKwirthAvailable(entity) && !loading && error && (\r\n <WarningPanel title={'An error has ocurred while obtaining data from kuebernetes clusters.'} message={error?.message} />\r\n )}\r\n\r\n {!isKwirthAvailable(entity) && !loading && (\r\n <MissingAnnotationEmptyState readMoreUrl='https://github.com/jfvilas/plugin-kwirth-fileman' annotation={[ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR]}/>\r\n )}\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length===0 &&\r\n <ComponentNotFound error={ErrorType.NO_CLUSTERS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)===0 &&\r\n <ComponentNotFound error={ErrorType.NO_PODS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)>0 &&\r\n <Box sx={{ display: 'flex', height:'100%'}}>\r\n <Box sx={{ width: '200px', maxWidth:'200px'}}>\r\n <Grid container direction='column'>\r\n <Grid item> \r\n <Card>\r\n <ClusterList resources={validClusters} selectedClusterName={selectedClusterName} onSelect={onSelectCluster}/>\r\n </Card>\r\n </Grid>\r\n {!props.hideVersion &&\r\n <Grid item>\r\n <Card>\r\n <KwirthNews latestVersions={backendInfo} backendVersion={backendVersion} ownVersion={VERSION}/>\r\n </Card>\r\n </Grid>\r\n }\r\n </Grid>\r\n </Box>\r\n\r\n <Box sx={{ flexGrow: 1, flex:1, overflow:'hidden', p:1, marginLeft:'8px' }}>\r\n\r\n { !selectedClusterName && \r\n <img src={LogoIcon} style={{ left:'40%', marginTop:'10%', width:'20%', position:'relative' }} />\r\n }\r\n\r\n { selectedClusterName && <>\r\n <Card style={{ marginTop:-8, marginBottom:'8px' }}>\r\n <CardHeader\r\n title={statusButtons(selectedClusterName)}\r\n style={{marginTop:-4, marginBottom:4, flexShrink:0}}\r\n action={actionButtons()}\r\n />\r\n </Card>\r\n { started && <Grid ref={filemanBoxRef} style={{height: `calc(100vh - ${filemanBoxTop}px - 35px)`}}>\r\n <FileManager \r\n className={styles.customFm}\r\n files={stateFiles}\r\n filePreviewPath='http://avoid-console-error'\r\n primaryColor='#1976d2'\r\n fontFamily='\"Helvetica Neue\", Helvetica, Roboto, Arial, sans-serif'\r\n height='100%'\r\n actions={new Map()}\r\n icons={icons} \r\n fileUploadConfig={fileUploadConfig}\r\n onCreateFolder={onCreateFolder}\r\n onError={onError}\r\n onRename={onRename}\r\n onPaste={onPaste}\r\n onDelete={onDelete}\r\n onFolderChange={onFolderChange}\r\n onRefresh={onRefresh}\r\n onFileUploading={onFileUploading}\r\n onDownload={onDownload}\r\n enableFilePreview={false}\r\n initialPath={''}\r\n permissions={permissions}\r\n maxNavigationPaneLevel={3}\r\n showBreadcrumb={true}\r\n />\r\n </Grid>}\r\n </>}\r\n </Box>\r\n </Box>\r\n }\r\n { showStatusDialog && <StatusLog level={statusLevel} onClose={() => setShowStatusDialog(false)} statusMessages={statusMessages} onClear={statusClear}/>}\r\n </>)\r\n}\r\n"],"names":["cluster","FilemanCommandEnum","content","uuid","level","p","error"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import styleInject from '../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
2
2
 
3
- var css_248z = ".file-explorer {\r\n box-shadow: 0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12);\r\n border-radius: 4px;\r\n min-height: 150px;\r\n border: 0\r\n}\r\n\r\n.file-explorer .toolbar {\r\n border-top-right-radius: 4px;\r\n border-top-left-radius: 4px;\r\n min-height: 46px;\r\n background-color: #fcfcfc;\r\n}\r\n\r\n.file-explorer .breadcrumb {\r\n padding-top: 10px;\r\n min-height: 36px;\r\n}\r\n\r\n.file-explorer .statusbar {\r\n height: 20px;\r\n}\r\n\r\n.file-explorer .file-item {\r\n padding-top: 4px;\r\n font-size: 14px;\r\n}\r\n\r\n.file-explorer .sb-folder-name {\r\n font-size: 14px;\r\n}\r\n\r\n.file-explorer .folder-name {\r\n font-size: 14px;\r\n}\r\n\r\n.file-explorer .sb-folders-list::-webkit-scrollbar {\r\n width: 10px;\r\n height: 10px;\r\n}\r\n\r\n.file-explorer .files::-webkit-scrollbar {\r\n width: 10px;\r\n height: 10px;\r\n}\r\n\r\n.file-explorer .files {\r\n padding: 2px;\r\n column-gap: 2px;\r\n row-gap: 2px;\r\n}\r\n\r\n.file-explorer .files .file-item .selection-checkbox {\r\n top: 6px;\r\n}\r\n\r\n.file-explorer .files .file-item-container {\r\n margin: 0 0;\r\n}";
3
+ var css_248z = ".file-explorer *::-webkit-scrollbar {\r\n width: 8px !important;\r\n height: 8px !important;\r\n display: block !important;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-thumb {\r\n border-radius: 10px !important;\r\n}\r\n\r\n\r\n/* --- ESTILOS MODO CLARO (POR DEFECTO) --- */\r\n.file-explorer {\r\n box-shadow: 0px 2px 4px rgba(0,0,0,0.1);\r\n background-color: #ffffff;\r\n border-radius: 4px;\r\n min-height: 150px;\r\n border: 1px solid #e0e0e0;\r\n color: #000000;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-track {\r\n background: #f0f0f0 !important;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-thumb {\r\n background: #cdcdcd !important;\r\n border: 2px solid #f0f0f0 !important;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-thumb:hover {\r\n background: #a6a6a6 !important;\r\n}\r\n\r\n.file-explorer .toolbar {\r\n border-top-right-radius: 4px;\r\n border-top-left-radius: 4px;\r\n min-height: 46px;\r\n background-color: #f5f5f5;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n/* :global(.item-action) {\r\n color: #1976d2;\r\n} */\r\n\r\n.file-explorer .breadcrumb {\r\n padding-top: 10px;\r\n min-height: 36px;\r\n color: #666666;\r\n}\r\n\r\n.file-explorer .file-item,\r\n.file-explorer .sb-folder-name,\r\n.file-explorer .folder-name {\r\n font-size: 14px;\r\n color: #000000;\r\n padding: 2px;\r\n}\r\n\r\n.file-explorer .sb-folder-name,\r\n.file-explorer .folder-name {\r\n font-size: 14px;\r\n color: #000000;\r\n}\r\n\r\n.file-explorer .files .file-item-container:hover {\r\n background-color: rgba(0, 0, 0, 0.04);\r\n}\r\n\r\n/* --- ESTILOS MODO OSCURO (ACTIVADOS POR DATA-THEME-MODE) --- */\r\n\r\n[data-theme-mode='dark'] .file-explorer {\r\n background-color: #1b1b1b !important;\r\n border-color: #333333 !important;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n color: #e0e0e0 !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .toolbar,\r\n[data-theme-mode='dark'] .file-explorer .grid,\r\n[data-theme-mode='dark'] .file-explorer .list,\r\n[data-theme-mode='dark'] .file-explorer .bread-crumb-container,\r\n[data-theme-mode='dark'] .file-explorer .search-input,\r\n[data-theme-mode='dark'] .file-explorer .statusbar,\r\n[data-theme-mode='dark'] .file-explorer .sidebar-resize,\r\n[data-theme-mode='dark'] .file-explorer .navigation-pane,\r\n[data-theme-mode='dark'] .file-explorer .fm-context-menu,\r\n[data-theme-mode='dark'] .file-explorer .fm-modal-header,\r\n[data-theme-mode='dark'] .file-explorer .fm-modal-heading,\r\n[data-theme-mode='dark'] .file-explorer .file-delete-confirm,\r\n[data-theme-mode='dark'] .file-explorer .file-rename-folder-action,\r\n[data-theme-mode='dark'] .file-explorer .fm-rename-folder-input,\r\n[data-theme-mode='dark'] .file-explorer .fm-rename-folder-container,\r\n[data-theme-mode='dark'] .file-explorer .file-delete-confirm-text,\r\n[data-theme-mode='dark'] .file-explorer .fm-modal,\r\n[data-theme-mode='dark'] .file-explorer .divider,\r\n[data-theme-mode='dark'] .file-explorer .files-header,\r\n[data-theme-mode='dark'] .file-explorer .toggle-view {\r\n background-color: #242424 !important;\r\n color: #e0e0e0 !important;\r\n border-color: #333333 !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .fm-context-menu .file-context-menu-list ul li,\r\n[data-theme-mode='dark'] .toggle-view ul li {\r\n color: #e0e0e0 !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .fm-context-menu .file-context-menu-list ul li:hover,\r\n[data-theme-mode='dark'] .toggle-view ul li:hover {\r\n background-color: rgba(255, 255, 255, 0.1) !important;\r\n color: #ffffff !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .file-item,\r\n[data-theme-mode='dark'] .file-explorer .sb-folder-name,\r\n[data-theme-mode='dark'] .file-explorer .folder-name,\r\n[data-theme-mode='dark'] .item-action {\r\n color: #ffffff !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .files .file-item-container:hover {\r\n background-color: rgba(255, 255, 255, 0.08) !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer *::-webkit-scrollbar-track {\r\n background: #1b1b1b !important; /* Fondo oscuro del explorador */\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer *::-webkit-scrollbar-thumb {\r\n background: #555555 !important; /* Gris que resalte en oscuro */\r\n border: 2px solid #1b1b1b !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer *::-webkit-scrollbar-thumb:hover {\r\n background: #777777 !important;\r\n}";
4
4
  var styles = {};
5
5
  styleInject(css_248z);
6
6
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
2
2
  import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';
3
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
3
4
  import { Entity } from '@backstage/catalog-model';
4
5
  import { ClusterValidPods, IBackendInfo } from '@jfvilas/plugin-kwirth-common';
5
6
 
@@ -19,7 +20,7 @@ interface KwirthFilemanApi {
19
20
  getVersion(): Promise<any>;
20
21
  getInfo(): any;
21
22
  }
22
- declare const kwirthFilemanApiRef: _backstage_core_plugin_api.ApiRef<KwirthFilemanApi>;
23
+ declare const kwirthFilemanApiRef: _backstage_frontend_plugin_api.ApiRef<KwirthFilemanApi>;
23
24
 
24
25
  interface KwirthFilemanClientOptions {
25
26
  discoveryApi: DiscoveryApi;
@@ -1,4 +1,4 @@
1
- const VERSION = "0.13.10";
1
+ const VERSION = "0.14.1";
2
2
 
3
3
  export { VERSION };
4
4
  //# sourceMappingURL=version.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.esm.js","sources":["../src/version.ts"],"sourcesContent":["export const VERSION:string=\"0.13.10\"; \r\n"],"names":[],"mappings":"AAAO,MAAM,OAAA,GAAe;;;;"}
1
+ {"version":3,"file":"version.esm.js","sources":["../src/version.ts"],"sourcesContent":["export const VERSION:string=\"0.14.1\"; \r\n"],"names":[],"mappings":"AAAO,MAAM,OAAA,GAAe;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jfvilas/plugin-kwirth-fileman",
3
- "version": "0.13.10",
3
+ "version": "0.14.1",
4
4
  "description": "Frontend plugin for doing visual file management on Kubernetes containers",
5
5
  "keywords": [
6
6
  "Backstage",
@@ -64,21 +64,21 @@
64
64
  "test": "backstage-cli package test"
65
65
  },
66
66
  "dependencies": {
67
- "@backstage/catalog-model": "^1.7.6",
68
- "@backstage/core-components": "^0.18.3",
69
- "@backstage/core-plugin-api": "^1.12.0",
70
- "@backstage/frontend-plugin-api": "^0.13.1",
71
- "@backstage/integration-react": "^1.2.12",
72
- "@backstage/plugin-auth-react": "^0.1.21",
73
- "@backstage/plugin-catalog-react": "^1.21.3",
74
- "@jfvilas/react-file-manager": "^1.1.7",
67
+ "@backstage/catalog-model": "^1.7.7",
68
+ "@backstage/core-components": "^0.18.8",
69
+ "@backstage/core-plugin-api": "^1.12.4",
70
+ "@backstage/frontend-plugin-api": "^0.15.1",
71
+ "@backstage/integration-react": "^1.2.16",
72
+ "@backstage/plugin-auth-react": "^0.1.25",
73
+ "@backstage/plugin-catalog-react": "^2.1.0",
74
+ "@jfvilas/react-file-manager": "^1.4.21",
75
75
  "@material-ui/core": "^4.12.2",
76
76
  "@material-ui/icons": "^4.9.1",
77
77
  "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
78
78
  "react-use": "^17.2.4"
79
79
  },
80
80
  "devDependencies": {
81
- "@backstage/cli": "^0.34.5",
81
+ "@backstage/cli": "^0.36.0",
82
82
  "@testing-library/dom": "^10.0.0",
83
83
  "@testing-library/jest-dom": "^6.0.0",
84
84
  "@testing-library/react": "^15.0.0",