fix(log): input text visibility + space-in-date 502

- UnifiedQueryPanel: fix JS operator precedence — .replace(' ','T') was
  called on '.000Z' suffix instead of concatenated string, resulting in
  '2026-06-27 12:46:28.000Z' (space not replaced) → ES 502
- normalizeTime: add space→T fallback for backward compat
- SyntaxHighlightInput: fix z-index layering (textarea z=2 was covering
  pre z=1, making highlighted text invisible). Move bg/border to parent,
  textarea bg→transparent, pre above textarea
This commit is contained in:
attacker committed 2026-06-27 12:54:31 +00:00
1 parent d40042d86e
commit 7af10097c9
3 files changed
+9 -6

No files matched your search

+1
View File
@@ -91,3 +91,4 @@ backend/cmd/static/
# kubectl 二进制(预打包进镜像,避免 Docker build 时网络下载) # kubectl 二进制(预打包进镜像,避免 Docker build 时网络下载)
backend/kubectl backend/kubectl
opsxsql/ opsxsql/
test_monitoring_es.py
+2
View File
@@ -155,6 +155,8 @@ func (h *LogProxyHandler) QueryES(c *gin.Context) {
if s == "" { if s == "" {
return s return s
} }
// 空格 → T(兼容前端未正确转换的格式)// Logan.Li
s = strings.Replace(s, " ", "T", 1)
// 查找时间部分结束位置(Z 或 +) // 查找时间部分结束位置(Z 或 +)
tzIdx := strings.IndexAny(s, "Z+") tzIdx := strings.IndexAny(s, "Z+")
timePart := s timePart := s
@@ -113,13 +113,13 @@ function SyntaxHighlightInput({ value, onChange, engine, placeholder }: {
}; };
const html = useMemo(() => highlightSyntax(value, engine), [value, engine]); const html = useMemo(() => highlightSyntax(value, engine), [value, engine]);
return ( return (
<div className="relative flex-1 min-w-[120px]" style={{ height: '40px' }}> <div className="relative flex-1 min-w-[120px]" style={{ height: '40px', background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', borderRadius: '0.25rem' }}>
<pre ref={preRef} className="absolute inset-0 m-0 font-mono text-xs rounded pointer-events-none overflow-hidden whitespace-pre-wrap break-all px-3 py-2.5" style={{ background: 'transparent', border: '1px solid transparent', lineHeight: '20px', color: 'var(--dg-text-primary)', zIndex: 1 }} dangerouslySetInnerHTML={{ __html: html }} />
<textarea ref={taRef} value={value} onChange={e => onChange(e.target.value)} onScroll={sync} onKeyDown={onKey} spellCheck={false} autoComplete="off" rows={1} <textarea ref={taRef} value={value} onChange={e => onChange(e.target.value)} onScroll={sync} onKeyDown={onKey} spellCheck={false} autoComplete="off" rows={1}
className="absolute inset-0 w-full h-full font-mono text-xs rounded resize-none outline-none overflow-auto whitespace-pre-wrap break-all px-3 py-2.5" className="absolute inset-0 w-full h-full font-mono text-xs rounded resize-none outline-none overflow-auto whitespace-pre-wrap break-all px-3 py-2.5"
style={{ background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'transparent', caretColor: 'var(--dg-text-primary)', lineHeight: '20px', zIndex: 2 }} style={{ background: 'transparent', color: 'transparent', caretColor: 'var(--dg-text-primary)', lineHeight: '20px', zIndex: 1 }}
placeholder={placeholder} /> placeholder={placeholder} />
{!value && <div className="absolute inset-0 flex items-center px-3 pointer-events-none" style={{ zIndex: 1 }}><span className="text-xs font-mono" style={{ color: 'var(--dg-text-muted)' }}>{placeholder}</span></div>} <pre ref={preRef} className="absolute inset-0 m-0 font-mono text-xs rounded pointer-events-none overflow-hidden whitespace-pre-wrap break-all px-3 py-2.5" style={{ background: 'transparent', lineHeight: '20px', color: 'var(--dg-text-primary)', zIndex: 2 }} dangerouslySetInnerHTML={{ __html: html }} />
{!value && <div className="absolute inset-0 flex items-center px-3 pointer-events-none" style={{ zIndex: 3 }}><span className="text-xs font-mono" style={{ color: 'var(--dg-text-muted)' }}>{placeholder}</span></div>}
</div> </div>
); );
} }
@@ -203,8 +203,8 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
// 真实 API 查询 // 真实 API 查询
try { try {
const startISO = timeRange.start + (timeRange.start.includes('T') ? '' : '.000Z').replace(' ', 'T'); const startISO = (timeRange.start + (timeRange.start.includes('T') ? '' : '.000Z')).replace(' ', 'T');
const endISO = timeRange.end + (timeRange.end.includes('T') ? '' : '.000Z').replace(' ', 'T'); const endISO = (timeRange.end + (timeRange.end.includes('T') ? '' : '.000Z')).replace(' ', 'T');
let result: any; let result: any;
if (effEngine === 'loki') { if (effEngine === 'loki') {