Skip to content

Commit 4cf6267

Browse files
Added settings & features for administrators in organizations (#653)
1 parent 5af6a8d commit 4cf6267

38 files changed

+1332
-92
lines changed

app/MindWork AI Studio/Assistants/DocumentAnalysis/DocumentAnalysisAssistant.razor

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,16 @@ else
136136

137137
<ReadFileContent Text="@T("Load output rules from document")" @bind-FileContent="@this.policyOutputRules" Disabled="@this.IsNoPolicySelectedOrProtected"/>
138138

139-
<MudText Typo="Typo.h5" Class="mt-6 mb-1">
140-
@T("Preparation for enterprise distribution")
141-
</MudText>
142-
143-
<MudButton StartIcon="@Icons.Material.Filled.ContentCopy" Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsEnterpriseConfiguration ?? false))" Variant="Variant.Filled" Color="Color.Default" OnClick="@this.ExportPolicyAsConfiguration">
144-
@T("Export policy as configuration section")
145-
</MudButton>
139+
@if (this.SettingsManager.ConfigurationData.App.ShowAdminSettings)
140+
{
141+
<MudText Typo="Typo.h5" Class="mt-6 mb-1">
142+
@T("Preparation for enterprise distribution")
143+
</MudText>
144+
145+
<MudButton StartIcon="@Icons.Material.Filled.ContentCopy" Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsEnterpriseConfiguration ?? false))" Variant="Variant.Filled" Color="Color.Default" OnClick="@this.ExportPolicyAsConfiguration">
146+
@T("Export policy as configuration section")
147+
</MudButton>
148+
}
146149
}
147150
</ExpansionPanel>
148151

app/MindWork AI Studio/Assistants/I18N/allTexts.lua

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,12 +2080,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898060643"]
20802080
-- Select the language for the app.
20812081
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"] = "Select the language for the app."
20822082

2083+
-- When enabled, additional administration options become visible. These options are intended for IT staff to manage organization-wide configuration, e.g. configuring and exporting providers for an entire organization.
2084+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2013281167"] = "When enabled, additional administration options become visible. These options are intended for IT staff to manage organization-wide configuration, e.g. configuring and exporting providers for an entire organization."
2085+
20832086
-- The global keyboard shortcut for toggling voice recording. This shortcut works system-wide, even when the app is not focused.
20842087
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2143741496"] = "The global keyboard shortcut for toggling voice recording. This shortcut works system-wide, even when the app is not focused."
20852088

20862089
-- Disable dictation and transcription
20872090
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T215381891"] = "Disable dictation and transcription"
20882091

2092+
-- Enterprise Administration
2093+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2277116008"] = "Enterprise Administration"
2094+
20892095
-- Language behavior
20902096
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior"
20912097

@@ -2095,6 +2101,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"]
20952101
-- Language
20962102
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
20972103

2104+
-- Administration settings are visible
2105+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591866808"] = "Administration settings are visible"
2106+
20982107
-- Save energy?
20992108
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3100928009"] = "Save energy?"
21002109

@@ -2104,9 +2113,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3165555978"]
21042113
-- App Options
21052114
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3577148634"] = "App Options"
21062115

2116+
-- Generate a 256-bit encryption secret for encrypting API keys in configuration plugins. Deploy this secret to client machines via Group Policy (Windows Registry) or environment variables. Providers can then be exported with encrypted API keys using the export buttons in the provider settings.
2117+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T362833"] = "Generate a 256-bit encryption secret for encrypting API keys in configuration plugins. Deploy this secret to client machines via Group Policy (Windows Registry) or environment variables. Providers can then be exported with encrypted API keys using the export buttons in the provider settings."
2118+
21072119
-- When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available.
21082120
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3652888444"] = "When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."
21092121

2122+
-- Show administration settings?
2123+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3694781396"] = "Show administration settings?"
2124+
2125+
-- Read the Enterprise IT documentation for details.
2126+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3705451321"] = "Read the Enterprise IT documentation for details."
2127+
21102128
-- Enable spellchecking?
21112129
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T3914529369"] = "Enable spellchecking?"
21122130

@@ -2140,6 +2158,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T817101267"]
21402158
-- Would you like to set one provider as the default for the entire app? When you configure a different provider for an assistant, it will always take precedence.
21412159
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T844514734"] = "Would you like to set one provider as the default for the entire app? When you configure a different provider for an assistant, it will always take precedence."
21422160

2161+
-- Generate an encryption secret and copy it to the clipboard
2162+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T922066419"] = "Generate an encryption secret and copy it to the clipboard"
2163+
2164+
-- Administration settings are not visible
2165+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T929143445"] = "Administration settings are not visible"
2166+
21432167
-- Delete
21442168
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T1469573738"] = "Delete"
21452169

@@ -2197,6 +2221,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T78223
21972221
-- Provider
21982222
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T900237532"] = "Provider"
21992223

2224+
-- Export configuration
2225+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T975426229"] = "Export configuration"
2226+
2227+
-- Cannot export the encrypted API key: No enterprise encryption secret is configured.
2228+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERBASE::T1832230847"] = "Cannot export the encrypted API key: No enterprise encryption secret is configured."
2229+
2230+
-- This provider has an API key configured. Do you want to include the encrypted API key in the export? Note: The recipient will need the same encryption secret to use the API key.
2231+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERBASE::T3368145670"] = "This provider has an API key configured. Do you want to include the encrypted API key in the export? Note: The recipient will need the same encryption secret to use the API key."
2232+
2233+
-- Export API Key?
2234+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERBASE::T4010580285"] = "Export API Key?"
2235+
22002236
-- Show provider's confidence level?
22012237
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T1052533048"] = "Show provider's confidence level?"
22022238

@@ -2302,6 +2338,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T853225
23022338
-- Provider
23032339
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T900237532"] = "Provider"
23042340

2341+
-- Export configuration
2342+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T975426229"] = "Export configuration"
2343+
23052344
-- No transcription provider configured yet.
23062345
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T1079350363"] = "No transcription provider configured yet."
23072346

@@ -2356,6 +2395,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T78
23562395
-- Provider
23572396
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T900237532"] = "Provider"
23582397

2398+
-- Export configuration
2399+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELTRANSCRIPTION::T975426229"] = "Export configuration"
2400+
23592401
-- Copy {0} to the clipboard
23602402
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::TEXTINFOLINE::T2206391442"] = "Copy {0} to the clipboard"
23612403

@@ -5017,6 +5059,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1420062548"] = "Database version
50175059
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
50185060
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1421513382"] = "This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library."
50195061

5062+
-- Encryption secret: is not configured
5063+
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1560776885"] = "Encryption secret: is not configured"
5064+
50205065
-- Qdrant is a vector database and vector similarity search engine. We use it to realize local RAG—retrieval-augmented generation—within AI Studio. Thanks for the effort and great work that has been and is being put into Qdrant.
50215066
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1619832053"] = "Qdrant is a vector database and vector similarity search engine. We use it to realize local RAG—retrieval-augmented generation—within AI Studio. Thanks for the effort and great work that has been and is being put into Qdrant."
50225067

@@ -5053,6 +5098,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1915240766"] = "In order to use
50535098
-- This library is used to convert HTML to Markdown. This is necessary, e.g., when you provide a URL as input for an assistant.
50545099
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1924365263"] = "This library is used to convert HTML to Markdown. This is necessary, e.g., when you provide a URL as input for an assistant."
50555100

5101+
-- Encryption secret: is configured
5102+
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1931141322"] = "Encryption secret: is configured"
5103+
50565104
-- We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust.
50575105
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1943216839"] = "We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust."
50585106

app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateInterval)" Data="@ConfigurationSelectDataFactory.GetUpdateIntervalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInterval = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInterval, out var meta) && meta.IsLocked"/>
1818
<ConfigurationSelect OptionDescription="@T("Update installation method")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateInstallation)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviourData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInstallation = selectedValue)" OptionHelp="@T("Should updates be installed automatically or manually?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInstallation, out var meta) && meta.IsLocked"/>
1919
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
20+
<ConfigurationOption OptionDescription="@T("Show administration settings?")" LabelOn="@T("Administration settings are visible")" LabelOff="@T("Administration settings are not visible")" State="@(() => this.SettingsManager.ConfigurationData.App.ShowAdminSettings)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.ShowAdminSettings = updatedState)" OptionHelp="@T("When enabled, additional administration options become visible. These options are intended for IT staff to manage organization-wide configuration, e.g. configuring and exporting providers for an entire organization.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.ShowAdminSettings, out var meta) && meta.IsLocked"/>
2021
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.PreviewVisibility, out var meta) && meta.IsLocked"/>
2122

2223
@if (this.SettingsManager.ConfigurationData.App.PreviewVisibility > PreviewVisibility.NONE)
@@ -36,4 +37,25 @@
3637
<ConfigurationSelect OptionDescription="@T("Select a transcription provider")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UseTranscriptionProvider)" Data="@this.GetFilteredTranscriptionProviders()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UseTranscriptionProvider = selectedValue)" OptionHelp="@T("Select a transcription provider for transcribing your voice. Without a selected provider, dictation and transcription features will be disabled.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UseTranscriptionProvider, out var meta) && meta.IsLocked"/>
3738
<ConfigurationShortcut ShortcutId="Shortcut.VOICE_RECORDING_TOGGLE" OptionDescription="@T("Voice recording shortcut")" Shortcut="@(() => this.SettingsManager.ConfigurationData.App.ShortcutVoiceRecording)" ShortcutUpdate="@(shortcut => this.SettingsManager.ConfigurationData.App.ShortcutVoiceRecording = shortcut)" OptionHelp="@T("The global keyboard shortcut for toggling voice recording. This shortcut works system-wide, even when the app is not focused.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.ShortcutVoiceRecording, out var meta) && meta.IsLocked"/>
3839
}
39-
</ExpansionPanel>
40+
41+
@if (this.SettingsManager.ConfigurationData.App.ShowAdminSettings)
42+
{
43+
<MudText Typo="Typo.h5" Class="mt-6 mb-3">
44+
@T("Enterprise Administration")
45+
</MudText>
46+
47+
<MudText Typo="Typo.body2" Class="mb-3">
48+
@T("Generate a 256-bit encryption secret for encrypting API keys in configuration plugins. Deploy this secret to client machines via Group Policy (Windows Registry) or environment variables. Providers can then be exported with encrypted API keys using the export buttons in the provider settings.")
49+
<MudLink Href="https://github.com/MindWorkAI/AI-Studio/blob/main/documentation/Enterprise%20IT.md" Target="_blank">
50+
@T("Read the Enterprise IT documentation for details.")
51+
</MudLink>
52+
</MudText>
53+
54+
<MudButton StartIcon="@Icons.Material.Filled.Key"
55+
Variant="Variant.Filled"
56+
Color="Color.Primary"
57+
OnClick="@this.GenerateEncryptionSecret">
58+
@T("Generate an encryption secret and copy it to the clipboard")
59+
</MudButton>
60+
}
61+
</ExpansionPanel>

app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ namespace AIStudio.Components.Settings;
66

77
public partial class SettingsPanelApp : SettingsPanelBase
88
{
9+
private async Task GenerateEncryptionSecret()
10+
{
11+
var secret = EnterpriseEncryption.GenerateSecret();
12+
await this.RustService.CopyText2Clipboard(this.Snackbar, secret);
13+
}
14+
915
private IEnumerable<ConfigurationSelectData<string>> GetFilteredTranscriptionProviders()
1016
{
1117
yield return new(T("Disable dictation and transcription"), string.Empty);

app/MindWork AI Studio/Components/Settings/SettingsPanelBase.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ public abstract class SettingsPanelBase : MSGComponentBase
1515

1616
[Inject]
1717
protected RustService RustService { get; init; } = null!;
18+
19+
[Inject]
20+
protected ISnackbar Snackbar { get; init; } = null!;
1821
}

app/MindWork AI Studio/Components/Settings/SettingsPanelEmbeddings.razor

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@using AIStudio.Provider
22
@using AIStudio.Settings.DataModel
3-
@inherits SettingsPanelBase
3+
@inherits SettingsPanelProviderBase
44

55
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
66
{
@@ -22,7 +22,7 @@
2222
<col style="width: 12em;"/>
2323
<col style="width: 12em;"/>
2424
<col/>
25-
<col style="width: 16em;"/>
25+
<col style="width: 22em;"/>
2626
</ColGroup>
2727
<HeaderContent>
2828
<MudTh>#</MudTh>
@@ -53,6 +53,9 @@
5353
<MudTooltip Text="@T("Edit")">
5454
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="@(() => this.EditEmbeddingProvider(context))"/>
5555
</MudTooltip>
56+
<MudTooltip Text="@T("Export configuration")">
57+
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Dataset" OnClick="@(() => this.ExportEmbeddingProvider(context))"/>
58+
</MudTooltip>
5659
<MudTooltip Text="@T("Delete")">
5760
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => this.DeleteEmbeddingProvider(context))"/>
5861
</MudTooltip>
@@ -73,4 +76,4 @@
7376
@T("Add Embedding")
7477
</MudButton>
7578
</ExpansionPanel>
76-
}
79+
}

app/MindWork AI Studio/Components/Settings/SettingsPanelEmbeddings.razor.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace AIStudio.Components.Settings;
99

10-
public partial class SettingsPanelEmbeddings : SettingsPanelBase
10+
public partial class SettingsPanelEmbeddings : SettingsPanelProviderBase
1111
{
1212
[Parameter]
1313
public List<ConfigurationSelectData<string>> AvailableEmbeddingProviders { get; set; } = new();
@@ -114,6 +114,14 @@ private async Task DeleteEmbeddingProvider(EmbeddingProvider provider)
114114
await this.UpdateEmbeddingProviders();
115115
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
116116
}
117+
118+
private async Task ExportEmbeddingProvider(EmbeddingProvider provider)
119+
{
120+
if (provider == EmbeddingProvider.NONE)
121+
return;
122+
123+
await this.ExportProvider(provider, SecretStoreType.EMBEDDING_PROVIDER, provider.ExportAsConfigurationSection);
124+
}
117125

118126
private async Task UpdateEmbeddingProviders()
119127
{
@@ -123,4 +131,4 @@ private async Task UpdateEmbeddingProviders()
123131

124132
await this.AvailableEmbeddingProvidersChanged.InvokeAsync(this.AvailableEmbeddingProviders);
125133
}
126-
}
134+
}

0 commit comments

Comments
 (0)