Skip to content

Commit

Permalink
Prototyping potential Digital Reader Library layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidMockler committed Jul 26, 2024
1 parent d5ea441 commit 0e152ae
Show file tree
Hide file tree
Showing 15 changed files with 653 additions and 25 deletions.
8 changes: 4 additions & 4 deletions api/src/endpoint/drStory/ownerId.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Story = require('../../models/story');
const DigitalReaderStory = require('../../models/drStory');
const User = require('../../models/user');
const mongoose = require('mongoose');
const {API404Error} = require('../../utils/APIError');
Expand All @@ -10,12 +10,12 @@ const handler = async (req, res) => {
throw new API404Error(`User with id ${req.params.id} not found.`);
}

const stories = await Story.find({'owner': req.params.id}).sort({$natural:-1});
const digitalReaderStories = await DigitalReaderStory.find({'owner': req.params.id}).sort({$natural:-1});

if (!stories) {
if (!digitalReaderStories) {
throw new API404Error(`No stories written by user with id ${req.params.id} were found.`);
}
return res.status(200).json(stories);
return res.status(200).json(digitalReaderStories);
};

export = handler;
21 changes: 21 additions & 0 deletions api/src/endpoint/drStory/public.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const DigitalReaderStory = require('../../models/drStory');
//const User = require('../../models/user');
const mongoose = require('mongoose');
const {API404Error} = require('../../utils/APIError');

// get stories by owner (user) ID
const handler = async (req, res) => {
/*const user = await User.findOne({'_id': req.params.id});
if (!user) {
throw new API404Error(`User with id ${req.params.id} not found.`);
}*/

const digitalReaderStories = await DigitalReaderStory.find({'public': 'true'}).sort({$natural:-1});

if (!digitalReaderStories) {
throw new API404Error(`No publicly available Digital Reader stories were found.`);
}
return res.status(200).json(digitalReaderStories);
};

export = handler;
47 changes: 47 additions & 0 deletions api/src/endpoint/drStory/verified.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const DigitalReaderStory = require('../../models/drStory');
//const User = require('../../models/user');
const mongoose = require('mongoose');
const {API404Error} = require('../../utils/APIError');

// get stories by owner (user) ID
const handler = async (req, res) => {
/*const user = await User.findOne({'_id': req.params.id});
if (!user) {
throw new API404Error(`User with id ${req.params.id} not found.`);
}*/

//const digitalReaderStories = await DigitalReaderStory.find({'public': 'true'}).sort({$natural:-1});

/*if (!digitalReaderStories) {
throw new API404Error(`No publicly available Digital Reader stories were found.`);
}*/

// Get all documents whose owners carry the ADMIN role
const digitalReaderStories = await DigitalReaderStory.aggregate([
{$lookup: {
from: 'users',
localField: 'owner',
foreignField: '_id',
as: 'ownerDocArr'
}},
{$project: {
title: 1,
ownerDoc: {$first: '$ownerDocArr'}
}},
{$project: {
title: 1,
ownerRole: '$ownerDoc.role'
}},
{$match: {
ownerRole: "ADMIN"
}}
])

if (!digitalReaderStories) {
throw new API404Error(`No An Scéalaí-verified Digital Reader stories were found.`);
}

return res.status(200).json(digitalReaderStories);
};

export = handler;
14 changes: 9 additions & 5 deletions api/src/routes/drStory.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ let storyRoutes;
(() => {
// ENDPOINT HANDLERS
// GET
/*const withId = require("../endpoint/story/withId");
//const withId = require("../endpoint/story/withId");

const ownerId = require("../endpoint/story/ownerId");
const author = require("../endpoint/story/author");
const ownerId = require("../endpoint/drStory/ownerId");
const allPublic = require("../endpoint/drStory/public");
const verified = require("../endpoint/drStory/verified");
/*const author = require("../endpoint/story/author");
const feedbackAudio = require("../endpoint/story/feedbackAudio");
const countGrammarErrors = require("../endpoint/story/countGrammarErrors");
const getStoryStats = require("../endpoint/story/getStoryStats");*/
Expand All @@ -38,10 +40,12 @@ let storyRoutes;

storyRoutes = makeEndpoints({
get: {
/*"/withId/:id": withId,
//"/withId/:id": withId,
// '/myStudentsStory/:id': myStudentsStory,
"/owner/:id": ownerId,
"/:author": author,
"/public": allPublic,
"/verified": verified,
/*"/:author": author,
"/feedbackAudio/:id": feedbackAudio,
"/countGrammarErrors/:id": countGrammarErrors,
"/getStoryStats/allDB": getStoryStats,*/
Expand Down
29 changes: 29 additions & 0 deletions ngapp/src/app/core/services/dr-story.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { TranslationService } from 'app/core/services/translation.service';
import config from 'abairconfig';
import { firstValueFrom, tap } from 'rxjs';

import { DigitalReaderStory } from 'app/core/models/drStory';

@Injectable({
providedIn: 'root'
})
Expand Down Expand Up @@ -157,6 +159,33 @@ export class DigitalReaderStoryService {
return this.http.post<{id: string}>(this.baseUrl + 'drStory/create', drStoryObj);
}

getDRStoriesByOwner(owner: string) : Observable<DigitalReaderStory[]> {
return this.http.get<DigitalReaderStory[]>(this.baseUrl + 'drStory/owner/' + owner);
}

getDRStoriesForLoggedInUser(): Observable<DigitalReaderStory[]> {
const userDetails = this.auth.getUserDetails();
if(!userDetails) {
return new Observable(subscriber=>{
subscriber.next([]);
subscriber.complete();
});
}
return this.getDRStoriesByOwner(userDetails._id);
}

// get all of the Digital Reader stories that have been signed off by An Scéalaí
// this amounts to all stories that were created by admins
// TODO: Implement
getAllAnScealaiVerifiedDRStories(): Observable<DigitalReaderStory[]> {
return this.http.get<DigitalReaderStory[]>(this.baseUrl + 'drStory/verified');
}

// get all of the publicly available Digital Reader stories
getAllPublicDRStories(): Observable<DigitalReaderStory[]> {
return this.http.get<DigitalReaderStory[]>(this.baseUrl + 'drStory/public');
}

/*
createDRStory(title: string, date: Date, dialects: Array<string>, htmlText: string, author: string) {
const drstoryObj = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,86 @@
<div class="container">
<div class="header">
<!--<div class="header">
Newly created tab!
</div>
</div>-->
<!--<div class="aboutContent">
<p style="text-align: center;">This is where the stories will be displayed/can be generated (I think)</p>
<p style="text-align: center;">List of stories in the db :</p>
<p style="text-align: center;">(will be filtered based in public/private/who created it)</p>
</div>-->
<div style="display: flex;">
<div style="width:100%">

<mat-tab-group mat-stretch-tabs="false" mat-align-tabs="center">
<mat-tab [label]="ts.l.verified_dr_stories">
<!--this section should probably be generated from the mongodb where the stories are stored, rather than hardcoded-->
<!--<br>-->
<div>
<app-dr-story-drawer
[storyList]="anScealaiVerifiedDRStories"
[title]="'[Potentially LC stories]'"
/>
</div> <br>
<div>
<app-dr-story-drawer
[storyList]="anScealaiVerifiedDRStories"
[title]="'[Aesóp]'"
/>
</div> <br>
<div>
<app-dr-story-drawer
[storyList]="anScealaiVerifiedDRStories"
[title]="'[Etc.]'"
/>
</div>
</mat-tab>
<mat-tab [label]="ts.l.public_dr_stories">
<!--<br>--><!--This break was causing a scrollbar to appear-->
<app-dr-story-drawer
[storyList]="publicDRStories"
[title]="ts.l.public_dr_stories"
/></mat-tab>
<mat-tab [label]="ts.l.my_stories" *ngIf="userDetails.role=='ADMIN' || userDetails.role=='TEACHER'">
<!--<br>-->
<app-dr-story-drawer
[storyList]="currUsersDRStories"
[title]="ts.l.my_stories"
/>
</mat-tab>
</mat-tab-group>
<!--<div style="width:100%">
<table style="margin:0 auto">
<tr style="margin:auto">
<th>Verified</th>
<th>Public</th>
<th *ngIf="userDetails.role=='ADMIN' || userDetails.role=='TEACHER'">Your stories</th>
</tr>
<tr style="margin:0 auto; vertical-align:top">
<td style="margin:0 auto">
<table style="margin:0 auto">
<th >Title</th>
<tr *ngFor="let story of anScealaiVerifiedDRStories">
<td>{{ story.title }}</td>
</tr>
</table>
</td>
<td style="margin:0 auto; vertical-align:top">
<table style="margin:0 auto">
<th >Title</th>
<tr *ngFor="let story of publicDRStories">
<td>{{ story.title }}</td>
</tr>
</table>
</td>
<td *ngIf="userDetails.role=='ADMIN' || userDetails.role=='TEACHER'" style="margin:0 auto; vertical-align:top">
<table style="margin:0 auto">
<th >Title</th>
<tr *ngFor="let story of currUsersDRStories">
<td>{{ story.title }}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>-->
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,9 @@ input[type="file"] {
display: none;
}

/*.file-upload {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
}*/
app-dr-story-drawer {
margin: 0 auto;
}

.footerLARA {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { TranslationService } from 'app/core/services/translation.service';
import { AuthenticationService } from 'app/core/services/authentication.service';
import { AuthenticationService, UserDetails } from 'app/core/services/authentication.service';

import { firstValueFrom } from "rxjs";
import { User } from "app/core/models/user";
Expand All @@ -26,19 +26,31 @@ import { objectUtil } from 'zod';
})
export class DigitalReaderLibraryComponent implements OnInit {

@Output() isFirstDrStory = new EventEmitter<boolean>();
public anScealaiVerifiedDRStories:DigitalReaderStory[] = []
public publicDRStories:DigitalReaderStory[] = []
public currUsersDRStories:DigitalReaderStory[] = []

public userDetails:any;

constructor(
public ts : TranslationService,
public auth: AuthenticationService,
public userService: UserService,
public drStoryService: DigitalReaderStoryService,
public http: HttpClient,
private dialog: MatDialog) {}
public http: HttpClient) {}

async ngOnInit() {

this.userDetails = this.auth.getUserDetails()

this.anScealaiVerifiedDRStories = await firstValueFrom(this.drStoryService.getAllAnScealaiVerifiedDRStories())
console.log(this.anScealaiVerifiedDRStories)

this.publicDRStories = await firstValueFrom(this.drStoryService.getAllPublicDRStories())
console.log(this.publicDRStories)

this.currUsersDRStories = await firstValueFrom(this.drStoryService.getDRStoriesForLoggedInUser())
console.log(this.currUsersDRStories)

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<div class="body">
<div *ngIf="storyList.length > 0">
<div class="myStories">{{ title }}</div>
<!-- search bar -->
<div class="form-group">
<input
type="text"
class="form-control searchBox"
id="search-text"
aria-describedby="search-text"
[(ngModel)]="searchText"
placeholder="{{ ts.l.search_story_title_or_content }}"
/>
</div>
</div>
<!-- list of stories -->
<div class="storyList">
<div *ngFor="let story of storyList | appFilter : searchText; let i = index" (click)="openStory(story)" style="display: flex;">
<!-- story entry-->
<div class="contentSection" [attr.id]="story._id">
<!-- date and menu icon-->
<div class="contentsDate">
{{ story.updatedAt | date : "d/M/yy" }}

<button mat-icon-button [matMenuTriggerFor]="menu" aria-label="Options to delete or rename your story" >
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item >
<mat-icon>delete</mat-icon>
<span>{{ ts.l.delete }}</span>
</button>
<button mat-menu-item >
<mat-icon>create</mat-icon>
<span>{{ ts.l.rename }}</span>
</button>
</mat-menu>
</div>
<!-- title container-->
<div class="titleContainer">
<div class="contentsTitle" [attr.id]="i" (blur)="saveStoryTitle(i, story)" (keydown.enter)="saveStoryTitle(i, story)" >
{{ story?.title }}
</div>
</div>

</div>
<mat-divider [vertical]="true" [inline]="true" style="height:85%;"></mat-divider>
</div>
</div>
<!--<button mat-fab class="newStoryButton" (click)="createNewStory()">
<mat-icon>add</mat-icon>
</button>-->
</div>
Loading

0 comments on commit 0e152ae

Please sign in to comment.