pyxecm 2.0.3__py3-none-any.whl → 3.0.0__py3-none-any.whl
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.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm/coreshare.py +76 -8
- pyxecm/helper/data.py +16 -24
- pyxecm/helper/otel_config.py +26 -0
- pyxecm/helper/web.py +1 -2
- pyxecm/otca.py +1356 -16
- pyxecm/otcs.py +4238 -758
- pyxecm/otds.py +4 -12
- pyxecm/otmm.py +4 -5
- pyxecm/py.typed +0 -0
- pyxecm-3.0.0.dist-info/METADATA +48 -0
- pyxecm-3.0.0.dist-info/RECORD +96 -0
- {pyxecm-2.0.3.dist-info → pyxecm-3.0.0.dist-info}/WHEEL +1 -2
- pyxecm-3.0.0.dist-info/entry_points.txt +4 -0
- {pyxecm/customizer/api → pyxecm_api}/__main__.py +1 -1
- pyxecm_api/agents/__init__.py +7 -0
- pyxecm_api/agents/app.py +13 -0
- pyxecm_api/agents/functions.py +119 -0
- pyxecm_api/agents/models.py +10 -0
- pyxecm_api/agents/otcm_knowledgegraph/functions.py +85 -0
- pyxecm_api/agents/otcm_knowledgegraph/models.py +61 -0
- pyxecm_api/agents/otcm_knowledgegraph/router.py +74 -0
- pyxecm_api/agents/otcm_user_agent/models.py +20 -0
- pyxecm_api/agents/otcm_user_agent/router.py +65 -0
- pyxecm_api/agents/otcm_workspace_agent/models.py +40 -0
- pyxecm_api/agents/otcm_workspace_agent/router.py +200 -0
- pyxecm_api/app.py +221 -0
- {pyxecm/customizer/api → pyxecm_api}/auth/functions.py +10 -2
- {pyxecm/customizer/api → pyxecm_api}/auth/router.py +4 -3
- {pyxecm/customizer/api → pyxecm_api}/common/functions.py +39 -9
- {pyxecm/customizer/api → pyxecm_api}/common/metrics.py +1 -2
- {pyxecm/customizer/api → pyxecm_api}/common/router.py +12 -11
- {pyxecm/customizer/api → pyxecm_api}/settings.py +30 -6
- {pyxecm/customizer/api → pyxecm_api}/terminal/router.py +1 -1
- {pyxecm/customizer/api → pyxecm_api}/v1_csai/router.py +39 -10
- pyxecm_api/v1_csai/statics/bindings/utils.js +189 -0
- pyxecm_api/v1_csai/statics/tom-select/tom-select.complete.min.js +356 -0
- pyxecm_api/v1_csai/statics/tom-select/tom-select.css +334 -0
- pyxecm_api/v1_csai/statics/vis-9.1.2/vis-network.css +1 -0
- pyxecm_api/v1_csai/statics/vis-9.1.2/vis-network.min.js +27 -0
- pyxecm_api/v1_maintenance/__init__.py +1 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_maintenance/functions.py +3 -3
- {pyxecm/customizer/api → pyxecm_api}/v1_maintenance/router.py +8 -8
- pyxecm_api/v1_otcs/__init__.py +1 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_otcs/functions.py +7 -5
- {pyxecm/customizer/api → pyxecm_api}/v1_otcs/router.py +24 -13
- pyxecm_api/v1_payload/__init__.py +1 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_payload/functions.py +10 -7
- {pyxecm/customizer/api → pyxecm_api}/v1_payload/router.py +11 -10
- {pyxecm/customizer → pyxecm_customizer}/__init__.py +8 -0
- {pyxecm/customizer → pyxecm_customizer}/__main__.py +15 -21
- {pyxecm/customizer → pyxecm_customizer}/browser_automation.py +414 -103
- {pyxecm/customizer → pyxecm_customizer}/customizer.py +178 -116
- {pyxecm/customizer → pyxecm_customizer}/guidewire.py +60 -20
- {pyxecm/customizer → pyxecm_customizer}/k8s.py +4 -4
- pyxecm_customizer/knowledge_graph.py +719 -0
- pyxecm_customizer/log.py +35 -0
- {pyxecm/customizer → pyxecm_customizer}/m365.py +41 -33
- {pyxecm/customizer → pyxecm_customizer}/payload.py +2359 -1991
- {pyxecm/customizer/api/common → pyxecm_customizer}/payload_list.py +57 -65
- {pyxecm/customizer → pyxecm_customizer}/salesforce.py +1 -1
- {pyxecm/customizer → pyxecm_customizer}/sap.py +6 -2
- {pyxecm/customizer → pyxecm_customizer}/servicenow.py +2 -4
- {pyxecm/customizer → pyxecm_customizer}/settings.py +7 -6
- {pyxecm/customizer → pyxecm_customizer}/successfactors.py +40 -28
- {pyxecm/customizer → pyxecm_customizer}/translate.py +14 -10
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/__main__.py +1 -1
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/app.py +16 -6
- pyxecm/customizer/api/app.py +0 -163
- pyxecm/customizer/log.py +0 -107
- pyxecm/customizer/nhc.py +0 -1169
- pyxecm/customizer/openapi.py +0 -258
- pyxecm/customizer/pht.py +0 -1357
- pyxecm-2.0.3.dist-info/METADATA +0 -119
- pyxecm-2.0.3.dist-info/RECORD +0 -78
- pyxecm-2.0.3.dist-info/licenses/LICENSE +0 -202
- pyxecm-2.0.3.dist-info/top_level.txt +0 -1
- {pyxecm/customizer/api → pyxecm_api}/__init__.py +0 -0
- {pyxecm/customizer/api/auth → pyxecm_api/agents/otcm_knowledgegraph}/__init__.py +0 -0
- {pyxecm/customizer/api/common → pyxecm_api/agents/otcm_user_agent}/__init__.py +0 -0
- {pyxecm/customizer/api/v1_csai → pyxecm_api/agents/otcm_workspace_agent}/__init__.py +0 -0
- {pyxecm/customizer/api/v1_maintenance → pyxecm_api/auth}/__init__.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/auth/models.py +0 -0
- {pyxecm/customizer/api/v1_otcs → pyxecm_api/common}/__init__.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/common/models.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/terminal/__init__.py +0 -0
- {pyxecm/customizer/api/v1_payload → pyxecm_api/v1_csai}/__init__.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_csai/models.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_maintenance/models.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_payload/models.py +0 -0
- {pyxecm/customizer → pyxecm_customizer}/exceptions.py +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/__init__.py +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/settings.py +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/static/favicon.avif +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/templates/maintenance.html +0 -0
|
@@ -8,28 +8,29 @@ import tempfile
|
|
|
8
8
|
from http import HTTPStatus
|
|
9
9
|
from typing import Annotated
|
|
10
10
|
|
|
11
|
-
from fastapi import APIRouter, Depends, HTTPException, Query, Response
|
|
11
|
+
from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response
|
|
12
12
|
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
|
|
13
13
|
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from pyxecm.customizer.api.common.functions import PAYLOAD_LIST, list_files_in_directory
|
|
17
|
-
from pyxecm.customizer.api.common.models import CustomizerStatus
|
|
14
|
+
from pyxecm_api.auth.functions import get_authorized_user
|
|
15
|
+
from pyxecm_api.auth.models import User
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
from .functions import PAYLOAD_LIST, list_files_in_directory
|
|
18
|
+
from .models import CustomizerStatus
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
router = APIRouter()
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger("pyxecm_api.common")
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
@router.get("/", include_in_schema=False)
|
|
25
|
-
async def redirect_to_api() -> RedirectResponse:
|
|
26
|
+
async def redirect_to_api(request: Request) -> RedirectResponse:
|
|
26
27
|
"""Redirect from / to /api.
|
|
27
28
|
|
|
28
29
|
Returns:
|
|
29
30
|
None
|
|
30
31
|
|
|
31
32
|
"""
|
|
32
|
-
return RedirectResponse(url="
|
|
33
|
+
return RedirectResponse(url=f"{request.url.path}api")
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
@router.get(path="/status", name="Get Status")
|
|
@@ -74,7 +75,7 @@ def shutdown(user: Annotated[User, Depends(get_authorized_user)]) -> JSONRespons
|
|
|
74
75
|
return JSONResponse({"status": "shutdown"}, status_code=HTTPStatus.ACCEPTED)
|
|
75
76
|
|
|
76
77
|
|
|
77
|
-
@router.get(path="/browser_automations/assets")
|
|
78
|
+
@router.get(path="/browser_automations/assets", tags=["payload"])
|
|
78
79
|
def list_browser_automation_files(
|
|
79
80
|
user: Annotated[User, Depends(get_authorized_user)], # noqa: ARG001
|
|
80
81
|
) -> JSONResponse:
|
|
@@ -90,7 +91,7 @@ def list_browser_automation_files(
|
|
|
90
91
|
return JSONResponse(result)
|
|
91
92
|
|
|
92
93
|
|
|
93
|
-
@router.get(path="/browser_automations/download")
|
|
94
|
+
@router.get(path="/browser_automations/download", tags=["payload"])
|
|
94
95
|
def get_browser_automation_file(
|
|
95
96
|
user: Annotated[User, Depends(get_authorized_user)], # noqa: ARG001
|
|
96
97
|
file: Annotated[str, Query(description="File name")],
|
|
@@ -16,28 +16,38 @@ from pydantic_settings import (
|
|
|
16
16
|
class CustomizerAPISettings(BaseSettings):
|
|
17
17
|
"""Settings for the Customizer API."""
|
|
18
18
|
|
|
19
|
+
title: str = Field(default="Customizer API", description="Name of the API Service")
|
|
20
|
+
description: str = Field(
|
|
21
|
+
default="API provided by [pyxecm](https://github.com/opentext/pyxecm). The documentation for the payload syntax can be found [here](https://opentext.github.io/pyxecm/payload-syntax/).",
|
|
22
|
+
description="Descriptive text on the SwaggerUI page.",
|
|
23
|
+
)
|
|
24
|
+
|
|
19
25
|
api_key: str | None = Field(
|
|
20
26
|
default=None,
|
|
21
27
|
description="Optional API KEY that can be specified that has access to the Customizer API, bypassing the OTDS authentication.",
|
|
22
28
|
)
|
|
23
29
|
bind_address: str = Field(default="0.0.0.0", description="Interface to bind the Customizer API.") # noqa: S104
|
|
24
30
|
bind_port: int = Field(default=8000, description="Port to bind the Customizer API to")
|
|
25
|
-
workers: int = Field(default=1, description="Number of workers to use for the API
|
|
26
|
-
root_path: str = Field(default="
|
|
31
|
+
workers: int = Field(default=1, description="Number of workers to use for the API background tasks")
|
|
32
|
+
root_path: str = Field(default="", description="Root path for the Customizer API")
|
|
27
33
|
openapi_url: str = Field(default="/api/openapi.json", description="OpenAPI URL")
|
|
34
|
+
reload: bool = Field(default=False, description="Enable or disable the autoreload feature")
|
|
28
35
|
|
|
36
|
+
concurrent_payloads: int = Field(
|
|
37
|
+
default=3, description="Maximum number of concurrent payloads that are executed at the same time."
|
|
38
|
+
)
|
|
29
39
|
import_payload: bool = Field(default=False)
|
|
30
40
|
payload: str = Field(
|
|
31
41
|
default="/payload/payload.yml.gz.b64",
|
|
32
|
-
description="Path to a single
|
|
42
|
+
description="Path to a single payload file to be loaded.",
|
|
33
43
|
)
|
|
34
44
|
payload_dir: str = Field(
|
|
35
45
|
default="/payload-external/",
|
|
36
|
-
description="Path to a directory of
|
|
46
|
+
description="Path to a directory of payload files. All files in this directory will be loaded in alphabetical order and dependencies will be added automatically on the previous object. So all payload in this folder will be processed sequentially in alphabetical oder.",
|
|
37
47
|
)
|
|
38
48
|
payload_dir_optional: str = Field(
|
|
39
49
|
default="/payload-optional/",
|
|
40
|
-
description="Path of
|
|
50
|
+
description="Path of payload files to be loaded. No additional logic for dependencies will be applied, they need to be managed within the payloadSettings section of each payload. See -> payloadOptions in the Payload Syntax documentation.",
|
|
41
51
|
)
|
|
42
52
|
|
|
43
53
|
temp_dir: str = Field(
|
|
@@ -46,6 +56,9 @@ class CustomizerAPISettings(BaseSettings):
|
|
|
46
56
|
)
|
|
47
57
|
|
|
48
58
|
loglevel: Literal["INFO", "DEBUG", "WARNING", "ERROR"] = "INFO"
|
|
59
|
+
log_payload_processing: bool = Field(
|
|
60
|
+
default=False, description="Print the customizer payload processing log messages to stdout"
|
|
61
|
+
)
|
|
49
62
|
logfolder: str = Field(
|
|
50
63
|
default=os.path.join(tempfile.gettempdir(), "customizer"),
|
|
51
64
|
description="Logfolder for Customizer logfiles",
|
|
@@ -59,6 +72,12 @@ class CustomizerAPISettings(BaseSettings):
|
|
|
59
72
|
default="default",
|
|
60
73
|
description="Namespace to use for otxecm resource lookups",
|
|
61
74
|
)
|
|
75
|
+
|
|
76
|
+
maintenance_page: bool = Field(
|
|
77
|
+
default=True,
|
|
78
|
+
description="Start the Maintenance Page server.",
|
|
79
|
+
)
|
|
80
|
+
|
|
62
81
|
maintenance_mode: bool = Field(
|
|
63
82
|
default=False,
|
|
64
83
|
description="Automatically enable and disable the maintenance mode during payload deployments.",
|
|
@@ -94,7 +113,7 @@ class CustomizerAPISettings(BaseSettings):
|
|
|
94
113
|
)
|
|
95
114
|
|
|
96
115
|
csai: bool = Field(
|
|
97
|
-
default=
|
|
116
|
+
default=False,
|
|
98
117
|
description="Enable the CSAI integration",
|
|
99
118
|
)
|
|
100
119
|
|
|
@@ -103,6 +122,11 @@ class CustomizerAPISettings(BaseSettings):
|
|
|
103
122
|
description="Prefix for the CSAI",
|
|
104
123
|
)
|
|
105
124
|
|
|
125
|
+
csai_studio_integration: bool = Field(
|
|
126
|
+
default=False,
|
|
127
|
+
description="Enable the CSAI Studio Integration",
|
|
128
|
+
)
|
|
129
|
+
|
|
106
130
|
upload_folder: str = Field(default=os.path.join(tempfile.gettempdir(), "upload"), description="Folder for uploads")
|
|
107
131
|
|
|
108
132
|
upload_key: str = Field(default=str(uuid.uuid4()), description="Upload key for the Logs")
|
|
@@ -10,7 +10,7 @@ import subprocess
|
|
|
10
10
|
|
|
11
11
|
from fastapi import APIRouter, HTTPException, Query, WebSocket, WebSocketDisconnect, status
|
|
12
12
|
|
|
13
|
-
from
|
|
13
|
+
from pyxecm_api.auth.functions import get_authorized_user, get_current_user
|
|
14
14
|
|
|
15
15
|
router = APIRouter(tags=["terminal"])
|
|
16
16
|
|
|
@@ -4,20 +4,22 @@ import logging
|
|
|
4
4
|
from http import HTTPStatus
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
|
-
from fastapi import APIRouter, Body, Depends
|
|
8
|
-
from fastapi.responses import JSONResponse
|
|
9
|
-
|
|
10
|
-
from pyxecm.customizer.api.auth.functions import get_authorized_user
|
|
11
|
-
from pyxecm.customizer.api.auth.models import User
|
|
12
|
-
from pyxecm.customizer.api.common.functions import get_k8s_object, get_otcs_object, get_settings
|
|
13
|
-
from pyxecm.customizer.api.settings import CustomizerAPISettings
|
|
14
|
-
from pyxecm.customizer.api.v1_csai.models import CSAIEmbedMetadata
|
|
15
|
-
from pyxecm.customizer.k8s import K8s
|
|
7
|
+
from fastapi import APIRouter, Body, Depends, Query
|
|
8
|
+
from fastapi.responses import HTMLResponse, JSONResponse
|
|
16
9
|
from pyxecm.otcs import OTCS
|
|
10
|
+
from pyxecm_customizer.k8s import K8s
|
|
11
|
+
|
|
12
|
+
from pyxecm_api.agents.functions import get_otca_object
|
|
13
|
+
from pyxecm_api.auth.functions import get_authorized_user
|
|
14
|
+
from pyxecm_api.auth.models import User
|
|
15
|
+
from pyxecm_api.common.functions import get_k8s_object, get_otcs_object, get_settings
|
|
16
|
+
from pyxecm_api.settings import CustomizerAPISettings
|
|
17
|
+
|
|
18
|
+
from .models import CSAIEmbedMetadata
|
|
17
19
|
|
|
18
20
|
router = APIRouter(prefix="/api/v1/csai", tags=["csai"])
|
|
19
21
|
|
|
20
|
-
logger = logging.getLogger("
|
|
22
|
+
logger = logging.getLogger("pyxecm_api.v1_csai")
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
@router.post("/metadata")
|
|
@@ -110,3 +112,30 @@ def set_csai_config_data(
|
|
|
110
112
|
k8s_object.restart_deployment(deployment)
|
|
111
113
|
|
|
112
114
|
return get_csai_config_data(user=user, k8s_object=k8s_object, settings=settings)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@router.get("/graph")
|
|
118
|
+
def get_csai_graph(name: Annotated[str, Query(..., description="Name of the Graph")]) -> HTMLResponse:
|
|
119
|
+
"""Display the graph of the given name.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
otca (Annotated[OTCA, Depends): Generic OTCA Objec
|
|
123
|
+
name (str): name of the graph
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
HTMLResponse: _description_
|
|
127
|
+
|
|
128
|
+
"""
|
|
129
|
+
otca = get_otca_object(otcs_object=None)
|
|
130
|
+
|
|
131
|
+
graphs = otca.get_graphs()
|
|
132
|
+
graph = [g for g in graphs if g["name"] == name]
|
|
133
|
+
|
|
134
|
+
if graph:
|
|
135
|
+
filename = otca.visualize_graph(graph[0]["id"])
|
|
136
|
+
|
|
137
|
+
with open(filename) as f:
|
|
138
|
+
file_content = f.read()
|
|
139
|
+
|
|
140
|
+
logger.info("name: %s", name)
|
|
141
|
+
return HTMLResponse(status_code=200, content=file_content)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
function neighbourhoodHighlight(params) {
|
|
2
|
+
// console.log("in nieghbourhoodhighlight");
|
|
3
|
+
allNodes = nodes.get({ returnType: "Object" });
|
|
4
|
+
// originalNodes = JSON.parse(JSON.stringify(allNodes));
|
|
5
|
+
// if something is selected:
|
|
6
|
+
if (params.nodes.length > 0) {
|
|
7
|
+
highlightActive = true;
|
|
8
|
+
var i, j;
|
|
9
|
+
var selectedNode = params.nodes[0];
|
|
10
|
+
var degrees = 2;
|
|
11
|
+
|
|
12
|
+
// mark all nodes as hard to read.
|
|
13
|
+
for (let nodeId in allNodes) {
|
|
14
|
+
// nodeColors[nodeId] = allNodes[nodeId].color;
|
|
15
|
+
allNodes[nodeId].color = "rgba(200,200,200,0.5)";
|
|
16
|
+
if (allNodes[nodeId].hiddenLabel === undefined) {
|
|
17
|
+
allNodes[nodeId].hiddenLabel = allNodes[nodeId].label;
|
|
18
|
+
allNodes[nodeId].label = undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
var connectedNodes = network.getConnectedNodes(selectedNode);
|
|
22
|
+
var allConnectedNodes = [];
|
|
23
|
+
|
|
24
|
+
// get the second degree nodes
|
|
25
|
+
for (i = 1; i < degrees; i++) {
|
|
26
|
+
for (j = 0; j < connectedNodes.length; j++) {
|
|
27
|
+
allConnectedNodes = allConnectedNodes.concat(
|
|
28
|
+
network.getConnectedNodes(connectedNodes[j])
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// all second degree nodes get a different color and their label back
|
|
34
|
+
for (i = 0; i < allConnectedNodes.length; i++) {
|
|
35
|
+
// allNodes[allConnectedNodes[i]].color = "pink";
|
|
36
|
+
allNodes[allConnectedNodes[i]].color = "rgba(150,150,150,0.75)";
|
|
37
|
+
if (allNodes[allConnectedNodes[i]].hiddenLabel !== undefined) {
|
|
38
|
+
allNodes[allConnectedNodes[i]].label =
|
|
39
|
+
allNodes[allConnectedNodes[i]].hiddenLabel;
|
|
40
|
+
allNodes[allConnectedNodes[i]].hiddenLabel = undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// all first degree nodes get their own color and their label back
|
|
45
|
+
for (i = 0; i < connectedNodes.length; i++) {
|
|
46
|
+
// allNodes[connectedNodes[i]].color = undefined;
|
|
47
|
+
allNodes[connectedNodes[i]].color = nodeColors[connectedNodes[i]];
|
|
48
|
+
if (allNodes[connectedNodes[i]].hiddenLabel !== undefined) {
|
|
49
|
+
allNodes[connectedNodes[i]].label =
|
|
50
|
+
allNodes[connectedNodes[i]].hiddenLabel;
|
|
51
|
+
allNodes[connectedNodes[i]].hiddenLabel = undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// the main node gets its own color and its label back.
|
|
56
|
+
// allNodes[selectedNode].color = undefined;
|
|
57
|
+
allNodes[selectedNode].color = nodeColors[selectedNode];
|
|
58
|
+
if (allNodes[selectedNode].hiddenLabel !== undefined) {
|
|
59
|
+
allNodes[selectedNode].label = allNodes[selectedNode].hiddenLabel;
|
|
60
|
+
allNodes[selectedNode].hiddenLabel = undefined;
|
|
61
|
+
}
|
|
62
|
+
} else if (highlightActive === true) {
|
|
63
|
+
// console.log("highlightActive was true");
|
|
64
|
+
// reset all nodes
|
|
65
|
+
for (let nodeId in allNodes) {
|
|
66
|
+
// allNodes[nodeId].color = "purple";
|
|
67
|
+
allNodes[nodeId].color = nodeColors[nodeId];
|
|
68
|
+
// delete allNodes[nodeId].color;
|
|
69
|
+
if (allNodes[nodeId].hiddenLabel !== undefined) {
|
|
70
|
+
allNodes[nodeId].label = allNodes[nodeId].hiddenLabel;
|
|
71
|
+
allNodes[nodeId].hiddenLabel = undefined;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
highlightActive = false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// transform the object into an array
|
|
78
|
+
var updateArray = [];
|
|
79
|
+
if (params.nodes.length > 0) {
|
|
80
|
+
for (let nodeId in allNodes) {
|
|
81
|
+
if (allNodes.hasOwnProperty(nodeId)) {
|
|
82
|
+
// console.log(allNodes[nodeId]);
|
|
83
|
+
updateArray.push(allNodes[nodeId]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
nodes.update(updateArray);
|
|
87
|
+
} else {
|
|
88
|
+
// console.log("Nothing was selected");
|
|
89
|
+
for (let nodeId in allNodes) {
|
|
90
|
+
if (allNodes.hasOwnProperty(nodeId)) {
|
|
91
|
+
// console.log(allNodes[nodeId]);
|
|
92
|
+
// allNodes[nodeId].color = {};
|
|
93
|
+
updateArray.push(allNodes[nodeId]);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
nodes.update(updateArray);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function filterHighlight(params) {
|
|
101
|
+
allNodes = nodes.get({ returnType: "Object" });
|
|
102
|
+
// if something is selected:
|
|
103
|
+
if (params.nodes.length > 0) {
|
|
104
|
+
filterActive = true;
|
|
105
|
+
let selectedNodes = params.nodes;
|
|
106
|
+
|
|
107
|
+
// hiding all nodes and saving the label
|
|
108
|
+
for (let nodeId in allNodes) {
|
|
109
|
+
allNodes[nodeId].hidden = true;
|
|
110
|
+
if (allNodes[nodeId].savedLabel === undefined) {
|
|
111
|
+
allNodes[nodeId].savedLabel = allNodes[nodeId].label;
|
|
112
|
+
allNodes[nodeId].label = undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
for (let i=0; i < selectedNodes.length; i++) {
|
|
117
|
+
allNodes[selectedNodes[i]].hidden = false;
|
|
118
|
+
if (allNodes[selectedNodes[i]].savedLabel !== undefined) {
|
|
119
|
+
allNodes[selectedNodes[i]].label = allNodes[selectedNodes[i]].savedLabel;
|
|
120
|
+
allNodes[selectedNodes[i]].savedLabel = undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
} else if (filterActive === true) {
|
|
125
|
+
// reset all nodes
|
|
126
|
+
for (let nodeId in allNodes) {
|
|
127
|
+
allNodes[nodeId].hidden = false;
|
|
128
|
+
if (allNodes[nodeId].savedLabel !== undefined) {
|
|
129
|
+
allNodes[nodeId].label = allNodes[nodeId].savedLabel;
|
|
130
|
+
allNodes[nodeId].savedLabel = undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
filterActive = false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// transform the object into an array
|
|
137
|
+
var updateArray = [];
|
|
138
|
+
if (params.nodes.length > 0) {
|
|
139
|
+
for (let nodeId in allNodes) {
|
|
140
|
+
if (allNodes.hasOwnProperty(nodeId)) {
|
|
141
|
+
updateArray.push(allNodes[nodeId]);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
nodes.update(updateArray);
|
|
145
|
+
} else {
|
|
146
|
+
for (let nodeId in allNodes) {
|
|
147
|
+
if (allNodes.hasOwnProperty(nodeId)) {
|
|
148
|
+
updateArray.push(allNodes[nodeId]);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
nodes.update(updateArray);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function selectNode(nodes) {
|
|
156
|
+
network.selectNodes(nodes);
|
|
157
|
+
neighbourhoodHighlight({ nodes: nodes });
|
|
158
|
+
return nodes;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function selectNodes(nodes) {
|
|
162
|
+
network.selectNodes(nodes);
|
|
163
|
+
filterHighlight({nodes: nodes});
|
|
164
|
+
return nodes;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function highlightFilter(filter) {
|
|
168
|
+
let selectedNodes = []
|
|
169
|
+
let selectedProp = filter['property']
|
|
170
|
+
if (filter['item'] === 'node') {
|
|
171
|
+
let allNodes = nodes.get({ returnType: "Object" });
|
|
172
|
+
for (let nodeId in allNodes) {
|
|
173
|
+
if (allNodes[nodeId][selectedProp] && filter['value'].includes((allNodes[nodeId][selectedProp]).toString())) {
|
|
174
|
+
selectedNodes.push(nodeId)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (filter['item'] === 'edge'){
|
|
179
|
+
let allEdges = edges.get({returnType: 'object'});
|
|
180
|
+
// check if the selected property exists for selected edge and select the nodes connected to the edge
|
|
181
|
+
for (let edge in allEdges) {
|
|
182
|
+
if (allEdges[edge][selectedProp] && filter['value'].includes((allEdges[edge][selectedProp]).toString())) {
|
|
183
|
+
selectedNodes.push(allEdges[edge]['from'])
|
|
184
|
+
selectedNodes.push(allEdges[edge]['to'])
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
selectNodes(selectedNodes)
|
|
189
|
+
}
|