feat(teamsbot): per-user settings API, system bot admin API, credentials removed from settings UI
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
dffebc8d73
commit
7366da06ac
2 changed files with 60 additions and 36 deletions
|
|
@ -180,7 +180,7 @@ export async function deleteSession(instanceId: string, sessionId: string): Prom
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get teamsbot configuration.
|
* Get teamsbot configuration (instance-level defaults).
|
||||||
*/
|
*/
|
||||||
export async function getConfig(instanceId: string): Promise<{ config: TeamsbotConfig }> {
|
export async function getConfig(instanceId: string): Promise<{ config: TeamsbotConfig }> {
|
||||||
const response = await api.get(`/api/teamsbot/${instanceId}/config`);
|
const response = await api.get(`/api/teamsbot/${instanceId}/config`);
|
||||||
|
|
@ -188,13 +188,54 @@ export async function getConfig(instanceId: string): Promise<{ config: TeamsbotC
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update teamsbot configuration.
|
* Update teamsbot configuration (instance-level defaults).
|
||||||
*/
|
*/
|
||||||
export async function updateConfig(instanceId: string, updates: ConfigUpdateRequest): Promise<{ config: TeamsbotConfig }> {
|
export async function updateConfig(instanceId: string, updates: ConfigUpdateRequest): Promise<{ config: TeamsbotConfig }> {
|
||||||
const response = await api.put(`/api/teamsbot/${instanceId}/config`, updates);
|
const response = await api.put(`/api/teamsbot/${instanceId}/config`, updates);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get per-user settings merged with instance defaults.
|
||||||
|
*/
|
||||||
|
export async function getUserSettings(instanceId: string): Promise<{ settings: any; effectiveConfig: TeamsbotConfig }> {
|
||||||
|
const response = await api.get(`/api/teamsbot/${instanceId}/settings`);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update per-user settings.
|
||||||
|
*/
|
||||||
|
export async function updateUserSettings(instanceId: string, updates: ConfigUpdateRequest): Promise<{ settings: any; effectiveConfig: TeamsbotConfig }> {
|
||||||
|
const response = await api.put(`/api/teamsbot/${instanceId}/settings`, updates);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset per-user settings to instance defaults.
|
||||||
|
*/
|
||||||
|
export async function resetUserSettings(instanceId: string): Promise<{ settings: null; effectiveConfig: TeamsbotConfig }> {
|
||||||
|
const response = await api.delete(`/api/teamsbot/${instanceId}/settings`);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemBot {
|
||||||
|
id: string;
|
||||||
|
mandateId: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
isActive: boolean;
|
||||||
|
creationDate?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List system bot accounts for this mandate.
|
||||||
|
*/
|
||||||
|
export async function listSystemBots(instanceId: string): Promise<{ bots: SystemBot[] }> {
|
||||||
|
const response = await api.get(`/api/teamsbot/${instanceId}/system-bots`);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test TTS voice with AI-generated sample text. Returns base64-encoded audio.
|
* Test TTS voice with AI-generated sample text. Returns base64-encoded audio.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,17 @@ export const TeamsbotSettingsView: React.FC = () => {
|
||||||
if (!instanceId) return;
|
if (!instanceId) return;
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const [configResult, languagesResult] = await Promise.all([
|
// Load per-user settings (merged with instance defaults)
|
||||||
teamsbotApi.getConfig(instanceId),
|
const [settingsResult, languagesResult] = await Promise.all([
|
||||||
|
teamsbotApi.getUserSettings(instanceId),
|
||||||
teamsbotApi.fetchLanguages(),
|
teamsbotApi.fetchLanguages(),
|
||||||
]);
|
]);
|
||||||
setConfig(configResult.config);
|
const effectiveConfig = settingsResult.effectiveConfig;
|
||||||
setFormData(configResult.config);
|
setConfig(effectiveConfig);
|
||||||
|
setFormData(effectiveConfig);
|
||||||
setLanguages(languagesResult);
|
setLanguages(languagesResult);
|
||||||
// Load voices for the current language
|
// Load voices for the current language
|
||||||
const lang = configResult.config.language || 'de-DE';
|
const lang = effectiveConfig.language || 'de-DE';
|
||||||
const voicesResult = await teamsbotApi.fetchVoices(lang);
|
const voicesResult = await teamsbotApi.fetchVoices(lang);
|
||||||
setVoices(voicesResult);
|
setVoices(voicesResult);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
@ -71,10 +73,11 @@ export const TeamsbotSettingsView: React.FC = () => {
|
||||||
setSuccessMsg(null);
|
setSuccessMsg(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await teamsbotApi.updateConfig(instanceId, formData);
|
// Save as per-user settings (not instance config)
|
||||||
setConfig(result.config);
|
const result = await teamsbotApi.updateUserSettings(instanceId, formData);
|
||||||
setFormData(result.config);
|
setConfig(result.effectiveConfig);
|
||||||
setSuccessMsg('Konfiguration gespeichert');
|
setFormData(result.effectiveConfig);
|
||||||
|
setSuccessMsg('Einstellungen gespeichert');
|
||||||
setTimeout(() => setSuccessMsg(null), 3000);
|
setTimeout(() => setSuccessMsg(null), 3000);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
setError(err.message || 'Fehler beim Speichern');
|
setError(err.message || 'Fehler beim Speichern');
|
||||||
|
|
@ -282,33 +285,13 @@ export const TeamsbotSettingsView: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bot Account */}
|
{/* Bot Account - managed by admin, read-only display */}
|
||||||
<div className={styles.settingsSection}>
|
<div className={styles.settingsSection}>
|
||||||
<h4 className={styles.sectionTitle}>Bot-Account (Microsoft)</h4>
|
<h4 className={styles.sectionTitle}>Bot-Account (Microsoft)</h4>
|
||||||
|
<span className={styles.hint}>
|
||||||
<div className={styles.formGroup}>
|
System-Bot-Accounts werden vom Administrator verwaltet und sind nicht direkt editierbar.
|
||||||
<label className={styles.label}>E-Mail</label>
|
Waehle beim Session-Start den gewuenschten Join-Modus.
|
||||||
<input
|
</span>
|
||||||
type="email"
|
|
||||||
className={styles.input}
|
|
||||||
value={formData.botAccountEmail || ''}
|
|
||||||
onChange={(e) => _updateField('botAccountEmail', e.target.value)}
|
|
||||||
placeholder="bot@ihrefirma.ch"
|
|
||||||
/>
|
|
||||||
<span className={styles.hint}>Dedizierter Microsoft-Account fuer authentifizierten Bot-Zugang. Leer = anonymer Gast.</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.formGroup}>
|
|
||||||
<label className={styles.label}>Passwort</label>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
className={styles.input}
|
|
||||||
value={formData.botAccountPassword || ''}
|
|
||||||
onChange={(e) => _updateField('botAccountPassword', e.target.value)}
|
|
||||||
placeholder="••••••••"
|
|
||||||
/>
|
|
||||||
<span className={styles.hint}>MFA muss fuer diesen Account deaktiviert sein. Passwort wird verschluesselt gespeichert.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Advanced Settings */}
|
{/* Advanced Settings */}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue