-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReplace Potainer localhost URLs.user.js
More file actions
125 lines (108 loc) · 4.6 KB
/
Replace Potainer localhost URLs.user.js
File metadata and controls
125 lines (108 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// ==UserScript==
// @name Replace Potainer localhost URLs
// @namespace tampermonkey-replace-localhost-urls
// @version 1.3
// @description Replaces localhost URLs on specific Potainer pages with the full server address, preserving the original port from the URL
// @author SimonTheCoder
// @match https://192.168.1.66:9443/*
// @match https://192.168.1.67:9443/*
// ==/UserScript==
(function() {
'use strict';
// Get the current server address
var serverAddress = window.location.hostname;
// Replace localhost URLs with the full server address, preserving the original port from the URL
const replaceURLs = () => {
const elements = document.querySelectorAll('a[href*="0.0.0.0:"]');
if(elements.length == 0) return;
console.log("find elemnt:", elements);
if(document.title.match(/_67/)!=null){
serverAddress = "192.168.1.67";
}
for (const element of elements) {
const url = element.href;
const replacedURL = url.replace('0.0.0.0:', `${serverAddress}:`);
console.log("replacedURL:",url," -> ", replacedURL);
element.href = replacedURL;
}
};
// 配置 Webhook 的基础地址
const WEBHOOK_BASE_URL = "http://192.168.1.66:5678/webhook/update-container";
// 定义按钮的样式类名,用于防止重复添加
const BUTTON_CLASS = "user-script-update-btn";
// 添加自定义样式
const style = document.createElement('style');
style.innerHTML = `
.${BUTTON_CLASS} {
display: inline-flex;
align-items: center;
justify-content: center;
margin-left: 10px;
padding: 2px 6px;
font-size: 12px;
color: #ffffff;
background-color: #2b3862; /* Portainer 深蓝色风格 */
border: 1px solid #48557d;
border-radius: 4px;
text-decoration: none !important;
cursor: pointer;
transition: background-color 0.2s;
}
.${BUTTON_CLASS}:hover {
background-color: #3f8fe3; /* 悬停变为亮蓝色 */
color: white;
}
.${BUTTON_CLASS} svg {
width: 12px;
height: 12px;
margin-right: 4px;
}
`;
document.head.appendChild(style);
// 主处理函数
function addUpdateButtons() {
// 1. 查找特定的表格 (使用 data-cy 属性定位最准确)
const table = document.querySelector('table[data-cy="docker-containers-datatable"]');
if (!table) return;
// 2. 获取所有行
const rows = table.querySelectorAll('tbody tr');
rows.forEach(row => {
// 3. 获取 Name 列 (通常是第2列,索引为1,因为第1列是checkbox)
const tds = row.querySelectorAll('td');
if (tds.length < 2) return;
const nameTd = tds[1];
// 防止重复添加
if (nameTd.querySelector(`.${BUTTON_CLASS}`)) return;
// 4. 获取容器名称 (从 title 属性或文本中获取)
const nameLink = nameTd.querySelector('a');
if (!nameLink) return;
const containerName = nameLink.textContent.trim();
// 5. 创建按钮
const btn = document.createElement('a');
btn.href = `${WEBHOOK_BASE_URL}?name=${encodeURIComponent(containerName)}`;
btn.target = "_blank"; // 在新标签页打开,如果想静默请求,需要改用 fetch
btn.className = BUTTON_CLASS;
btn.title = `Update container: ${containerName}`;
// 添加一个小图标 (Upload icon)
btn.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
</svg>
Update
`;
// 6. 追加到单元格
nameTd.style.display = "flex"; // 确保 flex 布局使名字和按钮对齐
nameTd.style.alignItems = "center";
nameTd.appendChild(btn);
});
}
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === "childList" && document.readyState === "complete") {
replaceURLs();
addUpdateButtons();
}
});
});
observer.observe(document, { childList: true, subtree: true });
})();