407 lines
12 KiB
TypeScript
407 lines
12 KiB
TypeScript
import { peopleRules } from "../constants/toolIcons";
|
|
|
|
/**
|
|
* 获取规则设置组件的 HTML 内容
|
|
*/
|
|
export function getRulesSettingsComponentContent(): string {
|
|
return `
|
|
<div class="rules-settings">
|
|
<div class="rules-header">
|
|
<h3 class="settings-section-title">个人规则</h3>
|
|
<button class="add-rule-button" onclick="showAddRuleModal()">+ 创建</button>
|
|
</div>
|
|
|
|
<div class="settings-section">
|
|
<div class="settings-item">
|
|
<div class="settings-item-header">
|
|
<label class="settings-item-label">启用个人规则</label>
|
|
<span class="settings-item-description">规则将在每次对话时自动应用</span>
|
|
</div>
|
|
<label class="settings-switch">
|
|
<input type="checkbox" id="enablePersonalRulesCheckbox" checked>
|
|
<span class="settings-switch-slider"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rules-list" id="rulesList">
|
|
<!-- 规则列表将动态插入这里 -->
|
|
</div>
|
|
|
|
<!-- 添加/编辑规则弹窗 -->
|
|
<div class="rule-modal" id="ruleModal" style="display: none;">
|
|
<div class="rule-modal-content">
|
|
<h4 id="modalTitle">创建个人规则</h4>
|
|
<input
|
|
type="text"
|
|
class="rule-name-input"
|
|
id="ruleNameInput"
|
|
placeholder="规则名称"
|
|
/>
|
|
<textarea
|
|
class="rule-textarea"
|
|
id="ruleTextarea"
|
|
placeholder="输入规则内容..."
|
|
rows="10"
|
|
></textarea>
|
|
<div class="rule-modal-actions">
|
|
<button class="settings-button settings-button-primary" onclick="saveRule()">保存</button>
|
|
<button class="settings-button settings-button-secondary" onclick="closeRuleModal()">取消</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 删除确认弹窗 -->
|
|
<div class="rule-modal" id="deleteConfirmModal" style="display: none;">
|
|
<div class="rule-modal-content" style="width: 400px;">
|
|
<h4>确认删除</h4>
|
|
<p id="deleteConfirmText" style="color: var(--vscode-foreground); margin: 16px 0;"></p>
|
|
<div class="rule-modal-actions">
|
|
<button class="settings-button settings-button-primary" onclick="confirmDelete()">确定</button>
|
|
<button class="settings-button settings-button-secondary" onclick="closeDeleteConfirmModal()">取消</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
/**
|
|
* 获取规则设置组件的 CSS 样式
|
|
*/
|
|
export function getRulesSettingsComponentStyles(): string {
|
|
return `
|
|
.rules-settings {
|
|
max-width: 700px;
|
|
}
|
|
|
|
.rules-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.add-rule-button {
|
|
padding: 6px 12px;
|
|
background: var(--vscode-button-background);
|
|
color: var(--vscode-button-foreground);
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.add-rule-button:hover {
|
|
background: var(--vscode-button-hoverBackground);
|
|
}
|
|
|
|
.rules-list {
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.rule-item {
|
|
background: var(--vscode-editor-background);
|
|
border: 1px solid var(--vscode-input-border);
|
|
border-radius: 4px;
|
|
padding: 12px;
|
|
margin-bottom: 8px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
position: relative;
|
|
}
|
|
|
|
.rule-item-name {
|
|
color: var(--vscode-foreground);
|
|
font-size: 13px;
|
|
}
|
|
|
|
.rule-item > div:first-child svg {
|
|
background-color: rgba(148, 204, 241, 0.3);
|
|
border-radius: 4px;
|
|
padding: 4px;
|
|
}
|
|
|
|
.rule-item-menu {
|
|
position: relative;
|
|
}
|
|
|
|
.rule-menu-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.rule-menu-icon:hover {
|
|
background: var(--vscode-toolbar-hoverBackground);
|
|
}
|
|
|
|
.rule-dropdown {
|
|
position: absolute;
|
|
right: 0;
|
|
top: 28px;
|
|
background: var(--vscode-menu-background);
|
|
border: 1px solid var(--vscode-menu-border);
|
|
border-radius: 4px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
z-index: 100;
|
|
min-width: 100px;
|
|
}
|
|
|
|
.rule-dropdown button {
|
|
display: block;
|
|
width: 100%;
|
|
padding: 8px 12px;
|
|
background: transparent;
|
|
color: var(--vscode-menu-foreground);
|
|
border: none;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.rule-dropdown button:hover {
|
|
background: var(--vscode-menu-selectionBackground);
|
|
color: var(--vscode-menu-selectionForeground);
|
|
}
|
|
|
|
.rule-modal {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.rule-modal-content {
|
|
background: var(--vscode-editor-background);
|
|
border: 1px solid var(--vscode-input-border);
|
|
border-radius: 6px;
|
|
padding: 20px;
|
|
width: 500px;
|
|
max-width: 90%;
|
|
}
|
|
|
|
.rule-modal-content h4 {
|
|
margin: 0 0 16px 0;
|
|
color: var(--vscode-foreground);
|
|
}
|
|
|
|
.rule-name-input {
|
|
width: 100%;
|
|
padding: 8px;
|
|
background: var(--vscode-input-background);
|
|
color: var(--vscode-input-foreground);
|
|
border: 1px solid var(--vscode-input-border);
|
|
border-radius: 4px;
|
|
font-size: 13px;
|
|
margin-bottom: 12px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.rule-name-input:focus {
|
|
outline: none;
|
|
border-color: var(--vscode-focusBorder);
|
|
}
|
|
|
|
.rule-textarea {
|
|
width: 100%;
|
|
padding: 12px;
|
|
background: var(--vscode-input-background);
|
|
color: var(--vscode-input-foreground);
|
|
border: 1px solid var(--vscode-input-border);
|
|
border-radius: 4px;
|
|
font-size: 13px;
|
|
font-family: var(--vscode-editor-font-family);
|
|
resize: vertical;
|
|
outline: none;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.rule-textarea:focus {
|
|
border-color: var(--vscode-focusBorder);
|
|
}
|
|
|
|
.rule-modal-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-top: 16px;
|
|
justify-content: flex-end;
|
|
}
|
|
`;
|
|
}
|
|
|
|
/**
|
|
* 获取规则设置组件的 JavaScript 脚本
|
|
*/
|
|
export function getRulesSettingsComponentScript(): string {
|
|
return `
|
|
let currentRules = [];
|
|
let editingRule = null;
|
|
let deletingFilename = null;
|
|
|
|
// 显示添加规则弹窗
|
|
function showAddRuleModal() {
|
|
editingRule = null;
|
|
document.getElementById('modalTitle').textContent = '创建个人规则';
|
|
document.getElementById('ruleNameInput').value = '';
|
|
document.getElementById('ruleTextarea').value = '';
|
|
document.getElementById('ruleModal').style.display = 'flex';
|
|
}
|
|
|
|
// 关闭弹窗
|
|
function closeRuleModal() {
|
|
document.getElementById('ruleModal').style.display = 'none';
|
|
closeAllDropdowns();
|
|
}
|
|
|
|
// 切换下拉菜单
|
|
function toggleDropdown(filename, event) {
|
|
event.stopPropagation();
|
|
closeAllDropdowns();
|
|
const dropdown = document.getElementById('dropdown-' + filename);
|
|
if (dropdown) {
|
|
dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
|
|
}
|
|
}
|
|
|
|
// 关闭所有下拉菜单
|
|
function closeAllDropdowns() {
|
|
document.querySelectorAll('.rule-dropdown').forEach(d => d.style.display = 'none');
|
|
}
|
|
|
|
// 点击页面其他地方关闭下拉菜单
|
|
document.addEventListener('click', closeAllDropdowns);
|
|
|
|
// 编辑规则
|
|
function editRule(filename) {
|
|
const rule = currentRules.find(r => r.filename === filename);
|
|
if (rule) {
|
|
editingRule = rule;
|
|
document.getElementById('modalTitle').textContent = '修改个人规则';
|
|
document.getElementById('ruleNameInput').value = rule.name;
|
|
document.getElementById('ruleTextarea').value = rule.content;
|
|
document.getElementById('ruleModal').style.display = 'flex';
|
|
}
|
|
}
|
|
|
|
// 保存规则
|
|
function saveRule() {
|
|
const name = document.getElementById('ruleNameInput').value.trim();
|
|
const content = document.getElementById('ruleTextarea').value.trim();
|
|
|
|
if (!name) {
|
|
alert('规则名称不能为空');
|
|
return;
|
|
}
|
|
if (!content) {
|
|
alert('规则内容不能为空');
|
|
return;
|
|
}
|
|
|
|
const enabled = document.getElementById('enablePersonalRulesCheckbox').checked;
|
|
|
|
if (editingRule) {
|
|
vscode.postMessage({
|
|
command: 'updatePersonalRule',
|
|
filename: editingRule.filename,
|
|
name: name,
|
|
content: content,
|
|
enabled: enabled
|
|
});
|
|
} else {
|
|
vscode.postMessage({
|
|
command: 'savePersonalRule',
|
|
name: name,
|
|
content: content,
|
|
enabled: enabled
|
|
});
|
|
}
|
|
|
|
closeRuleModal();
|
|
}
|
|
|
|
// 删除规则
|
|
function deleteRule(filename) {
|
|
closeAllDropdowns();
|
|
const rule = currentRules.find(r => r.filename === filename);
|
|
const ruleName = rule ? rule.name : filename;
|
|
|
|
deletingFilename = filename;
|
|
document.getElementById('deleteConfirmText').textContent = '确定要删除规则"' + ruleName + '"吗?此操作无法撤销。';
|
|
document.getElementById('deleteConfirmModal').style.display = 'flex';
|
|
}
|
|
|
|
// 关闭删除确认弹窗
|
|
function closeDeleteConfirmModal() {
|
|
document.getElementById('deleteConfirmModal').style.display = 'none';
|
|
deletingFilename = null;
|
|
}
|
|
|
|
// 确认删除
|
|
function confirmDelete() {
|
|
if (deletingFilename) {
|
|
vscode.postMessage({
|
|
command: 'deletePersonalRule',
|
|
filename: deletingFilename
|
|
});
|
|
}
|
|
closeDeleteConfirmModal();
|
|
}
|
|
|
|
// 渲染规则列表
|
|
function renderRulesList(rules) {
|
|
currentRules = rules || [];
|
|
const listEl = document.getElementById('rulesList');
|
|
|
|
if (currentRules.length === 0) {
|
|
listEl.innerHTML = '<div style="color: var(--vscode-descriptionForeground); padding: 16px; text-align: center;">暂无规则,点击"+ 创建"添加</div>';
|
|
return;
|
|
}
|
|
|
|
const peopleRulesIcon = '${peopleRules}';
|
|
|
|
listEl.innerHTML = currentRules.map(rule => \`
|
|
<div class="rule-item">
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
\${peopleRulesIcon}
|
|
<div class="rule-item-name">\${rule.filename}</div>
|
|
</div>
|
|
<div class="rule-item-menu">
|
|
<svg class="rule-menu-icon" onclick="toggleDropdown('\${rule.filename}', event)" viewBox="0 0 16 16" fill="currentColor">
|
|
<circle cx="8" cy="3" r="1.5"/>
|
|
<circle cx="8" cy="8" r="1.5"/>
|
|
<circle cx="8" cy="13" r="1.5"/>
|
|
</svg>
|
|
<div class="rule-dropdown" id="dropdown-\${rule.filename}" style="display: none;">
|
|
<button onclick="editRule('\${rule.filename}')">编辑</button>
|
|
<button onclick="deleteRule('\${rule.filename}')">删除</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
\`).join('');
|
|
}
|
|
|
|
// 加载规则列表
|
|
function loadPersonalRules(data) {
|
|
if (data && data.enabled !== undefined) {
|
|
document.getElementById('enablePersonalRulesCheckbox').checked = data.enabled;
|
|
}
|
|
if (data && data.rules) {
|
|
renderRulesList(data.rules);
|
|
}
|
|
}
|
|
|
|
// 页面加载时请求规则数据
|
|
vscode.postMessage({ command: 'loadPersonalRules' });
|
|
`;
|
|
}
|