From f8506e9763e9718cafde001a24cf80c91f2ffc42 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Fri, 9 Mar 2018 15:53:46 -0500 Subject: [PATCH] got metacode sets working --- README.md | 4 +- apiProxyMiddleware.js | 3 +- src/Metamaps/Admin.js | 49 ---------- src/Metamaps/DataFetcher.js | 118 +++++++++++++++++++--- src/Metamaps/GlobalUI/ReactApp.js | 13 ++- src/Metamaps/index.js | 3 +- src/routes/Admin/EditMetacode.js | 4 +- src/routes/Admin/EditMetacodeSet.js | 33 ++++++- src/routes/Admin/MetacodeSetEditor.js | 135 ++++++++++++++++++++++++++ src/routes/Admin/MetacodeSets.js | 7 +- src/routes/Admin/NewMetacode.js | 4 +- src/routes/Admin/NewMetacodeSet.js | 30 +++++- views/metacode_sets/_form.js | 89 ----------------- views/metacode_sets/edit.js | 24 ----- views/metacode_sets/new.js | 24 ----- 15 files changed, 325 insertions(+), 215 deletions(-) delete mode 100644 src/Metamaps/Admin.js create mode 100644 src/routes/Admin/MetacodeSetEditor.js delete mode 100644 views/metacode_sets/_form.js delete mode 100644 views/metacode_sets/edit.js delete mode 100644 views/metacode_sets/new.js diff --git a/README.md b/README.md index 7bad342d..d58b9d77 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ Checklist - [ ] new metacode - [ ] edit metacode - [x] list metacode_sets - - [ ] new metacode set - - [ ] edit metacode set + - [x] new metacode set + - [x] edit metacode set - [ ] authorized apps - [ ] registered apps - [ ] authorize diff --git a/apiProxyMiddleware.js b/apiProxyMiddleware.js index 47c5752a..46ce9693 100644 --- a/apiProxyMiddleware.js +++ b/apiProxyMiddleware.js @@ -1,7 +1,8 @@ const request = require('request') function apiProxyMiddleware (req, res, next) { - if (!(req.xhr || req.originalUrl.indexOf('.json') > -1 || req.method !== 'GET')) { + // TODO: tidy this up! + if (!(req.xhr || req.headers['Content-Type'] === 'application/json' || req.originalUrl.indexOf('.json') > -1 || req.method !== 'GET')) { return next() } const method = req.method.toLowerCase() diff --git a/src/Metamaps/Admin.js b/src/Metamaps/Admin.js deleted file mode 100644 index 9cb80750..00000000 --- a/src/Metamaps/Admin.js +++ /dev/null @@ -1,49 +0,0 @@ -/* global $ */ - -const Admin = { - selectMetacodes: [], - allMetacodes: [], - init: function() { - var self = Admin - - $('#metacodes_value').val(self.selectMetacodes.toString()) - }, - selectAll: function() { - var self = Admin - - $('.editMetacodes li').removeClass('toggledOff') - self.selectMetacodes = self.allMetacodes.slice(0) - $('#metacodes_value').val(self.selectMetacodes.toString()) - }, - deselectAll: function() { - var self = Admin - - $('.editMetacodes li').addClass('toggledOff') - self.selectMetacodes = [] - $('#metacodes_value').val(0) - }, - liClickHandler: function() { - var self = Admin - - if ($(this).attr('class') !== 'toggledOff') { - $(this).addClass('toggledOff') - const valueToRemove = $(this).attr('id') - self.selectMetacodes.splice(self.selectMetacodes.indexOf(valueToRemove), 1) - $('#metacodes_value').val(self.selectMetacodes.toString()) - } else if ($(this).attr('class') === 'toggledOff') { - $(this).removeClass('toggledOff') - self.selectMetacodes.push($(this).attr('id')) - $('#metacodes_value').val(self.selectMetacodes.toString()) - } - }, - validate: function() { - var self = Admin - - if (self.selectMetacodes.length === 0) { - window.alert('Would you pretty please select at least one metacode for the set?') - return false - } - } -} - -export default Admin diff --git a/src/Metamaps/DataFetcher.js b/src/Metamaps/DataFetcher.js index 6ebad3b7..c69bee21 100644 --- a/src/Metamaps/DataFetcher.js +++ b/src/Metamaps/DataFetcher.js @@ -1,51 +1,145 @@ -function fetchWithCookies(url) { - return fetch(url, { credentials: 'same-origin' }) +function get(url) { + return fetch(url, { + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json' + } + }) } -function postWithCookies(url, data = {}) { +function post(url, data = {}) { return fetch(url, { credentials: 'same-origin', method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, body: JSON.stringify(data) }) } +function put(url, data = {}) { + return fetch(url, { + credentials: 'same-origin', + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }) +} + +function deleteReq(url) { + return fetch(url, { + credentials: 'same-origin', + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + } + }) +} + async function getMetacodes() { - const res = await fetchWithCookies('/metacodes.json') + const res = await get('/metacodes') const data = await res.json() return data } async function getMetacodeSets() { - const res = await fetchWithCookies('/metacode_sets.json') + const res = await get('/metacode_sets') const data = await res.json() return data } +async function createMetacodeSet(metacodes, name, desc) { + const res = await post(`/metacode_sets`, { + metacodes: { + value: metacodes.toString() + }, + metacode_set: { + name, + desc + } + }) + if (!res.ok) { + throw new Error() + return + } + const data = await res.json() + return data +} + +async function updateMetacodeSet(id, metacodes, name, desc) { + const res = await put(`/metacode_sets/${id}`, { + metacodes: { + value: metacodes.toString() + }, + metacode_set: { + name, + desc + } + }) + if (!res.ok) { + throw new Error() + return + } + return true +} + +async function deleteMetacodeSet(id) { + const res = await deleteReq(`/metacode_sets/${id}`) + return res.ok +} + +async function createMetacode(name, color, icon) { + const res = await post(`/metacodes`, { + metacode: { + name, + color + } + }) + if (!res.ok) { + throw new Error() + return + } + const data = await res.json() + return data +} + +async function updateMetacode(id, name, color, icon) { + const res = await put(`/metacodes/${id}`) + return res.ok +} + async function getCurrentUser() { - const res = await fetchWithCookies('/users/current.json') + const res = await get('/users/current') const data = await res.json() return data } async function approveAccessRequest(mapId, requestId) { - const res = await postWithCookies(`/maps/${mapId}/approve_access/${requestId}`) - return res.status === 200 + const res = await post(`/maps/${mapId}/approve_access/${requestId}`) + return res.ok } async function denyAccessRequest(mapId, requestId) { - const res = await postWithCookies(`/maps/${mapId}/deny_access/${requestId}`) - return res.status === 200 + const res = await post(`/maps/${mapId}/deny_access/${requestId}`) + return res.ok } async function requestAccess(mapId) { - const res = await postWithCookies(`/maps/${mapId}/access_request`) - return res.status === 200 + const res = await post(`/maps/${mapId}/access_request`) + return res.ok } module.exports = { getMetacodes, getMetacodeSets, + createMetacodeSet, + updateMetacodeSet, + deleteMetacodeSet, + createMetacode, + updateMetacode, getCurrentUser, approveAccessRequest, denyAccessRequest, diff --git a/src/Metamaps/GlobalUI/ReactApp.js b/src/Metamaps/GlobalUI/ReactApp.js index 5c7ec981..1af64aa0 100644 --- a/src/Metamaps/GlobalUI/ReactApp.js +++ b/src/Metamaps/GlobalUI/ReactApp.js @@ -122,7 +122,8 @@ const ReactApp = { self.getMapsProps(), self.getContextMenuProps(), self.getTopicCardProps(), - self.getChatProps()) + self.getChatProps(), + self.getAdminProps()) }, getMapProps: function() { const self = ReactApp @@ -255,6 +256,16 @@ const ReactApp = { filterAllSynapses: Filter.filterAllSynapses } }, + getAdminProps: function() { + const self = ReactApp + return { + createMetacodeSet: DataFetcher.createMetacodeSet, + updateMetacodeSet: DataFetcher.updateMetacodeSet, + deleteMetacodeSet: DataFetcher.deleteMetacodeSet, + createMetacode: DataFetcher.createMetacode, + updateMetacode: DataFetcher.updateMetacode + } + }, resize: function() { const self = ReactApp const maps = ExploreMaps.collection diff --git a/src/Metamaps/index.js b/src/Metamaps/index.js index 77774e93..0770b30f 100644 --- a/src/Metamaps/index.js +++ b/src/Metamaps/index.js @@ -1,5 +1,4 @@ import Active from './Active' -import Admin from './Admin' import AutoLayout from './AutoLayout' import Cable from './Cable' import Control from './Control' @@ -32,7 +31,6 @@ import Visualize from './Visualize' const Metamaps = window.Metamaps || {} Metamaps.Active = Active -Metamaps.Admin = Admin Metamaps.AutoLayout = AutoLayout Metamaps.Cable = Cable Metamaps.Control = Control @@ -86,6 +84,7 @@ function runInitFunctions(serverData) { document.addEventListener('DOMContentLoaded', async function() { Metamaps.ServerData = Metamaps.ServerData || {} try { + // TODO: do these in parallel (Promise.all) const metacodes = await DataFetcher.getMetacodes() Metamaps.ServerData.Metacodes = metacodes diff --git a/src/routes/Admin/EditMetacode.js b/src/routes/Admin/EditMetacode.js index 036286c4..0d0f29e8 100644 --- a/src/routes/Admin/EditMetacode.js +++ b/src/routes/Admin/EditMetacode.js @@ -1,7 +1,7 @@ import React, { Component } from 'react' import AdminHeader from './AdminHeader' -class Metacodes extends Component { +class EditMetacode extends Component { render = () => { return (
@@ -11,4 +11,4 @@ class Metacodes extends Component { } } -export default Metacodes \ No newline at end of file +export default EditMetacode \ No newline at end of file diff --git a/src/routes/Admin/EditMetacodeSet.js b/src/routes/Admin/EditMetacodeSet.js index 036286c4..08b11324 100644 --- a/src/routes/Admin/EditMetacodeSet.js +++ b/src/routes/Admin/EditMetacodeSet.js @@ -1,14 +1,41 @@ import React, { Component } from 'react' -import AdminHeader from './AdminHeader' +import { browserHistory } from 'react-router' + +import AdminHeader from './AdminHeader' +import MetacodeSetEditor from './MetacodeSetEditor' + +/* +TODO: + get the data actually updating after the network response +*/ + +class EditMetacodeSet extends Component { + onSubmit = async (metacodes, name, desc) => { + const { updateMetacodeSet, params: { id } } = this.props + try { + const result = await updateMetacodeSet(id, metacodes, name, desc) + browserHistory.push(`/metacode_sets`) + } catch (e) { + console.log(e) + window.alert('There was an error updating the metacode set') + } + } -class Metacodes extends Component { render = () => { + const { metacodeSets, metacodes } = this.props + const id = parseInt(this.props.params.id, 10) + const metacodeSet = metacodeSets.find(m => m.id === id) return (
+
+
+ +
+
) } } -export default Metacodes \ No newline at end of file +export default EditMetacodeSet \ No newline at end of file diff --git a/src/routes/Admin/MetacodeSetEditor.js b/src/routes/Admin/MetacodeSetEditor.js new file mode 100644 index 00000000..bf2f840a --- /dev/null +++ b/src/routes/Admin/MetacodeSetEditor.js @@ -0,0 +1,135 @@ +import React, { Component } from 'react' +import { Link } from 'react-router' + +class MetacodeSetEditor extends Component { + constructor(props) { + super(props) + this.state = { + selectMetacodes: [], + name: '', + desc: '' + } + } + + componentDidMount() { + const { forEdit, metacodeSet } = this.props + if (forEdit) { + this.setState({ + selectMetacodes: metacodeSet.metacodes, + name: metacodeSet.name, + desc: metacodeSet.desc + }) + } + } + + selectAll = () => { + this.setState({ + selectMetacodes: this.props.metacodes.map(m => m.id) + }) + } + + deselectAll = () => { + this.setState({ selectMetacodes: [] }) + } + + liClickHandler = (metacodeId) => { + const { selectMetacodes } = this.state + if (selectMetacodes.indexOf(metacodeId) > -1) { + this.setState({ + selectMetacodes: selectMetacodes.filter(id => id !== metacodeId) + }) + } else { + this.setState({ + selectMetacodes: selectMetacodes.concat([metacodeId]) + }) + } + } + + updateForKey = (key) => event => this.setState({[key]: event.target.value}) + + validate = (event) => { + if (this.state.selectMetacodes.length === 0) { + event.preventDefault() + window.alert('Please select at least one metacode for the set') + } else if (this.state.name.length === 0) { + event.preventDefault() + window.alert('A name must be provided') + } + } + + onSubmit = (event) => { + event.preventDefault() + const { selectMetacodes, name, desc } = this.state + this.props.onSubmit(selectMetacodes, name, desc) + } + + render = () => { + const { selectMetacodes } = this.state + const { metacodes, forNew, forEdit } = this.props + const { length } = metacodes + return ( +
+ +
+ + +
+
+
+ +