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
7 changes: 7 additions & 0 deletions lib/Controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace OCA\Libresign\Controller;

use DateTimeInterface;
use OCA\Libresign\AppInfo\Application;
use OCA\Libresign\Exception\LibresignException;
use OCA\Libresign\Handler\CertificateEngine\CertificateEngineFactory;
Expand Down Expand Up @@ -631,6 +632,9 @@ public function updateOID(string $oid): DataResponse {
#[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/admin/reminder', requirements: ['apiVersion' => '(v1)'])]
public function reminderFetch(): DataResponse {
$response = $this->reminderService->getSettings();
if ($response['next_run'] instanceof \DateTime) {
$response['next_run'] = $response['next_run']->format(DateTimeInterface::ATOM);
}
return new DataResponse($response);
}

Expand All @@ -653,6 +657,9 @@ public function reminderSave(
string $sendTimer,
): DataResponse {
$response = $this->reminderService->save($daysBefore, $daysBetween, $max, $sendTimer);
if ($response['next_run'] instanceof \DateTime) {
$response['next_run'] = $response['next_run']->format(DateTimeInterface::ATOM);
}
return new DataResponse($response);
}
}
1 change: 1 addition & 0 deletions lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
* days_between: non-negative-int,
* max: non-negative-int,
* send_timer: string,
* next_run?: string,
* }
* @psalm-type LibresignCapabilities = array{
* features: list<string>,
Expand Down
19 changes: 15 additions & 4 deletions lib/Service/ReminderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace OCA\Libresign\Service;

use DateTime;
use OCA\Libresign\AppInfo\Application;
use OCA\Libresign\BackgroundJob\Reminder;
use OCA\Libresign\Db\SignRequestMapper;
Expand All @@ -29,12 +30,18 @@ public function __construct(
}

public function getSettings(): array {
return [
$settings = [
'days_before' => $this->appConfig->getValueInt(Application::APP_ID, 'reminder_days_before', 0),
'days_between' => $this->appConfig->getValueInt(Application::APP_ID, 'reminder_days_between', 0),
'max' => $this->appConfig->getValueInt(Application::APP_ID, 'reminder_max', 0),
'send_timer' => $this->appConfig->getValueString(Application::APP_ID, 'reminder_send_timer', '10:00'),
'next_run' => null,
];
foreach ($this->jobList->getJobsIterator(Reminder::class, 1, 0) as $job) {
$details = $this->jobList->getDetailsById($job->getId());
$settings['next_run'] = new \DateTime('@' . $details['last_checked'], new \DateTimeZone('UTC'));
}
return $settings;
}

public function save(
Expand All @@ -44,7 +51,7 @@ public function save(
string $sendTimer,
): array {
$config = $this->saveConfig($daysBefore, $daysBetween, $max, $sendTimer);
$this->scheduleJob($config['send_timer']);
$config['next_run'] = $this->scheduleJob($config['send_timer']);
return $config;
}

Expand Down Expand Up @@ -106,20 +113,24 @@ private function setIfChangedString(string $key, string $value, string $default
}
}

protected function scheduleJob(string $startTime): void {
protected function scheduleJob(string $startTime): ?DateTime {
$this->jobList->remove(
Reminder::class,
);

if ($startTime === '') {
return null;
}
$runAfter = $this->getStartTime($startTime);
if (!$runAfter) {
return;
return null;
}

$this->jobList->scheduleAfter(
Reminder::class,
$runAfter->getTimestamp(),
);
return $runAfter;
}

protected function getStartTime(string $startTime): ?\DateTime {
Expand Down
3 changes: 3 additions & 0 deletions openapi-administration.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@
},
"send_timer": {
"type": "string"
},
"next_run": {
"type": "string"
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,9 @@
},
"send_timer": {
"type": "string"
},
"next_run": {
"type": "string"
}
}
},
Expand Down
1 change: 1 addition & 0 deletions src/types/openapi/openapi-administration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ export type components = {
/** Format: int64 */
max: number;
send_timer: string;
next_run?: string;
};
RootCertificate: {
commonName: string;
Expand Down
1 change: 1 addition & 0 deletions src/types/openapi/openapi-full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,7 @@ export type components = {
/** Format: int64 */
max: number;
send_timer: string;
next_run?: string;
};
RootCertificate: {
commonName: string;
Expand Down
15 changes: 15 additions & 0 deletions src/views/Settings/Reminders.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
class="settings-section__loading-icon"
:size="20" />
<div v-if="reminderState">
{{ t('libresign', 'Next job execution: {date}', {date: nextRunFormatted}) }}
<NcTextField :value.sync="reminderDaysBefore"
:label="t('libresign', 'First reminder after (days)')"
:placeholder="t('libresign', 'First reminder after (days)')"
Expand Down Expand Up @@ -61,6 +62,7 @@ import debounce from 'debounce'

import axios from '@nextcloud/axios'
import { translate as t } from '@nextcloud/l10n'
import Moment from '@nextcloud/moment'
import { generateOcsUrl } from '@nextcloud/router'

import { NcDateTimePickerNative } from '@nextcloud/vue'
Expand Down Expand Up @@ -100,6 +102,7 @@ export default {
previousReminderMax: 0,
displaySuccessReminderMax: false,
reminderState: false,
nextRun: null,
loading: false,
}
},
Expand All @@ -111,6 +114,13 @@ export default {
reminderState: this.reminderState ? t('libresign', 'off') : t('libresign', 'on'),
})
},
nextRunFormatted() {
if (this.nextRun) {
return this.dateFromSqlAnsi(this.nextRun)
}
// TRANSLATORS No next reminder job to signers is scheduled
return t('libresign', 'Not scheduled')
},
},
watch: {
reminderState(reminderState) {
Expand All @@ -128,6 +138,9 @@ export default {
this.getData()
},
methods: {
dateFromSqlAnsi(date) {
return Moment(Date.parse(date)).format('LL LTS')
},
async getData() {
this.loading = true

Expand All @@ -148,6 +161,7 @@ export default {
this.reminderState = this.reminderDaysBefore > 0
|| this.reminderDaysBetween > 0
|| this.max > 0
this.nextRun = response.next_run
})
.finally(() => {
this.loading = false
Expand Down Expand Up @@ -194,6 +208,7 @@ export default {
this.displaySuccessReminderSendTimer = true
setTimeout(() => { this.displaySuccessReminderSendTimer = false }, 2000)
}
this.nextRun = response.next_run
})
}, 1000),
formatHourMinute(date) {
Expand Down
75 changes: 65 additions & 10 deletions tests/php/Unit/Service/ReminderServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,42 +347,97 @@ public function testSave(
}

public static function providerSave(): array {
$now = (new DateTime());
return [
[
'daysBefore' => 0, 'daysBetween' => 0, 'max' => 0, 'sendTimer' => '',
'expected' => ['days_before' => 0, 'days_between' => 0, 'max' => 0, 'send_timer' => ''],
'expected' => [
'days_before' => 0,
'days_between' => 0,
'max' => 0,
'next_run' => null,
'send_timer' => '',
],
],
[
'daysBefore' => 0, 'daysBetween' => 0, 'max' => 1, 'sendTimer' => '',
'expected' => ['days_before' => 0, 'days_between' => 0, 'max' => 0, 'send_timer' => ''],
'expected' => [
'days_before' => 0,
'days_between' => 0,
'max' => 0,
'next_run' => null,
'send_timer' => '',
],
],
[
'daysBefore' => 0, 'daysBetween' => 1, 'max' => 0, 'sendTimer' => '',
'expected' => ['days_before' => 0, 'days_between' => 0, 'max' => 0, 'send_timer' => ''],
'expected' => [
'days_before' => 0,
'days_between' => 0,
'max' => 0,
'next_run' => null,
'send_timer' => '',
],
],
[
'daysBefore' => 0, 'daysBetween' => 1, 'max' => 1, 'sendTimer' => '',
'expected' => ['days_before' => 0, 'days_between' => 0, 'max' => 0, 'send_timer' => ''],
'expected' => [
'days_before' => 0,
'days_between' => 0,
'max' => 0,
'next_run' => null,
'send_timer' => '',
],
],
[
'daysBefore' => 1, 'daysBetween' => 0, 'max' => 0, 'sendTimer' => '',
'expected' => ['days_before' => 0, 'days_between' => 0, 'max' => 0, 'send_timer' => ''],
'expected' => [
'days_before' => 0,
'days_between' => 0,
'max' => 0,
'next_run' => null,
'send_timer' => '',
],
],
[
'daysBefore' => 1, 'daysBetween' => 1, 'max' => 0, 'sendTimer' => '',
'expected' => ['days_before' => 0, 'days_between' => 0, 'max' => 0, 'send_timer' => ''],
'expected' => [
'days_before' => 0,
'days_between' => 0,
'max' => 0,
'next_run' => null,
'send_timer' => '',
],
],
[
'daysBefore' => 1, 'daysBetween' => 1, 'max' => 1, 'sendTimer' => '',
'expected' => ['days_before' => 1, 'days_between' => 1, 'max' => 1, 'send_timer' => '10:00'],
'expected' => [
'days_before' => 1,
'days_between' => 1,
'max' => 1,
'next_run' => (clone $now)->modify('+1 day')->setTime(10, 0),
'send_timer' => '10:00',
],
],
[
'daysBefore' => 1, 'daysBetween' => 1, 'max' => 1, 'sendTimer' => '11:05:00',
'expected' => ['days_before' => 1, 'days_between' => 1, 'max' => 1, 'send_timer' => '10:00'],
'daysBefore' => 1, 'daysBetween' => 1, 'max' => 1, 'sendTimer' => '11:05:00', // Invalid timer, need to be HH:mm
'expected' => [
'days_before' => 1,
'days_between' => 1,
'max' => 1,
'next_run' => (clone $now)->modify('+1 day')->setTime(10, 0),
'send_timer' => '10:00',
],
],
[
'daysBefore' => 1, 'daysBetween' => 1, 'max' => 1, 'sendTimer' => '11:05',
'expected' => ['days_before' => 1, 'days_between' => 1, 'max' => 1, 'send_timer' => '11:05'],
'expected' => [
'days_before' => 1,
'days_between' => 1,
'max' => 1,
'next_run' => (clone $now)->modify('+1 day')->setTime(11, 5),
'send_timer' => '11:05',
],
],
];
}
Expand Down
Loading