diff --git a/client/coral-admin/src/components/App.css b/client/coral-admin/src/components/App.css new file mode 100644 index 000000000..39c7cf942 --- /dev/null +++ b/client/coral-admin/src/components/App.css @@ -0,0 +1,11 @@ +:global { + html, body, #root, #root > div { + min-height: 100%; + } + + body { + margin: 0; + background-color: #FAFAFA; + font-family: 'Roboto', sans-serif; + } +} diff --git a/client/coral-admin/src/components/App.js b/client/coral-admin/src/components/App.js index 52535f91a..a7ab1e336 100644 --- a/client/coral-admin/src/components/App.js +++ b/client/coral-admin/src/components/App.js @@ -1,5 +1,6 @@ import React from 'react'; import ToastContainer from './ToastContainer'; +import './App.css'; import 'material-design-lite'; import AppRouter from '../AppRouter'; diff --git a/middleware/staticTemplate.js b/middleware/staticTemplate.js index f16caaea9..d8137693e 100644 --- a/middleware/staticTemplate.js +++ b/middleware/staticTemplate.js @@ -94,9 +94,13 @@ const createResolveFactory = (() => { module.exports = async (req, res, next) => { try { - // Attach the custom css url. - const { customCssUrl } = await SettingsService.select('customCssUrl'); + // Attach the custom css url and organization name. + const { customCssUrl, organizationName } = await SettingsService.select( + 'customCssUrl', + 'organizationName' + ); res.locals.customCssUrl = customCssUrl; + res.locals.organizationName = organizationName; } catch (err) { console.warn(err); } diff --git a/package.json b/package.json index f6ff46a59..01b671dde 100644 --- a/package.json +++ b/package.json @@ -219,6 +219,7 @@ "babel-plugin-dynamic-import-node": "^1.1.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", "browserstack-local": "^1.3.0", + "casual": "^1.5.19", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", "chai-datetime": "^1.5.0", diff --git a/public/css/dev.css b/public/css/dev.css new file mode 100644 index 000000000..2fd6c1982 --- /dev/null +++ b/public/css/dev.css @@ -0,0 +1,9 @@ +.container { + width: auto; + max-width: 680px; + padding: 0 15px; +} + +.graphiql em { + font-family: georgia; +} diff --git a/routes/dev/assets.js b/routes/dev/assets.js index cb1f27e43..aea0628e3 100644 --- a/routes/dev/assets.js +++ b/routes/dev/assets.js @@ -1,49 +1,58 @@ const express = require('express'); const router = express.Router(); - -const errors = require('../../errors'); -const Assets = require('../../services/assets'); - -const body = - 'Lorem ipsum dolor sponge amet, consectetur adipiscing clam. Ut lobortis sollicitudin pillar a ornare. Curabitur dignissim vestibulum cay non rhoncus. Cras laoreet ante vel nunc hendrerit, shelf imperdiet neque egestas. Suspendisse aliquet iaculis fermentum. Talk volutpat, tellus posuere laoreet consequat, mi lacus laoreet massa, sed vehicula mauris velit non lectus. Integer non trust nec neque congue faucibus porttitor sit amet elkhorn.'; +const casual = require('casual'); +const { ErrNotFound } = require('../../errors'); +const Asset = require('../../models/asset'); router.get('/id/:asset_id', async (req, res, next) => { try { - const asset = await Assets.findById(req.params.asset_id); + const asset = await Asset.findOne({ id: req.params.asset_id }); if (asset === null) { - return next(errors.ErrNotFound); + throw new ErrNotFound(); } res.render('dev/article', { title: asset.title, asset_id: asset.id, asset_url: asset.url, - body: '', - basePath: '/client/embed/stream', }); } catch (err) { return next(err); } }); +router.get('/random', (req, res) => { + const title = casual.title; + + res.redirect(`./title/${title.replace(/ /g, '-')}`); +}); + router.get('/title/:asset_title', (req, res) => { - return res.render('dev/article', { + res.render('dev/article', { title: req.params.asset_title.split('-').join(' '), asset_url: '', asset_id: null, - body: body, - basePath: '/client/embed/stream', }); }); router.get('/', async (req, res, next) => { - let skip = req.query.skip ? parseInt(req.query.skip) : 0; - let limit = req.query.limit ? parseInt(req.query.limit) : 25; - try { - const assets = await Assets.all(skip, limit); + const skip = req.query.skip ? parseInt(req.query.skip) : 0; + const limit = req.query.limit ? parseInt(req.query.limit) : 6; + + const [assets, count] = await Promise.all([ + Asset.find({}) + .sort({ created_at: 1 }) + .limit(limit) + .skip(skip), + Asset.count(), + ]); + res.render('dev/articles', { - assets: assets, + skip, + limit, + count, + assets, }); } catch (err) { return next(err); diff --git a/routes/dev/index.js b/routes/dev/index.js index ac72db254..58daca583 100644 --- a/routes/dev/index.js +++ b/routes/dev/index.js @@ -16,8 +16,6 @@ router.get('/', staticTemplate, async (req, res) => { title: 'Coral Talk', asset_url: '', asset_id: '', - body: '', - basePath: '/static/embed/stream', }); } }); diff --git a/services/assets.js b/services/assets.js index 794145eb3..5f1fa989d 100644 --- a/services/assets.js +++ b/services/assets.js @@ -232,11 +232,5 @@ module.exports = class AssetsService { await AssetModel.remove({ id: srcAssetID, }); - - // That's it! - } - - static all(limit = undefined) { - return AssetModel.find({}).limit(limit); } }; diff --git a/views/admin.ejs b/views/admin.ejs index b8f775d79..89cc150f7 100644 --- a/views/admin.ejs +++ b/views/admin.ejs @@ -3,16 +3,11 @@ Talk - Coral Admin - + <%- include partials/head %> - - - <%- include partials/head %> + <%- include partials/custom-css %>
diff --git a/views/api/graphiql.ejs b/views/api/graphiql.ejs index b6d609de6..8007569b3 100644 --- a/views/api/graphiql.ejs +++ b/views/api/graphiql.ejs @@ -5,13 +5,17 @@ GraphiQL + <%- include ../partials/dev %> @@ -20,6 +24,8 @@ + <%- include ../partials/dev-nav %> +
- \ No newline at end of file + diff --git a/views/dev/article.ejs b/views/dev/article.ejs index 8abfc34af..008d3989e 100644 --- a/views/dev/article.ejs +++ b/views/dev/article.ejs @@ -8,53 +8,45 @@ - - <%= title %> + <%- include ../partials/dev %> -
-

<%= title %>

-

<%= body %>

-

Admin - All Assets

-
- + -
+ * You can listen to events using the example below. + * The argument passed is the event emitter from + * https://github.com/asyncly/EventEmitter2 + * + * events: function(events) { + * events.onAny(function(eventName, data) { + * console.log(eventName, data); + * }); + * }, + */ + plugins_config: { + /** + * You can disable rendering slot components of a plugin by doing: + * + * 'talk-plugin-love': { + * disable_components: true, + * }, + */ + test: 'data', + debug: false + } + }) + + diff --git a/views/dev/articles.ejs b/views/dev/articles.ejs index 0ce684029..1b07ed116 100644 --- a/views/dev/articles.ejs +++ b/views/dev/articles.ejs @@ -1,14 +1,40 @@ - -

- Asset list -

-<% assets.forEach(function (asset) { %> - <%= asset.url %>
-<% }) %> -

- (For dev use only. FYI, you can: ?skip=100&limit=25) -

- - + + All Assets + <%- include ../partials/dev %> + + + <%- include ../partials/dev-nav %> +
+
+

All Assets

+ <%= skip + 1 %> - <%= skip + assets.length %> of <%= count %> Assets +
+
+ <% if (skip === 0) { %> Create a random article<% } %> + <% assets.forEach(function (asset) { %> + +
+
<%= asset.title %>
+ Created <%= asset.created_at.toLocaleString('en-US') %> +
+ <%= asset.url %> +
+ <% }) %> +
+ <% if (count !== assets.length) { %> + + <% } %> +
+ diff --git a/views/embed/stream.ejs b/views/embed/stream.ejs index 2027f6069..a1c708b55 100644 --- a/views/embed/stream.ejs +++ b/views/embed/stream.ejs @@ -5,6 +5,7 @@ <%- include ../partials/head %> + <%- include ../partials/custom-css %>
diff --git a/views/login.ejs b/views/login.ejs index c5a86c2fb..671b25c83 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -6,6 +6,7 @@ <%- include partials/head %> + <%- include partials/custom-css %>
diff --git a/views/partials/account.ejs b/views/partials/account.ejs index 79857baf0..ff2166816 100644 --- a/views/partials/account.ejs +++ b/views/partials/account.ejs @@ -1,3 +1,4 @@ -<%- include ./head %> +<%- include head %> +<%- include custom-css %> diff --git a/views/partials/custom-css.ejs b/views/partials/custom-css.ejs new file mode 100644 index 000000000..d453c37e1 --- /dev/null +++ b/views/partials/custom-css.ejs @@ -0,0 +1 @@ +<% if (locals.customCssUrl) { %><% } %> diff --git a/views/partials/dev-nav.ejs b/views/partials/dev-nav.ejs new file mode 100644 index 000000000..088c52c20 --- /dev/null +++ b/views/partials/dev-nav.ejs @@ -0,0 +1,8 @@ + diff --git a/views/partials/dev.ejs b/views/partials/dev.ejs new file mode 100644 index 000000000..691b548e5 --- /dev/null +++ b/views/partials/dev.ejs @@ -0,0 +1,5 @@ + + + + + diff --git a/views/partials/head.ejs b/views/partials/head.ejs index e848b3909..dc3df7103 100644 --- a/views/partials/head.ejs +++ b/views/partials/head.ejs @@ -18,9 +18,6 @@ -<%_ if (locals.customCssUrl) { _%> - -<%_ } _%> <%- include data %> diff --git a/yarn.lock b/yarn.lock index 5cf363b6e..f0da6d006 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1828,6 +1828,13 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" +casual@^1.5.19: + version "1.5.19" + resolved "https://registry.yarnpkg.com/casual/-/casual-1.5.19.tgz#66fac46f7ae463f468f5913eb139f9c41c58bbf2" + dependencies: + mersenne-twister "^1.0.1" + moment "^2.15.2" + center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" @@ -7154,6 +7161,10 @@ merge@^1.1.3: version "1.2.0" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" +mersenne-twister@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a" + metascraper-author@^3.9.2: version "3.9.2" resolved "https://registry.yarnpkg.com/metascraper-author/-/metascraper-author-3.9.2.tgz#ff2020ac428f59a875d655df3b0d4bea171fde19" @@ -7436,6 +7447,10 @@ moment@^2.10.3: version "2.19.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.1.tgz#56da1a2d1cbf01d38b7e1afc31c10bcfa1929167" +moment@^2.15.2: + version "2.22.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad" + mongodb-core@2.1.17: version "2.1.17" resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.17.tgz#a418b337a14a14990fb510b923dee6a813173df8"