From b73fb9d60c462ca7e39a0489b9a30ad64ad4b447 Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Wed, 6 Jul 2016 17:18:42 -0400 Subject: [PATCH 01/41] Updated Schemas --- client/imports/ui/pages/account/account.ts | 52 +++++++++++----------- collections/courses.ts | 3 ++ collections/users.ts | 3 ++ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/client/imports/ui/pages/account/account.ts b/client/imports/ui/pages/account/account.ts index ca6cadca..274aae37 100644 --- a/client/imports/ui/pages/account/account.ts +++ b/client/imports/ui/pages/account/account.ts @@ -12,44 +12,42 @@ import { HTTP_PROVIDERS } from '@angular/http'; import { RouterLink, ROUTER_PROVIDERS, ROUTER_DIRECTIVES, RouteConfig } from '@angular/router-deprecated'; - import { InjectUser, RequireUser } from 'angular2-meteor-accounts-ui'; + import { InjectUser } from 'angular2-meteor-accounts-ui'; // Angular Material Imports import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; import { MeteorComponent } from 'angular2-meteor'; + import { MD_SIDENAV_DIRECTIVES } from '@angular2-material/sidenav'; + +// Toolbar + import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; // Icon import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon' - -// Define TuxLab Component - @Component({ +// Define Account Component +@Component({ selector: 'tuxlab-account', templateUrl: '/client/imports/ui/pages/account/account.html', - directives: [ MD_ICON_DIRECTIVES, - MATERIAL_DIRECTIVES ], + directives: [ MATERIAL_DIRECTIVES, + MD_TOOLBAR_DIRECTIVES, + MD_ICON_DIRECTIVES ], viewProviders: [ MdIconRegistry ], encapsulation: ViewEncapsulation.None - }) - +}) + @InjectUser("user") export class Account extends MeteorComponent { - user: Meteor.User; - name: String = "Name Here"; - school: String = "School Here"; - email: String = "example@example.com"; - imgsrc: String = "http://www.placekitten.com/g/250/250"; - constructor(mdIconRegistry: MdIconRegistry) { - super(); - // Create Icon Font - mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); - mdIconRegistry.setDefaultFontSetClass('tuxicon'); - - } - test() { - this.name = this.user.profile.name; - this.school = "Carnegie Mellon University"; - this.imgsrc = this.user.profile.picture; - this.email = this.user.profile.email; - } -} + user: Meteor.User; + imgsrc: String = "http://www.placekitten.com/g/250/250"; + name: String = "Name Here"; + school: String = "School Name Here"; + email: String = "example@example.com"; + constructor(mdIconRegistry: MdIconRegistry) { + super(); + // Create Icon Font + mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); + mdIconRegistry.setDefaultFontSetClass('tuxicon'); + + } +} diff --git a/collections/courses.ts b/collections/courses.ts index effab4c9..4be78795 100644 --- a/collections/courses.ts +++ b/collections/courses.ts @@ -63,6 +63,9 @@ if (Meteor.isServer){ }, labs: { type: [labSchema] + }, + instructor_name: { + type: String } }); (courses).attachSchema(courseSchema); diff --git a/collections/users.ts b/collections/users.ts index 78e7da50..bd28bd78 100644 --- a/collections/users.ts +++ b/collections/users.ts @@ -15,6 +15,9 @@ if (Meteor.isServer){ last_name: { type: String }, + school: { + type: String + }, email: { type: String }, From 0effec138a87a69216c1fd09005026cb071ca9a2 Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Wed, 6 Jul 2016 17:30:32 -0400 Subject: [PATCH 02/41] Load Screen --- .../ui/components/loadscreen/loadscreen.html | 10 ++++ .../ui/components/loadscreen/loadscreen.ts | 46 +++++++++++++++++++ .../ui/components/markdown/markdown.ts | 1 - .../ui/pages/instructor/instructor.html | 1 + .../imports/ui/pages/instructor/instructor.ts | 6 ++- 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 client/imports/ui/components/loadscreen/loadscreen.html create mode 100644 client/imports/ui/components/loadscreen/loadscreen.ts diff --git a/client/imports/ui/components/loadscreen/loadscreen.html b/client/imports/ui/components/loadscreen/loadscreen.html new file mode 100644 index 00000000..158d78fb --- /dev/null +++ b/client/imports/ui/components/loadscreen/loadscreen.html @@ -0,0 +1,10 @@ +
+ + This is an alert title + You can specify some description text in here + + + +
\ No newline at end of file diff --git a/client/imports/ui/components/loadscreen/loadscreen.ts b/client/imports/ui/components/loadscreen/loadscreen.ts new file mode 100644 index 00000000..48ba17ab --- /dev/null +++ b/client/imports/ui/components/loadscreen/loadscreen.ts @@ -0,0 +1,46 @@ +// Meteor Imports + import { Meteor } from 'meteor/meteor'; + import { Mongo } from 'meteor/mongo'; + import 'reflect-metadata'; + import 'zone.js/dist/zone'; + +// Angular Imports + import { Component, ViewEncapsulation, provide } from '@angular/core'; + import { bootstrap } from 'angular2-meteor-auto-bootstrap'; + import { APP_BASE_HREF } from '@angular/common'; + import { HTTP_PROVIDERS } from '@angular/http'; + import { InjectUser } from 'angular2-meteor-accounts-ui'; + +// Angular Material Imports + import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; + import { MeteorComponent } from 'angular2-meteor'; + import { OVERLAY_PROVIDERS } from '@angular2-material/core/overlay/overlay'; + +// Toolbar + import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; + +// Icon + import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; + +// Define LoadScreen Component + @Component({ + selector: 'tuxlab-loadscreen', + templateUrl: '/client/imports/ui/components/loadscreen/loadscreen.html', + directives: [ MATERIAL_DIRECTIVES, + MD_TOOLBAR_DIRECTIVES, + MD_ICON_DIRECTIVES ], + viewProviders: [ MdIconRegistry ], + providers: [ OVERLAY_PROVIDERS ], + encapsulation: ViewEncapsulation.None + }) + +// Export LoadScreen Class +export class LoadScreen extends MeteorComponent { + constructor(mdIconRegistry: MdIconRegistry) { + super(); + // Create Icon Font + mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); + mdIconRegistry.setDefaultFontSetClass('tuxicon'); + + } +} diff --git a/client/imports/ui/components/markdown/markdown.ts b/client/imports/ui/components/markdown/markdown.ts index 82be3b41..d3d62526 100644 --- a/client/imports/ui/components/markdown/markdown.ts +++ b/client/imports/ui/components/markdown/markdown.ts @@ -18,7 +18,6 @@ // Toolbar import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; - import "../../../../../node_modules/@angular2-material/toolbar/toolbar.css"; // Icon import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; diff --git a/client/imports/ui/pages/instructor/instructor.html b/client/imports/ui/pages/instructor/instructor.html index 4502e313..2caf1718 100644 --- a/client/imports/ui/pages/instructor/instructor.html +++ b/client/imports/ui/pages/instructor/instructor.html @@ -10,4 +10,5 @@ + \ No newline at end of file diff --git a/client/imports/ui/pages/instructor/instructor.ts b/client/imports/ui/pages/instructor/instructor.ts index 4e74a510..2919bf8d 100644 --- a/client/imports/ui/pages/instructor/instructor.ts +++ b/client/imports/ui/pages/instructor/instructor.ts @@ -21,6 +21,8 @@ // Editor Component import { MDEditor } from '../../components/mdeditor/mdeditor'; + + import { LoadScreen } from '../../components/loadscreen/loadscreen'; // Define InstructorView Component @Component({ @@ -30,7 +32,8 @@ MATERIAL_DIRECTIVES, MD_ICON_DIRECTIVES, MD_SIDENAV_DIRECTIVES, - MDEditor + MDEditor, + LoadScreen ], viewProviders: [ MdIconRegistry ], encapsulation: ViewEncapsulation.None @@ -45,7 +48,6 @@ export class Instructor extends MeteorComponent { // Create Icon Font mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); mdIconRegistry.setDefaultFontSetClass('tuxicon'); - } } From 78426b80d4dc702a618692a2fd2e9d8e065d3f4a Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Wed, 6 Jul 2016 17:35:20 -0400 Subject: [PATCH 03/41] Loading Screen --- client/imports/ui/components/loadscreen/loadscreen.html | 3 --- client/imports/ui/components/loadscreen/loadscreen.ts | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/client/imports/ui/components/loadscreen/loadscreen.html b/client/imports/ui/components/loadscreen/loadscreen.html index 158d78fb..fdf5b002 100644 --- a/client/imports/ui/components/loadscreen/loadscreen.html +++ b/client/imports/ui/components/loadscreen/loadscreen.html @@ -4,7 +4,4 @@ You can specify some description text in here - \ No newline at end of file diff --git a/client/imports/ui/components/loadscreen/loadscreen.ts b/client/imports/ui/components/loadscreen/loadscreen.ts index 48ba17ab..6624bb3c 100644 --- a/client/imports/ui/components/loadscreen/loadscreen.ts +++ b/client/imports/ui/components/loadscreen/loadscreen.ts @@ -41,6 +41,6 @@ export class LoadScreen extends MeteorComponent { // Create Icon Font mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); mdIconRegistry.setDefaultFontSetClass('tuxicon'); - + } } From 658bd9f6803fa8d09e0b1d1207676623fb8765bd Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Thu, 7 Jul 2016 14:53:51 -0400 Subject: [PATCH 04/41] publish subscribe and dynamic explore page --- .../ui/components/explore/explore.html | 18 +-- .../imports/ui/components/explore/explore.ts | 58 +++------ .../imports/ui/components/explore/search.html | 8 +- .../imports/ui/components/explore/search.ts | 40 +++--- .../imports/ui/components/lablist/lablist.ts | 94 +++++++------- collections/course_records.ts | 19 ++- collections/courses.ts | 10 ++ tests/example_data/example_course.js | 116 ++++++++++++++++++ 8 files changed, 236 insertions(+), 127 deletions(-) diff --git a/client/imports/ui/components/explore/explore.html b/client/imports/ui/components/explore/explore.html index b99ef8b3..b4028e99 100644 --- a/client/imports/ui/components/explore/explore.html +++ b/client/imports/ui/components/explore/explore.html @@ -6,37 +6,37 @@ - + - + - \ No newline at end of file + diff --git a/client/imports/ui/components/explore/explore.ts b/client/imports/ui/components/explore/explore.ts index efb9181c..cb47a2c1 100644 --- a/client/imports/ui/components/explore/explore.ts +++ b/client/imports/ui/components/explore/explore.ts @@ -21,15 +21,20 @@ // Icon import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; +// Courses Imports + import { courses } from "../../../../../collections/courses.ts"; + // Define ExploreView Component @Component({ selector: 'tuxlab-exploreview', templateUrl: '/client/imports/ui/components/explore/explore.html', - directives: [ MATERIAL_DIRECTIVES, - MD_ICON_DIRECTIVES, - MD_TABS_DIRECTIVES, - MD_INPUT_DIRECTIVES, - MdToolbar ], + directives: [ + MATERIAL_DIRECTIVES, + MD_ICON_DIRECTIVES, + MD_TABS_DIRECTIVES, + MD_INPUT_DIRECTIVES, + MdToolbar + ], viewProviders: [ MdIconRegistry ], encapsulation: ViewEncapsulation.None }) @@ -37,45 +42,20 @@ // Export ExploreView Class export class ExploreView extends MeteorComponent { - courses: Array = [ - { - 'id': '1', - 'courseName': 'Great Practical Ideas for Computer Scientists', - 'description': ` - Throughout your education as a Computer Scientist at - Carnegie Mellon, you will take courses on programming, - theoretical ideas, logic, systems, etc. As you progress, - you will be expected to pick up the so-called “tools of - the trade.” This course is intended to help you learn - what you need to know in a friendly, low-stress, - high-support way. We will discuss UNIX, LaTeX, debugging - and many other essential tools. - `, - 'syllabus': 'This is supposed to be the syllabus.', - 'content': 'This is the course content of GPI.' - }, - { - 'id': '2', - 'courseName': 'Great Theoretical Ideas in Computer Science', - 'description': 'This course will blow your mind', - 'syllabus': 'Fail to be amazing and you will fail the course.', - 'content': 'This is the course content of GTI.' - }, - { - 'id': '3', - 'courseName': 'Principles of Functional Programming', - 'description': 'This course will teach you how to program functionally.', - 'syllabus': 'You will scrape by with a course average of 90%.', - 'content': 'We will be using SML.' - } - ]; - + courses: Array = []; + constructor(mdIconRegistry: MdIconRegistry) { super(); // Create Icon Font mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); mdIconRegistry.setDefaultFontSetClass('tuxicon'); + + this.getCourses(); } - + getCourses() { + this.subscribe('courses', () => { + this.courses = courses.find().fetch(); + }, true); + } } diff --git a/client/imports/ui/components/explore/search.html b/client/imports/ui/components/explore/search.html index 9503e62b..57747fb8 100644 --- a/client/imports/ui/components/explore/search.html +++ b/client/imports/ui/components/explore/search.html @@ -18,14 +18,14 @@

Search Results

Course Number Course Name - Seats Left + Instructor - {{ course.number }} - {{ course.name }} - {{ course.quantity }} + {{ course.course_number }} + {{ course.course_name }} + {{ course.instructor_name }} diff --git a/client/imports/ui/components/explore/search.ts b/client/imports/ui/components/explore/search.ts index 6834f5b5..878366c7 100644 --- a/client/imports/ui/components/explore/search.ts +++ b/client/imports/ui/components/explore/search.ts @@ -21,6 +21,9 @@ // Icon import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; +// Courses Database Imports + import { courses } from '../../../../../collections/courses'; + // Define SearchView Component @Component({ selector: 'tuxlab-searchview', @@ -37,30 +40,14 @@ // Export Explore Class export class SearchView extends MeteorComponent { - courses: Array = [ - {'id': 1, 'number': '15-131', 'name': 'Great Practical Ideas for Computer Scientists', 'quantity': '12'}, - {'id': 2, 'number': '15-251', 'name': 'Great Theoretical Ideas in Computer Science', 'quantity': '12'}, - {'id': 3, 'number': '15-122', 'name': 'Principles of Imperative Computation', 'quantity': '23'}, - {'id': 4, 'number': '15-112', 'name': 'Principles of Programming', 'quantity': '11'}, - {'id': 5, 'number': '15-150', 'name': 'Principles of Functional Programming', 'quantity': '14'}, - {'id': 6, 'number': '21-127', 'name': 'Concepts of Mathematics', 'quantity': '54'}, - {'id': 7, 'number': '21-299', 'name': 'Calculus in Twelve Dimensions', 'quantity': '76'}, - {'id': 8, 'number': '79-104', 'name': 'Global Histories', 'quantity': '56'}, - {'id': 9, 'number': '15-999', 'name': 'Introduction to Linux', 'quantity': '44'}, - {'id': 10, 'number': '15-998', 'name': 'Vim Usage', 'quantity': '1'}, - {'id': 11, 'number': '15-000', 'name': 'Emacs Usage', 'quantity': '2'}, - {'id': 12, 'number': '15-997', 'name': 'Bash Commands', 'quantity': '3'}, - {'id': 13, 'number': '21-241', 'name': 'Matrices and Linear Transformations', 'quantity': '4'}, - {'id': 14, 'number': '21-341', 'name': 'Matrix Theory', 'quantity': '5'}, - {'id': 15, 'number': '36-225', 'name': 'Probability Theory', 'quantity': '6'} - ]; + courses: Array = []; pagination = { currentPage: 1, - itemsPerPage: 5, + itemsPerPage: 10, totalItems: this.courses.length }; ipp: Array = [5, 10, 15]; - selectedPage = 5; + selectedPage = 10; pagedCourses: Array = []; constructor(mdIconRegistry: MdIconRegistry) { @@ -70,11 +57,18 @@ export class SearchView extends MeteorComponent { // Create Icon Font mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); mdIconRegistry.setDefaultFontSetClass('tuxicon'); - - // Refresh Courses List on load - this.refreshCourses(); - + + // Subscribe Courses Database + this.getCourses(); } + + getCourses() { + this.subscribe('courses', () => { + this.courses = courses.find().fetch(); + this.pagination.totalItems = this.courses.length; + this.refreshCourses(); + }, true); + } // Refresh Courses List refreshCourses() { diff --git a/client/imports/ui/components/lablist/lablist.ts b/client/imports/ui/components/lablist/lablist.ts index 3a9581fd..f8f8f380 100644 --- a/client/imports/ui/components/lablist/lablist.ts +++ b/client/imports/ui/components/lablist/lablist.ts @@ -36,55 +36,55 @@ }) // Export LabList Class - export class LabList extends MeteorComponent { - user: Meteor.User; - courseId: String; // TODO: Get from URL - userId: String = '1'; // TODO: Get from Meteor.userId - labs: Array = []; - courseRecord; - - // Progress Bar Value - public determinateValue: number = 30; - - constructor(mdIconRegistry: MdIconRegistry) { - super(); - // Create Icon Font - mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); - mdIconRegistry.setDefaultFontSetClass('tuxicon'); - - this.setLab(this.courseId, this.userId); - } + export class LabList extends MeteorComponent { + user: Meteor.User; + courseId: String; // TODO: Get from URL + userId: String = '1'; // TODO: Get from Meteor.userId + labs: Array = []; + courseRecord; + + // Progress Bar Value + public determinateValue: number = 30; + + constructor(mdIconRegistry: MdIconRegistry) { + super(); + // Create Icon Font + mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); + mdIconRegistry.setDefaultFontSetClass('tuxicon'); + + this.setLab(this.courseId, this.userId); + } // Method to subscribe to course_records database and set Lab data - setLab(courseId: String, userId: String) { - this.subscribe('course-records', [courseId, userId], () => { - this.courseRecord = course_records.findOne({ user_id: userId }); //TODO: add course_id - if(this.courseRecord !== undefined) { - let labs = this.courseRecord.labs; - let totalCompleted = 0; - let totalNumTasks = 0; - for (let i = 0; i < labs.length; i++) { - let lab = labs[i]; - let tasksCompleted = 0; - let tasks = lab.tasks; - for (let j = 0; j < tasks.length; j++) { - let task = tasks[j]; - if (task.status === 'SUCCESS') { - tasksCompleted++; - } - } - this.labs.push({ - 'name': 'Lab ' + (i + 1).toString(), - 'completed': tasksCompleted.toString() + '/' + tasks.length.toString(), - 'date': lab.data.due_date - }); - totalCompleted += tasksCompleted; - totalNumTasks += tasks.length; - } - this.determinateValue = (totalCompleted * 100.0) / totalNumTasks; - } - }, true); - } + setLab(courseId: String, userId: String) { + this.subscribe('course-records', [courseId, userId], () => { + this.courseRecord = course_records.findOne({ user_id: userId }); //TODO: add course_id + if(this.courseRecord !== undefined) { + let labs = this.courseRecord.labs; + let totalCompleted = 0; + let totalNumTasks = 0; + for (let i = 0; i < labs.length; i++) { + let lab = labs[i]; + let tasksCompleted = 0; + let tasks = lab.tasks; + for (let j = 0; j < tasks.length; j++) { + let task = tasks[j]; + if (task.status === 'SUCCESS') { + tasksCompleted++; + } + } + this.labs.push({ + 'name': 'Lab ' + (i + 1).toString(), + 'completed': tasksCompleted.toString() + '/' + tasks.length.toString(), + 'date': lab.data.due_date + }); + totalCompleted += tasksCompleted; + totalNumTasks += tasks.length; + } + this.determinateValue = (totalCompleted * 100.0) / totalNumTasks; + } + }, true); + } // Link to lab function toLab(lab) { diff --git a/collections/course_records.ts b/collections/course_records.ts index 590454e6..8f5223ed 100644 --- a/collections/course_records.ts +++ b/collections/course_records.ts @@ -1,8 +1,7 @@ +import { Mongo } from 'meteor/mongo'; +import { Meteor } from 'meteor/meteor'; -import {Mongo} from 'meteor/mongo'; -import {Meteor} from 'meteor/meteor'; - -import {Roles} from './users.ts'; +import { Roles } from './users.ts'; export const course_records = new Mongo.Collection('course_records'); @@ -34,9 +33,19 @@ course_records.allow({ /* Schema */ declare var SimpleSchema: any; + if(Meteor.isServer) { Meteor.publish('course-records', function() { - return course_records.find(); + const options = { + + }; + const user = Meteor.users.findOne(this.userId); + if(user) { + return course_records.find({ user_id: this.userId }, options); + } + else { + return null; + } }); Meteor.startup(function() { var taskSchema = new SimpleSchema({ diff --git a/collections/courses.ts b/collections/courses.ts index 59ad79ba..25dad368 100644 --- a/collections/courses.ts +++ b/collections/courses.ts @@ -5,6 +5,8 @@ import { Roles } from './users.ts'; export const courses = new Mongo.Collection('courses'); +const MAX_COURSES = 4; + /** AUTHENTICATION **/ @@ -24,6 +26,14 @@ courses.allow({ declare var SimpleSchema: any; if (Meteor.isServer){ + Meteor.publish('courses', function() { + console.log(this.userId); + const options = { + sort: { course_number: 1 }, + limit: MAX_COURSES + }; + return courses.find({}, options); + }); Meteor.startup(function(){ var courseSchema = new SimpleSchema({ course_name: { diff --git a/tests/example_data/example_course.js b/tests/example_data/example_course.js index 1f8cb9cc..c3f0326f 100644 --- a/tests/example_data/example_course.js +++ b/tests/example_data/example_course.js @@ -8,6 +8,14 @@ var course_labfile = require('fs').readFileSync('./tests/example_data/example_la var course_obj = { course_number: "15-131", course_name: "Great Practical Ideas for Computer Scientists", + course_description: ` + Throughout your education as a Computer Scientist at Carnegie Mellon, + you will take courses on programming, theoretical ideas, logic, systems, etc. + As you progress, you will be expected to pick up the so-called “tools of the + trade.” This course is intended to help you learn what you need to know in a + friendly, low-stress, high-support way. We will discuss UNIX, LaTeX, + debugging and many other essential tools. + `, instructor_name: "Tom Cortina", file: course_labfile, labs: [ @@ -27,3 +35,111 @@ var course_obj = { } module.exports = course_obj; + + +// More Sample Data +/* +var myCourse1 = { + course_number: '15-122', + course_name: 'Principles of Imperative Programming', + course_description: ` + This course teaches imperative programming and methods for ensuring the correctness + of programs. It is intended for students with a basic understanding of programming + (variables, expressions, loops, arrays, functions). Students will learn the process + and concepts needed to go from high-level descriptions of algorithms to correct + imperative implementations, with specific applications to basic data structures + and algorithms. Much of the course will be conducted in a subset of C amenable + to verification, with a transition to full C near the end. + `, + instructor_name: 'Tom Cortina', + labs: [ + '574467bc11091623418a429d', + '574467bc110as623418a429d', + '574467bc11fab623418a429d' + ] +}; + +var myCourse2 = { + course_number: '15-131', + course_name: 'Great Practical Ideas for Computer Scientists', + course_description: ` + Throughout your education as a Computer Scientist at Carnegie Mellon, you will + take courses on programming, theoretical ideas, logic, systems, etc. As you progress, + you will be expected to pick up the so-called “tools of the trade.” This course is + intended to help you learn what you need to know in a friendly, low-stress, high-support + way. We will discuss UNIX, LaTeX, debugging and many other essential tools. + `, + instructor_name: 'Derek Brown', + labs: [ + '574467bc11091623418a429d', + '574467bc110as623418a429d', + '574467bc11fab623418a429d' + ] +}; + +var myCourse3 = { + course_number: '15-150', + course_name: 'Principles of Functional Programming', + course_description: ` + The purpose of this course is to introduce the theory and practice of functional + programming (FP). The characteristic feature of FP is the emphasis on computation + as evaluation. The traditional distinction between program and data characteristic of + imperative programming (IP) is replaced by an emphasis on classifying expressions by + types that specify their applicative behavior. Types include familiar (fixed and arbitrary + precision) numeric types, tuples and records (structs), classified values (objects), + inductive types such as trees, functions with specified inputs and outputs, and commands + such as input and output. Well-typed expressions are evaluated to produce values, + in a manner that is guaranteed to be type-safe. Because functional programs do not cause + side-effects we can take advantage of simple mathematical principles in reasoning about + applicative behavior and analyzing the runtime properties of programs. + `, + instructor_name: 'Michael Erdman', + labs: [ + '574467bc11091623418a429d', + '574467bc110as623418a429d', + '574467bc11fab623418a429d' + ] +}; + +var myCourse4 = { + course_number: '15-251', + course_name: 'Great Theoretical Ideas in Computer Science', + course_description: ` + Welcome to 15-251! This course will take a philosophical and historical perspective on + the development of theoretical computer science. From using a pile of stones to represent + and manipulate numbers, humans have progressively developed an abstract vocabulary with + which to mathematically represent their world. The ancients, especially the Greeks, + realized that they could consistently reason about their representations in a step-by-step + manner. In other words, by computing in abstract models, they could describe and + predict patterns in the world around them. + `, + instructor_name: 'Bernhard Haeupler', + labs: [ + '574467bc11091623418a429d', + '574467bc110as623418a429d', + '574467bc11fab623418a429d' + ] +}; + +var myCourse5 = { + course_number: '15-322', + course_name: 'Introduction to Computer Music', + course_description: ` + Computers are used to synthesize sound, process signals, and compose music. Personal + computers have replaced studios full of sound recording and processing equipment, + completing a revolution that began with recording and electronics. In this + course, students will learn the fundamentals of digital audio, basic sound + synthesis algorithms, and techniques for digital audio effects and processing. + Students will apply their knowledge in programming assignments using a very high-level + programming language for sound synthesis and composition. In a final project, + students will demonstrate their mastery of tools and techniques through a publicly + performed music composition. + `, + instructor_name: 'Jesse Styles', + labs: [ + '574467bc11091623418a429d', + '574467bc110as623418a429d', + '574467bc11fab623418a429d' + ] +}; +*/ From 5e1fd854ff51ba8d9446cd327b56b2f213216ad5 Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Thu, 7 Jul 2016 17:24:20 -0400 Subject: [PATCH 05/41] deleted swap file --- collections/.courses.ts.swp | Bin 12288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 collections/.courses.ts.swp diff --git a/collections/.courses.ts.swp b/collections/.courses.ts.swp deleted file mode 100644 index 739c884e550987078f257964cc6080b5cfac8645..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O>Y}T7{{lSizy+9et~IAm35S?TUrT}mr9l!s1I(WH~~}yVZA%9m#%kLGqY|h zHw6ihkSOAexO3nJ2X0(If+G@#9ylNn2M+K7IP#y_@!AQgh{~zxS?QPc&d&4ppJyyt znclgV+a3PAf05yOnz7^G-F>Cqe3pIt7-K3(BO%ow9t7bHAAARBM_?3XlS%04YEUkOHItDL@L40{;UAbbgGzjXLmi-(Hv8{n&xKd!!pFKnjoo zqyQ;E3XlS%04YEUkOHItDL@K5f(ir?V{<{oexDS2=-+)g*2HpY}z;APm{S3YW_rM3>J@76VfgP|7*1$>d%aia0 zJ_gsoc`y%tIKkNW;B)Xkcn6Gt0B?e8U=_@RzfjY!;6C^od@0&H}5! zBe;f?GATd`kOHItDL@L40{>Y7zVF&&=5epSYVVwTYe9PZk~^GP_XDkiaL^40ViGjvE7dQ&4R`|Gj-dn0ZPHak(YPgKLn-;^KkPl}X z43Wwt<|vSSwi3S1Q*o1b<6)i%S7|x7Beck*uXG@Fk$e3jwP#no`k2*frtTVU=1)xu zUC5NDMUvQ2ktl(H)%!++yD53mOJX%>xzn%xIE}p0)5J-coAT|eu?sT^SF0Ux5T{B= z?UtrA+DwHv=DTsU;_7TiSYQ{VmIyr^Ugx3ooxpKqQ?HeeTO!P41c#a2KnF~V4`scq z%zE0NjgzvIrPnjRRUP*Aj4m$zG`x!d8<&8bgfyDC0`wqOet{Bg4K~5J@0kIYMToP+ znwtSQatmgjrc%tfusOI%E^}|e>AkSTrweSGCGK<2O^#Jp$Pt2$8Tv93VG>BeO()H^ z%?iifS!Iny-fdmk=rs9agRyddlsm)qz*d&v;B%~AO0r&%G^1gh#!AaTXVUZnN3RUC z5n8rNs8nEyM_I^i6jMF+Te*1-xZUUQMfil3k9Mf@J9qdbb{n$EB1Fj9876pfK=At~q0o$V_dSGU`(=5~AY zDg<9-m}wfJ(|mQewYjs^-RPnpF0SIY=FMu4_-e z$NMrH@&(@=VV}IfN%jRSeuKB{-sY43Zd*Sy{_GOWxGCG!T2F(PjaSVY+OMKUc|({g OIlI^XG0kj1%=#PJcqvT) From bfaf8ce77099fce4e4426650c14972148724086d Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Thu, 7 Jul 2016 18:06:22 -0400 Subject: [PATCH 06/41] publish subscribe --- .../imports/ui/components/explore/explore.ts | 4 +- client/imports/ui/pages/account/account.html | 6 +- client/imports/ui/pages/account/account.ts | 4 - collections/course_records.ts | 6 +- collections/courses.ts | 19 ++- collections/labs.ts | 12 +- tests/example_data/example_course.js | 145 ------------------ 7 files changed, 19 insertions(+), 177 deletions(-) delete mode 100644 tests/example_data/example_course.js diff --git a/client/imports/ui/components/explore/explore.ts b/client/imports/ui/components/explore/explore.ts index cb47a2c1..d0a07ba3 100644 --- a/client/imports/ui/components/explore/explore.ts +++ b/client/imports/ui/components/explore/explore.ts @@ -29,12 +29,12 @@ selector: 'tuxlab-exploreview', templateUrl: '/client/imports/ui/components/explore/explore.html', directives: [ - MATERIAL_DIRECTIVES, + MATERIAL_DIRECTIVES, MD_ICON_DIRECTIVES, MD_TABS_DIRECTIVES, MD_INPUT_DIRECTIVES, MdToolbar - ], + ], viewProviders: [ MdIconRegistry ], encapsulation: ViewEncapsulation.None }) diff --git a/client/imports/ui/pages/account/account.html b/client/imports/ui/pages/account/account.html index 70bf2db5..647ede8f 100644 --- a/client/imports/ui/pages/account/account.html +++ b/client/imports/ui/pages/account/account.html @@ -5,9 +5,9 @@ diff --git a/client/imports/ui/pages/account/account.ts b/client/imports/ui/pages/account/account.ts index 274aae37..870ff580 100644 --- a/client/imports/ui/pages/account/account.ts +++ b/client/imports/ui/pages/account/account.ts @@ -39,10 +39,6 @@ @InjectUser("user") export class Account extends MeteorComponent { user: Meteor.User; - imgsrc: String = "http://www.placekitten.com/g/250/250"; - name: String = "Name Here"; - school: String = "School Name Here"; - email: String = "example@example.com"; constructor(mdIconRegistry: MdIconRegistry) { super(); // Create Icon Font diff --git a/collections/course_records.ts b/collections/course_records.ts index 7ca04dcc..97c4c9a2 100644 --- a/collections/course_records.ts +++ b/collections/course_records.ts @@ -35,11 +35,11 @@ declare var SimpleSchema: any; if(Meteor.isServer) { - Meteor.publish('course-records', function() { + Meteor.publish('course-records', function() { const user = Meteor.users.findOne(this.userId); if(user) { return course_records.find({ - user_id: '1' // Change to user_id: this.userId + user_id: this.userId }, { fields: { 'labs.data': 0, @@ -50,7 +50,7 @@ if(Meteor.isServer) { else { return null; } - }); + }); Meteor.startup(function() { var taskSchema = new SimpleSchema({ _id: { diff --git a/collections/courses.ts b/collections/courses.ts index 81089202..aa9df6b8 100644 --- a/collections/courses.ts +++ b/collections/courses.ts @@ -8,8 +8,6 @@ import { course_records } from './course_records.ts'; export const courses = new Mongo.Collection('courses'); -const MAX_COURSES = 4; - /** AUTHENTICATION **/ @@ -30,16 +28,17 @@ courses.allow({ if (Meteor.isServer){ Meteor.publish('courses', function() { - const user = Meteor.users.findOne(this.userId); - if(user) { + if(this.userId) { let courseRecords = course_records.find({ _id: this.userId }); - let publishCourses = new Mongo.Collection(null); - courseRecords.forEach(function(cr) { - let courseId = cr.course_id; - publishCourses.insert(courses.findOne({ _id: courseId })); + let courseIds = courseRecords.map(function(cr) { + return (cr).course_id; }); - return courses.find({}); - // return publishCourses.find(); + const query = { + '_id': { + $in: courseIds + } + }; + return courses.find(query); } else { return null; diff --git a/collections/labs.ts b/collections/labs.ts index d5704ba4..f6686075 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -27,16 +27,8 @@ labs.allow({ if(Meteor.isServer) { Meteor.publish('labs', function() { - const user = Meteor.users.findOne({ _id: this.userId }); - if(user) { - let publishLabs = new Mongo.Collection(null); - labs.forEach(function(lb) { - let lab = lb; - if (lab.hidden === false) { - publishLabs.insert(lb); - } - }); - return publishLabs.find(); + if(this.userId) { + return labs.find({ hidden: false }); } else { return null; diff --git a/tests/example_data/example_course.js b/tests/example_data/example_course.js deleted file mode 100644 index c3f0326f..00000000 --- a/tests/example_data/example_course.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - Example Data for the 15-131 -**/ - -// Import LabFile -var course_labfile = require('fs').readFileSync('./tests/example_data/example_labfile.js', "utf8").toString(); - -var course_obj = { - course_number: "15-131", - course_name: "Great Practical Ideas for Computer Scientists", - course_description: ` - Throughout your education as a Computer Scientist at Carnegie Mellon, - you will take courses on programming, theoretical ideas, logic, systems, etc. - As you progress, you will be expected to pick up the so-called “tools of the - trade.” This course is intended to help you learn what you need to know in a - friendly, low-stress, high-support way. We will discuss UNIX, LaTeX, - debugging and many other essential tools. - `, - instructor_name: "Tom Cortina", - file: course_labfile, - labs: [ - { - _id: 1, - lab_name: "Getting Started with Git", - file: course_labfile, - tasks: [ - { - _id: 1, - name: "Git Clone", - md: "Git Clone Testing!" - } - ] - } - ] -} - -module.exports = course_obj; - - -// More Sample Data -/* -var myCourse1 = { - course_number: '15-122', - course_name: 'Principles of Imperative Programming', - course_description: ` - This course teaches imperative programming and methods for ensuring the correctness - of programs. It is intended for students with a basic understanding of programming - (variables, expressions, loops, arrays, functions). Students will learn the process - and concepts needed to go from high-level descriptions of algorithms to correct - imperative implementations, with specific applications to basic data structures - and algorithms. Much of the course will be conducted in a subset of C amenable - to verification, with a transition to full C near the end. - `, - instructor_name: 'Tom Cortina', - labs: [ - '574467bc11091623418a429d', - '574467bc110as623418a429d', - '574467bc11fab623418a429d' - ] -}; - -var myCourse2 = { - course_number: '15-131', - course_name: 'Great Practical Ideas for Computer Scientists', - course_description: ` - Throughout your education as a Computer Scientist at Carnegie Mellon, you will - take courses on programming, theoretical ideas, logic, systems, etc. As you progress, - you will be expected to pick up the so-called “tools of the trade.” This course is - intended to help you learn what you need to know in a friendly, low-stress, high-support - way. We will discuss UNIX, LaTeX, debugging and many other essential tools. - `, - instructor_name: 'Derek Brown', - labs: [ - '574467bc11091623418a429d', - '574467bc110as623418a429d', - '574467bc11fab623418a429d' - ] -}; - -var myCourse3 = { - course_number: '15-150', - course_name: 'Principles of Functional Programming', - course_description: ` - The purpose of this course is to introduce the theory and practice of functional - programming (FP). The characteristic feature of FP is the emphasis on computation - as evaluation. The traditional distinction between program and data characteristic of - imperative programming (IP) is replaced by an emphasis on classifying expressions by - types that specify their applicative behavior. Types include familiar (fixed and arbitrary - precision) numeric types, tuples and records (structs), classified values (objects), - inductive types such as trees, functions with specified inputs and outputs, and commands - such as input and output. Well-typed expressions are evaluated to produce values, - in a manner that is guaranteed to be type-safe. Because functional programs do not cause - side-effects we can take advantage of simple mathematical principles in reasoning about - applicative behavior and analyzing the runtime properties of programs. - `, - instructor_name: 'Michael Erdman', - labs: [ - '574467bc11091623418a429d', - '574467bc110as623418a429d', - '574467bc11fab623418a429d' - ] -}; - -var myCourse4 = { - course_number: '15-251', - course_name: 'Great Theoretical Ideas in Computer Science', - course_description: ` - Welcome to 15-251! This course will take a philosophical and historical perspective on - the development of theoretical computer science. From using a pile of stones to represent - and manipulate numbers, humans have progressively developed an abstract vocabulary with - which to mathematically represent their world. The ancients, especially the Greeks, - realized that they could consistently reason about their representations in a step-by-step - manner. In other words, by computing in abstract models, they could describe and - predict patterns in the world around them. - `, - instructor_name: 'Bernhard Haeupler', - labs: [ - '574467bc11091623418a429d', - '574467bc110as623418a429d', - '574467bc11fab623418a429d' - ] -}; - -var myCourse5 = { - course_number: '15-322', - course_name: 'Introduction to Computer Music', - course_description: ` - Computers are used to synthesize sound, process signals, and compose music. Personal - computers have replaced studios full of sound recording and processing equipment, - completing a revolution that began with recording and electronics. In this - course, students will learn the fundamentals of digital audio, basic sound - synthesis algorithms, and techniques for digital audio effects and processing. - Students will apply their knowledge in programming assignments using a very high-level - programming language for sound synthesis and composition. In a final project, - students will demonstrate their mastery of tools and techniques through a publicly - performed music composition. - `, - instructor_name: 'Jesse Styles', - labs: [ - '574467bc11091623418a429d', - '574467bc110as623418a429d', - '574467bc11fab623418a429d' - ] -}; -*/ From 5123b2fd25118396736b4323cc94e2df480b9ecd Mon Sep 17 00:00:00 2001 From: Sander Shi Date: Fri, 8 Jul 2016 13:25:02 -0400 Subject: [PATCH 07/41] template fixes --- .../ui/components/explore/explore.html | 6 +- .../imports/ui/components/explore/explore.ts | 7 +- .../imports/ui/components/explore/search.html | 28 ++++--- .../imports/ui/components/explore/search.ts | 78 ++----------------- .../imports/ui/components/lablist/lablist.ts | 6 +- client/imports/ui/pages/account/account.html | 2 +- client/imports/ui/pages/course/course.ts | 52 +++++++------ client/imports/ui/pages/explore/explore.html | 4 +- client/index.html | 4 +- client/style/base/_body.scss | 12 ++- client/style/base/_toolbar.scss | 26 ++++--- client/style/dashboard/_dashboard.scss | 2 +- client/style/explore/_explore.scss | 21 ++--- client/tuxlab.html | 30 +++---- client/tuxlab.ts | 1 + collections/course_records.ts | 3 +- collections/courses.ts | 16 +++- public/assets | 2 +- 18 files changed, 123 insertions(+), 177 deletions(-) diff --git a/client/imports/ui/components/explore/explore.html b/client/imports/ui/components/explore/explore.html index b4028e99..77c81a5b 100644 --- a/client/imports/ui/components/explore/explore.html +++ b/client/imports/ui/components/explore/explore.html @@ -6,7 +6,7 @@