From 3bea9fb0a0ce8940efa884363e6b8feb4443d4ae Mon Sep 17 00:00:00 2001 From: kylebuss Date: Tue, 10 Dec 2024 08:53:28 -0600 Subject: [PATCH] Help video page --- .../ClientApp/src/app/app-routing.module.ts | 2 + .../ClientApp/src/app/app.component.html | 1 + .../src/app/core/models/help-video.ts | 8 +++ .../help-videos/help-videos.component.html | 27 +++++++ .../help-videos/help-videos.component.scss | 12 ++++ .../help-videos/help-videos.component.spec.ts | 22 ++++++ .../help-videos/help-videos.component.ts | 25 +++++++ .../sa-help-videos-dialog.component.html | 23 ++++++ .../sa-help-videos-dialog.component.scss | 0 .../sa-help-videos-dialog.component.spec.ts | 22 ++++++ .../sa-help-videos-dialog.component.ts | 10 +++ .../sa-help-videos.component.html | 54 ++++++++++++++ .../sa-help-videos.component.scss | 47 +++++++++++++ .../sa-help-videos.component.spec.ts | 22 ++++++ .../sa-help-videos.component.ts | 25 +++++++ .../system-administration.component.html | 3 + .../src/xforge-common/xforge-common.module.ts | 4 +- .../SystemAdministrationController.cs | 70 +++++++++++++++++++ .../Services/ISystemAdministrationService.cs | 11 +++ .../Services/SFServiceCollectionExtensions.cs | 1 + .../Services/SystemAdministrationService.cs | 36 ++++++++++ src/SIL.XForge/Controllers/UrlConstants.cs | 1 + .../DataAccessApplicationBuilderExtensions.cs | 6 +- .../DataAccessServiceCollectionExtensions.cs | 4 ++ src/SIL.XForge/Models/HelpVideo.cs | 11 +++ 25 files changed, 445 insertions(+), 2 deletions(-) create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/app/core/models/help-video.ts create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.html create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.scss create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.spec.ts create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.ts create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.html create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.scss create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.spec.ts create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.ts create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.html create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.scss create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.spec.ts create mode 100644 src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.ts create mode 100644 src/SIL.XForge.Scripture/Controllers/SystemAdministrationController.cs create mode 100644 src/SIL.XForge.Scripture/Services/ISystemAdministrationService.cs create mode 100644 src/SIL.XForge.Scripture/Services/SystemAdministrationService.cs create mode 100644 src/SIL.XForge/Models/HelpVideo.cs diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/app-routing.module.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/app-routing.module.ts index 8099ec2058..ef19996b7d 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/app-routing.module.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/app-routing.module.ts @@ -14,10 +14,12 @@ import { SettingsComponent } from './settings/settings.component'; import { PageNotFoundComponent } from './shared/page-not-found/page-not-found.component'; import { SettingsAuthGuard, SyncAuthGuard } from './shared/project-router.guard'; import { SyncComponent } from './sync/sync.component'; +import { HelpVideosComponent } from './shared/help-videos/help-videos.component'; const routes: Routes = [ { path: 'callback/auth0', component: MyProjectsComponent, canActivate: [AuthGuard] }, { path: 'connect-project', component: ConnectProjectComponent, canActivate: [AuthGuard] }, + { path: 'help-videos', component: HelpVideosComponent }, { path: 'login', redirectTo: 'projects', pathMatch: 'full' }, { path: 'join/:shareKey', component: JoinComponent }, { path: 'join/:shareKey/:locale', component: JoinComponent }, diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html b/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html index 8a2fd4ac72..92312c7fa5 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/app.component.html @@ -55,6 +55,7 @@ help {{ t("help") }} + smart_display Tutorials book {{ t("manual") }} campaign {{ t("announcements") }} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/core/models/help-video.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/core/models/help-video.ts new file mode 100644 index 0000000000..0db3349a0a --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/core/models/help-video.ts @@ -0,0 +1,8 @@ +export interface HelpVideo { + id: string; + name: string; + url: string; + description: string; + keywords: string[]; + feature: string; +} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.html b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.html new file mode 100644 index 0000000000..8d4d29f398 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.html @@ -0,0 +1,27 @@ +

Tutorial Videos

+@if (!isOnline) { + Connect to internet to view videos +} @else { + + Search for video + + + +
+ @for (value of ["1", "2", "3", "4", "5"]; track value) { + + + Video Name {{ value }} + + + + + + Description of the video {{ value }} + + + } +
+} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.scss b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.scss new file mode 100644 index 0000000000..33ae9942c1 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.scss @@ -0,0 +1,12 @@ +.help-videos, +mat-card-header, +mat-card-footer { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 2rem; +} + +mat-form-field { + width: 85%; +} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.spec.ts new file mode 100644 index 0000000000..7ce5dbc5c7 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HelpVideosComponent } from './help-videos.component'; + +describe('HelpVideosComponent', () => { + let component: HelpVideosComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HelpVideosComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(HelpVideosComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.ts new file mode 100644 index 0000000000..952a9cd37c --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/app/shared/help-videos/help-videos.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { OnlineStatusService } from '../../../xforge-common/online-status.service'; + +@Component({ + selector: 'app-help-videos', + standalone: true, + imports: [MatCardModule, MatIconModule, MatInputModule, MatFormFieldModule], + templateUrl: './help-videos.component.html', + styleUrl: './help-videos.component.scss' +}) +export class HelpVideosComponent { + isOnlineStatus: boolean; + constructor(private readonly onlineStatusService: OnlineStatusService) { + this.onlineStatusService.onlineStatus$.subscribe(isOnline => { + this.isOnlineStatus = isOnline; + }); + } + get isOnline(): boolean { + return this.isOnlineStatus; + } +} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.html b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.html new file mode 100644 index 0000000000..0084cd1cec --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.html @@ -0,0 +1,23 @@ +

{{ data.isEdit ? "Edit Help Video" : "Add Help Video" }}

+ +
+ + Title + + + + URL + + + + Description + + +
+
+ + + + diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.scss b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.spec.ts new file mode 100644 index 0000000000..275b3d1e95 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SaHelpVideosDialogComponent } from './sa-help-videos-dialog.component'; + +describe('SaHelpVideosDialogComponent', () => { + let component: SaHelpVideosDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SaHelpVideosDialogComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(SaHelpVideosDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.ts new file mode 100644 index 0000000000..c3ddd53c02 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos-dialog/sa-help-videos-dialog.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-sa-help-videos-dialog', + standalone: true, + imports: [], + templateUrl: './sa-help-videos-dialog.component.html', + styleUrl: './sa-help-videos-dialog.component.scss' +}) +export class SaHelpVideosDialogComponent {} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.html b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.html new file mode 100644 index 0000000000..dcb6a4c469 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.html @@ -0,0 +1,54 @@ + + + + Video Name + + {{ element.videoName }} + + + + + Video Description + + {{ element.videoDescription }} + + + + + URL + + {{ element.url }} + + + + + Component + + {{ element.component }} + + + + + Keywords + + {{ element.keywords }} + + + + + + + + + + + + + + + + + + + + diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.scss b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.scss new file mode 100644 index 0000000000..3c1826be95 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.scss @@ -0,0 +1,47 @@ +@use 'src/variables'; +@use 'src/breakpoints'; + +.help-controls { + margin: 32px 0; +} + +mat-form-field { + margin-top: 10px; +} + +mat-table { + width: 100%; +} + +.mat-column-tasks { + @include breakpoints.media-breakpoint-down(md) { + display: none; + } +} + +.no-projects-label { + padding-top: 14px; +} + +.connect-cell { + text-align: right; + text-overflow: initial; +} + +.task-label { + font-size: small; + color: variables.$greyLight; +} + +.small-form-field { + width: 130px; +} + +td > mat-checkbox { + margin: 0 1em; +} + +ng-container { + display: flex; + align-items: center; +} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.spec.ts new file mode 100644 index 0000000000..33d036ccb9 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SaHelpVideosComponent } from './sa-help-videos.component'; + +describe('HelpVideosComponent', () => { + let component: SaHelpVideosComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SaHelpVideosComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(SaHelpVideosComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.ts new file mode 100644 index 0000000000..39d7570f81 --- /dev/null +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/sa-help-video-tab/sa-help-videos.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-sa-help-videos', + templateUrl: './sa-help-videos.component.html', + styleUrl: './sa-help-videos.component.scss' +}) +export class SaHelpVideosComponent { + constructor() {} + displayedColumns: string[] = ['videoName', 'videoDescription', 'url', 'component', 'keywords', 'edit', 'delete']; + dataSource = [ + { + videoName: 'Video 1', + videoDescription: 'Description for Video 1', + url: 'https://youtube.com', + component: ['Component1'] + } + ]; + + componentOptions: string[] = ['Component1', 'Component2', 'Component3']; + + addEditVideoData() { + this.dataSource.push({ videoName: '', videoDescription: '', url: '', component: [] }); + } +} diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/system-administration.component.html b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/system-administration.component.html index 7cfec0cb87..8a0932248c 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/system-administration.component.html +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/system-administration/system-administration.component.html @@ -8,5 +8,8 @@

System Administration

+ + + diff --git a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/xforge-common.module.ts b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/xforge-common.module.ts index 0a869b7d20..26af3648ca 100644 --- a/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/xforge-common.module.ts +++ b/src/SIL.XForge.Scripture/ClientApp/src/xforge-common/xforge-common.module.ts @@ -23,6 +23,7 @@ import { SaUsersComponent } from './system-administration/sa-users.component'; import { SystemAdministrationComponent } from './system-administration/system-administration.component'; import { UICommonModule } from './ui-common.module'; import { WriteStatusComponent } from './write-status/write-status.component'; +import { SaHelpVideosComponent } from './system-administration/sa-help-video-tab/sa-help-videos.component'; const componentExports = [ GenericDialogComponent, @@ -34,7 +35,8 @@ const componentExports = [ WriteStatusComponent, OwnerComponent, ProjectSelectComponent, - SyncProgressComponent + SyncProgressComponent, + SaHelpVideosComponent ]; @NgModule({ diff --git a/src/SIL.XForge.Scripture/Controllers/SystemAdministrationController.cs b/src/SIL.XForge.Scripture/Controllers/SystemAdministrationController.cs new file mode 100644 index 0000000000..931e15569f --- /dev/null +++ b/src/SIL.XForge.Scripture/Controllers/SystemAdministrationController.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using SIL.XForge.Models; +using SIL.XForge.Scripture.Services; +using SIL.XForge.Services; + +namespace SIL.XForge.Scripture.Controllers; + +/// +/// Provides methods for uploading files. +/// +[Authorize] +[Route(UrlConstants.CommandApiNamespace + "/" + UrlConstants.SystemAdministration)] +public class SystemAdministrationController : ControllerBase +{ + private readonly ISystemAdministrationService _systemAdministrationService; + private readonly IExceptionHandler _exceptionHandler; + + public SystemAdministrationController( + ISystemAdministrationService systemAdministrationService, + IExceptionHandler exceptionHandler + ) + { + _systemAdministrationService = systemAdministrationService; + _exceptionHandler = exceptionHandler; + } + + [HttpGet("getHelpVideos")] + public IActionResult GetHelpVideos(string[] systemRoles) + { + try + { + return Ok(_systemAdministrationService.GetHelpVideos(systemRoles)); + } + catch (ForbiddenException) + { + return Forbid(); + } + catch (Exception) + { + _exceptionHandler.RecordEndpointInfoForException( + new Dictionary { { "method", "GetHelpVideos" } } + ); + throw; + } + } + + [HttpPost("saveHelpVideo")] + public async Task SaveHelpVideo(HelpVideo helpVideo, string[] systemRoles) + { + try + { + return Ok(await _systemAdministrationService.SaveHelpVideoAsync(systemRoles, helpVideo)); + } + catch (ForbiddenException) + { + return Forbid(); + } + catch (Exception) + { + _exceptionHandler.RecordEndpointInfoForException( + new Dictionary { { "method", "SaveHelpVideo" } } + ); + throw; + } + } +} diff --git a/src/SIL.XForge.Scripture/Services/ISystemAdministrationService.cs b/src/SIL.XForge.Scripture/Services/ISystemAdministrationService.cs new file mode 100644 index 0000000000..cc74adff44 --- /dev/null +++ b/src/SIL.XForge.Scripture/Services/ISystemAdministrationService.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using SIL.XForge.Models; + +namespace SIL.XForge.Scripture.Services; + +public interface ISystemAdministrationService +{ + IEnumerable GetHelpVideos(string[] systemRoles); + Task> SaveHelpVideoAsync(string[] systemRoles, HelpVideo helpVideo); +} diff --git a/src/SIL.XForge.Scripture/Services/SFServiceCollectionExtensions.cs b/src/SIL.XForge.Scripture/Services/SFServiceCollectionExtensions.cs index 16d5389f6f..24c6d5a3db 100644 --- a/src/SIL.XForge.Scripture/Services/SFServiceCollectionExtensions.cs +++ b/src/SIL.XForge.Scripture/Services/SFServiceCollectionExtensions.cs @@ -27,6 +27,7 @@ public static IServiceCollection AddSFServices(this IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); return services; } } diff --git a/src/SIL.XForge.Scripture/Services/SystemAdministrationService.cs b/src/SIL.XForge.Scripture/Services/SystemAdministrationService.cs new file mode 100644 index 0000000000..a9b80fc5e9 --- /dev/null +++ b/src/SIL.XForge.Scripture/Services/SystemAdministrationService.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using MongoDB.Bson; +using PtxUtils; +using SIL.XForge.DataAccess; +using SIL.XForge.Models; +using SIL.XForge.Services; + +namespace SIL.XForge.Scripture.Services; + +public class SystemAdministrationService : ISystemAdministrationService +{ + private readonly IRepository _helpVideos; + + public SystemAdministrationService(IRepository helpVideos) => _helpVideos = helpVideos; + + public IEnumerable GetHelpVideos(string[] systemRoles) + { + if (!systemRoles.Contains(SystemRole.SystemAdmin)) + throw new ForbiddenException(); + + return _helpVideos.Query().AsEnumerable(); + } + + public async Task> SaveHelpVideoAsync(string[] systemRoles, HelpVideo helpVideo) + { + if (!systemRoles.Contains(SystemRole.SystemAdmin)) + throw new ForbiddenException(); + + helpVideo.Id = new ObjectId().ToString(); + await _helpVideos.InsertAsync(helpVideo); + return GetHelpVideos(systemRoles); + } +} diff --git a/src/SIL.XForge/Controllers/UrlConstants.cs b/src/SIL.XForge/Controllers/UrlConstants.cs index 47d3a6132f..a1e8d51520 100644 --- a/src/SIL.XForge/Controllers/UrlConstants.cs +++ b/src/SIL.XForge/Controllers/UrlConstants.cs @@ -7,4 +7,5 @@ public static class UrlConstants public const string Users = "users"; public const string Projects = "projects"; public const string ProjectNotifications = "project-notifications"; + public const string SystemAdministration = "system-administration"; } diff --git a/src/SIL.XForge/DataAccess/DataAccessApplicationBuilderExtensions.cs b/src/SIL.XForge/DataAccess/DataAccessApplicationBuilderExtensions.cs index fc2fb7ddc4..91fcfc1626 100644 --- a/src/SIL.XForge/DataAccess/DataAccessApplicationBuilderExtensions.cs +++ b/src/SIL.XForge/DataAccess/DataAccessApplicationBuilderExtensions.cs @@ -6,7 +6,11 @@ namespace Microsoft.AspNetCore.Builder; public static class DataAccessApplicationBuilderExtensions { - public static void UseDataAccess(this IApplicationBuilder app) => app.InitRepository(); + public static void UseDataAccess(this IApplicationBuilder app) + { + app.InitRepository(); + app.InitRepository(); + } public static void InitRepository(this IApplicationBuilder app) where T : IIdentifiable => app.ApplicationServices.GetService>().Init(); diff --git a/src/SIL.XForge/DataAccess/DataAccessServiceCollectionExtensions.cs b/src/SIL.XForge/DataAccess/DataAccessServiceCollectionExtensions.cs index 0997d0575d..4957eb1b02 100644 --- a/src/SIL.XForge/DataAccess/DataAccessServiceCollectionExtensions.cs +++ b/src/SIL.XForge/DataAccess/DataAccessServiceCollectionExtensions.cs @@ -45,11 +45,15 @@ public static IServiceCollection AddDataAccess(this IServiceCollection services, DataAccessClassMap.RegisterClass(cm => cm.MapIdProperty(e => e.Id)); DataAccessClassMap.RegisterClass(cm => cm.MapIdProperty(e => e.Id)); + // DataAccessClassMap.RegisterClass(cm => cm.MapIdProperty(hv => hv.Id)); + services.AddSingleton(sp => new MongoClient(options.ConnectionString)); services.AddSingleton(sp => sp.GetService().GetDatabase(options.MongoDatabaseName)); services.AddMongoRepository("user_secrets", cm => cm.MapIdProperty(us => us.Id)); + services.AddMongoRepository("help_videos", cm => cm.MapIdProperty(hv => hv.Id)); + return services; } diff --git a/src/SIL.XForge/Models/HelpVideo.cs b/src/SIL.XForge/Models/HelpVideo.cs new file mode 100644 index 0000000000..4df752f2b1 --- /dev/null +++ b/src/SIL.XForge/Models/HelpVideo.cs @@ -0,0 +1,11 @@ +namespace SIL.XForge.Models; + +public class HelpVideo : IIdentifiable +{ + public string Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string Feature { get; set; } + public string[] Keywords { get; set; } + public string Url { get; set; } +}