|
|
@@ -1,4 +1,4 @@
|
|
|
-import React, { useEffect, useContext } from "react";
|
|
|
+import React, { useEffect, useContext, useState } from "react";
|
|
|
import { ResourceListField } from "../types";
|
|
|
import { Context } from "shared/Context";
|
|
|
import { useWebsockets } from "shared/hooks/useWebsockets";
|
|
|
@@ -9,6 +9,7 @@ import styled from "styled-components";
|
|
|
const ResourceList: React.FC<ResourceListField> = (props) => {
|
|
|
const { currentCluster, currentProject } = useContext(Context);
|
|
|
const { formState } = useContext(PorterFormContext);
|
|
|
+ const [resourceList, updateResourceList] = useState<any[]>(props.value);
|
|
|
|
|
|
const {
|
|
|
newWebsocket,
|
|
|
@@ -17,6 +18,14 @@ const ResourceList: React.FC<ResourceListField> = (props) => {
|
|
|
closeWebsocket,
|
|
|
} = useWebsockets();
|
|
|
|
|
|
+ const sortAndUpdateResources = (list: any[]) => {
|
|
|
+ list.sort((a, b) => {
|
|
|
+ return b.timestamp.localeCompare(a.timestamp);
|
|
|
+ });
|
|
|
+
|
|
|
+ updateResourceList(list);
|
|
|
+ };
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
let { group, version, resource } = props.context.config;
|
|
|
let apiEndpoint = `/api/projects/${currentProject.id}/clusters/${currentCluster.id}/namespaces/${formState.variables.namespace}/releases/${formState.variables.currentChart.name}/0/form_stream?`;
|
|
|
@@ -24,15 +33,50 @@ const ResourceList: React.FC<ResourceListField> = (props) => {
|
|
|
|
|
|
const wsConfig = {
|
|
|
onmessage(evt: MessageEvent) {
|
|
|
- console.log("EVENT IS", evt);
|
|
|
+ let { data, kind } = JSON.parse(evt.data);
|
|
|
+
|
|
|
+ // parse for name and label, which uniquely identify a resource
|
|
|
+ for (let [key] of Object.entries(data)) {
|
|
|
+ // check the name and label in the value
|
|
|
+ let { name, label } = data[key][0];
|
|
|
+
|
|
|
+ // attempt to find a corresponding name and label in the current array
|
|
|
+ let foundMatch = false;
|
|
|
+
|
|
|
+ resourceList.forEach((resource, index) => {
|
|
|
+ if (resource.name == name && resource.label == label) {
|
|
|
+ foundMatch = true;
|
|
|
+
|
|
|
+ switch (kind) {
|
|
|
+ case "update":
|
|
|
+ case "create":
|
|
|
+ // replace this resource in the list
|
|
|
+ resourceList[index] = data[key][0];
|
|
|
+ break;
|
|
|
+ case "delete":
|
|
|
+ // remove this resource from the list
|
|
|
+ resourceList.splice(index, 1);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!foundMatch && kind != "delete") {
|
|
|
+ // add this resource to the list
|
|
|
+ resourceList.push(data[key][0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ sortAndUpdateResources([...resourceList]);
|
|
|
},
|
|
|
onerror() {
|
|
|
- closeWebsocket("testing");
|
|
|
+ closeWebsocket("stream");
|
|
|
},
|
|
|
};
|
|
|
|
|
|
- newWebsocket("testing", apiEndpoint, wsConfig);
|
|
|
- openWebsocket("testing");
|
|
|
+ newWebsocket("stream", apiEndpoint, wsConfig);
|
|
|
+ openWebsocket("stream");
|
|
|
|
|
|
return () => {
|
|
|
closeAllWebsockets();
|
|
|
@@ -41,14 +85,14 @@ const ResourceList: React.FC<ResourceListField> = (props) => {
|
|
|
|
|
|
return (
|
|
|
<ResourceListWrapper>
|
|
|
- {props.value?.map((resource: any, i: number) => {
|
|
|
+ {resourceList?.map((resource: any, i: number) => {
|
|
|
if (resource.data) {
|
|
|
return (
|
|
|
<ExpandableResource
|
|
|
key={i}
|
|
|
button={props?.settings?.options["resource-button"]}
|
|
|
resource={resource}
|
|
|
- isLast={i === props.value.length - 1}
|
|
|
+ isLast={i === resourceList.length - 1}
|
|
|
roundAllCorners={true}
|
|
|
/>
|
|
|
);
|