diff --git a/scripts/langindex.json b/scripts/langindex.json
index 4d1fdd0b8..cfc5ef1f8 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -697,6 +697,7 @@
"addon.mod_glossary.definition": "glossary",
"addon.mod_glossary.deleteentry": "glossary",
"addon.mod_glossary.entriestobesynced": "local_moodlemobileapp",
+ "addon.mod_glossary.entry": "glossary",
"addon.mod_glossary.entrydeleted": "glossary",
"addon.mod_glossary.entrypendingapproval": "local_moodlemobileapp",
"addon.mod_glossary.entryusedynalink": "glossary",
diff --git a/src/addons/mod/glossary/classes/glossary-entries-source.ts b/src/addons/mod/glossary/classes/glossary-entries-source.ts
index 057856e55..cd45af84c 100644
--- a/src/addons/mod/glossary/classes/glossary-entries-source.ts
+++ b/src/addons/mod/glossary/classes/glossary-entries-source.ts
@@ -29,8 +29,6 @@ import { AddonModGlossaryOffline, AddonModGlossaryOfflineEntry } from '../servic
*/
export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource {
- static readonly NEW_ENTRY: AddonModGlossaryNewEntryForm = { newEntry: true };
-
readonly COURSE_ID: number;
readonly CM_ID: number;
readonly GLOSSARY_PATH_PREFIX: string;
@@ -54,16 +52,6 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource<
this.GLOSSARY_PATH_PREFIX = glossaryPathPrefix;
}
- /**
- * Type guard to infer NewEntryForm objects.
- *
- * @param entry Item to check.
- * @returns Whether the item is a new entry form.
- */
- isNewEntryForm(entry: AddonModGlossaryEntryItem): entry is AddonModGlossaryNewEntryForm {
- return 'newEntry' in entry;
- }
-
/**
* Type guard to infer entry objects.
*
@@ -81,22 +69,18 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource<
* @returns Whether the item is an offline entry.
*/
isOfflineEntry(entry: AddonModGlossaryEntryItem): entry is AddonModGlossaryOfflineEntry {
- return !this.isNewEntryForm(entry) && !this.isOnlineEntry(entry);
+ return !this.isOnlineEntry(entry);
}
/**
* @inheritdoc
*/
getItemPath(entry: AddonModGlossaryEntryItem): string {
- if (this.isOnlineEntry(entry)) {
- return `${this.GLOSSARY_PATH_PREFIX}entry/${entry.id}`;
- }
-
if (this.isOfflineEntry(entry)) {
- return `${this.GLOSSARY_PATH_PREFIX}edit/${entry.timecreated}`;
+ return `${this.GLOSSARY_PATH_PREFIX}entry/new-${entry.timecreated}`;
}
- return `${this.GLOSSARY_PATH_PREFIX}edit/0`;
+ return `${this.GLOSSARY_PATH_PREFIX}entry/${entry.id}`;
}
/**
@@ -263,7 +247,6 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource<
offlineEntries.sort((a, b) => a.concept.localeCompare(b.concept));
- entries.push(AddonModGlossaryEntriesSource.NEW_ENTRY);
entries.push(...offlineEntries);
}
@@ -315,12 +298,7 @@ export class AddonModGlossaryEntriesSource extends CoreRoutedItemsManagerSource<
/**
* Type of items that can be held by the entries manager.
*/
-export type AddonModGlossaryEntryItem = AddonModGlossaryEntry | AddonModGlossaryOfflineEntry | AddonModGlossaryNewEntryForm;
-
-/**
- * Type to select the new entry form.
- */
-export type AddonModGlossaryNewEntryForm = { newEntry: true };
+export type AddonModGlossaryEntryItem = AddonModGlossaryEntry | AddonModGlossaryOfflineEntry;
/**
* Fetch mode to sort entries.
diff --git a/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts b/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts
deleted file mode 100644
index b1136068b..000000000
--- a/src/addons/mod/glossary/classes/glossary-entries-swipe-manager.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-// (C) Copyright 2015 Moodle Pty Ltd.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
-import { AddonModGlossaryEntriesSource, AddonModGlossaryEntryItem } from './glossary-entries-source';
-
-/**
- * Helper to manage swiping within a collection of glossary entries.
- */
-export abstract class AddonModGlossaryEntriesSwipeManager
- extends CoreSwipeNavigationItemsManager {
-
- /**
- * @inheritdoc
- */
- protected skipItemInSwipe(item: AddonModGlossaryEntryItem): boolean {
- return this.getSource().isNewEntryForm(item);
- }
-
-}
diff --git a/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html b/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html
index 2413ed563..1198552e1 100644
--- a/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html
+++ b/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html
@@ -31,7 +31,7 @@
[componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline" (completionChanged)="onCompletionChange()">
- 0">
+ 0" class="addon-mod-glossary-index--offline-entries">
{{ 'addon.mod_glossary.entriestobesynced' | translate }}
@@ -40,9 +40,12 @@
-
-
+
+
+
+
+
diff --git a/src/addons/mod/glossary/components/index/index.scss b/src/addons/mod/glossary/components/index/index.scss
new file mode 100644
index 000000000..96c31cca1
--- /dev/null
+++ b/src/addons/mod/glossary/components/index/index.scss
@@ -0,0 +1,13 @@
+:host {
+
+ .addon-mod-glossary-index--offline-entries {
+ border-bottom: 1px solid var(--stroke);
+ }
+
+ .addon-mod-glossary-index--offline-entry {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ }
+
+}
diff --git a/src/addons/mod/glossary/components/index/index.ts b/src/addons/mod/glossary/components/index/index.ts
index b7a797451..904f91028 100644
--- a/src/addons/mod/glossary/components/index/index.ts
+++ b/src/addons/mod/glossary/components/index/index.ts
@@ -26,6 +26,7 @@ import { CoreRatingProvider } from '@features/rating/services/rating';
import { CoreRatingOffline } from '@features/rating/services/rating-offline';
import { CoreRatingSyncProvider } from '@features/rating/services/rating-sync';
import { IonContent } from '@ionic/angular';
+import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
@@ -61,6 +62,7 @@ import { AddonModGlossaryModePickerPopoverComponent } from '../mode-picker/mode-
@Component({
selector: 'addon-mod-glossary-index',
templateUrl: 'addon-mod-glossary-index.html',
+ styleUrls: ['index.scss'],
})
export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivityComponent
implements OnInit, AfterViewInit, OnDestroy {
@@ -399,7 +401,11 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
* Opens new entry editor.
*/
openNewEntry(): void {
- this.entries?.select(AddonModGlossaryEntriesSource.NEW_ENTRY);
+ CoreNavigator.navigate(
+ this.splitView.outletActivated
+ ? '../new'
+ : './entry/new',
+ );
}
/**
diff --git a/src/addons/mod/glossary/glossary-lazy.module.ts b/src/addons/mod/glossary/glossary-lazy.module.ts
index c96ce6e7d..8f12bc001 100644
--- a/src/addons/mod/glossary/glossary-lazy.module.ts
+++ b/src/addons/mod/glossary/glossary-lazy.module.ts
@@ -27,13 +27,9 @@ const mobileRoutes: Routes = [
component: AddonModGlossaryIndexPage,
},
{
- path: ':courseId/:cmId/entry/:entryId',
+ path: ':courseId/:cmId/entry/:entrySlug',
loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
},
- {
- path: ':courseId/:cmId/edit/:timecreated',
- loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
- },
];
const tabletRoutes: Routes = [
@@ -42,18 +38,18 @@ const tabletRoutes: Routes = [
component: AddonModGlossaryIndexPage,
children: [
{
- path: 'entry/:entryId',
+ path: 'entry/:entrySlug',
loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
},
- {
- path: 'edit/:timecreated',
- loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
- },
],
},
];
const routes: Routes = [
+ {
+ path: ':courseId/:cmId/entry/new',
+ loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
+ },
...conditionalRoutes(mobileRoutes, () => CoreScreen.isMobile),
...conditionalRoutes(tabletRoutes, () => CoreScreen.isTablet),
];
diff --git a/src/addons/mod/glossary/glossary.module.ts b/src/addons/mod/glossary/glossary.module.ts
index 82def7f99..3b58c3b10 100644
--- a/src/addons/mod/glossary/glossary.module.ts
+++ b/src/addons/mod/glossary/glossary.module.ts
@@ -49,50 +49,35 @@ export const ADDON_MOD_GLOSSARY_SERVICES: Type[] = [
];
const mainMenuRoutes: Routes = [
- {
- path: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/entry/:entryId`,
- loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
- data: { swipeEnabled: false },
- },
- {
- path: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/edit/:timecreated`,
- loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
- data: { swipeEnabled: false },
- },
+ // Course activity navigation.
{
path: AddonModGlossaryModuleHandlerService.PAGE_NAME,
loadChildren: () => import('./glossary-lazy.module').then(m => m.AddonModGlossaryLazyModule),
},
+
+ // Single Activity format navigation.
+ {
+ path: `${COURSE_CONTENTS_PATH}/${AddonModGlossaryModuleHandlerService.PAGE_NAME}/entry/new`,
+ loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
+ data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
+ },
...conditionalRoutes(
- [
- {
- path: `${COURSE_CONTENTS_PATH}/${AddonModGlossaryModuleHandlerService.PAGE_NAME}/entry/:entryId`,
- loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
- data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
- },
- {
- path: `${COURSE_CONTENTS_PATH}/${AddonModGlossaryModuleHandlerService.PAGE_NAME}/edit/:timecreated`,
- loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
- data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
- },
- ],
+ [{
+ path: `${COURSE_CONTENTS_PATH}/${AddonModGlossaryModuleHandlerService.PAGE_NAME}/entry/:entrySlug`,
+ loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
+ data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
+ }],
() => CoreScreen.isMobile,
),
];
+// Single Activity format navigation.
const courseContentsRoutes: Routes = conditionalRoutes(
- [
- {
- path: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/entry/:entryId`,
- loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
- data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
- },
- {
- path: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/edit/:timecreated`,
- loadChildren: () => import('./glossary-edit-lazy.module').then(m => m.AddonModGlossaryEditLazyModule),
- data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
- },
- ],
+ [{
+ path: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/entry/:entrySlug`,
+ loadChildren: () => import('./glossary-entry-lazy.module').then(m => m.AddonModGlossaryEntryLazyModule),
+ data: { glossaryPathPrefix: `${AddonModGlossaryModuleHandlerService.PAGE_NAME}/` },
+ }],
() => CoreScreen.isTablet,
);
diff --git a/src/addons/mod/glossary/lang.json b/src/addons/mod/glossary/lang.json
index 6206a6430..124f2c100 100644
--- a/src/addons/mod/glossary/lang.json
+++ b/src/addons/mod/glossary/lang.json
@@ -17,6 +17,7 @@
"definition": "Definition",
"deleteentry": "Delete entry",
"entriestobesynced": "Entries to be synced",
+ "entry": "Entry",
"entrydeleted": "Entry deleted",
"entrypendingapproval": "This entry is pending approval.",
"entryusedynalink": "This entry should be automatically linked",
diff --git a/src/addons/mod/glossary/pages/edit/edit.html b/src/addons/mod/glossary/pages/edit/edit.html
index 835718d27..eee439c4a 100644
--- a/src/addons/mod/glossary/pages/edit/edit.html
+++ b/src/addons/mod/glossary/pages/edit/edit.html
@@ -11,7 +11,7 @@
-
+
- {{ entry.timemodified | coreDateDayOrTime }}
+ {{ onlineEntry.timemodified | coreDateDayOrTime }}
@@ -53,32 +59,37 @@
-
-
+
+
- 0">
+
+
+
+
+ 0">
{{ 'core.tag.tags' | translate }}:
-
+
-
+
{{ 'addon.mod_glossary.entrypendingapproval' | translate }}
- 0 && commentsEnabled" contextLevel="module"
- [instanceId]="glossary.coursemodule" component="mod_glossary" [itemId]="entry.id" area="glossary_entry"
- [courseId]="glossary.course" [showItem]="true">
+ 0 && commentsEnabled"
+ contextLevel="module" [instanceId]="glossary.coursemodule" component="mod_glossary" [itemId]="onlineEntry.id"
+ area="glossary_entry" [courseId]="glossary.course" [showItem]="true">
-
-
+
diff --git a/src/addons/mod/glossary/pages/entry/entry.ts b/src/addons/mod/glossary/pages/entry/entry.ts
index 1db3fc59e..7c6e6076d 100644
--- a/src/addons/mod/glossary/pages/entry/entry.ts
+++ b/src/addons/mod/glossary/pages/entry/entry.ts
@@ -12,9 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { AddonModGlossaryOffline, AddonModGlossaryOfflineEntry } from '@addons/mod/glossary/services/glossary-offline';
import { Component, OnDestroy, OnInit, Optional, ViewChild } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
+import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreCommentsCommentsComponent } from '@features/comments/components/comments/comments';
import { CoreComments } from '@features/comments/services/comments';
@@ -26,8 +28,7 @@ import { CoreNetwork } from '@services/network';
import { CoreDomUtils, ToastDuration } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { Translate } from '@singletons';
-import { AddonModGlossaryEntriesSource } from '../../classes/glossary-entries-source';
-import { AddonModGlossaryEntriesSwipeManager } from '../../classes/glossary-entries-swipe-manager';
+import { AddonModGlossaryEntriesSource, AddonModGlossaryEntryItem } from '../../classes/glossary-entries-source';
import {
AddonModGlossary,
AddonModGlossaryEntry,
@@ -48,8 +49,9 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy {
component = AddonModGlossaryProvider.COMPONENT;
componentId?: number;
- entry?: AddonModGlossaryEntry;
- entries?: AddonModGlossaryEntryEntriesSwipeManager;
+ onlineEntry?: AddonModGlossaryEntry;
+ offlineEntry?: AddonModGlossaryOfflineEntry;
+ entries!: AddonModGlossaryEntryEntriesSwipeManager;
glossary?: AddonModGlossaryGlossary;
loaded = false;
showAuthor = false;
@@ -59,52 +61,67 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy {
canDelete = false;
commentsEnabled = false;
courseId!: number;
- cmId?: number;
-
- protected entryId!: number;
+ cmId!: number;
constructor(@Optional() protected splitView: CoreSplitViewComponent, protected route: ActivatedRoute) {}
+ get entry(): AddonModGlossaryEntry | AddonModGlossaryOfflineEntry | undefined {
+ return this.onlineEntry ?? this.offlineEntry;
+ }
+
/**
* @inheritdoc
*/
async ngOnInit(): Promise {
+ let onlineEntryId: number | null = null;
+ let offlineEntry: {
+ concept: string;
+ timecreated: number;
+ } | null = null;
try {
- const routeData = this.route.snapshot.data;
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
- this.entryId = CoreNavigator.getRequiredRouteNumberParam('entryId');
this.tagsEnabled = CoreTag.areTagsAvailableInSite();
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
+ this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
- if (routeData.swipeEnabled ?? true) {
- this.cmId = CoreNavigator.getRequiredRouteNumberParam('cmId');
- const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(
- AddonModGlossaryEntriesSource,
- [this.courseId, this.cmId, routeData.glossaryPathPrefix ?? ''],
- );
+ const entrySlug = CoreNavigator.getRequiredRouteParam('entrySlug');
+ const routeData = this.route.snapshot.data;
+ const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(
+ AddonModGlossaryEntriesSource,
+ [this.courseId, this.cmId, routeData.glossaryPathPrefix ?? ''],
+ );
- this.entries = new AddonModGlossaryEntryEntriesSwipeManager(source);
+ this.entries = new AddonModGlossaryEntryEntriesSwipeManager(source);
- await this.entries.start();
+ await this.entries.start();
+
+ if (entrySlug.startsWith('new-')) {
+ offlineEntry = {
+ concept : CoreNavigator.getRequiredRouteParam('concept'),
+ timecreated: Number(entrySlug.slice(4)),
+ };
} else {
- this.cmId = CoreNavigator.getRouteNumberParam('cmId');
+ onlineEntryId = Number(entrySlug);
}
} catch (error) {
CoreDomUtils.showErrorModal(error);
-
CoreNavigator.back();
return;
}
try {
- await this.fetchEntry();
+ if (onlineEntryId) {
+ await this.loadOnlineEntry(onlineEntryId);
- if (!this.glossary || !this.componentId) {
- return;
+ if (!this.glossary || !this.componentId) {
+ return;
+ }
+
+ await CoreUtils.ignoreErrors(AddonModGlossary.logEntryView(onlineEntryId, this.componentId, this.glossary?.name));
+ } else if (offlineEntry) {
+ await this.loadOfflineEntry(offlineEntry.concept, offlineEntry.timecreated);
}
-
- await CoreUtils.ignoreErrors(AddonModGlossary.logEntryView(this.entryId, this.componentId, this.glossary.name));
} finally {
this.loaded = true;
}
@@ -114,14 +131,18 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy {
* @inheritdoc
*/
ngOnDestroy(): void {
- this.entries?.destroy();
+ this.entries.destroy();
}
/**
* Delete entry.
*/
async deleteEntry(): Promise {
- const entryId = this.entry?.id;
+ if (!this.onlineEntry) {
+ return;
+ }
+
+ const entryId = this.onlineEntry.id;
const glossaryId = this.glossary?.id;
const cancelled = await CoreUtils.promiseFails(
CoreDomUtils.showConfirm(Translate.instant('addon.mod_glossary.areyousuredelete')),
@@ -141,7 +162,7 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy {
await CoreUtils.ignoreErrors(AddonModGlossary.invalidateEntriesByCategory(glossaryId));
await CoreUtils.ignoreErrors(AddonModGlossary.invalidateEntriesByDate(glossaryId, 'CREATION'));
await CoreUtils.ignoreErrors(AddonModGlossary.invalidateEntriesByDate(glossaryId, 'UPDATE'));
- await CoreUtils.ignoreErrors(this.entries?.getSource().invalidateCache(false));
+ await CoreUtils.ignoreErrors(this.entries.getSource().invalidateCache(false));
CoreDomUtils.showToast('addon.mod_glossary.entrydeleted', true, ToastDuration.LONG);
@@ -164,67 +185,100 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy {
* @returns Promise resolved when done.
*/
async doRefresh(refresher?: IonRefresher): Promise {
- if (this.glossary?.allowcomments && this.entry && this.entry.id > 0 && this.commentsEnabled && this.comments) {
- // Refresh comments. Don't add it to promises because we don't want the comments fetch to block the entry fetch.
+ if (this.onlineEntry && this.glossary?.allowcomments && this.onlineEntry.id > 0 && this.commentsEnabled && this.comments) {
+ // Refresh comments asynchronously (without blocking the current promise).
CoreUtils.ignoreErrors(this.comments.doRefresh());
}
try {
- await CoreUtils.ignoreErrors(AddonModGlossary.invalidateEntry(this.entryId));
+ if (this.onlineEntry) {
+ await CoreUtils.ignoreErrors(AddonModGlossary.invalidateEntry(this.onlineEntry.id));
+ await this.loadOnlineEntry(this.onlineEntry.id);
+ } else if (this.offlineEntry) {
+ const entrySlug = CoreNavigator.getRequiredRouteParam('entrySlug');
+ const timecreated = Number(entrySlug.slice(4));
- await this.fetchEntry();
+ await this.loadOfflineEntry(timecreated);
+ }
} finally {
refresher?.complete();
}
}
/**
- * Convenience function to get the glossary entry.
- *
- * @returns Promise resolved when done.
+ * Load online entry data.
*/
- protected async fetchEntry(): Promise {
+ protected async loadOnlineEntry(entryId: number): Promise {
try {
- const result = await AddonModGlossary.getEntry(this.entryId);
+ const result = await AddonModGlossary.getEntry(entryId);
const canDeleteEntries = CoreNetwork.isOnline() && await AddonModGlossary.canDeleteEntries();
- this.entry = result.entry;
+ this.onlineEntry = result.entry;
this.ratingInfo = result.ratinginfo;
this.canDelete = canDeleteEntries && !!result.permissions?.candelete;
- if (this.glossary) {
- // Glossary already loaded, nothing else to load.
- return;
- }
-
- // Load the glossary.
- this.glossary = await AddonModGlossary.getGlossaryById(this.courseId, this.entry.glossaryid);
- this.componentId = this.glossary.coursemodule;
-
- switch (this.glossary.displayformat) {
- case 'fullwithauthor':
- case 'encyclopedia':
- this.showAuthor = true;
- this.showDate = true;
- break;
- case 'fullwithoutauthor':
- this.showAuthor = false;
- this.showDate = true;
- break;
- default: // Default, and faq, simple, entrylist, continuous.
- this.showAuthor = false;
- this.showDate = false;
- }
+ await this.loadGlossary();
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingentry', true);
}
}
+ /**
+ * Load offline entry data.
+ *
+ * @param concept Entry concept.
+ * @param timecreated Entry Timecreated.
+ */
+ protected async loadOfflineEntry(concept: string, timecreated: number): Promise {
+ try {
+ const glossary = await this.loadGlossary();
+
+ this.offlineEntry = await AddonModGlossaryOffline.getOfflineEntry(glossary.id, concept, timecreated);
+ } catch (error) {
+ CoreDomUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingentry', true);
+ }
+ }
+
+ /**
+ * Load glossary data.
+ *
+ * @returns Glossary.
+ */
+ protected async loadGlossary(): Promise {
+ if (this.glossary) {
+ return this.glossary;
+ }
+
+ this.glossary = await AddonModGlossary.getGlossary(this.courseId, this.cmId);
+ this.componentId = this.glossary.coursemodule;
+
+ switch (this.glossary.displayformat) {
+ case 'fullwithauthor':
+ case 'encyclopedia':
+ this.showAuthor = true;
+ this.showDate = true;
+ break;
+ case 'fullwithoutauthor':
+ this.showAuthor = false;
+ this.showDate = true;
+ break;
+ default: // Default, and faq, simple, entrylist, continuous.
+ this.showAuthor = false;
+ this.showDate = false;
+ }
+
+ return this.glossary;
+ }
+
/**
* Function called when rating is updated online.
*/
ratingUpdated(): void {
- AddonModGlossary.invalidateEntry(this.entryId);
+ if (!this.onlineEntry) {
+ return;
+ }
+
+ AddonModGlossary.invalidateEntry(this.onlineEntry.id);
}
}
@@ -232,13 +286,14 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy {
/**
* Helper to manage swiping within a collection of glossary entries.
*/
-class AddonModGlossaryEntryEntriesSwipeManager extends AddonModGlossaryEntriesSwipeManager {
+class AddonModGlossaryEntryEntriesSwipeManager
+ extends CoreSwipeNavigationItemsManager {
/**
* @inheritdoc
*/
protected getSelectedItemPathFromRoute(route: ActivatedRouteSnapshot): string | null {
- return `${this.getSource().GLOSSARY_PATH_PREFIX}entry/${route.params.entryId}`;
+ return `${this.getSource().GLOSSARY_PATH_PREFIX}entry/${route.params.entrySlug}`;
}
}
diff --git a/src/addons/mod/glossary/services/handlers/edit-link.ts b/src/addons/mod/glossary/services/handlers/edit-link.ts
index 8859a6d72..541a975ed 100644
--- a/src/addons/mod/glossary/services/handlers/edit-link.ts
+++ b/src/addons/mod/glossary/services/handlers/edit-link.ts
@@ -51,14 +51,8 @@ export class AddonModGlossaryEditLinkHandlerService extends CoreContentLinksHand
);
await CoreNavigator.navigateToSitePath(
- AddonModGlossaryModuleHandlerService.PAGE_NAME + '/edit/0',
- {
- params: {
- courseId: module.course,
- cmId: module.id,
- },
- siteId,
- },
+ AddonModGlossaryModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/entry/new`,
+ { siteId },
);
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingglossary', true);
diff --git a/src/addons/mod/glossary/services/handlers/entry-link.ts b/src/addons/mod/glossary/services/handlers/entry-link.ts
index d58a0bac3..2402b7f53 100644
--- a/src/addons/mod/glossary/services/handlers/entry-link.ts
+++ b/src/addons/mod/glossary/services/handlers/entry-link.ts
@@ -56,14 +56,8 @@ export class AddonModGlossaryEntryLinkHandlerService extends CoreContentLinksHan
);
await CoreNavigator.navigateToSitePath(
- AddonModGlossaryModuleHandlerService.PAGE_NAME + `/entry/${entryId}`,
- {
- params: {
- courseId: module.course,
- cmId: module.id,
- },
- siteId,
- },
+ AddonModGlossaryModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/entry/${entryId}`,
+ { siteId },
);
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingentry', true);
diff --git a/src/addons/mod/glossary/tests/behat/navigation.feature b/src/addons/mod/glossary/tests/behat/navigation.feature
index 659d286ff..d245ac8da 100644
--- a/src/addons/mod/glossary/tests/behat/navigation.feature
+++ b/src/addons/mod/glossary/tests/behat/navigation.feature
@@ -280,6 +280,7 @@ Feature: Test glossary navigation
| Concept | Tomato |
| Definition | Tomato is a fruit |
And I press "Save" in the app
+ And I press "Add a new entry" in the app
And I set the following fields to these values in the app:
| Concept | Cashew |
| Definition | Cashew is a fruit |