mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-07-13 17:46:26 +00:00
Improved enterprise update policies & Flatpak support (#853)
Some checks are pending
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Sync Flatpak repo (push) Blocked by required conditions
Build and Release / Collect Flatpak artifacts (push) Blocked by required conditions
Some checks are pending
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Sync Flatpak repo (push) Blocked by required conditions
Build and Release / Collect Flatpak artifacts (push) Blocked by required conditions
This commit is contained in:
parent
5890b3734a
commit
2f81546cfe
@ -3001,6 +3001,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1059411425"]
|
||||
-- Do you want to show preview features in the app?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1118505044"] = "Do you want to show preview features in the app?"
|
||||
|
||||
-- AI Studio cannot check for updates when running as a Flatpak. Updates are managed outside the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1190632518"] = "AI Studio cannot check for updates when running as a Flatpak. Updates are managed outside the app."
|
||||
|
||||
-- Voice recording shortcut
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1278320412"] = "Voice recording shortcut"
|
||||
|
||||
@ -3043,9 +3046,15 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1890416390"]
|
||||
-- Which preview features would you like to enable?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898060643"] = "Which preview features would you like to enable?"
|
||||
|
||||
-- This setting has no effect while updates are disabled by your organization.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898114759"] = "This setting has no effect while updates are disabled by your organization."
|
||||
|
||||
-- Select the language for the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"] = "Select the language for the app."
|
||||
|
||||
-- Your organization has disabled update checks and installations.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1909339369"] = "Your organization has disabled update checks and installations."
|
||||
|
||||
-- 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.
|
||||
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."
|
||||
|
||||
@ -3064,6 +3073,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"]
|
||||
-- Update installation method
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Update installation method"
|
||||
|
||||
-- AI Studio cannot install updates when running as a Flatpak. Use the update method provided by your Flatpak distribution.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T244540698"] = "AI Studio cannot install updates when running as a Flatpak. Use the update method provided by your Flatpak distribution."
|
||||
|
||||
-- Language
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
|
||||
|
||||
@ -6286,6 +6298,12 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T25417398"] = "Update from v{0
|
||||
-- Install later
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T2936430090"] = "Install later"
|
||||
|
||||
-- Close
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEINSTRUCTIONSDIALOG::T3448155331"] = "Close"
|
||||
|
||||
-- Show me the latest release page
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEINSTRUCTIONSDIALOG::T59688848"] = "Show me the latest release page"
|
||||
|
||||
-- Create new workspace
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1541251414"] = "Create new workspace"
|
||||
|
||||
@ -6661,6 +6679,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1347508205"] = "Copies the confi
|
||||
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1388816916"] = "This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat."
|
||||
|
||||
-- Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1402243995"] = "Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio."
|
||||
|
||||
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
|
||||
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."
|
||||
|
||||
@ -6766,6 +6787,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2435772109"] = "Configuration or
|
||||
-- Configuration slot:
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T254943559"] = "Configuration slot:"
|
||||
|
||||
-- AI Studio cannot update itself when installed as a Flatpak. A Flathub listing is planned. Until then, you can find the latest release on GitHub.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T254976975"] = "AI Studio cannot update itself when installed as a Flatpak. A Flathub listing is planned. Until then, you can find the latest release on GitHub."
|
||||
|
||||
-- This library is used to determine the language of the operating system. This is necessary to set the language of the user interface.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2557014401"] = "This library is used to determine the language of the operating system. This is necessary to set the language of the user interface."
|
||||
|
||||
@ -7018,6 +7042,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T864851737"] = "Axum is used to p
|
||||
-- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T870640199"] = "For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose."
|
||||
|
||||
-- How to update
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T906183311"] = "How to update"
|
||||
|
||||
-- Install Pandoc
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T986578435"] = "Install Pandoc"
|
||||
|
||||
@ -7423,6 +7450,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107
|
||||
-- Toggle the sidebar: show the workspaces next to the chat when desired
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3711207137"] = "Toggle the sidebar: show the workspaces next to the chat when desired"
|
||||
|
||||
-- Updates disabled by your organization
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T4048970098"] = "Updates disabled by your organization"
|
||||
|
||||
-- Also show features in alpha: these are in development; expect bugs and missing features
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T4146964761"] = "Also show features in alpha: these are in development; expect bugs and missing features"
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Settings.DataModel
|
||||
@using AIStudio.Tools.Rust
|
||||
@using AIStudio.Tools.Services
|
||||
@inherits SettingsPanelBase
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Apps" HeaderText="@T("App Options")">
|
||||
@ -15,8 +16,8 @@
|
||||
<ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("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.")"/>
|
||||
<ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections.")"/>
|
||||
<ConfigurationSlider T="int" OptionDescription="@T("Request timeout")" Min="@ExternalHttpClientTimeout.MIN_HTTP_CLIENT_TIMEOUT_SECONDS" Max="@ExternalHttpClientTimeout.MAX_HTTP_CLIENT_TIMEOUT_SECONDS" Step="60" Unit="@T("seconds")" Value="@(() => this.SettingsManager.ConfigurationData.App.HttpClientTimeoutSeconds)" ValueUpdate="@(updatedValue => this.SettingsManager.ConfigurationData.App.HttpClientTimeoutSeconds = updatedValue)" OptionHelp="@T("How long AI Studio waits for external HTTP requests, such as AI providers, embeddings, transcription, ERI data sources, and enterprise configuration downloads.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.HttpClientTimeoutSeconds, out var meta) && meta.IsLocked"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.DisplayedUpdateInterval)" Data="@ConfigurationSelectDataFactory.GetManagedUpdateIntervalData(this.DisplayedUpdateInterval)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInterval = selectedValue)" OptionHelp="@this.UpdateIntervalHelp" IsLocked="@this.IsUpdateIntervalLocked"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Update installation method")" SelectedValue="@(() => this.DisplayedUpdateInstallation)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviourData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInstallation = selectedValue)" OptionHelp="@this.UpdateInstallationHelp" IsLocked="@this.IsUpdateInstallationLocked"/>
|
||||
<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.")"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Start page")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.StartPage)" Data="@ConfigurationSelectDataFactory.GetStartPageData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.StartPage = selectedValue)" OptionHelp="@this.GetStartPageHelpText()" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.StartPage, out var meta) && meta.IsLocked"/>
|
||||
<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"/>
|
||||
|
||||
@ -2,11 +2,62 @@ using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Settings.DataModel;
|
||||
using AIStudio.Tools.Rust;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Components.Settings;
|
||||
|
||||
public partial class SettingsPanelApp : SettingsPanelBase
|
||||
{
|
||||
[Inject]
|
||||
private UpdatePolicy UpdatePolicy { get; init; } = null!;
|
||||
|
||||
private UpdatePolicyMode updatePolicyMode;
|
||||
|
||||
private UpdateInterval DisplayedUpdateInterval => this.updatePolicyMode is UpdatePolicyMode.FLATPAK
|
||||
? UpdateInterval.NO_CHECK
|
||||
: this.SettingsManager.ConfigurationData.App.UpdateInterval;
|
||||
|
||||
private UpdateInstallation DisplayedUpdateInstallation => this.updatePolicyMode is UpdatePolicyMode.FLATPAK
|
||||
? UpdateInstallation.MANUAL
|
||||
: this.SettingsManager.ConfigurationData.App.UpdateInstallation;
|
||||
|
||||
private string UpdateIntervalHelp => this.updatePolicyMode switch
|
||||
{
|
||||
UpdatePolicyMode.ENTERPRISE_DISABLED => T("Your organization has disabled update checks and installations."),
|
||||
UpdatePolicyMode.FLATPAK => T("AI Studio cannot check for updates when running as a Flatpak. Updates are managed outside the app."),
|
||||
_ => T("How often should we check for app updates?")
|
||||
};
|
||||
|
||||
private string UpdateInstallationHelp => this.updatePolicyMode switch
|
||||
{
|
||||
UpdatePolicyMode.ENTERPRISE_DISABLED => T("This setting has no effect while updates are disabled by your organization."),
|
||||
UpdatePolicyMode.FLATPAK => T("AI Studio cannot install updates when running as a Flatpak. Use the update method provided by your Flatpak distribution."),
|
||||
_ => T("Should updates be installed automatically or manually?")
|
||||
};
|
||||
|
||||
private bool IsUpdateIntervalLocked() => this.updatePolicyMode is UpdatePolicyMode.ENTERPRISE_DISABLED or UpdatePolicyMode.FLATPAK ||
|
||||
ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInterval, out var meta) && meta.IsLocked;
|
||||
|
||||
private bool IsUpdateInstallationLocked() => this.updatePolicyMode is UpdatePolicyMode.ENTERPRISE_DISABLED or UpdatePolicyMode.FLATPAK ||
|
||||
ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInstallation, out var meta) && meta.IsLocked;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
|
||||
await base.OnInitializedAsync();
|
||||
this.updatePolicyMode = this.UpdatePolicy.CurrentMode;
|
||||
}
|
||||
|
||||
protected override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
{
|
||||
if (triggeredEvent is Event.CONFIGURATION_CHANGED)
|
||||
this.updatePolicyMode = this.UpdatePolicy.CurrentMode;
|
||||
|
||||
await base.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
|
||||
}
|
||||
|
||||
private ConfigurationShortcutData VoiceRecordingShortcut => new()
|
||||
{
|
||||
Id = Shortcut.VOICE_RECORDING_TOGGLE,
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
@inherits MSGComponentBase
|
||||
<MudDialog>
|
||||
<DialogContent>
|
||||
<MudJustifiedText Typo="Typo.body1">
|
||||
@this.Message
|
||||
</MudJustifiedText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@if (!string.IsNullOrWhiteSpace(this.ReleaseUrl))
|
||||
{
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@this.ReleaseUrl" Target="_blank">
|
||||
@T("Show me the latest release page")
|
||||
</MudButton>
|
||||
}
|
||||
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||
@T("Close")
|
||||
</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
@ -0,0 +1,19 @@
|
||||
using AIStudio.Components;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Dialogs;
|
||||
|
||||
public partial class UpdateInstructionsDialog : MSGComponentBase
|
||||
{
|
||||
[CascadingParameter]
|
||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string? ReleaseUrl { get; set; }
|
||||
|
||||
private void Close() => this.MudDialog.Close();
|
||||
}
|
||||
@ -29,6 +29,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
[Inject]
|
||||
private RustService RustService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private UpdatePolicy UpdatePolicy { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private AIJobService AIJobService { get; init; } = null!;
|
||||
|
||||
@ -186,6 +189,8 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.INSTALL_UPDATE:
|
||||
if (!this.UpdatePolicy.AllowsInstallations)
|
||||
break;
|
||||
this.performingUpdate = true;
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
@ -371,6 +376,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
|
||||
private async Task ShowUpdateDialog()
|
||||
{
|
||||
if (!this.UpdatePolicy.AllowsInstallations)
|
||||
return;
|
||||
|
||||
if(this.currentUpdateResponse is null)
|
||||
return;
|
||||
|
||||
@ -398,6 +406,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
if (!this.UpdatePolicy.AllowsInstallations)
|
||||
return;
|
||||
|
||||
this.performingUpdate = true;
|
||||
this.StateHasChanged();
|
||||
await this.RustService.InstallUpdate();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
@attribute [Route(Routes.ABOUT)]
|
||||
@using AIStudio.Tools.PluginSystem
|
||||
@using AIStudio.Tools.Services
|
||||
@inherits MSGComponentBase
|
||||
|
||||
<div class="inner-scrolling-context">
|
||||
@ -53,7 +54,7 @@
|
||||
<MudText Typo="Typo.body1">
|
||||
@this.WorkingDirectory
|
||||
</MudText>
|
||||
<MudCopyClipboardButton TooltipMessage="@(T("Copies the working directory to the clipboard"))" StringContent="@this.runtimeInfo.WorkingDirectory"/>
|
||||
<MudCopyClipboardButton TooltipMessage="@(T("Copies the working directory to the clipboard"))" StringContent="@this.RuntimeInfo.WorkingDirectory"/>
|
||||
</div>
|
||||
</MudListItem>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.InsertDriveFile">
|
||||
@ -61,7 +62,7 @@
|
||||
<MudText Typo="Typo.body1">
|
||||
@this.ExecutablePath
|
||||
</MudText>
|
||||
<MudCopyClipboardButton TooltipMessage="@(T("Copies the executable path to the clipboard"))" StringContent="@this.runtimeInfo.ExecutablePath"/>
|
||||
<MudCopyClipboardButton TooltipMessage="@(T("Copies the executable path to the clipboard"))" StringContent="@this.RuntimeInfo.ExecutablePath"/>
|
||||
</div>
|
||||
</MudListItem>
|
||||
@if (OperatingSystem.IsLinux())
|
||||
@ -193,7 +194,7 @@
|
||||
</MudList>
|
||||
<MudStack Row="true">
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Update" OnClick="@this.CheckForUpdate">
|
||||
@T("Check for updates")
|
||||
@(this.updatePolicyMode is UpdatePolicyMode.SELF_UPDATE ? T("Check for updates") : T("How to update"))
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Default" StartIcon="@Icons.Material.Filled.Download" OnClick="@(async () => await this.ShowPandocDialog())">
|
||||
@this.PandocButtonText
|
||||
|
||||
@ -29,6 +29,12 @@ public partial class Information : MSGComponentBase
|
||||
[Inject]
|
||||
private ISnackbar Snackbar { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private UpdatePolicy UpdatePolicy { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private RuntimeInfoResponse RuntimeInfo { get; init; }
|
||||
|
||||
[Inject]
|
||||
private DatabaseClientProvider DatabaseClientProvider { get; init; } = null!;
|
||||
|
||||
@ -42,7 +48,7 @@ public partial class Information : MSGComponentBase
|
||||
|
||||
private string osLanguage = string.Empty;
|
||||
private string osUserName = string.Empty;
|
||||
private RuntimeInfoResponse runtimeInfo;
|
||||
private UpdatePolicyMode updatePolicyMode;
|
||||
|
||||
private static string VersionApp => $"MindWork AI Studio: v{META_DATA.Version} (commit {META_DATA.AppCommitHash}, build {META_DATA.BuildNum}, {META_DATA_ARCH.Architecture.ToRID().ToUserFriendlyName()})";
|
||||
|
||||
@ -54,13 +60,13 @@ public partial class Information : MSGComponentBase
|
||||
|
||||
private string OSUserName => $"{T("Username provided by the OS")}: '{this.osUserName}'";
|
||||
|
||||
private string WorkingDirectory => $"{T("Working directory")}: {this.runtimeInfo.WorkingDirectory}";
|
||||
private string WorkingDirectory => $"{T("Working directory")}: {this.RuntimeInfo.WorkingDirectory}";
|
||||
|
||||
private string ExecutablePath => $"{T("Executable path")}: {this.runtimeInfo.ExecutablePath}";
|
||||
private string ExecutablePath => $"{T("Executable path")}: {this.RuntimeInfo.ExecutablePath}";
|
||||
|
||||
private string LinuxPackageType => $"{T("Linux package")}: {this.LinuxPackageTypeDisplayName}";
|
||||
|
||||
private string LinuxPackageTypeDisplayName => this.runtimeInfo.LinuxPackageType switch
|
||||
private string LinuxPackageTypeDisplayName => this.RuntimeInfo.LinuxPackageType switch
|
||||
{
|
||||
"appimage" => "AppImage",
|
||||
"flatpak" => "Flatpak",
|
||||
@ -162,7 +168,7 @@ public partial class Information : MSGComponentBase
|
||||
|
||||
this.osLanguage = await this.RustService.ReadUserLanguage();
|
||||
this.osUserName = await this.RustService.ReadUserName();
|
||||
this.runtimeInfo = await this.RustService.GetRuntimeInfo();
|
||||
this.updatePolicyMode = this.UpdatePolicy.CurrentMode;
|
||||
this.logPaths = await this.RustService.GetLogPaths();
|
||||
|
||||
await this.RefreshVectorStoreInfo(CancellationToken.None);
|
||||
@ -185,6 +191,7 @@ public partial class Information : MSGComponentBase
|
||||
case Event.PLUGINS_RELOADED:
|
||||
case Event.ENTERPRISE_ENVIRONMENTS_CHANGED:
|
||||
case Event.CONFIGURATION_CHANGED:
|
||||
this.updatePolicyMode = this.UpdatePolicy.CurrentMode;
|
||||
this.RefreshEnterpriseConfigurationState();
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
break;
|
||||
@ -603,7 +610,27 @@ public partial class Information : MSGComponentBase
|
||||
""";
|
||||
|
||||
private async Task CheckForUpdate()
|
||||
{
|
||||
this.updatePolicyMode = this.UpdatePolicy.CurrentMode;
|
||||
if (this.updatePolicyMode is UpdatePolicyMode.SELF_UPDATE)
|
||||
{
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.USER_SEARCH_FOR_UPDATE);
|
||||
return;
|
||||
}
|
||||
|
||||
var parameters = new DialogParameters<UpdateInstructionsDialog>();
|
||||
if (this.updatePolicyMode is UpdatePolicyMode.ENTERPRISE_DISABLED)
|
||||
{
|
||||
parameters.Add(x => x.Message, T("Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio."));
|
||||
}
|
||||
else if (this.updatePolicyMode is UpdatePolicyMode.FLATPAK)
|
||||
{
|
||||
parameters.Add(x => x.Message, T("AI Studio cannot update itself when installed as a Flatpak. A Flathub listing is planned. Until then, you can find the latest release on GitHub."));
|
||||
parameters.Add(x => x.ReleaseUrl, "https://github.com/MindWorkAI/AI-Studio/releases/latest");
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
await this.DialogService.ShowAsync<UpdateInstructionsDialog>(T("How to update"), parameters, DialogOptions.FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +200,10 @@ CONFIG["DATA_SOURCES"] = {}
|
||||
CONFIG["SETTINGS"] = {}
|
||||
|
||||
-- Configure the update check interval:
|
||||
-- Allowed values are: NO_CHECK, ONCE_STARTUP, HOURLY, DAILY, WEEKLY
|
||||
-- Allowed values are: NO_CHECK, DISABLE_UPDATES, ONCE_STARTUP, HOURLY, DAILY, WEEKLY
|
||||
-- NO_CHECK disables automatic checks, but users can still check and install updates manually.
|
||||
-- DISABLE_UPDATES is intended for enterprise configurations and disables all update checks
|
||||
-- and installations. It is not offered as a selectable option in the normal app settings.
|
||||
-- CONFIG["SETTINGS"]["DataApp.UpdateInterval"] = "NO_CHECK"
|
||||
|
||||
-- Configure how updates are installed:
|
||||
|
||||
@ -3003,6 +3003,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1059411425"]
|
||||
-- Do you want to show preview features in the app?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1118505044"] = "Möchten Sie Vorschaufunktionen in der App anzeigen lassen?"
|
||||
|
||||
-- AI Studio cannot check for updates when running as a Flatpak. Updates are managed outside the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1190632518"] = "AI Studio kann bei Ausführung als Flatpak nicht nach Updates suchen. Updates werden außerhalb der App verwaltet."
|
||||
|
||||
-- Voice recording shortcut
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1278320412"] = "Tastaturkurzbefehl für Sprachaufnahme"
|
||||
|
||||
@ -3045,9 +3048,15 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1890416390"]
|
||||
-- Which preview features would you like to enable?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898060643"] = "Welche Vorschaufunktionen möchten Sie aktivieren?"
|
||||
|
||||
-- This setting has no effect while updates are disabled by your organization.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898114759"] = "Diese Einstellung hat keine Auswirkungen, solange Updates von Ihrer Organisation deaktiviert sind."
|
||||
|
||||
-- Select the language for the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"] = "Wählen Sie die Sprache für die App aus."
|
||||
|
||||
-- Your organization has disabled update checks and installations.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1909339369"] = "Ihre Organisation hat die Suche nach Updates und deren Installation deaktiviert."
|
||||
|
||||
-- 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.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2013281167"] = "Wenn diese Option aktiviert ist, werden zusätzliche Optionen für die Administration angezeigt. Diese Optionen sind für IT-Mitarbeitende vorgesehen, um organisationsweite Einstellungen zu verwalten, z. B. Anbieter für eine gesamte Organisation zu konfigurieren und zu exportieren."
|
||||
|
||||
@ -3066,6 +3075,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"]
|
||||
-- Update installation method
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Installationsmethode für Updates"
|
||||
|
||||
-- AI Studio cannot install updates when running as a Flatpak. Use the update method provided by your Flatpak distribution.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T244540698"] = "AI Studio kann keine Updates installieren, wenn es als Flatpak ausgeführt wird. Verwenden Sie die von Ihrer Flatpak-Distribution bereitgestellte Methode zur Aktualisierung."
|
||||
|
||||
-- Language
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Sprache"
|
||||
|
||||
@ -6288,6 +6300,12 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T25417398"] = "Aktualisieren v
|
||||
-- Install later
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T2936430090"] = "Später installieren"
|
||||
|
||||
-- Close
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEINSTRUCTIONSDIALOG::T3448155331"] = "Schließen"
|
||||
|
||||
-- Show me the latest release page
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEINSTRUCTIONSDIALOG::T59688848"] = "Zeig mir die Seite mit der neuesten Version"
|
||||
|
||||
-- Create new workspace
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1541251414"] = "Neuen Arbeitsbereich erstellen"
|
||||
|
||||
@ -6663,6 +6681,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1347508205"] = "Kopiert den Slot
|
||||
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1388816916"] = "Diese Bibliothek wird verwendet, um PDF-Dateien zu lesen. Das ist zum Beispiel notwendig, um PDFs als Datenquelle für einen Chat zu nutzen."
|
||||
|
||||
-- Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1402243995"] = "Updates werden von Ihrer Organisation verwaltet. Wenn Sie Fragen zur Aktualisierung von AI Studio haben, wenden Sie sich an Ihre IT-Abteilung."
|
||||
|
||||
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1421513382"] = "Diese Bibliothek wird verwendet, um die MudBlazor-Bibliothek zu erweitern. Sie stellt zusätzliche Komponenten bereit, die nicht Teil der MudBlazor-Bibliothek sind."
|
||||
|
||||
@ -6768,6 +6789,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2435772109"] = "Ursprung der Kon
|
||||
-- Configuration slot:
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T254943559"] = "Slot der Konfiguration:"
|
||||
|
||||
-- AI Studio cannot update itself when installed as a Flatpak. A Flathub listing is planned. Until then, you can find the latest release on GitHub.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T254976975"] = "AI Studio kann sich nicht selbst aktualisieren, wenn es als Flatpak installiert ist. Ein Eintrag auf Flathub ist geplant. Bis dahin finden Sie die neueste Version auf GitHub."
|
||||
|
||||
-- This library is used to determine the language of the operating system. This is necessary to set the language of the user interface.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2557014401"] = "Diese Bibliothek wird verwendet, um die Sprache des Betriebssystems zu erkennen. Dies ist notwendig, um die Sprache der Benutzeroberfläche einzustellen."
|
||||
|
||||
@ -7020,6 +7044,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T864851737"] = "Axum wird verwend
|
||||
-- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T870640199"] = "Für einige Datenübertragungen müssen wir die Daten in Base64 kodieren. Diese Rust-Bibliothek eignet sich dafür hervorragend."
|
||||
|
||||
-- How to update
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T906183311"] = "Update-Anleitung "
|
||||
|
||||
-- Install Pandoc
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T986578435"] = "Pandoc installieren"
|
||||
|
||||
@ -7425,6 +7452,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107
|
||||
-- Toggle the sidebar: show the workspaces on demand next to the chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3711207137"] = "Seitenleiste umschalten: Arbeitsbereiche bei Bedarf neben dem Chat anzeigen"
|
||||
|
||||
-- Updates disabled by your organization
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T4048970098"] = "Updates wurden von Ihrer Organisation deaktiviert"
|
||||
|
||||
-- Also show features in alpha: these are in development; expect bugs and missing features
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T4146964761"] = "Zeige auch Funktionen im Alpha-Stadium an: Diese befinden sich in der Entwicklung; es werden Fehler und fehlende Funktionen auftreten."
|
||||
|
||||
|
||||
@ -3003,6 +3003,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1059411425"]
|
||||
-- Do you want to show preview features in the app?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1118505044"] = "Do you want to show preview features in the app?"
|
||||
|
||||
-- AI Studio cannot check for updates when running as a Flatpak. Updates are managed outside the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1190632518"] = "AI Studio cannot check for updates when running as a Flatpak. Updates are managed outside the app."
|
||||
|
||||
-- Voice recording shortcut
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1278320412"] = "Voice recording shortcut"
|
||||
|
||||
@ -3045,9 +3048,15 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1890416390"]
|
||||
-- Which preview features would you like to enable?
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898060643"] = "Which preview features would you like to enable?"
|
||||
|
||||
-- This setting has no effect while updates are disabled by your organization.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1898114759"] = "This setting has no effect while updates are disabled by your organization."
|
||||
|
||||
-- Select the language for the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"] = "Select the language for the app."
|
||||
|
||||
-- Your organization has disabled update checks and installations.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1909339369"] = "Your organization has disabled update checks and installations."
|
||||
|
||||
-- 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.
|
||||
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."
|
||||
|
||||
@ -3066,6 +3075,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"]
|
||||
-- Update installation method
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Update installation method"
|
||||
|
||||
-- AI Studio cannot install updates when running as a Flatpak. Use the update method provided by your Flatpak distribution.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T244540698"] = "AI Studio cannot install updates when running as a Flatpak. Use the update method provided by your Flatpak distribution."
|
||||
|
||||
-- Language
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
|
||||
|
||||
@ -6288,6 +6300,12 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T25417398"] = "Update from v{0
|
||||
-- Install later
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T2936430090"] = "Install later"
|
||||
|
||||
-- Close
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEINSTRUCTIONSDIALOG::T3448155331"] = "Close"
|
||||
|
||||
-- Show me the latest release page
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEINSTRUCTIONSDIALOG::T59688848"] = "Show me the latest release page"
|
||||
|
||||
-- Create new workspace
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1541251414"] = "Create new workspace"
|
||||
|
||||
@ -6663,6 +6681,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1347508205"] = "Copies the confi
|
||||
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1388816916"] = "This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat."
|
||||
|
||||
-- Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1402243995"] = "Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio."
|
||||
|
||||
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
|
||||
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."
|
||||
|
||||
@ -6768,6 +6789,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2435772109"] = "Configuration or
|
||||
-- Configuration slot:
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T254943559"] = "Configuration slot:"
|
||||
|
||||
-- AI Studio cannot update itself when installed as a Flatpak. A Flathub listing is planned. Until then, you can find the latest release on GitHub.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T254976975"] = "AI Studio cannot update itself when installed as a Flatpak. A Flathub listing is planned. Until then, you can find the latest release on GitHub."
|
||||
|
||||
-- This library is used to determine the language of the operating system. This is necessary to set the language of the user interface.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2557014401"] = "This library is used to determine the language of the operating system. This is necessary to set the language of the user interface."
|
||||
|
||||
@ -7020,6 +7044,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T864851737"] = "Axum is used to p
|
||||
-- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T870640199"] = "For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose."
|
||||
|
||||
-- How to update
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T906183311"] = "How to update"
|
||||
|
||||
-- Install Pandoc
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T986578435"] = "Install Pandoc"
|
||||
|
||||
@ -7425,6 +7452,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107
|
||||
-- Toggle the sidebar: show the workspaces on demand next to the chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3711207137"] = "Toggle the sidebar: show the workspaces on demand next to the chat"
|
||||
|
||||
-- Updates disabled by your organization
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T4048970098"] = "Updates disabled by your organization"
|
||||
|
||||
-- Also show features in alpha: these are in development; expect bugs and missing features
|
||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T4146964761"] = "Also show features in alpha: these are in development; expect bugs and missing features"
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ using AIStudio.Tools.AIJobs;
|
||||
using AIStudio.Tools.AssistantSessions;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
using AIStudio.Tools.PluginSystem.Assistants;
|
||||
using AIStudio.Tools.Rust;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
@ -88,6 +89,7 @@ internal sealed class Program
|
||||
return;
|
||||
}
|
||||
|
||||
var runtimeInfo = await rust.GetRuntimeInfo();
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.WebHost.ConfigureKestrel(kestrelServerOptions =>
|
||||
{
|
||||
@ -127,6 +129,7 @@ internal sealed class Program
|
||||
builder.Services.AddSingleton(new MudTheme());
|
||||
builder.Services.AddSingleton(MessageBus.INSTANCE);
|
||||
builder.Services.AddSingleton(rust);
|
||||
builder.Services.AddSingleton(typeof(RuntimeInfoResponse), runtimeInfo);
|
||||
builder.Services.AddMudMarkdownClipboardService<MarkdownClipboardService>();
|
||||
builder.Services.AddSingleton<SettingsManager>();
|
||||
builder.Services.AddSingleton<ThreadSafeRandom>();
|
||||
@ -134,6 +137,7 @@ internal sealed class Program
|
||||
builder.Services.AddSingleton<AssistantSessionService>();
|
||||
builder.Services.AddSingleton<VoiceRecordingAvailabilityService>();
|
||||
builder.Services.AddSingleton<AssistantPluginInstallService>();
|
||||
builder.Services.AddSingleton<UpdatePolicy>();
|
||||
builder.Services.AddSingleton<DataSourceService>();
|
||||
builder.Services.AddScoped<PandocAvailabilityService>();
|
||||
builder.Services.AddTransient<HTMLParser>();
|
||||
|
||||
@ -74,6 +74,15 @@ public static class ConfigurationSelectDataFactory
|
||||
yield return new (TB("Check every week"), UpdateInterval.WEEKLY);
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigurationSelectData<UpdateInterval>> GetManagedUpdateIntervalData(UpdateInterval currentValue)
|
||||
{
|
||||
if (currentValue is UpdateInterval.DISABLE_UPDATES)
|
||||
yield return new(TB("Updates disabled by your organization"), UpdateInterval.DISABLE_UPDATES);
|
||||
|
||||
foreach (var option in GetUpdateIntervalData())
|
||||
yield return option;
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigurationSelectData<UpdateInstallation>> GetUpdateBehaviourData()
|
||||
{
|
||||
yield return new(TB("Install updates manually"), UpdateInstallation.MANUAL);
|
||||
|
||||
@ -3,6 +3,7 @@ namespace AIStudio.Settings.DataModel;
|
||||
public enum UpdateInterval
|
||||
{
|
||||
NO_CHECK,
|
||||
DISABLE_UPDATES,
|
||||
ONCE_STARTUP,
|
||||
HOURLY,
|
||||
DAILY,
|
||||
|
||||
23
app/MindWork AI Studio/Tools/Services/UpdatePolicy.cs
Normal file
23
app/MindWork AI Studio/Tools/Services/UpdatePolicy.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Settings.DataModel;
|
||||
using AIStudio.Tools.Rust;
|
||||
|
||||
namespace AIStudio.Tools.Services;
|
||||
|
||||
public sealed class UpdatePolicy(SettingsManager settingsManager, RuntimeInfoResponse runtimeInfo)
|
||||
{
|
||||
public UpdatePolicyMode CurrentMode => settingsManager.ConfigurationData.App.UpdateInterval is UpdateInterval.DISABLE_UPDATES
|
||||
? UpdatePolicyMode.ENTERPRISE_DISABLED
|
||||
: runtimeInfo.LinuxPackageType switch
|
||||
{
|
||||
"flatpak" => UpdatePolicyMode.FLATPAK,
|
||||
_ => UpdatePolicyMode.SELF_UPDATE
|
||||
};
|
||||
|
||||
public bool AllowsManualChecks => this.CurrentMode is UpdatePolicyMode.SELF_UPDATE;
|
||||
|
||||
public bool AllowsAutomaticChecks => this.CurrentMode is UpdatePolicyMode.SELF_UPDATE &&
|
||||
settingsManager.ConfigurationData.App.UpdateInterval is not UpdateInterval.NO_CHECK;
|
||||
|
||||
public bool AllowsInstallations => this.CurrentMode is UpdatePolicyMode.SELF_UPDATE;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
namespace AIStudio.Tools.Services;
|
||||
|
||||
public enum UpdatePolicyMode
|
||||
{
|
||||
SELF_UPDATE,
|
||||
FLATPAK,
|
||||
ENTERPRISE_DISABLED
|
||||
}
|
||||
@ -16,15 +16,15 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
private readonly SettingsManager settingsManager;
|
||||
private readonly MessageBus messageBus;
|
||||
private readonly RustService rust;
|
||||
private readonly UpdatePolicy updatePolicy;
|
||||
private readonly ILogger<UpdateService> logger;
|
||||
|
||||
private TimeSpan updateInterval;
|
||||
|
||||
public UpdateService(MessageBus messageBus, SettingsManager settingsManager, RustService rust, ILogger<UpdateService> logger)
|
||||
public UpdateService(MessageBus messageBus, SettingsManager settingsManager, RustService rust, UpdatePolicy updatePolicy, ILogger<UpdateService> logger)
|
||||
{
|
||||
this.settingsManager = settingsManager;
|
||||
this.messageBus = messageBus;
|
||||
this.rust = rust;
|
||||
this.updatePolicy = updatePolicy;
|
||||
this.logger = logger;
|
||||
|
||||
this.messageBus.RegisterComponent(this);
|
||||
@ -41,42 +41,21 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
while (!stoppingToken.IsCancellationRequested && !IS_INITIALIZED)
|
||||
await Task.Delay(TimeSpan.FromSeconds(3), stoppingToken);
|
||||
|
||||
//
|
||||
// Set the update interval based on the user's settings.
|
||||
//
|
||||
this.updateInterval = this.settingsManager.ConfigurationData.App.UpdateInterval switch
|
||||
{
|
||||
UpdateInterval.NO_CHECK => Timeout.InfiniteTimeSpan,
|
||||
UpdateInterval.ONCE_STARTUP => Timeout.InfiniteTimeSpan,
|
||||
|
||||
UpdateInterval.HOURLY => TimeSpan.FromHours(1),
|
||||
UpdateInterval.DAILY => TimeSpan.FromDays(1),
|
||||
UpdateInterval.WEEKLY => TimeSpan.FromDays(7),
|
||||
|
||||
_ => TimeSpan.FromHours(1)
|
||||
};
|
||||
|
||||
//
|
||||
// When the user doesn't want to check for updates, we can
|
||||
// return early.
|
||||
//
|
||||
if(this.settingsManager.ConfigurationData.App.UpdateInterval is UpdateInterval.NO_CHECK)
|
||||
return;
|
||||
|
||||
//
|
||||
// Check for updates at the beginning. The user aspects this when the app
|
||||
// is started.
|
||||
//
|
||||
await this.CheckForUpdate();
|
||||
|
||||
//
|
||||
// Start the update loop. This will check for updates based on the
|
||||
// user's settings.
|
||||
//
|
||||
DateTimeOffset? lastAutomaticCheck = null;
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(this.updateInterval, stoppingToken);
|
||||
var interval = this.GetCurrentUpdateInterval();
|
||||
if (this.updatePolicy.AllowsAutomaticChecks &&
|
||||
(
|
||||
lastAutomaticCheck is null ||
|
||||
interval != Timeout.InfiniteTimeSpan && DateTimeOffset.UtcNow - lastAutomaticCheck >= interval)
|
||||
)
|
||||
{
|
||||
await this.CheckForUpdate();
|
||||
lastAutomaticCheck = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,6 +76,7 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.USER_SEARCH_FOR_UPDATE:
|
||||
if (this.updatePolicy.AllowsManualChecks)
|
||||
await this.CheckForUpdate(notifyUserWhenNoUpdate: true);
|
||||
break;
|
||||
}
|
||||
@ -143,6 +123,9 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
|
||||
if (!isDevEnvironment && this.settingsManager.ConfigurationData.App.UpdateInstallation is UpdateInstallation.AUTOMATIC)
|
||||
{
|
||||
if (!this.updatePolicy.AllowsInstallations)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await this.messageBus.SendMessage<bool>(null, Event.INSTALL_UPDATE);
|
||||
@ -175,6 +158,16 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
||||
}
|
||||
}
|
||||
|
||||
private TimeSpan GetCurrentUpdateInterval() => this.settingsManager.ConfigurationData.App.UpdateInterval switch
|
||||
{
|
||||
UpdateInterval.ONCE_STARTUP => Timeout.InfiniteTimeSpan,
|
||||
UpdateInterval.HOURLY => TimeSpan.FromHours(1),
|
||||
UpdateInterval.DAILY => TimeSpan.FromDays(1),
|
||||
UpdateInterval.WEEKLY => TimeSpan.FromDays(7),
|
||||
|
||||
_ => Timeout.InfiniteTimeSpan
|
||||
};
|
||||
|
||||
public static void SetBlazorDependencies(ISnackbar snackbar)
|
||||
{
|
||||
SNACKBAR = snackbar;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# v26.7.3, build 245 (2026-07-xx xx:xx UTC)
|
||||
- Improved the "My Tasks Assistant": you can now provide one or more documents in addition to text or use documents alone when asking to identify tasks.
|
||||
- Improved update guidance for Flatpak installations and added an enterprise option that lets organizations manage updates entirely through their IT department.
|
||||
- Fixed an issue that could leave AI Studio unresponsive after waking the computer from sleep.
|
||||
- Fixed enterprise configuration plugins from Windows-created ZIP files not loading correctly on Linux when the ZIP contained plugin files inside a folder.
|
||||
- Upgraded Rust to v1.97.0.
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
Do you want to manage MindWork AI Studio in a corporate environment or within an organization? This documentation explains what you need to do and how it works. First, here's an overview of the entire process:
|
||||
|
||||
- You can distribute MindWork AI Studio to employees' devices using tools like Microsoft System Center Configuration Manager (SCCM).
|
||||
- Employees can get updates through the built-in update feature. If you want, you can disable automatic updates and control which version gets distributed.
|
||||
- Employees can get updates through the built-in update feature. Enterprise configuration can disable automatic checks or the entire built-in update feature so that the IT department controls which version gets distributed.
|
||||
- AI Studio checks about every 16 minutes to see where and which configuration it should load. This information is loaded from the local system. On Windows, you might use the registry, for example.
|
||||
- If it finds the necessary metadata, AI Studio downloads the configuration as a ZIP file from the specified server.
|
||||
- The configuration is an AI Studio plugin written in Lua.
|
||||
@ -12,6 +12,15 @@ Do you want to manage MindWork AI Studio in a corporate environment or within an
|
||||
|
||||
AI Studio checks about every 16 minutes to see if the configuration ID, the server for the configuration, or the configuration itself has changed. If it finds any changes, it loads the updated configuration from the server and applies it right away.
|
||||
|
||||
### Manage app updates
|
||||
|
||||
Set `CONFIG["SETTINGS"]["DataApp.UpdateInterval"]` in the configuration plugin to control update checks:
|
||||
|
||||
- `NO_CHECK` disables automatic update checks. Users can still check for and install updates manually.
|
||||
- `DISABLE_UPDATES` disables automatic and manual update checks and installations. AI Studio tells users that updates are managed by their organization and directs questions to their IT department. This policy takes effect immediately when the enterprise configuration changes.
|
||||
|
||||
Use `DISABLE_UPDATES` when your organization distributes approved versions through its own software-management process.
|
||||
|
||||
## Configure the devices
|
||||
So that MindWork AI Studio knows where to load which configuration, this information must be provided as metadata on employees' devices. Currently, the following options are available:
|
||||
|
||||
|
||||
@ -451,8 +451,9 @@ pub async fn change_location_to(url: &str) {
|
||||
|
||||
/// Checks for updates.
|
||||
pub async fn check_for_update(_token: APIToken) -> Json<CheckUpdateResponse> {
|
||||
if is_dev() {
|
||||
warn!(Source = "Updater"; "The app is running in development mode; skipping update check.");
|
||||
if !self_update_allowed(is_dev(), is_flatpak()) {
|
||||
let reason = if is_flatpak() { "Flatpak installations are updated externally" } else { "the app is running in development mode" };
|
||||
warn!(Source = "Updater"; "Skipping update check because {reason}.");
|
||||
return Json(CheckUpdateResponse {
|
||||
update_is_available: false,
|
||||
error: false,
|
||||
@ -536,8 +537,9 @@ pub struct CheckUpdateResponse {
|
||||
|
||||
/// Installs the update.
|
||||
pub async fn install_update(_token: APIToken) {
|
||||
if is_dev() {
|
||||
warn!(Source = "Updater"; "The app is running in development mode; skipping update installation.");
|
||||
if !self_update_allowed(is_dev(), is_flatpak()) {
|
||||
let reason = if is_flatpak() { "Flatpak installations are updated externally" } else { "the app is running in development mode" };
|
||||
warn!(Source = "Updater"; "Skipping update installation because {reason}.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -595,6 +597,10 @@ pub async fn install_update(_token: APIToken) {
|
||||
}
|
||||
}
|
||||
|
||||
fn self_update_allowed(development: bool, flatpak: bool) -> bool {
|
||||
!development && !flatpak
|
||||
}
|
||||
|
||||
/// Request payload for registering a global shortcut.
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct RegisterShortcutRequest {
|
||||
@ -1027,6 +1033,20 @@ mod tests {
|
||||
use super::*;
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
fn self_update_is_disabled_in_development() {
|
||||
assert!(!self_update_allowed(true, false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_update_is_disabled_for_flatpak() {
|
||||
assert!(!self_update_allowed(false, true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_update_is_enabled_for_normal_production_installations() {
|
||||
assert!(self_update_allowed(false, false));
|
||||
}
|
||||
#[test]
|
||||
fn pdfium_library_directory_prefers_resources_libraries() {
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user