ui: move validation warning to tab header as badge

This commit is contained in:
sokol
2026-02-18 18:01:38 +03:00
parent 5cc15eb87a
commit 325699d036
2 changed files with 13 additions and 18 deletions

View File

@@ -21,10 +21,6 @@ export function ConfigTemplate(props: ConfigTemplateProps) {
}
}, [props.config.template.content, mode]);
// Validate placeholders (check if @placeholders@ have matching params)
const missingPlaceholders = props.config.validatePlaceholders();
const hasValidationWarnings = missingPlaceholders.length > 0;
function handleEdit() {
setOriginalContent(props.config.template.content);
setDraftContent(props.config.template.content);
@@ -71,21 +67,11 @@ export function ConfigTemplate(props: ConfigTemplateProps) {
<div className="config-template-editor">
{mode === 'view' ? (
<>
<div className="mb-2 d-flex gap-2 align-items-center">
<div className="mb-2">
<button className="btn btn-primary btn-sm" onClick={handleEdit}>
Edit
</button>
{hasValidationWarnings && (
<span className="text-warning">
{missingPlaceholders.length} placeholder(s) without params
</span>
)}
</div>
{hasValidationWarnings && (
<div className="alert alert-warning py-2 px-3 mb-2" style={{ fontSize: '0.875rem' }}>
<strong>Missing parameters:</strong> {missingPlaceholders.join(", ")}
</div>
)}
<Highlight className="language-json">
{props.config.template.content || "{}"}
</Highlight>

View File

@@ -10,9 +10,13 @@ import { ConfigTemplate } from "./ConfigTemplate";
export function Content(props: { config: Config, env: Env, onTemplateSaved: (newContent: string) => void }) {
const [selectTab, setTab] = useState(ContentType.Env);
// Validate placeholders for warning badge
const missingPlaceholders = props.config.validatePlaceholders();
const hasValidationWarnings = missingPlaceholders.length > 0;
return (
<>
<ContentTabs onSelected={(id) => setTab(id)} selectedTab={selectTab} />
<ContentTabs onSelected={(id) => setTab(id)} selectedTab={selectTab} hasValidationWarnings={hasValidationWarnings} />
<div className="">
{selectTab == ContentType.Env ? (<ContentParams env={props.env} />) : ""}
{selectTab == ContentType.Json ? (<ConfigTemplate config={props.config} onSaved={props.onTemplateSaved} />) : ""}
@@ -30,7 +34,7 @@ enum ContentType {
Test = 3
}
function ContentTabs(props: { onSelected: (id: ContentType) => void, selectedTab: ContentType }) {
function ContentTabs(props: { onSelected: (id: ContentType) => void, selectedTab: ContentType, hasValidationWarnings: boolean }) {
function clickHandler(type: ContentType) {
props.onSelected(type);
}
@@ -45,7 +49,12 @@ function ContentTabs(props: { onSelected: (id: ContentType) => void, selectedTab
<a className={"nav-link" + isActive(ContentType.Env)} aria-current="page" href="#" onClick={() => clickHandler(ContentType.Env)}>Env</a>
</li>
<li className="nav-item">
<a className={"nav-link" + isActive(ContentType.Json)} href="#" onClick={() => clickHandler(ContentType.Json)} >Content Template</a>
<a className={"nav-link" + isActive(ContentType.Json)} href="#" onClick={() => clickHandler(ContentType.Json)} >
Content Template
{props.hasValidationWarnings && (
<span className="badge bg-warning text-dark ms-1">!</span>
)}
</a>
</li>
<li className="nav-item">
<a className={"nav-link" + isActive(ContentType.Raw)} href="#" onClick={() => clickHandler(ContentType.Raw)}>Raw template</a>