Files
configucci/src/componets/content/Content.tsx

149 lines
4.4 KiB
TypeScript

import { useState } from 'react';
import { Tabs, TabPanel, CodeBlock } from '../../components/ui';
import { Env } from '../../models/Env';
import { Config } from '../../models/Config';
import { ConfigTemplateEditor } from './ConfigTemplate';
import { Builder } from '../../builders';
interface ContentProps {
config: Config;
env: Env;
onTemplateSaved: (newContent: string) => void;
}
export function Content({ config, env, onTemplateSaved }: ContentProps) {
const [activeTab, setActiveTab] = useState('env');
// Validate placeholders for warning badge
const missingPlaceholders = config.validatePlaceholders();
const hasValidationWarnings = missingPlaceholders.length > 0;
const tabs: Array<{ id: string; label: string; badge?: string | number; badgeVariant?: 'warning' | 'danger' }> = [
{ id: 'env', label: 'Env' },
{
id: 'template',
label: 'Content Template',
badge: hasValidationWarnings ? '!' : undefined,
badgeVariant: hasValidationWarnings ? 'warning' : undefined,
},
{ id: 'raw', label: 'Raw Template' },
{ id: 'test', label: 'Test-filled' },
];
return (
<div className="bg-white rounded-xl shadow-lg border border-slate-200 overflow-hidden">
<Tabs tabs={tabs} activeTab={activeTab} onChange={setActiveTab} />
<div className="p-4">
<TabPanel isActive={activeTab === 'env'}>
<ContentParams env={env} />
</TabPanel>
<TabPanel isActive={activeTab === 'template'}>
<ConfigTemplateEditor config={config} onSaved={onTemplateSaved} />
</TabPanel>
<TabPanel isActive={activeTab === 'raw'}>
<ContentRaw config={config} env={env} />
</TabPanel>
<TabPanel isActive={activeTab === 'test'}>
<ContentTest config={config} env={env} />
</TabPanel>
</div>
</div>
);
}
function ContentParams({ env }: { env: Env }) {
const xml = Builder.getEnv(env).build();
return (
<div className="animate-fade-in">
<CodeBlock code={xml} language="xml" maxHeight="500px" />
</div>
);
}
function ContentRaw({ config }: { config: Config; env: Env }) {
const envsXml = Builder.getEnvs(config.envs);
const templateContent = config.template.content;
const xml = `<engine>
${envsXml}
<template>
${templateContent}
</template>
</engine>`;
return (
<div className="animate-fade-in">
<CodeBlock code={xml} language="xml" maxHeight="500px" />
</div>
);
}
function ContentTest({ config, env }: { config: Config; env: Env }) {
const [selectedEnvId, setSelectedEnvId] = useState(env.id ?? 0);
const selectedEnv = config.envs.find(e => e.id === selectedEnvId) ?? env;
const filledTemplate = fillTemplate(config, selectedEnv);
const selectOptions = config.envs.map((e) => ({
value: e.id ?? 0,
label: e.name ?? 'Unknown',
}));
return (
<div className="animate-fade-in space-y-4">
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-slate-700">Select Environment:</label>
<select
className="px-3 py-1.5 border border-slate-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
value={selectedEnvId}
onChange={(e) => setSelectedEnvId(Number(e.target.value))}
>
{selectOptions.map((opt) => (
<option key={opt.value} value={opt.value}>{opt.label}</option>
))}
</select>
</div>
<CodeBlock code={filledTemplate} language="json" maxHeight="500px" />
</div>
);
}
function fillTemplate(config: Config, env: Env): string {
const defaultEnv = config.envs.find((e) => e.name === 'DEFAULT');
const paramMap = new Map<string, string>();
// Load DEFAULT values first
if (defaultEnv) {
for (const param of defaultEnv.params) {
if (param.name && param.value !== undefined) {
paramMap.set(param.name, param.value);
}
}
}
// Override with selected environment values
for (const param of env.params) {
if (param.name && param.value !== undefined) {
paramMap.set(param.name, param.value);
}
}
let filledTemplate = config.template.content;
const placeholderRegex = /@(\w+)@/g;
filledTemplate = filledTemplate.replace(placeholderRegex, (_, paramName) => {
if (paramName === Config.ENV_NAME_PARAM) {
return env.name ?? '--NO-VALUE--';
}
return paramMap.get(paramName) ?? '--NO-VALUE--';
});
return filledTemplate;
}