Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 88 additions & 3 deletions mcpgateway/static/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6674,7 +6674,7 @@ async function viewServer(serverId) {
toolsList.appendChild(toolItem);
});

// If more than maxToShow, add a summary badge
// If more than maxToShow, add a summary badge (clickable to expand)
if (server.associatedTools.length > maxToShow) {
const moreItem = document.createElement("div");
moreItem.className = "flex items-center space-x-2";
Expand All @@ -6686,6 +6686,32 @@ async function viewServer(serverId) {
const remaining = server.associatedTools.length - maxToShow;
moreBadge.textContent = `+${remaining} more`;

// Expand inline to show full list when clicked
moreBadge.addEventListener("click", () => {
toolsList.innerHTML = "";
(server.associatedTools || []).forEach((toolId) => {
const toolItem = document.createElement("div");
toolItem.className = "flex items-center space-x-2";

const toolBadge = document.createElement("span");
toolBadge.className =
"inline-block bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full dark:bg-green-900 dark:text-green-200";
toolBadge.textContent =
window.toolMapping && window.toolMapping[toolId]
? window.toolMapping[toolId]
: toolId;

const toolIdSpan = document.createElement("span");
toolIdSpan.className =
"text-xs text-gray-500 dark:text-gray-400";
toolIdSpan.textContent = `(${toolId})`;

toolItem.appendChild(toolBadge);
toolItem.appendChild(toolIdSpan);
toolsList.appendChild(toolItem);
});
});

moreItem.appendChild(moreBadge);
toolsList.appendChild(moreItem);
}
Expand Down Expand Up @@ -6740,7 +6766,7 @@ async function viewServer(serverId) {
resourcesList.appendChild(resourceItem);
});

// If more than maxToShow, add a summary badge
// If more than maxToShow, add a summary badge (clickable to expand)
if (server.associatedResources.length > maxToShow) {
const moreItem = document.createElement("div");
moreItem.className = "flex items-center space-x-2";
Expand All @@ -6753,6 +6779,38 @@ async function viewServer(serverId) {
server.associatedResources.length - maxToShow;
moreBadge.textContent = `+${remaining} more`;

moreBadge.addEventListener("click", () => {
resourcesList.innerHTML = "";
(server.associatedResources || []).forEach(
(resourceId) => {
const resourceItem =
document.createElement("div");
resourceItem.className =
"flex items-center space-x-2";

const resourceBadge =
document.createElement("span");
resourceBadge.className =
"inline-block bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full dark:bg-blue-900 dark:text-blue-200";
resourceBadge.textContent =
window.resourceMapping &&
window.resourceMapping[resourceId]
? window.resourceMapping[resourceId]
: `Resource ${resourceId}`;

const resourceIdSpan =
document.createElement("span");
resourceIdSpan.className =
"text-xs text-gray-500 dark:text-gray-400";
resourceIdSpan.textContent = `(${resourceId})`;

resourceItem.appendChild(resourceBadge);
resourceItem.appendChild(resourceIdSpan);
resourcesList.appendChild(resourceItem);
},
);
});

moreItem.appendChild(moreBadge);
resourcesList.appendChild(moreItem);
}
Expand Down Expand Up @@ -6806,7 +6864,7 @@ async function viewServer(serverId) {
promptsList.appendChild(promptItem);
});

// If more than maxToShow, add a summary badge
// If more than maxToShow, add a summary badge (clickable to expand)
if (server.associatedPrompts.length > maxToShow) {
const moreItem = document.createElement("div");
moreItem.className = "flex items-center space-x-2";
Expand All @@ -6819,6 +6877,33 @@ async function viewServer(serverId) {
server.associatedPrompts.length - maxToShow;
moreBadge.textContent = `+${remaining} more`;

moreBadge.addEventListener("click", () => {
promptsList.innerHTML = "";
(server.associatedPrompts || []).forEach((promptId) => {
const promptItem = document.createElement("div");
promptItem.className =
"flex items-center space-x-2";

const promptBadge = document.createElement("span");
promptBadge.className =
"inline-block bg-purple-100 text-purple-800 text-xs px-2 py-1 rounded-full dark:bg-purple-900 dark:text-purple-200";
promptBadge.textContent =
window.promptMapping &&
window.promptMapping[promptId]
? window.promptMapping[promptId]
: `Prompt ${promptId}`;

const promptIdSpan = document.createElement("span");
promptIdSpan.className =
"text-xs text-gray-500 dark:text-gray-400";
promptIdSpan.textContent = `(${promptId})`;

promptItem.appendChild(promptBadge);
promptItem.appendChild(promptIdSpan);
promptsList.appendChild(promptItem);
});
});

moreItem.appendChild(moreBadge);
promptsList.appendChild(moreItem);
}
Expand Down
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@
"overrides": {
"keyv": "5.1.0",
"minimatch": ">=10.2.1"
},
"dependencies": {
"alpinejs": "^3.15.8"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ __all__ = [
]

def py_scan_container(container: typing.Any, config: typing.Any) -> tuple[builtins.int, typing.Any, list]: ...

25 changes: 12 additions & 13 deletions plugins_rust/pii_filter/python/pii_filter_rust/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ __all__ = [
class PIIDetectorRust:
r"""
Main PII detector exposed to Python

# Example (Python)
```python
from pii_filter import PIIDetectorRust

config = {"detect_ssn": True, "detect_email": True}
detector = PIIDetectorRust(config)

text = "My SSN is 123-45-6789 and email is john@example.com"
detections = detector.detect(text)
print(detections) # {"ssn": [...], "email": [...]}

masked = detector.mask(text, detections)
print(masked) # "My SSN is [REDACTED] and email is [REDACTED]"
```
"""
def __new__(cls, config: typing.Any) -> PIIDetectorRust:
r"""
Create a new PII detector

# Arguments
* `config` - Python dictionary or Pydantic model with configuration

# Configuration Keys
* `detect_ssn` (bool): Detect Social Security Numbers
* `detect_credit_card` (bool): Detect credit card numbers
Expand All @@ -55,10 +55,10 @@ class PIIDetectorRust:
def detect(self, text: builtins.str) -> typing.Any:
r"""
Detect PII in text

# Arguments
* `text` - Text to scan for PII

# Returns
Dictionary mapping PII type to list of detections:
```python
Expand All @@ -75,23 +75,22 @@ class PIIDetectorRust:
def mask(self, text: builtins.str, detections: typing.Any) -> builtins.str:
r"""
Mask detected PII in text

# Arguments
* `text` - Original text
* `detections` - Detection results from detect()

# Returns
Masked text with PII replaced
"""
def process_nested(self, data: typing.Any, path: builtins.str) -> tuple[builtins.bool, typing.Any, typing.Any]:
r"""
Process nested data structures (dicts, lists, strings)

# Arguments
* `data` - Python object (dict, list, str, or other)
* `path` - Current path in the structure (for logging)

# Returns
Tuple of (modified: bool, new_data: Any, detections: dict)
"""

Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ def py_scan_container(container: typing.Any, config: typing.Any) -> tuple[builti
r"""
Scan Python container for secrets using optimized type dispatch
"""

Loading
Loading