Skip to content

Conversation

@samuelsonbrito
Copy link
Contributor

Pull Request Description

This pull request introduces a new Dashboard widget that displays documents with pending signatures for the current user. The widget lists only files that are associated with the user and are still awaiting their signature, providing quick access directly from the Dashboard.

The implementation reuses existing LibreSign services and mappers to ensure consistent permission checks and filtering logic. Each item shows relevant document information and links directly to the signing page, improving visibility and usability for users who need to complete pending signatures.

Pull Request Type

  • Feature
image

@github-project-automation github-project-automation bot moved this to 0. Needs triage in Roadmap Dec 30, 2025
@samuelsonbrito samuelsonbrito force-pushed the feat/dashboard-pending-signatures-widget branch 2 times, most recently from 42755c8 to 75371a1 Compare December 30, 2025 01:57
@samuelsonbrito samuelsonbrito self-assigned this Dec 30, 2025
@vitormattos
Copy link
Member

Nice! Make a rebase with main branch. I fixed the integration tests.

Signed-off-by: samuelsonmesquita <samuelsonma@gmail.com>
@samuelsonbrito samuelsonbrito force-pushed the feat/dashboard-pending-signatures-widget branch from 4343635 to 67205cd Compare December 31, 2025 15:04
Signed-off-by: samuelsonmesquita <samuelsonma@gmail.com>
@samuelsonbrito samuelsonbrito force-pushed the feat/dashboard-pending-signatures-widget branch from 67205cd to e3b9eea Compare December 31, 2025 15:29
Signed-off-by: samuelsonmesquita <samuelsonma@gmail.com>
@samuelsonbrito
Copy link
Contributor Author

image image

@samuelsonbrito samuelsonbrito force-pushed the feat/dashboard-pending-signatures-widget branch 2 times, most recently from f531813 to b58d236 Compare December 31, 2025 20:31
Signed-off-by: samuelsonmesquita <samuelsonma@gmail.com>
@samuelsonbrito samuelsonbrito force-pushed the feat/dashboard-pending-signatures-widget branch from b58d236 to 1d36bae Compare December 31, 2025 21:31
@samuelsonbrito samuelsonbrito marked this pull request as ready for review December 31, 2025 21:35

$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);

// Register Dashboard Widget
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method called already says this

Suggested change
// Register Dashboard Widget

Comment on lines +76 to +125
try {
$user = $this->userSession->getUser();
if (!$user) {
return new WidgetItems([], $this->l10n->t('User not found'));
}

$result = $this->signRequestMapper->getFilesAssociatedFilesWithMe(
$user,
['status' => [\OCA\Libresign\Db\File::STATUS_ABLE_TO_SIGN, \OCA\Libresign\Db\File::STATUS_PARTIAL_SIGNED]],
1,
$limit,
['sortBy' => 'created_at', 'sortDirection' => 'desc']
);

$items = [];

foreach ($result['data'] as $fileEntity) {
try {
$signRequest = $this->getSignRequestForUser($fileEntity, $user);

if (!$signRequest || $signRequest->getSigned()) {
continue;
}

$item = new WidgetItem(
$this->getDocumentTitle($fileEntity),
$this->getSubtitle($signRequest, $fileEntity),
$this->urlGenerator->linkToRouteAbsolute('libresign.page.signFPath', ['uuid' => $signRequest->getUuid(), 'path' => 'pdf']),
$this->urlGenerator->getAbsoluteURL(
$this->urlGenerator->imagePath('core', 'filetypes/application-pdf.svg')
),
$this->getTimestamp($fileEntity)
);

$items[] = $item;
} catch (\Exception $e) {
continue;
}
}

return new WidgetItems(
$items,
empty($items) ? $this->l10n->t('No pending signatures') : '',
);
} catch (\Exception $e) {
return new WidgetItems(
[],
$this->l10n->t('Error loading pending signatures'),
);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's strange a very big try catch. Maybe could be removed and believe into the requested methods.
The insider try catch also sounds strange because it's a controlled environment, isn't this?

@github-project-automation github-project-automation bot moved this from 0. Needs triage to 1. to do in Roadmap Jan 2, 2026
return null;
}

private function signRequestBelongsToUser(\OCA\Libresign\Db\SignRequest $signRequest, \OCP\IUser $user): bool {
Copy link
Member

@vitormattos vitormattos Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method isn't necessary because the method to list already will ensures this and only will return files that belongs to the signer.

Review the related logic because removing this, will affect other places of this class.

Comment on lines +158 to +173
private function getDocumentTitle(\OCA\Libresign\Db\File $fileEntity): string {
if ($fileEntity->getName()) {
return $fileEntity->getName();
}

try {
$files = $this->signFileService->getNextcloudFiles($fileEntity);
if (!empty($files)) {
$file = current($files);
return $file->getName();
}
} catch (\Exception $e) {
}

return $this->l10n->t('Document');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't necessary, the table file already have a column name, you can use the name, isn't a nullable value..

Copy link
Member

@vitormattos vitormattos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool! Visually it looks great.

I sent some comments regarding the backend; it needs some improvements.

Comment on lines +178 to +189
$displayName = $signRequest->getDisplayName();
if ($displayName) {
$parts[] = $this->l10n->t('From: %s', [$displayName]);
}

$createdAt = $fileEntity->getCreatedAt();
if ($createdAt instanceof \DateTime) {
$date = $createdAt->format('d/m/Y');
$parts[] = $this->l10n->t('Date: %s', [$date]);
}

return implode('', $parts);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't good to use implode with translated words. This could generate problems when the user language is RTL and not LTR.

Created at always exists and the name too.

Also is good to use // TRANSLATORS to add the translation context to translators.

@vitormattos
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 1. to do

Development

Successfully merging this pull request may close these issues.

3 participants