From 20df342c9ad28c1ca35d14f7c6523ea4cdfed5a7 Mon Sep 17 00:00:00 2001 From: Eugen Ciur <eugen@papermerge.com> Date: Tue, 12 Apr 2022 21:22:18 +0200 Subject: [PATCH] add notification service --- app/app.js | 9 +++++- app/components/notifications/index.hbs | 5 ++++ app/components/notifications/index.js | 11 +++++++ app/components/notifications/toast/index.hbs | 21 ++++++++++++++ app/components/notifications/toast/index.js | 12 ++++++++ app/components/role/edit.js | 1 - .../viewer/action_buttons/index.hbs | 5 ++-- app/components/viewer/index.hbs | 1 + app/components/viewer/index.js | 23 +++++++++++++-- app/services/notify.js | 29 +++++++++++++++++++ app/styles/app.scss | 4 +++ app/templates/authenticated.hbs | 1 + package.json | 4 +-- 13 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 app/components/notifications/index.hbs create mode 100644 app/components/notifications/index.js create mode 100644 app/components/notifications/toast/index.hbs create mode 100644 app/components/notifications/toast/index.js create mode 100644 app/services/notify.js diff --git a/app/app.js b/app/app.js index 45290a9..a6a2cdc 100644 --- a/app/app.js +++ b/app/app.js @@ -3,7 +3,7 @@ import Resolver from 'ember-resolver'; import loadInitializers from 'ember-load-initializers'; import config from 'papermerge/config/environment'; import '@popperjs/core'; -import 'bootstrap'; +import bootstrap from 'bootstrap'; export default class App extends Application { @@ -27,6 +27,13 @@ export default class App extends Application { if (divs.length > 0) { divs[0].style.display = 'None'; } + + /*Initializer bootstrap toasts*/ + let toastElList = [].slice.call(document.querySelectorAll('.toast')) + toastElList.map(function (toastEl) { + return new bootstrap.Toast(toastEl) + }) + } } diff --git a/app/components/notifications/index.hbs b/app/components/notifications/index.hbs new file mode 100644 index 0000000..f6cc4c6 --- /dev/null +++ b/app/components/notifications/index.hbs @@ -0,0 +1,5 @@ +<div class="toast-container position-fixed top-0 end-0 p-3"> + {{#each this.notifications as |notification|}} + <Notifications::Toast @notification={{notification}} /> + {{/each}} +</div> diff --git a/app/components/notifications/index.js b/app/components/notifications/index.js new file mode 100644 index 0000000..e025c2d --- /dev/null +++ b/app/components/notifications/index.js @@ -0,0 +1,11 @@ +import Component from '@glimmer/component'; +import { service } from '@ember/service'; + + +export default class NotificationsComponent extends Component { + @service notify; + + get notifications() { + return this.notify.notifications; + } +} \ No newline at end of file diff --git a/app/components/notifications/toast/index.hbs b/app/components/notifications/toast/index.hbs new file mode 100644 index 0000000..ac47068 --- /dev/null +++ b/app/components/notifications/toast/index.hbs @@ -0,0 +1,21 @@ +<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true"> + <div class="toast-header"> + {{#if (is_equal this.type 'info') }} + <strong class="me-auto text-primary"> + <i class='bi bi-info-circle mx-2'></i>Info + </strong> + {{else if (is_equal this.type 'error')}} + <strong class="me-auto text-danger"> + <i class='bi bi-info-circle mx-2'></i>Error + </strong> + {{else}} + <strong class="me-auto text-warning"> + <i class='bi bi-info-circle mx-2'></i>Warning + </strong> + {{/if}} + <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> + </div> + <div class="toast-body"> + {{this.message}} + </div> +</div> diff --git a/app/components/notifications/toast/index.js b/app/components/notifications/toast/index.js new file mode 100644 index 0000000..03f0ff4 --- /dev/null +++ b/app/components/notifications/toast/index.js @@ -0,0 +1,12 @@ +import Component from '@glimmer/component'; + + +export default class ToastComponent extends Component { + get type() { + return this.args.notification.type; + } + + get message() { + return this.args.notification.message; + } +} \ No newline at end of file diff --git a/app/components/role/edit.js b/app/components/role/edit.js index 4096a36..2ff0d1c 100644 --- a/app/components/role/edit.js +++ b/app/components/role/edit.js @@ -1,6 +1,5 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; -import { tracked } from '@glimmer/tracking'; import { inject as service } from '@ember/service'; import { group_perms_by_model } from 'papermerge/utils'; diff --git a/app/components/viewer/action_buttons/index.hbs b/app/components/viewer/action_buttons/index.hbs index e52acb6..67102cd 100644 --- a/app/components/viewer/action_buttons/index.hbs +++ b/app/components/viewer/action_buttons/index.hbs @@ -31,10 +31,11 @@ {{#if @page_order_changed }} Page order changed. <button - class="btn btn-success" + class="btn btn-success pe-4" type="button" {{on "click" @onPageOrderApply}}> - Apply Changes + <Spinner @inProgress={{@apply_page_order_changes_in_progress}} /> + Apply Changes </button> <button class="btn btn-secondary" diff --git a/app/components/viewer/index.hbs b/app/components/viewer/index.hbs index 1925961..87dccdc 100644 --- a/app/components/viewer/index.hbs +++ b/app/components/viewer/index.hbs @@ -6,6 +6,7 @@ @ocrStatus={{this.ocrStatus}} @selectedPages={{this.selected_pages}} @page_order_changed={{this.page_order_changed}} + @apply_page_order_changes_in_progress={{this.apply_page_order_changes_in_progress}} @onPageOrderApply={{this.onPageOrderApply}} @onPageOrderDiscard={{this.onPageOrderDiscard}} @openConfirmDeletionModal={{this.openConfirmDeletionModal}} diff --git a/app/components/viewer/index.js b/app/components/viewer/index.js index 3afae65..ec2e4a2 100644 --- a/app/components/viewer/index.js +++ b/app/components/viewer/index.js @@ -23,6 +23,7 @@ export default class ViewerComponent extends Component { @service websockets; @service store; @service requests; + @service notify; @service router; @tracked ocr_status = null; @@ -38,6 +39,7 @@ export default class ViewerComponent extends Component { @tracked show_confirm_pages_deletion_modal = false; @tracked show_rename_node_modal = false; @tracked page_order_changed = false; + @tracked apply_page_order_changes_in_progress = false; initial_pages_memo = A([]); @@ -254,11 +256,26 @@ export default class ViewerComponent extends Component { @action async onPageOrderApply() { - await this.requests.reorderPagesApply({ + this.apply_page_order_changes_in_progress = true; + this.requests.reorderPagesApply({ old_items: this.initial_pages_memo, new_items: this.pages - }); - this.router.refresh(); + }).then( + () => { // on success + this.apply_page_order_changes_in_progress = false; + this.notify.info( + 'New page order successfully applied' + ); + this.page_order_changed = false; + }, + () => { // on failure + this.apply_page_order_changes_in_progress = false; + this.notify.error( + 'There was a problem while saving new page order' + ); + this.page_order_changed = false; + } + ); } @action diff --git a/app/services/notify.js b/app/services/notify.js new file mode 100644 index 0000000..0c8df9b --- /dev/null +++ b/app/services/notify.js @@ -0,0 +1,29 @@ +import Service from '@ember/service'; +import { tracked } from 'tracked-built-ins'; +import { TrackedArray } from 'tracked-built-ins'; + + +export default class Notify extends Service { + /* + Push notifications to your visitors with a toast, a lightweight and easily customizable alert message. + */ + @tracked notifications = new TrackedArray([]); + + info(message) { + let type = 'info'; + + this.notifications.push({message, type}); + } + + warning(message) { + let type = 'warning'; + + this.notifications.push({message, type}); + } + + error(message) { + let type = 'error'; + + this.notifications.push({message, type}); + } +} diff --git a/app/styles/app.scss b/app/styles/app.scss index 62e279d..3bd27af 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -73,3 +73,7 @@ main { .droparea { outline: 1px solid green; } + +.toast-container { + z-index: 1000; +} \ No newline at end of file diff --git a/app/templates/authenticated.hbs b/app/templates/authenticated.hbs index 56b274a..a28f426 100644 --- a/app/templates/authenticated.hbs +++ b/app/templates/authenticated.hbs @@ -6,6 +6,7 @@ @pinned_tags={{@model.pinned_tags}} @expanded={{this.expanded_sidebar}} /> <div class="w-100 central-bar"> + <Notifications /> <Nav::Topbar @onSidebarToggle={{this.onSidebarToggle}} /> <div class="container-fluid mx-2 my-1"> diff --git a/package.json b/package.json index f208e37..d26c936 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,8 @@ "prettier": "^2.5.1", "qunit": "^2.17.2", "qunit-dom": "^2.0.0", - "sass": "^1.47.0" + "sass": "^1.47.0", + "tracked-built-ins": "^2.0.1" }, "engines": { "node": "12.* || 14.* || >= 16" @@ -78,7 +79,6 @@ "edition": "octane" }, "devDependencies": { - "tracked-built-ins": "^2.0.1", "webpack": "^5.65.0" } } -- GitLab