MOBILE-1332 notes: Delete notes

main
Pau Ferrer Ocaña 2019-01-23 16:56:06 +01:00
parent fb84053da1
commit 58b2e33156
6 changed files with 83 additions and 1 deletions

View File

@ -898,7 +898,9 @@
"addon.mod_workshop_assessment_rubric.mustchooseone": "workshopform_rubric", "addon.mod_workshop_assessment_rubric.mustchooseone": "workshopform_rubric",
"addon.notes.addnewnote": "notes", "addon.notes.addnewnote": "notes",
"addon.notes.coursenotes": "notes", "addon.notes.coursenotes": "notes",
"addon.notes.deleteconfirm": "notes",
"addon.notes.eventnotecreated": "notes", "addon.notes.eventnotecreated": "notes",
"addon.notes.eventnotedeleted": "notes",
"addon.notes.nonotes": "notes", "addon.notes.nonotes": "notes",
"addon.notes.note": "notes", "addon.notes.note": "notes",
"addon.notes.notes": "notes", "addon.notes.notes": "notes",

View File

@ -1,4 +1,7 @@
<core-navbar-buttons end> <core-navbar-buttons end>
<button *ngIf="canDeleteNotes" item-end ion-button icon-only clear (click)="toggleDelete($event)" [attr.aria-label]="'core.delete' | translate">
<ion-icon name="create" ios="md-create"></ion-icon>
</button>
<core-context-menu> <core-context-menu>
<core-context-menu-item [hidden]="!(notesLoaded && !hasOffline)" [priority]="100" [content]="'core.refresh' | translate" (action)="refreshNotes(false)" [iconAction]="refreshIcon" [closeOnClick]="true"></core-context-menu-item> <core-context-menu-item [hidden]="!(notesLoaded && !hasOffline)" [priority]="100" [content]="'core.refresh' | translate" (action)="refreshNotes(false)" [iconAction]="refreshIcon" [closeOnClick]="true"></core-context-menu-item>
<core-context-menu-item [hidden]="!(notesLoaded && hasOffline)" [priority]="100" [content]="'core.settings.synchronizenow' | translate" (action)="refreshNotes(true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> <core-context-menu-item [hidden]="!(notesLoaded && hasOffline)" [priority]="100" [content]="'core.settings.synchronizenow' | translate" (action)="refreshNotes(true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
@ -37,6 +40,9 @@
<h2 *ngIf="!userId">{{note.userfullname}}</h2> <h2 *ngIf="!userId">{{note.userfullname}}</h2>
<p *ngIf="!note.offline" item-end>{{note.lastmodified | coreDateDayOrTime}}</p> <p *ngIf="!note.offline" item-end>{{note.lastmodified | coreDateDayOrTime}}</p>
<p *ngIf="note.offline" item-end><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> <p *ngIf="note.offline" item-end><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p>
<button *ngIf="showDelete && (type != 'personal' || note.usermodified == currentUserId)" item-end ion-button icon-only clear [@coreSlideInOut]="'fromRight'" color="danger" (click)="deleteNote($event, note)" [attr.aria-label]="'core.delete' | translate">
<ion-icon name="trash"></ion-icon>
</button>
</ion-item> </ion-item>
<ion-item text-wrap> <ion-item text-wrap>
<core-format-text [clean]="true" [text]="note.content"></core-format-text> <core-format-text [clean]="true" [text]="note.content"></core-format-text>

View File

@ -14,11 +14,13 @@
import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Content, ModalController } from 'ionic-angular'; import { Content, ModalController } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
import { coreSlideInOut } from '@classes/animations';
import { AddonNotesProvider } from '../../providers/notes'; import { AddonNotesProvider } from '../../providers/notes';
import { AddonNotesSyncProvider } from '../../providers/notes-sync'; import { AddonNotesSyncProvider } from '../../providers/notes-sync';
@ -28,6 +30,7 @@ import { AddonNotesSyncProvider } from '../../providers/notes-sync';
@Component({ @Component({
selector: 'addon-notes-list', selector: 'addon-notes-list',
templateUrl: 'addon-notes-list.html', templateUrl: 'addon-notes-list.html',
animations: [coreSlideInOut]
}) })
export class AddonNotesListComponent implements OnInit, OnDestroy { export class AddonNotesListComponent implements OnInit, OnDestroy {
@Input() courseId: number; @Input() courseId: number;
@ -44,11 +47,14 @@ export class AddonNotesListComponent implements OnInit, OnDestroy {
hasOffline = false; hasOffline = false;
notesLoaded = false; notesLoaded = false;
user: any; user: any;
showDelete = false;
canDeleteNotes = false;
currentUserId: number;
constructor(private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, constructor(private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider,
sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, private modalCtrl: ModalController, sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, private modalCtrl: ModalController,
private notesProvider: AddonNotesProvider, private notesSync: AddonNotesSyncProvider, private notesProvider: AddonNotesProvider, private notesSync: AddonNotesSyncProvider,
private userProvider: CoreUserProvider) { private userProvider: CoreUserProvider, private translate: TranslateService) {
// Refresh data if notes are synchronized automatically. // Refresh data if notes are synchronized automatically.
this.syncObserver = eventsProvider.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => { this.syncObserver = eventsProvider.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => {
if (data.courseId == this.courseId) { if (data.courseId == this.courseId) {
@ -64,6 +70,8 @@ export class AddonNotesListComponent implements OnInit, OnDestroy {
this.fetchNotes(false); this.fetchNotes(false);
} }
}, sitesProvider.getCurrentSiteId()); }, sitesProvider.getCurrentSiteId());
this.currentUserId = sitesProvider.getCurrentSiteUserId();
} }
/** /**
@ -111,6 +119,14 @@ export class AddonNotesListComponent implements OnInit, OnDestroy {
}).catch((message) => { }).catch((message) => {
this.domUtils.showErrorModal(message); this.domUtils.showErrorModal(message);
}).finally(() => { }).finally(() => {
let canDelete = this.notes && this.notes.length > 0;
if (canDelete && this.type == 'personal') {
canDelete = this.notes.find((note) => {
return note.usermodified == this.currentUserId;
});
}
this.canDeleteNotes = canDelete;
this.notesLoaded = true; this.notesLoaded = true;
this.refreshIcon = 'refresh'; this.refreshIcon = 'refresh';
this.syncIcon = 'sync'; this.syncIcon = 'sync';
@ -151,6 +167,7 @@ export class AddonNotesListComponent implements OnInit, OnDestroy {
/** /**
* Add a new Note to user and course. * Add a new Note to user and course.
*
* @param {Event} e Event. * @param {Event} e Event.
*/ */
addNote(e: Event): void { addNote(e: Event): void {
@ -173,6 +190,38 @@ export class AddonNotesListComponent implements OnInit, OnDestroy {
modal.present(); modal.present();
} }
/**
* Delete a note.
*
* @param {Event} e Click event.
* @param {any} note Note to delete.
*/
deleteNote(e: Event, note: any): void {
e.preventDefault();
e.stopPropagation();
this.domUtils.showConfirm(this.translate.instant('addon.notes.deleteconfirm')).then(() => {
this.notesProvider.deleteNote(note).then(() => {
this.showDelete = false;
this.refreshNotes(true);
this.domUtils.showToast('addon.notes.eventnotedeleted', true, 3000);
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'Delete note failed.');
});
}).catch(() => {
// User cancelled, nothing to do.
});
}
/**
* Toggle delete.
*/
toggleDelete(): void {
this.showDelete = !this.showDelete;
}
/** /**
* Tries to synchronize course notes. * Tries to synchronize course notes.
* *

View File

@ -1,7 +1,9 @@
{ {
"addnewnote": "Add a new note", "addnewnote": "Add a new note",
"coursenotes": "Course notes", "coursenotes": "Course notes",
"deleteconfirm": "Delete this note?",
"eventnotecreated": "Note created", "eventnotecreated": "Note created",
"eventnotedeleted": "Note deleted",
"nonotes": "There are no notes of this type yet", "nonotes": "There are no notes of this type yet",
"note": "Note", "note": "Note",
"notes": "Notes", "notes": "Notes",

View File

@ -133,6 +133,27 @@ export class AddonNotesProvider {
}); });
} }
/**
* Delete a note.
*
* @param {any} note Note object to delete.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<void>} Promise resolved when done.
*/
deleteNote(note: any, siteId?: string): Promise<void> {
return this.sitesProvider.getSite(siteId).then((site) => {
if (typeof note.offline != 'undefined' && note.offline) {
return this.notesOffline.deleteNote(note.userid, note.content, note.created, site.id);
}
const data = {
notes: [note.id]
};
return site.write('core_notes_delete_notes', data);
});
}
/** /**
* Returns whether or not the notes plugin is enabled for a certain site. * Returns whether or not the notes plugin is enabled for a certain site.
* *

View File

@ -898,7 +898,9 @@
"addon.mod_workshop_assessment_rubric.mustchooseone": "You have to select one of these items", "addon.mod_workshop_assessment_rubric.mustchooseone": "You have to select one of these items",
"addon.notes.addnewnote": "Add a new note", "addon.notes.addnewnote": "Add a new note",
"addon.notes.coursenotes": "Course notes", "addon.notes.coursenotes": "Course notes",
"addon.notes.deleteconfirm": "Delete this note?",
"addon.notes.eventnotecreated": "Note created", "addon.notes.eventnotecreated": "Note created",
"addon.notes.eventnotedeleted": "Note deleted",
"addon.notes.nonotes": "There are no notes of this type yet", "addon.notes.nonotes": "There are no notes of this type yet",
"addon.notes.note": "Note", "addon.notes.note": "Note",
"addon.notes.notes": "Notes", "addon.notes.notes": "Notes",