mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-07-21 13:42:54 +00:00
Store office suite choice in a single config option
Previously it was three boolean options, which were supposed to be mutually exclusive, which had to be taken care of manually. Also previously there was only indirect indication of the choice "none", which is brittle, too. Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const optionsForm = document.getElementById('options-form');
|
||||
// Don't run if the expected form isn't present.
|
||||
if (document.getElementById('options-form') === null) {
|
||||
if (optionsForm === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -20,14 +21,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
const communityContainersCheckboxes = document.querySelectorAll("#community-form input[type='checkbox']");
|
||||
|
||||
// Office suite radio buttons
|
||||
const collaboraRadio = document.getElementById('office-collabora');
|
||||
const onlyofficeRadio = document.getElementById('office-onlyoffice');
|
||||
const euroofficeRadio = document.getElementById('office-eurooffice');
|
||||
const noneRadio = document.getElementById('office-none');
|
||||
const collaboraHidden = document.getElementById('collabora');
|
||||
const onlyofficeHidden = document.getElementById('onlyoffice');
|
||||
const euroofficeHidden = document.getElementById('eurooffice');
|
||||
let initialOfficeSelection = null;
|
||||
const officeSuiteChoiceList = optionsForm.elements['office_suite_choice'];
|
||||
const initialOfficeSelection = document.getElementById('initial-office-suite')?.value ?? '';
|
||||
|
||||
optionsContainersCheckboxes.forEach(checkbox => {
|
||||
initialStateOptionsContainers[checkbox.id] = checkbox.checked; // Use checked property to capture actual initial state
|
||||
@@ -37,19 +32,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
initialStateCommunityContainers[checkbox.id] = checkbox.checked; // Use checked property to capture actual initial state
|
||||
});
|
||||
|
||||
// Store initial office suite selection
|
||||
if (collaboraRadio && onlyofficeRadio && euroofficeRadio && noneRadio) {
|
||||
if (collaboraRadio.checked) {
|
||||
initialOfficeSelection = 'collabora';
|
||||
} else if (onlyofficeRadio.checked) {
|
||||
initialOfficeSelection = 'onlyoffice';
|
||||
} else if (euroofficeRadio.checked) {
|
||||
initialOfficeSelection = 'eurooffice';
|
||||
} else {
|
||||
initialOfficeSelection = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Function to compare current states to initial states
|
||||
function checkForOptionContainerChanges() {
|
||||
let hasChanges = false;
|
||||
@@ -60,32 +42,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
}
|
||||
});
|
||||
|
||||
// Check office suite changes and sync to hidden inputs
|
||||
if (collaboraRadio && onlyofficeRadio && euroofficeRadio && noneRadio && collaboraHidden && onlyofficeHidden && euroofficeHidden) {
|
||||
let currentOfficeSelection = null;
|
||||
if (collaboraRadio.checked) {
|
||||
currentOfficeSelection = 'collabora';
|
||||
collaboraHidden.value = 'on';
|
||||
onlyofficeHidden.value = '';
|
||||
euroofficeHidden.value = '';
|
||||
} else if (onlyofficeRadio.checked) {
|
||||
currentOfficeSelection = 'onlyoffice';
|
||||
collaboraHidden.value = '';
|
||||
onlyofficeHidden.value = 'on';
|
||||
euroofficeHidden.value = '';
|
||||
} else if (euroofficeRadio.checked) {
|
||||
currentOfficeSelection = 'eurooffice';
|
||||
collaboraHidden.value = '';
|
||||
onlyofficeHidden.value = '';
|
||||
euroofficeHidden.value = 'on';
|
||||
} else {
|
||||
currentOfficeSelection = 'none';
|
||||
collaboraHidden.value = '';
|
||||
onlyofficeHidden.value = '';
|
||||
euroofficeHidden.value = '';
|
||||
}
|
||||
|
||||
if (currentOfficeSelection !== initialOfficeSelection) {
|
||||
if (officeSuiteChoiceList) {
|
||||
if (officeSuiteChoiceList.value !== initialOfficeSelection) {
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
@@ -156,12 +114,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
handleTalkVisibility(); // Ensure talk-recording is correctly initialized
|
||||
|
||||
// Add event listeners for office suite radio buttons
|
||||
if (collaboraRadio && onlyofficeRadio && euroofficeRadio && noneRadio) {
|
||||
collaboraRadio.addEventListener('change', checkForOptionContainerChanges);
|
||||
onlyofficeRadio.addEventListener('change', checkForOptionContainerChanges);
|
||||
euroofficeRadio.addEventListener('change', checkForOptionContainerChanges);
|
||||
noneRadio.addEventListener('change', checkForOptionContainerChanges);
|
||||
}
|
||||
officeSuiteChoiceList?.forEach((elem) => elem.addEventListener('change', checkForOptionContainerChanges));
|
||||
|
||||
// Initial call to check for changes
|
||||
checkForOptionContainerChanges();
|
||||
|
||||
@@ -153,9 +153,7 @@ $app->get('/containers', function (Request $request, Response $response, array $
|
||||
'backup_times' => $configurationManager->getBackupTimes(),
|
||||
'current_channel' => $dockerActionManager->GetCurrentChannel(),
|
||||
'is_clamav_enabled' => $configurationManager->isClamavEnabled,
|
||||
'is_onlyoffice_enabled' => $configurationManager->isOnlyofficeEnabled,
|
||||
'is_eurooffice_enabled' => $configurationManager->isEuroofficeEnabled,
|
||||
'is_collabora_enabled' => $configurationManager->isCollaboraEnabled,
|
||||
'office_suite' => $configurationManager->getOfficeSuiteString(),
|
||||
'is_talk_enabled' => $configurationManager->isTalkEnabled,
|
||||
'borg_restore_password' => $configurationManager->borgRestorePassword,
|
||||
'daily_backup_time' => $configurationManager->getDailyBackupTime(),
|
||||
|
||||
@@ -12,6 +12,7 @@ use AIO\Container\ContainerVolume;
|
||||
use AIO\Container\ContainerVolumes;
|
||||
use AIO\Data\ConfigurationManager;
|
||||
use AIO\Data\DataConst;
|
||||
use AIO\Data\OfficeSuite;
|
||||
use AIO\Docker\DockerActionManager;
|
||||
|
||||
readonly class ContainerDefinitionFetcher {
|
||||
@@ -75,15 +76,15 @@ readonly class ContainerDefinitionFetcher {
|
||||
continue;
|
||||
}
|
||||
} elseif ($entry['container_name'] === 'nextcloud-aio-onlyoffice') {
|
||||
if (!$this->configurationManager->isOnlyofficeEnabled) {
|
||||
if ($this->configurationManager->officeSuite !== OfficeSuite::Onlyoffice) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($entry['container_name'] === 'nextcloud-aio-eurooffice') {
|
||||
if (!$this->configurationManager->isEuroofficeEnabled) {
|
||||
if ($this->configurationManager->officeSuite !== OfficeSuite::Eurooffice) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($entry['container_name'] === 'nextcloud-aio-collabora') {
|
||||
if (!$this->configurationManager->isCollaboraEnabled) {
|
||||
if ($this->configurationManager->officeSuite !== OfficeSuite::Collabora) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($entry['container_name'] === 'nextcloud-aio-talk') {
|
||||
@@ -192,15 +193,15 @@ readonly class ContainerDefinitionFetcher {
|
||||
continue;
|
||||
}
|
||||
} elseif ($value === 'nextcloud-aio-onlyoffice') {
|
||||
if (!$this->configurationManager->isOnlyofficeEnabled) {
|
||||
if ($this->configurationManager->officeSuite !== OfficeSuite::Onlyoffice) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($value === 'nextcloud-aio-eurooffice') {
|
||||
if (!$this->configurationManager->isEuroofficeEnabled) {
|
||||
if ($this->configurationManager->officeSuite !== OfficeSuite::Eurooffice) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($value === 'nextcloud-aio-collabora') {
|
||||
if (!$this->configurationManager->isCollaboraEnabled) {
|
||||
if ($this->configurationManager->officeSuite !== OfficeSuite::Collabora) {
|
||||
continue;
|
||||
}
|
||||
} elseif ($value === 'nextcloud-aio-talk') {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace AIO\Controller;
|
||||
|
||||
use AIO\Data\ConfigurationManager;
|
||||
use AIO\Data\InvalidSettingConfigurationException;
|
||||
use AIO\Data\OfficeSuite;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
@@ -76,24 +77,10 @@ readonly class ConfigurationController {
|
||||
}
|
||||
|
||||
if (isset($request->getParsedBody()['options-form'])) {
|
||||
$officeSuiteChoice = $request->getParsedBody()['office_suite_choice'] ?? '';
|
||||
|
||||
if ($officeSuiteChoice === 'collabora') {
|
||||
$this->configurationManager->isCollaboraEnabled = true;
|
||||
$this->configurationManager->isOnlyofficeEnabled = false;
|
||||
$this->configurationManager->isEuroofficeEnabled = false;
|
||||
} elseif ($officeSuiteChoice === 'onlyoffice') {
|
||||
$this->configurationManager->isCollaboraEnabled = false;
|
||||
$this->configurationManager->isOnlyofficeEnabled = true;
|
||||
$this->configurationManager->isEuroofficeEnabled = false;
|
||||
} elseif ($officeSuiteChoice === 'eurooffice') {
|
||||
$this->configurationManager->isCollaboraEnabled = false;
|
||||
$this->configurationManager->isOnlyofficeEnabled = false;
|
||||
$this->configurationManager->isEuroofficeEnabled = true;
|
||||
} else {
|
||||
$this->configurationManager->isCollaboraEnabled = false;
|
||||
$this->configurationManager->isOnlyofficeEnabled = false;
|
||||
$this->configurationManager->isEuroofficeEnabled = false;
|
||||
if (isset($request->getParsedBody()['office_suite_choice'])) {
|
||||
$inputValue = strval($request->getParsedBody()['office_suite_choice'] ?? '');
|
||||
$officeSuite = OfficeSuite::tryFrom($inputValue) ?? OfficeSuite::None;
|
||||
$this->configurationManager->officeSuite = $officeSuite;
|
||||
}
|
||||
$this->configurationManager->isClamavEnabled = isset($request->getParsedBody()['clamav']);
|
||||
$this->configurationManager->isTalkEnabled = isset($request->getParsedBody()['talk']);
|
||||
|
||||
@@ -11,6 +11,7 @@ use AIO\Docker\DockerActionManager;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use AIO\Data\ConfigurationManager;
|
||||
use AIO\Data\OfficeSuite;
|
||||
use Slim\Psr7\NonBufferedBody;
|
||||
|
||||
readonly class DockerController {
|
||||
@@ -299,7 +300,7 @@ readonly class DockerController {
|
||||
// This is a hack but no better solution was found for the meantime
|
||||
// Stop Collabora first to make sure it force-saves
|
||||
// See https://github.com/nextcloud/richdocuments/issues/3799
|
||||
if ($id === self::TOP_CONTAINER && $this->configurationManager->isCollaboraEnabled) {
|
||||
if ($id === self::TOP_CONTAINER && $this->configurationManager->officeSuite === OfficeSuite::Collabora) {
|
||||
$this->PerformRecursiveContainerStop('nextcloud-aio-collabora', false, $addToStreamingResponseBody);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,22 +95,9 @@ class ConfigurationManager
|
||||
set { $this->set('isClamavEnabled', $value); }
|
||||
}
|
||||
|
||||
public bool $isOnlyofficeEnabled {
|
||||
// Type-cast because old configs could have 1/0 for this key.
|
||||
get => (bool) $this->get('isOnlyofficeEnabled', false);
|
||||
set { $this->set('isOnlyofficeEnabled', $value); }
|
||||
}
|
||||
|
||||
public bool $isEuroofficeEnabled {
|
||||
// Only enabled if no other office suite is enabled.
|
||||
get => !$this->isOtherOfficeThanEuroOfficeEnabled() && $this->get('isEuroofficeEnabled', true);
|
||||
set { $this->set('isEuroofficeEnabled', $value); }
|
||||
}
|
||||
|
||||
public bool $isCollaboraEnabled {
|
||||
// Type-cast because old configs could have 1/0 for this key.
|
||||
get => (bool) $this->get('isCollaboraEnabled', false);
|
||||
set { $this->set('isCollaboraEnabled', $value); }
|
||||
public OfficeSuite $officeSuite {
|
||||
get => $this->readOfficeSuite();
|
||||
set { $this->writeOfficeSuite($value); }
|
||||
}
|
||||
|
||||
public bool $isTalkEnabled {
|
||||
@@ -416,6 +403,75 @@ class ConfigurationManager
|
||||
}
|
||||
}
|
||||
|
||||
private function has(string $key) : bool {
|
||||
return array_key_exists($key, $this->getConfig());
|
||||
}
|
||||
|
||||
private function unset(string ...$keys) : void {
|
||||
$changed = false;
|
||||
$this->getConfig();
|
||||
foreach ($keys as $key) {
|
||||
if ($this->has($key)) {
|
||||
unset($this->config[$key]);
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
// Only write if this isn't called in between startTransaction() and commitTransaction().
|
||||
if ($changed && $this->noWrite !== true) {
|
||||
$this->writeConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private function writeOfficeSuite(OfficeSuite $officeSuite) : void
|
||||
{
|
||||
$this->set('officeSuite', $officeSuite->value);
|
||||
// Remove the deprecated options.
|
||||
$this->unset('isCollaboraEnabled', 'isOnlyofficeEnabled', 'isEuroofficeEnabled');
|
||||
}
|
||||
|
||||
private function readOfficeSuite() : OfficeSuite
|
||||
{
|
||||
if ($this->has('officeSuite')) {
|
||||
$configValue = (string) $this->get('officeSuite', '');
|
||||
return OfficeSuite::tryFrom($configValue) ?? OfficeSuite::None;
|
||||
}
|
||||
|
||||
// Check the three boolean legacy options. Convert to boolean because very old configs could have
|
||||
// `1`/`0` or even `"1"`/`"0"`/`""` as values.
|
||||
if (boolval($this->get('isCollaboraEnabled', false)) === true) {
|
||||
return OfficeSuite::Collabora;
|
||||
}
|
||||
if (boolval($this->get('isOnlyofficeEnabled', false)) === true) {
|
||||
return OfficeSuite::Onlyoffice;
|
||||
}
|
||||
if (boolval($this->get('isEuroofficeEnabled', false)) === true) {
|
||||
return OfficeSuite::Eurooffice;
|
||||
}
|
||||
|
||||
// All offices disabled.
|
||||
if (
|
||||
$this->has('isCollaboraEnabled') && boolval($this->get('isCollaboraEnabled')) === false
|
||||
&& $this->has('isOnlyofficeEnabled') && boolval($this->get('isOnlyofficeEnabled')) === false
|
||||
&& (
|
||||
// Eurooffice can be unset, which should be treated as `false`, too, because it means that
|
||||
// the office choice wasn't ever saved after Eurooffice was introduced, but the user had
|
||||
// previously disabled both available options, which means they want no office.
|
||||
!$this->has('isEuroofficeEnabled')
|
||||
|| boolval($this->get('isEuroofficeEnabled')) === false
|
||||
)
|
||||
) {
|
||||
return OfficeSuite::None;
|
||||
}
|
||||
|
||||
// Default
|
||||
return OfficeSuite::Eurooffice;
|
||||
}
|
||||
|
||||
public function getOfficeSuiteString() : string
|
||||
{
|
||||
return $this->officeSuite->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows to assign multiple attributes without saving the config to disk in between. It must be
|
||||
* followed by a call to commitTransaction(), which then writes all changes to disk.
|
||||
@@ -532,12 +588,6 @@ class ConfigurationManager
|
||||
return '';
|
||||
}
|
||||
|
||||
// Helper function for EuroOffice to make sure that it does not
|
||||
// get enabled on existing instances after updating the default
|
||||
private function isOtherOfficeThanEuroOfficeEnabled() : bool {
|
||||
return $this->isCollaboraEnabled || $this->isOnlyofficeEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidSettingConfigurationException
|
||||
*
|
||||
@@ -1164,9 +1214,9 @@ class ConfigurationManager
|
||||
'BACKUP_RESTORE_PASSWORD' => $this->borgRestorePassword,
|
||||
'CLAMAV_ENABLED' => $this->isClamavEnabled ? 'yes' : '',
|
||||
'TALK_RECORDING_ENABLED' => $this->isTalkRecordingEnabled ? 'yes' : '',
|
||||
'ONLYOFFICE_ENABLED' => $this->isOnlyofficeEnabled ? 'yes' : '',
|
||||
'EUROOFFICE_ENABLED' => $this->isEuroofficeEnabled ? 'yes' : '',
|
||||
'COLLABORA_ENABLED' => $this->isCollaboraEnabled ? 'yes' : '',
|
||||
'ONLYOFFICE_ENABLED' => $this->officeSuite === OfficeSuite::Onlyoffice ? 'yes' : '',
|
||||
'EUROOFFICE_ENABLED' => $this->officeSuite === OfficeSuite::Eurooffice ? 'yes' : '',
|
||||
'COLLABORA_ENABLED' => $this->officeSuite === OfficeSuite::Collabora ? 'yes' : '',
|
||||
'TALK_ENABLED' => $this->isTalkEnabled ? 'yes' : '',
|
||||
'UPDATE_NEXTCLOUD_APPS' => ($this->isDailyBackupRunning() && $this->areAutomaticUpdatesEnabled()) ? 'yes' : '',
|
||||
'TIMEZONE' => $this->timezone === '' ? 'Etc/UTC' : $this->timezone,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace AIO\Data;
|
||||
|
||||
enum OfficeSuite: string
|
||||
{
|
||||
case Collabora = 'collabora';
|
||||
case Onlyoffice = 'onlyoffice';
|
||||
case Eurooffice = 'eurooffice';
|
||||
case None = '';
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
name="office_suite_choice"
|
||||
value="eurooffice"
|
||||
class="office-radio"
|
||||
{% if is_eurooffice_enabled == true %}
|
||||
{% if office_suite == 'eurooffice' %}
|
||||
checked="checked"
|
||||
{% endif %}
|
||||
>
|
||||
@@ -49,14 +49,13 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
</label>
|
||||
<input type="hidden" id="eurooffice" name="eurooffice" value="" data-initial-state="{% if is_eurooffice_enabled == true %}true{% else %}false{% endif %}">
|
||||
<input
|
||||
type="radio"
|
||||
id="office-collabora"
|
||||
name="office_suite_choice"
|
||||
value="collabora"
|
||||
class="office-radio"
|
||||
{% if is_collabora_enabled == true %}
|
||||
{% if office_suite == 'collabora' %}
|
||||
checked="checked"
|
||||
{% endif %}
|
||||
>
|
||||
@@ -86,14 +85,13 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
</label>
|
||||
<input type="hidden" id="collabora" name="collabora" value="" data-initial-state="{% if is_collabora_enabled == true %}true{% else %}false{% endif %}">
|
||||
<input
|
||||
type="radio"
|
||||
id="office-onlyoffice"
|
||||
name="office_suite_choice"
|
||||
value="onlyoffice"
|
||||
class="office-radio"
|
||||
{% if is_onlyoffice_enabled == true %}
|
||||
{% if office_suite == 'onlyoffice' %}
|
||||
checked="checked"
|
||||
{% endif %}
|
||||
>
|
||||
@@ -123,7 +121,6 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
</label>
|
||||
<input type="hidden" id="onlyoffice" name="onlyoffice" value="" data-initial-state="{% if is_onlyoffice_enabled == true %}true{% else %}false{% endif %}">
|
||||
</div>
|
||||
{% if isAnyRunning == false %}
|
||||
<div class="office-none-card">
|
||||
@@ -133,7 +130,7 @@
|
||||
name="office_suite_choice"
|
||||
value=""
|
||||
class="office-radio"
|
||||
{% if is_collabora_enabled == false and is_onlyoffice_enabled == false and is_eurooffice_enabled == false %}
|
||||
{% if office_suite == '' %}
|
||||
checked="checked"
|
||||
{% endif %}
|
||||
>
|
||||
@@ -143,6 +140,7 @@
|
||||
</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<input type="hidden" id="initial-office-suite" value="{{ office_suite }}">
|
||||
<input class="options-form-submit" type="submit" value="Save changes" />
|
||||
<h3>Additional Optional Containers</h3>
|
||||
<p>
|
||||
@@ -270,7 +268,7 @@
|
||||
<script type="text/javascript" src="disable-containers.js?v1"></script>
|
||||
{% endif %}
|
||||
|
||||
{% if is_collabora_enabled == true and isAnyRunning == false and was_start_button_clicked == true %}
|
||||
{% if office_suite == 'collabora' and isAnyRunning == false and was_start_button_clicked == true %}
|
||||
<h3>Nextcloud Office dictionaries</h3>
|
||||
|
||||
{% if collabora_dictionaries == "" %}
|
||||
|
||||
Reference in New Issue
Block a user