From d1a4d70da47d76c29d9deedac34d95ba9cb30025 Mon Sep 17 00:00:00 2001 From: Mathilde McKeever Date: Sat, 9 Jan 2021 13:15:45 -0800 Subject: [PATCH 01/80] First steps in adding the notes moddel and updating the api --- huxley/api/permissions.py | 8 ++++++ huxley/api/serializers/note.py | 12 ++++++++ huxley/api/urls.py | 6 ++++ huxley/api/views/__init__.py | 2 +- huxley/api/views/note.py | 44 +++++++++++++++++++++++++++++ huxley/core/admin/__init__.py | 1 + huxley/core/migrations/0047_note.py | 24 ++++++++++++++++ huxley/core/models.py | 36 +++++++++++++++++++++++ 8 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 huxley/api/serializers/note.py create mode 100644 huxley/api/views/note.py create mode 100644 huxley/core/migrations/0047_note.py diff --git a/huxley/api/permissions.py b/huxley/api/permissions.py index 851f9ed01..88f513fb4 100644 --- a/huxley/api/permissions.py +++ b/huxley/api/permissions.py @@ -331,6 +331,14 @@ def has_permission(self, request, view): return False +class NotePermission(permissions.BasePermission): + '''Accept requests to view Notes when user is not an advisor''' + def has_permission(self, request, view): + user = request.user + if not user.is_advisor(): + return True + return False + def user_is_advisor(request, view, school_id): user = request.user diff --git a/huxley/api/serializers/note.py b/huxley/api/serializers/note.py new file mode 100644 index 000000000..9faabc7ba --- /dev/null +++ b/huxley/api/serializers/note.py @@ -0,0 +1,12 @@ +# Copyright (c) 2011-2020 Berkeley Model United Nations. All rights reserved. +# Use of this source code is governed by a BSD License (see LICENSE). + +from rest_framework import serializers + +from huxley.core.models import Note + + +class NoteSerializer(serializers.ModelSerializer): + class Meta: + model = Rubric + fields = ('id', 'is_chair', 'sender', 'recipient', 'msg', 'timestamp') \ No newline at end of file diff --git a/huxley/api/urls.py b/huxley/api/urls.py index 9f647ea1b..5562a7238 100644 --- a/huxley/api/urls.py +++ b/huxley/api/urls.py @@ -89,6 +89,12 @@ url(r'^secretariat_member_committee/?$', views.secretariat_member.SecretariatMemberCommitteeList.as_view(), name='secretariat_member_committee_list'), + url(r'^notes/?$', + views.note.NoteList.as_view(), + name='note_list'), + url(r'^note/?$', + views.note.NoteDetail.as_view(), + name='note_detail') ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/huxley/api/views/__init__.py b/huxley/api/views/__init__.py index b3397bd75..d5ea180fe 100644 --- a/huxley/api/views/__init__.py +++ b/huxley/api/views/__init__.py @@ -1,4 +1,4 @@ # Copyright (c) 2011-2015 Berkeley Model United Nations. All rights reserved. # Use of this source code is governed by a BSD License (see LICENSE). -from huxley.api.views import assignment, committee, committee_feedback, country, delegate, school, user, position_paper, registration, register, rubric, secretariat_member +from huxley.api.views import assignment, committee, committee_feedback, country, delegate, school, user, position_paper, registration, register, rubric, secretariat_member, note diff --git a/huxley/api/views/note.py b/huxley/api/views/note.py new file mode 100644 index 000000000..e82a08908 --- /dev/null +++ b/huxley/api/views/note.py @@ -0,0 +1,44 @@ +# Copyright (c) 2011-2021 Berkeley Model United Nations. All rights reserved. +# Use of this source code is governed by a BSD License (see LICENSE). + +from rest_framework import generics, status +from rest_framework.authentication import SessionAuthentication +from rest_framework.response import Response + +from huxley.api.mixins import ListUpdateModelMixin +from huxley.api import permissions +from huxley.api.serializers import NoteSerializer +from huxley.core.models import Note + + +class NoteList(generics.ListCreateAPIView): + authentication_classes = (SessionAuthentication, ) + permission_classes = (permissions.NotePermission, ) + serializer_class = NoteSerializer + + def get_queryset(self): + queryset = Note.objects.all() + query_params = self.request.GET + sender = query_params.get('sender', None) + recipient = query_params.get('recipient', None) + + committee_id = query_params.get('committee_id', None) + if committee_id: + queryset = queryset.filter(sender__committee_id=committee_id) | + queryset.filter(recipient__committee_id=committee_id) + + + if sender and recipient: + queryset = queryset.filter(sender_id = sender).filter(recipient_id = recipient) | + queryset.filter(sender_id = recipient).filter(recipient_id = sender) + + + return queryset + + +class NoteDetail(generics.CreateAPIView, generics.RetrieveAPIView): + authentication_classes = (SessionAuthentication, ) + queryset = Note.objects.all() + permission_classes = (permissions.NotePermission, ) + serializer_class = NoteSerializer + diff --git a/huxley/core/admin/__init__.py b/huxley/core/admin/__init__.py index c8fbea61e..1fa53a005 100644 --- a/huxley/core/admin/__init__.py +++ b/huxley/core/admin/__init__.py @@ -27,3 +27,4 @@ admin.site.register(Rubric) admin.site.register(PositionPaper, PositionPaperAdmin) admin.site.register(SecretariatMember, SecretariatMemberAdmin) +admin.site.register(Note) \ No newline at end of file diff --git a/huxley/core/migrations/0047_note.py b/huxley/core/migrations/0047_note.py new file mode 100644 index 000000000..be2594c8c --- /dev/null +++ b/huxley/core/migrations/0047_note.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.6 on 2021-01-09 12:09 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0046_auto_20200919_1744'), + ] + + operations = [ + migrations.CreateModel( + name='Note', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_chair', models.SmallIntegerField(choices=[(0, 0), (1, 1), (2, 2)], default=0)), + ('msg', models.CharField(max_length=1000)), + ('recipient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.Assignment')), + ('sender', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.Assignment')), + ], + ), + ] diff --git a/huxley/core/models.py b/huxley/core/models.py index a0e1e06b6..eb32147ac 100644 --- a/huxley/core/models.py +++ b/huxley/core/models.py @@ -685,3 +685,39 @@ class SecretariatMember(models.Model): def __str__(self): return self.name + +class Note(models.Model): + """Note objects allow delegates to send and receive notes over Huxley.""" + + #TODO add an export of notes so can reference note content later should there be any legal issues. + + #is_chair - 0: Between two Assignments, 1: Sender is Chair, 2: Recipient is Chair + is_chair = models.SmallIntegerField(default= 0, choices = ((0, 0), (1, 1), (2, 2))) + sender = models.ForeignKey(Assignment, on_delete=models.CASCADE, null=True, blank=True, related_name = '+') + recipient = models.ForeignKey(Assignment, on_delete=models.CASCADE, null=True, blank=True, related_name = '+') + msg = models.CharField(max_length = 1000) + timestamp = models.DateTimeField(auto_now_add=True) + + def __str__(self): + if self.is_chair == 0: + committee = str(self.sender.committee) + sender = str(self.sender.country) + recipient = str(self.recipient.country) + + else if self.is_chair == 1: + committee = str(self.recipient.committee) + sender = 'Chair' + recipient = str(self.recipient.country) + + else: + committee = str(self.sender.committee) + sender = str(self.sender.country) + recipient = 'Chair' + + + return committee + ": " sender + ' -> ' + recipient + ' - ' + self.id + + class Meta: + db_table = u'note' + ordering = ['timestamp'] + \ No newline at end of file From 0fbc4338328dbd0228183e80fe09c0c64ca31b31 Mon Sep 17 00:00:00 2001 From: Shayna Kothari Date: Mon, 11 Jan 2021 00:46:44 -0800 Subject: [PATCH 02/80] packages updated, but site doesn't display --- huxley/www/js/css/Button.less | 10 ++-- huxley/www/js/css/IEWarning.less | 4 +- huxley/www/js/css/JSWarning.less | 4 +- huxley/www/js/css/NavLink.less | 8 +-- huxley/www/js/css/base.less | 2 +- huxley/www/js/css/content.less | 8 +-- package.json | 96 +++++++++++++---------------- webpack.config.js | 100 ++++++++++++++++++------------- 8 files changed, 117 insertions(+), 115 deletions(-) diff --git a/huxley/www/js/css/Button.less b/huxley/www/js/css/Button.less index 142c1789a..5c3819476 100644 --- a/huxley/www/js/css/Button.less +++ b/huxley/www/js/css/Button.less @@ -57,7 +57,7 @@ @blue-shadow: darken(@blue, 5%); background-color: @blue; - background-image: url(/static/img/button-loading-blue.gif); + background-image: url(../..//static/img/button-loading-blue.gif); border-color: @blue-shadow; color: #fff; text-shadow: @blue-shadow 0px 1px; @@ -72,7 +72,7 @@ @green-shadow: darken(@green, 5%); background-color: @green; - background-image: url(/static/img/button-loading-green.gif); + background-image: url(../..//static/img/button-loading-green.gif); border-color: @green-shadow; color: #fff; text-shadow: @green-shadow 0px 1px; @@ -101,7 +101,7 @@ @red-shadow: darken(@red, 5%); background-color: @red; - background-image: url(/static/img/loading.gif); + background-image: url(../..//static/img/loading.gif); border-color: @red-shadow; color: #fff; text-shadow: @red-shadow 0px 1px; @@ -144,12 +144,12 @@ only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { .button { &.button-blue { - background-image: url(/static/img/button-loading-blue-2x.gif); + background-image: url(../..//static/img/button-loading-blue-2x.gif); background-size: 20px 20px; } &.button-green { - background-image: url(/static/img/button-loading-green-2x.gif); + background-image: url(../..//static/img/button-loading-green-2x.gif); background-size: 20px 20px; } } diff --git a/huxley/www/js/css/IEWarning.less b/huxley/www/js/css/IEWarning.less index 004c8194f..fe3e02c57 100644 --- a/huxley/www/js/css/IEWarning.less +++ b/huxley/www/js/css/IEWarning.less @@ -3,7 +3,7 @@ border-bottom: 1px solid #6ae; .banner { - background: url(/static/img/ie50.png) left center no-repeat; + background: url(../..//static/img/ie50.png) left center no-repeat; color: #005; text-shadow: 0px 1px #8cf; @@ -23,7 +23,7 @@ only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { .banner-wrapper.ie-warning { .banner { - background-image: url(/static/img/ie-2x.png); + background-image: url(../..//static/img/ie-2x.png); background-size: 50px 50px; } } diff --git a/huxley/www/js/css/JSWarning.less b/huxley/www/js/css/JSWarning.less index 15a38e703..3ac67b1ef 100644 --- a/huxley/www/js/css/JSWarning.less +++ b/huxley/www/js/css/JSWarning.less @@ -3,7 +3,7 @@ border-bottom: 1px solid #c66; .banner { - background: url(/static/img/js.png) left center no-repeat; + background: url(../..//static/img/js.png) left center no-repeat; color: #400; text-shadow: 0px 1px #ffc0c0; @@ -22,7 +22,7 @@ only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { .banner-wrapper.js-warning { .banner { - background-image: url(/static/img/js-2x.png); + background-image: url(../..//static/img/js-2x.png); background-size: 50px 50px; } } diff --git a/huxley/www/js/css/NavLink.less b/huxley/www/js/css/NavLink.less index 6330df1a5..376fef05e 100644 --- a/huxley/www/js/css/NavLink.less +++ b/huxley/www/js/css/NavLink.less @@ -18,12 +18,12 @@ a.nav-link { &:active, &:visited { outline: 0; } &.arrow-left { - background: url(/static/img/arrow-left.png) left center no-repeat; + background: url(../..//static/img/arrow-left.png) left center no-repeat; padding-left: 18px; } &.arrow-right { - background: url(/static/img/arrow-right.png) right center no-repeat; + background: url(../..//static/img/arrow-right.png) right center no-repeat; padding-right: 18px; } } @@ -37,12 +37,12 @@ only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { a.nav-link { &.arrow-left { - background-image: url(/static/img/arrow-left-2x.png); + background-image: url(../..//static/img/arrow-left-2x.png); background-size: 14px 14px; } &.arrow-right { - background-image: url(/static/img/arrow-right-2x.png); + background-image: url(../..//static/img/arrow-right-2x.png); background-size: 14px 14px; } } diff --git a/huxley/www/js/css/base.less b/huxley/www/js/css/base.less index a157c47bd..e66bd23fe 100644 --- a/huxley/www/js/css/base.less +++ b/huxley/www/js/css/base.less @@ -10,7 +10,7 @@ html { } body { - background: #000 url(/static/img/berkeley.jpg) center -165px no-repeat fixed; + background: #000 url(../../static/img/berkeley.jpg) center -165px no-repeat fixed; font-family: @font-family; text-align: center; } diff --git a/huxley/www/js/css/content.less b/huxley/www/js/css/content.less index f3607b0a7..fd353ac76 100644 --- a/huxley/www/js/css/content.less +++ b/huxley/www/js/css/content.less @@ -85,13 +85,13 @@ .logo { padding-top: 202px; - background: url(/static/img/logo.png) center top no-repeat; + background: url(../..//static/img/logo.png) center top no-repeat; text-align: center; } .logo-small { padding: 16px 0; - background: url(/static/img/logo-small.png) center center no-repeat; + background: url(../..//static/img/logo-small.png) center center no-repeat; text-align: center; } @@ -114,12 +114,12 @@ only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { .content-outer { .logo { - background: url(/static/img/logo-2x.png) center top no-repeat; + background: url(../..//static/img/logo-2x.png) center top no-repeat; background-size: 200px 202px; } .logo-small { - background: url(/static/img/logo-small-2x.png) center center no-repeat; + background: url(../..//static/img/logo-small-2x.png) center center no-repeat; background-size: 32px 32px; } } diff --git a/package.json b/package.json index ce46b0e3a..f455de1aa 100644 --- a/package.json +++ b/package.json @@ -5,72 +5,58 @@ "main": "huxley/www/static/js/huxley.browserify.js", "license": "BSD", "dependencies": { - "classnames": "2.2.5", - "fbjs": "0.8.3", - "flux": "^2.1.1", - "history": "^1.12.0", - "js-cookie": "~2.0.3", - "react": "15.0.0", - "react-dom": "15.0.0", - "react-modal": "1.4.0", - "react-router": "1.0.0", - "whatwg-fetch": "^2.0.3" + "fbjs": "^3.0.0", + "flux": "^4.0.1", + "react": "^17.0.0", + "react-dom": "^17.0.0", + "react-modal": "^3.12.1", + "react-router": "^5.2.0", + "style-loader": "^2.0.0" }, "scripts": { "test": "jest", - "build": "./node_modules/.bin/webpack --progress --watch" - }, - "jest": { - "scriptPreprocessor": "/node_modules/babel-jest", - "setupTestFrameworkScriptFile": "/scripts/jestPreprocessor.js", - "unmockedModulePathPatterns": [ - "node_modules/babel-core", - "node_modules/core-js", - "/node_modules/flux", - "/node_modules/react", - "/node_modules/es6-promise" - ], - "moduleDirectories": [ - "node_modules", - "/huxley/www/js" - ], - "testPathIgnorePatterns": [ - "/node_modules/", - "huxley/static" - ] + "build": "NODE_ENV=production ./node_modules/.bin/webpack --progress --watch", + "develop": "NODE_ENV=development ./node_modules/.bin/webpack --progress --watch", + "clean": "rm -rf ./node_modules" }, "private": true, "devDependencies": { - "babel-core": "^6.13.2", - "babel-jest": "^14.1.0", - "babel-loader": "^7.0.0", - "babel-plugin-transform-object-rest-spread": "^6.16.0", - "babel-polyfill": "^6.16.0", - "babel-preset-es2015": "^6.13.2", - "babel-preset-es2017": "^6.16.0", - "babel-preset-react": "^6.11.1", - "check-dependencies": "^1.0.1", - "core-js": "^2.4.1", - "css-loader": "^0.28.0", - "extract-text-webpack-plugin": "^2.1.0", - "html-loader": "^0.4.5", - "jest-cli": "~14.1.0", - "less": "^2.7.2", - "less-loader": "^4.0.3", - "markdown-loader": "^2.0.0", - "prettier": "^1.5.3", - "style-loader": "^0.16.1", - "uglify-js": "~2.6.0", - "webpack": "^2.4.1" + "@babel/core": "^7.12.10", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/preset-env": "^7.12.11", + "@babel/preset-react": "^7.12.10", + "babel-loader": "^8.2.2", + "buffer": "^6.0.3", + "check-dependencies": "^1.1.0", + "classnames": "^2.2.6", + "core-js": "^2.6.12", + "crypto-browserify": "^3.12.0", + "css-loader": "^5.0.1", + "history": "^5.0.0", + "html-loader": "^1.3.2", + "jest": "^26.6.3", + "jest-cli": "^26.6.3", + "js-cookie": "^2.2.1", + "less": "^4.1.0", + "less-loader": "^7.2.1", + "markdown-loader": "^6.0.0", + "mini-css-extract-plugin": "^1.3.3", + "path-browserify": "^1.0.1", + "prettier": "^2.2.1", + "stream-browserify": "^3.0.0", + "uglify-js": "^3.12.4", + "url-loader": "^4.1.1", + "webpack": "^5.12.3", + "webpack-cli": "^4.3.1", + "whatwg-fetch": "^3.5.0" }, "babel": { "presets": [ - "es2015", - "es2017", - "react" + "@babel/preset-env", + "@babel/preset-react" ], "plugins": [ - "transform-object-rest-spread" + "@babel/plugin-proposal-object-rest-spread" ] } } diff --git a/webpack.config.js b/webpack.config.js index 8582f962c..ea08c4ef0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,45 +1,30 @@ -var path = require('path'); -var webpack = require('webpack'); +var path = require("path"); +var webpack = require("webpack"); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const TerserPlugin = require("terser-webpack-plugin"); -var package = require('./package.json'); +var package = require("./package.json"); -var JS_ROOT = path.join(__dirname, 'huxley/www/js'); -var STATIC_ROOT = path.join(__dirname, 'huxley/www/static/js'); +var JS_ROOT = path.join(__dirname, "huxley/www/js"); +var STATIC_ROOT = path.join(__dirname, "huxley/www/static/js"); const marked = require("marked"); const renderer = new marked.Renderer(); var plugins = [ - new webpack.EnvironmentPlugin([ - 'NODE_ENV', - ]), - new ExtractTextPlugin('huxley.css'), - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - filename: 'vendor.js', - }), + new webpack.EnvironmentPlugin(["NODE_ENV"]), + new MiniCssExtractPlugin({ filename: "huxley.css" }), ]; -if (process.env.NODE_ENV === 'production') { - plugins.push( - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false, - }, - mangle: true, - }) - ); -} module.exports = { entry: { - huxley: path.join(JS_ROOT, 'entry.js'), + huxley: path.join(JS_ROOT, "entry.js"), vendor: Object.keys(package.dependencies), }, output: { path: STATIC_ROOT, - filename: '[name].js', + filename: "[name].js", }, module: { rules: [ @@ -47,41 +32,72 @@ module.exports = { test: /\.js$/, exclude: /node_modules/, use: { - loader: 'babel-loader', + loader: "babel-loader", options: { - plugins: ['transform-object-rest-spread'], - presets: ['es2015', 'es2017', 'react'], - } + plugins: ["@babel/plugin-proposal-object-rest-spread"], + presets: ["@babel/preset-env", "@babel/preset-react"], + }, }, }, { test: /\.less$/, exclude: /node_modules/, - use: ExtractTextPlugin.extract({ - use: [ - {loader: 'css-loader'}, - {loader: 'less-loader'}, - ], - fallback: 'style-loader', - }), + use: [ + MiniCssExtractPlugin.loader, + "css-loader", + "less-loader", + ], }, { test: /\.md$/, use: [ - {loader: "html-loader"}, + { loader: "html-loader" }, { loader: "markdown-loader", options: { pedantic: true, - renderer - } - } + renderer, + }, + }, + ], + }, + { + test: /\.(png|svg|jpg|jpeg|gif)$/i, + exclude: /node_modules/, + use: [ + {loader: "url-loader"}, ] }, ], }, plugins: plugins, resolve: { - modules: ['node_modules', JS_ROOT], + modules: ["node_modules", JS_ROOT], + fallback: { + "path": require.resolve("path-browserify"), + "crypto": require.resolve("crypto-browserify"), + "buffer": require.resolve("buffer/"), + "stream": require.resolve("stream-browserify") + } + }, + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + extractComments: false, + }), + ] }, + // optimization: { + // runtimeChunk: "single", // enable "runtime" chunk + // splitChunks: { + // cacheGroups: { + // vendor: { + // test: /[\\/]node_modules[\\/]/, + // chunks: "all", + // }, + // }, + // }, + // }, + mode: process.env.NODE_ENV, }; From aaeac9d2df95e7218cfc26ff1cb336a708995ff2 Mon Sep 17 00:00:00 2001 From: Mathilde McKeever Date: Mon, 11 Jan 2021 14:40:37 -0800 Subject: [PATCH 03/80] notes try a message box --- .flowconfig | 11 +++ huxley/api/serializers/__init__.py | 1 + huxley/api/serializers/note.py | 2 +- huxley/api/views/note.py | 21 +++--- huxley/core/models.py | 5 +- huxley/www/js/actions/NoteActions.js | 27 +++++++ huxley/www/js/components/DelegateNoteView.js | 55 ++++++++++++++ huxley/www/js/components/DelegateView.js | 1 + huxley/www/js/components/NoteMessageBox.js | 37 ++++++++++ huxley/www/js/constants/ActionConstants.js | 2 + huxley/www/js/entry.js | 2 + huxley/www/js/lib/ServerAPI.js | 17 +++++ huxley/www/js/stores/NoteStore.js | 75 ++++++++++++++++++++ package.json | 10 ++- 14 files changed, 253 insertions(+), 13 deletions(-) create mode 100644 .flowconfig create mode 100644 huxley/www/js/actions/NoteActions.js create mode 100644 huxley/www/js/components/DelegateNoteView.js create mode 100644 huxley/www/js/components/NoteMessageBox.js create mode 100644 huxley/www/js/stores/NoteStore.js diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 000000000..1fed44533 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,11 @@ +[ignore] + +[include] + +[libs] + +[lints] + +[options] + +[strict] diff --git a/huxley/api/serializers/__init__.py b/huxley/api/serializers/__init__.py index 2db53d4f6..3027f9493 100644 --- a/huxley/api/serializers/__init__.py +++ b/huxley/api/serializers/__init__.py @@ -12,3 +12,4 @@ from .position_paper import PositionPaperSerializer from .rubric import RubricSerializer from .secretariat_member import SecretariatMemberSerializer +from .note import NoteSerializer \ No newline at end of file diff --git a/huxley/api/serializers/note.py b/huxley/api/serializers/note.py index 9faabc7ba..30b5e1b2c 100644 --- a/huxley/api/serializers/note.py +++ b/huxley/api/serializers/note.py @@ -8,5 +8,5 @@ class NoteSerializer(serializers.ModelSerializer): class Meta: - model = Rubric + model = Note fields = ('id', 'is_chair', 'sender', 'recipient', 'msg', 'timestamp') \ No newline at end of file diff --git a/huxley/api/views/note.py b/huxley/api/views/note.py index e82a08908..c5560e8de 100644 --- a/huxley/api/views/note.py +++ b/huxley/api/views/note.py @@ -19,20 +19,25 @@ class NoteList(generics.ListCreateAPIView): def get_queryset(self): queryset = Note.objects.all() query_params = self.request.GET - sender = query_params.get('sender', None) - recipient = query_params.get('recipient', None) + sender_id = query_params.get('sender_id', None) + recipient_id = query_params.get('recipient_id', None) + chair = query_params.get('chair', None) committee_id = query_params.get('committee_id', None) if committee_id: - queryset = queryset.filter(sender__committee_id=committee_id) | - queryset.filter(recipient__committee_id=committee_id) + queryset = queryset.filter(sender__committee_id=committee_id) | queryset.filter( + recipient__committee_id=committee_id) - if sender and recipient: - queryset = queryset.filter(sender_id = sender).filter(recipient_id = recipient) | - queryset.filter(sender_id = recipient).filter(recipient_id = sender) + if sender_id and recipient_id: + queryset = queryset.filter(sender_id = sender_id).filter(recipient_id = recipient_id) | queryset.filter( + sender_id = recipient_id).filter(recipient_id = sender_id) - + if sender_id and chair: + queryset = queryset.filter(sender_id = sender_id).filter(is_chair = 2) | queryset.filter( + is_chair = 1).filter(recipient_id = sender_id) + + return queryset diff --git a/huxley/core/models.py b/huxley/core/models.py index eb32147ac..0559c7546 100644 --- a/huxley/core/models.py +++ b/huxley/core/models.py @@ -699,12 +699,13 @@ class Note(models.Model): timestamp = models.DateTimeField(auto_now_add=True) def __str__(self): + committee, sender, recipient = "", "", "" if self.is_chair == 0: committee = str(self.sender.committee) sender = str(self.sender.country) recipient = str(self.recipient.country) - else if self.is_chair == 1: + elif self.is_chair == 1: committee = str(self.recipient.committee) sender = 'Chair' recipient = str(self.recipient.country) @@ -715,7 +716,7 @@ def __str__(self): recipient = 'Chair' - return committee + ": " sender + ' -> ' + recipient + ' - ' + self.id + return committee + ": " + sender + ' -> ' + recipient + ' - ' + self.id class Meta: db_table = u'note' diff --git a/huxley/www/js/actions/NoteActions.js b/huxley/www/js/actions/NoteActions.js new file mode 100644 index 000000000..fbe5033a3 --- /dev/null +++ b/huxley/www/js/actions/NoteActions.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2011-2021 Berkeley Model United Nations. All rights reserved. + * Use of this source code is governed by a BSD License (see LICENSE). + */ + +'use strict'; + +var ActionConstants = require('constants/ActionConstants'); +var Dispatcher = require('dispatcher/Dispatcher'); + +var NoteActions = { + addNote(Note) { + Dispatcher.dispatch({ + actionType: ActionConstants.ADD_NOTE, + note: note, + }); + }, + + notesFetched(notes) { + Dispatcher.dispatch({ + actionType: ActionConstants.NOTES_FETCHED, + notes: notes, + }); + }, +}; + +module.exports = NoteActions; diff --git a/huxley/www/js/components/DelegateNoteView.js b/huxley/www/js/components/DelegateNoteView.js new file mode 100644 index 000000000..fa7e989bb --- /dev/null +++ b/huxley/www/js/components/DelegateNoteView.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2011-2021 Berkeley Model United Nations. All rights reserved. + * Use of this source code is governed by a BSD License (see LICENSE). + +*/ + + 'use strict'; + + var React = require('react'); + var ReactRouter = require('react-router'); + + var Button = require('components/core/Button'); + var ConferenceContext = require('components/ConferenceContext'); + var CurrentUserStore = require('stores/CurrentUserStore'); + var InnerView = require('components/InnerView'); + var TextTemplate = require('components/core/TextTemplate'); + var User = require('utils/User'); + var NoteMessageBox = require('components/NoteMessageBox') + + + var ServerAPI = require('lib/ServerAPI'); + + var DelegateNoteView = React.createClass({ + mixins: [ReactRouter.History], + + contextTypes: { + conference: React.PropTypes.shape(ConferenceContext), + }, + +// getInitialState() { + +// }, + + componentWillMount() { + var user = CurrentUserStore.getCurrentUser(); + if (!User.isDelegate(user)) { + this.history.pushState(null, '/'); + } + }, + +// componentDidMount() { + +// }, + +// componentWillUnmount() { +// }, + + render() { + return ; + }, + + + }); + + module.exports = DelegateNoteView; + \ No newline at end of file diff --git a/huxley/www/js/components/DelegateView.js b/huxley/www/js/components/DelegateView.js index c59a0f88f..d7527cb74 100644 --- a/huxley/www/js/components/DelegateView.js +++ b/huxley/www/js/components/DelegateView.js @@ -22,6 +22,7 @@ var DelegateView = React.createClass({
Profile Paper + Notes Committee Feedback diff --git a/huxley/www/js/components/NoteMessageBox.js b/huxley/www/js/components/NoteMessageBox.js new file mode 100644 index 000000000..3c4273c35 --- /dev/null +++ b/huxley/www/js/components/NoteMessageBox.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2011-2021 Berkeley Model United Nations. All rights reserved. + * Use of this source code is governed by a BSD License (see LICENSE). + */ + +//@flow + +'use strict'; + +const Button = require('components/core/Button'); +const TextTemplate = require('components/core/TextTemplate'); + + +const cx = require('classnames'); +const React = require('react'); +type NoteMessageBoxProps = { + conversation: Array, + user_assignment: number +} + +class NoteMessageBox extends React.Component { + + render(): any { + return this.props.conversation.map(note => (note.sender === this.props.user_assignment) ? this.renderSent(note.msg) : this.renderReceived(note.msg)); + } + + renderReceived(msg: string): any { + return
{msg}
; + } + + renderSent(msg: string): any { + return
{msg}
; + } + +} + +module.exports = NoteMessageBox; diff --git a/huxley/www/js/constants/ActionConstants.js b/huxley/www/js/constants/ActionConstants.js index 3832e89d8..38b2e39d1 100644 --- a/huxley/www/js/constants/ActionConstants.js +++ b/huxley/www/js/constants/ActionConstants.js @@ -35,4 +35,6 @@ module.exports = { RUBRIC_FETCHED: 'RUBRIC_FETCHED', STORE_PAPER: 'STORE_PAPER', SECRETARIAT_MEMBERS_FETCHED: 'SECRETARIAT_MEMBERS_FETCHED', + ADD_NOTE: 'ADD_NOTE', + NOTES_FETCHED: 'NOTES_FETCHED', }; diff --git a/huxley/www/js/entry.js b/huxley/www/js/entry.js index 51193411e..2fc2ccb59 100644 --- a/huxley/www/js/entry.js +++ b/huxley/www/js/entry.js @@ -28,6 +28,7 @@ var ChairSummaryView = require('components/ChairSummaryView'); var DelegateCommitteeFeedbackView = require('components/DelegateCommitteeFeedbackView'); var DelegatePaperView = require('components/DelegatePaperView'); var DelegateProfileView = require('components/DelegateProfileView'); +var DelegateNoteView = require('components/DelegateNoteView'); var ForgotPasswordView = require('components/ForgotPasswordView'); var LoginView = require('components/LoginView'); var NotFoundView = require('components/NotFoundView'); @@ -77,6 +78,7 @@ var routes = ( /> + diff --git a/huxley/www/js/lib/ServerAPI.js b/huxley/www/js/lib/ServerAPI.js index 7ddfa1b3e..e7fa9f82d 100644 --- a/huxley/www/js/lib/ServerAPI.js +++ b/huxley/www/js/lib/ServerAPI.js @@ -184,6 +184,23 @@ var ServerAPI = { updateRubric(rubric) { return _patch(`api/rubrics/${rubric.id}`, rubric); }, + + createNote(is_chair, sender, recipient, msg) { + return _post('api/note', {is_chair, sender, school, recipient, msg}) + }, + + getNotesByCommittee(committee_id) { + return _get('api/notes', {committee_id}) + }, + + getNotesByConversation(sender_id, recipient_id) { + return _get('api/notes', {sender_id, recipient_id}) + }, + + getNotesByConversationWithChair(sender_id) { + return _get('api/notes', {sender_id, chair:true}) + }, + }; function _encodeQueryString(params) { diff --git a/huxley/www/js/stores/NoteStore.js b/huxley/www/js/stores/NoteStore.js new file mode 100644 index 000000000..1b83d2cc8 --- /dev/null +++ b/huxley/www/js/stores/NoteStore.js @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2011-2021 Berkeley Model United Nations. All rights reserved. + * Use of this source code is governed by a BSD License (see LICENSE). + */ + +'use strict'; + +var ActionConstants = require('constants/ActionConstants'); +var CurrentUserStore = require('stores/CurrentUserStore'); +var NoteActions = require('actions/NoteActions'); +var Dispatcher = require('dispatcher/Dispatcher'); +var ServerAPI = require('lib/ServerAPI'); +var {Store} = require('flux/utils'); + +var _notes = {}; +var _notesFetched = false; +var _previousUserID = -1; + +class NoteStore extends Store { + getCommitteeNotes(committeeID) { + var noteIDs = Object.keys(_notes); + if (!_notesFetched) { + ServerAPI.getNotesByCommitteee(committeeID).then(value => { + NoteActions.notesFetched(value); + }); + + return []; + } + + return noteIDs.map(id => _notes[id]); + } + + getConversationNotes(senderID, recipientID, chair) { + var noteIDs = Object.keys(_notes); + if (!_notesFetched) { + if (chair) { + ServerAPI.geteNotesByConversationWithChair(senderID).then(value => { + NoteActions.notesFetched(value); + }); + } else { + ServerAPI.getNotesByConversation(senderID, recipientID).then(value => { + NoteActions.notesFetched(value); + }); + } + + return []; + } + + return noteIDs.map(id => _notes[id]); + } + + addNote(note) { + _notes[note.id] = note; + } + + __onDispatch(action) { + switch (action.actionType) { + case ActionConstants.ADD_NOTE: + this.addNote(action.note); + break; + case ActionConstants.NOTES_FETCHED: + for (const note of action.notes) { + _notes[note.id] = note; + } + _notesFetched = true; + break; + default: + return; + } + + this.__emitChange(); + } +} + +module.exports = new NoteStore(Dispatcher); diff --git a/package.json b/package.json index ce46b0e3a..31242c49e 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ }, "scripts": { "test": "jest", - "build": "./node_modules/.bin/webpack --progress --watch" + "build": "./node_modules/.bin/webpack --progress --watch", + "flow": "flow" }, "jest": { "scriptPreprocessor": "/node_modules/babel-jest", @@ -41,6 +42,9 @@ }, "private": true, "devDependencies": { + "@babel/cli": "^7.12.10", + "@babel/core": "^7.12.10", + "@babel/preset-flow": "^7.12.1", "babel-core": "^6.13.2", "babel-jest": "^14.1.0", "babel-loader": "^7.0.0", @@ -53,6 +57,7 @@ "core-js": "^2.4.1", "css-loader": "^0.28.0", "extract-text-webpack-plugin": "^2.1.0", + "flow-bin": "^0.142.0", "html-loader": "^0.4.5", "jest-cli": "~14.1.0", "less": "^2.7.2", @@ -67,7 +72,8 @@ "presets": [ "es2015", "es2017", - "react" + "react", + "@babel/preset-flow" ], "plugins": [ "transform-object-rest-spread" From b19179a4b7be25f7fe4f07de9f767768e01d3d9b Mon Sep 17 00:00:00 2001 From: Shayna Kothari Date: Mon, 11 Jan 2021 14:54:06 -0800 Subject: [PATCH 04/80] advisor view migrations --- .../js/components/AdvisorAssignmentsView.js | 66 +++++++------- .../www/js/components/AdvisorFeedbackView.js | 38 ++++---- huxley/www/js/components/AdvisorPaperView.js | 63 +++++++------- .../www/js/components/AdvisorProfileView.js | 47 +++++----- huxley/www/js/components/AdvisorRosterView.js | 86 +++++++++---------- huxley/www/js/components/AdvisorView.js | 22 +++-- 6 files changed, 161 insertions(+), 161 deletions(-) diff --git a/huxley/www/js/components/AdvisorAssignmentsView.js b/huxley/www/js/components/AdvisorAssignmentsView.js index a77725219..fcd7c9cf6 100644 --- a/huxley/www/js/components/AdvisorAssignmentsView.js +++ b/huxley/www/js/components/AdvisorAssignmentsView.js @@ -6,7 +6,6 @@ 'use strict'; var React = require('react'); -var ReactRouter = require('react-router'); var _accessSafe = require('utils/_accessSafe'); var AssignmentActions = require('actions/AssignmentActions'); @@ -31,14 +30,9 @@ var TextTemplate = require('components/core/TextTemplate'); var AdvisorAssignmentsViewText = require('text/AdvisorAssignmentsViewText.md'); var AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); -var AdvisorAssignmentsView = React.createClass({ - mixins: [ReactRouter.History], +class AdvisorAssignmentsView extends React.Component { - contextTypes: { - conference: React.PropTypes.shape(ConferenceContext), - }, - - getInitialState: function() { + getInitialState() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var delegates = DelegateStore.getSchoolDelegates(schoolID); var assigned = this.prepareAssignedDelegates(delegates); @@ -55,9 +49,9 @@ var AdvisorAssignmentsView = React.createClass({ success: false, registration: RegistrationStore.getRegistration(schoolID, conferenceID), }; - }, + } - componentDidMount: function() { + componentDidMount() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var conferenceID = this.context.conference.session; @@ -92,18 +86,18 @@ var AdvisorAssignmentsView = React.createClass({ registration: RegistrationStore.getRegistration(schoolID, conferenceID), }); }); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._successTimout && clearTimeout(this._successTimeout); this._committeesToken && this._committeesToken.remove(); this._countriesToken && this._countriesToken.remove(); this._delegatesToken && this._delegatesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); this._registrationToken && this._registrationToken.remove(); - }, + } - render: function() { + render() { var registration = this.state.registration; var waitlisted = _accessSafe(registration, 'is_waitlisted') == null @@ -164,9 +158,9 @@ var AdvisorAssignmentsView = React.createClass({ ); } - }, + } - renderAssignmentRows: function() { + renderAssignmentRows() { var committees = this.state.committees; var countries = this.state.countries; var finalized = @@ -204,7 +198,7 @@ var AdvisorAssignmentsView = React.createClass({ ); }.bind(this), ); - }, + } /* To make it easier to assign and unassign delegates to assignments we maintain @@ -213,7 +207,7 @@ var AdvisorAssignmentsView = React.createClass({ to be assigned to it. This way we can easily manage the relationship from assignment to delegates via this object. */ - prepareAssignedDelegates: function(delegates) { + prepareAssignedDelegates(delegates) { var assigned = {}; for (var i = 0; i < delegates.length; i++) { if (delegates[i].assignment) { @@ -228,9 +222,9 @@ var AdvisorAssignmentsView = React.createClass({ } return assigned; - }, + } - renderDelegateDropdown: function(assignment, slot) { + renderDelegateDropdown(assignment, slot) { var selectedDelegateID = assignment.id in this.state.assigned ? this.state.assigned[assignment.id][slot] @@ -249,9 +243,9 @@ var AdvisorAssignmentsView = React.createClass({ disabled={disableView} /> ); - }, + } - _handleDelegateAssignment: function(assignmentId, slot, event) { + _handleDelegateAssignment(assignmentId, slot, event) { var delegates = this.state.delegates; var assigned = this.state.assigned; var newDelegateId = event.target.value, @@ -281,9 +275,9 @@ var AdvisorAssignmentsView = React.createClass({ delegates: delegates, assigned: assigned, }); - }, + } - _handleFinalize: function(event) { + _handleFinalize(event) { var confirm = window.confirm( 'By pressing okay you are committing to the financial responsibility of each assignment. Are you sure you want to finalize assignments?', ); @@ -296,9 +290,9 @@ var AdvisorAssignmentsView = React.createClass({ this._handleError, ); } - }, + } - _handleAssignmentDelete: function(assignment) { + _handleAssignmentDelete(assignment) { var confirm = window.confirm( 'Are you sure you want to delete this assignment?', ); @@ -311,9 +305,9 @@ var AdvisorAssignmentsView = React.createClass({ this._handleError, ); } - }, + } - _handleSave: function(event) { + _handleSave(event) { this._successTimout && clearTimeout(this._successTimeout); this.setState({loading: true}); var school = CurrentUserStore.getCurrentUser().school; @@ -323,9 +317,9 @@ var AdvisorAssignmentsView = React.createClass({ this._handleSuccess, this._handleError, ); - }, + } - _handleSuccess: function(response) { + _handleSuccess(response) { this.setState({ loading: false, success: true, @@ -335,14 +329,18 @@ var AdvisorAssignmentsView = React.createClass({ () => this.setState({success: false}), 2000, ); - }, + } - _handleError: function(response) { + _handleError(response) { this.setState({loading: false}); window.alert( 'Something went wrong. Please refresh your page and try again.', ); - }, -}); + } +} + +AdvisorAssignmentsView.contextTypes = { + conference: React.PropTypes.shape(ConferenceContext), +}; module.exports = AdvisorAssignmentsView; diff --git a/huxley/www/js/components/AdvisorFeedbackView.js b/huxley/www/js/components/AdvisorFeedbackView.js index da4955938..933cfcb2c 100644 --- a/huxley/www/js/components/AdvisorFeedbackView.js +++ b/huxley/www/js/components/AdvisorFeedbackView.js @@ -25,14 +25,9 @@ var TextTemplate = require('components/core/TextTemplate'); var AdvisorFeedbackViewText = require('text/AdvisorFeedbackViewText.md'); var AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); -var AdvisorFeedbackView = React.createClass({ - mixins: [ReactRouter.History], +class AdvisorFeedbackView extends React.Component { - contextTypes: { - conference: React.PropTypes.shape(ConferenceContext), - }, - - getInitialState: function() { + getInitialState() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var delegates = DelegateStore.getSchoolDelegates(schoolID); var conferenceID = this.context.conference.session; @@ -49,9 +44,9 @@ var AdvisorFeedbackView = React.createClass({ delegates: delegates, loading: false, }; - }, + } - componentDidMount: function() { + componentDidMount() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var conferenceID = this.context.conference.session; this._registrationToken = RegistrationStore.addListener(() => { @@ -84,17 +79,17 @@ var AdvisorFeedbackView = React.createClass({ feedback: feedback, }); }); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._registrationToken && this._registrationToken.remove(); this._committeesToken && this._committeesToken.remove(); this._countriesToken && this._countriesToken.remove(); this._delegatesToken && this._delegatesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); - }, + } - render: function() { + render() { var registration = this.state.registration; var waitlisted = _accessSafe(registration, 'is_waitlisted') == null @@ -133,9 +128,9 @@ var AdvisorFeedbackView = React.createClass({ ); } - }, + } - renderAssignmentRows: function() { + renderAssignmentRows() { var assignments = this.state.assignments; var committees = this.state.committees; var countries = this.state.countries; @@ -192,7 +187,7 @@ var AdvisorFeedbackView = React.createClass({ ); }); - }, + } /* @@ -203,7 +198,7 @@ var AdvisorFeedbackView = React.createClass({ country name instead of delegate name. */ - prepareFeedback: function(delegates) { + prepareFeedback(delegates) { var feedback = {}; for (var delegate of delegates) { if (delegate.assignment) { @@ -211,7 +206,12 @@ var AdvisorFeedbackView = React.createClass({ } } return feedback; - }, -}); + } +} + +AdvisorFeedbackView.contextTypes = { + conference: React.PropTypes.shape(ConferenceContext), + history: ReactRouter.PropTypes.history, +} module.exports = AdvisorFeedbackView; diff --git a/huxley/www/js/components/AdvisorPaperView.js b/huxley/www/js/components/AdvisorPaperView.js index df1f0e82d..0b1dd6273 100644 --- a/huxley/www/js/components/AdvisorPaperView.js +++ b/huxley/www/js/components/AdvisorPaperView.js @@ -30,14 +30,9 @@ const cx = require('classnames'); var AdvisorPaperViewText = require('text/AdvisorPaperViewText.md'); var AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); -var AdvisorPaperView = React.createClass({ - mixins: [ReactRouter.History], +class AdvisorPaperView extends React.Component { - contextTypes: { - conference: React.PropTypes.shape(ConferenceContext), - }, - - getInitialState: function() { + getInitialState() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var conferenceID = this.context.conference.session; return { @@ -48,11 +43,11 @@ var AdvisorPaperView = React.createClass({ graded_files: PositionPaperStore.getGradedPositionPaperFiles(), rubric: RubricStore.getRubric, loading: false, - errors: {}, + errors: {} }; - }, + } - componentDidMount: function() { + componentDidMount() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var conferenceID = this.context.conference.session; this._committeesToken = CommitteeStore.addListener(() => { @@ -91,18 +86,18 @@ var AdvisorPaperView = React.createClass({ rubric: RubricStore.getRubric, }); }); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._registrationToken && this._registrationToken.remove(); this._rubricsToken && this._rubricsToken.remove(); this._papersToken && this._papersToken.remove(); this._countriesToken && this._countriesToken.remove(); this._committeesToken && this._committeesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); - }, + } - render: function() { + render() { var conference = this.context.conference; var registration = this.state.registration; var waitlisted = @@ -129,9 +124,9 @@ var AdvisorPaperView = React.createClass({ ); } - }, + } - renderPaperTables: function() { + renderPaperTables() { var committees = {}; var cm = this.state.committees; var countries = this.state.countries; @@ -219,9 +214,9 @@ var AdvisorPaperView = React.createClass({ ); }.bind(this), ); - }, + } - renderCommitteeRows: function( + renderCommitteeRows( countryAssignments, rubric, files, @@ -381,9 +376,9 @@ var AdvisorPaperView = React.createClass({ ); }.bind(this), ); - }, + } - calculateTotalScore: function(paper, rubric, topic_2 = false) { + calculateTotalScore(paper, rubric, topic_2 = false) { var totalScore = -1; if (topic_2) { totalScore = @@ -401,9 +396,9 @@ var AdvisorPaperView = React.createClass({ inflateGrades(paper.score_5, rubric.grade_value_5); } return totalScore; - }, + } - calculateMaxScore: function(rubric, topic_2 = false) { + calculateMaxScore(rubric, topic_2 = false) { var totalMaxScore = -1; if (topic_2) { totalMaxScore = @@ -421,9 +416,9 @@ var AdvisorPaperView = React.createClass({ rubric.grade_value_5; } return totalMaxScore; - }, + } - calculateCategory: function(value, weight) { + calculateCategory(value, weight) { var interval = weight / 5; if (value >= interval * 5) { return '5 - Exceeds Expectations'; @@ -438,9 +433,9 @@ var AdvisorPaperView = React.createClass({ } else { ('0 - Needs Improvement'); } - }, + } - calculateScore: function(category, weight) { + calculateScore(category, weight) { var interval = weight / 5; if (category == '5 - Exceeds Expectations') { return interval * 5; @@ -455,9 +450,9 @@ var AdvisorPaperView = React.createClass({ } else { return 0; } - }, + } - renderError: function(field) { + renderError(field) { if (this.state.errors[field]) { return ( {this.state.errors[field]} @@ -465,14 +460,18 @@ var AdvisorPaperView = React.createClass({ } return null; - }, + } - _handleError: function(response) { + _handleError(response) { this.setState({ errors: response, loading: false, }); - }, -}); + } +} + +AdvisorPaperView.contextTypes = { + conference: React.PropTypes.shape(ConferenceContext), +}; module.exports = AdvisorPaperView; diff --git a/huxley/www/js/components/AdvisorProfileView.js b/huxley/www/js/components/AdvisorProfileView.js index 8672e9b31..ea610c6c7 100644 --- a/huxley/www/js/components/AdvisorProfileView.js +++ b/huxley/www/js/components/AdvisorProfileView.js @@ -33,7 +33,7 @@ const AdvisorChecklistTeamFeeText = require('text/checklists/AdvisorChecklistTea const AdvisorChecklistWaiversText = require('text/checklists/AdvisorChecklistWaiversText.md'); const AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); -const AdvisorProfileView = React.createClass({ +class AdvisorProfileView extends React.Component { // #489 // The below code was commented out due to // https://github.com/reactjs/react-router/blob/master/upgrade-guides/v1.0.0.md#routehandler @@ -42,12 +42,7 @@ const AdvisorProfileView = React.createClass({ // user: React.PropTypes.object.isRequired // }, - contextTypes: { - conference: React.PropTypes.shape(ConferenceContext), - shake: React.PropTypes.func, - }, - - getInitialState: function() { + getInitialState() { var user = this.props.user; var school = User.getSchool(user); var conferenceID = this.context.conference.session; @@ -71,9 +66,9 @@ const AdvisorProfileView = React.createClass({ delegates: DelegateStore.getSchoolDelegates(school.id), assignments: AssignmentStore.getSchoolAssignments(school.id), }; - }, + } - componentDidMount: function() { + componentDidMount() { var schoolID = User.getSchool(this.props.user).id; var conferenceID = this.context.conference.session; this._registrationToken = RegistrationStore.addListener(() => { @@ -91,16 +86,16 @@ const AdvisorProfileView = React.createClass({ assignments: AssignmentStore.getSchoolAssignments(schoolID), }); }); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._successTimout && clearTimeout(this._successTimeout); this._registrationToken && this._registrationToken.remove(); this._delegatesToken && this._delegatesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); - }, + } - render: function() { + render() { var conference = this.context.conference; var user = this.props.user; var school = User.getSchool(user); @@ -525,9 +520,9 @@ const AdvisorProfileView = React.createClass({ ); - }, + } - renderError: function(field) { + renderError(field) { if (this.state.errors[field]) { return ( {this.state.errors[field]} @@ -543,9 +538,9 @@ const AdvisorProfileView = React.createClass({ } return null; - }, + } - _handleSubmit: function(event) { + _handleSubmit(event) { this._successTimout && clearTimeout(this._successTimeout); this.setState({loading: true}); var user = this.props.user; @@ -570,9 +565,9 @@ const AdvisorProfileView = React.createClass({ this._handleError, ); event.preventDefault(); - }, + } - _handleSuccess: function(response) { + _handleSuccess(response) { this.setState({ errors: {}, loading: false, @@ -583,9 +578,9 @@ const AdvisorProfileView = React.createClass({ () => this.setState({success: false}), 2000, ); - }, + } - _handleError: function(response) { + _handleError(response) { if (!response) { return; } @@ -599,6 +594,12 @@ const AdvisorProfileView = React.createClass({ this.context.shake && this.context.shake(); }, ); - }, -}); + } +} + +AdvisorProfileView.contextTypes = { + conference: React.PropTypes.shape(ConferenceContext), + shake: React.PropTypes.func, +}; + module.exports = AdvisorProfileView; diff --git a/huxley/www/js/components/AdvisorRosterView.js b/huxley/www/js/components/AdvisorRosterView.js index 9cfcb42fe..33347950f 100644 --- a/huxley/www/js/components/AdvisorRosterView.js +++ b/huxley/www/js/components/AdvisorRosterView.js @@ -31,14 +31,8 @@ require('css/Modal.less'); var AdvisorRosterViewText = require('text/AdvisorRosterViewText.md'); var AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); -var AdvisorRosterView = React.createClass({ - mixins: [ReactRouter.History], - - contextTypes: { - conference: React.PropTypes.shape(ConferenceContext), - }, - - getInitialState: function() { +class AdvisorRosterView extends React.Component { + getInitialState() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var conferenceID = this.context.conference.session; var assignments = AssignmentStore.getSchoolAssignments(schoolID).filter( @@ -64,13 +58,13 @@ var AdvisorRosterView = React.createClass({ modal_onClick: null, errors: {}, }; - }, + } - componentWillMount: function() { + componentWillMount() { Modal.setAppElement('body'); - }, + } - componentDidMount: function() { + componentDidMount() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var conferenceID = this.context.conference.session; this._registrationToken = RegistrationStore.addListener(() => { @@ -101,15 +95,15 @@ var AdvisorRosterView = React.createClass({ assignment_ids: assignment_ids, }); }); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { this._registrationToken && this._registrationToken.remove(); this._delegatesToken && this._delegatesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); - }, + } - render: function() { + render() { var conference = this.context.conference; var registration = this.state.registration; var waitlisted = @@ -197,9 +191,9 @@ var AdvisorRosterView = React.createClass({ ); } - }, + } - renderRosterRows: function() { + renderRosterRows() { var committees = this.state.committees; var countries = this.state.countries; var assignments = this.state.assignments; @@ -276,9 +270,9 @@ var AdvisorRosterView = React.createClass({ ); }.bind(this), ); - }, + } - openModal: function(name, email, fn, event) { + openModal(name, email, fn, event) { this.setState({ modal_open: true, modal_name: name, @@ -287,14 +281,14 @@ var AdvisorRosterView = React.createClass({ errors: {}, }); event.preventDefault(); - }, + } - closeModal: function(event) { + closeModal(event) { this.setState({modal_open: false}); event.preventDefault(); - }, + } - renderError: function(field) { + renderError(field) { if (this.state.errors[field]) { return ( {this.state.errors[field]} @@ -302,18 +296,18 @@ var AdvisorRosterView = React.createClass({ } return null; - }, + } - _handleDeleteDelegate: function(delegate) { + _handleDeleteDelegate(delegate) { const confirmed = window.confirm( `Are you sure you want to delete this delegate (${delegate.name})?`, ); if (confirmed) { DelegateActions.deleteDelegate(delegate.id, this._handleDeleteError); } - }, + } - _handleAddDelegate: function(data) { + _handleAddDelegate(data) { this.setState({loading: true}); var user = CurrentUserStore.getCurrentUser(); ServerAPI.createDelegate( @@ -322,56 +316,60 @@ var AdvisorRosterView = React.createClass({ user.school.id, ).then(this._handleAddDelegateSuccess, this._handleError); event.preventDefault(); - }, + } - _handleEditDelegate: function(delegate) { + _handleEditDelegate(delegate) { var user = CurrentUserStore.getCurrentUser(); this.setState({loading: true}); var delta = {name: this.state.modal_name, email: this.state.modal_email}; DelegateActions.updateDelegate(delegate.id, delta, this._handleError); event.preventDefault(); - }, + } - _handleDelegatePasswordChange: function(delegate) { + _handleDelegatePasswordChange(delegate) { ServerAPI.resetDelegatePassword(delegate.id).then( this._handlePasswordChangeSuccess, this._handlePasswordChangeError, ); - }, + } - _handleAddDelegateSuccess: function(response) { + _handleAddDelegateSuccess(response) { DelegateActions.addDelegate(response); this.setState({ loading: false, modal_open: false, }); - }, + } - _handlePasswordChangeSuccess: function(response) { + _handlePasswordChangeSuccess(response) { this.setState({ loading: false, modal_open: false, }); window.alert(`Password successfully reset.`); - }, + } - _handlePasswordChangeError: function(response) { + _handlePasswordChangeError(response) { window.alert(`The passowrd could not be reset.`); - }, + } - _handleDeleteError: function(response) { + _handleDeleteError(response) { window.alert( `There was an issue processing your request. Please refresh you page and try again.`, ); - }, + } - _handleError: function(response) { + _handleError(response) { this.setState({ errors: response, loading: false, modal_open: true, }); - }, -}); + } +} + +AdvisorRosterView.contextTypes = { + conference: React.PropTypes.shape(ConferenceContext), +}; module.exports = AdvisorRosterView; diff --git a/huxley/www/js/components/AdvisorView.js b/huxley/www/js/components/AdvisorView.js index b5bbda5d4..00ba7a821 100644 --- a/huxley/www/js/components/AdvisorView.js +++ b/huxley/www/js/components/AdvisorView.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import {React} from 'react'; +import PropTypes from 'react-router'; var NavTab = require('components/NavTab'); var PermissionDeniedView = require('components/PermissionDeniedView'); @@ -16,16 +16,16 @@ var User = require('utils/User'); require('css/NavBar.less'); -var AdvisorView = React.createClass({ - mixins: [ReactRouter.History], +class AdvisorView extends React.Component { + - componentDidMount: function() { + componentDidMount() { if (User.isAnonymous(this.props.user)) { this.history.pushState(null, '/login'); } - }, + } - render: function() { + render() { var content = User.isAdvisor(this.props.user) ? ( this.props.children ) : ( @@ -47,7 +47,11 @@ var AdvisorView = React.createClass({
); - }, -}); + } +} + +AdvisorView.contextTypes = { + history: PropTypes.history, +} module.exports = AdvisorView; From f096966b29f8bd7a024447d5577f2f5e3ec26243 Mon Sep 17 00:00:00 2001 From: Shayna Kothari Date: Mon, 11 Jan 2021 15:25:47 -0800 Subject: [PATCH 05/80] up to delegate --- .../js/components/AdvisorAssignmentsView.js | 2 +- .../www/js/components/AdvisorFeedbackView.js | 3 +- huxley/www/js/components/AdvisorPaperView.js | 3 +- .../www/js/components/AdvisorProfileView.js | 2 +- huxley/www/js/components/AdvisorRosterView.js | 3 +- huxley/www/js/components/AdvisorView.js | 2 +- .../www/js/components/ChairAttendanceView.js | 78 +++++++++--------- .../components/ChairCommitteeFeedbackView.js | 42 +++++----- .../js/components/ChairDelegateEmailView.js | 37 +++++---- huxley/www/js/components/ChairPapersView.js | 52 ++++++------ huxley/www/js/components/ChairRubricView.js | 51 ++++++------ huxley/www/js/components/ChairSummaryView.js | 66 ++++++++-------- huxley/www/js/components/ChairView.js | 8 +- .../www/js/components/ChangePasswordView.js | 68 ++++++++-------- huxley/www/js/components/ConferenceContext.js | 2 +- huxley/www/js/components/CountrySelect.js | 32 ++++---- .../DelegateCommitteeFeedbackView.js | 60 +++++++------- huxley/www/js/components/DelegatePaperView.js | 79 ++++++++----------- .../www/js/components/DelegateProfileView.js | 28 +++---- huxley/www/js/components/DelegateSelect.js | 27 ++++--- huxley/www/js/components/DelegateView.js | 8 +- .../js/components/DelegationAttendanceRow.js | 31 ++++---- 22 files changed, 343 insertions(+), 341 deletions(-) diff --git a/huxley/www/js/components/AdvisorAssignmentsView.js b/huxley/www/js/components/AdvisorAssignmentsView.js index fcd7c9cf6..3a8575433 100644 --- a/huxley/www/js/components/AdvisorAssignmentsView.js +++ b/huxley/www/js/components/AdvisorAssignmentsView.js @@ -5,7 +5,7 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var _accessSafe = require('utils/_accessSafe'); var AssignmentActions = require('actions/AssignmentActions'); diff --git a/huxley/www/js/components/AdvisorFeedbackView.js b/huxley/www/js/components/AdvisorFeedbackView.js index 933cfcb2c..aea421106 100644 --- a/huxley/www/js/components/AdvisorFeedbackView.js +++ b/huxley/www/js/components/AdvisorFeedbackView.js @@ -5,8 +5,7 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import React from 'react'; var _accessSafe = require('utils/_accessSafe'); var AssignmentActions = require('actions/AssignmentActions'); diff --git a/huxley/www/js/components/AdvisorPaperView.js b/huxley/www/js/components/AdvisorPaperView.js index 0b1dd6273..cad4596e3 100644 --- a/huxley/www/js/components/AdvisorPaperView.js +++ b/huxley/www/js/components/AdvisorPaperView.js @@ -5,8 +5,7 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import React from 'react'; var _accessSafe = require('utils/_accessSafe'); var AssignmentStore = require('stores/AssignmentStore'); diff --git a/huxley/www/js/components/AdvisorProfileView.js b/huxley/www/js/components/AdvisorProfileView.js index ea610c6c7..a2a1baca2 100644 --- a/huxley/www/js/components/AdvisorProfileView.js +++ b/huxley/www/js/components/AdvisorProfileView.js @@ -5,7 +5,7 @@ 'use strict'; -const React = require('react'); +import React from 'react'; var _accessSafe = require('utils/_accessSafe'); const AssignmentStore = require('stores/AssignmentStore'); diff --git a/huxley/www/js/components/AdvisorRosterView.js b/huxley/www/js/components/AdvisorRosterView.js index 33347950f..9e763d159 100644 --- a/huxley/www/js/components/AdvisorRosterView.js +++ b/huxley/www/js/components/AdvisorRosterView.js @@ -6,8 +6,7 @@ 'use strict'; var Modal = require('react-modal'); -var React = require('react'); -var ReactRouter = require('react-router'); +import React from 'react'; var _accessSafe = require('utils/_accessSafe'); var AssignmentStore = require('stores/AssignmentStore'); diff --git a/huxley/www/js/components/AdvisorView.js b/huxley/www/js/components/AdvisorView.js index 00ba7a821..8114fddaa 100644 --- a/huxley/www/js/components/AdvisorView.js +++ b/huxley/www/js/components/AdvisorView.js @@ -21,7 +21,7 @@ class AdvisorView extends React.Component { componentDidMount() { if (User.isAnonymous(this.props.user)) { - this.history.pushState(null, '/login'); + this.context.history.pushState(null, '/login'); } } diff --git a/huxley/www/js/components/ChairAttendanceView.js b/huxley/www/js/components/ChairAttendanceView.js index 4c2e8b8d5..74c62c673 100644 --- a/huxley/www/js/components/ChairAttendanceView.js +++ b/huxley/www/js/components/ChairAttendanceView.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import { React } from 'react'; +import PropTypes from 'react-router'; var Button = require('components/core/Button'); var AssignmentStore = require('stores/AssignmentStore'); @@ -22,9 +22,7 @@ var User = require('utils/User'); require('css/Table.less'); var ChairAttendanceViewText = require('text/ChairAttendanceViewText.md'); -var ChairAttendanceView = React.createClass({ - mixins: [ReactRouter.History], - +class ChairAttendanceView extends React.Component { getInitialState() { var user = CurrentUserStore.getCurrentUser(); var assignments = AssignmentStore.getCommitteeAssignments(user.committee); @@ -46,15 +44,15 @@ var ChairAttendanceView = React.createClass({ delegates: delegates, attendance: attendance, }; - }, - + } + componentWillMount() { var user = CurrentUserStore.getCurrentUser(); if (!User.isChair(user)) { - this.history.pushState(null, '/'); + this.context.history.pushState(null, '/'); } - }, - + } + componentDidMount() { var user = CurrentUserStore.getCurrentUser(); var attendance = this.state.attendance; @@ -64,7 +62,7 @@ var ChairAttendanceView = React.createClass({ var update = this._mapAttendance(delegates); this.setState({ delegates: delegates, - attendance: {...attendance, ...update}, + attendance: { ...attendance, ...update }, }); }); @@ -77,7 +75,7 @@ var ChairAttendanceView = React.createClass({ countries[a1.country].name < countries[a2.country].name ? -1 : 1, ); } - this.setState({assignments: assignments}); + this.setState({ assignments: assignments }); }); this._countriesToken = CountryStore.addListener(() => { @@ -94,16 +92,16 @@ var ChairAttendanceView = React.createClass({ countries: countries, }); }); - }, - + } + componentWillUnmount() { this._successTimout && clearTimeout(this._successTimeout); this._countriesToken && this._countriesToken.remove(); this._delegatesToken && this._delegatesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); this._successTimeout && clearTimeout(this._successTimeout); - }, - + } + render() { return ( @@ -112,7 +110,7 @@ var ChairAttendanceView = React.createClass({
- +
@@ -124,10 +122,10 @@ var ChairAttendanceView = React.createClass({
Assignment
-
+
+ style={{ margin: '0px auto 20px auto', tableLayout: 'fixed' }}> {this.renderAttendanceRows()} @@ -144,8 +142,8 @@ var ChairAttendanceView = React.createClass({ ); - }, - + } + renderAttendanceRows() { var assignments = this.state.assignments; var attendance = this.state.attendance; @@ -167,8 +165,8 @@ var ChairAttendanceView = React.createClass({ attendance={attendance[assignment.id]} />, ); - }, - + } + _mapAttendance(delegates) { var attendance = {}; for (var delegate of delegates) { @@ -181,22 +179,22 @@ var ChairAttendanceView = React.createClass({ }; } return attendance; - }, - + } + _handleAttendanceChange(field, assignmentID, event) { var attendanceMap = this.state.attendance; var oldAttendance = attendanceMap[assignmentID]; this.setState({ attendance: { ...attendanceMap, - [assignmentID]: {...oldAttendance, [field]: !oldAttendance[field]}, + [assignmentID]: { ...oldAttendance, [field]: !oldAttendance[field] }, }, }); - }, - + } + _handleSaveAttendance(event) { this._successTimout && clearTimeout(this._successTimeout); - this.setState({loading: true}); + this.setState({ loading: true }); var committee = CurrentUserStore.getCurrentUser().committee; var attendanceMap = this.state.attendance; var delegates = this.state.delegates; @@ -227,26 +225,30 @@ var ChairAttendanceView = React.createClass({ this._handleError, ); event.preventDefault(); - }, + } - _handleSuccess: function(response) { + _handleSuccess(response) { this.setState({ loading: false, success: true, }); this._successTimeout = setTimeout( - () => this.setState({success: false}), + () => this.setState({ success: false }), 2000, ); - }, - - _handleError: function(response) { - this.setState({loading: false}); + } + + _handleError(response) { + this.setState({ loading: false }); window.alert( 'Something went wrong. Please refresh your page and try again.', ); - }, -}); + } +} + +ChairAttendanceView.contextTypes = { + history: PropTypes.history, +} module.exports = ChairAttendanceView; diff --git a/huxley/www/js/components/ChairCommitteeFeedbackView.js b/huxley/www/js/components/ChairCommitteeFeedbackView.js index 859288363..25fec23c6 100644 --- a/huxley/www/js/components/ChairCommitteeFeedbackView.js +++ b/huxley/www/js/components/ChairCommitteeFeedbackView.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import React from 'react'; +import PropTypes from 'react-router'; var CommitteeFeedbackStore = require('stores/CommitteeFeedbackStore'); var CurrentUserStore = require('stores/CurrentUserStore'); @@ -17,16 +17,16 @@ var User = require('utils/User'); require('css/Table.less'); var ChairCommitteeFeedbackViewText = require('text/ChairCommitteeFeedbackViewText.md'); -var ChairCommitteeFeedbackView = React.createClass({ - mixins: [ReactRouter.History], +class ChairCommitteeFeedbackView extends React.Component { + getInitialState() { var committeeID = CurrentUserStore.getCurrentUser().committee; return { feedback: CommitteeFeedbackStore.getCommitteeFeedback(committeeID), }; - }, - + } + componentDidMount() { this._committeeFeedbackToken = CommitteeFeedbackStore.addListener(() => { var committeeID = CurrentUserStore.getCurrentUser().committee; @@ -34,19 +34,19 @@ var ChairCommitteeFeedbackView = React.createClass({ feedback: CommitteeFeedbackStore.getCommitteeFeedback(committeeID), }); }); - }, - + } + componentWillMount() { var user = CurrentUserStore.getCurrentUser(); if (!User.isChair(user)) { - this.history.pushState(null, '/'); + this.context.history.pushState(null, '/'); } - }, - + } + componentsWillUnmount() { this._committeeFeedbackToken && this._committeeFeedbackToken.remove(); - }, - + } + render() { return ( @@ -68,8 +68,8 @@ var ChairCommitteeFeedbackView = React.createClass({ {this.mapFeedbackToTable()} ); - }, - + } + mapFeedbackToTable() { var data = {}; for (var singleFeedback of this.state.feedback) { @@ -120,8 +120,8 @@ var ChairCommitteeFeedbackView = React.createClass({ } } return tables; - }, - + } + renderFeedbackRows(obj) { return obj.map(function(singleFeedback) { return ( @@ -133,7 +133,11 @@ var ChairCommitteeFeedbackView = React.createClass({ ); }); - }, -}); + } +} + +ChairCommitteeFeedbackView.contextTypes = { + history: PropTypes.history, +} module.exports = ChairCommitteeFeedbackView; diff --git a/huxley/www/js/components/ChairDelegateEmailView.js b/huxley/www/js/components/ChairDelegateEmailView.js index 9011c44e8..062bd8885 100644 --- a/huxley/www/js/components/ChairDelegateEmailView.js +++ b/huxley/www/js/components/ChairDelegateEmailView.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import React from 'react'; +import PropTypes from 'react-router'; var AssignmentStore = require('stores/AssignmentStore'); var CountryStore = require('stores/CountryStore'); @@ -19,8 +19,7 @@ var User = require('utils/User'); require('css/Table.less'); var ChairDelegateEmailViewText = require('text/ChairDelegateEmailViewText.md'); -var ChairDelegateEmailView = React.createClass({ - mixins: [ReactRouter.History], +class ChairDelegateEmailView extends React.Component { getInitialState() { var user = CurrentUserStore.getCurrentUser(); @@ -40,16 +39,16 @@ var ChairDelegateEmailView = React.createClass({ countries: countries, delegates: delegates, }; - }, + } - componentWillMount() { +componentWillMount() { var user = CurrentUserStore.getCurrentUser(); if (!User.isChair(user)) { - this.history.pushState(null, '/'); + this.context.history.pushState(null, '/'); } - }, + } - componentDidMount() { +componentDidMount() { var user = CurrentUserStore.getCurrentUser(); this._delegatesToken = DelegateStore.addListener(() => { @@ -83,15 +82,15 @@ var ChairDelegateEmailView = React.createClass({ countries: countries, }); }); - }, + } - componentWillUnmount() { +componentWillUnmount() { this._countriesToken && this._countriesToken.remove(); this._delegatesToken && this._delegatesToken.remove(); this._assignmentsToken && this._assignmentsToken.remove(); - }, + } - render() { +render() { return ( @@ -121,9 +120,9 @@ var ChairDelegateEmailView = React.createClass({ ); - }, + } - renderEmailRows() { +renderEmailRows() { var assignments = this.state.assignments; var delegates = this.state.delegates; var countries = this.state.countries; @@ -139,7 +138,11 @@ var ChairDelegateEmailView = React.createClass({ ); }); - }, -}); + } +} + +ChairCommitteeFeedbackView.contextTypes = { + history: PropTypes.history, +} module.exports = ChairDelegateEmailView; diff --git a/huxley/www/js/components/ChairPapersView.js b/huxley/www/js/components/ChairPapersView.js index e6193c156..616328238 100644 --- a/huxley/www/js/components/ChairPapersView.js +++ b/huxley/www/js/components/ChairPapersView.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import {React} from 'react'; +import PropTypes from 'react-router'; var Button = require('components/core/Button'); var AssignmentStore = require('stores/AssignmentStore'); @@ -27,9 +27,8 @@ var ServerAPI = require('lib/ServerAPI'); require('css/Table.less'); var ChairPapersViewText = require('text/ChairPapersViewText.md'); -var ChairPapersView = React.createClass({ - mixins: [ReactRouter.History], - +class ChairPapersView extends React.Component { + getInitialState() { var user = CurrentUserStore.getCurrentUser(); var assignments = AssignmentStore.getCommitteeAssignments(user.committee); @@ -65,14 +64,14 @@ var ChairPapersView = React.createClass({ graded_files: graded_files, errors: {}, }; - }, + } componentWillMount() { var user = CurrentUserStore.getCurrentUser(); if (!User.isChair(user)) { - this.history.pushState(null, '/'); + this.context.history.pushState(null, '/'); } - }, + } componentDidMount() { var user = CurrentUserStore.getCurrentUser(); @@ -132,7 +131,7 @@ var ChairPapersView = React.createClass({ }); } }); - }, + } componentWillUnmount() { this._countriesToken && this._countriesToken.remove(); @@ -141,7 +140,7 @@ var ChairPapersView = React.createClass({ this._papersToken && this._papersToken.remove(); this._rubricToken && this._rubricToken.remove(); this._successTimeout && clearTimeout(this._successTimeout); - }, + } render() { if (this.state.current_assignment == null) { @@ -162,7 +161,7 @@ var ChairPapersView = React.createClass({ ); } - }, + } renderRubric() { var user = CurrentUserStore.getCurrentUser(); @@ -194,7 +193,7 @@ var ChairPapersView = React.createClass({ } else { return
; } - }, + } renderAssignmentList() { const assignments = this.state.assignments; @@ -215,19 +214,19 @@ var ChairPapersView = React.createClass({ } else { return
; } - }, + } _handleScoreChange(field, paperID, event) { const paper = {...this.state.papers[paperID], [field]: Number(event)}; PositionPaperActions.storePositionPaper(paper); - }, + } _handleUnsetAssignment(event) { this.setState({ current_assignment: null, uploadedFile: null, }); - }, + } _handleAssignmentSelect(assignmentID, event) { var assignments = this.state.assignments; @@ -237,12 +236,12 @@ var ChairPapersView = React.createClass({ PositionPaperActions.fetchPositionPaperFile(a.paper.id); } event.preventDefault(); - }, + } _handleUploadPaper(paperID, event) { this.setState({uploadedFile: event.target.files[0]}); event.preventDefault(); - }, + } _handleSubmitPaper(paperID, event) { var file = this.state.uploadedFile; @@ -274,7 +273,7 @@ var ChairPapersView = React.createClass({ }); } event.preventDefault(); - }, + } _handleSavePaper(paperID, event) { this.setState({loading: true}); @@ -293,9 +292,9 @@ var ChairPapersView = React.createClass({ ); event.preventDefault(); this._handleSubmitPaper(paperID, event); - }, + } - _handleSuccess: function(response) { + _handleSuccess(response) { this.setState({ loading: false, success: true, @@ -305,14 +304,19 @@ var ChairPapersView = React.createClass({ () => this.setState({success: false}), 2000, ); - }, + } - _handleError: function(response) { + _handleError(response) { this.setState({loading: false}); window.alert( 'Something went wrong. Please refresh your page and try again.', ); - }, -}); + } +} + +ChairPapersView.contextTypes = { + history: PropTypes.history, + +} module.exports = ChairPapersView; diff --git a/huxley/www/js/components/ChairRubricView.js b/huxley/www/js/components/ChairRubricView.js index 7b764501f..4dee22488 100644 --- a/huxley/www/js/components/ChairRubricView.js +++ b/huxley/www/js/components/ChairRubricView.js @@ -5,8 +5,7 @@ 'use strict'; -const React = require('react'); -const ReactRouter = require('react-router'); +import React from 'react'; const Button = require('components/core/Button'); const CommitteeStore = require('stores/CommitteeStore'); @@ -22,7 +21,7 @@ const User = require('utils/User'); require('css/Table.less'); const ChairRubricText = require('text/ChairRubricViewText.md'); -const ChairRubricView = React.createClass({ +class ChairRubricView extends React.Component { getInitialState() { var user = CurrentUserStore.getCurrentUser(); var committees = CommitteeStore.getCommittees(); @@ -37,15 +36,15 @@ const ChairRubricView = React.createClass({ committees: committees, rubric: rubric, }; - }, - + } + componentWillMount() { var user = CurrentUserStore.getCurrentUser(); if (!User.isChair(user)) { - this.history.pushState(null, '/'); + this.context.history.pushState(null, '/'); } - }, - + } + componentDidMount() { this._committeesToken = CommitteeStore.addListener(() => { var user = CurrentUserStore.getCurrentUser(); @@ -63,13 +62,13 @@ const ChairRubricView = React.createClass({ this.setState({rubric: RubricStore.getRubric(committee.rubric.id)}); } }); - }, - + } + componentWillUnmount() { this._rubricToken && this._rubricToken.remove(); this._successTimeout && clearTimeout(this._successTimeout); - }, - + } + render() { var rubric = this.state.rubric; if (rubric == null) { @@ -262,9 +261,9 @@ const ChairRubricView = React.createClass({ ); - }, + } - _renderTopicTwo(rubric) { +_renderTopicTwo(rubric) { return (
@@ -362,9 +361,9 @@ const ChairRubricView = React.createClass({
); - }, + } - _handleChange(field, event) { +_handleChange(field, event) { var rubric = this.state.rubric; if (field == 'use_topic_2') { event = !rubric.use_topic_2; @@ -375,9 +374,9 @@ const ChairRubricView = React.createClass({ [field]: event, }, }); - }, + } - _handleValueChange(field, event) { +_handleValueChange(field, event) { var rubric = this.state.rubric; this.setState({ rubric: { @@ -385,17 +384,17 @@ const ChairRubricView = React.createClass({ [field]: Number(event), }, }); - }, + } - _handleSaveRubric(event) { +_handleSaveRubric(event) { this.setState({loading: true}); this._successTimout && clearTimeout(this._successTimeout); var rubric = {...this.state.rubric}; RubricActions.updateRubric(rubric, this._handleSuccess, this._handleError); event.preventDefault(); - }, + } - _handleSuccess: function(response) { +_handleSuccess(response) { this.setState({ loading: false, success: true, @@ -405,14 +404,14 @@ const ChairRubricView = React.createClass({ () => this.setState({success: false}), 2000, ); - }, + } - _handleError: function(response) { +_handleError(response) { this.setState({loading: false}); window.alert( 'Something went wrong. Please refresh your page and try again.', ); - }, -}); + } +} module.exports = ChairRubricView; diff --git a/huxley/www/js/components/ChairSummaryView.js b/huxley/www/js/components/ChairSummaryView.js index 4279006bd..fe478d019 100644 --- a/huxley/www/js/components/ChairSummaryView.js +++ b/huxley/www/js/components/ChairSummaryView.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var ReactRouter = require('react-router'); +import React from 'react'; +import PropTypes from 'react-router'; var Button = require('components/core/Button'); var AssignmentStore = require('stores/AssignmentStore'); @@ -21,9 +21,7 @@ var User = require('utils/User'); require('css/Table.less'); var ChairSummaryViewText = require('text/ChairSummaryViewText.md'); -var ChairSummaryView = React.createClass({ - mixins: [ReactRouter.History], - +class ChairSummaryView extends React.Component { getInitialState() { var user = CurrentUserStore.getCurrentUser(); var assignments = AssignmentStore.getCommitteeAssignments(user.committee); @@ -51,16 +49,16 @@ var ChairSummaryView = React.createClass({ delegates: delegates, summaries: summaries, }; - }, + } - componentWillMount() { +componentWillMount() { var user = CurrentUserStore.getCurrentUser(); if (!User.isChair(user)) { - this.history.pushState(null, '/'); + this.context.history.pushState(null, '/'); } - }, + } - componentDidMount() { +componentDidMount() { var user = CurrentUserStore.getCurrentUser(); this._delegatesToken = DelegateStore.addListener(() => { @@ -102,9 +100,9 @@ var ChairSummaryView = React.createClass({ countries: countries, }); }); - }, + } - componentWillUnmount() { +componentWillUnmount() { this._successTimoutSave && clearTimeout(this._successTimeoutSave); this._successTimoutPublish && clearTimeout(this._successTimeoutPublish); this._countriesToken && this._countriesToken.remove(); @@ -112,9 +110,9 @@ var ChairSummaryView = React.createClass({ this._assignmentsToken && this._assignmentsToken.remove(); this._successTimeoutSave && clearTimeout(this._successTimeoutSave); this._successTimeoutPublish && clearTimeout(this._successTimeoutPublish); - }, + } - render() { +render() { return ( @@ -159,9 +157,9 @@ var ChairSummaryView = React.createClass({ ); - }, + } - renderSummaryRows() { +renderSummaryRows() { var assignments = this.state.assignments; var summaries = this.state.summaries; var assignmentIDs = Object.keys(summaries); @@ -187,9 +185,9 @@ var ChairSummaryView = React.createClass({ ); }); - }, + } - _handleSummaryChange(assignment, event) { +_handleSummaryChange(assignment, event) { var summaries = this.state.summaries; this.setState({ summaries: { @@ -197,9 +195,9 @@ var ChairSummaryView = React.createClass({ [assignment.id]: event.target.value, }, }); - }, + } - _handleSaveSummaries(event) { +_handleSaveSummaries(event) { this._successTimoutSave && clearTimeout(this._successTimeoutSave); this.setState({loadingSave: true}); var committee = CurrentUserStore.getCurrentUser().committee; @@ -219,9 +217,9 @@ var ChairSummaryView = React.createClass({ this._handleErrorSave, ); event.preventDefault(); - }, + } - _handlePublishSummaries(event) { +_handlePublishSummaries(event) { var confirm = window.confirm( 'By pressing ok, you are allowing advisors ' + 'to read the summaries that you have written ' + @@ -256,9 +254,9 @@ var ChairSummaryView = React.createClass({ ); event.preventDefault(); } - }, + } - _handleSuccessSave: function(response) { +_handleSuccessSave(response) { this.setState({ loadingSave: false, successSave: true, @@ -268,16 +266,16 @@ var ChairSummaryView = React.createClass({ () => this.setState({successSave: false}), 2000, ); - }, + } - _handleErrorSave: function(response) { +_handleErrorSave(response) { this.setState({loadingSave: false}); window.alert( 'Something went wrong. Please refresh your page and try again.', ); - }, + } - _handleSuccessPublish: function(response) { +_handleSuccessPublish(response) { this.setState({ loadingPublish: false, successPublish: true, @@ -287,14 +285,18 @@ var ChairSummaryView = React.createClass({ () => this.setState({successPublish: false}), 2000, ); - }, + } - _handleErrorPublish: function(response) { +_handleErrorPublish(response) { this.setState({loadingPublish: false}); window.alert( 'Something went wrong. Please refresh your page and try again.', ); - }, -}); + } +} + +ChairSummaryView.contextTypes = { + history: PropTypes.history, +} module.exports = ChairSummaryView; diff --git a/huxley/www/js/components/ChairView.js b/huxley/www/js/components/ChairView.js index ab5fb9892..8c6db7d79 100644 --- a/huxley/www/js/components/ChairView.js +++ b/huxley/www/js/components/ChairView.js @@ -5,7 +5,7 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var NavTab = require('components/NavTab'); var Shaker = require('components/Shaker'); @@ -13,7 +13,7 @@ var TopBar = require('components/TopBar'); require('css/NavBar.less'); -var ChairView = React.createClass({ +class ChairView extends React.Component { render() { return (
@@ -31,7 +31,7 @@ var ChairView = React.createClass({
); - }, -}); + } +} module.exports = ChairView; diff --git a/huxley/www/js/components/ChangePasswordView.js b/huxley/www/js/components/ChangePasswordView.js index 96c393990..a2a30c93e 100644 --- a/huxley/www/js/components/ChangePasswordView.js +++ b/huxley/www/js/components/ChangePasswordView.js @@ -5,8 +5,8 @@ 'use strict'; -var cx = require('classnames'); -var React = require('react'); +import cx from 'classnames'; +import React from 'react'; var Button = require('components/core/Button'); var ServerAPI = require('lib/ServerAPI'); @@ -14,14 +14,8 @@ var StatusLabel = require('components/core/StatusLabel'); require('css/ChangePasswordView.less'); -var ChangePasswordView = React.createClass({ - propTypes: { - isVisible: React.PropTypes.bool.isRequired, - onClick: React.PropTypes.func, - onSuccess: React.PropTypes.func.isRequired, - }, - - getInitialState: function() { +class ChangePasswordView extends React.Component { +getInitialState() { return { message: '', success: false, @@ -30,13 +24,13 @@ var ChangePasswordView = React.createClass({ newPassword: '', newPassword2: '', }; - }, + } - componentWillReceiveProps: function(nextProps) { +componentWillReceiveProps(nextProps) { this.setState(this.getInitialState()); - }, + } - render: function() { +render() { return (
); - }, + } - renderMessage: function() { +renderMessage() { if (!this.state.message) { return null; } @@ -91,25 +85,23 @@ var ChangePasswordView = React.createClass({ {this.state.message} ); - }, - - onSuccess: function() { + } onSuccess() { setTimeout(this.props.onSuccess, 750); - }, + } - _handleCurrentPasswordChange: function(event) { +_handleCurrentPasswordChange(event) { this.setState({currentPassword: event.target.value}); - }, + } - _handleNewPasswordChange: function(event) { +_handleNewPasswordChange(event) { this.setState({newPassword: event.target.value}); - }, + } - _handleNewPassword2Change: function(event) { +_handleNewPassword2Change(event) { this.setState({newPassword2: event.target.value}); - }, + } - _handleSubmit: function(event) { +_handleSubmit(event) { if (this.state.newPassword != this.state.newPassword2) { this.setState({ message: 'Please enter the same password again', @@ -124,9 +116,9 @@ var ChangePasswordView = React.createClass({ ); event.preventDefault(); } - }, + } - _handleSuccess: function(response) { +_handleSuccess(response) { this.setState( { loading: false, @@ -138,19 +130,25 @@ var ChangePasswordView = React.createClass({ }, this.onSuccess, ); - }, + } - _handleError: function(response) { +_handleError(response) { this.setState({ loading: false, message: response.detail, success: false, }); - }, + } - _handleDropdownClick: function(e) { +_handleDropdownClick(e) { this.props.onClick && this.props.onClick(e); - }, -}); + } +} + +ChangePasswordView.propTypes = { + isVisible: React.PropTypes.bool.isRequired, + onClick: React.PropTypes.func, + onSuccess: React.PropTypes.func.isRequired, +}; module.exports = ChangePasswordView; diff --git a/huxley/www/js/components/ConferenceContext.js b/huxley/www/js/components/ConferenceContext.js index a0ba0534a..5fe5cf496 100644 --- a/huxley/www/js/components/ConferenceContext.js +++ b/huxley/www/js/components/ConferenceContext.js @@ -5,7 +5,7 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var ConferenceContext = { session: React.PropTypes.number, diff --git a/huxley/www/js/components/CountrySelect.js b/huxley/www/js/components/CountrySelect.js index 9bbabc666..2f3e9efca 100644 --- a/huxley/www/js/components/CountrySelect.js +++ b/huxley/www/js/components/CountrySelect.js @@ -5,17 +5,10 @@ 'use strict'; -var React = require('react'); +import React from 'react'; -var CountrySelect = React.createClass({ - propTypes: { - onChange: React.PropTypes.func, - countries: React.PropTypes.array, - selectedCountryID: React.PropTypes.number, - countryPreferences: React.PropTypes.array, - }, - - shouldComponentUpdate: function(nextProps, nextState) { +class CountrySelect extends React.Component { +shouldComponentUpdate(nextProps, nextState) { for (var i = 0; i < this.props.countryPreferences.length; i++) { if ( this.props.countryPreferences[i] !== nextProps.countryPreferences[i] @@ -27,9 +20,9 @@ var CountrySelect = React.createClass({ nextProps.selectedCountryID !== this.props.selectedCountryID || nextProps.countries.length !== this.props.countries.length ); - }, + } - render: function() { +render() { return ( ); - }, + } - renderDelegateOptions: function() { +renderDelegateOptions() { return this.props.delegates.map(delegate => (
); - }, + } shake() { const element = ReactDOM.findDOMNode(this); @@ -41,7 +36,11 @@ var Shaker = React.createClass({ element.classList.remove('shake'); }, 301); } - }, -}); + } +}; + +Shaker.childContextTypes = { + shake: React.PropTypes.func, +} module.exports = Shaker; diff --git a/huxley/www/js/components/SupportLink.js b/huxley/www/js/components/SupportLink.js index b54328770..3cb86f5cb 100644 --- a/huxley/www/js/components/SupportLink.js +++ b/huxley/www/js/components/SupportLink.js @@ -5,13 +5,12 @@ 'use strict'; -var cx = require('classnames'); -var React = require('react'); +import React from 'react'; require('css/SupportLink.less'); -var SupportLink = React.createClass({ - render: function() { +class SupportLink extends React.Component { + render() { return (
Having Issues? @@ -26,7 +25,7 @@ var SupportLink = React.createClass({
); - }, -}); + } +}; module.exports = SupportLink; diff --git a/huxley/www/js/components/TopBar.js b/huxley/www/js/components/TopBar.js index 20663f971..d7d3ccc0c 100644 --- a/huxley/www/js/components/TopBar.js +++ b/huxley/www/js/components/TopBar.js @@ -5,30 +5,30 @@ 'use strict'; -var cx = require('classnames'); -var React = require('react'); +import React from 'react'; +import cx from 'classnames'; var ChangePasswordView = require('components/ChangePasswordView'); var LogoutButton = require('components/LogoutButton'); require('css/TopBar.less'); -var TopBar = React.createClass({ - getInitialState: function() { +class TopBar extends React.Components { + getInitialState() { return { changePasswordVisible: false, }; - }, + } - componentDidMount: function() { + componentDidMount() { document.addEventListener('click', this._hideDropdown); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { document.removeEventListener('click', this._hideDropdown); - }, + } - render: function() { + render() { var {user} = this.props; return ( @@ -68,31 +68,31 @@ var TopBar = React.createClass({ />
); - }, + } - _handleChangePasswordClick: function(e) { + _handleChangePasswordClick(e) { e.preventDefault(); this._stopPropagation(e); this.setState({ changePasswordVisible: !this.state.changePasswordVisible, }); - }, + } - _handleDropdownClick: function(e) { + _handleDropdownClick(e) { this._stopPropagation(e); - }, + } - _hideDropdown: function() { + _hideDropdown() { this.setState({changePasswordVisible: false}); - }, + } - _stopPropagation: function(e) { + _stopPropagation(e) { e.stopPropagation(); // TODO: display a warning if stopImmediatePropagation isn't supported. var ne = e.nativeEvent; ne.stopImmediatePropagation && ne.stopImmediatePropagation(); - }, -}); + } +}; module.exports = TopBar; diff --git a/huxley/www/js/components/core/Button.js b/huxley/www/js/components/core/Button.js index 8c467b179..0c1c1b5d8 100644 --- a/huxley/www/js/components/core/Button.js +++ b/huxley/www/js/components/core/Button.js @@ -5,31 +5,14 @@ 'use strict'; -var cx = require('classnames'); -var React = require('react'); -var ReactRouter = require('react-router'); +import cx from 'classnames'; +import {React} from 'react'; +import ReactRouter from 'react-router'; require('css/Button.less'); -var Button = React.createClass({ - propTypes: { - color: React.PropTypes.oneOf(['blue', 'green', 'yellow', 'red']), - href: React.PropTypes.string, - loading: React.PropTypes.bool, - size: React.PropTypes.oneOf(['small', 'medium', 'large']), - success: React.PropTypes.bool, - }, - - getDefaultProps: function() { - return { - color: 'blue', - loading: false, - size: 'medium', - success: false, - }; - }, - - render: function() { +class Button extends React.Component { + render() { var ButtonComponent = this.props.href ? ReactRouter.Link : 'button'; return ( @@ -54,7 +37,17 @@ var Button = React.createClass({ ); - }, -}); + } +}; + +Button.propTypes = { + color: React.PropTypes.oneOf(['blue', 'green', 'yellow', 'red']), + href: React.PropTypes.string, + loading: React.PropTypes.bool, + size: React.PropTypes.oneOf(['small', 'medium', 'large']), + success: React.PropTypes.bool, +} + + module.exports = Button; diff --git a/huxley/www/js/components/core/StatusLabel.js b/huxley/www/js/components/core/StatusLabel.js index ffdfc5c80..77d084184 100644 --- a/huxley/www/js/components/core/StatusLabel.js +++ b/huxley/www/js/components/core/StatusLabel.js @@ -5,17 +5,12 @@ 'use strict'; -var React = require('react'); - -var cx = require('classnames'); +import {React} from 'react'; +import cx from 'classnames'; require('css/StatusLabel.less'); -var StatusLabel = React.createClass({ - propTypes: { - status: React.PropTypes.oneOf(['success', 'error']).isRequired, - }, - +class StatusLabel extends React.Component { render() { return (
); - }, -}); + } +}; + +Table.propTypes = { + emptyMessage: React.PropTypes.string.isRequired, + isEmpty: React.PropTypes.bool.isRequired, +}, module.exports = Table; diff --git a/huxley/www/js/components/core/TextInput.js b/huxley/www/js/components/core/TextInput.js index 13058bb86..43d26241a 100644 --- a/huxley/www/js/components/core/TextInput.js +++ b/huxley/www/js/components/core/TextInput.js @@ -5,8 +5,8 @@ 'use strict'; -var React = require('react'); -var cx = require('classnames'); +import {React} from 'react'; +import cx from 'classnames'; require('css/TextInput.less'); @@ -15,17 +15,8 @@ require('css/TextInput.less'); * Controlled inputs cannot preserve cursor position upon rendering. * See issue #519. */ -var TextInput = React.createClass({ - propTypes: { - defaultValue: React.PropTypes.string, - isControlled: React.PropTypes.bool, - onChange: React.PropTypes.func, - placeholder: React.PropTypes.string, - value: React.PropTypes.string, - type: React.PropTypes.oneOf(['text', 'password']), - }, - - render: function() { +class TextInput extends React.Component{ + render() { return ( ); - }, - - _handleChange: function(event) { + } + _handleChange(event) { this.props.onChange && this.props.onChange(event.target.value); - }, -}); + } +}; + +TextInput.propTypes = { + defaultValue: React.PropTypes.string, + isControlled: React.PropTypes.bool, + onChange: React.PropTypes.func, + placeholder: React.PropTypes.string, + value: React.PropTypes.string, + type: React.PropTypes.oneOf(['text', 'password']), +} module.exports = TextInput; diff --git a/huxley/www/js/components/core/TextTemplate.js b/huxley/www/js/components/core/TextTemplate.js index df216b547..c45104aec 100644 --- a/huxley/www/js/components/core/TextTemplate.js +++ b/huxley/www/js/components/core/TextTemplate.js @@ -5,7 +5,7 @@ 'use strict'; -const React = require('react'); +import {React} from 'react'; const entityMap = { '&': '&', @@ -18,10 +18,10 @@ const entityMap = { '=': '=', }; -const TextTemplate = React.createClass({ +class TextTemplate extends React.Component { render() { return
; - }, + } createMarkup() { var text = this.props.children; @@ -30,15 +30,15 @@ const TextTemplate = React.createClass({ const value = this.escapeHtml(this.props[variable]); text = text.replace(regex, value); } - + return {__html: text}; - }, + } escapeHtml(string) { return String(string).replace(/[&<>"'`=\/]/g, function(s) { return entityMap[s]; }); - }, -}); + } +}; module.exports = TextTemplate; diff --git a/huxley/www/js/components/registration/RegistrationAccountInformation.js b/huxley/www/js/components/registration/RegistrationAccountInformation.js index 407d4106a..280aed238 100644 --- a/huxley/www/js/components/registration/RegistrationAccountInformation.js +++ b/huxley/www/js/components/registration/RegistrationAccountInformation.js @@ -5,21 +5,13 @@ 'use strict'; -var React = require('react'); +import {React} from 'react'; var RegistrationTextInput = require('components/registration/RegistrationTextInput'); var _accessSafe = require('utils/_accessSafe'); -const RegistrationAccountInformation = React.createClass({ - propTypes: { - handlers: React.PropTypes.object, - errors: React.PropTypes.object, - accountInformation: React.PropTypes.object, - blur: React.PropTypes.func, - focus: React.PropTypes.func, - }, - - shouldComponentUpdate: function(nextProps, nextState) { +class RegistrationAccountInformation extends React.Component { + shouldComponentUpdate(nextProps, nextState) { for (let key in this.props.accountInformation) { if ( this.props.accountInformation[key] !== nextProps.accountInformation[key] @@ -35,9 +27,9 @@ const RegistrationAccountInformation = React.createClass({ } return false; - }, + } - render: function() { + render() { var accessErrors = _accessSafe.bind(this, this.props.errors); var accessHandlers = _accessSafe.bind(this, this.props.handlers); var accessAccount = _accessSafe.bind(this, this.props.accountInformation); @@ -82,7 +74,15 @@ const RegistrationAccountInformation = React.createClass({ />
); - }, -}); + } +}; + +RegistrationAccountInformation.propTypes = { + handlers: React.PropTypes.object, + errors: React.PropTypes.object, + accountInformation: React.PropTypes.object, + blur: React.PropTypes.func, + focus: React.PropTypes.func, +} module.exports = RegistrationAccountInformation; diff --git a/huxley/www/js/components/registration/RegistrationComments.js b/huxley/www/js/components/registration/RegistrationComments.js index 039cf50bf..89da45072 100644 --- a/huxley/www/js/components/registration/RegistrationComments.js +++ b/huxley/www/js/components/registration/RegistrationComments.js @@ -5,19 +5,13 @@ 'use strict'; -var React = require('react'); +import React from 'react'; -const RegistrationComments = React.createClass({ - propTypes: { - handler: React.PropTypes.func, - value: React.PropTypes.string, - }, - - shouldComponentUpdate: function(nextProps, nextState) { +class RegistrationComments extends React.Component { + shouldComponentUpdate(nextProps, nextState) { return this.props.value !== nextProps.value; - }, - - render: function() { + } + render() { return (

Comments

@@ -35,7 +29,12 @@ const RegistrationComments = React.createClass({ />
); - }, -}); + } +}; + +RegistrationComments.propTypes = { + handler: React.PropTypes.func, + value: React.PropTypes.string, +} module.exports = RegistrationComments; diff --git a/huxley/www/js/components/registration/RegistrationCountryPreferences.js b/huxley/www/js/components/registration/RegistrationCountryPreferences.js index 9adf02db3..4f849610e 100644 --- a/huxley/www/js/components/registration/RegistrationCountryPreferences.js +++ b/huxley/www/js/components/registration/RegistrationCountryPreferences.js @@ -5,14 +5,10 @@ 'use strict'; -var React = require('react'); +import React from 'react'; -const RegistrationCountryPreferences = React.createClass({ - propTypes: { - renderCountryDropdown: React.PropTypes.func, - }, - - render: function() { +class RegistrationCountryPreferences extends React.Component { + render() { return (

Country Preferences

@@ -38,7 +34,11 @@ const RegistrationCountryPreferences = React.createClass({
); - }, -}); + } +}; + +RegistrationCountryPreferences.propTypes = { + renderCountryDropdown: React.PropTypes.func, +}, module.exports = RegistrationCountryPreferences; diff --git a/huxley/www/js/components/registration/RegistrationPhoneInput.js b/huxley/www/js/components/registration/RegistrationPhoneInput.js index 755333eaf..0051f8c7b 100644 --- a/huxley/www/js/components/registration/RegistrationPhoneInput.js +++ b/huxley/www/js/components/registration/RegistrationPhoneInput.js @@ -5,19 +5,12 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var PhoneInput = require('components/PhoneInput'); var StatusLabel = require('components/core/StatusLabel'); -const RegistrationPhoneInput = React.createClass({ - propTypes: { - errors: React.PropTypes.arrayOf(React.PropTypes.string), - onChange: React.PropTypes.func, - placeholder: React.PropTypes.string, - value: React.PropTypes.string, - }, - +class RegistrationPhoneInput extends React.Component { render() { const {errors, ...inputProps} = this.props; return ( @@ -31,7 +24,14 @@ const RegistrationPhoneInput = React.createClass({ )}
); - }, -}); + } +}; + +RegistrationPhoneInput.propTypes = { + errors: React.PropTypes.arrayOf(React.PropTypes.string), + onChange: React.PropTypes.func, + placeholder: React.PropTypes.string, + value: React.PropTypes.string, +} module.exports = RegistrationPhoneInput; diff --git a/huxley/www/js/components/registration/RegistrationPrimaryContact.js b/huxley/www/js/components/registration/RegistrationPrimaryContact.js index 3bd2ec77d..504239523 100644 --- a/huxley/www/js/components/registration/RegistrationPrimaryContact.js +++ b/huxley/www/js/components/registration/RegistrationPrimaryContact.js @@ -5,23 +5,14 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var RegistrationPhoneInput = require('components/registration/RegistrationPhoneInput'); var RegistrationTextInput = require('components/registration/RegistrationTextInput'); var _accessSafe = require('utils/_accessSafe'); -const RegistrationPrimaryContact = React.createClass({ - propTypes: { - handlers: React.PropTypes.object, - primaryContactInformation: React.PropTypes.object, - errors: React.PropTypes.object, - renderContactGenderField: React.PropTypes.func, - renderContactTypeField: React.PropTypes.func, - isInternational: React.PropTypes.bool, - }, - - render: function() { +class RegistrationPrimaryContact extends React.Component { + render() { var accessHandlers = _accessSafe.bind(this, this.props.handlers); var accessPrimary = _accessSafe.bind( this, @@ -54,7 +45,16 @@ const RegistrationPrimaryContact = React.createClass({ {this.props.renderContactTypeField('primary_type')} ); - }, -}); + } +}; + +RegistrationPrimaryContact.propTypes = { + handlers: React.PropTypes.object, + primaryContactInformation: React.PropTypes.object, + errors: React.PropTypes.object, + renderContactGenderField: React.PropTypes.func, + renderContactTypeField: React.PropTypes.func, + isInternational: React.PropTypes.bool, +} module.exports = RegistrationPrimaryContact; diff --git a/huxley/www/js/components/registration/RegistrationProgramInformation.js b/huxley/www/js/components/registration/RegistrationProgramInformation.js index f0eddda1f..f18fe19ba 100644 --- a/huxley/www/js/components/registration/RegistrationProgramInformation.js +++ b/huxley/www/js/components/registration/RegistrationProgramInformation.js @@ -5,22 +5,14 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var ProgramTypes = require('constants/ProgramTypes'); var NumberInput = require('components/NumberInput'); var _accessSafe = require('utils/_accessSafe'); -const RegistrationProgramInformation = React.createClass({ - propTypes: { - handlers: React.PropTypes.object, - errors: React.PropTypes.object, - programInformation: React.PropTypes.object, - handleProgramTypeChange: React.PropTypes.func, - programType: React.PropTypes.oneOf([ProgramTypes.CLUB, ProgramTypes.CLASS]), - }, - - shouldComponentUpdate: function(nextProps, nextState) { +class RegistrationProgramInformation extends React.Component { + shouldComponentUpdate(nextProps, nextState) { for (let key in this.props.programInformation) { if ( this.props.programInformation[key] !== nextProps.programInformation[key] @@ -36,9 +28,9 @@ const RegistrationProgramInformation = React.createClass({ } return this.props.programType !== nextProps.programType; - }, + } - render: function() { + render() { var accessHandlers = _accessSafe.bind(this, this.props.handlers); var accessErrors = _accessSafe.bind(this, this.props.errors); var accessProgram = _accessSafe.bind(this, this.props.programInformation); @@ -126,9 +118,9 @@ const RegistrationProgramInformation = React.createClass({

); - }, + } - _handleDelegateSum: function(beginner, intermediate, advanced) { + _handleDelegateSum(beginner, intermediate, advanced) { var sum = 0; if (beginner) { sum += parseInt(beginner, 10) || 0; @@ -140,7 +132,15 @@ const RegistrationProgramInformation = React.createClass({ sum += parseInt(advanced, 10) || 0; } return sum; - }, -}); + } +}; + +RegistrationProgramInformation.propTypes = { + handlers: React.PropTypes.object, + errors: React.PropTypes.object, + programInformation: React.PropTypes.object, + handleProgramTypeChange: React.PropTypes.func, + programType: React.PropTypes.oneOf([ProgramTypes.CLUB, ProgramTypes.CLASS]), +} module.exports = RegistrationProgramInformation; diff --git a/huxley/www/js/components/registration/RegistrationSchoolInformation.js b/huxley/www/js/components/registration/RegistrationSchoolInformation.js index c1835aae1..a2dcfcfae 100644 --- a/huxley/www/js/components/registration/RegistrationSchoolInformation.js +++ b/huxley/www/js/components/registration/RegistrationSchoolInformation.js @@ -5,21 +5,13 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var RegistrationTextInput = require('components/registration/RegistrationTextInput'); var _accessSafe = require('utils/_accessSafe'); -const RegistrationSchoolInformation = React.createClass({ - propTypes: { - handlers: React.PropTypes.object, - errors: React.PropTypes.object, - schoolInformation: React.PropTypes.object, - handleInternationalChange: React.PropTypes.func, - schoolInternational: React.PropTypes.bool, - }, - - shouldComponentUpdate: function(nextProps, nextState) { +class RegistrationSchoolInformation extends React.Component { + shouldComponentUpdate(nextProps, nextState) { for (let key in this.props.schoolInformation) { if ( this.props.schoolInformation[key] !== nextProps.schoolInformation[key] @@ -35,9 +27,9 @@ const RegistrationSchoolInformation = React.createClass({ } return this.props.schoolInternational !== nextProps.schoolInternational; - }, + } - render: function() { + render() { var accessErrors = _accessSafe.bind(this, this.props.errors); var accessHandlers = _accessSafe.bind(this, this.props.handlers); var accessSchool = _accessSafe.bind(this, this.props.schoolInformation); @@ -109,7 +101,15 @@ const RegistrationSchoolInformation = React.createClass({ /> ); - }, -}); + } +}; + +RegistrationSchoolInformation.propTypes = { + handlers: React.PropTypes.object, + errors: React.PropTypes.object, + schoolInformation: React.PropTypes.object, + handleInternationalChange: React.PropTypes.func, + schoolInternational: React.PropTypes.bool, +} module.exports = RegistrationSchoolInformation; diff --git a/huxley/www/js/components/registration/RegistrationSecondaryContact.js b/huxley/www/js/components/registration/RegistrationSecondaryContact.js index f4cd4f587..d8c55c09e 100644 --- a/huxley/www/js/components/registration/RegistrationSecondaryContact.js +++ b/huxley/www/js/components/registration/RegistrationSecondaryContact.js @@ -5,23 +5,14 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var RegistrationPhoneInput = require('components/registration/RegistrationPhoneInput'); var RegistrationTextInput = require('components/registration/RegistrationTextInput'); var _accessSafe = require('utils/_accessSafe'); -const RegistrationSecondaryContact = React.createClass({ - propTypes: { - handlers: React.PropTypes.object, - secondaryContactInformation: React.PropTypes.object, - errors: React.PropTypes.object, - renderContactGenderField: React.PropTypes.func, - renderContactTypeField: React.PropTypes.func, - isInternational: React.PropTypes.bool, - }, - - render: function() { +class RegistrationSecondaryContact extends React.Component { + render() { var accessHandlers = _accessSafe.bind(this, this.props.handlers); var accessSecondary = _accessSafe.bind( this, @@ -54,7 +45,16 @@ const RegistrationSecondaryContact = React.createClass({ {this.props.renderContactTypeField('secondary_type')} ); - }, -}); + } +}; + +RegistrationSecondaryContact.propTypes = { + handlers: React.PropTypes.object, + secondaryContactInformation: React.PropTypes.object, + errors: React.PropTypes.object, + renderContactGenderField: React.PropTypes.func, + renderContactTypeField: React.PropTypes.func, + isInternational: React.PropTypes.bool, +} module.exports = RegistrationSecondaryContact; diff --git a/huxley/www/js/components/registration/RegistrationSpecialCommitteePreferences.js b/huxley/www/js/components/registration/RegistrationSpecialCommitteePreferences.js index bcc450a23..2be415c78 100644 --- a/huxley/www/js/components/registration/RegistrationSpecialCommitteePreferences.js +++ b/huxley/www/js/components/registration/RegistrationSpecialCommitteePreferences.js @@ -5,20 +5,13 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var NumberInput = require('components/NumberInput'); var _accessSafe = require('utils/_accessSafe'); -const RegistrationSpecialCommitteePreferences = React.createClass({ - propTypes: { - handlers: React.PropTypes.object, - errors: React.PropTypes.object, - specialCommitteePrefValues: React.PropTypes.object, - renderCommittees: React.PropTypes.func, - }, - - render: function() { +class RegistrationSpecialCommitteePreferences extends React.Component { + render() { var accessHandlers = _accessSafe.bind(this, this.props.handlers); var accessErrors = _accessSafe.bind(this, this.props.errors); var accessValues = _accessSafe.bind( @@ -52,7 +45,14 @@ const RegistrationSpecialCommitteePreferences = React.createClass({ {accessErrors('num_chinese_speaking_delegates')} ); - }, -}); + } +}; + +RegistrationSpecialCommitteePreferences.propTypes = { + handlers: React.PropTypes.object, + errors: React.PropTypes.object, + specialCommitteePrefValues: React.PropTypes.object, + renderCommittees: React.PropTypes.func, +} module.exports = RegistrationSpecialCommitteePreferences; diff --git a/huxley/www/js/components/registration/RegistrationTextInput.js b/huxley/www/js/components/registration/RegistrationTextInput.js index da30bdd20..a48571fd9 100644 --- a/huxley/www/js/components/registration/RegistrationTextInput.js +++ b/huxley/www/js/components/registration/RegistrationTextInput.js @@ -5,20 +5,12 @@ 'use strict'; -var React = require('react'); +import React from 'react'; var TextInput = require('components/core/TextInput'); var StatusLabel = require('components/core/StatusLabel'); -const RegistrationTextInput = React.createClass({ - propTypes: { - errors: React.PropTypes.arrayOf(React.PropTypes.string), - onChange: React.PropTypes.func, - placeholder: React.PropTypes.string, - value: React.PropTypes.string, - type: React.PropTypes.oneOf(['text', 'password']), - }, - +class RegistrationTextInput extends React.Component { render() { const {errors, ...inputProps} = this.props; return ( @@ -32,7 +24,15 @@ const RegistrationTextInput = React.createClass({ )} ); - }, -}); + } +}; + +RegistrationTextInput.propTypes = { + errors: React.PropTypes.arrayOf(React.PropTypes.string), + onChange: React.PropTypes.func, + placeholder: React.PropTypes.string, + value: React.PropTypes.string, + type: React.PropTypes.oneOf(['text', 'password']), +} module.exports = RegistrationTextInput; From 6a6c5f85d0f9eb211f9f4386f72086cbace5df4e Mon Sep 17 00:00:00 2001 From: Shayna Kothari Date: Mon, 11 Jan 2021 15:42:06 -0800 Subject: [PATCH 07/80] formatted --- .../js/components/AdvisorAssignmentsView.js | 111 ++++---- .../www/js/components/AdvisorFeedbackView.js | 59 ++--- huxley/www/js/components/AdvisorPaperView.js | 145 ++++++----- .../www/js/components/AdvisorProfileView.js | 227 ++++++++-------- huxley/www/js/components/AdvisorRosterView.js | 136 +++++----- huxley/www/js/components/AdvisorView.js | 24 +- .../www/js/components/ChairAttendanceView.js | 121 +++++---- .../components/ChairCommitteeFeedbackView.js | 76 +++--- .../js/components/ChairDelegateEmailView.js | 85 +++--- huxley/www/js/components/ChairPapersView.js | 105 ++++---- huxley/www/js/components/ChairRubricView.js | 145 +++++------ huxley/www/js/components/ChairSummaryView.js | 156 ++++++----- huxley/www/js/components/ChairView.js | 12 +- .../www/js/components/ChangePasswordView.js | 83 +++--- huxley/www/js/components/ConferenceContext.js | 4 +- huxley/www/js/components/CountrySelect.js | 21 +- .../DelegateCommitteeFeedbackView.js | 242 +++++++++--------- huxley/www/js/components/DelegatePaperView.js | 113 ++++---- .../www/js/components/DelegateProfileView.js | 66 ++--- huxley/www/js/components/DelegateSelect.js | 19 +- huxley/www/js/components/DelegateView.js | 12 +- .../js/components/DelegationAttendanceRow.js | 27 +- .../www/js/components/ForgotPasswordView.js | 86 +++---- huxley/www/js/components/Huxley.js | 76 +++--- huxley/www/js/components/InnerView.js | 14 +- huxley/www/js/components/LoginView.js | 130 +++++----- huxley/www/js/components/LogoutButton.js | 35 +-- huxley/www/js/components/NavLink.js | 36 +-- huxley/www/js/components/NavTab.js | 22 +- huxley/www/js/components/NotFoundView.js | 15 +- huxley/www/js/components/NumberInput.js | 32 +-- huxley/www/js/components/OuterView.js | 26 +- .../www/js/components/PaperAssignmentList.js | 92 ++++--- huxley/www/js/components/PaperGradeTable.js | 204 +++++++-------- scripts/.prettierrc | 4 + 35 files changed, 1393 insertions(+), 1368 deletions(-) create mode 100644 scripts/.prettierrc diff --git a/huxley/www/js/components/AdvisorAssignmentsView.js b/huxley/www/js/components/AdvisorAssignmentsView.js index 3a8575433..a7e555fe8 100644 --- a/huxley/www/js/components/AdvisorAssignmentsView.js +++ b/huxley/www/js/components/AdvisorAssignmentsView.js @@ -3,35 +3,34 @@ * Use of this source code is governed by a BSD License (see LICENSE). */ -'use strict'; - -import React from 'react'; - -var _accessSafe = require('utils/_accessSafe'); -var AssignmentActions = require('actions/AssignmentActions'); -var AssignmentStore = require('stores/AssignmentStore'); -var Button = require('components/core/Button'); -var _checkDate = require('utils/_checkDate'); -var CommitteeStore = require('stores/CommitteeStore'); -var ConferenceContext = require('components/ConferenceContext'); -var CountryStore = require('stores/CountryStore'); -var CurrentUserStore = require('stores/CurrentUserStore'); -var CurrentUserActions = require('actions/CurrentUserActions'); -var DelegateActions = require('actions/DelegateActions'); -var DelegateSelect = require('components/DelegateSelect'); -var DelegateStore = require('stores/DelegateStore'); -var InnerView = require('components/InnerView'); -var RegistrationActions = require('actions/RegistrationActions'); -var RegistrationStore = require('stores/RegistrationStore'); -var ServerAPI = require('lib/ServerAPI'); -var Table = require('components/core/Table'); -var TextTemplate = require('components/core/TextTemplate'); - -var AdvisorAssignmentsViewText = require('text/AdvisorAssignmentsViewText.md'); -var AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); +"use strict"; + +import React from "react"; + +var _accessSafe = require("utils/_accessSafe"); +var AssignmentActions = require("actions/AssignmentActions"); +var AssignmentStore = require("stores/AssignmentStore"); +var Button = require("components/core/Button"); +var _checkDate = require("utils/_checkDate"); +var CommitteeStore = require("stores/CommitteeStore"); +var ConferenceContext = require("components/ConferenceContext"); +var CountryStore = require("stores/CountryStore"); +var CurrentUserStore = require("stores/CurrentUserStore"); +var CurrentUserActions = require("actions/CurrentUserActions"); +var DelegateActions = require("actions/DelegateActions"); +var DelegateSelect = require("components/DelegateSelect"); +var DelegateStore = require("stores/DelegateStore"); +var InnerView = require("components/InnerView"); +var RegistrationActions = require("actions/RegistrationActions"); +var RegistrationStore = require("stores/RegistrationStore"); +var ServerAPI = require("lib/ServerAPI"); +var Table = require("components/core/Table"); +var TextTemplate = require("components/core/TextTemplate"); + +var AdvisorAssignmentsViewText = require("text/AdvisorAssignmentsViewText.md"); +var AdvisorWaitlistText = require("text/AdvisorWaitlistText.md"); class AdvisorAssignmentsView extends React.Component { - getInitialState() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var delegates = DelegateStore.getSchoolDelegates(schoolID); @@ -40,7 +39,7 @@ class AdvisorAssignmentsView extends React.Component { return { assigned: assigned, assignments: AssignmentStore.getSchoolAssignments(schoolID).filter( - assignment => !assignment.rejected, + (assignment) => !assignment.rejected ), committees: CommitteeStore.getCommittees(), countries: CountryStore.getCountries(), @@ -56,11 +55,11 @@ class AdvisorAssignmentsView extends React.Component { var conferenceID = this.context.conference.session; this._committeesToken = CommitteeStore.addListener(() => { - this.setState({committees: CommitteeStore.getCommittees()}); + this.setState({ committees: CommitteeStore.getCommittees() }); }); this._countriesToken = CountryStore.addListener(() => { - this.setState({countries: CountryStore.getCountries()}); + this.setState({ countries: CountryStore.getCountries() }); }); this._delegatesToken = DelegateStore.addListener(() => { @@ -76,7 +75,7 @@ class AdvisorAssignmentsView extends React.Component { this._assignmentsToken = AssignmentStore.addListener(() => { this.setState({ assignments: AssignmentStore.getSchoolAssignments(schoolID).filter( - assignment => !assignment.rejected, + (assignment) => !assignment.rejected ), }); }); @@ -100,11 +99,11 @@ class AdvisorAssignmentsView extends React.Component { render() { var registration = this.state.registration; var waitlisted = - _accessSafe(registration, 'is_waitlisted') == null + _accessSafe(registration, "is_waitlisted") == null ? null : registration.is_waitlisted; var finalized = - _accessSafe(this.state.registration, 'assignments_finalized') == null + _accessSafe(this.state.registration, "assignments_finalized") == null ? false : this.state.registration.assignments_finalized; var committees = this.state.committees; @@ -121,7 +120,8 @@ class AdvisorAssignmentsView extends React.Component { + conferenceExternal={conference.external} + > {AdvisorWaitlistText} @@ -134,14 +134,15 @@ class AdvisorAssignmentsView extends React.Component { + isEmpty={!shouldRenderAssignments} + > - - + + @@ -152,8 +153,9 @@ class AdvisorAssignmentsView extends React.Component { color="green" onClick={finalized ? this._handleSave : this._handleFinalize} loading={this.state.loading} - success={this.state.success}> - {finalized ? 'Save' : 'Finalize Assignments'} + success={this.state.success} + > + {finalized ? "Save" : "Finalize Assignments"} ); @@ -164,11 +166,11 @@ class AdvisorAssignmentsView extends React.Component { var committees = this.state.committees; var countries = this.state.countries; var finalized = - _accessSafe(this.state.registration, 'assignments_finalized') == null + _accessSafe(this.state.registration, "assignments_finalized") == null ? false : this.state.registration.assignments_finalized; return this.state.assignments.map( - function(assignment) { + function (assignment) { return ( @@ -181,7 +183,8 @@ class AdvisorAssignmentsView extends React.Component { )} @@ -196,7 +199,7 @@ class AdvisorAssignmentsView extends React.Component { ); - }.bind(this), + }.bind(this) ); } @@ -236,7 +239,7 @@ class AdvisorAssignmentsView extends React.Component { onChange={this._handleDelegateAssignment.bind( this, assignment.id, - slot, + slot )} delegates={this.state.delegates} selectedDelegateID={selectedDelegateID} @@ -279,7 +282,7 @@ class AdvisorAssignmentsView extends React.Component { _handleFinalize(event) { var confirm = window.confirm( - 'By pressing okay you are committing to the financial responsibility of each assignment. Are you sure you want to finalize assignments?', + "By pressing okay you are committing to the financial responsibility of each assignment. Are you sure you want to finalize assignments?" ); if (confirm) { RegistrationActions.updateRegistration( @@ -287,14 +290,14 @@ class AdvisorAssignmentsView extends React.Component { { assignments_finalized: true, }, - this._handleError, + this._handleError ); } } _handleAssignmentDelete(assignment) { var confirm = window.confirm( - 'Are you sure you want to delete this assignment?', + "Are you sure you want to delete this assignment?" ); if (confirm) { AssignmentActions.updateAssignment( @@ -302,20 +305,20 @@ class AdvisorAssignmentsView extends React.Component { { rejected: true, }, - this._handleError, + this._handleError ); } } _handleSave(event) { this._successTimout && clearTimeout(this._successTimeout); - this.setState({loading: true}); + this.setState({ loading: true }); var school = CurrentUserStore.getCurrentUser().school; DelegateActions.updateDelegates( school.id, this.state.delegates, this._handleSuccess, - this._handleError, + this._handleError ); } @@ -326,15 +329,15 @@ class AdvisorAssignmentsView extends React.Component { }); this._successTimeout = setTimeout( - () => this.setState({success: false}), - 2000, + () => this.setState({ success: false }), + 2000 ); } _handleError(response) { - this.setState({loading: false}); + this.setState({ loading: false }); window.alert( - 'Something went wrong. Please refresh your page and try again.', + "Something went wrong. Please refresh your page and try again." ); } } diff --git a/huxley/www/js/components/AdvisorFeedbackView.js b/huxley/www/js/components/AdvisorFeedbackView.js index aea421106..c0e9432c3 100644 --- a/huxley/www/js/components/AdvisorFeedbackView.js +++ b/huxley/www/js/components/AdvisorFeedbackView.js @@ -1,37 +1,36 @@ /** * Copyright (c) 2011-2015 Berkeley Model United Nations. All rights reserved. * Use of this source code is governed by a BSD License (see LICENSE). -*/ + */ -'use strict'; +"use strict"; -import React from 'react'; +import React from "react"; -var _accessSafe = require('utils/_accessSafe'); -var AssignmentActions = require('actions/AssignmentActions'); -var AssignmentStore = require('stores/AssignmentStore'); -var Button = require('components/core/Button'); -var CommitteeStore = require('stores/CommitteeStore'); -var ConferenceContext = require('components/ConferenceContext'); -var CountryStore = require('stores/CountryStore'); -var CurrentUserStore = require('stores/CurrentUserStore'); -var DelegateStore = require('stores/DelegateStore'); -var InnerView = require('components/InnerView'); -var RegistrationStore = require('stores/RegistrationStore'); -var Table = require('components/core/Table'); -var TextTemplate = require('components/core/TextTemplate'); +var _accessSafe = require("utils/_accessSafe"); +var AssignmentActions = require("actions/AssignmentActions"); +var AssignmentStore = require("stores/AssignmentStore"); +var Button = require("components/core/Button"); +var CommitteeStore = require("stores/CommitteeStore"); +var ConferenceContext = require("components/ConferenceContext"); +var CountryStore = require("stores/CountryStore"); +var CurrentUserStore = require("stores/CurrentUserStore"); +var DelegateStore = require("stores/DelegateStore"); +var InnerView = require("components/InnerView"); +var RegistrationStore = require("stores/RegistrationStore"); +var Table = require("components/core/Table"); +var TextTemplate = require("components/core/TextTemplate"); -var AdvisorFeedbackViewText = require('text/AdvisorFeedbackViewText.md'); -var AdvisorWaitlistText = require('text/AdvisorWaitlistText.md'); +var AdvisorFeedbackViewText = require("text/AdvisorFeedbackViewText.md"); +var AdvisorWaitlistText = require("text/AdvisorWaitlistText.md"); class AdvisorFeedbackView extends React.Component { - getInitialState() { var schoolID = CurrentUserStore.getCurrentUser().school.id; var delegates = DelegateStore.getSchoolDelegates(schoolID); var conferenceID = this.context.conference.session; var assignments = AssignmentStore.getSchoolAssignments(schoolID).filter( - assignment => !assignment.rejected, + (assignment) => !assignment.rejected ); var feedback = this.prepareFeedback(delegates); return { @@ -55,17 +54,17 @@ class AdvisorFeedbackView extends React.Component { }); this._committeesToken = CommitteeStore.addListener(() => { - this.setState({committees: CommitteeStore.getCommittees()}); + this.setState({ committees: CommitteeStore.getCommittees() }); }); this._countriesToken = CountryStore.addListener(() => { - this.setState({countries: CountryStore.getCountries()}); + this.setState({ countries: CountryStore.getCountries() }); }); this._assignmentsToken = AssignmentStore.addListener(() => { this.setState({ assignments: AssignmentStore.getSchoolAssignments(schoolID).filter( - assignment => !assignment.rejected, + (assignment) => !assignment.rejected ), }); }); @@ -91,7 +90,7 @@ class AdvisorFeedbackView extends React.Component { render() { var registration = this.state.registration; var waitlisted = - _accessSafe(registration, 'is_waitlisted') == null + _accessSafe(registration, "is_waitlisted") == null ? null : registration.is_waitlisted; if (waitlisted) { @@ -99,7 +98,8 @@ class AdvisorFeedbackView extends React.Component { + conferenceExternal={conference.external} + > {AdvisorWaitlistText} @@ -110,7 +110,8 @@ class AdvisorFeedbackView extends React.Component { {AdvisorFeedbackViewText}
Committee Country Delegation Size{finalized ? 'Delegate' : 'Delete Assignments'}{finalized ? 'Delegate' : ''}{finalized ? "Delegate" : "Delete Assignments"}{finalized ? "Delegate" : ""}
{committees[assignment.committee].name}
+ isEmpty={!Object.keys(this.state.feedback).length} + > @@ -134,7 +135,7 @@ class AdvisorFeedbackView extends React.Component { var committees = this.state.committees; var countries = this.state.countries; var feedback = this.state.feedback; - return assignments.map(assignment => { + return assignments.map((assignment) => { var delegates = feedback[assignment.id]; if (delegates == null) { return; @@ -178,7 +179,7 @@ class AdvisorFeedbackView extends React.Component {
Committee