diff --git a/app/db/src/app/app-routing.module.ts b/app/db/src/app/app-routing.module.ts
index 28d5ad29..baded72a 100644
--- a/app/db/src/app/app-routing.module.ts
+++ b/app/db/src/app/app-routing.module.ts
@@ -1,6 +1,7 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { SearchPage } from './pages/search/search.page';
+import { SavedPagesAdminPage } from './pages/saved-pages-admin/saved-pages-admin.page';
const routes: Routes = [
{
@@ -19,10 +20,15 @@ const routes: Routes = [
component: SearchPage,
},
{
- path: 'saved/:id',
+ path: 'page/:id',
pathMatch: 'prefix',
component: SearchPage,
},
+ {
+ path: 'saved/admin',
+ pathMatch: 'prefix',
+ component: SavedPagesAdminPage,
+ },
];
@NgModule({
diff --git a/app/db/src/app/app.component.html b/app/db/src/app/app.component.html
index 140cccb1..30dfe6f5 100644
--- a/app/db/src/app/app.component.html
+++ b/app/db/src/app/app.component.html
@@ -23,7 +23,7 @@
library_books
{{ p.title }}
diff --git a/app/db/src/app/app.component.ts b/app/db/src/app/app.component.ts
index b64e3713..19e51ce8 100644
--- a/app/db/src/app/app.component.ts
+++ b/app/db/src/app/app.component.ts
@@ -15,7 +15,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
styleUrls: ['./app.component.scss'],
})
export class AppComponent extends SubscriberBase implements AfterViewInit {
- savedPages$ = this.appService.select((state) => state.savedPages.value);
+ savedPages$ = this.appService.select((state) => (state.savedPages === null ? null : state.savedPages.value));
mainPages$ = this.appService.select((state) => state.mainPages);
fontSize$ = this.appService.select((state) => state.displaySettings.value.cardFontSize + 'pt');
cardFont$ = this.appService.select((state) => state.displaySettings.value.cardFontFamily);
diff --git a/app/db/src/app/app.module.ts b/app/db/src/app/app.module.ts
index f15ef106..e86017f6 100644
--- a/app/db/src/app/app.module.ts
+++ b/app/db/src/app/app.module.ts
@@ -51,6 +51,9 @@ import { ClipboardModule } from '@angular/cdk/clipboard';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
+import { SavedPagesAdminPage } from './pages/saved-pages-admin/saved-pages-admin.page';
+import { SavedPageCardComponent } from './components/saved-page-card/saved-page-card.component';
+
import { SearchPage } from './pages/search/search.page';
import { OkCancelModalComponent } from './components/ok-cancel-modal/ok-cancel-modal.component';
@@ -70,6 +73,8 @@ import { AddToPageModalComponent } from './components/add-to-page-modal/add-to-p
@NgModule({
declarations: [
AppComponent,
+ SavedPagesAdminPage,
+ SavedPageCardComponent,
SearchPage,
PassageCardComponent,
StrongsComponent,
diff --git a/app/db/src/app/components/saved-page-card/saved-page-card.component.html b/app/db/src/app/components/saved-page-card/saved-page-card.component.html
new file mode 100644
index 00000000..690e2c26
--- /dev/null
+++ b/app/db/src/app/components/saved-page-card/saved-page-card.component.html
@@ -0,0 +1,34 @@
+
+ {{
+ icon$ | async
+ }}
+ Page: {{ savedPage.title }}
+
+
+
+
+ {{ format(q) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/db/src/app/components/saved-page-card/saved-page-card.component.scss b/app/db/src/app/components/saved-page-card/saved-page-card.component.scss
new file mode 100644
index 00000000..7c1e8669
--- /dev/null
+++ b/app/db/src/app/components/saved-page-card/saved-page-card.component.scss
@@ -0,0 +1,15 @@
+.pages-title {
+ background-color: var(--page-color-primary);
+}
+
+.card-actions {
+ color: var(--page-color-primary);
+}
+
+.card-content {
+ overflow-y: auto;
+ max-height: 25rem;
+ font-family: var(--card-font-family);
+ font-size: var(--card-font-size);
+ padding: 0.5rem;
+}
diff --git a/app/db/src/app/components/saved-page-card/saved-page-card.component.ts b/app/db/src/app/components/saved-page-card/saved-page-card.component.ts
new file mode 100644
index 00000000..b889141c
--- /dev/null
+++ b/app/db/src/app/components/saved-page-card/saved-page-card.component.ts
@@ -0,0 +1,85 @@
+import { Component, ElementRef, ChangeDetectionStrategy, Input, OnInit } from '@angular/core';
+import { MatDialog } from '@angular/material/dialog';
+import { AppService } from '../../services/app.service';
+import { Observable } from 'rxjs';
+import { SavedPage } from 'src/app/models/page-state';
+import { CardItem, CardType } from 'src/app/models/card-state';
+import { NoteItem } from 'src/app/models/note-state';
+import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
+import { MatSnackBar } from '@angular/material/snack-bar';
+
+@Component({
+ selector: 'app-saved-page-card',
+ templateUrl: 'saved-page-card.component.html',
+ styleUrls: ['./saved-page-card.component.scss'],
+ preserveWhitespaces: true,
+})
+export class SavedPageCardComponent implements OnInit {
+ icon$: Observable;
+
+ @Input()
+ savedPage: SavedPage;
+
+ constructor(protected appService: AppService, public dialog: MatDialog, private snackBar: MatSnackBar) {
+ this.icon$ = appService.select((state) => state.cardIcons.savedPage);
+ }
+
+ format(item: CardItem) {
+ if (item.type === CardType.Note) {
+ return `Note: ${(item.data as NoteItem).title}`;
+ } else if (item.type === CardType.Passage) {
+ return `Passage: ${item.qry}`;
+ } else if (item.type === CardType.Strongs) {
+ return `Strongs: ${item.qry}`;
+ } else if (item.type === CardType.Word) {
+ return `Word Search: ${item.qry}`;
+ }
+ return '';
+ }
+
+ onRemoveCard(card: CardItem) {
+ this.dialog
+ .open(OkCancelModalComponent, {
+ data: {
+ title: 'Delete Card from Saved Page',
+ content: `Do you want to delete this card '${this.format(card)}' from the saved page '${
+ this.savedPage.title
+ }?`,
+ },
+ })
+ .afterClosed()
+ .subscribe((ds: OkCancelResult) => {
+ if (ds.ok) {
+ this.appService.updateSavedPage({
+ ...this.savedPage,
+ queries: this.savedPage.queries.filter((o) => o !== card),
+ });
+ this.snackBar.open(`${this.savedPage.title} has been updated!`, '', {
+ duration: 3 * 1000,
+ });
+ }
+ });
+ }
+
+ onRemovePage() {
+ this.dialog
+ .open(OkCancelModalComponent, {
+ data: {
+ title: 'Delete Saved Page',
+ content: `Do you want to delete the saved page '${this.savedPage.title}?`,
+ },
+ })
+ .afterClosed()
+ .subscribe((ds: OkCancelResult) => {
+ if (ds.ok) {
+ this.appService.removeSavedPage(this.savedPage);
+ this.snackBar.open(`${this.savedPage.title} has been deleted!`, '', {
+ duration: 3 * 1000,
+ });
+ }
+ });
+ }
+ ngOnInit(): void {
+ console.log(this.savedPage);
+ }
+}
diff --git a/app/db/src/app/components/words/words-card.component.scss b/app/db/src/app/components/words/words-card.component.scss
index 7f4eba8b..33bfe2df 100644
--- a/app/db/src/app/components/words/words-card.component.scss
+++ b/app/db/src/app/components/words/words-card.component.scss
@@ -13,7 +13,7 @@
.card-content {
overflow-y: auto;
max-height: 25rem;
- font-family: var(--card-font);
+ font-family: var(--card-font-family);
font-size: var(--card-font-size);
padding: 0.5rem;
}
diff --git a/app/db/src/app/constants.ts b/app/db/src/app/constants.ts
index 01ef32b8..03e77081 100644
--- a/app/db/src/app/constants.ts
+++ b/app/db/src/app/constants.ts
@@ -1,10 +1,12 @@
export const PageTitles = {
Search: 'Search',
+ PageAdmin: 'Page Admin',
Help: 'Help',
};
export const PageIcons = {
Search: 'search',
+ PageAdmin: 'library_books',
Help: 'help',
};
diff --git a/app/db/src/app/models/card-state.ts b/app/db/src/app/models/card-state.ts
index e7052220..d47a9f96 100644
--- a/app/db/src/app/models/card-state.ts
+++ b/app/db/src/app/models/card-state.ts
@@ -24,4 +24,5 @@ export interface CardIcons {
readonly passage: string;
readonly strongs: string;
readonly note: string;
+ readonly savedPage: string;
}
diff --git a/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.html b/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.html
new file mode 100644
index 00000000..236e957f
--- /dev/null
+++ b/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.html
@@ -0,0 +1,16 @@
+
+
+ Saved Pages Admin
+
+
diff --git a/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.scss b/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.scss
new file mode 100644
index 00000000..e161d074
--- /dev/null
+++ b/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.scss
@@ -0,0 +1,20 @@
+mat-card {
+ max-width: 800px;
+ margin: 1.5rem auto;
+ padding: 0;
+}
+
+.page-title {
+ width: 100%;
+ position: relative;
+ margin-left: 0.8rem;
+ margin-right: 0.8rem;
+}
+
+.page-content {
+ padding: 0 1rem 0 1rem;
+ overflow-y: scroll;
+ height: calc(100vh - 66px);
+ width: calc(100% - 15px);
+ margin-top: 2px;
+}
diff --git a/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.ts b/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.ts
new file mode 100644
index 00000000..c3d9f24e
--- /dev/null
+++ b/app/db/src/app/pages/saved-pages-admin/saved-pages-admin.page.ts
@@ -0,0 +1,20 @@
+import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
+import { MatDialog } from '@angular/material/dialog';
+import { AppService } from '../../services/app.service';
+import { NavService } from '../../services/nav.service';
+import { SubscriberBase } from '../../common/subscriber-base';
+
+@Component({
+ selector: 'app-saved-pages-admin',
+ templateUrl: './saved-pages-admin.page.html',
+ styleUrls: ['./saved-pages-admin.page.scss'],
+})
+export class SavedPagesAdminPage extends SubscriberBase implements OnInit {
+ savedPages$ = this.appService.select((state) => (state.savedPages === null ? null : state.savedPages.value));
+
+ constructor(public navService: NavService, private appService: AppService, private dialog: MatDialog) {
+ super();
+ }
+
+ ngOnInit() {}
+}
diff --git a/app/db/src/app/pages/search/search.page.ts b/app/db/src/app/pages/search/search.page.ts
index 9603a630..fb6176a3 100644
--- a/app/db/src/app/pages/search/search.page.ts
+++ b/app/db/src/app/pages/search/search.page.ts
@@ -54,7 +54,6 @@ export class SearchPage extends SubscriberBase implements OnInit {
if (evt instanceof NavigationEnd) {
this.init();
}
- console.log(evt);
})
);
@@ -75,8 +74,6 @@ export class SearchPage extends SubscriberBase implements OnInit {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.onSavedPagedLoaded(id);
this.navService.closeNav(); // close the nav immediately.
- } else {
- // its a blank search. load nothing.
}
}
diff --git a/app/db/src/app/services/app-state-actions.ts b/app/db/src/app/services/app-state-actions.ts
index 9fc9a207..c53297f3 100644
--- a/app/db/src/app/services/app-state-actions.ts
+++ b/app/db/src/app/services/app-state-actions.ts
@@ -33,6 +33,20 @@ export class AppActionFactory {
} as AppAction;
}
+ static newUpdateSavedPage(savedPage: SavedPage) {
+ return {
+ type: 'UPDATE_SAVED_PAGE',
+ savedPage,
+ } as AppAction;
+ }
+
+ static newRemoveSavedPage(savedPage: SavedPage) {
+ return {
+ type: 'REMOVE_SAVED_PAGE',
+ savedPage,
+ } as AppAction;
+ }
+
static newAddCardToSavedPage(card: CardItem, pageId: string) {
return {
type: 'ADD_CARD_TO_SAVED_PAGE',
@@ -167,6 +181,14 @@ export type AppAction =
type: 'UPDATE_SAVED_PAGES';
savedPages: IStorable;
}
+ | {
+ type: 'UPDATE_SAVED_PAGE';
+ savedPage: SavedPage;
+ }
+ | {
+ type: 'REMOVE_SAVED_PAGE';
+ savedPage: SavedPage;
+ }
| {
type: 'ADD_CARD_TO_SAVED_PAGE';
card: CardItem;
diff --git a/app/db/src/app/services/app-state-initial-state.ts b/app/db/src/app/services/app-state-initial-state.ts
index e019c3f1..e6686514 100644
--- a/app/db/src/app/services/app-state-initial-state.ts
+++ b/app/db/src/app/services/app-state-initial-state.ts
@@ -22,17 +22,12 @@ export const initialState: AppState = {
],
autocomplete: [],
currentSavedPage: null,
- savedPages: {
- createdOn: new Date(0).toISOString(),
- value: [],
- },
- notes: {
- createdOn: new Date(0).toISOString(),
- value: [],
- },
+ savedPages: null,
+ notes: null,
savedPagesLoaded: false,
mainPages: [
{ title: PageTitles.Search, icon: PageIcons.Search, route: 'search' },
+ { title: PageTitles.PageAdmin, icon: PageIcons.PageAdmin, route: 'saved/admin' },
{ title: PageTitles.Help, icon: PageIcons.Help, route: 'help' },
],
error: null,
@@ -63,5 +58,6 @@ export const initialState: AppState = {
passage: 'menu_book',
strongs: 'speaker_notes',
note: 'text_snippet',
+ savedPage: 'library_books',
},
};
diff --git a/app/db/src/app/services/app-state-reducer.ts b/app/db/src/app/services/app-state-reducer.ts
index 11ab7c23..e767a558 100644
--- a/app/db/src/app/services/app-state-reducer.ts
+++ b/app/db/src/app/services/app-state-reducer.ts
@@ -17,8 +17,18 @@ function maybeMutateStorable(
incumbant: IStorable,
composeState: (item: IStorable) => AppState
): AppState {
+ // if the candidate is null, then return the state.
+ if (!candidate) {
+ return state;
+ }
+
+ // if the incumbant is null, then def use the candidate.
+ if (!incumbant) {
+ return composeState(candidate);
+ }
+
// only update if the settings are newer.
- if (new Date(candidate.createdOn) > new Date(incumbant.createdOn)) {
+ if (!incumbant || new Date(candidate.createdOn) > new Date(incumbant.createdOn)) {
return composeState(candidate);
}
@@ -83,6 +93,36 @@ export function reducer(state: AppState, action: AppAction): AppState {
};
});
}
+ case 'UPDATE_SAVED_PAGE': {
+ const savedPages = new Storable(
+ state.savedPages.value.map((o) => {
+ if (o.id === action.savedPage.id) {
+ return action.savedPage;
+ }
+ return o;
+ })
+ );
+
+ return maybeMutateStorable(state, savedPages, state.savedPages, (item) => {
+ return {
+ ...state,
+ savedPagesLoaded: true,
+ savedPages: item,
+ };
+ });
+ }
+
+ case 'REMOVE_SAVED_PAGE': {
+ const savedPages = new Storable(state.savedPages.value.filter((o) => o.id !== action.savedPage.id));
+
+ return maybeMutateStorable(state, savedPages, state.savedPages, (item) => {
+ return {
+ ...state,
+ savedPagesLoaded: true,
+ savedPages: item,
+ };
+ });
+ }
case 'UPDATE_CURRENT_PAGE': {
const savedPages = new Storable([
...state.savedPages.value.filter((o) => o.id !== state.currentSavedPage.id),
diff --git a/app/db/src/app/services/app.service.ts b/app/db/src/app/services/app.service.ts
index ff12c42f..408dc2e6 100644
--- a/app/db/src/app/services/app.service.ts
+++ b/app/db/src/app/services/app.service.ts
@@ -111,6 +111,19 @@ export class AppService extends createStateService(reducer, initialState) {
});
}
+ updateSavedPage(savedPage: SavedPage) {
+ this.dispatch({
+ type: 'UPDATE_SAVED_PAGE',
+ savedPage,
+ });
+ }
+ removeSavedPage(savedPage: SavedPage) {
+ this.dispatch({
+ type: 'REMOVE_SAVED_PAGE',
+ savedPage,
+ });
+ }
+
addCardToSavedPage(pageId: string, card: CardItem) {
this.dispatch({
type: 'ADD_CARD_TO_SAVED_PAGE',
diff --git a/app/db/src/app/services/storage.service.ts b/app/db/src/app/services/storage.service.ts
index 2af844d1..2f0dcef6 100644
--- a/app/db/src/app/services/storage.service.ts
+++ b/app/db/src/app/services/storage.service.ts
@@ -18,7 +18,7 @@ export class StorageService extends SubscriberBase {
private displaySettingsRemoteObject: AngularFireObject>;
private savedPagesState$ = this.appService.select((state) => state.savedPages);
- private savedPagesPath = 'savedPaged';
+ private savedPagesPath = 'savedPages';
private savedPagesRemoteObject: AngularFireObject>;
private noteItemsState$ = this.appService.select((state) => state.notes);
@@ -34,7 +34,7 @@ export class StorageService extends SubscriberBase {
this.addSubscription(
this.displaySettingsState$.subscribe((settings) => {
- if (!settings) {
+ if (!settings || settings.createdOn === new Date(0).toISOString()) {
return;
}
diff --git a/app/db/src/styles/app.scss b/app/db/src/styles/app.scss
index c0371ea6..f9133f58 100644
--- a/app/db/src/styles/app.scss
+++ b/app/db/src/styles/app.scss
@@ -21,6 +21,9 @@ html {
--note-color-primary: rgb(71, 1, 54);
--note-color-accent: rgb(165, 86, 145);
+
+ --page-color-primary: rgb(46, 42, 54);
+ --page-color-accent: rgb(111, 109, 116);
}
body {