Merge pull request #5472 from LibreSign/chore/filters-modified-and-status

chore: adjustment in the filters modified and status
This commit is contained in:
Vitor Mattos 2025-12-08 18:13:19 -03:00 committed by GitHub
commit 252018adb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 133 additions and 20 deletions

View file

@ -83,6 +83,7 @@ class PageController extends AEnvironmentPageAwareController {
#[FrontpageRoute(verb: 'GET', url: '/')]
public function index(): TemplateResponse {
$this->initialState->provideInitialState('config', $this->accountService->getConfig($this->userSession->getUser()));
$this->initialState->provideInitialState('filters', $this->accountService->getConfigFilters($this->userSession->getUser()));
$this->initialState->provideInitialState('certificate_engine', $this->accountService->getCertificateEngineName());
try {

View file

@ -554,13 +554,15 @@ class SignRequestMapper extends QBMapper {
);
}
if (!empty($filter['start'])) {
$start = (new \DateTime('@' . $filter['start'], new \DateTimeZone('UTC')))->format('Y-m-d H:i:s');
$qb->andWhere(
$qb->expr()->gte('f.created_at', $qb->createNamedParameter($filter['start'], IQueryBuilder::PARAM_INT))
$qb->expr()->gte('f.created_at', $qb->createNamedParameter($start, IQueryBuilder::PARAM_STR))
);
}
if (!empty($filter['end'])) {
$end = (new \DateTime('@' . $filter['end'], new \DateTimeZone('UTC')))->format('Y-m-d H:i:s');
$qb->andWhere(
$qb->expr()->lte('f.created_at', $qb->createNamedParameter($filter['end'], IQueryBuilder::PARAM_INT))
$qb->expr()->lte('f.created_at', $qb->createNamedParameter($end, IQueryBuilder::PARAM_STR))
);
}
}

View file

@ -194,16 +194,21 @@ class AccountService {
$info['hasSignatureFile'] = $this->hasSignatureFile($user);
$info['phoneNumber'] = $this->getPhoneNumber($user);
$info['isApprover'] = $this->validateHelper->userCanApproveValidationDocuments($user, false);
$info['grid_view'] = $this->getUserConfigGridView($user);
$info['id_docs_filters'] = $this->getUserConfigIdDocsFilters($user);
$info['id_docs_sort'] = $this->getUserConfigIdDocsSort($user);
$info['crl_filters'] = $this->getUserConfigCrlFilters($user);
$info['crl_sort'] = $this->getUserConfigCrlSort($user);
$info['grid_view'] = $this->getUserConfigByKey($user, 'grid_view') === '1';
return array_filter($info);
}
public function getConfigFilters(?IUser $user = null): array {
$info['filter_modified'] = $this->getUserConfigByKey($user, 'filter_modified');
$info['filter_status'] = $this->getUserConfigByKey($user, 'filter_status');
return $info;
}
private function updateIdentifyMethodToAccount(int $signRequestId, string $email, string $uid): void {
$identifyMethods = $this->identifyMethodService->getIdentifyMethodsFromSignRequestId($signRequestId);
@ -241,12 +246,12 @@ class AccountService {
}
}
private function getUserConfigGridView(?IUser $user = null): bool {
private function getUserConfigByKey(?IUser $user = null, string $key): string {
if (!$user) {
return false;
return '';
}
return $this->config->getUserValue($user->getUID(), Application::APP_ID, 'grid_view', false) === '1';
return $this->config->getUserValue($user->getUID(), Application::APP_ID, $key);
}
private function getUserConfigIdDocsFilters(?IUser $user = null): array {

View file

@ -6,25 +6,71 @@
import { defineStore } from 'pinia'
import { emit } from '@nextcloud/event-bus'
import { loadState } from '@nextcloud/initial-state'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import logger from '../helpers/logger.js'
export const useFiltersStore = defineStore('filter', {
state: () => ({
chips: {},
filter_modified: loadState('libresign', 'filters', { filter_modified: '' }).filter_modified,
filter_status: loadState('libresign', 'filters', { filter_status: '' }).filter_status,
}),
getters: {
activeChips(state) {
return Object.values(state.chips).flat()
},
filterStatusArray(state) {
try {
return state.filter_status != '' ? JSON.parse(state.filter_status) : []
} catch (e) {
console.error('Erro ao converter filter_status:', e)
return []
}
},
},
actions: {
onFilterUpdateChips(event) {
async onFilterUpdateChips(event) {
this.chips = { ...this.chips, [event.id]: [...event.detail] }
emit('libresign:filters:update')
logger.debug('File list filter chips updated', { chips: event.detail })
},
async onFilterUpdateChipsAndSave(event) {
this.chips = { ...this.chips, [event.id]: [...event.detail] }
if(event.id == 'modified'){
let value = this.chips['modified'][0]?.id || '';
await axios.put(generateOcsUrl('/apps/libresign/api/v1/account/config/{key}', { key: 'filter_modified' }), {
value,
})
emit('libresign:filters:update')
}
if(event.id == 'status'){
const value = event.detail.length > 0 ? JSON.stringify(event.detail.map(item => item.id)) : '';
await axios.put(generateOcsUrl('/apps/libresign/api/v1/account/config/{key}', { key: 'filter_status' }), {
value,
})
this.filter_status = value
emit('libresign:filters:update')
}
logger.debug('File list filter chips updated', { chips: event.detail })
},
},
})

View file

@ -48,8 +48,10 @@ export default {
</script>
<style scoped lang="scss">
.files-list-filter__clear-button :deep(.action-button__text) {
.files-list-filter__clear-button {
:deep(.action-button__text) {
color: var(--color-error-text);
}
}
:deep(.button-vue) {

View file

@ -51,7 +51,7 @@ export default {
},
data() {
return {
selectedOption: null,
selectedOption: this.filtersStore.filter_modified || null,
timePresets: [
{
id: 'today',
@ -94,6 +94,11 @@ export default {
return this.timePresets.find(({ id }) => id === this.selectedOption) ?? null
},
},
mounted() {
if (this.selectedOption) {
this.setPreset(this.currentPreset)
}
},
watch: {
selectedOption() {
if (this.selectedOption === null) {
@ -101,8 +106,8 @@ export default {
this.setPreset()
} else {
this.setPreset(this.currentPreset)
}
this.setMarkedFilter()
},
},
methods: {
@ -114,6 +119,7 @@ export default {
end: preset.end,
icon: calendarSvg,
text: preset.label,
id: preset.id,
onclick: () => this.setPreset(),
})
} else {
@ -126,8 +132,26 @@ export default {
this.selectedOption = null
this.timeRangeEnd = null
this.timeRangeStart = null
this.filtersStore.onFilterUpdateChipsAndSave({ detail: '', id: 'modified' })
}
},
setMarkedFilter() {
const chips = []
const preset = this.currentPreset
if (preset) {
chips.push({
start: preset.start,
end: preset.end,
icon: calendarSvg,
text: preset.label,
id: preset.id,
onclick: () => this.setPreset(),
})
}
this.filtersStore.onFilterUpdateChipsAndSave({ detail: chips, id: 'modified' })
},
},
}
</script>

View file

@ -13,8 +13,8 @@
<NcActionButton v-for="status of fileStatus"
:key="status.id"
type="checkbox"
:model-value="selectedOptions.includes(status)"
@click="toggleOption(status)">
:model-value="selectedOptions.includes(status.id)"
@click="toggleOption(status.id)">
<template #icon>
<NcIconSvgWrapper :svg="status.icon" />
</template>
@ -50,7 +50,7 @@ export default {
},
data() {
return {
selectedOptions: [],
selectedOptions: this.filtersStore.filterStatusArray || [],
}
},
computed: {
@ -61,6 +61,11 @@ export default {
return fileStatus.filter(item => [0, 1, 2, 3].includes(item.id))
},
},
mounted() {
if (this.selectedOptions.length > 0) {
this.setMarkedFilter()
}
},
watch: {
selectedOptions(newValue, oldValue) {
if (newValue.length === 0) {
@ -68,18 +73,24 @@ export default {
} else {
this.setPreset(newValue)
}
this.setMarkedFilter()
},
},
methods: {
setPreset(presets) {
const chips = []
if (presets && presets.length > 0) {
for (const preset of presets) {
for (const id of presets) {
const status = fileStatus.find(item => item.id === id)
if (!status) continue
chips.push({
id: preset.id,
icon: preset.icon,
text: preset.label,
onclick: () => this.setPreset(presets.filter(({ id }) => id !== preset.id)),
id: status.id,
icon: status.icon || '',
text: status.label,
onclick: () => {
this.selectedOptions = this.selectedOptions.filter(v => v !== status.id)
},
})
}
} else {
@ -90,6 +101,7 @@ export default {
resetFilter() {
if (this.selectedOptions.length > 0) {
this.selectedOptions = []
this.filtersStore.onFilterUpdateChipsAndSave({ detail: [], id: 'status' })
}
},
toggleOption(option) {
@ -100,6 +112,27 @@ export default {
this.selectedOptions.push(option)
}
},
setMarkedFilter() {
const chips = []
if (this.selectedOptions.length > 0) {
for (const id of this.selectedOptions) {
const status = fileStatus.find(item => item.id === id)
if (!status) continue
chips.push({
id: status.id,
icon: status.icon || '',
text: status.label,
onclick: () => {
this.selectedOptions = this.selectedOptions.filter(v => v !== id)
},
})
}
}
this.filtersStore.onFilterUpdateChipsAndSave({ detail: chips, id: 'status' })
}
},
}
</script>