From c0ddd00cc68d4841cf14fa0cc8c335ae6bedb95f Mon Sep 17 00:00:00 2001 From: Aldarien Date: Wed, 30 Nov 2022 20:45:18 -0300 Subject: [PATCH] Scheduling UI corrected --- api/common/Controller/Jobs.php | 13 +- api/src/Model/Message.php | 31 ++- api/src/Repository/Message.php | 5 +- ui/resources/views/emails/messages.blade.php | 266 ++++++------------- 4 files changed, 115 insertions(+), 200 deletions(-) diff --git a/api/common/Controller/Jobs.php b/api/common/Controller/Jobs.php index d0eca33..9320eae 100644 --- a/api/common/Controller/Jobs.php +++ b/api/common/Controller/Jobs.php @@ -12,7 +12,7 @@ class Jobs { use Json; - public function schedule(ServerRequestInterface $request, ResponseInterface $response, Service $jobsService): ResponseInterface + public function schedule(ServerRequestInterface $request, ResponseInterface $response, Service $service, \ProVM\Common\Service\Messages $messagesService): ResponseInterface { $body = $request->getBody(); $json = \Safe\json_decode($body->getContents()); @@ -25,21 +25,24 @@ class Jobs 'scheduled' => 0 ]; foreach ($json->messages as $message_id) { - if ($jobsService->schedule($message_id)) { + if ($service->schedule($message_id)) { + $message = $messagesService->getRepository()->fetchById($message_id); + $message->doesHaveScheduledDownloads(); + $messagesService->getRepository()->save($message); $output['scheduled'] ++; } } return $this->withJson($response, $output); } - public function pending(ServerRequestInterface $request, ResponseInterface $response, Service $jobsService): ResponseInterface + public function pending(ServerRequestInterface $request, ResponseInterface $response, Service $service): ResponseInterface { $pending = array_map(function(Job $job) { return $job->toArray(); - }, $jobsService->getPending()); + }, $service->getPending()); $output = [ 'total' => count($pending), 'pending' => $pending ]; return $this->withJson($response, $output); } -} \ No newline at end of file +} diff --git a/api/src/Model/Message.php b/api/src/Model/Message.php index e89e27a..d9a4373 100644 --- a/api/src/Model/Message.php +++ b/api/src/Model/Message.php @@ -108,7 +108,12 @@ class Message implements Model } public function getState(string $name): \ProVM\Emails\Model\State\Message { - return $this->getStates()[$name]; + try { + return $this->getStates()[$name]; + } catch (\Exception $e) { + $this->newState($name); + return $this->getStates()[$name]; + } } public function addState(\ProVM\Emails\Model\State\Message $state): Message { @@ -127,6 +132,7 @@ class Message implements Model $this->addState((new \ProVM\Emails\Model\State\Message()) ->setName($name) ->setMessage($this) + ->setValue(false) ); return $this; } @@ -143,31 +149,31 @@ class Message implements Model { return $this->getState('downloaded_attachments')->getValue() ?? false; } + public function hasScheduledDownloads(): bool + { + return $this->getState('scheduled_downloads')->getValue() ?? false; + } public function doesHaveAttachments(): Message { - if (!isset($this->getStates()['has_attachments'])) { - $this->newState('has_attachments'); - } $this->getState('has_attachments')->setValue(true); return $this; } public function doesHaveValidAttachments(): Message { - if (!isset($this->getStates()['valid_attachments'])) { - $this->newState('valid_attachments'); - } $this->getState('valid_attachments')->setValue(true); return $this; } public function doesHaveDownloadedAttachments(): Message { - if (!isset($this->getStates()['downloaded_attachments'])) { - $this->newState('downloaded_attachments'); - } $this->getState('downloaded_attachments')->setValue(true); return $this; } + public function doesHaveScheduledDownloads(): Message + { + $this->getState('scheduled_downloads')->setValue(true); + return $this; + } protected array $attachments; public function getAttachments(): array @@ -205,11 +211,12 @@ class Message implements Model 'states' => [ 'has_attachments' => $this->hasAttachments(), 'valid_attachments' => $this->hasValidAttachments(), - 'downloaded_attachments' => $this->hasDownloadedAttachments() + 'downloaded_attachments' => $this->hasDownloadedAttachments(), + 'scheduled_downloads' => $this->hasScheduledDownloads() ], 'attachments' => $this->hasValidAttachments() ? array_map(function(Attachment $attachment) { return $attachment->toArray(); }, $this->getAttachments()) : [] ]; } -} \ No newline at end of file +} diff --git a/api/src/Repository/Message.php b/api/src/Repository/Message.php index 4976dd4..45d192f 100644 --- a/api/src/Repository/Message.php +++ b/api/src/Repository/Message.php @@ -111,7 +111,8 @@ class Message extends Repository $valid_states = [ 'has_attachments', 'valid_attachments', - 'downloaded_attachments' + 'downloaded_attachments', + 'scheduled_downloads' ]; foreach ($valid_states as $state_name) { try { @@ -160,4 +161,4 @@ class Message extends Repository WHERE `mailbox_id` = ? `subject` = ? AND `from` = ? AND `date_time` = ?"; return $this->fetchOne($query, [$mailbox_id, $subject, $from, $dateTime->format('Y-m-d H:i:s')]); } -} \ No newline at end of file +} diff --git a/ui/resources/views/emails/messages.blade.php b/ui/resources/views/emails/messages.blade.php index 47101f3..4af8bb1 100644 --- a/ui/resources/views/emails/messages.blade.php +++ b/ui/resources/views/emails/messages.blade.php @@ -17,7 +17,8 @@ states = { attachments: false, valid: false, - downloaded: false + downloaded: false, + scheduled: false } attachments @@ -81,10 +82,15 @@ const map_keys = { has_attachments: 'attachments', valid_attachments: 'valid', - downloaded_attachments: 'downloaded' + downloaded_attachments: 'downloaded', + scheduled_downloads: 'scheduled' } Object.keys(states).forEach(k => { - this.states[map_keys[k]] = states[k] + if (k in map_keys) { + this.states[map_keys[k]] = states[k] + } else { + this.states[map_keys[k]] = false + } }) return this }, @@ -103,6 +109,9 @@ }, downloaded: () => { return this.states.downloaded + }, + scheduled: () => { + return this.states.scheduled } } } @@ -119,80 +128,99 @@ downloaded: () => { this.states.downloaded = true return this + }, + scheduled: () => { + this.states.scheduled = true + return this } } } draw() { - const format = Intl.DateTimeFormat('es-CL', {dateStyle: 'full', timeStyle: 'short'}) - let date = new Date() - try { - date = new Date(this.get().date()) - } catch (e) { - console.debug(e) - } - const valid = $('').html($('').addClass(this.has().valid() ? 'green check circle icon' : 'red times circle icon')) - if (this.has().valid() && this.get().attachments().length > 0) { - const list = $('
').addClass('ui list') - this.get().attachments().forEach(attachment => { - list.append($('
').addClass('item').html(attachment.filename)) - }) - valid.append( - $('
').addClass('ui popup').append(list) - ) - } - const tr = $('').append( - $('').html(this.get().subject()) - ).append( - $('').html(format.format(date)) - ).append( - $('').html(this.get().from().full) - ).append( - $('').html($('').addClass(this.has().attachments() ? 'green check circle icon' : 'red times circle icon')) - ).append( - valid - ).append( - $('').html($('').addClass(this.has().downloaded() ? 'green check circle icon' : 'red times circle icon')) - ).append( - $('').append( - (this.has().attachments() && this.has().valid() && !this.has().downloaded()) ? - $('').addClass('ui mini green circular icon button').append( - $('').addClass('clock icon') - ).click(() => { - this.download().attachments(this.get().id()) - }) : '' - ) - ) - if (this.has().downloaded()) { - tr.find('td').each((i, td) => { - const content = $(td).html() - if (content.indexOf('icon') > -1) { - return + return { + row: () => { + const format = Intl.DateTimeFormat('es-CL', {dateStyle: 'full', timeStyle: 'short'}) + let date = new Date() + try { + date = new Date(this.get().date()) + } catch (e) { + console.debug(e) } - $(td).html('') - $(td).append( - $('').attr('href', '{{$urls->base}}/emails/message/' + this.id).html(content) + const valid = $('').html($('').addClass(this.has().valid() ? 'green check circle icon' : 'red times circle icon')) + if (this.has().valid() && this.get().attachments().length > 0) { + const list = $('
').addClass('ui list') + this.get().attachments().forEach(attachment => { + list.append($('
').addClass('item').html(attachment.filename)) + }) + valid.append( + $('
').addClass('ui popup').append(list) + ) + } + const tr = $('').attr('data-id', this.get().id()).append( + $('').html(this.get().subject()) + ).append( + $('').html(format.format(date)) + ).append( + $('').html(this.get().from().full) + ).append( + $('').html($('').addClass(this.has().attachments() ? 'green check circle icon' : 'red times circle icon')) + ).append( + valid + ).append( + $('').html($('').addClass(this.has().downloaded() ? 'green check circle icon' : 'red times circle icon')) + ).append( + $('').append( + (this.has().attachments() && this.has().valid() && !this.has().downloaded()) ? + ((this.has().scheduled()) ? this.draw().scheduledButton() : this.draw().scheduleButton()) : '' + ) ) - }) + if (this.has().downloaded()) { + tr.find('td').each((i, td) => { + const content = $(td).html() + if (content.indexOf('icon') > -1) { + return + } + $(td).html('') + $(td).append( + $('').attr('href', '{{$urls->base}}/emails/message/' + this.id).html(content) + ) + }) + } + return tr + }, + scheduleButton: () => { + return $('').addClass('ui mini circular icon button').append( + $('').addClass('clock icon') + ).click(e => { + this.download().attachments(e) + }) + }, + scheduledButton: () => { + return $('').addClass('ui green circular inverted check icon') + }, + schedulingButton: () => { + return $('').addClass('ui circular inverted redo loading icon') + } } - return tr } - download() { return { - attachments: id => { + attachments: event => { + const td = $(event.currentTarget).parent() + const id = this.get().id() const uri = '/messages/schedule' const data = { messages: [ id ] } + td.html('').append(this.draw().schedulingButton()) return Send.put({ uri, data }).then(response => { if (response.scheduled > 0) { - alert('Scheduled Attachments Job') + td.html('').append(this.draw().scheduledButton()) } }) } @@ -205,9 +233,6 @@ name: '', count: '' }, - page: 1, - current: 0, - shown: 10, total: null, visible: [], get: function() { @@ -250,7 +275,6 @@ } }, draw: function() { - const columns = 8 return { loader: () => { $(this.id.results).html('').append( @@ -270,8 +294,6 @@ this.draw().head() ).append( this.draw().body() - ).append( - this.draw().footer() ) }, head: () => { @@ -286,43 +308,8 @@ } values.push(v) } - const dropdown = $('
').addClass('ui scrolling dropdown').append( - $('').addClass('dropdown icon') - ).append( - $('
').addClass('text').html(this.shown) - ).dropdown({ - values, - onChange: (value, text, $choice) => { - if (value === this.shown) { - return - } - this.shown = parseInt(value) - // Trigger pending transition - $choice.parent().parent().dropdown('hide') - this.get() - } - }) + return $('').append( - $('').append( - $('').addClass('right aligned').attr('colspan', columns).append( - dropdown - ).append( - $('').addClass('ui basic label').html((this.current + 1) + ' - ' + Math.min(this.shown + this.current, this.total ?? 99999999)) - ).append( - $('').addClass('ui mini circular icon button').append( - $('').addClass('left chevron icon') - ).click(() => { - this.prev() - }) - ).append( - $('').addClass('ui mini circular icon button').append( - $('').addClass('right chevron icon') - ).click(() => { - this.next() - }) - ) - ) - ).append( $('').append( $('').html('#') ).append( @@ -345,7 +332,7 @@ body: () => { const tbody = $('') this.visible.forEach((m, i) => { - const row = m.draw() + const row = m.draw().row() row.prepend( $('').html(i + this.current + 1) ) @@ -353,95 +340,12 @@ }) return tbody }, - footer: () => { - const pages = this.lastPage() - const paging = $('
').addClass('ui right floated pagination menu') - if (this.page !== 1) { - paging.append( - $('').addClass('icon item').append( - $('').addClass('step backward icon') - ).click(() => { - this.first() - }) - ) - } - for (let i = 0; i < pages; i ++) { - const page = $('').addClass('item').html(i + 1).click(() => { - this.goto(i + 1) - }) - if (i + 1 === this.page) { - page.addClass('active') - } - paging.append(page) - } - if (this.page !== this.lastPage()) { - paging.append( - $('').addClass('icon item').append( - $('').addClass('step forward icon') - ).click(() => { - this.last() - }) - ) - } - return $('').append( - $('').append( - $('').attr('colspan', columns).append(paging) - ) - ) - }, empty: () => { $(this.id.count).html(' (0)') return $('
').addClass('ui message').html('No messages found.') } } }, - lastPage: function() { - let pages = Math.floor(this.total / this.shown) - if (this.total / this.shown > pages) { - pages ++ - } - return pages - }, - first: function() { - if (this.current === 0) { - return - } - this.page = 1 - this.current = 0 - this.get() - }, - next: function() { - if (this.current + this.shown >= this.total) { - return - } - this.page ++ - this.current += this.shown - this.get() - }, - goto: function(page) { - if (this.page === page) { - return - } - this.page = page - this.current = (this.page - 1) * this.shown - this.get() - }, - prev: function() { - if (this.current < this.shown) { - return - } - this.page -- - this.current -= this.shown - this.get() - }, - last: function() { - if (this.page === this.lastPage()) { - return - } - this.page = this.lastPage() - this.current = (this.page - 1) * this.shown - this.get() - }, setup: function() { this.get().mailbox().then(() => { this.get().messages()