Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions lib/Migration/Version17001Date20260210000000.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
namespace OCA\Libresign\Migration;

use OCA\Libresign\AppInfo\Application;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

Expand All @@ -20,6 +23,14 @@
* - telegram → telegramToken
* - whatsapp → whatsappToken
* - xmpp → xmppToken
*
* Also migrate files list config keys to use prefixed naming:
* - grid_view → files_list_grid_view
* - signer_identify_tab → files_list_signer_identify_tab
* - sorting_mode → files_list_sorting_mode
* - sorting_direction → files_list_sorting_direction
* - filter_modified → files_list_filter_modified
* - filter_status → files_list_filter_status
*/
class Version17001Date20260210000000 extends SimpleMigrationStep {
private const LEGACY_MAPPING = [
Expand All @@ -30,8 +41,19 @@ class Version17001Date20260210000000 extends SimpleMigrationStep {
'xmpp' => 'xmppToken',
];

private const USER_CONFIG_MIGRATIONS = [
'grid_view' => 'files_list_grid_view',
'signer_identify_tab' => 'files_list_signer_identify_tab',
'sorting_mode' => 'files_list_sorting_mode',
'sorting_direction' => 'files_list_sorting_direction',
'filter_modified' => 'files_list_filter_modified',
'filter_status' => 'files_list_filter_status',
];

public function __construct(
private IAppConfig $appConfig,
private IConfig $config,
private IDBConnection $db,
) {
}

Expand Down Expand Up @@ -91,5 +113,47 @@ function ($methodName) use (&$updated) {
$this->appConfig->setValueArray(Application::APP_ID, 'identify_methods', $identifyMethods);
$output->info('Updated signature method names to new format with Token suffix');
}

$this->migrateUserConfigs($output);
}

private function migrateUserConfigs(IOutput $output): void {
$oldKeys = array_keys(self::USER_CONFIG_MIGRATIONS);
$query = $this->db->getQueryBuilder();
$query->selectDistinct('userid')
->from('preferences')
->where($query->expr()->eq('appid', $query->createNamedParameter(Application::APP_ID)))
->andWhere($query->expr()->in('configkey', $query->createNamedParameter($oldKeys, IQueryBuilder::PARAM_STR_ARRAY)));

$result = $query->executeQuery();
$userIds = $result->fetchAll(\PDO::FETCH_COLUMN);

if (empty($userIds)) {
return;
}

$migratedCount = 0;
$output->info('Migrating files list config keys for ' . count($userIds) . ' users...');

foreach ($userIds as $userId) {
foreach (self::USER_CONFIG_MIGRATIONS as $oldKey => $newKey) {
$oldValue = $this->config->getUserValue($userId, Application::APP_ID, $oldKey, null);
$newValue = $this->config->getUserValue($userId, Application::APP_ID, $newKey, null);

// If old key has a value and new key is empty, migrate
if ($oldValue !== null && $oldValue !== '' && ($newValue === null || $newValue === '')) {
$this->config->setUserValue($userId, Application::APP_ID, $newKey, $oldValue);
$this->config->deleteUserValue($userId, Application::APP_ID, $oldKey);
$migratedCount++;
} elseif ($oldValue !== null && $oldValue !== '' && $newValue !== null && $newValue !== '') {
// Both exist, just delete the old one
$this->config->deleteUserValue($userId, Application::APP_ID, $oldKey);
}
}
}

if ($migratedCount > 0) {
$output->info("Migrated $migratedCount config keys to new prefixed format");
}
}
}
17 changes: 9 additions & 8 deletions lib/Service/AccountService.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ public function getCertificateEngineName(): string {
* @return array<string, mixed>
*/
public function getConfig(?IUser $user = null): array {

$info['identificationDocumentsFlow'] = $this->appConfig->getValueBool(Application::APP_ID, 'identification_documents', false);
$info['hasSignatureFile'] = $this->hasSignatureFile($user);
$info['phoneNumber'] = $this->getPhoneNumber($user);
Expand All @@ -199,24 +200,24 @@ public function getConfig(?IUser $user = null): array {
$info['id_docs_sort'] = $this->getUserConfigIdDocsSort($user);
$info['crl_filters'] = $this->getUserConfigCrlFilters($user);
$info['crl_sort'] = $this->getUserConfigCrlSort($user);
$info['grid_view'] = $this->getUserConfigByKey('grid_view', $user) === '1';
$info['signer_identify_tab'] = $this->getUserConfigByKey('signer_identify_tab', $user);
$info['sorting_mode'] = $this->getUserConfigByKey('sorting_mode', $user) ?: 'name';
$info['sorting_direction'] = $this->getUserConfigByKey('sorting_direction', $user) ?: 'asc';
$info['files_list_grid_view'] = $this->getUserConfigByKey('files_list_grid_view', $user) === '1';
$info['files_list_signer_identify_tab'] = $this->getUserConfigByKey('files_list_signer_identify_tab', $user);
$info['files_list_sorting_mode'] = $this->getUserConfigByKey('files_list_sorting_mode', $user) ?: 'name';
$info['files_list_sorting_direction'] = $this->getUserConfigByKey('files_list_sorting_direction', $user) ?: 'asc';

return array_filter($info);
}

public function getConfigFilters(?IUser $user = null): array {
$info['filter_modified'] = $this->getUserConfigByKey('filter_modified', $user);
$info['filter_status'] = $this->getUserConfigByKey('filter_status', $user);
$info['files_list_filter_modified'] = $this->getUserConfigByKey('files_list_filter_modified', $user);
$info['files_list_filter_status'] = $this->getUserConfigByKey('files_list_filter_status', $user);

return $info;
}

public function getConfigSorting(?IUser $user = null): array {
$info['sorting_mode'] = $this->getUserConfigByKey('sorting_mode', $user) ?: 'name';
$info['sorting_direction'] = $this->getUserConfigByKey('sorting_direction', $user) ?: 'asc';
$info['files_list_sorting_mode'] = $this->getUserConfigByKey('files_list_sorting_mode', $user) ?: 'name';
$info['files_list_sorting_direction'] = $this->getUserConfigByKey('files_list_sorting_direction', $user) ?: 'asc';

return $info;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/RightSidebar/RequestSignatureTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ export default {
subscribe('libresign:edit-signer', this.editSigner)
this.filesStore.disableIdentifySigner()

this.activeTab = this.userConfigStore.signer_identify_tab || ''
this.activeTab = this.userConfigStore.files_list_signer_identify_tab || ''

this.adminSignatureFlow = loadState('libresign', 'signature_flow', 'none')

Expand Down Expand Up @@ -709,7 +709,7 @@ export default {
}, 1000)

this.debouncedTabChange = debounce((tabId) => {
this.userConfigStore.update('signer_identify_tab', tabId)
this.userConfigStore.update('files_list_signer_identify_tab', tabId)
}, 500)
},
methods: {
Expand Down Expand Up @@ -866,7 +866,7 @@ export default {
},
addSigner() {
this.signerToEdit = {}
this.activeTab = this.userConfigStore.signer_identify_tab || ''
this.activeTab = this.userConfigStore.files_list_signer_identify_tab || ''
this.filesStore.enableIdentifySigner()
},
editSigner(signer) {
Expand Down
4 changes: 2 additions & 2 deletions src/store/filesSorting.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ export const useFilesSortingStore = defineStore('filesSorting', {

async saveSorting() {
try {
await axios.put(generateOcsUrl('/apps/libresign/api/v1/account/config/{key}', { key: 'sorting_mode' }), {
await axios.put(generateOcsUrl('/apps/libresign/api/v1/account/config/{key}', { key: 'files_list_sorting_mode' }), {
value: this.sortingMode,
})
await axios.put(generateOcsUrl('/apps/libresign/api/v1/account/config/{key}', { key: 'sorting_direction' }), {
await axios.put(generateOcsUrl('/apps/libresign/api/v1/account/config/{key}', { key: 'files_list_sorting_direction' }), {
value: this.sortingDirection,
})
} catch (error) {
Expand Down
6 changes: 3 additions & 3 deletions src/tests/store/filesSorting.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ vi.mock('@nextcloud/event-bus', () => ({
}))

vi.mock('@nextcloud/initial-state', () => ({
loadState: () => ({ sorting_mode: 'created_at', sorting_direction: 'desc' }),
loadState: () => ({ files_list_sorting_mode: 'name', files_list_sorting_direction: 'asc' }),
}))

vi.mock('@nextcloud/axios', () => ({
Expand Down Expand Up @@ -85,11 +85,11 @@ describe('filesSorting store', () => {

expect(putMock).toHaveBeenCalledTimes(2)
expect(putMock).toHaveBeenCalledWith(
'/apps/libresign/api/v1/account/config/sorting_mode',
'/apps/libresign/api/v1/account/config/files_list_sorting_mode',
{ value: 'created_at' }
)
expect(putMock).toHaveBeenCalledWith(
'/apps/libresign/api/v1/account/config/sorting_direction',
'/apps/libresign/api/v1/account/config/files_list_sorting_direction',
{ value: 'desc' }
)
})
Expand Down
4 changes: 2 additions & 2 deletions src/views/FilesList/FileEntry/FileEntryPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ export default {
const url = new URL(previewUrl)

// Request tiny previews
url.searchParams.set('x', this.userConfigStore.grid_view ? '128' : '32')
url.searchParams.set('y', this.userConfigStore.grid_view ? '128' : '32')
url.searchParams.set('x', this.userConfigStore.files_list_grid_view ? '128' : '32')
url.searchParams.set('y', this.userConfigStore.files_list_grid_view ? '128' : '32')
url.searchParams.set('mimeFallback', 'true')

// Handle cropping
Expand Down
6 changes: 3 additions & 3 deletions src/views/FilesList/FilesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
type="tertiary"
@click="toggleGridView">
<template #icon>
<ListViewIcon v-if="userConfigStore.grid_view" />
<ListViewIcon v-if="userConfigStore.files_list_grid_view" />
<ViewGridIcon v-else />
</template>
</NcButton>
Expand Down Expand Up @@ -136,7 +136,7 @@ export default {
return HomeSvg
},
gridViewButtonLabel() {
return this.userConfigStore.grid_view
return this.userConfigStore.files_list_grid_view
? t('libresign', 'Switch to list view')
: t('libresign', 'Switch to grid view')
},
Expand Down Expand Up @@ -165,7 +165,7 @@ export default {
this.filesStore.updateAllFiles()
},
toggleGridView() {
this.userConfigStore.update('grid_view', !this.userConfigStore.grid_view)
this.userConfigStore.update('files_list_grid_view', !this.userConfigStore.files_list_grid_view)
},
checkAndOpenFileFromUri() {
const uuid = this.$route.query.uuid
Expand Down
2 changes: 1 addition & 1 deletion src/views/FilesList/FilesListVirtual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-->
<template>
<VirtualList ref="table"
:data-component="userConfigStore.grid_view ? FileEntryGrid : FileEntry"
:data-component="userConfigStore.files_list_grid_view ? FileEntryGrid : FileEntry"
:loading="loading"
:caption="caption">
<template #filters>
Expand Down
4 changes: 2 additions & 2 deletions src/views/FilesList/VirtualList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-->
<template>
<div class="files-list"
:class="{ 'files-list--grid': userConfigStore.grid_view }"
:class="{ 'files-list--grid': userConfigStore.files_list_grid_view }"
data-cy-files-list>
<div class="files-list__filters">
<slot name="filters" />
Expand Down Expand Up @@ -38,7 +38,7 @@
</thead>
<!-- Body -->
<tbody class="files-list__tbody"
:class="userConfigStore.grid_view ? 'files-list__tbody--grid' : 'files-list__tbody--list'"
:class="userConfigStore.files_list_grid_view ? 'files-list__tbody--grid' : 'files-list__tbody--list'"
data-cy-files-list-tbody>
<component :is="dataComponent"
v-for="(item) in filesStore.filesSorted()"
Expand Down
Loading
Loading