diff --git a/ProgramInformationV2.Data/CourseraImport/CourseraImportManager.cs b/ProgramInformationV2.Data/CourseraImport/CourseraImportManager.cs index 35c5926..5b8a9cc 100644 --- a/ProgramInformationV2.Data/CourseraImport/CourseraImportManager.cs +++ b/ProgramInformationV2.Data/CourseraImport/CourseraImportManager.cs @@ -13,7 +13,7 @@ public async Task GetCourse(string source, string id) { var course = new Course { Source = source, Title = courseraCourse.Title, - Url = "https://www.coursera.com" + courseraCourse.Url, + Url = "https://www.coursera.org" + courseraCourse.Url, Id = source + "-" + courseraCourse.Id, PlatformType = PlatformTypes.Coursera, ImageUrl = courseraCourse.ImageUrl, diff --git a/ProgramInformationV2.Data/FieldList/CourseGroup.cs b/ProgramInformationV2.Data/FieldList/CourseGroup.cs index 867e336..2a7048c 100644 --- a/ProgramInformationV2.Data/FieldList/CourseGroup.cs +++ b/ProgramInformationV2.Data/FieldList/CourseGroup.cs @@ -21,6 +21,7 @@ public CourseGroup() { new() { Title = "Title", CategoryType = CategoryType.Course, FieldType = FieldType.General, IsRequired = true, InitialDescription = "Name your course. This will appear when users search for courses. -- Do not include the rubric or course number, as it will be added to the title when displayed." }, new() { Title = "Rubric", CategoryType = CategoryType.Course, FieldType = FieldType.General }, new() { Title = "Course Number", CategoryType = CategoryType.Course, FieldType = FieldType.General }, + new() { Title = "Platform Type", CategoryType = CategoryType.Course, FieldType = FieldType.General }, new() { Title = "Summary", CategoryType = CategoryType.Course, FieldType = FieldType.General, InitialDescription = "Briefly summarize the course. This will appear when users search courses; they will read a brief summary of the course before clicking into the course page." }, new() { Title = "Description", CategoryType = CategoryType.Course, FieldType = FieldType.General, InitialDescription = "This text should describe the course. It will be on the course page." }, new() { Title = "Information", CategoryType = CategoryType.Course, FieldType = FieldType.General, InitialDescription = "For example: 3 undergraduate hours. 2 or 4 graduate hours." }, diff --git a/ProgramInformationV2.Function/GetCourses.cs b/ProgramInformationV2.Function/GetCourses.cs index 1ae1bb6..2b07448 100644 --- a/ProgramInformationV2.Function/GetCourses.cs +++ b/ProgramInformationV2.Function/GetCourses.cs @@ -81,6 +81,7 @@ public async Task Id([HttpTrigger(AuthorizationLevel.Anonymous [OpenApiParameter(name: "skills", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "A list of skills the course will give you. You can separate the skills by the characters '[-]'.")] [OpenApiParameter(name: "departments", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "A list of departments the course is in. You can separate the departments by the characters '[-]'.")] [OpenApiParameter(name: "q", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "A full text search string -- it will search the title and description for the search querystring.")] + [OpenApiParameter(name: "platform", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "Either 'coursera', 'campus', 'custom', 'moodle' for platform type.")] [OpenApiParameter(name: "period", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "Either 'upcoming' (future courses), 'current' (courses that are going on now), or 'open' (courses that are going on now or in the future).")] [OpenApiParameter(name: "formats", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "Either 'On-Campus', 'Online', 'Off-Campus', or 'Hybrid'. Can choose multiple by separating them with the characters '[-]'")] [OpenApiParameter(name: "rubric", In = ParameterLocation.Query, Required = false, Type = typeof(string), Description = "The course rubric.")] @@ -105,13 +106,15 @@ public async Task Search([HttpTrigger(AuthorizationLevel.Anony var take = requestHelper.GetInteger(req, "take", 1000); var skip = requestHelper.GetInteger(req, "skip"); var period = requestHelper.GetRequest(req, "period", false); - + if (!Enum.TryParse(requestHelper.GetRequest(req, "platform", false), true, out PlatformTypes platform)) { + platform = PlatformTypes.None; + } var isUpcoming = period.Equals("upcoming") || period.Equals("open"); var isCurrent = period.Equals("current") || period.Equals("open"); requestHelper.Validate(); var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(await _courseGetter.GetCourses(source, query, tags, tags2, tags3, skills, departments, formats, rubric, terms, isUpcoming, isCurrent, take, skip)); + await response.WriteAsJsonAsync(await _courseGetter.GetCourses(source, query, tags, tags2, tags3, skills, departments, formats, rubric, platform, terms, isUpcoming, isCurrent, take, skip)); return response; } diff --git a/ProgramInformationV2.Search/Getters/CourseGetter.cs b/ProgramInformationV2.Search/Getters/CourseGetter.cs index 71ebaf8..4c565e8 100644 --- a/ProgramInformationV2.Search/Getters/CourseGetter.cs +++ b/ProgramInformationV2.Search/Getters/CourseGetter.cs @@ -52,7 +52,7 @@ public async Task GetCourseBySection(string sectionId) { return response.IsValid ? response.Documents.FirstOrDefault() ?? new Course() : new Course(); } - public async Task> GetCourses(string source, string search, IEnumerable tags, IEnumerable tags2, IEnumerable tags3, IEnumerable skills, IEnumerable departments, IEnumerable formats, string rubric, IEnumerable terms, bool isUpcoming, bool isCurrent, int take, int skip) { + public async Task> GetCourses(string source, string search, IEnumerable tags, IEnumerable tags2, IEnumerable tags3, IEnumerable skills, IEnumerable departments, IEnumerable formats, string rubric, PlatformTypes platform, IEnumerable terms, bool isUpcoming, bool isCurrent, int take, int skip) { var response = await _openSearchClient.SearchAsync(s => s.Index(UrlTypes.Courses.ConvertToUrlString()) .Skip(skip) .Size(take) @@ -66,7 +66,8 @@ public async Task> GetCourses(string source, string search, f => departments.Any() ? f.Terms(m => m.Field(fld => fld.DepartmentList).Terms(departments)) : f.MatchAll(), f => skills.Any() ? f.Terms(m => m.Field(fld => fld.SkillList).Terms(skills)) : f.MatchAll(), f => formats.Any() ? f.Terms(m => m.Field(fld => fld.Formats).Terms(formats)) : f.MatchAll(), - f => rubric.Any() ? f.Term(m => m.Field(fld => fld.Rubric).Value(rubric)) : f.MatchAll(), + f => !string.IsNullOrWhiteSpace(rubric) ? f.Term(m => m.Field(fld => fld.Rubric).Value(rubric)) : f.MatchAll(), + f => platform != PlatformTypes.None ? f.Term(m => m.Field(fld => fld.PlatformType).Value(platform)) : f.MatchAll(), f => terms.Any() ? f.Terms(m => m.Field(fld => fld.Terms).Terms(terms)) : f.MatchAll(), f => isUpcoming ? f.Term(m => m.Field(fld => fld.IsUpcoming).Value(true)) : f.MatchAll(), f => isCurrent ? f.Term(m => m.Field(fld => fld.IsCurrent).Value(true)) : f.MatchAll()) diff --git a/ProgramInformationV2/Components/Controls/PlatformSelectList.razor b/ProgramInformationV2/Components/Controls/PlatformSelectList.razor new file mode 100644 index 0000000..e806770 --- /dev/null +++ b/ProgramInformationV2/Components/Controls/PlatformSelectList.razor @@ -0,0 +1,14 @@ +@using ProgramInformationV2.Search.Models +@if (GetFieldItemActive()) { + +
+ + +

@GetFieldItemDescription()

+
+
+} \ No newline at end of file diff --git a/ProgramInformationV2/Components/Controls/PlatformSelectList.razor.cs b/ProgramInformationV2/Components/Controls/PlatformSelectList.razor.cs new file mode 100644 index 0000000..2ab7c2b --- /dev/null +++ b/ProgramInformationV2/Components/Controls/PlatformSelectList.razor.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Components; +using ProgramInformationV2.Components.Layout; +using ProgramInformationV2.Data.FieldList; +using ProgramInformationV2.Search.Models; + +namespace ProgramInformationV2.Components.Controls { + public partial class PlatformSelectList { + private PlatformTypes? _value; + + [Parameter] + public IEnumerable FieldItems { get; set; } = default!; + + public string Id => Title.Replace(" ", "_").ToLowerInvariant(); + + [CascadingParameter] + public SidebarLayout Layout { get; set; } = default!; + + [Parameter] + public string Title { get; set; } = ""; + + [Parameter] + public PlatformTypes? Value { + get => _value; + set { + if (_value == value) + return; + if (Layout != null) + Layout.SetDirty(); + _value = value; + ValueChanged.InvokeAsync(value.HasValue ? value.Value : PlatformTypes.None); + } + } + + [Parameter] + public EventCallback ValueChanged { get; set; } + + public bool GetFieldItemActive() => FieldItems == null ? false : FieldItems.FirstOrDefault(f => f.Title == Title)?.ShowItem ?? true; + + public string GetFieldItemDescription() => FieldItems == null ? "" : FieldItems.FirstOrDefault(f => f.Title == Title)?.Description ?? ""; + + } +} diff --git a/ProgramInformationV2/Components/Pages/Course/CourseraImport.razor b/ProgramInformationV2/Components/Pages/Course/CourseraImport.razor index 3e7f85d..d7cc8a0 100644 --- a/ProgramInformationV2/Components/Pages/Course/CourseraImport.razor +++ b/ProgramInformationV2/Components/Pages/Course/CourseraImport.razor @@ -2,12 +2,6 @@ @layout SidebarLayout Import a Coursera Course -

Import a Coursera Course

@if (_useCourses.HasValue && _useCourses.Value) @@ -20,7 +14,7 @@ @if (ListOfCourseraCourses != null && ListOfCourseraCoursesSelected != null) { -
+
diff --git a/ProgramInformationV2/Components/Pages/Course/General.razor b/ProgramInformationV2/Components/Pages/Course/General.razor index 37dbbdd..47c9b4e 100644 --- a/ProgramInformationV2/Components/Pages/Course/General.razor +++ b/ProgramInformationV2/Components/Pages/Course/General.razor @@ -11,6 +11,7 @@ + diff --git a/ProgramInformationV2/wwwroot/css/boxes.css b/ProgramInformationV2/wwwroot/css/boxes.css index 3a94cae..0b30653 100644 --- a/ProgramInformationV2/wwwroot/css/boxes.css +++ b/ProgramInformationV2/wwwroot/css/boxes.css @@ -92,3 +92,9 @@ div.button-group { div.button-group button { max-height: 40px; } + +div.container-coursera { + padding: 20px; + border: 1px solid var(--il-blue); + margin: 15px 0; +}