From eb719e34a8b42672dfebf59564a0c4c6681bc618 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 21 Apr 2024 14:35:51 +1200 Subject: [PATCH 001/393] Add aggregate query to HB model --- server/homebrew.model.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/homebrew.model.js b/server/homebrew.model.js index 36c9aa192..57e57d9e8 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -60,6 +60,12 @@ HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, f return brews; }; +HomebrewSchema.statics.getAggregate = async function(aggregate, options={}){ + const output = await Homebrew.aggregate(aggregate, options) + .catch((error)=>{throw 'Can not get aggregate';}); + return output; +}; + const Homebrew = mongoose.model('Homebrew', HomebrewSchema); module.exports = { From 770025da0473aadd15bf450b1112e5c8cc50480b Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 21 Apr 2024 14:42:20 +1200 Subject: [PATCH 002/393] Add lock count route, update pipelines --- server/admin.api.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 5363ecc08..93c7771a7 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -27,10 +27,12 @@ const mw = { }; const junkBrewPipeline = [ - { $match : { - updatedAt : { $lt: Moment().subtract(30, 'days').toDate() }, - lastViewed : { $lt: Moment().subtract(30, 'days').toDate() } - }}, + { $match : + { + updatedAt : { $lt: Moment().subtract(30, 'days').toDate() }, + lastViewed : { $lt: Moment().subtract(30, 'days').toDate() } + } + }, { $project: { textBinSize: { $binarySize: '$textBin' } } }, { $match: { textBinSize: { $lt: 140 } } }, { $limit: 100 } @@ -138,6 +140,31 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ } }); +router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ + try { + const countLocksPipeline = [ + { + $match : + { + 'lock.locked' : true, + }, + }, + { + $count : + 'count', + } + ]; + const totalLockCount = await HomebrewModel.getAggregate(countLocksPipeline); + const count = totalLockCount[0].count; + return res.json({ + count + }); + } catch (error) { + console.error(error); + return res.status(500).json({ error: 'Unable to get lock count' }); + } +}); + router.get('/admin', mw.adminOnly, (req, res)=>{ templateFn('admin', { url : req.originalUrl From 8c5f2ff61cb12f44d00399f19fdd6e97b024b24e Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 21 Apr 2024 22:17:10 +1200 Subject: [PATCH 003/393] Add route to get locked documents with review requested --- server/admin.api.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index 93c7771a7..b6f72efa1 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -165,6 +165,27 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ } }); +router.get('/admin/lockreviews', mw.adminOnly, async (req, res)=>{ + try { + const countReviewsPipeline = [ + { + $match : + { + 'lock.locked' : true, + 'lock.reviewRequested' : { '$exists': 1 } + }, + } + ]; + const reviewDocuments = await HomebrewModel.getAggregate(countReviewsPipeline); + return res.json({ + reviewDocuments + }); + } catch (error) { + console.error(error); + return res.status(500).json({ error: 'Unable to get lock count' }); + } +}); + router.get('/admin', mw.adminOnly, (req, res)=>{ templateFn('admin', { url : req.originalUrl From b4a7dc0cbd13bf9145e4398ecad89bed08f5c1b6 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 21 Apr 2024 22:48:11 +1200 Subject: [PATCH 004/393] Update lock review route --- server/admin.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index b6f72efa1..552b8a30f 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -165,7 +165,7 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ } }); -router.get('/admin/lockreviews', mw.adminOnly, async (req, res)=>{ +router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ try { const countReviewsPipeline = [ { From 14c7a1152802da1e8eba5570efeb2495cab18be3 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 21 Apr 2024 22:51:53 +1200 Subject: [PATCH 005/393] Fix error message --- server/admin.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index 552b8a30f..48a05438d 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -182,7 +182,7 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ }); } catch (error) { console.error(error); - return res.status(500).json({ error: 'Unable to get lock count' }); + return res.status(500).json({ error: 'Unable to get review collection' }); } }); From 874cbe1da43d9da27e732249b92fd2ed2bf32213 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 22 Apr 2024 00:26:34 +1200 Subject: [PATCH 006/393] Don't forget to update the schema! --- server/homebrew.model.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/homebrew.model.js b/server/homebrew.model.js index 57e57d9e8..81f31f1eb 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -26,7 +26,9 @@ const HomebrewSchema = mongoose.Schema({ updatedAt : { type: Date, default: Date.now }, lastViewed : { type: Date, default: Date.now }, views : { type: Number, default: 0 }, - version : { type: Number, default: 1 } + version : { type: Number, default: 1 }, + + lock : { type: Object } }, { versionKey: false }); HomebrewSchema.statics.increaseView = async function(query) { From 8feae7efb622f1e2727bead01e83e7951244339b Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 22 Apr 2024 00:32:32 +1200 Subject: [PATCH 007/393] Function request review route --- server/admin.api.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index 48a05438d..846757f23 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -186,6 +186,33 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ } }); +router.get('/admin/lock/requestreview/:id', mw.adminOnly, async (req, res)=>{ + try { + const filter = { + shareId : req.params.id, + 'lock.locked' : true + }; + + const brew = await HomebrewModel.findOne(filter).exec(); + if(!brew) { return res.status(500).json({ error: `Brew ID ${req.params.id} is not locked!` }); }; + + brew.lock.reviewRequested = new Date(); + brew.markModified('lock'); + + console.log(brew); + + await brew.save() + .catch((err)=>{ + return err; + }); + + return res.json(brew); + } catch (error) { + console.error(error); + return res.status(500).json({ error: `Unable to set request for review on brew ID ${req.params.id}` }); + } +}); + router.get('/admin', mw.adminOnly, (req, res)=>{ templateFn('admin', { url : req.originalUrl From 99f5aad94238030207bd0a349bb4ea902aefd822 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 14:32:04 +1200 Subject: [PATCH 008/393] Stop review request if it has already been logged --- server/admin.api.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 846757f23..dfaa6d03f 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -193,19 +193,20 @@ router.get('/admin/lock/requestreview/:id', mw.adminOnly, async (req, res)=>{ 'lock.locked' : true }; - const brew = await HomebrewModel.findOne(filter).exec(); + const brew = await HomebrewModel.findOne(filter); if(!brew) { return res.status(500).json({ error: `Brew ID ${req.params.id} is not locked!` }); }; + if(brew.lock.reviewRequested){ return res.status(500).json({ error: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); }; + brew.lock.reviewRequested = new Date(); brew.markModified('lock'); - console.log(brew); - await brew.save() .catch((err)=>{ return err; }); + console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); return res.json(brew); } catch (error) { console.error(error); From 71b84e1aba73c38bce5d08348747aa7e7e813ccd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 14:33:29 +1200 Subject: [PATCH 009/393] Log message when review already requested --- server/admin.api.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index dfaa6d03f..e28b2fff8 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -196,7 +196,10 @@ router.get('/admin/lock/requestreview/:id', mw.adminOnly, async (req, res)=>{ const brew = await HomebrewModel.findOne(filter); if(!brew) { return res.status(500).json({ error: `Brew ID ${req.params.id} is not locked!` }); }; - if(brew.lock.reviewRequested){ return res.status(500).json({ error: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); }; + if(brew.lock.reviewRequested){ + console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); + return res.status(500).json({ error: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + }; brew.lock.reviewRequested = new Date(); brew.markModified('lock'); From e8b9b3d583b2496bd42a2b547854be4d6bc4faaa Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 15:27:40 +1200 Subject: [PATCH 010/393] Add lock route --- server/admin.api.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index e28b2fff8..cbde256f7 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -165,6 +165,27 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ } }); +router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ + const lock = req.body; + + try { + const filter = { + shareId : req.params.id + }; + + const brew = await HomebrewModel.findOne(filter); + + brew.lock = lock; + brew.markModified('lock'); + + await brew.save(); + + console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); + } catch {} + + return; +}); + router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ try { const countReviewsPipeline = [ From 1c2ae8392c56a79598ec2b7519382ca8cad9c719 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 15:32:26 +1200 Subject: [PATCH 011/393] Increase max lines in Linter --- server/admin.api.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/admin.api.js b/server/admin.api.js index cbde256f7..2034a0e68 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -1,3 +1,4 @@ +/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/ const HomebrewModel = require('./homebrew.model.js').model; const router = require('express').Router(); const Moment = require('moment'); From e9db7d1bb92014bc14b69209f30f4911ccdab048 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 15:37:50 +1200 Subject: [PATCH 012/393] Add return on success to lock route --- server/admin.api.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 2034a0e68..5a8b19acb 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -182,9 +182,12 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); - } catch {} + } catch (error) { + console.error(error); + return res.status(500).json({ error: `Unable to set lock on brew ${req.params.id}` }); + } - return; + return res.status(200).json({ status: 'SUCCESS', lock }); }); router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ From 4b1d6ebd7c6537ad700b42078772f0595368c186 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 15:58:43 +1200 Subject: [PATCH 013/393] Rename review request route --- server/admin.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index 5a8b19acb..620ddebae 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -211,7 +211,7 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ } }); -router.get('/admin/lock/requestreview/:id', mw.adminOnly, async (req, res)=>{ +router.get('/admin/lock/review/request/:id', mw.adminOnly, async (req, res)=>{ try { const filter = { shareId : req.params.id, From 20d48d7dc2d74def10e3e760cedf2f3b544661bd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Apr 2024 15:59:11 +1200 Subject: [PATCH 014/393] Add review removal route --- server/admin.api.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index 620ddebae..9f72a5ea2 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -242,6 +242,30 @@ router.get('/admin/lock/review/request/:id', mw.adminOnly, async (req, res)=>{ } }); +router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ + try { + const filter = { + shareId : req.params.id, + 'lock.locked' : true, + 'lock.reviewRequested' : { '$exists': 1 } + }; + + const brew = await HomebrewModel.findOne(filter); + if(!brew) { return res.status(500).json({ error: `Brew ID ${req.params.id} does not have a review pending!` }); }; + + delete brew.lock.reviewRequested; + brew.markModified('lock'); + + await brew.save(); + + console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); + return res.json(brew); + } catch (error) { + console.error(error); + return res.status(500).json({ error: `Unable to remove request for review on brew ID ${req.params.id}` }); + } +}); + router.get('/admin', mw.adminOnly, (req, res)=>{ templateFn('admin', { url : req.originalUrl From b4ce621630c39e03be9f1737ba83a287d473d470 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 9 May 2024 07:37:37 +1200 Subject: [PATCH 015/393] Request review no longer Admin only --- server/admin.api.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index 9f72a5ea2..455258555 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -211,7 +211,9 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ } }); -router.get('/admin/lock/review/request/:id', mw.adminOnly, async (req, res)=>{ +router.get('/admin/lock/review/request/:id', async (req, res)=>{ + // === This route is NOT Admin only === + // Any user can request a review of their document try { const filter = { shareId : req.params.id, From 1fe2a26e8336a03b5730e7b03441e8cd52411296 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Fri, 10 May 2024 12:38:31 +1200 Subject: [PATCH 016/393] Tabify Admin page --- client/admin/admin.jsx | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index 92e0b2aee..c20b6abed 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -8,11 +8,38 @@ const BrewLookup = require('./brewLookup/brewLookup.jsx'); const BrewCompress = require ('./brewCompress/brewCompress.jsx'); const Stats = require('./stats/stats.jsx'); +const tabGroups = ['brews']; + const Admin = createClass({ getDefaultProps : function() { return {}; }, + getInitialState : function() { + return { + currentTab : 'brews' + }; + }, + + handleClick : function(newTab) { + if(this.state.currentTab === newTab) return; + this.setState({ + currentTab : newTab + }); + }, + + renderBrewTools : function(){ + return <> + +
+ +
+ +
+ + ; + }, + render : function(){ return
@@ -23,13 +50,12 @@ const Admin = createClass({
- -
- -
- -
- +
+ {tabGroups.map((name, idx)=>{ + return ; + })} +
+ {this.state.currentTab == 'brews' && this.renderBrewTools()}
; } From e7dc757293f00d7f78c21b4aad4a3f22d5447051 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 11 May 2024 23:58:37 +1200 Subject: [PATCH 017/393] Initial UI functionality for most Lock functions --- client/admin/admin.jsx | 7 +- client/admin/admin.less | 18 +++ client/admin/lockTools/lockTools.jsx | 176 ++++++++++++++++++++++++++ client/admin/lockTools/lockTools.less | 3 + server/admin.api.js | 48 +++++-- 5 files changed, 240 insertions(+), 12 deletions(-) create mode 100644 client/admin/lockTools/lockTools.jsx create mode 100644 client/admin/lockTools/lockTools.less diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index c20b6abed..088847a66 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -8,7 +8,9 @@ const BrewLookup = require('./brewLookup/brewLookup.jsx'); const BrewCompress = require ('./brewCompress/brewCompress.jsx'); const Stats = require('./stats/stats.jsx'); -const tabGroups = ['brews']; +const LockTools = require('./lockTools/lockTools.jsx'); + +const tabGroups = ['brews', 'locks']; const Admin = createClass({ getDefaultProps : function() { @@ -52,10 +54,11 @@ const Admin = createClass({
{tabGroups.map((name, idx)=>{ - return ; + return ; })}
{this.state.currentTab == 'brews' && this.renderBrewTools()} + {this.state.currentTab == 'locks' && }
; } diff --git a/client/admin/admin.less b/client/admin/admin.less index a61335835..39a66bd54 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -40,5 +40,23 @@ body{ margin : 30px 0px; } + .tabs { + border-bottom: 1px solid black; + } + + button.tab { + margin: 2px 2px 0px; + border-width: 1px 1px 0px; + border-style: solid; + border-color: black; + border-radius: 5px 5px 0px 0px; + color: black; + background-color: transparent; + &.active { + background-color: #000000a0; + color: white; + text-decoration: underline; + } + } } diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx new file mode 100644 index 000000000..710a29681 --- /dev/null +++ b/client/admin/lockTools/lockTools.jsx @@ -0,0 +1,176 @@ +require('./lockTools.less'); +const React = require('react'); +const createClass = require('create-react-class'); + +const request = require('superagent'); + +const LockTools = createClass({ + getInitialState : function() { + return { + fetching : false, + reviewCount : 0 + }; + }, + + componentDidMount : function() { + this.updateReviewCount(); + }, + + updateReviewCount : async function() { + const newCount = await request.get('/admin/lock') + .then((res)=>{return res.body?.count || 'Unknown';}); + if(newCount != this.state.reviewCount){ + this.setState({ + reviewCount : newCount + }); + } + }, + + render : function() { + return
+

Lock Count

+

Number of brews currently locked: {this.state.reviewCount}

+ +
+ +
+

Lock Brew

+ NYI +
+ +
+ +
; + } +}); + +const LockTable = createClass({ + getDefaultProps : function() { + return { + title : '', + fetchURL : '/admin/locks', + resultName : '', + propertyNames : ['shareId'] + }; + }, + + getInitialState : function() { + return { + result : '', + error : '', + searching : false + }; + }, + + clickFn(){ + this.setState({ searching: true, error: null }); + + request.get(this.props.fetchURL) + .then((res)=>this.setState({ result: res.body })) + .catch((err)=>this.setState({ error: err })) + .finally(()=>{ + this.setState({ searching: false }); + }); + }, + + render : function () { + return <> +

{this.props.title}

+ + {this.state.result[this.props.resultName] && + <> +

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

+ + + + {this.props.propertyNames.map((name, idx)=>{ + return ; + })} + + + + {this.state.result[this.props.resultName].map((result, resultIdx)=>{ + return {navigator.clipboard.writeText(result.shareId.toString());}}> + {this.props.propertyNames.map((name, nameIdx)=>{ + return ; + })} + ; + })} + +
{name}
+ {result[name].toString()} +
+ + } + ; + } +}); + +const LockLookup = createClass({ + getDefaultProps : function() { + return { + fetchURL : '/admin/lookup' + }; + }, + + getInitialState : function() { + return { + query : '', + result : '', + error : '', + searching : false + }; + }, + + handleChange(e){ + this.setState({ query: e.target.value }); + }, + + clickFn(){ + this.setState({ searching: true, error: null }); + + request.get(`${this.props.fetchURL}/${this.state.query}`) + .then((res)=>this.setState({ result: res.body })) + .catch((err)=>this.setState({ error: err })) + .finally(()=>{ + this.setState({ searching: false }); + }); + }, + + renderResult : function(){ + return <> +

Result:

+ + + {Object.keys(this.state.result).map((key, idx)=>{ + return + + + ; + })} + +
{key}{this.state.result[key].toString()} +
+ ; + }, + + render : function() { + return
+

{this.props.title}

+ + + + {this.state.error + &&
{this.state.error.toString()}
+ } + + {this.state.result && this.renderResult()} +
; + } +}); + +module.exports = LockTools; \ No newline at end of file diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less new file mode 100644 index 000000000..8f0ec04bd --- /dev/null +++ b/client/admin/lockTools/lockTools.less @@ -0,0 +1,3 @@ +.lockTools { + display: block; +} \ No newline at end of file diff --git a/server/admin.api.js b/server/admin.api.js index 455258555..e1d33f029 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -162,12 +162,13 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ }); } catch (error) { console.error(error); - return res.status(500).json({ error: 'Unable to get lock count' }); + return res.json({ status: 'ERROR', detail: 'Unable to get lock count', error }); } }); router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ const lock = req.body; + lock.applied = new Date; try { const filter = { @@ -176,6 +177,8 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ const brew = await HomebrewModel.findOne(filter); + if(brew.lock) return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); + brew.lock = lock; brew.markModified('lock'); @@ -184,10 +187,34 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); } catch (error) { console.error(error); - return res.status(500).json({ error: `Unable to set lock on brew ${req.params.id}` }); + return res.json({ error, message: `Unable to set lock on brew ${req.params.id}` }); } - return res.status(200).json({ status: 'SUCCESS', lock }); + return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); +}); + +router.get('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ + try { + const filter = { + shareId : req.params.id + }; + + const brew = await HomebrewModel.findOne(filter); + + if(!brew.lock) return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); + + brew.lock = undefined; + brew.markModified('lock'); + + await brew.save(); + + console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); + } catch (error) { + console.error(error); + return res.json({ status: 'ERROR', detail: `Unable to clear lock on brew ${req.params.id}`, error }); + } + + return res.json({ status: 'UNLOCKED', detail: `Lock removed from brew ID ${req.params.id}` }); }); router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ @@ -202,12 +229,13 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ } ]; const reviewDocuments = await HomebrewModel.getAggregate(countReviewsPipeline); + console.log(reviewDocuments); return res.json({ reviewDocuments }); } catch (error) { console.error(error); - return res.status(500).json({ error: 'Unable to get review collection' }); + return res.json({ status: 'ERROR', detail: 'Unable to get review collection', error }); } }); @@ -221,11 +249,11 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ }; const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.status(500).json({ error: `Brew ID ${req.params.id} is not locked!` }); }; + if(!brew) { return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); }; if(brew.lock.reviewRequested){ console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); - return res.status(500).json({ error: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + return res.json({ status: 'NOT REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); }; brew.lock.reviewRequested = new Date(); @@ -237,10 +265,10 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ }); console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); - return res.json(brew); + return res.json({ status: 'REVIEW REQUESTED', brew }); } catch (error) { console.error(error); - return res.status(500).json({ error: `Unable to set request for review on brew ID ${req.params.id}` }); + return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); } }); @@ -253,7 +281,7 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ }; const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.status(500).json({ error: `Brew ID ${req.params.id} does not have a review pending!` }); }; + if(!brew) { return res.json({ status: 'NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; delete brew.lock.reviewRequested; brew.markModified('lock'); @@ -264,7 +292,7 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ return res.json(brew); } catch (error) { console.error(error); - return res.status(500).json({ error: `Unable to remove request for review on brew ID ${req.params.id}` }); + return res.json({ error: `Unable to remove request for review on brew ID ${req.params.id}` }); } }); From 2a91d3ddbdaab7387d7c5c07a0eb356173f5edbc Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 16:07:28 +1200 Subject: [PATCH 018/393] Additional styling --- client/admin/lockTools/lockTools.less | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 8f0ec04bd..9554ffa19 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -1,3 +1,13 @@ .lockTools { - display: block; + .lockBrew label { + width: 50%; + display: inline-block; + text-align: right; + line-height: 1.5em; + input { + float: right; + width: 70%; + margin-left: 10px; + } + } } \ No newline at end of file From 2502c0e87ca04e35f01987ffb3a60d969488b383 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 16:08:26 +1200 Subject: [PATCH 019/393] Add missing return status messages --- server/admin.api.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index e1d33f029..eb025a686 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -170,14 +170,18 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ const lock = req.body; lock.applied = new Date; + let brew; try { const filter = { shareId : req.params.id }; - const brew = await HomebrewModel.findOne(filter); + brew = await HomebrewModel.findOne(filter); - if(brew.lock) return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); + if(brew.lock) { + console.log('ALREADY LOCKED'); + return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); + } brew.lock = lock; brew.markModified('lock'); @@ -187,7 +191,7 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); } catch (error) { console.error(error); - return res.json({ error, message: `Unable to set lock on brew ${req.params.id}` }); + return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); } return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); @@ -244,8 +248,8 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ // Any user can request a review of their document try { const filter = { - shareId : req.params.id, - 'lock.locked' : true + shareId : req.params.id, + lock : { $exists: 1 } }; const brew = await HomebrewModel.findOne(filter); @@ -283,7 +287,7 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ const brew = await HomebrewModel.findOne(filter); if(!brew) { return res.json({ status: 'NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; - delete brew.lock.reviewRequested; + brew.lock.reviewRequested = undefined; brew.markModified('lock'); await brew.save(); From 65f1c19721b9a8f9eeeb930253a17c026a28674b Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 16:14:09 +1200 Subject: [PATCH 020/393] Add functional Lock Brew component --- client/admin/lockTools/lockTools.jsx | 75 +++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 710a29681..6e5d7f90e 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -34,8 +34,7 @@ const LockTools = createClass({

-

Lock Brew

- NYI +

@@ -44,6 +43,77 @@ const LockTools = createClass({ } }); +const LockBrew = createClass({ + getInitialState : function() { + return { + brewId : '', + code : 1000, + editMessage : '', + shareMessage : '' + }; + }, + + handleChange : function(e, varName) { + const output = {}; + output[varName] = e.target.value; + this.setState(output); + }, + + submit : function(e){ + e.preventDefault(); + if(!this.state.editMessage) return; + const newLock = { + code : parseInt(this.state.code) || 100, + editMessage : this.state.editMessage, + shareMessage : this.state.shareMessage, + applied : new Date, + locked : true + }; + + request.post(`/admin/lock/${this.state.brewId}`) + .send(newLock) + .set('Content-Type', 'application/json') + .then((response)=>{ + console.log(response.body); + }); + }, + + renderInput : function (name) { + return this.handleChange(e, name)} autoComplete='off' required/>; + }, + + render : function() { + return
+

Lock Brew

+
+ +
+ +
+ +
+ +
+ +
+
; + } +}); + const LockTable = createClass({ getDefaultProps : function() { return { @@ -140,6 +210,7 @@ const LockLookup = createClass({ }, renderResult : function(){ + console.log(this.state.result); return <>

Result:

From b093be52a25321e2f0148c148b8c830371839d20 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 16:57:28 +1200 Subject: [PATCH 021/393] Update esLint rules --- client/admin/lockTools/lockTools.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 6e5d7f90e..9e53e31fd 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -1,3 +1,4 @@ +/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/ require('./lockTools.less'); const React = require('react'); const createClass = require('create-react-class'); From 7c4721932dcd6c1adea242aa0bf80fca77b5e4a3 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 19:50:27 +1200 Subject: [PATCH 022/393] Remove unnecessary function from HB.model --- server/admin.api.js | 45 ++++++++++++++++++---------------------- server/homebrew.model.js | 6 ------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index eb025a686..625e44f22 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -147,16 +147,16 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ { $match : { - 'lock.locked' : true, - }, + lock : { $exists: 1 } + } }, { - $count : - 'count', + $count : 'count' } ]; - const totalLockCount = await HomebrewModel.getAggregate(countLocksPipeline); + const totalLockCount = await HomebrewModel.aggregate(countLocksPipeline); const count = totalLockCount[0].count; + console.log(totalLockCount); return res.json({ count }); @@ -188,10 +188,10 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); - console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); + // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); } catch (error) { console.error(error); - return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); + return res.json({ status: 'ERROR', error, detail: `Unable to set lock on brew ${req.params.id}` }); } return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); @@ -212,7 +212,7 @@ router.get('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); - console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); + // console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); } catch (error) { console.error(error); return res.json({ status: 'ERROR', detail: `Unable to clear lock on brew ${req.params.id}`, error }); @@ -227,13 +227,11 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ { $match : { - 'lock.locked' : true, 'lock.reviewRequested' : { '$exists': 1 } }, } ]; - const reviewDocuments = await HomebrewModel.getAggregate(countReviewsPipeline); - console.log(reviewDocuments); + const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline); return res.json({ reviewDocuments }); @@ -256,20 +254,17 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ if(!brew) { return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); }; if(brew.lock.reviewRequested){ - console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'NOT REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'ALREADY REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); }; brew.lock.reviewRequested = new Date(); brew.markModified('lock'); - await brew.save() - .catch((err)=>{ - return err; - }); + await brew.save(); - console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUESTED', brew }); + // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested for ${brew.shareId} - ${brew.title}` }); } catch (error) { console.error(error); return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); @@ -277,14 +272,14 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ }); router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ + let brew; try { const filter = { shareId : req.params.id, - 'lock.locked' : true, - 'lock.reviewRequested' : { '$exists': 1 } + 'lock.reviewRequested' : { $exists: 1 } }; - const brew = await HomebrewModel.findOne(filter); + brew = await HomebrewModel.findOne(filter); if(!brew) { return res.json({ status: 'NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; brew.lock.reviewRequested = undefined; @@ -292,11 +287,11 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); - console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); - return res.json(brew); + // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Request for Review removed from brew ID ${brew.shareId} - ${brew.title}` }); } catch (error) { console.error(error); - return res.json({ error: `Unable to remove request for review on brew ID ${req.params.id}` }); + return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); } }); diff --git a/server/homebrew.model.js b/server/homebrew.model.js index 81f31f1eb..ea32265ff 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -62,12 +62,6 @@ HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, f return brews; }; -HomebrewSchema.statics.getAggregate = async function(aggregate, options={}){ - const output = await Homebrew.aggregate(aggregate, options) - .catch((error)=>{throw 'Can not get aggregate';}); - return output; -}; - const Homebrew = mongoose.model('Homebrew', HomebrewSchema); module.exports = { From c0c674d8626abcc74169e2f4f548327831e73966 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 19:52:08 +1200 Subject: [PATCH 023/393] Comment out debug logging --- server/admin.api.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 625e44f22..8c29791ce 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -147,16 +147,16 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ { $match : { - lock : { $exists: 1 } + lock : true } }, { - $count : 'count' + $count : + 'count' } ]; const totalLockCount = await HomebrewModel.aggregate(countLocksPipeline); const count = totalLockCount[0].count; - console.log(totalLockCount); return res.json({ count }); @@ -179,7 +179,7 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ brew = await HomebrewModel.findOne(filter); if(brew.lock) { - console.log('ALREADY LOCKED'); + // console.log('ALREADY LOCKED'); return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); } @@ -191,7 +191,7 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); } catch (error) { console.error(error); - return res.json({ status: 'ERROR', error, detail: `Unable to set lock on brew ${req.params.id}` }); + return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); } return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); @@ -227,6 +227,7 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ { $match : { + 'lock.locked' : true, 'lock.reviewRequested' : { '$exists': 1 } }, } @@ -255,16 +256,19 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ if(brew.lock.reviewRequested){ // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'ALREADY REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + return res.json({ status: 'NOT REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); }; brew.lock.reviewRequested = new Date(); brew.markModified('lock'); - await brew.save(); + await brew.save() + .catch((err)=>{ + return err; + }); // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested for ${brew.shareId} - ${brew.title}` }); + return res.json({ status: 'REVIEW REQUESTED', brew }); } catch (error) { console.error(error); return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); @@ -272,14 +276,14 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ }); router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ - let brew; try { const filter = { shareId : req.params.id, - 'lock.reviewRequested' : { $exists: 1 } + 'lock.locked' : true, + 'lock.reviewRequested' : { '$exists': 1 } }; - brew = await HomebrewModel.findOne(filter); + const brew = await HomebrewModel.findOne(filter); if(!brew) { return res.json({ status: 'NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; brew.lock.reviewRequested = undefined; @@ -288,10 +292,10 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Request for Review removed from brew ID ${brew.shareId} - ${brew.title}` }); + return res.json(brew); } catch (error) { console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); + return res.json({ error: `Unable to remove request for review on brew ID ${req.params.id}` }); } }); From b237f29636bea20f7486915e0883b62ed8a3da2b Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 19:58:29 +1200 Subject: [PATCH 024/393] Clean up API functions --- server/admin.api.js | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 8c29791ce..13d3cb78c 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -155,8 +155,7 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ 'count' } ]; - const totalLockCount = await HomebrewModel.aggregate(countLocksPipeline); - const count = totalLockCount[0].count; + const count = await HomebrewModel.aggregate(countLocksPipeline); return res.json({ count }); @@ -167,16 +166,15 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ }); router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ - const lock = req.body; - lock.applied = new Date; - - let brew; try { + const lock = req.body; + lock.applied = new Date; + const filter = { shareId : req.params.id }; - brew = await HomebrewModel.findOne(filter); + const brew = await HomebrewModel.findOne(filter); if(brew.lock) { // console.log('ALREADY LOCKED'); @@ -189,12 +187,11 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); } catch (error) { console.error(error); return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); } - - return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); }); router.get('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ @@ -256,19 +253,16 @@ router.get('/admin/lock/review/request/:id', async (req, res)=>{ if(brew.lock.reviewRequested){ // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'NOT REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + return res.json({ status: 'ALREADY REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); }; brew.lock.reviewRequested = new Date(); brew.markModified('lock'); - await brew.save() - .catch((err)=>{ - return err; - }); + await brew.save(); // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUESTED', brew }); + return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); } catch (error) { console.error(error); return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); @@ -279,12 +273,11 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ try { const filter = { shareId : req.params.id, - 'lock.locked' : true, - 'lock.reviewRequested' : { '$exists': 1 } + 'lock.reviewRequested' : { $exists: 1 } }; const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.json({ status: 'NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; + if(!brew) { return res.json({ status: 'REVIEW REQUEST NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; brew.lock.reviewRequested = undefined; brew.markModified('lock'); @@ -292,10 +285,10 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); - return res.json(brew); + return res.json({status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); } catch (error) { console.error(error); - return res.json({ error: `Unable to remove request for review on brew ID ${req.params.id}` }); + return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); } }); From f5014f29c3973c1442c76d497fa78c4cad01b5ad Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 15 May 2024 23:13:53 +1200 Subject: [PATCH 025/393] Linter fix --- server/admin.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index 13d3cb78c..f0714f1ce 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -285,7 +285,7 @@ router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); - return res.json({status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); } catch (error) { console.error(error); return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); From 96b955f2fe5b885cabb4e73b96b6c03422d6f55d Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 16 May 2024 17:00:26 +1200 Subject: [PATCH 026/393] Change lock check to stub.lock from stub.lock.locked --- server/homebrew.api.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index e73a704a8..ef3af9a21 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -54,7 +54,7 @@ const api = { }); stub = stub?.toObject(); - if(stub?.lock?.locked && accessType != 'edit') { + if(stub?.lock && accessType != 'edit') { throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.message, brewId: stub.shareId, brewTitle: stub.title }; } @@ -83,9 +83,9 @@ const api = { if(accessType === 'edit' && (authorsExist && !(isAuthor || isInvited))) { const accessError = { name: 'Access Error', status: 401 }; if(req.account){ - throw { ...accessError, message: 'User is not an Author', HBErrorCode: '03', authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId}; + throw { ...accessError, message: 'User is not an Author', HBErrorCode: '03', authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId }; } - throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04', authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId}; + throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04', authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId }; } // If after all of that we still don't have a brew, throw an exception From 4e11a0c737e0ad3332ba7dba6effae7a455d01c3 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 16 May 2024 17:02:00 +1200 Subject: [PATCH 027/393] Fix error message --- server/homebrew.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index ef3af9a21..4baab48ce 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -55,7 +55,7 @@ const api = { stub = stub?.toObject(); if(stub?.lock && accessType != 'edit') { - throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.message, brewId: stub.shareId, brewTitle: stub.title }; + throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title }; } // If there is a google id, try to find the google brew From 7b287fb0f438b5d16e0a670a497a46048bb6f42a Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 16 May 2024 17:04:37 +1200 Subject: [PATCH 028/393] Fix test --- server/homebrew.api.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 8a4748e38..c8539bf63 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -300,7 +300,7 @@ describe('Tests for api', ()=>{ }); it('access is denied to a locked brew', async()=>{ - const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, message: 'brew locked' } }; + const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, shareMessage: 'brew locked' } }; model.get = jest.fn(()=>toBrewPromise(lockBrew)); api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); From d751addf9d8224be02f56d661ef1c7661f6fe344 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 16 May 2024 17:18:50 +1200 Subject: [PATCH 029/393] Change lock static error message --- client/homebrew/pages/errorPage/errors/errorIndex.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js index f9d52c109..85df6d286 100644 --- a/client/homebrew/pages/errorPage/errors/errorIndex.js +++ b/client/homebrew/pages/errorPage/errors/errorIndex.js @@ -140,7 +140,7 @@ const errorIndex = (props)=>{ '100' : dedent` ## This brew has been locked. - Please contact the Administrators to unlock this document. + Once the author has taken corrective action, they may request an administrative review to have this document unlocked. : From 6314672109a4fdf9e2b16dce32fc08e3c0b7cf5c Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 14:59:08 +1200 Subject: [PATCH 030/393] Pass the entire lock object to LockNotification --- client/homebrew/pages/editPage/editPage.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 48d0f3fe5..a9652a3ad 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -396,7 +396,7 @@ const EditPage = createClass({ {this.renderNavbar()}
- {this.props.brew.lock && } + {this.props.brew.lock && } Date: Sat, 8 Jun 2024 15:31:46 +1200 Subject: [PATCH 031/393] Shift API call for REQUEST REVIEW to PUT --- server/admin.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index bc4f1fe73..9f25d74c8 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -237,7 +237,7 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ } }); -router.get('/admin/lock/review/request/:id', async (req, res)=>{ +router.put('/admin/lock/review/request/:id', async (req, res)=>{ // === This route is NOT Admin only === // Any user can request a review of their document try { From f81d16309c872cffb4b91310abdc0a3d2e35a16c Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 15:53:01 +1200 Subject: [PATCH 032/393] Add functionality to REQUEST REVIEW button --- .../lockNotification/lockNotification.jsx | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx index c5eeaee47..da79ff265 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx @@ -1,17 +1,28 @@ require('./lockNotification.less'); const React = require('react'); +const request = require('../../../utils/request-middleware.js'); import Dialog from '../../../../components/dialog.jsx'; function LockNotification(props) { props = { shareId : 0, disableLock : ()=>{}, - message : '', + lock : {}, ...props }; - const removeLock = ()=>{ - alert(`Not yet implemented - ID ${props.shareId}`); + const [reviewState, setReviewState] = React.useState(false); + + const removeLock = async ()=>{ + await request.put(`/admin/lock/review/request/${props.shareId}`) + .then(()=>{ + setReviewState(true); + }); + }; + + const renderReviewButton = function(){ + if(reviewState || props.lock.reviewRequested){ return ; }; + return ; }; return @@ -19,11 +30,11 @@ function LockNotification(props) {

This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.


LOCK REASON

-

{props.message || 'Unable to retrieve Lock Message'}

+

{props.lock.editMessage || 'Unable to retrieve Lock Message'}


Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.

Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.

- + {renderReviewButton()}
; }; From 00fd1e415c8ac350f30759f4ecceb57894321d16 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 15:53:28 +1200 Subject: [PATCH 033/393] Change styling for inactive REQUEST REVIEW button --- .../pages/editPage/lockNotification/lockNotification.less | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.less b/client/homebrew/pages/editPage/lockNotification/lockNotification.less index 54f1a9569..de2692ec0 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.less +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.less @@ -15,7 +15,10 @@ color : white; background-color : #333333; - &:hover { background-color : #777777; } + &.inactive, + &:hover { + background-color : #777777; + } } h1, h3 { From bc7731b819b9e7d5e8534e739a007043b00c6372 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 16:08:18 +1200 Subject: [PATCH 034/393] Fix review requested aggregation pipeline --- server/admin.api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index 9f25d74c8..498c1bff3 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -222,7 +222,6 @@ router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ { $match : { - 'lock.locked' : true, 'lock.reviewRequested' : { '$exists': 1 } }, } From 240342007b955c269b1e092614963e3429a120bd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 16:36:20 +1200 Subject: [PATCH 035/393] Fix lock count function --- server/admin.api.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 498c1bff3..8559143c2 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -141,19 +141,13 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ try { - const countLocksPipeline = [ - { - $match : - { - lock : true - } - }, - { - $count : - 'count' - } - ]; - const count = await HomebrewModel.aggregate(countLocksPipeline); + const countLocksQuery = { + lock : { $exists: true } + }; + const count = await HomebrewModel.countDocuments(countLocksQuery) + .then((result)=>{ + return result; + }); return res.json({ count }); From 634b099ade26c18e122c83e9d25a0c024f6883ce Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 16:48:16 +1200 Subject: [PATCH 036/393] Add styling to LockTable --- client/admin/lockTools/lockTools.jsx | 2 +- client/admin/lockTools/lockTools.less | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 9e53e31fd..808f9058e 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -153,7 +153,7 @@ const LockTable = createClass({ {this.state.result[this.props.resultName] && <>

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

-
+
{this.props.propertyNames.map((name, idx)=>{ diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 9554ffa19..765c3cc5d 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -10,4 +10,16 @@ margin-left: 10px; } } + + .lockTable{ + td{ + border: 1px solid #333333; + padding: 4px 10px; + text-align: center; + + &:hover { + cursor: pointer; + } + } + } } \ No newline at end of file From 01ae858a1461a068eedbb10077ec6407190dc5b1 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 17:08:05 +1200 Subject: [PATCH 037/393] Update LockLookup placeholder value --- client/admin/lockTools/lockTools.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 808f9058e..d9448fc14 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -231,7 +231,7 @@ const LockLookup = createClass({ render : function() { return

{this.props.title}

- + From deef5998c54199ade997cb06e0629c6a49262d4a Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 18:55:14 +1200 Subject: [PATCH 038/393] Update LockBrew text and styling --- client/admin/lockTools/lockTools.jsx | 80 ++++++++++++++++++--------- client/admin/lockTools/lockTools.less | 45 ++++++++++++--- 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index d9448fc14..58829eacf 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -85,32 +85,60 @@ const LockBrew = createClass({ render : function() { return
-

Lock Brew

-
- -
- -
- -
- -
- - +
+

Lock Brew

+
+ +
+ +
+ +
+ +
+ + +
+
+

Suggestions

+
+

Codes

+
    +
  • 455 - Generic Lock
  • +
  • 456 - Copyright issues
  • +
  • 457 - Confidential Information Leakage
  • +
  • 458 - Sensitive Personal Information
  • +
  • 459 - Defamation or Libel
  • +
  • 460 - Hate Speech or Discrimination
  • +
  • 461 - Illegal Activities
  • +
  • 462 - Malware or Phishing
  • +
  • 463 - Plagiarism
  • +
  • 465 - Misrepresentation
  • +
  • 466 - Inappropriate Content
  • +
+
+
+

Messages

+
    +
  • Edit Message: This is the private message that is ONLY displayed to the authors of the locked brew. This message MUST specify exactly what actions must be taken in order to have the brew unlocked.
  • +
  • Share Message: This is the public message that is displayed to the EVERYONE that attempts to view the locked brew.
  • +
+
+
; } }); diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 765c3cc5d..c34a69485 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -1,13 +1,40 @@ .lockTools { - .lockBrew label { - width: 50%; - display: inline-block; - text-align: right; - line-height: 1.5em; - input { - float: right; - width: 70%; - margin-left: 10px; + .lockBrew { + columns: 2; + + .lockForm { + break-inside: avoid; + + label { + width: 100%; + display: inline-block; + text-align: right; + line-height: 1.5em; + input { + float: right; + width: 70%; + margin-left: 10px; + } + } + } + + .lockSuggestions { + break-inside: avoid; + columns: 2; + line-height: 1.2em; + h2 { + column-span: all; + } + h3 { + margin-top: 0px; + } + b { + font-weight: 600; + } + + .lockCodes { + break-inside: avoid; + } } } From 7830c7e2eb6bd0fc4e6af5cdac23eee4e5cfc15a Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 19:59:01 +1200 Subject: [PATCH 039/393] Add divs for styling of brewsAwaitingReview --- client/admin/lockTools/lockTools.jsx | 65 +++++++++++++++------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 58829eacf..7f92cdd0e 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -174,35 +174,42 @@ const LockTable = createClass({ render : function () { return <> -

{this.props.title}

- - {this.state.result[this.props.resultName] && - <> -

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

-
- - - {this.props.propertyNames.map((name, idx)=>{ - return ; - })} - - - - {this.state.result[this.props.resultName].map((result, resultIdx)=>{ - return {navigator.clipboard.writeText(result.shareId.toString());}}> - {this.props.propertyNames.map((name, nameIdx)=>{ - return ; - })} - ; - })} - -
{name}
- {result[name].toString()} -
- - } +
+
+

{this.props.title}

+ +
+ {this.state.result[this.props.resultName] && + <> +

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

+
+

Click a row to copy the Share ID to the clipboard

+ + + + {this.props.propertyNames.map((name, idx)=>{ + return ; + })} + + + + {this.state.result[this.props.resultName].map((result, resultIdx)=>{ + return {navigator.clipboard.writeText(result.shareId.toString());}}> + {this.props.propertyNames.map((name, nameIdx)=>{ + return ; + })} + ; + })} + +
{name}
+ {result[name].toString()} +
+ + } +
; } }); From 44f2e3838735868203129b142f93298c79cb3d17 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 20:00:10 +1200 Subject: [PATCH 040/393] Shift unlock and removeReview functions to use PUT --- client/admin/lockTools/lockTools.jsx | 2 +- server/admin.api.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 7f92cdd0e..710d08ff2 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -237,7 +237,7 @@ const LockLookup = createClass({ clickFn(){ this.setState({ searching: true, error: null }); - request.get(`${this.props.fetchURL}/${this.state.query}`) + request.put(`${this.props.fetchURL}/${this.state.query}`) .then((res)=>this.setState({ result: res.body })) .catch((err)=>this.setState({ error: err })) .finally(()=>{ diff --git a/server/admin.api.js b/server/admin.api.js index 8559143c2..d02cdb67b 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -186,7 +186,7 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ } }); -router.get('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ +router.put('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ try { const filter = { shareId : req.params.id @@ -260,7 +260,7 @@ router.put('/admin/lock/review/request/:id', async (req, res)=>{ } }); -router.get('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ +router.put('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ try { const filter = { shareId : req.params.id, From 7d37602d433895c063857df733c0ae2dbdce8e30 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 20:01:53 +1200 Subject: [PATCH 041/393] Remove debugging line --- client/admin/lockTools/lockTools.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 710d08ff2..9a1d1d0ce 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -246,7 +246,6 @@ const LockLookup = createClass({ }, renderResult : function(){ - console.log(this.state.result); return <>

Result:

From 17aa564c57c27174d847676efc86f83efb7e5f24 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 8 Jun 2024 21:05:44 +1200 Subject: [PATCH 042/393] Add styling for result tables --- client/admin/lockTools/lockTools.less | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index c34a69485..272646ce2 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -39,14 +39,14 @@ } .lockTable{ - td{ - border: 1px solid #333333; - padding: 4px 10px; - text-align: center; - - &:hover { - cursor: pointer; - } + td:hover { + cursor: pointer; } } + + td { + border: 1px solid #333333; + padding: 4px 10px; + text-align: center; + } } \ No newline at end of file From 24cf78bc033b565ccde43b78c3837d2c132cbfdf Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Jun 2024 20:44:55 +1200 Subject: [PATCH 043/393] Add lock result --- client/admin/lockTools/lockTools.jsx | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 9a1d1d0ce..bf77be018 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -50,7 +50,8 @@ const LockBrew = createClass({ brewId : '', code : 1000, editMessage : '', - shareMessage : '' + shareMessage : '', + result : {} }; }, @@ -75,7 +76,7 @@ const LockBrew = createClass({ .send(newLock) .set('Content-Type', 'application/json') .then((response)=>{ - console.log(response.body); + this.setState({ result: response.body }); }); }, @@ -83,6 +84,23 @@ const LockBrew = createClass({ return this.handleChange(e, name)} autoComplete='off' required/>; }, + renderResult : function(){ + return <> +

Result:

+
+ + {Object.keys(this.state.result).map((key, idx)=>{ + return + + + ; + })} + +
{key}{this.state.result[key].toString()} +
+ ; + }, + render : function() { return
@@ -112,6 +130,7 @@ const LockBrew = createClass({ + {this.state.result && this.renderResult()}

Suggestions

From c594fc58b35ee76d00770e1a8d885523d29246fa Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Jun 2024 21:47:52 +1200 Subject: [PATCH 044/393] Spread lock object in /lock response --- server/admin.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index d02cdb67b..8f997aed9 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -179,7 +179,7 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ await brew.save(); // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, lock }); + return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); } catch (error) { console.error(error); return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); From fc99328459b1aec2df0aa90cb8890a23a112faa4 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Jun 2024 21:48:55 +1200 Subject: [PATCH 045/393] Tweak styling, remove obsolete locked property --- client/admin/lockTools/lockTools.jsx | 10 +++++----- client/admin/lockTools/lockTools.less | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index bf77be018..2135425eb 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -37,9 +37,11 @@ const LockTools = createClass({

- +
+ + +

-
; } }); @@ -68,8 +70,7 @@ const LockBrew = createClass({ code : parseInt(this.state.code) || 100, editMessage : this.state.editMessage, shareMessage : this.state.shareMessage, - applied : new Date, - locked : true + applied : new Date }; request.post(`/admin/lock/${this.state.brewId}`) @@ -204,7 +205,6 @@ const LockTable = createClass({ {this.state.result[this.props.resultName] && <>

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

-

Click a row to copy the Share ID to the clipboard

diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 272646ce2..d78462d35 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -49,4 +49,10 @@ padding: 4px 10px; text-align: center; } + + .brewLookup{ + h2 { + margin-top: 0px; + } + } } \ No newline at end of file From 7e8078767982710bd05285ff2138a0abd60b793d Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Jun 2024 22:18:12 +1200 Subject: [PATCH 046/393] Tweak styling --- client/admin/lockTools/lockTools.less | 1 + 1 file changed, 1 insertion(+) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index d78462d35..9bf2b39ef 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -51,6 +51,7 @@ } .brewLookup{ + min-height: 175px; h2 { margin-top: 0px; } From 0803362a504e5c2c4bacc8d58533cd598e8a54e0 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Jun 2024 22:29:47 +1200 Subject: [PATCH 047/393] More styling tweaks --- client/admin/lockTools/lockTools.less | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 9bf2b39ef..82341eddb 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -44,11 +44,13 @@ } } - td { - border: 1px solid #333333; + th, td { padding: 4px 10px; text-align: center; } + td{ + border: 1px solid #333333; + } .brewLookup{ min-height: 175px; From 7094d43ee5169d725b48e74a64cb8e9a821bbc1a Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 29 Jun 2024 15:29:02 +1200 Subject: [PATCH 048/393] Shift API calls to /api from /admin --- client/admin/lockTools/lockTools.jsx | 22 +++++++++++---------- client/homebrew/utils/request-middleware.js | 3 ++- server/admin.api.js | 10 +++++----- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 2135425eb..31520b88c 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -3,7 +3,8 @@ require('./lockTools.less'); const React = require('react'); const createClass = require('create-react-class'); -const request = require('superagent'); +// const request = require('superagent'); +const request = require('../../homebrew/utils/request-middleware.js'); const LockTools = createClass({ getInitialState : function() { @@ -18,7 +19,7 @@ const LockTools = createClass({ }, updateReviewCount : async function() { - const newCount = await request.get('/admin/lock') + const newCount = await request.get('/api/lock/count') .then((res)=>{return res.body?.count || 'Unknown';}); if(newCount != this.state.reviewCount){ this.setState({ @@ -33,13 +34,13 @@ const LockTools = createClass({

Number of brews currently locked: {this.state.reviewCount}


- +

- - + +

; @@ -48,11 +49,12 @@ const LockTools = createClass({ const LockBrew = createClass({ getInitialState : function() { + // Default values return { brewId : '', - code : 1000, + code : 455, editMessage : '', - shareMessage : '', + shareMessage : 'This Brew has been locked.', result : {} }; }, @@ -73,7 +75,7 @@ const LockBrew = createClass({ applied : new Date }; - request.post(`/admin/lock/${this.state.brewId}`) + request.post(`/api/lock/${this.state.brewId}`) .send(newLock) .set('Content-Type', 'application/json') .then((response)=>{ @@ -167,7 +169,7 @@ const LockTable = createClass({ getDefaultProps : function() { return { title : '', - fetchURL : '/admin/locks', + fetchURL : '/api/locks', resultName : '', propertyNames : ['shareId'] }; @@ -236,7 +238,7 @@ const LockTable = createClass({ const LockLookup = createClass({ getDefaultProps : function() { return { - fetchURL : '/admin/lookup' + fetchURL : '/api/lookup' }; }, diff --git a/client/homebrew/utils/request-middleware.js b/client/homebrew/utils/request-middleware.js index f6bc2571b..80ee58f5d 100644 --- a/client/homebrew/utils/request-middleware.js +++ b/client/homebrew/utils/request-middleware.js @@ -1,6 +1,7 @@ const request = require('superagent'); +const version = require('../../../package.json').version; -const addHeader = (request)=>request.set('Homebrewery-Version', global.version); +const addHeader = (request)=>request.set('Homebrewery-Version', version); const requestMiddleware = { get : (path)=>addHeader(request.get(path)), diff --git a/server/admin.api.js b/server/admin.api.js index 8f997aed9..1bf597bb4 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -139,7 +139,7 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ } }); -router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ +router.get('/api/lock/count', mw.adminOnly, async (req, res)=>{ try { const countLocksQuery = { lock : { $exists: true } @@ -157,7 +157,7 @@ router.get('/admin/lock', mw.adminOnly, async (req, res)=>{ } }); -router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ +router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ try { const lock = req.body; lock.applied = new Date; @@ -186,7 +186,7 @@ router.post('/admin/lock/:id', mw.adminOnly, async (req, res)=>{ } }); -router.put('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ +router.put('/api/unlock/:id', mw.adminOnly, async (req, res)=>{ try { const filter = { shareId : req.params.id @@ -210,7 +210,7 @@ router.put('/admin/unlock/:id', mw.adminOnly, async (req, res)=>{ return res.json({ status: 'UNLOCKED', detail: `Lock removed from brew ID ${req.params.id}` }); }); -router.get('/admin/lock/reviews', mw.adminOnly, async (req, res)=>{ +router.get('/api/lock/reviews', mw.adminOnly, async (req, res)=>{ try { const countReviewsPipeline = [ { @@ -260,7 +260,7 @@ router.put('/admin/lock/review/request/:id', async (req, res)=>{ } }); -router.put('/admin/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ +router.put('/api/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ try { const filter = { shareId : req.params.id, From b0687493803eda0e8500a8223c2d34ec01b141ec Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 25 Jul 2024 22:11:14 +1200 Subject: [PATCH 049/393] Move copy ID to clipboard to separate button --- client/admin/lockTools/lockTools.jsx | 7 +++++-- client/admin/lockTools/lockTools.less | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 31520b88c..b5c94399a 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -207,23 +207,26 @@ const LockTable = createClass({ {this.state.result[this.props.resultName] && <>

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

-

Click a row to copy the Share ID to the clipboard

{this.props.propertyNames.map((name, idx)=>{ return ; })} + + {this.state.result[this.props.resultName].map((result, resultIdx)=>{ - return {navigator.clipboard.writeText(result.shareId.toString());}}> + return {this.props.propertyNames.map((name, nameIdx)=>{ return ; })} + + ; })} diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 82341eddb..5737a32e0 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -39,8 +39,16 @@ } .lockTable{ - td:hover { + cursor: default; + .row:hover { + background-color: #ccc; + color: #000; + } + .icon { cursor: pointer; + &:hover{ + text-shadow: 0px 0px 6px black; + } } } From fd5ff2c61a38137ec956491a7e31a8bf2ab7287b Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 23 Aug 2024 14:04:04 -0500 Subject: [PATCH 050/393] Relocate more general purposes snippets from 5ePHB to Blank Should include all supporting style content. --- themes/V3/5ePHB/snippets.js | 128 ------------------ themes/V3/Blank/snippets.js | 73 +++++++++- .../V3/{5ePHB => Blank}/snippets/index.gen.js | 0 .../snippets/tableOfContents.gen.js | 0 themes/V3/Blank/style.less | 127 +++++++++++++++++ 5 files changed, 199 insertions(+), 129 deletions(-) rename themes/V3/{5ePHB => Blank}/snippets/index.gen.js (100%) rename themes/V3/{5ePHB => Blank}/snippets/tableOfContents.gen.js (100%) diff --git a/themes/V3/5ePHB/snippets.js b/themes/V3/5ePHB/snippets.js index 4daa05c51..f5c8120c1 100644 --- a/themes/V3/5ePHB/snippets.js +++ b/themes/V3/5ePHB/snippets.js @@ -6,138 +6,13 @@ const MonsterBlockGen = require('./snippets/monsterblock.gen.js'); const scriptGen = require('./snippets/script.gen.js'); const ClassFeatureGen = require('./snippets/classfeature.gen.js'); const CoverPageGen = require('./snippets/coverpage.gen.js'); -const TableOfContentsGen = require('./snippets/tableOfContents.gen.js'); -const indexGen = require('./snippets/index.gen.js'); const QuoteGen = require('./snippets/quote.gen.js'); const dedent = require('dedent-tabs').default; module.exports = [ - - { - groupName : 'Text Editor', - icon : 'fas fa-pencil-alt', - view : 'text', - snippets : [ - { - name : 'Table of Contents', - icon : 'fas fa-book', - gen : TableOfContentsGen, - experimental : true, - subsnippets : [ - { - name : 'Table of Contents', - icon : 'fas fa-book', - gen : TableOfContentsGen, - experimental : true - }, - { - name : 'Include in ToC up to H3', - icon : 'fas fa-dice-three', - gen : dedent `\n{{tocDepthH3 - }}\n`, - - }, - { - name : 'Include in ToC up to H4', - icon : 'fas fa-dice-four', - gen : dedent `\n{{tocDepthH4 - }}\n`, - }, - { - name : 'Include in ToC up to H5', - icon : 'fas fa-dice-five', - gen : dedent `\n{{tocDepthH5 - }}\n`, - }, - { - name : 'Include in ToC up to H6', - icon : 'fas fa-dice-six', - gen : dedent `\n{{tocDepthH6 - }}\n`, - } - ] - }, - { - name : 'Index', - icon : 'fas fa-bars', - gen : indexGen, - experimental : true - } - ] - }, - { - groupName : 'Style Editor', - icon : 'fas fa-pencil-alt', - view : 'style', - snippets : [ - { - name : 'Remove Drop Cap', - icon : 'fas fa-remove-format', - gen : dedent`/* Removes Drop Caps */ - .page h1+p:first-letter { - all: unset; - }\n\n - /* Removes Small-Caps in first line */ - .page h1+p:first-line { - all: unset; - }` - }, - { - name : 'Tweak Drop Cap', - icon : 'fas fa-sliders-h', - gen : dedent`/* Drop Cap settings */ - .page h1 + p::first-letter { - font-family: SolberaImitationRemake; - font-size: 3.5cm; - background-image: linear-gradient(-45deg, #322814, #998250, #322814); - line-height: 1em; - }\n\n` - } - ] - }, - - /*********************** IMAGES *******************/ - { - groupName : 'Images', - icon : 'fas fa-images', - view : 'text', - snippets : [ - { - name : 'Image', - icon : 'fas fa-image', - gen : dedent` - ![cat warrior](https://s-media-cache-ak0.pinimg.com/736x/4a/81/79/4a8179462cfdf39054a418efd4cb743e.jpg) {width:325px,mix-blend-mode:multiply} - - {{artist,position:relative,top:-230px,left:10px,margin-bottom:-30px - ##### Cat Warrior - [Kyoung Hwan Kim](https://www.artstation.com/tahra) - }}` - }, - { - name : 'Background Image', - icon : 'fas fa-tree', - gen : dedent` - ![homebrew mug](http://i.imgur.com/hMna6G0.png) {position:absolute,top:50px,right:30px,width:280px} - - {{artist,top:80px,right:30px - ##### Homebrew Mug - [naturalcrit](https://homebrew.naturalcrit.com) - }}` - }, - { - name : 'Watermark', - icon : 'fas fa-id-card', - gen : dedent` - {{watermark Homebrewery}}\n` - }, - ] - }, - - /************************* PHB ********************/ - { groupName : 'PHB', icon : 'fas fa-book', @@ -332,9 +207,6 @@ module.exports = [ ] }, - - - /**************** PAGE *************/ { diff --git a/themes/V3/Blank/snippets.js b/themes/V3/Blank/snippets.js index 8d45560c5..b30412bd0 100644 --- a/themes/V3/Blank/snippets.js +++ b/themes/V3/Blank/snippets.js @@ -4,6 +4,8 @@ const WatercolorGen = require('./snippets/watercolor.gen.js'); const ImageMaskGen = require('./snippets/imageMask.gen.js'); const FooterGen = require('./snippets/footer.gen.js'); const dedent = require('dedent-tabs').default; +const TableOfContentsGen = require('./snippets/tableOfContents.gen.js'); +const indexGen = require('./snippets/index.gen.js'); module.exports = [ @@ -125,7 +127,53 @@ module.exports = [ [Homebrewery.Naturalcrit.com](https://homebrewery.naturalcrit.com) }}\n\n`; }, - } + }, + { + name : 'Table of Contents', + icon : 'fas fa-book', + gen : TableOfContentsGen, + experimental : true, + subsnippets : [ + { + name : 'Table of Contents', + icon : 'fas fa-book', + gen : TableOfContentsGen, + experimental : true + }, + { + name : 'Include in ToC up to H3', + icon : 'fas fa-dice-three', + gen : dedent `\n{{tocDepthH3 + }}\n`, + + }, + { + name : 'Include in ToC up to H4', + icon : 'fas fa-dice-four', + gen : dedent `\n{{tocDepthH4 + }}\n`, + }, + { + name : 'Include in ToC up to H5', + icon : 'fas fa-dice-five', + gen : dedent `\n{{tocDepthH5 + }}\n`, + }, + { + name : 'Include in ToC up to H6', + icon : 'fas fa-dice-six', + gen : dedent `\n{{tocDepthH6 + }}\n`, + } + ] + }, + { + name : 'Index', + icon : 'fas fa-bars', + gen : indexGen, + experimental : true + }, + ] }, { @@ -138,6 +186,29 @@ module.exports = [ icon : 'fas fa-code', gen : '/* This is a comment that will not be rendered into your brew. */' }, + { + name : 'Remove Drop Cap', + icon : 'fas fa-remove-format', + gen : dedent`/* Removes Drop Caps */ + .page h1+p:first-letter { + all: unset; + }\n\n + /* Removes Small-Caps in first line */ + .page h1+p:first-line { + all: unset; + }` + }, + { + name : 'Tweak Drop Cap', + icon : 'fas fa-sliders-h', + gen : dedent`/* Drop Cap settings */ + .page h1 + p::first-letter { + font-family: SolberaImitationRemake; + font-size: 3.5cm; + background-image: linear-gradient(-45deg, #322814, #998250, #322814); + line-height: 1em; + }\n\n` + }, ] }, diff --git a/themes/V3/5ePHB/snippets/index.gen.js b/themes/V3/Blank/snippets/index.gen.js similarity index 100% rename from themes/V3/5ePHB/snippets/index.gen.js rename to themes/V3/Blank/snippets/index.gen.js diff --git a/themes/V3/5ePHB/snippets/tableOfContents.gen.js b/themes/V3/Blank/snippets/tableOfContents.gen.js similarity index 100% rename from themes/V3/5ePHB/snippets/tableOfContents.gen.js rename to themes/V3/Blank/snippets/tableOfContents.gen.js diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 18a478cf9..4b0653f4b 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -482,3 +482,130 @@ body { counter-reset : page-numbers; } .pageNumber { left : 30px; } } } + +// ***************************** +// * INDEX +// *****************************/ +.page { + .index { + font-size : 0.218cm; + + ul ul { margin : 0; } + + ul { + padding-left : 0; + text-indent : 0; + list-style-type : none; + } + + & > ul > li { + padding-left : 1.5em; + text-indent : -1.5em; + } + } +} + +// ***************************** +// * TABLE OF CONTENTS +// *****************************/ + +// Default Exclusions +// Anything not exlcuded is included, default Headers are H1, H2, and H3. +h4, +h5, +h6, +.page:has(.frontCover), +.page:has(.backCover), +.page:has(.insideCover), +.monster, +.noToC, +.toc { --TOC: exclude; } + +.tocDepthH2 :is(h1, h2) {--TOC: include; } +.tocDepthH3 :is(h1, h2, h3) {--TOC: include; } +.tocDepthH4 :is(h1, h2, h3, h4) {--TOC: include; } +.tocDepthH5 :is(h1, h2, h3, h4, h5) {--TOC: include; } +.tocDepthH6 :is(h1, h2, h3, h4, h5, h6) {--TOC: include; } + +.tocIncludeH1 h1 {--TOC: include; } +.tocIncludeH2 h2 {--TOC: include; } +.tocIncludeH3 h3 {--TOC: include; } +.tocIncludeH4 h4 {--TOC: include; } +.tocIncludeH5 h5 {--TOC: include; } +.tocIncludeH6 h6 {--TOC: include; } + +.page:has(.partCover) { + --TOC: exclude; + & h1 { + --TOC: include; + } + } + +.page { + &:has(.toc)::after { display : none; } + .toc { + -webkit-column-break-inside : avoid; + page-break-inside : avoid; + break-inside : avoid; + h1 { + margin-bottom : 0.3cm; + text-align : center; + } + a { + display : inline; + color : inherit; + text-decoration : none; + &:hover { text-decoration : underline; } + } + h4 { + margin-top : 0.2cm; + line-height : 0.4cm; + & + ul li { line-height : 1.2em; } + } + ul { + padding-left : 0; + margin-top : 0; + list-style-type : none; + a { + display : flex; + flex-flow : row nowrap; + justify-content : space-between; + width : 100%; + } + li + li h3 { + margin-top : 0.26cm; + line-height : 1em; + } + h3 span:first-child::after { border : none; } + span { + display : contents; + &:first-child::after { + bottom : 0.08cm; + flex : 1; + margin-right : 0.16cm; + margin-bottom : 0.08cm; + margin-left : 0.08cm; /* Spacing before dot leaders */ + content : ''; + border-bottom : 0.05cm dotted #000000; + } + &:last-child { + display : inline-block; + align-self : flex-end; + font-family : 'BookInsanityRemake'; + font-size : 0.34cm; + font-weight : normal; + color : #000000; + } + } + ul { /* List indent */ + margin-left : 1em; + } + } + &.wide { + .useColumns(0.96, @fillMode: balance); + } + } + .toc.wide li { + break-inside: auto; + } +} From 2c573bfef5dee6829418318c99822c223af0cc8e Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 23 Aug 2024 14:18:58 -0500 Subject: [PATCH 051/393] Failed to save one file's changes. --- themes/V3/5ePHB/style.less | 126 ------------------------------------- 1 file changed, 126 deletions(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index ddffbec2f..e4bbb3514 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -792,111 +792,6 @@ } } -// ***************************** -// * TABLE OF CONTENTS -// *****************************/ - -// Default Exclusions -// Anything not exlcuded is included, default Headers are H1, H2, and H3. -h4, -h5, -h6, -.page:has(.frontCover), -.page:has(.backCover), -.page:has(.insideCover), -.monster, -.noToC, -.toc { --TOC: exclude; } - -.tocDepthH2 :is(h1, h2) {--TOC: include; } -.tocDepthH3 :is(h1, h2, h3) {--TOC: include; } -.tocDepthH4 :is(h1, h2, h3, h4) {--TOC: include; } -.tocDepthH5 :is(h1, h2, h3, h4, h5) {--TOC: include; } -.tocDepthH6 :is(h1, h2, h3, h4, h5, h6) {--TOC: include; } - -.tocIncludeH1 h1 {--TOC: include; } -.tocIncludeH2 h2 {--TOC: include; } -.tocIncludeH3 h3 {--TOC: include; } -.tocIncludeH4 h4 {--TOC: include; } -.tocIncludeH5 h5 {--TOC: include; } -.tocIncludeH6 h6 {--TOC: include; } - -.page:has(.partCover) { - --TOC: exclude; - & h1 { - --TOC: include; - } - } - -.page { - &:has(.toc)::after { display : none; } - .toc { - -webkit-column-break-inside : avoid; - page-break-inside : avoid; - break-inside : avoid; - h1 { - margin-bottom : 0.3cm; - text-align : center; - } - a { - display : inline; - color : inherit; - text-decoration : none; - &:hover { text-decoration : underline; } - } - h4 { - margin-top : 0.2cm; - line-height : 0.4cm; - & + ul li { line-height : 1.2em; } - } - ul { - padding-left : 0; - margin-top : 0; - list-style-type : none; - a { - display : flex; - flex-flow : row nowrap; - justify-content : space-between; - width : 100%; - } - li + li h3 { - margin-top : 0.26cm; - line-height : 1em; - } - h3 span:first-child::after { border : none; } - span { - display : contents; - &:first-child::after { - bottom : 0.08cm; - flex : 1; - margin-right : 0.16cm; - margin-bottom : 0.08cm; - margin-left : 0.08cm; /* Spacing before dot leaders */ - content : ''; - border-bottom : 0.05cm dotted #000000; - } - &:last-child { - display : inline-block; - align-self : flex-end; - font-family : 'BookInsanityRemake'; - font-size : 0.34cm; - font-weight : normal; - color : #000000; - } - } - ul { /* List indent */ - margin-left : 1em; - } - } - &.wide { - .useColumns(0.96, @fillMode: balance); - } - } - .toc.wide li { - break-inside: auto; - } -} - // ***************************** // * DEFINITION LISTS // *****************************/ @@ -958,24 +853,3 @@ h6, } } } -// ***************************** -// * INDEX -// *****************************/ -.page { - .index { - font-size : 0.218cm; - - ul ul { margin : 0; } - - ul { - padding-left : 0; - text-indent : 0; - list-style-type : none; - } - - & > ul > li { - padding-left : 1.5em; - text-indent : -1.5em; - } - } -} From ad1dfc8e2bc10f82f581c3267882df2cc1545235 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 23 Aug 2024 16:52:35 -0500 Subject: [PATCH 052/393] Move Page styles ( cover Page, etc ) to Blank from 5ePHB --- themes/V3/5ePHB/style.less | 264 ------------------------------------ themes/V3/Blank/style.less | 265 +++++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+), 264 deletions(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index e4bbb3514..e33a0b2be 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -538,259 +538,6 @@ } h5 + table { margin-top : 0.2cm; } } -// ***************************** -// * FRONT COVER PAGE -// *****************************/ -.page:has(.frontCover) { - columns : 1; - text-align : center; - &::after { display : none; } - h1 { - margin-top : 1.2cm; - margin-bottom : 0; - font-family : 'NodestoCapsCondensed'; - font-size : 2.245cm; - font-weight : normal; - line-height : 1.9cm; - color : white; - text-shadow : unset; - text-transform : uppercase; - -webkit-text-stroke: 0.2cm black; - paint-order:stroke; - } - h2 { - font-family : 'NodestoCapsCondensed'; - font-size : 0.85cm; - font-weight : normal; - color : white; - letter-spacing : 0.1cm; - -webkit-text-stroke: 0.14cm black; - paint-order:stroke; - } - hr { - position : relative; - display : block; - width : 12cm; - height : 0.5cm; - margin : auto; - visibility : visible; - background-image : @horizontalRule; - filter : drop-shadow(0 0 3px black); - background-size : 100% 100%; - border : none; - } - .banner { - position : absolute; - bottom : 4.2cm; - left : 0; - display : flex; - flex-direction : column; - justify-content : center; - width : 10.5cm; - height : 1.7cm; - padding-top : 0.1cm; - padding-left : 1cm; - font-family : 'NodestoCapsCondensed'; - font-size : 1cm; - font-weight : normal; - color : white; - text-align : left; - letter-spacing : 0.014cm; - background-image : url('/assets/coverPageBanner.svg'); - filter : drop-shadow(2px 2px 2px black); - } - .footnote { - position : absolute; - right : 0; - bottom : 1.3cm; - left : 0; - width : 70%; - margin-right : auto; - margin-left : auto; - font-family : 'Overpass'; - font-size : 0.496cm; - color : white; - text-align : center; - -webkit-text-stroke: 0.1cm black; - paint-order:stroke; - } - .logo { - position : absolute; - top : 0.5cm; - right : 0; - left : 0; - filter : drop-shadow(0 0 0.075cm black); - img { - width : 100%; - height : 2cm; - } - } -} -// ***************************** -// * INSIDE COVER PAGE -// *****************************/ -.page:has(.insideCover) { - columns : 1; - text-align : center; - &::after { display : none; } - h1 { - margin-top : 1.2cm; - margin-bottom : 0; - font-family : 'NodestoCapsCondensed'; - font-size : 2.1cm; - font-weight : normal; - line-height : 1.785cm; - text-transform : uppercase; - } - h2 { - font-family : 'NodestoCapsCondensed'; - font-size : 0.85cm; - font-weight : normal; - letter-spacing : 0.5cm; - } - hr { - position : relative; - display : block; - width : 12cm; - height : 0.5cm; - margin : auto; - visibility : visible; - background-image : @horizontalRule; - background-size : 100% 100%; - border : none; - } - .logo { - position : absolute; - right : 0; - bottom : 1cm; - left : 0; - height : 2cm; - img { - width : 100%; - height : 2cm; - } - } -} -// ***************************** -// * BACK COVER -// *****************************/ -.page:has(.backCover) { - padding : 2.25cm 1.3cm 2cm 1.3cm; - color : #FFFFFF; - columns : 1; - &::after { display : none; } - .columnWrapper { width : 7.6cm; } - .backCover { - position : absolute; - inset : 0; - z-index : -1; - width : 11cm; - background-image : @backCover; - background-repeat : no-repeat; - background-size : contain; - } - .blank { height : 1.4em; } - h1 { - margin-bottom : 0.3cm; - font-family : 'NodestoCapsCondensed'; - font-size : 1.35cm; - line-height : 1.28cm; - color : #ED1C24; - text-align : center; - } - h1 + p::first-line, - h1 + p::first-letter { all : unset; } - img { - position : absolute; - top : 0px; - z-index : -2; - height : 100%; - } - hr { - width : 4.5cm; - height : 0.53cm; - margin-top : 1.1cm; - margin-right : auto; - margin-left : auto; - visibility : visible; - background-image : @horizontalRule; - background-size : 100% 100%; - border : none; - } - p { - font-family : 'Overpass'; - font-size : 0.332cm; - line-height : 0.35cm; - } - hr + p { - margin-top : 0.6cm; - text-align : center; - } - .logo { - position : absolute; - bottom : 2cm; - left : 1.2cm; - z-index : 0; - width : 7.6cm; - height : 1.5cm; - img { - position : relative; - z-index : 0; - width : 100%; - height : 1.5cm; - } - p { - position : relative; - width : 100%; - font-family : 'NodestoCapsWide'; - font-size : 0.4cm; - line-height : 1em; - line-height : 1.28cm; - color : #FFFFFF; - text-align : center; - text-indent : 0; - } - } -} - -// ***************************** -// * PART COVER -// *****************************/ -.page:has(.partCover) { - padding-top : 0; - text-align : center; - columns : 1; - - .partCover { - position : absolute; - top : 0; - left : 0; - width : 100%; - height : 6cm; - background-image : @partCoverHeaderPHB; - background-repeat : no-repeat; - background-size : 100%; - } - - h1 { - position : relative; - margin-top : 0.4cm; - font-family : 'NodestoCapsCondensed'; - font-size : 2.3cm; - text-align : center; - text-transform : uppercase; - } - - h2 { - position : relative; - margin-top : -0.7em; - margin-right : auto; - margin-left : auto; - font-family : 'Overpass'; - font-size : 0.45cm; - line-height : 0.495cm; - } -} // ***************************** // * DEFINITION LISTS @@ -807,17 +554,6 @@ } } -// ***************************** -// * WIDE -// *****************************/ -.page .wide { margin-bottom : 0.325cm; } - -.page h1 + * { margin-top : 0; } - -.page .descriptive.wide + * { - margin-top: 0; -} - //***************************** // * RUNE TABLE // *****************************/ diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 4b0653f4b..791ebce73 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -609,3 +609,268 @@ h6, break-inside: auto; } } + +// ***************************** +// * WIDE +// *****************************/ +.page .wide { margin-bottom : 0.325cm; } + +.page h1 + * { margin-top : 0; } + +.page .descriptive.wide + * { + margin-top: 0; +} + +// ***************************** +// * FRONT COVER PAGE +// *****************************/ +.page:has(.frontCover) { + columns : 1; + text-align : center; + &::after { display : none; } + h1 { + margin-top : 1.2cm; + margin-bottom : 0; + font-family : 'NodestoCapsCondensed'; + font-size : 2.245cm; + font-weight : normal; + line-height : 1.9cm; + color : white; + text-shadow : unset; + text-transform : uppercase; + -webkit-text-stroke: 0.2cm black; + paint-order:stroke; + } + h2 { + font-family : 'NodestoCapsCondensed'; + font-size : 0.85cm; + font-weight : normal; + color : white; + letter-spacing : 0.1cm; + -webkit-text-stroke: 0.14cm black; + paint-order:stroke; + } + hr { + position : relative; + display : block; + width : 12cm; + height : 0.5cm; + margin : auto; + visibility : visible; + background-image : @horizontalRule; + filter : drop-shadow(0 0 3px black); + background-size : 100% 100%; + border : none; + } + .banner { + position : absolute; + bottom : 4.2cm; + left : 0; + display : flex; + flex-direction : column; + justify-content : center; + width : 10.5cm; + height : 1.7cm; + padding-top : 0.1cm; + padding-left : 1cm; + font-family : 'NodestoCapsCondensed'; + font-size : 1cm; + font-weight : normal; + color : white; + text-align : left; + letter-spacing : 0.014cm; + background-image : url('/assets/coverPageBanner.svg'); + filter : drop-shadow(2px 2px 2px black); + } + .footnote { + position : absolute; + right : 0; + bottom : 1.3cm; + left : 0; + width : 70%; + margin-right : auto; + margin-left : auto; + font-family : 'Overpass'; + font-size : 0.496cm; + color : white; + text-align : center; + -webkit-text-stroke: 0.1cm black; + paint-order:stroke; + } + .logo { + position : absolute; + top : 0.5cm; + right : 0; + left : 0; + filter : drop-shadow(0 0 0.075cm black); + img { + width : 100%; + height : 2cm; + } + } +} +// ***************************** +// * INSIDE COVER PAGE +// *****************************/ +.page:has(.insideCover) { + columns : 1; + text-align : center; + &::after { display : none; } + h1 { + margin-top : 1.2cm; + margin-bottom : 0; + font-family : 'NodestoCapsCondensed'; + font-size : 2.1cm; + font-weight : normal; + line-height : 1.785cm; + text-transform : uppercase; + } + h2 { + font-family : 'NodestoCapsCondensed'; + font-size : 0.85cm; + font-weight : normal; + letter-spacing : 0.5cm; + } + hr { + position : relative; + display : block; + width : 12cm; + height : 0.5cm; + margin : auto; + visibility : visible; + background-image : @horizontalRule; + background-size : 100% 100%; + border : none; + } + .logo { + position : absolute; + right : 0; + bottom : 1cm; + left : 0; + height : 2cm; + img { + width : 100%; + height : 2cm; + } + } +} +// ***************************** +// * BACK COVER +// *****************************/ +.page:has(.backCover) { + padding : 2.25cm 1.3cm 2cm 1.3cm; + color : #FFFFFF; + columns : 1; + &::after { display : none; } + .columnWrapper { width : 7.6cm; } + .backCover { + position : absolute; + inset : 0; + z-index : -1; + width : 11cm; + background-image : @backCover; + background-repeat : no-repeat; + background-size : contain; + } + .blank { height : 1.4em; } + h1 { + margin-bottom : 0.3cm; + font-family : 'NodestoCapsCondensed'; + font-size : 1.35cm; + line-height : 1.28cm; + color : #ED1C24; + text-align : center; + } + h1 + p::first-line, + h1 + p::first-letter { all : unset; } + img { + position : absolute; + top : 0px; + z-index : -2; + height : 100%; + } + hr { + width : 4.5cm; + height : 0.53cm; + margin-top : 1.1cm; + margin-right : auto; + margin-left : auto; + visibility : visible; + background-image : @horizontalRule; + background-size : 100% 100%; + border : none; + } + p { + font-family : 'Overpass'; + font-size : 0.332cm; + line-height : 0.35cm; + } + hr + p { + margin-top : 0.6cm; + text-align : center; + } + .logo { + position : absolute; + bottom : 2cm; + left : 1.2cm; + z-index : 0; + width : 7.6cm; + height : 1.5cm; + img { + position : relative; + z-index : 0; + width : 100%; + height : 1.5cm; + } + p { + position : relative; + width : 100%; + font-family : 'NodestoCapsWide'; + font-size : 0.4cm; + line-height : 1em; + line-height : 1.28cm; + color : #FFFFFF; + text-align : center; + text-indent : 0; + } + } +} + +// ***************************** +// * PART COVER +// *****************************/ +.page:has(.partCover) { + padding-top : 0; + text-align : center; + columns : 1; + + .partCover { + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 6cm; + background-image : @partCoverHeaderPHB; + background-repeat : no-repeat; + background-size : 100%; + } + + h1 { + position : relative; + margin-top : 0.4cm; + font-family : 'NodestoCapsCondensed'; + font-size : 2.3cm; + text-align : center; + text-transform : uppercase; + } + + h2 { + position : relative; + margin-top : -0.7em; + margin-right : auto; + margin-left : auto; + font-family : 'Overpass'; + font-size : 0.45cm; + line-height : 0.495cm; + } +} From a3c01305df17b78d860de1d0c407941103516393 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 25 Aug 2024 19:15:57 -0500 Subject: [PATCH 053/393] Revert "Move Page styles ( cover Page, etc ) to Blank from 5ePHB" This reverts commit ad1dfc8e2bc10f82f581c3267882df2cc1545235. --- themes/V3/5ePHB/style.less | 264 ++++++++++++++++++++++++++++++++++++ themes/V3/Blank/style.less | 265 ------------------------------------- 2 files changed, 264 insertions(+), 265 deletions(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index e33a0b2be..e4bbb3514 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -538,6 +538,259 @@ } h5 + table { margin-top : 0.2cm; } } +// ***************************** +// * FRONT COVER PAGE +// *****************************/ +.page:has(.frontCover) { + columns : 1; + text-align : center; + &::after { display : none; } + h1 { + margin-top : 1.2cm; + margin-bottom : 0; + font-family : 'NodestoCapsCondensed'; + font-size : 2.245cm; + font-weight : normal; + line-height : 1.9cm; + color : white; + text-shadow : unset; + text-transform : uppercase; + -webkit-text-stroke: 0.2cm black; + paint-order:stroke; + } + h2 { + font-family : 'NodestoCapsCondensed'; + font-size : 0.85cm; + font-weight : normal; + color : white; + letter-spacing : 0.1cm; + -webkit-text-stroke: 0.14cm black; + paint-order:stroke; + } + hr { + position : relative; + display : block; + width : 12cm; + height : 0.5cm; + margin : auto; + visibility : visible; + background-image : @horizontalRule; + filter : drop-shadow(0 0 3px black); + background-size : 100% 100%; + border : none; + } + .banner { + position : absolute; + bottom : 4.2cm; + left : 0; + display : flex; + flex-direction : column; + justify-content : center; + width : 10.5cm; + height : 1.7cm; + padding-top : 0.1cm; + padding-left : 1cm; + font-family : 'NodestoCapsCondensed'; + font-size : 1cm; + font-weight : normal; + color : white; + text-align : left; + letter-spacing : 0.014cm; + background-image : url('/assets/coverPageBanner.svg'); + filter : drop-shadow(2px 2px 2px black); + } + .footnote { + position : absolute; + right : 0; + bottom : 1.3cm; + left : 0; + width : 70%; + margin-right : auto; + margin-left : auto; + font-family : 'Overpass'; + font-size : 0.496cm; + color : white; + text-align : center; + -webkit-text-stroke: 0.1cm black; + paint-order:stroke; + } + .logo { + position : absolute; + top : 0.5cm; + right : 0; + left : 0; + filter : drop-shadow(0 0 0.075cm black); + img { + width : 100%; + height : 2cm; + } + } +} +// ***************************** +// * INSIDE COVER PAGE +// *****************************/ +.page:has(.insideCover) { + columns : 1; + text-align : center; + &::after { display : none; } + h1 { + margin-top : 1.2cm; + margin-bottom : 0; + font-family : 'NodestoCapsCondensed'; + font-size : 2.1cm; + font-weight : normal; + line-height : 1.785cm; + text-transform : uppercase; + } + h2 { + font-family : 'NodestoCapsCondensed'; + font-size : 0.85cm; + font-weight : normal; + letter-spacing : 0.5cm; + } + hr { + position : relative; + display : block; + width : 12cm; + height : 0.5cm; + margin : auto; + visibility : visible; + background-image : @horizontalRule; + background-size : 100% 100%; + border : none; + } + .logo { + position : absolute; + right : 0; + bottom : 1cm; + left : 0; + height : 2cm; + img { + width : 100%; + height : 2cm; + } + } +} +// ***************************** +// * BACK COVER +// *****************************/ +.page:has(.backCover) { + padding : 2.25cm 1.3cm 2cm 1.3cm; + color : #FFFFFF; + columns : 1; + &::after { display : none; } + .columnWrapper { width : 7.6cm; } + .backCover { + position : absolute; + inset : 0; + z-index : -1; + width : 11cm; + background-image : @backCover; + background-repeat : no-repeat; + background-size : contain; + } + .blank { height : 1.4em; } + h1 { + margin-bottom : 0.3cm; + font-family : 'NodestoCapsCondensed'; + font-size : 1.35cm; + line-height : 1.28cm; + color : #ED1C24; + text-align : center; + } + h1 + p::first-line, + h1 + p::first-letter { all : unset; } + img { + position : absolute; + top : 0px; + z-index : -2; + height : 100%; + } + hr { + width : 4.5cm; + height : 0.53cm; + margin-top : 1.1cm; + margin-right : auto; + margin-left : auto; + visibility : visible; + background-image : @horizontalRule; + background-size : 100% 100%; + border : none; + } + p { + font-family : 'Overpass'; + font-size : 0.332cm; + line-height : 0.35cm; + } + hr + p { + margin-top : 0.6cm; + text-align : center; + } + .logo { + position : absolute; + bottom : 2cm; + left : 1.2cm; + z-index : 0; + width : 7.6cm; + height : 1.5cm; + img { + position : relative; + z-index : 0; + width : 100%; + height : 1.5cm; + } + p { + position : relative; + width : 100%; + font-family : 'NodestoCapsWide'; + font-size : 0.4cm; + line-height : 1em; + line-height : 1.28cm; + color : #FFFFFF; + text-align : center; + text-indent : 0; + } + } +} + +// ***************************** +// * PART COVER +// *****************************/ +.page:has(.partCover) { + padding-top : 0; + text-align : center; + columns : 1; + + .partCover { + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 6cm; + background-image : @partCoverHeaderPHB; + background-repeat : no-repeat; + background-size : 100%; + } + + h1 { + position : relative; + margin-top : 0.4cm; + font-family : 'NodestoCapsCondensed'; + font-size : 2.3cm; + text-align : center; + text-transform : uppercase; + } + + h2 { + position : relative; + margin-top : -0.7em; + margin-right : auto; + margin-left : auto; + font-family : 'Overpass'; + font-size : 0.45cm; + line-height : 0.495cm; + } +} // ***************************** // * DEFINITION LISTS @@ -554,6 +807,17 @@ } } +// ***************************** +// * WIDE +// *****************************/ +.page .wide { margin-bottom : 0.325cm; } + +.page h1 + * { margin-top : 0; } + +.page .descriptive.wide + * { + margin-top: 0; +} + //***************************** // * RUNE TABLE // *****************************/ diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 791ebce73..4b0653f4b 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -609,268 +609,3 @@ h6, break-inside: auto; } } - -// ***************************** -// * WIDE -// *****************************/ -.page .wide { margin-bottom : 0.325cm; } - -.page h1 + * { margin-top : 0; } - -.page .descriptive.wide + * { - margin-top: 0; -} - -// ***************************** -// * FRONT COVER PAGE -// *****************************/ -.page:has(.frontCover) { - columns : 1; - text-align : center; - &::after { display : none; } - h1 { - margin-top : 1.2cm; - margin-bottom : 0; - font-family : 'NodestoCapsCondensed'; - font-size : 2.245cm; - font-weight : normal; - line-height : 1.9cm; - color : white; - text-shadow : unset; - text-transform : uppercase; - -webkit-text-stroke: 0.2cm black; - paint-order:stroke; - } - h2 { - font-family : 'NodestoCapsCondensed'; - font-size : 0.85cm; - font-weight : normal; - color : white; - letter-spacing : 0.1cm; - -webkit-text-stroke: 0.14cm black; - paint-order:stroke; - } - hr { - position : relative; - display : block; - width : 12cm; - height : 0.5cm; - margin : auto; - visibility : visible; - background-image : @horizontalRule; - filter : drop-shadow(0 0 3px black); - background-size : 100% 100%; - border : none; - } - .banner { - position : absolute; - bottom : 4.2cm; - left : 0; - display : flex; - flex-direction : column; - justify-content : center; - width : 10.5cm; - height : 1.7cm; - padding-top : 0.1cm; - padding-left : 1cm; - font-family : 'NodestoCapsCondensed'; - font-size : 1cm; - font-weight : normal; - color : white; - text-align : left; - letter-spacing : 0.014cm; - background-image : url('/assets/coverPageBanner.svg'); - filter : drop-shadow(2px 2px 2px black); - } - .footnote { - position : absolute; - right : 0; - bottom : 1.3cm; - left : 0; - width : 70%; - margin-right : auto; - margin-left : auto; - font-family : 'Overpass'; - font-size : 0.496cm; - color : white; - text-align : center; - -webkit-text-stroke: 0.1cm black; - paint-order:stroke; - } - .logo { - position : absolute; - top : 0.5cm; - right : 0; - left : 0; - filter : drop-shadow(0 0 0.075cm black); - img { - width : 100%; - height : 2cm; - } - } -} -// ***************************** -// * INSIDE COVER PAGE -// *****************************/ -.page:has(.insideCover) { - columns : 1; - text-align : center; - &::after { display : none; } - h1 { - margin-top : 1.2cm; - margin-bottom : 0; - font-family : 'NodestoCapsCondensed'; - font-size : 2.1cm; - font-weight : normal; - line-height : 1.785cm; - text-transform : uppercase; - } - h2 { - font-family : 'NodestoCapsCondensed'; - font-size : 0.85cm; - font-weight : normal; - letter-spacing : 0.5cm; - } - hr { - position : relative; - display : block; - width : 12cm; - height : 0.5cm; - margin : auto; - visibility : visible; - background-image : @horizontalRule; - background-size : 100% 100%; - border : none; - } - .logo { - position : absolute; - right : 0; - bottom : 1cm; - left : 0; - height : 2cm; - img { - width : 100%; - height : 2cm; - } - } -} -// ***************************** -// * BACK COVER -// *****************************/ -.page:has(.backCover) { - padding : 2.25cm 1.3cm 2cm 1.3cm; - color : #FFFFFF; - columns : 1; - &::after { display : none; } - .columnWrapper { width : 7.6cm; } - .backCover { - position : absolute; - inset : 0; - z-index : -1; - width : 11cm; - background-image : @backCover; - background-repeat : no-repeat; - background-size : contain; - } - .blank { height : 1.4em; } - h1 { - margin-bottom : 0.3cm; - font-family : 'NodestoCapsCondensed'; - font-size : 1.35cm; - line-height : 1.28cm; - color : #ED1C24; - text-align : center; - } - h1 + p::first-line, - h1 + p::first-letter { all : unset; } - img { - position : absolute; - top : 0px; - z-index : -2; - height : 100%; - } - hr { - width : 4.5cm; - height : 0.53cm; - margin-top : 1.1cm; - margin-right : auto; - margin-left : auto; - visibility : visible; - background-image : @horizontalRule; - background-size : 100% 100%; - border : none; - } - p { - font-family : 'Overpass'; - font-size : 0.332cm; - line-height : 0.35cm; - } - hr + p { - margin-top : 0.6cm; - text-align : center; - } - .logo { - position : absolute; - bottom : 2cm; - left : 1.2cm; - z-index : 0; - width : 7.6cm; - height : 1.5cm; - img { - position : relative; - z-index : 0; - width : 100%; - height : 1.5cm; - } - p { - position : relative; - width : 100%; - font-family : 'NodestoCapsWide'; - font-size : 0.4cm; - line-height : 1em; - line-height : 1.28cm; - color : #FFFFFF; - text-align : center; - text-indent : 0; - } - } -} - -// ***************************** -// * PART COVER -// *****************************/ -.page:has(.partCover) { - padding-top : 0; - text-align : center; - columns : 1; - - .partCover { - position : absolute; - top : 0; - left : 0; - width : 100%; - height : 6cm; - background-image : @partCoverHeaderPHB; - background-repeat : no-repeat; - background-size : 100%; - } - - h1 { - position : relative; - margin-top : 0.4cm; - font-family : 'NodestoCapsCondensed'; - font-size : 2.3cm; - text-align : center; - text-transform : uppercase; - } - - h2 { - position : relative; - margin-top : -0.7em; - margin-right : auto; - margin-left : auto; - font-family : 'Overpass'; - font-size : 0.45cm; - line-height : 0.495cm; - } -} From 4448410c3ea263e1ac2cc10d9caacbc571645e42 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 1 Nov 2024 14:02:27 -0500 Subject: [PATCH 054/393] Partial implementation --- .circleci/config.yml | 2 +- .../homebrew/editor/snippetbar/snippetbar.jsx | 4 ++ client/homebrew/pages/editPage/editPage.jsx | 2 + package.json | 4 +- server/homebrew.api.js | 6 ++ shared/helpers.js | 60 +++++++++++++++++++ 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f18f84943..abd8faacc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ orbs: jobs: build: docker: - - image: cimg/node:20.17.0 + - image: cimg/node:20.18.0 - image: mongo:4.4 working_directory: ~/homebrewery diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 50237b914..1f786fd93 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -6,6 +6,7 @@ const _ = require('lodash'); const cx = require('classnames'); import { loadHistory } from '../../utils/versionHistory.js'; +import { brewSnippetsToJSON } from '../../../../shared/helpers.js'; //Import all themes const ThemeSnippets = {}; @@ -114,6 +115,9 @@ const Snippetbar = createClass({ oldSnippets = _.keyBy(compiledSnippets, 'groupName'); } + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.snippetsBundle); + compiledSnippets.push(userSnippetsasJSON); + return compiledSnippets; }, diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 744e187a6..a98b16717 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -61,6 +61,7 @@ const EditPage = createClass({ currentEditorCursorPageNum : 1, currentBrewRendererPageNum : 1, displayLockMessage : this.props.brew.lock || false, + snippetsBundle : {}, themeBundle : {} }; }, @@ -440,6 +441,7 @@ const EditPage = createClass({ reportError={this.errorReported} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} + snippets={this.props.snippets} snippetBundle={this.state.themeBundle.snippets} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} diff --git a/package.json b/package.json index 94d0122ab..3fe3ce5a6 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "description": "Create authentic looking D&D homebrews using only markdown", "version": "3.16.0", "engines": { - "npm": "^10.2.x", - "node": "^20.17.x" + "npm": "^10.8.x", + "node": "^20.18.x" }, "repository": { "type": "git", diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 213b341ca..2abbf9485 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -170,6 +170,12 @@ const api = { `\`\`\`\n\n` + `${text}`; } + if(brew.snippets !== undefined) { + text = `\`\`\`snippets\n` + + `${brew.snippets || ''}\n` + + `\`\`\`\n\n` + + `${text}`; + } const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); text = `\`\`\`metadata\n` + `${yaml.dump(metadata)}\n` + diff --git a/shared/helpers.js b/shared/helpers.js index ac684b06f..e75dcdb28 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -1,6 +1,65 @@ const _ = require('lodash'); const yaml = require('js-yaml'); const request = require('../client/homebrew/utils/request-middleware.js'); +const dedent = require('dedent'); + +// Convert the templates from a brew to a Snippets Structure. +const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ + const textSplit = /^\\page/gm; + const mpAsSnippets = []; + // Snippets from Themes first. + if(themeBundleSnippets) { + for (let themes of themeBundleSnippets) { + const userSnippets = []; + for (let snips of themes.snippets.split(textSplit)) { + const name = snips.split('\n')[0]; + if(name.length != 0) { + userSnippets.push({ + name : name, + icon : '', + gen : snips.split('\n').slice(0), + }); + } + } + if(userSnippets.length > 0) { + mpAsSnippets.push({ + name : themes.name, + icon : '', + gen : '', + subsnippets : userSnippets + }); + } + } + } + // Local Snippets + if(userBrewSnippets) { + const userSnippets = []; + for (let snips of userBrewSnippets.split(textSplit)) { + let name = mp.split('\n')[0]; + if(name.length != 0) { + userSnippets.push({ + name : name, + icon : '', + gen : snips.split('\n').slice(0), + }); + } + } + if(userSnippets.length) { + mpAsSnippets.push({ + name : menuTitle, + icon : '', + subsnippets : userSnippets + }); + } + } + + return { + groupName : 'Brew Snippets', + icon : 'fas fa-th-list', + view : 'text', + snippets : mpAsSnippets + }; +}; const splitTextStyleAndMetadata = (brew)=>{ brew.text = brew.text.replaceAll('\r\n', '\n'); @@ -55,4 +114,5 @@ module.exports = { splitTextStyleAndMetadata, printCurrentBrew, fetchThemeBundle, + brewSnippetsToJSON }; From 7cd82ffc4edaf2ee47b38cb6ca4298957483ed47 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 2 Nov 2024 17:37:43 -0500 Subject: [PATCH 055/393] WOrking snippets insertion from local. --- shared/helpers.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index e75dcdb28..b84cb0332 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -35,12 +35,12 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ if(userBrewSnippets) { const userSnippets = []; for (let snips of userBrewSnippets.split(textSplit)) { - let name = mp.split('\n')[0]; + let name = snips.split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name, + name : name.slice('\snippet '.length), icon : '', - gen : snips.split('\n').slice(0), + gen : snips.slice(name.length + 1), }); } } @@ -70,16 +70,19 @@ const splitTextStyleAndMetadata = (brew)=>{ Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); brew.text = brew.text.slice(index + 5); } - if(brew.text.startsWith('```css')) { - const index = brew.text.indexOf('```\n\n'); - brew.style = brew.text.slice(7, index - 1); - brew.text = brew.text.slice(index + 5); - } if(brew.text.startsWith('```snippets')) { const index = brew.text.indexOf('```\n\n'); brew.snippets = brew.text.slice(11, index - 1); brew.text = brew.text.slice(index + 5); } + if(brew.text.startsWith('```css')) { + const index = brew.text.indexOf('```\n\n'); + brew.style = brew.text.slice(7, index - 1); + brew.text = brew.text.slice(index + 5); + } + // if(!brew?.snippets) { + brew.snippets = `\\snippet Example\nI am an example user snippet\n`; + // } }; const printCurrentBrew = ()=>{ From 4f240bf1100c46fca948b00899d71a2db2bb4205 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 2 Nov 2024 22:30:18 -0500 Subject: [PATCH 056/393] WIP --- client/homebrew/editor/editor.jsx | 2 +- .../homebrew/editor/snippetbar/snippetbar.jsx | 21 ++++++++++++------- server/homebrew.api.js | 4 +--- server/homebrew.api.spec.js | 2 -- shared/helpers.js | 7 +++++-- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 9fef72cbb..27737fcba 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -499,7 +499,7 @@ const Editor = createClass({ historySize={this.historySize()} currentEditorTheme={this.state.editorTheme} updateEditorTheme={this.updateEditorTheme} - snippetBundle={this.props.snippetBundle} + themeBundle={this.props.themeBundle} cursorPos={this.codeEditor.current?.getCursorPosition() || {}} updateBrew={this.props.updateBrew} /> diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 1f786fd93..111b4fd38 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -41,7 +41,6 @@ const Snippetbar = createClass({ unfoldCode : ()=>{}, updateEditorTheme : ()=>{}, cursorPos : {}, - snippetBundle : [], updateBrew : ()=>{} }; }, @@ -102,20 +101,26 @@ const Snippetbar = createClass({ }, compileSnippets : function() { + console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); - for (let snippets of this.props.snippetBundle) { - if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name - snippets = ThemeSnippets[snippets]; + console.log(this.props.themesBundle); - const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName'); - compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer)); + if( this.props.themesBundle) { + for (let snippets of this.props?.themesBundle?.snippets) { + if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name + snippets = ThemeSnippets[snippets]; - oldSnippets = _.keyBy(compiledSnippets, 'groupName'); + const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName'); + compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer)); + + oldSnippets = _.keyBy(compiledSnippets, 'groupName'); + } } - const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.snippetsBundle); + console.log(this.props.themesBundle); + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props?.themesBundle?.snippets); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 2abbf9485..685415c14 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -296,7 +296,7 @@ const api = { splitTextStyleAndMetadata(currentTheme); // If there is anything in the snippets or style members, append them to the appropriate array - if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); + if(currentTheme?.snippets) completeSnippets.push({ name: currentTheme.title, snippets: currentTheme.snippets }); if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`); req.params.id = currentTheme.theme; @@ -304,9 +304,7 @@ const api = { } //=== Static Themes ===// else { - const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; - completeSnippets.push(localSnippets); completeStyles.push(`/* From Theme ${req.params.id} */\n\n${localStyle}`); req.params.id = Themes[req.params.renderer][req.params.id].baseTheme; diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index a1222cb57..3c86e4208 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -627,8 +627,6 @@ brew`); `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` ], snippets : [ - 'V3_Blank', - 'V3_5ePHB' ] }); }); diff --git a/shared/helpers.js b/shared/helpers.js index b84cb0332..d5a4512a6 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -8,9 +8,12 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ const textSplit = /^\\page/gm; const mpAsSnippets = []; // Snippets from Themes first. + //console.log(themeBundleSnippets); if(themeBundleSnippets) { + console.log('Looping!'); for (let themes of themeBundleSnippets) { const userSnippets = []; + console.log(themes); for (let snips of themes.snippets.split(textSplit)) { const name = snips.split('\n')[0]; if(name.length != 0) { @@ -80,9 +83,9 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.style = brew.text.slice(7, index - 1); brew.text = brew.text.slice(index + 5); } - // if(!brew?.snippets) { + if(!brew?.snippets) { brew.snippets = `\\snippet Example\nI am an example user snippet\n`; - // } + } }; const printCurrentBrew = ()=>{ From b9b3d284cf3d89a62b671789047cd7c0ea0defde Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 11:14:31 -0600 Subject: [PATCH 057/393] WOrking snippet editor - menu population regression --- client/homebrew/editor/editor.jsx | 19 +++++++++++- .../homebrew/editor/snippetbar/snippetbar.jsx | 18 +++++++----- .../editor/snippetbar/snippetbar.less | 3 ++ client/homebrew/pages/editPage/editPage.jsx | 17 +++++++++-- server/homebrew.api.js | 2 ++ shared/helpers.js | 29 +++++++++---------- 6 files changed, 61 insertions(+), 27 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 27737fcba..dedfeaebb 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -21,6 +21,7 @@ const DEFAULT_STYLE_TEXT = dedent` color: black; }`; +const DEFAULT_SNIPPET_TEXT = ``; let isJumping = false; const Editor = createClass({ @@ -35,6 +36,7 @@ const Editor = createClass({ onTextChange : ()=>{}, onStyleChange : ()=>{}, onMetaChange : ()=>{}, + onSnipChange : ()=>{}, reportError : ()=>{}, onCursorPageChange : ()=>{}, @@ -51,7 +53,7 @@ const Editor = createClass({ getInitialState : function() { return { editorTheme : this.props.editorTheme, - view : 'text' //'text', 'style', 'meta' + view : 'text' //'text', 'style', 'meta', 'snip' }; }, @@ -61,6 +63,7 @@ const Editor = createClass({ isText : function() {return this.state.view == 'text';}, isStyle : function() {return this.state.view == 'style';}, isMeta : function() {return this.state.view == 'meta';}, + isSnip : function() {return this.state.view == 'snip';}, componentDidMount : function() { @@ -459,6 +462,20 @@ const Editor = createClass({ userThemes={this.props.userThemes}/> ; } + + if(this.isSnip()){ + return <> + + ; + } }, redo : function(){ diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 111b4fd38..bb932c0fe 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -41,6 +41,7 @@ const Snippetbar = createClass({ unfoldCode : ()=>{}, updateEditorTheme : ()=>{}, cursorPos : {}, + themeBundle : [], updateBrew : ()=>{} }; }, @@ -64,7 +65,7 @@ const Snippetbar = createClass({ }, componentDidUpdate : async function(prevProps, prevState) { - if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.snippetBundle != this.props.snippetBundle) { + if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.themeBundle != this.props.themeBundle) { this.setState({ snippets : this.compileSnippets() }); @@ -101,15 +102,12 @@ const Snippetbar = createClass({ }, compileSnippets : function() { - console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); - console.log(this.props.themesBundle); - - if( this.props.themesBundle) { - for (let snippets of this.props?.themesBundle?.snippets) { + if(this.props.themeBundle.snippets) { + for (let snippets of this.props.themeBundle.snippets) { if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name snippets = ThemeSnippets[snippets]; @@ -119,8 +117,8 @@ const Snippetbar = createClass({ oldSnippets = _.keyBy(compiledSnippets, 'groupName'); } } - console.log(this.props.themesBundle); - const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props?.themesBundle?.snippets); + + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.themeBundle.snippets); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; @@ -266,6 +264,10 @@ const Snippetbar = createClass({ onClick={()=>this.props.onViewChange('meta')}> +
this.props.onViewChange('snip')}> + +
; diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 319cd0cad..a7202c428 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -48,6 +48,9 @@ &.meta { .tooltipLeft('Properties'); } + &.snip { + .tooltipLeft('Snippets'); + } &.undo { .tooltipLeft('Undo'); font-size : 0.75em; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index a98b16717..df840bc48 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -61,7 +61,6 @@ const EditPage = createClass({ currentEditorCursorPageNum : 1, currentBrewRendererPageNum : 1, displayLockMessage : this.props.brew.lock || false, - snippetsBundle : {}, themeBundle : {} }; }, @@ -143,6 +142,19 @@ const EditPage = createClass({ }), ()=>{if(this.state.autoSave) this.trySave();}); }, + handleSnipChange : function(snippet){ + console.log('Snip Change!'); + //If there are errors, run the validator on every change to give quick feedback + let htmlErrors = this.state.htmlErrors; + if(htmlErrors.length) htmlErrors = Markdown.validate(snippet); + + this.setState((prevState)=>({ + brew : { ...prevState.brew, snippets: snippet }, + isPending : true, + htmlErrors : htmlErrors, + }), ()=>{if(this.state.autoSave) this.trySave();}); + }, + handleStyleChange : function(style){ this.setState((prevState)=>({ brew : { ...prevState.brew, style: style }, @@ -438,11 +450,12 @@ const EditPage = createClass({ onTextChange={this.handleTextChange} onStyleChange={this.handleStyleChange} onMetaChange={this.handleMetaChange} + onSnipChange={this.handleSnipChange} reportError={this.errorReported} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} snippets={this.props.snippets} - snippetBundle={this.state.themeBundle.snippets} + themeBundle={this.state.themeBundle} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 685415c14..9c4f55ef7 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -304,7 +304,9 @@ const api = { } //=== Static Themes ===// else { + const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; + completeSnippets.push(localSnippets); completeStyles.push(`/* From Theme ${req.params.id} */\n\n${localStyle}`); req.params.id = Themes[req.params.renderer][req.params.id].baseTheme; diff --git a/shared/helpers.js b/shared/helpers.js index d5a4512a6..27c372dd7 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -8,29 +8,26 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ const textSplit = /^\\page/gm; const mpAsSnippets = []; // Snippets from Themes first. - //console.log(themeBundleSnippets); if(themeBundleSnippets) { - console.log('Looping!'); for (let themes of themeBundleSnippets) { - const userSnippets = []; - console.log(themes); - for (let snips of themes.snippets.split(textSplit)) { - const name = snips.split('\n')[0]; + if(typeof themes !== 'string') { + const userSnippets = []; + const name = themes.snippets.split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name, + name : name.slice('\snippets '.length), icon : '', - gen : snips.split('\n').slice(0), + gen : themes.snippets.slice(name.length + 1), + }); + } + if(userSnippets.length > 0) { + mpAsSnippets.push({ + name : themes.name, + icon : '', + gen : '', + subsnippets : userSnippets }); } - } - if(userSnippets.length > 0) { - mpAsSnippets.push({ - name : themes.name, - icon : '', - gen : '', - subsnippets : userSnippets - }); } } } From 7f7f3557b36e29575e3703137445149d015f49fd Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 12:30:14 -0600 Subject: [PATCH 058/393] Mostly working. Needs tweakages. Presentable --- client/homebrew/editor/editor.jsx | 2 +- .../homebrew/editor/snippetbar/snippetbar.jsx | 5 +++- client/homebrew/pages/editPage/editPage.jsx | 1 - shared/helpers.js | 24 ++++++++++--------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index dedfeaebb..6c74bfdf7 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -158,7 +158,7 @@ const Editor = createClass({ highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; - if(this.state.view === 'text') { + if(this.state.view === 'text') { const codeMirror = this.codeEditor.current.codeMirror; codeMirror.operation(()=>{ // Batch CodeMirror styling diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index bb932c0fe..066711c41 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -65,7 +65,10 @@ const Snippetbar = createClass({ }, componentDidUpdate : async function(prevProps, prevState) { - if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.themeBundle != this.props.themeBundle) { + if(prevProps.renderer != this.props.renderer || + prevProps.theme != this.props.theme || + prevProps.themeBundle != this.props.themeBundle || + prevProps.brew.snippets != this.props.brew.snippets) { this.setState({ snippets : this.compileSnippets() }); diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index df840bc48..be5af729b 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -143,7 +143,6 @@ const EditPage = createClass({ }, handleSnipChange : function(snippet){ - console.log('Snip Change!'); //If there are errors, run the validator on every change to give quick feedback let htmlErrors = this.state.htmlErrors; if(htmlErrors.length) htmlErrors = Markdown.validate(snippet); diff --git a/shared/helpers.js b/shared/helpers.js index 27c372dd7..750f533cd 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -5,20 +5,22 @@ const dedent = require('dedent'); // Convert the templates from a brew to a Snippets Structure. const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ - const textSplit = /^\\page/gm; + const textSplit = /^\\snippet /gm; const mpAsSnippets = []; // Snippets from Themes first. if(themeBundleSnippets) { for (let themes of themeBundleSnippets) { if(typeof themes !== 'string') { const userSnippets = []; - const name = themes.snippets.split('\n')[0]; - if(name.length != 0) { - userSnippets.push({ - name : name.slice('\snippets '.length), - icon : '', - gen : themes.snippets.slice(name.length + 1), - }); + for (let snips of themes.snippets.trim().split(textSplit)) { + const name = snips.trim().split('\n')[0]; + if(name.length != 0) { + userSnippets.push({ + name : name.slice('\snippets'.length), + icon : '', + gen : snips.slice(name.length + 1), + }); + } } if(userSnippets.length > 0) { mpAsSnippets.push({ @@ -34,11 +36,11 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ // Local Snippets if(userBrewSnippets) { const userSnippets = []; - for (let snips of userBrewSnippets.split(textSplit)) { + for (let snips of userBrewSnippets.trim().split(textSplit)) { let name = snips.split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name.slice('\snippet '.length), + name : name, icon : '', gen : snips.slice(name.length + 1), }); @@ -72,7 +74,7 @@ const splitTextStyleAndMetadata = (brew)=>{ } if(brew.text.startsWith('```snippets')) { const index = brew.text.indexOf('```\n\n'); - brew.snippets = brew.text.slice(11, index - 1); + brew.snippets = brew.text.slice(12, index - 1); brew.text = brew.text.slice(index + 5); } if(brew.text.startsWith('```css')) { From f4e951623348728d243f5097e532b459a8cee638 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 12:41:04 -0600 Subject: [PATCH 059/393] Remove testing helper --- shared/helpers.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index 750f533cd..8b94704bd 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -82,9 +82,6 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.style = brew.text.slice(7, index - 1); brew.text = brew.text.slice(index + 5); } - if(!brew?.snippets) { - brew.snippets = `\\snippet Example\nI am an example user snippet\n`; - } }; const printCurrentBrew = ()=>{ From f43a155e6efad0e267ebfb0196d94546923062fc Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 12:52:54 -0600 Subject: [PATCH 060/393] Fix Test --- server/homebrew.api.spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 3c86e4208..a1222cb57 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -627,6 +627,8 @@ brew`); `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` ], snippets : [ + 'V3_Blank', + 'V3_5ePHB' ] }); }); From e0400c0425be5d00c3541fca64bda5f2ed43bf8f Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 12 Nov 2024 18:41:31 -0600 Subject: [PATCH 061/393] Snippets should go after existing tab sections --- shared/helpers.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index 8b94704bd..e603abaf0 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -72,16 +72,16 @@ const splitTextStyleAndMetadata = (brew)=>{ Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); brew.text = brew.text.slice(index + 5); } - if(brew.text.startsWith('```snippets')) { - const index = brew.text.indexOf('```\n\n'); - brew.snippets = brew.text.slice(12, index - 1); - brew.text = brew.text.slice(index + 5); - } if(brew.text.startsWith('```css')) { const index = brew.text.indexOf('```\n\n'); brew.style = brew.text.slice(7, index - 1); brew.text = brew.text.slice(index + 5); } + if(brew.text.startsWith('```snippets')) { + const index = brew.text.indexOf('```\n\n'); + brew.snippets = brew.text.slice(12, index - 1); + brew.text = brew.text.slice(index + 5); + } }; const printCurrentBrew = ()=>{ From f7561b78247ea98c85a5f65f0452bf578ef0890d Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 13 Nov 2024 20:53:04 -0600 Subject: [PATCH 062/393] Insert a CR --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index df7f41503..5206f4cbf 100644 --- a/README.md +++ b/README.md @@ -144,3 +144,4 @@ your contribution to the project, please join our [gitter chat][gitter-url]. [github-mark-duplicate-url]: https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/about-duplicate-issues-and-pull-requests [github-pr-docs-url]: https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request [gitter-url]: https://gitter.im/naturalcrit/Lobby + From d541a70da54ee4f59f72255518cfe3380e6690ab Mon Sep 17 00:00:00 2001 From: David Bolack Date: Thu, 14 Nov 2024 06:54:36 -0600 Subject: [PATCH 063/393] Remove unneeded dedent --- shared/helpers.js | 1 - 1 file changed, 1 deletion(-) diff --git a/shared/helpers.js b/shared/helpers.js index e603abaf0..f5411f501 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -1,7 +1,6 @@ const _ = require('lodash'); const yaml = require('js-yaml'); const request = require('../client/homebrew/utils/request-middleware.js'); -const dedent = require('dedent'); // Convert the templates from a brew to a Snippets Structure. const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ From c5935ec262c3c59fd5db441df868655eb0232232 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 23 Nov 2024 01:57:07 -0600 Subject: [PATCH 064/393] Add Snippets to /new --- client/homebrew/pages/homePage/homePage.jsx | 3 ++- client/homebrew/pages/newPage/newPage.jsx | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 00d0c801d..0a598556a 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -108,7 +108,8 @@ const HomePage = createClass({ onTextChange={this.handleTextChange} renderer={this.state.brew.renderer} showEditButtons={false} - snippetBundle={this.state.themeBundle.snippets} + snippets={this.props.snippets} + themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} currentEditorViewPageNum={this.state.currentEditorViewPageNum} diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index ee2c67d5f..ca31e03a5 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -141,6 +141,18 @@ const NewPage = createClass({ localStorage.setItem(STYLEKEY, style); }, + handleSnipChange : function(snippet){ + //If there are errors, run the validator on every change to give quick feedback + let htmlErrors = this.state.htmlErrors; + if(htmlErrors.length) htmlErrors = Markdown.validate(snippet); + + this.setState((prevState)=>({ + brew : { ...prevState.brew, snippets: snippet }, + isPending : true, + htmlErrors : htmlErrors, + }), ()=>{if(this.state.autoSave) this.trySave();}); + }, + handleMetaChange : function(metadata, field=undefined){ if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed fetchThemeBundle(this, metadata.renderer, metadata.theme); @@ -231,9 +243,11 @@ const NewPage = createClass({ onTextChange={this.handleTextChange} onStyleChange={this.handleStyleChange} onMetaChange={this.handleMetaChange} + onSnipChange={this.handleSnipChange} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} - snippetBundle={this.state.themeBundle.snippets} + snippets={this.props.snippets} + themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} currentEditorViewPageNum={this.state.currentEditorViewPageNum} From b6e445c445355d60bc272fd20628fd0d7ab14cc3 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 24 Nov 2024 18:13:32 -0600 Subject: [PATCH 065/393] Convert storage of snippets in Brew to yaml by request. --- server/homebrew.api.js | 16 ++++++----- shared/helpers.js | 64 ++++++++++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 42d4efca3..b0532e392 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -8,9 +8,11 @@ import Markdown from '../shared/naturalcrit/markdown.js'; import yaml from 'js-yaml'; import asyncHandler from 'express-async-handler'; import { nanoid } from 'nanoid'; -import { splitTextStyleAndMetadata } from '../shared/helpers.js'; +import { splitTextStyleAndMetadata, + brewSnippetsToJSON } from '../shared/helpers.js'; import checkClientVersion from './middleware/check-client-version.js'; + const router = express.Router(); import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js'; @@ -176,15 +178,15 @@ const api = { mergeBrewText : (brew)=>{ let text = brew.text; - if(brew.style !== undefined) { - text = `\`\`\`css\n` + - `${brew.style || ''}\n` + + if(brew.snippets !== undefined) { + text = `\`\`\`snippets\n` + + `${yaml.dump(brewSnippetsToJSON('brew_snippets', brew.snippets, null, false))}` + `\`\`\`\n\n` + `${text}`; } - if(brew.snippets !== undefined) { - text = `\`\`\`snippets\n` + - `${brew.snippets || ''}\n` + + if(brew.style !== undefined) { + text = `\`\`\`css\n` + + `${brew.style || ''}\n` + `\`\`\`\n\n` + `${text}`; } diff --git a/shared/helpers.js b/shared/helpers.js index be3c3331d..b6cbe2df8 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -3,7 +3,7 @@ import yaml from 'js-yaml'; import request from '../client/homebrew/utils/request-middleware.js'; // Convert the templates from a brew to a Snippets Structure. -const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ +const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=null, full=true)=>{ const textSplit = /^\\snippet /gm; const mpAsSnippets = []; // Snippets from Themes first. @@ -17,7 +17,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ userSnippets.push({ name : name.slice('\snippets'.length), icon : '', - gen : snips.slice(name.length + 1), + gen : snips.slice(name.length + 1).trim(), }); } } @@ -37,49 +37,71 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ const userSnippets = []; for (let snips of userBrewSnippets.trim().split(textSplit)) { let name = snips.split('\n')[0]; + let justSnippet = snips.slice(name.length + 1); + if(justSnippet.slice(-1) === '\n') { + justSnippet = justSnippet.slice(0, -1); + } if(name.length != 0) { - userSnippets.push({ + const subSnip = { name : name, - icon : '', - gen : snips.slice(name.length + 1), - }); + gen : justSnippet, + }; + // if(full) subSnip.icon = ''; + userSnippets.push(subSnip); } } if(userSnippets.length) { mpAsSnippets.push({ name : menuTitle, - icon : '', + // icon : '', subsnippets : userSnippets }); } } - return { - groupName : 'Brew Snippets', - icon : 'fas fa-th-list', - view : 'text', - snippets : mpAsSnippets + const returnObj = { + snippets : mpAsSnippets }; + + if(full) { + returnObj.groupName = 'Brew Snippets'; + returnObj.icon = 'fas fa-th-list'; + returnObj.view = 'text'; + } + + return returnObj; +}; + +const yamlSnippetsToText = (yamlObj)=>{ + if(typeof yamlObj == 'string') return yamlObj; + + let snippetsText = ''; + for (let snippet of yamlObj.snippets) { + for (let subSnippet of snippet.subsnippets) { + snippetsText = `${snippetsText}\\snippet ${subSnippet.name}\n${subSnippet.gen || ''}\n`; + } + } + return snippetsText; }; const splitTextStyleAndMetadata = (brew)=>{ brew.text = brew.text.replaceAll('\r\n', '\n'); if(brew.text.startsWith('```metadata')) { - const index = brew.text.indexOf('```\n\n'); - const metadataSection = brew.text.slice(12, index - 1); + const index = brew.text.indexOf('\n```\n\n'); + const metadataSection = brew.text.slice(11, index - 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); - brew.text = brew.text.slice(index + 5); + brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { - const index = brew.text.indexOf('```\n\n'); - brew.style = brew.text.slice(7, index - 1); - brew.text = brew.text.slice(index + 5); + const index = brew.text.indexOf('\n```\n\n'); + brew.style = brew.text.slice(6, index - 1); + brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```snippets')) { - const index = brew.text.indexOf('```\n\n'); - brew.snippets = brew.text.slice(12, index - 1); - brew.text = brew.text.slice(index + 5); + const index = brew.text.indexOf('\n```\n\n'); + brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index - 1))).slice(0, -1); + brew.text = brew.text.slice(index + 6); } }; From 008b31e530166abbe7d9646af19b7a57747ef5cd Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 24 Nov 2024 18:58:50 -0600 Subject: [PATCH 066/393] Correct failing test. --- server/homebrew.api.spec.js | 2 +- shared/helpers.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 84ffc3052..2da940e40 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -908,7 +908,7 @@ brew`); }); describe('Get CSS', ()=>{ it('should return brew style content as CSS text', async ()=>{ - const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n````\n\n' }; + const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n```\n\n' }; const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); diff --git a/shared/helpers.js b/shared/helpers.js index b6cbe2df8..9b0b43084 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -88,19 +88,19 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.text = brew.text.replaceAll('\r\n', '\n'); if(brew.text.startsWith('```metadata')) { const index = brew.text.indexOf('\n```\n\n'); - const metadataSection = brew.text.slice(11, index - 1); + const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { const index = brew.text.indexOf('\n```\n\n'); - brew.style = brew.text.slice(6, index - 1); + brew.style = brew.text.slice(7, index + 1); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```snippets')) { const index = brew.text.indexOf('\n```\n\n'); - brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index - 1))).slice(0, -1); + brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index + 1))).slice(0, -1); brew.text = brew.text.slice(index + 6); } }; From e763ae16313ff03713ea1f42f2c30af004d26929 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 24 Nov 2024 21:57:59 -0600 Subject: [PATCH 067/393] t shouldn't have been saved... --- package-lock.json | 39 ++++++++++++++++++++++++++++++++------- package.json | 2 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index b20286889..589e7b661 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "^1.0.10", + "marked-extended-tables": "file:../marked-extended-tables", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", @@ -71,6 +71,35 @@ "npm": "^10.8.x" } }, + "../marked-extended-tables": { + "version": "1.0.10", + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.24.6", + "@babel/preset-env": "^7.25.4", + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/commit-analyzer": "^12.0.0", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^10.1.7", + "@semantic-release/npm": "^12.0.1", + "@semantic-release/release-notes-generator": "^13.0.0", + "babel-jest": "^29.5.0", + "eslint": "^8.57.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "jest-cli": "^29.7.0", + "marked": "^14.1.0", + "rollup": "^4.18.0", + "semantic-release": "^24.1.0" + }, + "peerDependencies": { + "marked": ">=3 <15" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -10543,12 +10572,8 @@ } }, "node_modules/marked-extended-tables": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.10.tgz", - "integrity": "sha512-zvRS0GPTkxq8UWawSDecd1Rxd2KD8crrmq2QALGDdrgkcgRNQzHlbnlujBGuXxdgDJg7f6UTv+JpcfejBpKdSg==", - "peerDependencies": { - "marked": ">=3 <15" - } + "resolved": "../marked-extended-tables", + "link": true }, "node_modules/marked-gfm-heading-id": { "version": "3.2.0", diff --git a/package.json b/package.json index 8755d0699..87390b48d 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "^1.0.10", + "marked-extended-tables": "file:../marked-extended-tables", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", From 74b4cb2afde0f97b02aa60781378670651bfe212 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 25 Nov 2024 13:59:24 -0600 Subject: [PATCH 068/393] Revert local error in package.json --- package-lock.json | 40 ++++++++-------------------------------- package.json | 2 +- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 589e7b661..e5f637e46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "file:../marked-extended-tables", + "marked-extended-tables": "^1.0.10", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", @@ -71,35 +71,6 @@ "npm": "^10.8.x" } }, - "../marked-extended-tables": { - "version": "1.0.10", - "license": "MIT", - "devDependencies": { - "@babel/core": "^7.24.6", - "@babel/preset-env": "^7.25.4", - "@rollup/plugin-commonjs": "^26.0.1", - "@rollup/plugin-node-resolve": "^15.2.3", - "@semantic-release/changelog": "^6.0.3", - "@semantic-release/commit-analyzer": "^12.0.0", - "@semantic-release/git": "^10.0.1", - "@semantic-release/github": "^10.1.7", - "@semantic-release/npm": "^12.0.1", - "@semantic-release/release-notes-generator": "^13.0.0", - "babel-jest": "^29.5.0", - "eslint": "^8.57.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", - "jest-cli": "^29.7.0", - "marked": "^14.1.0", - "rollup": "^4.18.0", - "semantic-release": "^24.1.0" - }, - "peerDependencies": { - "marked": ">=3 <15" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -10572,8 +10543,13 @@ } }, "node_modules/marked-extended-tables": { - "resolved": "../marked-extended-tables", - "link": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.10.tgz", + "integrity": "sha512-zvRS0GPTkxq8UWawSDecd1Rxd2KD8crrmq2QALGDdrgkcgRNQzHlbnlujBGuXxdgDJg7f6UTv+JpcfejBpKdSg==", + "license": "MIT", + "peerDependencies": { + "marked": ">=3 <15" + } }, "node_modules/marked-gfm-heading-id": { "version": "3.2.0", diff --git a/package.json b/package.json index 87390b48d..8755d0699 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "file:../marked-extended-tables", + "marked-extended-tables": "^1.0.10", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", From 73c68fd11c7517e465bf5bcf690ee24f190bb6f9 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 27 Nov 2024 21:35:29 -0600 Subject: [PATCH 069/393] Functional first pass. Needs: - [ ] opinions on UI placement - [ ] opinions on best choice for displaying a write-in based User Brew ( flip to writin box? Add to drop-down list? ) --- .../editor/metadataEditor/metadataEditor.jsx | 35 ++++++++++++++++--- server/homebrew.api.js | 4 +-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index bfc3b8b61..0405b942b 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -47,7 +47,8 @@ const MetadataEditor = createClass({ getInitialState : function(){ return { - showThumbnail : true + showThumbnail : true, + showThemeWritein : false }; }, @@ -57,6 +58,12 @@ const MetadataEditor = createClass({ }); }, + toggleThemeWritein : function(){ + this.setState({ + showThemeWritein : !this.state.showThemeWritein + }); + }, + renderThumbnail : function(){ if(!this.state.showThumbnail) return; return ; @@ -115,6 +122,12 @@ const MetadataEditor = createClass({ this.props.onChange(this.props.metadata, 'theme'); }, + handleThemeWritein : function(e) { + this.props.metadata.renderer = 'V3'; + this.props.metadata.theme = e.target.value; + this.props.onChange(this.props.metadata, 'theme'); + }, + handleLanguage : function(languageCode){ this.props.metadata.lang = languageCode; this.props.onChange(this.props.metadata); @@ -213,6 +226,7 @@ const MetadataEditor = createClass({ }); }; + const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] ?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` }; @@ -234,10 +248,23 @@ const MetadataEditor = createClass({ return
- {dropdown} + {!this.state.showThemeWritein?dropdown:''} + + {this.renderThemeWritein()}
; }, + renderThemeWritein : function(){ + if(!this.state.showThemeWritein) return; + return this.handleThemeWritein(e)} />; + }, + renderLanguageDropdown : function(){ const langCodes = ['en', 'de', 'de-ch', 'fr', 'ja', 'es', 'it', 'sv', 'ru', 'zh-Hans', 'zh-Hant']; const listLanguages = ()=>{ @@ -345,7 +372,7 @@ const MetadataEditor = createClass({ placeholder='add tag' unique={true} values={this.props.metadata.tags} onChange={(e)=>this.handleFieldChange('tags', e)} - /> + />
@@ -370,7 +397,7 @@ const MetadataEditor = createClass({ values={this.props.metadata.invitedAuthors} notes={['Invited author usernames are case sensitive.', 'After adding an invited author, send them the edit link. There, they can choose to accept or decline the invitation.']} onChange={(e)=>this.handleFieldChange('invitedAuthors', e)} - /> + />

Privacy

diff --git a/server/homebrew.api.js b/server/homebrew.api.js index b8d4024ad..f997de1c4 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ import _ from 'lodash'; -import {model as HomebrewModel} from './homebrew.model.js'; +import { model as HomebrewModel } from './homebrew.model.js'; import express from 'express'; import zlib from 'zlib'; import GoogleActions from './googleActions.js'; @@ -302,7 +302,7 @@ const api = { splitTextStyleAndMetadata(currentTheme); // If there is anything in the snippets or style members, append them to the appropriate array - if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); + // if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`); req.params.id = currentTheme.theme; From 43222b7651040e981ee09ffc3207b8e3027588ab Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 4 Dec 2024 21:41:04 -0600 Subject: [PATCH 070/393] Fix test --- server/homebrew.api.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index de0d35e40..0af9863aa 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -1005,7 +1005,7 @@ brew`); expect(testBrew.theme).toEqual('5ePHB'); expect(testBrew.lang).toEqual('en'); // Style - expect(testBrew.style).toEqual('style\nstyle\nstyle'); + expect(testBrew.style).toEqual('style\nstyle\nstyle\n'); // Text expect(testBrew.text).toEqual('text\n'); }); From 6e5f071f2273fec3450464c83d349c3e52f758af Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 10 Dec 2024 21:21:41 -0600 Subject: [PATCH 071/393] Move Properties icon to the end of the snippets bar. --- client/homebrew/editor/snippetbar/snippetbar.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index d252c7120..00a826bc1 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -262,14 +262,14 @@ const Snippetbar = createClass({ onClick={()=>this.props.onViewChange('style')}>
-
this.props.onViewChange('meta')}> - -
this.props.onViewChange('snip')}>
+
this.props.onViewChange('meta')}> + +
From dae297e0f54aa23333dbb3a9c1e19d3feabae223 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 10 Dec 2024 21:52:38 -0600 Subject: [PATCH 072/393] Partially implement disabled BrewSnippets --- client/homebrew/editor/snippetbar/snippetbar.jsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 00a826bc1..1809d8f7b 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -217,8 +217,6 @@ const Snippetbar = createClass({ renderEditorButtons : function(){ if(!this.props.showEditButtons) return; - - return (
{this.props.view !== 'meta' && <>
@@ -324,10 +322,11 @@ const SnippetGroup = createClass({ }, render : function(){ + const groupName = `groupName ${this.props.snippets.length === 0 ? 'disabled' : ''}`; return
- {this.props.groupName} + {this.props.groupName}
{this.renderSnippets(this.props.snippets)} From 86856605b94d50eef6aced21447d00d8ecf583aa Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 10 Dec 2024 23:08:51 -0600 Subject: [PATCH 073/393] Add editor highlighting --- client/homebrew/editor/editor.jsx | 22 +++++++++++++++++++--- client/homebrew/editor/editor.less | 8 ++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 95581e5d8..46fcf46c7 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -158,7 +158,7 @@ const Editor = createClass({ highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; - if(this.state.view === 'text') { + if((this.state.view === 'text') ||(this.state.view === 'snip')) { const codeMirror = this.codeEditor.current.codeMirror; codeMirror.operation(()=>{ // Batch CodeMirror styling @@ -178,8 +178,10 @@ const Editor = createClass({ for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear(); let editorPageCount = 2; // start page count from page 2 + let userSnippetCount = 1; // start snippet count from page 2 - _.forEach(this.props.brew.text.split('\n'), (line, lineNumber)=>{ + const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; + _.forEach(whichSource.split('\n'), (line, lineNumber)=>{ //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); @@ -193,7 +195,7 @@ const Editor = createClass({ // Styling for \page breaks if((this.props.renderer == 'legacy' && line.includes('\\page')) || - (this.props.renderer == 'V3' && line.match(/^\\page$/))) { + (this.props.renderer == 'V3' && line.match(/^\\page$/) && this.state.view === 'text')) { // add back the original class 'background' but also add the new class '.pageline' codeMirror.addLineClass(lineNumber, 'background', 'pageLine'); @@ -206,12 +208,26 @@ const Editor = createClass({ editorPageCount += 1; }; + // New Codemirror styling for V3 renderer if(this.props.renderer == 'V3') { if(line.match(/^\\column$/)){ codeMirror.addLineClass(lineNumber, 'text', 'columnSplit'); } + // Styling for \snippet breaks + if(this.state.view === 'snip' && line.match(/^\\snippet\ .*$/)) { + + // add back the original class 'background' but also add the new class '.snippetLine' + codeMirror.addLineClass(lineNumber, 'background', 'snippetLine'); + const userSnippetCountElement = Object.assign(document.createElement('span'), { + className : 'editor-snippet-count', + textContent : userSnippetCount + }); + codeMirror.setBookmark({ line: lineNumber, ch: line.length }, userSnippetCountElement); + + userSnippetCount += 1; + }; // definition lists if(line.includes('::')){ if(/^:*$/.test(line) == true){ return; }; diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index b2e96683e..a73b596d7 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -10,10 +10,18 @@ background : #33333328; border-top : #333399 solid 1px; } + .snippetLine { + background : #33333328; + border-top : #333399 solid 1px; + } .editor-page-count { float : right; color : grey; } + .editor-snippet-count { + float : right; + color : grey; + } .columnSplit { font-style : italic; color : grey; From ed099aa061bef4ad783d64a459232beed0c12602 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 20 Dec 2024 21:47:05 -0600 Subject: [PATCH 074/393] Disable the BrewSnippets menu if empty. --- client/homebrew/editor/snippetbar/snippetbar.jsx | 6 +++--- client/homebrew/editor/snippetbar/snippetbar.less | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 1809d8f7b..b1fd02fd2 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -322,11 +322,11 @@ const SnippetGroup = createClass({ }, render : function(){ - const groupName = `groupName ${this.props.snippets.length === 0 ? 'disabled' : ''}`; - return
+ const snippetGroup = `snippetGroup snippetBarButton ${this.props.snippets.length === 0 ? 'disabledSnippets' : ''}`; + return
- {this.props.groupName} + {this.props.groupName}
{this.renderSnippets(this.props.snippets)} diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 33242174b..3478dfde0 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -231,6 +231,13 @@ } } } + .disabledSnippets { + color: grey; + cursor: not-allowed; + + &:hover { background-color: #DDDDDD;} + } + } @container editor (width < 553px) { .snippetBar { From 7c357a2aa130a072cad58779c377d0888e61992c Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 29 Dec 2024 23:23:48 -0600 Subject: [PATCH 075/393] Attempt to save state but seems to break brew. --- .../editor/metadataEditor/metadataEditor.jsx | 13 ++++++++++--- .../editor/metadataEditor/metadataEditor.less | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0405b942b..0bd91ae35 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -40,6 +40,7 @@ const MetadataEditor = createClass({ theme : '5ePHB', lang : 'en' }, + onChange : ()=>{}, reportError : ()=>{} }; @@ -47,8 +48,10 @@ const MetadataEditor = createClass({ getInitialState : function(){ return { - showThumbnail : true, - showThemeWritein : false + showThumbnail : true, + showThemeWritein : false, + lastThemePulldown : '', + lastThemeWriteIn : '' }; }, @@ -60,8 +63,12 @@ const MetadataEditor = createClass({ toggleThemeWritein : function(){ this.setState({ - showThemeWritein : !this.state.showThemeWritein + showThemeWritein : !this.state.showThemeWritein, + // lastThemePulldown : !this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, + // lastThemeWriteIn : !this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme }); + // if(this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; + // else this.props.metadata.theme = this.state.lastThemePulldown; }, renderThumbnail : function(){ diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 2cff01cfe..13397c89f 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -71,7 +71,7 @@ border : 1px solid gray; &:focus { outline : 1px solid #444444; } } - &.thumbnail { + &.thumbnail, &.themes{ height : 1.4em; label { line-height : 2.0em; } .value { From fe2d02a24c570c829eca48a7481cf7f99e245cbf Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 30 Dec 2024 12:28:47 -0600 Subject: [PATCH 076/393] Work in progress. Still issues with saving the state of the theme pulldowns and collecting the written in theme. --- .../editor/metadataEditor/metadataEditor.jsx | 27 +++++++++++++------ .../editor/metadataEditor/metadataEditor.less | 11 ++++++++ client/homebrew/pages/editPage/editPage.jsx | 5 ++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0bd91ae35..08b9c7165 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -62,13 +62,17 @@ const MetadataEditor = createClass({ }, toggleThemeWritein : function(){ + console.log('toggleThemeWritein'); this.setState({ showThemeWritein : !this.state.showThemeWritein, - // lastThemePulldown : !this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, - // lastThemeWriteIn : !this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme + lastThemePulldown : this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, + lastThemeWriteIn : this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme }); - // if(this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; - // else this.props.metadata.theme = this.state.lastThemePulldown; + console.log(this.state); + console.log(this.props.metadata); + if(!this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; + else this.props.metadata.theme = this.state.lastThemePulldown; + this.props.onChange(this.props.metadata, 'theme'); }, renderThumbnail : function(){ @@ -130,9 +134,13 @@ const MetadataEditor = createClass({ }, handleThemeWritein : function(e) { + console.log('Enter!'); this.props.metadata.renderer = 'V3'; this.props.metadata.theme = e.target.value; + console.log(e.target.value); + this.props.onChange(this.props.metadata, 'renderer'); this.props.onChange(this.props.metadata, 'theme'); + console.log(this.props.metadata); }, handleLanguage : function(languageCode){ @@ -214,6 +222,7 @@ const MetadataEditor = createClass({ if(!global.enable_themes) return; const mergedThemes = _.merge(Themes, this.props.userThemes); + console.log(mergedThemes); const listThemes = (renderer)=>{ return _.map(_.values(mergedThemes[renderer]), (theme)=>{ @@ -230,11 +239,11 @@ const MetadataEditor = createClass({
; - }); + }).filter(Boolean); }; - const currentRenderer = this.props.metadata.renderer; + console.log(this.props.metadata.theme); const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] ?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` }; let dropdown; @@ -250,13 +259,14 @@ const MetadataEditor = createClass({
{currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name}
{listThemes(currentRenderer)} + {console.log(listThemes(currentRenderer))} ; } return
{!this.state.showThemeWritein?dropdown:''} - {this.renderThemeWritein()} @@ -268,7 +278,8 @@ const MetadataEditor = createClass({ return this.handleThemeWritein(e)} />; }, diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 13397c89f..9f13fbc49 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -88,6 +88,17 @@ } } + &.themes{ + .value { + overflow : visible; + text-overflow : auto; + } + button { + padding-left: 5px; + padding-right: 5px; + } + } + &.description { flex : 1; textarea.value { diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index cf2b559c3..585d5205d 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -151,9 +151,10 @@ const EditPage = createClass({ }, handleMetaChange : function(metadata, field=undefined){ - if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed + if(field == 'theme' || field == 'renderer') {// Fetch theme bundle only if theme or renderer was changed + console.log(metadata); fetchThemeBundle(this, metadata.renderer, metadata.theme); - + } this.setState((prevState)=>({ brew : { ...prevState.brew, From b9f7e820c7d9f4320386941c54e8b3de1ebc384a Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 7 Jan 2025 20:36:38 -0600 Subject: [PATCH 077/393] Functionally? working. --- .../editor/metadataEditor/metadataEditor.jsx | 40 +++++++++---------- client/homebrew/pages/editPage/editPage.jsx | 1 - 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 08b9c7165..6d8755aba 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -16,6 +16,8 @@ const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder']; const homebreweryThumbnail = require('../../thumbnail.png'); +let mergedThemes; + const callIfExists = (val, fn, ...args)=>{ if(val[fn]) { val[fn](...args); @@ -47,11 +49,12 @@ const MetadataEditor = createClass({ }, getInitialState : function(){ + mergedThemes = _.merge(Themes, this.props.userThemes); return { showThumbnail : true, - showThemeWritein : false, - lastThemePulldown : '', - lastThemeWriteIn : '' + showThemeWritein : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? false : true, + lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] : '', + lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] }; }, @@ -62,17 +65,12 @@ const MetadataEditor = createClass({ }, toggleThemeWritein : function(){ - console.log('toggleThemeWritein'); - this.setState({ - showThemeWritein : !this.state.showThemeWritein, - lastThemePulldown : this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, - lastThemeWriteIn : this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme - }); - console.log(this.state); - console.log(this.props.metadata); if(!this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; else this.props.metadata.theme = this.state.lastThemePulldown; this.props.onChange(this.props.metadata, 'theme'); + this.setState({ + showThemeWritein : !this.state.showThemeWritein + }); }, renderThumbnail : function(){ @@ -130,17 +128,22 @@ const MetadataEditor = createClass({ handleTheme : function(theme){ this.props.metadata.renderer = theme.renderer; this.props.metadata.theme = theme.path; + this.setState({ + lastThemePulldown : theme.path + }); + this.props.onChange(this.props.metadata, 'theme'); }, handleThemeWritein : function(e) { - console.log('Enter!'); this.props.metadata.renderer = 'V3'; this.props.metadata.theme = e.target.value; - console.log(e.target.value); + this.setState({ + lastThemeWriteIn : e.target.value + }); + this.props.onChange(this.props.metadata, 'renderer'); this.props.onChange(this.props.metadata, 'theme'); - console.log(this.props.metadata); }, handleLanguage : function(languageCode){ @@ -221,9 +224,6 @@ const MetadataEditor = createClass({ renderThemeDropdown : function(){ if(!global.enable_themes) return; - const mergedThemes = _.merge(Themes, this.props.userThemes); - console.log(mergedThemes); - const listThemes = (renderer)=>{ return _.map(_.values(mergedThemes[renderer]), (theme)=>{ if(theme.path == this.props.metadata.shareId) return; @@ -243,9 +243,8 @@ const MetadataEditor = createClass({ }; const currentRenderer = this.props.metadata.renderer; - console.log(this.props.metadata.theme); const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` }; + ?? { name: `!!! Manually selected theme !!! ID=${this.props.metadata.theme}` }; let dropdown; if(currentRenderer == 'legacy') { @@ -259,7 +258,6 @@ const MetadataEditor = createClass({
{currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name}
{listThemes(currentRenderer)} - {console.log(listThemes(currentRenderer))} ; } @@ -279,7 +277,7 @@ const MetadataEditor = createClass({ default='' placeholder='Enter share id' className='value' - defaultValue={this.state.lastThemeWriteIn} + defaultValue={this.state.lastThemeWriteIn || this.props.metadata.theme} onChange={(e)=>this.handleThemeWritein(e)} />; }, diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 585d5205d..ef6da5099 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -152,7 +152,6 @@ const EditPage = createClass({ handleMetaChange : function(metadata, field=undefined){ if(field == 'theme' || field == 'renderer') {// Fetch theme bundle only if theme or renderer was changed - console.log(metadata); fetchThemeBundle(this, metadata.renderer, metadata.theme); } this.setState((prevState)=>({ From 74122d90579812916b526626144f85ff9f7debba Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 7 Jan 2025 22:11:01 -0600 Subject: [PATCH 078/393] Display name of write in theme next to write-in Clear user's active ThemeBundle when an incomplete/broken/invalid writein. Needs theming help. --- client/homebrew/editor/editor.jsx | 1 + .../editor/metadataEditor/metadataEditor.jsx | 13 ++++++++----- .../editor/metadataEditor/metadataEditor.less | 4 ++++ client/homebrew/pages/editPage/editPage.jsx | 1 + server/homebrew.api.js | 6 +++++- shared/helpers.js | 15 +++++++++++++-- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index bba5f3ad9..3e37aba57 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -454,6 +454,7 @@ const Editor = createClass({ rerenderParent={this.rerenderParent} /> diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 6d8755aba..694444bc9 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -53,8 +53,8 @@ const MetadataEditor = createClass({ return { showThumbnail : true, showThemeWritein : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? false : true, - lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] : '', - lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] + lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme].path : '', + lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : this.props.metadata.theme }; }, @@ -244,7 +244,7 @@ const MetadataEditor = createClass({ const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `!!! Manually selected theme !!! ID=${this.props.metadata.theme}` }; + ?? { name: `${this.props.themeBundle?.path || ''}`, author: '!!!' }; let dropdown; if(currentRenderer == 'legacy') { @@ -273,12 +273,15 @@ const MetadataEditor = createClass({ renderThemeWritein : function(){ if(!this.state.showThemeWritein) return; - return + this.handleThemeWritein(e)} />; + onChange={(e)=>this.handleThemeWritein(e)} /> + {`${this.state.lastThemeWriteIn ? this.props.themeBundle?.path || '' : ''}`} +
; }, renderLanguageDropdown : function(){ diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 9f13fbc49..d06e420ae 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -1,5 +1,9 @@ @import 'naturalcrit/styles/colors.less'; +.userThemeName { + padding-left: 10px; + padding-right: 10px; +} .metadataEditor { position : absolute; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index ef6da5099..7c7044832 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -443,6 +443,7 @@ const EditPage = createClass({ reportError={this.errorReported} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} + themeBundle={this.state.themeBundle} snippetBundle={this.state.themeBundle.snippets} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 8f0d143fa..8b4175491 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -279,6 +279,7 @@ const api = { let currentTheme; const completeStyles = []; const completeSnippets = []; + let themePath = ''; while (req.params.id) { //=== User Themes ===// @@ -292,6 +293,7 @@ const api = { currentTheme = req.brew; splitTextStyleAndMetadata(currentTheme); + if(themePath === '') themePath = currentTheme.title; // If there is anything in the snippets or style members, append them to the appropriate array // if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); @@ -301,6 +303,7 @@ const api = { req.params.renderer = currentTheme.renderer; } else { //=== Static Themes ===// + if(themePath === '') themePath = req.params.id; const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; completeSnippets.push(localSnippets); @@ -313,7 +316,8 @@ const api = { const returnObj = { // Reverse the order of the arrays so they are listed oldest parent to youngest child. styles : completeStyles.reverse(), - snippets : completeSnippets.reverse() + snippets : completeSnippets.reverse(), + path : themePath }; res.setHeader('Content-Type', 'application/json'); diff --git a/shared/helpers.js b/shared/helpers.js index b2190cdcd..3aff9538a 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -44,8 +44,13 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ .catch((err)=>{ obj.setState({ error: err }); }); - if(!res) return; - + if(!res) { + obj.setState((prevState)=>({ + ...prevState, + themeBundle : {} + })); + return; + } const themeBundle = res.body; themeBundle.joinedStyles = themeBundle.styles.map((style)=>``).join('\n\n'); obj.setState((prevState)=>({ @@ -54,8 +59,14 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ })); }; +const fetchBrewAsThemeJSON = async (renderer, theme)=>{ + if(!renderer || !theme) return; + +} + export { splitTextStyleAndMetadata, printCurrentBrew, fetchThemeBundle, + fetchBrewAsThemeJSON }; From 94a431eec8ffeed1340615d15e56a5136529040f Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 7 Jan 2025 22:28:12 -0600 Subject: [PATCH 079/393] Update tests. --- server/homebrew.api.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 8270b1568..d6433bced 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -587,6 +587,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : 'User Theme A', styles : ['/* From Brew: https://localhost/share/userThemeAID */\n\nUser Theme A Style'], snippets : [] }); @@ -607,6 +608,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : 'User Theme A', styles : [ '/* From Brew: https://localhost/share/userThemeCID */\n\nUser Theme C Style', '/* From Brew: https://localhost/share/userThemeBID */\n\nUser Theme B Style', @@ -623,6 +625,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : '5ePHB', styles : [ `/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`, `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` @@ -649,6 +652,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : 'User Theme A', styles : [ `/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`, `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");`, From 6eb938bb373b2d15428f9c3425c0ce8bdcddd8ce Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 8 Jan 2025 09:25:16 -0600 Subject: [PATCH 080/393] Change theme button toggle to be a bit more obvious. --- client/homebrew/editor/metadataEditor/metadataEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 694444bc9..0fd17db3e 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -265,7 +265,7 @@ const MetadataEditor = createClass({ {!this.state.showThemeWritein?dropdown:''} {this.renderThemeWritein()}
; From 2d47cd2a767f7e2f258bd057efc09ad4a58eb3e6 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 8 Jan 2025 09:28:37 -0600 Subject: [PATCH 081/393] Formatting cleanup --- .../editor/metadataEditor/metadataEditor.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0fd17db3e..92e737764 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -265,7 +265,7 @@ const MetadataEditor = createClass({ {!this.state.showThemeWritein?dropdown:''} {this.renderThemeWritein()}
; @@ -275,11 +275,11 @@ const MetadataEditor = createClass({ if(!this.state.showThemeWritein) return; return
this.handleThemeWritein(e)} /> + default='' + placeholder='Enter share id' + className='value' + defaultValue={this.state.lastThemeWriteIn || this.props.metadata.theme} + onChange={(e)=>this.handleThemeWritein(e)} /> {`${this.state.lastThemeWriteIn ? this.props.themeBundle?.path || '' : ''}`}
; }, From 662f039daa9437317cd128271d2962ecfbd32fb0 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 12 Jan 2025 14:13:27 -0600 Subject: [PATCH 082/393] Merge conflict clearing --- package-lock.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 072108b1f..d05e97f62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "classnames": "^2.5.1", "codemirror": "^5.65.6", "cookie-parser": "^1.4.7", - "core-js": "^3.39.0", + "core-js": "^3.40.0", "cors": "^2.8.5", "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.3", @@ -36,17 +36,17 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "^1.0.10", + "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.9.2", + "mongoose": "^8.9.4", "nanoid": "5.0.9", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-frame-component": "^4.1.3", + "react-frame-component": "^5.2.7", "react-router": "^7.1.1", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", @@ -54,7 +54,7 @@ }, "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.1", - "babel-plugin-transform-import-meta": "^2.2.1", + "babel-plugin-transform-import-meta": "^2.3.2", "eslint": "^9.17.0", "eslint-plugin-jest": "^28.10.0", "eslint-plugin-react": "^7.37.3", @@ -3678,14 +3678,14 @@ } }, "node_modules/babel-plugin-transform-import-meta": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.2.1.tgz", - "integrity": "sha512-AxNh27Pcg8Kt112RGa3Vod2QS2YXKKJ6+nSvRtv7qQTJAdx0MZa4UHZ4lnxHUWA2MNbLuZQv5FVab4P1CoLOWw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.2.tgz", + "integrity": "sha512-902o4GiQqI1GqAXfD5rEoz0PJamUfJ3VllpdWaNsFTwdaNjFSFHawvBO+cp5K2j+g2h3bZ4lnM1Xb6yFYGihtA==", "dev": true, "license": "BSD", "dependencies": { - "@babel/template": "^7.4.4", - "tslib": "^2.4.0" + "@babel/template": "^7.25.9", + "tslib": "^2.8.1" }, "peerDependencies": { "@babel/core": "^7.10.0" @@ -4645,9 +4645,9 @@ } }, "node_modules/core-js": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", - "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -9868,12 +9868,12 @@ } }, "node_modules/marked-extended-tables": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.10.tgz", - "integrity": "sha512-zvRS0GPTkxq8UWawSDecd1Rxd2KD8crrmq2QALGDdrgkcgRNQzHlbnlujBGuXxdgDJg7f6UTv+JpcfejBpKdSg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.1.0.tgz", + "integrity": "sha512-xPQlnmr/mpIJEjwg9/guSKzxoKu7hyCD/sM59mcZc+nMIh2JuVM2se+kCa1Jo1UH+BEHcNlZ221ziJ/cOxAgCA==", "license": "MIT", "peerDependencies": { - "marked": ">=3 <15" + "marked": ">=3 <16" } }, "node_modules/marked-gfm-heading-id": { @@ -10254,9 +10254,9 @@ } }, "node_modules/mongoose": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.2.tgz", - "integrity": "sha512-mLWynmZS1v8HTeMxyLhskQncS1SkrjW1eLNuFDYGQMQ/5QrFrxTLNwWXeCRZeKT2lXyaxW8bnJC9AKPT9jYMkw==", + "version": "8.9.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.4.tgz", + "integrity": "sha512-DndoI01aV/q40P9DiYDXsYjhj8vZjmmuFwcC3Tro5wFznoE1z6Fe2JgMnbLR6ghglym5ziYizSfAJykp+UPZWg==", "license": "MIT", "dependencies": { "bson": "^6.10.1", @@ -11675,9 +11675,9 @@ } }, "node_modules/react-frame-component": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.3.tgz", - "integrity": "sha512-4PurhctiqnmC1F5prPZ+LdsalH7pZ3SFA5xoc0HBe8mSHctdLLt4Cr2WXfXOoajHBYq/yiipp9zOgx+vy8GiEA==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-5.2.7.tgz", + "integrity": "sha512-ROjHtSLoSVYUBfTieazj/nL8jIX9rZFmHC0yXEU+dx6Y82OcBEGgU9o7VyHMrBFUN9FuQ849MtIPNNLsb4krbg==", "license": "MIT", "peerDependencies": { "prop-types": "^15.5.9", From f6c95fb8b773ebeff021bd7a581e352e7ea5bddd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Tue, 14 Jan 2025 08:25:46 +1300 Subject: [PATCH 083/393] Extend header nav to exclude frontCover pages --- .../brewRenderer/headerNav/headerNav.jsx | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index 68963129f..8278e2bd9 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -11,11 +11,18 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ const renderHeaderLinks = ()=>{ if(!pagesRef.current) return; + const excludedPages = { + '.frontCover' : 'Cover Page', + '.toc' : 'Contents' + }; + + const excluded = Object.keys(excludedPages).join(','); + const selector = [ - '.pages > .page', // All page elements, which by definition have IDs - '.page:not(:has(.toc)) > [id]', // All direct children of non-ToC .page with an ID (Legacy) - '.page:not(:has(.toc)) > .columnWrapper > [id]', // All direct children of non-ToC .page > .columnWrapper with an ID (V3) - '.page:not(:has(.toc)) h2', // All non-ToC H2 titles, like Monster frame titles + '.pages > .page', // All page elements, which by definition have IDs + `.page:not(:has(${excluded})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy) + `.page:not(:has(${excluded})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3) + `.page:not(:has(${excluded})) h2`, // All non-excluded H2 titles, like Monster frame titles ]; const elements = pagesRef.current.querySelectorAll(selector.join(',')); if(!elements) return; @@ -32,9 +39,13 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ elements.forEach((el)=>{ if(el.className.match(/\bpage\b/)) { let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number - if(el.querySelector('.toc')){ // If the page contains a table of contents, add "- Contents" to the display text - text += ' - Contents'; - }; + Object.keys(excludedPages).every((pageType)=>{ + if(el.querySelector(pageType)){ // If the page contains a table of contents, add "- Contents" to the display text + text += ` - ${excludedPages[pageType]}`; + return false; + }; + return true; + }); navList.push({ depth : 0, // Pages are always at the least indented level text : text, From 60b6dbb38809677939e1052165f669cf9aa751f5 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 24 Jan 2025 13:52:49 -0600 Subject: [PATCH 084/393] Workaround for unclosed
 blocks before
 rendering.

Unsure if this is a fix you really need but it resolves the issue posted.
---
 shared/naturalcrit/markdown.js | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js
index 99766b536..74f29cebf 100644
--- a/shared/naturalcrit/markdown.js
+++ b/shared/naturalcrit/markdown.js
@@ -922,6 +922,18 @@ const globalVarsList    = {};
 let varsQueue       = [];
 let globalPageNumber = 0;
 
+const closePre = (text)=>{
+	const cols = text.split(/^\\column$/gm);
+	if((cols[0].match(/```/g)||[]).length % 2 != 0) {
+		// Catch inserted column pattern
+		if(cols[0].endsWith('\n\n \n')) {
+			cols[0] = cols[0].slice(0, cols[0].length-'\n\n \n'.length);
+			cols[0] += '\n```\n\n \n';
+		} else cols[0] += '\n```\n';
+	}
+	return cols.join(`\n\\column\n`);
+};
+
 const Markdown = {
 	marked : Marked,
 	render : (rawBrewText, pageNumber=0)=>{
@@ -932,7 +944,7 @@ const Markdown = {
 			MarkedGFMResetHeadingIDs();
 		}
 
-		rawBrewText = rawBrewText.replace(/^\\column$/gm, `\n
\n`); + rawBrewText = closePre(rawBrewText).replace(/^\\column$/gm, `\n
\n`); const opts = Marked.defaults; From 004729b2a4f0ad27711a1c60a9ba415c4ad47141 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 28 Jan 2025 19:37:02 -0600 Subject: [PATCH 085/393] Fix editor regression. --- client/homebrew/editor/editor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 46fcf46c7..2d349252a 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -181,7 +181,7 @@ const Editor = createClass({ let userSnippetCount = 1; // start snippet count from page 2 const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; - _.forEach(whichSource.split('\n'), (line, lineNumber)=>{ + _.forEach(whichSource?.split('\n'), (line, lineNumber)=>{ //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); From f1eb6e1ce473bd1a6cacbbbce0bac9bb55875dda Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 28 Jan 2025 21:31:43 -0600 Subject: [PATCH 086/393] Alter varCallInline content to alig with preceeding varDefBlock in inline definitions. This was failing due to both labels having the extraneous spaces cleaned up but the variable label portion of the varCallInline did not, preventing them from being matched during variable resolution. --- shared/naturalcrit/markdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 99766b536..1914cd201 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -735,7 +735,7 @@ function MarkedVariables() { varsQueue.push( { type : 'varCallInline', varName : label, - content : match[9] + content : match[9].replace(/\s+/g, ' ').replace(/\[\s+/, '[').replace(/\s+\]/, ']') }); } if(match[12]) { // Inline Call From 66bfc8f27b8fd5784267c3f6cfd26ec18842fdc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Fri, 31 Jan 2025 22:33:47 +0100 Subject: [PATCH 087/393] style change --- .../notificationLookup/notificationLookup.less | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/admin/notificationUtils/notificationLookup/notificationLookup.less b/client/admin/notificationUtils/notificationLookup/notificationLookup.less index 3f9b78310..edef88b71 100644 --- a/client/admin/notificationUtils/notificationLookup/notificationLookup.less +++ b/client/admin/notificationUtils/notificationLookup/notificationLookup.less @@ -31,8 +31,12 @@ font-weight : 900; } - dl dt{ - font-weight: 900; + dl { + padding-top:0.5em; + dt { + font-weight: 900; + height:fit-content; + } } } } From 564f5d71b2549dbc86bb8fa0d2f4b033340a4764 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 31 Jan 2025 16:12:00 -0600 Subject: [PATCH 088/393] WIP --- shared/naturalcrit/markdown.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 1914cd201..1cd11d7b5 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -59,6 +59,12 @@ mathParser.functions.signed = function (a) { return `${a}`; }; +// Make sure we normalize variable names consistantly. +const normalizeVarNames = (label)=>{ + return label.trim() + .replace(/\s+/g, ' '); +}; + //Processes the markdown within an HTML block if it's just a class-wrapper renderer.html = function (html) { if(_.startsWith(_.trim(html), '')){ @@ -533,7 +539,7 @@ const replaceVar = function(input, hoist=false, allowUnresolved=false) { const match = regex.exec(input); const prefix = match[1]; - const label = match[2]; + const label = normalizeVarNames(match[2]); // Ensure the label name is normalized as it should be in the var stack. //v=====--------------------< HANDLE MATH >-------------------=====v// const mathRegex = /[a-z]+\(|[+\-*/^(),]/g; @@ -688,7 +694,7 @@ function MarkedVariables() { }); } if(match[3]) { // Block Definition - const label = match[4] ? match[4].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[4] ? normalizeVarNames(match[4]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space const content = match[5] ? match[5].trim().replace(/[ \t]+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space varsQueue.push( @@ -698,7 +704,7 @@ function MarkedVariables() { }); } if(match[6]) { // Block Call - const label = match[7] ? match[7].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[7] ? normalizeVarNames(match[7]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space varsQueue.push( { type : 'varCallBlock', @@ -707,7 +713,7 @@ function MarkedVariables() { }); } if(match[8]) { // Inline Definition - const label = match[10] ? match[10].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[10] ? normalizeVarNames(match[10]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space let content = match[11] || null; // In case of nested (), find the correct matching end ) @@ -735,11 +741,11 @@ function MarkedVariables() { varsQueue.push( { type : 'varCallInline', varName : label, - content : match[9].replace(/\s+/g, ' ').replace(/\[\s+/, '[').replace(/\s+\]/, ']') + content : match[9] }); } if(match[12]) { // Inline Call - const label = match[13] ? match[13].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[13] ? normalizeVarNames(match[13]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space varsQueue.push( { type : 'varCallInline', From 3ce9bb13102c315f2f1c2e8d9dca827b988569e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Fri, 31 Jan 2025 23:20:35 +0100 Subject: [PATCH 089/393] initial commit --- client/admin/admin.jsx | 56 ++++++++++++------------- client/admin/admin.less | 8 +++- client/admin/brewUtils/stats/stats.jsx | 5 ++- client/admin/brewUtils/stats/stats.less | 9 ++-- server/admin.api.js | 1 - 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index f2f2667a4..9f84eaad4 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -1,47 +1,47 @@ -require('./admin.less'); -const React = require('react'); -const createClass = require('create-react-class'); - +import './admin.less'; +import React, { useEffect, useState } from 'react'; const BrewUtils = require('./brewUtils/brewUtils.jsx'); const NotificationUtils = require('./notificationUtils/notificationUtils.jsx'); const tabGroups = ['brew', 'notifications']; -const Admin = createClass({ - getDefaultProps : function() { - return {}; - }, +const Admin = ()=>{ + const [currentTab, setCurrentTab] = useState('brew'); - getInitialState : function(){ - return ({ - currentTab : 'brew' - }); - }, + useEffect(()=>{ + setCurrentTab(localStorage.getItem('hbAdminTab')); + }, []); - handleClick : function(newTab){ - if(this.state.currentTab === newTab) return; - this.setState({ - currentTab : newTab - }); - }, + useEffect(()=>{ + localStorage.setItem('hbAdminTab', currentTab); + }, [currentTab]); - render : function(){ - return
+ return ( +
- homebrewery admin + The Homebrewery Admin Page + back to homepage
+
- {this.state.currentTab==='brew' && } - {this.state.currentTab==='notifications' && } + {currentTab === 'brew' && } + {currentTab === 'notifications' && }
-
; - } -}); +
+ ); +}; module.exports = Admin; diff --git a/client/admin/admin.less b/client/admin/admin.less index c6c9b4662..47ef10528 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -30,6 +30,10 @@ body { color : white; background-color : @red; i { margin-right : 30px; } + + a { + float:right; + } } hr { margin : 30px 0px; } @@ -48,10 +52,10 @@ body { } dl { - @maxItemWidth : 132px; + @maxItemWidth : 180px; dt { float : left; - width : @maxItemWidth; + max-width : @maxItemWidth; clear : left; text-align : right; &::after { content : ' : '; } diff --git a/client/admin/brewUtils/stats/stats.jsx b/client/admin/brewUtils/stats/stats.jsx index 85ce10610..35f46d143 100644 --- a/client/admin/brewUtils/stats/stats.jsx +++ b/client/admin/brewUtils/stats/stats.jsx @@ -14,7 +14,8 @@ const Stats = createClass({ getInitialState(){ return { stats : { - totalBrews : 0 + totalBrews : 0, + totalPublishedBrews : 0 }, fetching : false }; @@ -34,6 +35,8 @@ const Stats = createClass({
Total Brew Count
{this.state.stats.totalBrews}
+
Total Brews Published
+
{this.state.stats.totalPublishedBrews}
{this.state.fetching diff --git a/client/admin/brewUtils/stats/stats.less b/client/admin/brewUtils/stats/stats.less index b5a4612e1..355845cbc 100644 --- a/client/admin/brewUtils/stats/stats.less +++ b/client/admin/brewUtils/stats/stats.less @@ -4,10 +4,13 @@ .pending { position : absolute; - top : 0px; - left : 0px; + top : 0.5em; + left : 100px; width : 100%; height : 100%; - background-color : rgba(238,238,238, 0.5); + } + + &:has(.pending) { + opacity:0.5; } } \ No newline at end of file diff --git a/server/admin.api.js b/server/admin.api.js index 1a39f020b..65c91fee8 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -135,7 +135,6 @@ router.put('/admin/compress/:id', (req, res)=>{ }); }); - router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ try { const totalBrewsCount = await HomebrewModel.countDocuments({}); From b1ff68c3b1df577a8e51654373ac62024f0baaf9 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 31 Jan 2025 16:12:00 -0600 Subject: [PATCH 090/393] Update code to use helper function to ensure unifrom normalization of Variable labels. --- shared/naturalcrit/markdown.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 1914cd201..1cd11d7b5 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -59,6 +59,12 @@ mathParser.functions.signed = function (a) { return `${a}`; }; +// Make sure we normalize variable names consistantly. +const normalizeVarNames = (label)=>{ + return label.trim() + .replace(/\s+/g, ' '); +}; + //Processes the markdown within an HTML block if it's just a class-wrapper renderer.html = function (html) { if(_.startsWith(_.trim(html), '')){ @@ -533,7 +539,7 @@ const replaceVar = function(input, hoist=false, allowUnresolved=false) { const match = regex.exec(input); const prefix = match[1]; - const label = match[2]; + const label = normalizeVarNames(match[2]); // Ensure the label name is normalized as it should be in the var stack. //v=====--------------------< HANDLE MATH >-------------------=====v// const mathRegex = /[a-z]+\(|[+\-*/^(),]/g; @@ -688,7 +694,7 @@ function MarkedVariables() { }); } if(match[3]) { // Block Definition - const label = match[4] ? match[4].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[4] ? normalizeVarNames(match[4]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space const content = match[5] ? match[5].trim().replace(/[ \t]+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space varsQueue.push( @@ -698,7 +704,7 @@ function MarkedVariables() { }); } if(match[6]) { // Block Call - const label = match[7] ? match[7].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[7] ? normalizeVarNames(match[7]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space varsQueue.push( { type : 'varCallBlock', @@ -707,7 +713,7 @@ function MarkedVariables() { }); } if(match[8]) { // Inline Definition - const label = match[10] ? match[10].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[10] ? normalizeVarNames(match[10]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space let content = match[11] || null; // In case of nested (), find the correct matching end ) @@ -735,11 +741,11 @@ function MarkedVariables() { varsQueue.push( { type : 'varCallInline', varName : label, - content : match[9].replace(/\s+/g, ' ').replace(/\[\s+/, '[').replace(/\s+\]/, ']') + content : match[9] }); } if(match[12]) { // Inline Call - const label = match[13] ? match[13].trim().replace(/\s+/g, ' ') : null; // Trim edge spaces and shorten blocks of whitespace to 1 space + const label = match[13] ? normalizeVarNames(match[13]) : null; // Trim edge spaces and shorten blocks of whitespace to 1 space varsQueue.push( { type : 'varCallInline', From a504703d411c8a7c34cd2057b8f8ec66ac2ecb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Sat, 1 Feb 2025 15:47:41 +0100 Subject: [PATCH 091/393] removed unnecessary files and refactored layout of dl --- client/admin/admin.less | 40 ++++++++++--------- .../brewUtils/brewCleanup/brewCleanup.jsx | 10 ++--- .../brewUtils/brewCleanup/brewCleanup.less | 9 ----- .../brewUtils/brewCompress/brewCompress.jsx | 9 ++--- .../brewUtils/brewCompress/brewCompress.less | 9 ----- .../admin/brewUtils/brewLookup/brewLookup.jsx | 8 ++-- .../brewUtils/brewLookup/brewLookup.less | 6 --- client/admin/brewUtils/brewUtils.jsx | 2 +- client/admin/brewUtils/brewUtils.less | 33 +++++++++++++++ client/admin/brewUtils/stats/stats.jsx | 5 +-- client/admin/brewUtils/stats/stats.less | 16 -------- .../notificationAdd/notificationAdd.less | 6 ++- .../notificationLookup.less | 7 ---- 13 files changed, 71 insertions(+), 89 deletions(-) delete mode 100644 client/admin/brewUtils/brewCleanup/brewCleanup.less delete mode 100644 client/admin/brewUtils/brewCompress/brewCompress.less delete mode 100644 client/admin/brewUtils/brewLookup/brewLookup.less create mode 100644 client/admin/brewUtils/brewUtils.less delete mode 100644 client/admin/brewUtils/stats/stats.less diff --git a/client/admin/admin.less b/client/admin/admin.less index 47ef10528..51c675b5f 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -22,7 +22,6 @@ body { } :where(.admin) { - header { padding : 20px 0px; margin-bottom : 30px; @@ -31,14 +30,13 @@ body { background-color : @red; i { margin-right : 30px; } - a { - float:right; - } + a { float : right; } } hr { margin : 30px 0px; } :where(.container) { + padding-bottom : 50px; input { height : 33px; padding : 0px 10px; @@ -52,20 +50,23 @@ body { } dl { - @maxItemWidth : 180px; + display : grid; + grid-template-columns : 120px 1fr; + row-gap : 10px; + align-items : center; + justify-items : start; + padding-top : 0.5em; dt { - float : left; - max-width : @maxItemWidth; - clear : left; - text-align : right; + float : left; + clear : left; + height : fit-content; + font-weight : 900; + text-align : right; &::after { content : ' : '; } } - dd { - height : 1em; - padding : 0 0 0.5em 0; - margin-left : @maxItemWidth + 6px; - } + dd { height : fit-content; } } + .tabs button { margin-right : 3px; @@ -95,10 +96,11 @@ body { } .error { - background: rgb(178, 54, 54); - color:white; - font-weight: 900; - margin-block:10px; - padding:10px; + float : right; + padding : 10px; + margin-block : 10px; + font-weight : 900; + color : white; + background : rgb(178, 54, 54); } } diff --git a/client/admin/brewUtils/brewCleanup/brewCleanup.jsx b/client/admin/brewUtils/brewCleanup/brewCleanup.jsx index a166ae112..d4b17c570 100644 --- a/client/admin/brewUtils/brewCleanup/brewCleanup.jsx +++ b/client/admin/brewUtils/brewCleanup/brewCleanup.jsx @@ -1,10 +1,8 @@ -require('./brewCleanup.less'); const React = require('react'); const createClass = require('create-react-class'); const request = require('superagent'); - const BrewCleanup = createClass({ displayName : 'BrewCleanup', getDefaultProps(){ @@ -39,9 +37,9 @@ const BrewCleanup = createClass({ if(!this.state.primed) return; if(!this.state.count){ - return
No Matching Brews found.
; + return
No Matching Brews found.
; } - return
+ return
; }, render(){ - return
+ return

Brew Cleanup

Removes very short brews to tidy up the database

@@ -65,7 +63,7 @@ const BrewCleanup = createClass({ {this.renderPrimed()} {this.state.error - &&
{this.state.error.toString()}
+ &&
{this.state.error.toString()}
}
; } diff --git a/client/admin/brewUtils/brewCleanup/brewCleanup.less b/client/admin/brewUtils/brewCleanup/brewCleanup.less deleted file mode 100644 index 16fc98957..000000000 --- a/client/admin/brewUtils/brewCleanup/brewCleanup.less +++ /dev/null @@ -1,9 +0,0 @@ -.BrewCleanup { - .removeBox { - margin-top : 20px; - button { - margin-right : 10px; - background-color : @red; - } - } -} \ No newline at end of file diff --git a/client/admin/brewUtils/brewCompress/brewCompress.jsx b/client/admin/brewUtils/brewCompress/brewCompress.jsx index 2c8e5b023..ccb59e027 100644 --- a/client/admin/brewUtils/brewCompress/brewCompress.jsx +++ b/client/admin/brewUtils/brewCompress/brewCompress.jsx @@ -1,10 +1,7 @@ -require('./brewCompress.less'); const React = require('react'); const createClass = require('create-react-class'); - const request = require('superagent'); - const BrewCompress = createClass({ displayName : 'BrewCompress', getDefaultProps(){ @@ -53,9 +50,9 @@ const BrewCompress = createClass({ if(!this.state.primed) return; if(!this.state.count){ - return
No Matching Brews found.
; + return
No Matching Brews found.
; } - return
+ return
; }, render(){ - return
+ return

Brew Compression

Compresses the text in brews to binary

diff --git a/client/admin/brewUtils/brewCompress/brewCompress.less b/client/admin/brewUtils/brewCompress/brewCompress.less deleted file mode 100644 index 8668e9280..000000000 --- a/client/admin/brewUtils/brewCompress/brewCompress.less +++ /dev/null @@ -1,9 +0,0 @@ -.BrewCompress { - .removeBox { - margin-top : 20px; - button { - margin-right : 10px; - background-color : @red; - } - } -} \ No newline at end of file diff --git a/client/admin/brewUtils/brewLookup/brewLookup.jsx b/client/admin/brewUtils/brewLookup/brewLookup.jsx index e5b585ced..fb780f29e 100644 --- a/client/admin/brewUtils/brewLookup/brewLookup.jsx +++ b/client/admin/brewUtils/brewLookup/brewLookup.jsx @@ -1,5 +1,3 @@ -require('./brewLookup.less'); - const React = require('react'); const createClass = require('create-react-class'); const cx = require('classnames'); @@ -55,7 +53,7 @@ const BrewLookup = createClass({ renderFoundBrew(){ const brew = this.state.foundBrew; - return
+ return
Title
{brew.title}
@@ -90,7 +88,7 @@ const BrewLookup = createClass({ }, render(){ - return
+ return

Brew Lookup

; } diff --git a/client/admin/brewUtils/brewLookup/brewLookup.less b/client/admin/brewUtils/brewLookup/brewLookup.less deleted file mode 100644 index da15e3a64..000000000 --- a/client/admin/brewUtils/brewLookup/brewLookup.less +++ /dev/null @@ -1,6 +0,0 @@ -.brewLookup { - .cleanButton { - display : inline-block; - width : 100%; - } -} \ No newline at end of file diff --git a/client/admin/brewUtils/brewUtils.jsx b/client/admin/brewUtils/brewUtils.jsx index de8c29895..bab2cb82f 100644 --- a/client/admin/brewUtils/brewUtils.jsx +++ b/client/admin/brewUtils/brewUtils.jsx @@ -1,6 +1,6 @@ const React = require('react'); const createClass = require('create-react-class'); - +require('./brewUtils.less'); const BrewCleanup = require('./brewCleanup/brewCleanup.jsx'); const BrewLookup = require('./brewLookup/brewLookup.jsx'); diff --git a/client/admin/brewUtils/brewUtils.less b/client/admin/brewUtils/brewUtils.less new file mode 100644 index 000000000..25e40a818 --- /dev/null +++ b/client/admin/brewUtils/brewUtils.less @@ -0,0 +1,33 @@ +.brewUtil { + .result { + margin-top : 20px; + button { + margin-right : 10px; + background-color : @red; + } + } + .cleanButton { + display : inline-block; + width : 100%; + } +} + +.stats { + position : relative; + + .pending { + position : absolute; + top : 0.5em; + left : 100px; + width : 100%; + height : 100%; + } + + &:has(.pending) { + opacity:0.5; + } + + dl { + grid-template-columns: 200px 250px; + } +} \ No newline at end of file diff --git a/client/admin/brewUtils/stats/stats.jsx b/client/admin/brewUtils/stats/stats.jsx index 35f46d143..7f96618f9 100644 --- a/client/admin/brewUtils/stats/stats.jsx +++ b/client/admin/brewUtils/stats/stats.jsx @@ -1,11 +1,8 @@ -require('./stats.less'); const React = require('react'); const createClass = require('create-react-class'); -const cx = require('classnames'); const request = require('superagent'); - const Stats = createClass({ displayName : 'Stats', getDefaultProps(){ @@ -30,7 +27,7 @@ const Stats = createClass({ .finally(()=>this.setState({ fetching: false })); }, render(){ - return
+ return

Stats

Total Brew Count
diff --git a/client/admin/brewUtils/stats/stats.less b/client/admin/brewUtils/stats/stats.less deleted file mode 100644 index 355845cbc..000000000 --- a/client/admin/brewUtils/stats/stats.less +++ /dev/null @@ -1,16 +0,0 @@ - -.Stats { - position : relative; - - .pending { - position : absolute; - top : 0.5em; - left : 100px; - width : 100%; - height : 100%; - } - - &:has(.pending) { - opacity:0.5; - } -} \ No newline at end of file diff --git a/client/admin/notificationUtils/notificationAdd/notificationAdd.less b/client/admin/notificationUtils/notificationAdd/notificationAdd.less index 878da24c2..72862e956 100644 --- a/client/admin/notificationUtils/notificationAdd/notificationAdd.less +++ b/client/admin/notificationUtils/notificationAdd/notificationAdd.less @@ -6,7 +6,7 @@ .field { display : grid; - grid-template-columns : 120px 150px; + grid-template-columns : 120px 200px; align-items : center; justify-items : stretch; width : 100%; @@ -18,6 +18,10 @@ padding : 0px 10px; margin-bottom : unset; font-family : monospace; + + &[type="date"] { + width:14ch; + } } textarea { diff --git a/client/admin/notificationUtils/notificationLookup/notificationLookup.less b/client/admin/notificationUtils/notificationLookup/notificationLookup.less index edef88b71..25d29251d 100644 --- a/client/admin/notificationUtils/notificationLookup/notificationLookup.less +++ b/client/admin/notificationUtils/notificationLookup/notificationLookup.less @@ -31,13 +31,6 @@ font-weight : 900; } - dl { - padding-top:0.5em; - dt { - font-weight: 900; - height:fit-content; - } - } } } .noNotification { margin-block : 20px; } From a04df0fdfc5fc2ca9a10a086e9d07fae4c15f230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Sat, 1 Feb 2025 19:27:55 +0100 Subject: [PATCH 092/393] small adjustements --- themes/V3/5ePHB/style.less | 3 --- 1 file changed, 3 deletions(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index ba975e58a..4f3e1d7a4 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -622,7 +622,6 @@ left : 0; filter : drop-shadow(0 0 0.075cm black); img { - width : 100%; height : 2cm; } } @@ -667,7 +666,6 @@ left : 0; height : 2cm; img { - width : 100%; height : 2cm; } } @@ -685,7 +683,6 @@ position : absolute; inset : 0; z-index : -1; - width : 11cm; background-image : @backCover; background-repeat : no-repeat; background-size : contain; From 8eef810f3f8f2dae658a8053435f84fff1eeb4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Sat, 1 Feb 2025 20:30:54 +0100 Subject: [PATCH 093/393] backcover logo width --- themes/V3/5ePHB/style.less | 1 - 1 file changed, 1 deletion(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index 4f3e1d7a4..6b8126eb6 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -734,7 +734,6 @@ img { position : relative; z-index : 0; - width : 100%; height : 1.5cm; } p { From bf2210447497b8b65e07c8881d6308dc82bc3c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Sun, 2 Feb 2025 22:19:38 +0100 Subject: [PATCH 094/393] move padding to a more deserving place --- client/admin/admin.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/admin/admin.less b/client/admin/admin.less index 51c675b5f..92d63da2c 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -22,6 +22,7 @@ body { } :where(.admin) { + padding-bottom : 50px; header { padding : 20px 0px; margin-bottom : 30px; @@ -36,7 +37,6 @@ body { hr { margin : 30px 0px; } :where(.container) { - padding-bottom : 50px; input { height : 33px; padding : 0px 10px; From 6d2cbaacc04e068c77e7c70f3f10e1f8945a26fc Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 5 Feb 2025 21:35:21 +1300 Subject: [PATCH 095/393] Add Admin API for getByUser --- server/admin.api.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index 1a39f020b..a7d1d9811 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -93,7 +93,7 @@ router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ /* Cleans `` from the "text" field of a brew */ router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{ - console.log(`[ADMIN] Cleaning script tags from ShareID ${req.params.id}`); + console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Cleaning script tags from ShareID ${req.params.id}`); function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');}; @@ -114,6 +114,18 @@ router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', return await HomebrewAPI.updateBrew(req, res); }); +/* Get list of a user's documents */ +router.get('/admin/user/list/:user', mw.adminOnly, async (req, res)=>{ + const username = req.params.user; + const fields = { _id: 0, text: 0, textBin: 0 }; // Remove unnecessary fields from document lists + + console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Get brew list for ${username}`); + + const brews = await HomebrewModel.getByUser(username, true, fields); + + return res.json(brews); +}); + /* Compresses the "text" field of a brew to binary */ router.put('/admin/compress/:id', (req, res)=>{ HomebrewModel.findOne({ _id: req.params.id }) From 03798e945dc4e69845e6da1b456c52afba8e7dbc Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 5 Feb 2025 21:35:33 +1300 Subject: [PATCH 096/393] Add UI --- client/admin/admin.jsx | 4 +- .../authorUtils/authorLookup/authorLookup.jsx | 90 +++++++++++++++++++ .../authorLookup/authorLookup.less | 48 ++++++++++ client/admin/authorUtils/authorUtils.jsx | 13 +++ 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 client/admin/authorUtils/authorLookup/authorLookup.jsx create mode 100644 client/admin/authorUtils/authorLookup/authorLookup.less create mode 100644 client/admin/authorUtils/authorUtils.jsx diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index f2f2667a4..c24f7f176 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -4,8 +4,9 @@ const createClass = require('create-react-class'); const BrewUtils = require('./brewUtils/brewUtils.jsx'); const NotificationUtils = require('./notificationUtils/notificationUtils.jsx'); +import AuthorUtils from './authorUtils/authorUtils.jsx'; -const tabGroups = ['brew', 'notifications']; +const tabGroups = ['brew', 'notifications', 'authors']; const Admin = createClass({ getDefaultProps : function() { @@ -39,6 +40,7 @@ const Admin = createClass({ {this.state.currentTab==='brew' && } {this.state.currentTab==='notifications' && } + {this.state.currentTab==='authors' && }
; } diff --git a/client/admin/authorUtils/authorLookup/authorLookup.jsx b/client/admin/authorUtils/authorLookup/authorLookup.jsx new file mode 100644 index 000000000..50226d93d --- /dev/null +++ b/client/admin/authorUtils/authorLookup/authorLookup.jsx @@ -0,0 +1,90 @@ +import './authorLookup.less'; + +import React from 'react'; +import request from 'superagent'; + +const authorLookup = ()=>{ + const [author, setAuthor] = React.useState(''); + const [searching, setSearching] = React.useState(false); + const [results, setResults] = React.useState([]); + + const lookup = async ()=>{ + if(!author) return; + + setSearching(true); + setResults([]); + + await request.get(`/admin/user/list/${author}`) + .then((brews)=>{ + setResults(brews.body); + setSearching(false); + }); + }; + + const renderResults = ()=>{ + if(results.length == 0) return <> +

Results

+

None found.

+ ; + + return <> +

{`Results - ${results.length}`}

+
{name}clipview
{result[name].toString()} {navigator.clipboard.writeText(result.shareId.toString());}}>
+ + + + + + + + + + + {results + .sort((a, b)=>{ // Sort brews from most recently updated + if(a.updatedAt > b.updatedAt) return -1; + if(a.updatedAt < b.updatedAt) return 1; + return 0; + }) + .map((brew, idx)=>{ + return + + + + + + ; + })} + +
TitleShareEditLast UpdateStorage
{brew.title}{brew.shareId}{brew.editId}{brew.updatedAt}{brew.googleId ? 'Google' : 'Homebrewery'}
+ ; + }; + + const handleKeyPress = (evt)=>{ + if(evt.key === 'Enter') return lookup(); + }; + + const handleChange = (evt)=>{ + setAuthor(evt.target.value); + }; + + return ( +
+
+

Author Lookup

+ +
+
+ {renderResults()} +
+
+ ); +}; + +module.exports = authorLookup; diff --git a/client/admin/authorUtils/authorLookup/authorLookup.less b/client/admin/authorUtils/authorLookup/authorLookup.less new file mode 100644 index 000000000..7f6903aa5 --- /dev/null +++ b/client/admin/authorUtils/authorLookup/authorLookup.less @@ -0,0 +1,48 @@ +.authorLookup { + position : relative; + display : flex; + flex-direction : column; + + .field { + display : flex; + gap : 5px; + align-items : center; + justify-items : stretch; + width : 100%; + margin-bottom : 20px; + + + input { + height : 33px; + padding : 0px 10px; + margin-bottom : unset; + font-family : monospace; + } + + button { + width: 50px; + + i { margin-right : 10px; } + } + } + + table.resultsTable { + * { + border: 1px solid black; + vertical-align: middle; + padding: 5px; + } + + th { + font-weight: bold; + } + + th, td { + text-align: center; + + &:first-of-type { + text-align: left; + } + } + } +} \ No newline at end of file diff --git a/client/admin/authorUtils/authorUtils.jsx b/client/admin/authorUtils/authorUtils.jsx new file mode 100644 index 000000000..a96eea528 --- /dev/null +++ b/client/admin/authorUtils/authorUtils.jsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import AuthorLookup from './authorLookup/authorLookup.jsx'; + +const authorUtils = ()=>{ + return ( +
+ +
+ ); +}; + +module.exports = authorUtils; \ No newline at end of file From ada06c961869a9f28ce34554d7bae0098da84f76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 03:24:23 +0000 Subject: [PATCH 097/393] Bump @stylistic/stylelint-plugin from 3.1.1 to 3.1.2 Bumps [@stylistic/stylelint-plugin](https://github.com/stylelint-stylistic/stylelint-stylistic) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/stylelint-stylistic/stylelint-stylistic/releases) - [Changelog](https://github.com/stylelint-stylistic/stylelint-stylistic/blob/main/CHANGELOG.md) - [Commits](https://github.com/stylelint-stylistic/stylelint-stylistic/compare/v3.1.1...v3.1.2) --- updated-dependencies: - dependency-name: "@stylistic/stylelint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 649c6597c..94ec75f88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { - "@stylistic/stylelint-plugin": "^3.1.1", + "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", "eslint": "^9.19.0", "eslint-plugin-jest": "^28.11.0", @@ -2773,10 +2773,11 @@ } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.1.tgz", - "integrity": "sha512-XagAHHIa528EvyGybv8EEYGK5zrVW74cHpsjhtovVATbhDRuJYfE+X4HCaAieW9lCkwbX6L+X0I4CiUG3w/hFw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.2.tgz", + "integrity": "sha512-tylFJGMQo62alGazK74MNxFjMagYOHmBZiePZFOJK2n13JZta0uVkB3Bh5qodUmOLtRH+uxH297EibK14UKm8g==", "dev": true, + "license": "MIT", "dependencies": { "@csstools/css-parser-algorithms": "^3.0.1", "@csstools/css-tokenizer": "^3.0.1", diff --git a/package.json b/package.json index 2bf3a0a93..b83237d59 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { - "@stylistic/stylelint-plugin": "^3.1.1", + "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", "eslint": "^9.19.0", "eslint-plugin-jest": "^28.11.0", From d061b902d5c8ddf03bf7d8abfa2c7c8e62377dec Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 7 Feb 2025 19:26:56 -0600 Subject: [PATCH 098/393] Make all typefaces available via blank - for now. --- themes/V3/Blank/style.less | 1 + 1 file changed, 1 insertion(+) diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 82a101d09..ded7370ba 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -5,6 +5,7 @@ @import (less) './themes/fonts/iconFonts/diceFont.less'; @import (less) './themes/fonts/iconFonts/gameIcons.less'; @import (less) './themes/fonts/iconFonts/fontAwesome.less'; +@import (less) './themes/fonts/Journal/fonts.less'; :root { //Colors From a7a7e46e89c8ac0c9cf66c08bd004335d3071cfd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 9 Feb 2025 22:40:54 +1300 Subject: [PATCH 099/393] Correct typo in date of v3.17.0 --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 8cfb499f6..1464df6b0 100644 --- a/changelog.md +++ b/changelog.md @@ -88,7 +88,7 @@ pre { ## changelog For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery). -### Thursday 01/30/2024 - v3.17.0 +### Thursday 01/30/2025 - v3.17.0 {{taskList ##### 5e-Cleric From 659510e364c68ea5a3e1199a3f74498c61119376 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 9 Feb 2025 12:07:09 -0500 Subject: [PATCH 100/393] Remove unused function --- shared/helpers.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index 3aff9538a..c31516ac9 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -59,14 +59,8 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ })); }; -const fetchBrewAsThemeJSON = async (renderer, theme)=>{ - if(!renderer || !theme) return; - -} - export { splitTextStyleAndMetadata, printCurrentBrew, fetchThemeBundle, - fetchBrewAsThemeJSON }; From cfbf4021dccb57df02cbd64db116a5a0ab54f651 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 9 Feb 2025 12:23:42 -0500 Subject: [PATCH 101/393] Remove unneeded filter --- client/homebrew/editor/metadataEditor/metadataEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 92e737764..8b7c31e53 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -239,7 +239,7 @@ const MetadataEditor = createClass({
; - }).filter(Boolean); + }); }; const currentRenderer = this.props.metadata.renderer; From a9fa0bd32d55a760a9f48a81df3351f2074dd05d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 03:10:29 +0000 Subject: [PATCH 102/393] Bump @babel/plugin-transform-runtime from 7.25.9 to 7.26.8 Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.25.9 to 7.26.8. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.8/packages/babel-plugin-transform-runtime) --- updated-dependencies: - dependency-name: "@babel/plugin-transform-runtime" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 ++++++----- package.json | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 649c6597c..0a3b2752c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "license": "MIT", "dependencies": { "@babel/core": "^7.26.7", - "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/plugin-transform-runtime": "^7.26.8", "@babel/preset-env": "^7.26.7", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", @@ -1404,12 +1404,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", - "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.8.tgz", + "integrity": "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", diff --git a/package.json b/package.json index 2bf3a0a93..1c010c365 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ }, "dependencies": { "@babel/core": "^7.26.7", - "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/plugin-transform-runtime": "^7.26.8", "@babel/preset-env": "^7.26.7", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", From 6cfdfad7d326bfb9e93a57cdcfb9f0e94fb724a6 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 10 Feb 2025 00:33:33 -0500 Subject: [PATCH 103/393] Clean up combobox component --- client/components/combobox.jsx | 14 +-- client/components/combobox.less | 88 +++++++++---------- .../editor/metadataEditor/metadataEditor.jsx | 8 +- 3 files changed, 53 insertions(+), 57 deletions(-) diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index 5fcc154bc..56633bbdd 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -58,10 +58,10 @@ const Combobox = createClass({ this.props.onEntry(e); }); }, - handleSelect : function(e){ + handleSelect : function(value, data=value){ this.setState({ - value : e.currentTarget.getAttribute('data-value') - }, ()=>{this.props.onSelect(this.state.value);}); + value : value + }, ()=>{this.props.onSelect(data);}); ; }, renderTextInput : function(){ @@ -82,6 +82,7 @@ const Combobox = createClass({ } }} /> + ); }, @@ -92,11 +93,10 @@ const Combobox = createClass({ const filterOn = _.isString(this.props.autoSuggest.filterOn) ? [this.props.autoSuggest.filterOn] : this.props.autoSuggest.filterOn; const filteredArrays = filterOn.map((attr)=>{ const children = dropdownChildren.filter((item)=>{ - if(suggestMethod === 'includes'){ + if(suggestMethod === 'includes') return item.props[attr]?.toLowerCase().includes(this.state.value.toLowerCase()); - } else if(suggestMethod === 'startsWith'){ + if(suggestMethod === 'startsWith') return item.props[attr]?.toLowerCase().startsWith(this.state.value.toLowerCase()); - } }); return children; }); @@ -111,7 +111,7 @@ const Combobox = createClass({ }, render : function () { const dropdownChildren = this.state.options.map((child, i)=>{ - const clone = React.cloneElement(child, { onClick: (e)=>this.handleSelect(e) }); + const clone = React.cloneElement(child, { onClick: ()=>this.handleSelect(child.props.value, child.props.data) }); return clone; }); return ( diff --git a/client/components/combobox.less b/client/components/combobox.less index 3810a874e..d58019f6f 100644 --- a/client/components/combobox.less +++ b/client/components/combobox.less @@ -1,50 +1,46 @@ .dropdown-container { - position:relative; - input { - width: 100%; - } - .dropdown-options { - position:absolute; - background-color: white; - z-index: 100; - width: 100%; - border: 1px solid gray; - overflow-y: auto; - max-height: 200px; + position : relative; + input { width : 100%; } + .item i { + position : absolute; + right : 10px; + color : black; + } + .dropdown-options { + position : absolute; + z-index : 100; + width : 100%; + max-height : 200px; + overflow-y : auto; + background-color : white; + border : 1px solid gray; - &::-webkit-scrollbar { - width: 14px; - } - &::-webkit-scrollbar-track { - background: #ffffff; - } - &::-webkit-scrollbar-thumb { - background-color: #949494; - border-radius: 10px; - border: 3px solid #ffffff; - } - - .item { - position:relative; - font-size: 11px; - font-family: Open Sans; - padding: 5px; - cursor: default; - margin: 0 3px; - //border-bottom: 1px solid darkgray; - &:hover { - filter: brightness(120%); - background-color: rgb(163, 163, 163); - } - .detail { - width:100%; - text-align: left; - color: rgb(124, 124, 124); - font-style:italic; - font-size: 9px; - } - } - - } + &::-webkit-scrollbar { width : 14px; } + &::-webkit-scrollbar-track { background : #FFFFFF; } + &::-webkit-scrollbar-thumb { + background-color : #949494; + border : 3px solid #FFFFFF; + border-radius : 10px; + } + .item { + position : relative; + padding : 5px; + margin : 0 3px; + font-family : "Open Sans"; + font-size : 11px; + cursor : default; + &:hover { + background-color : rgb(163, 163, 163); + filter : brightness(120%); + } + .detail { + width : 100%; + font-size : 9px; + font-style : italic; + color : rgb(124, 124, 124); + text-align : left; + } + } + } } diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index bfc3b8b61..9d2ec7db6 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -244,9 +244,9 @@ const MetadataEditor = createClass({ return _.map(langCodes.sort(), (code, index)=>{ const localName = new Intl.DisplayNames([code], { type: 'language' }); const englishName = new Intl.DisplayNames('en', { type: 'language' }); - return
- {`${code}`} -
{`${localName.of(code)}`}
+ return
+ {code} +
{localName.of(code)}
; }); }; @@ -269,7 +269,7 @@ const MetadataEditor = createClass({ autoSuggest={{ suggestMethod : 'startsWith', clearAutoSuggestOnClick : true, - filterOn : ['data-value', 'data-detail', 'title'] + filterOn : ['value', 'detail', 'title'] }} > From 11396389abf8c29d4d6aea2dbebe3547ddc34b36 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 10 Feb 2025 20:47:17 -0600 Subject: [PATCH 104/393] Move Superscript/Subscript functions into their own module --- package-lock.json | 10 ++++++++++ package.json | 1 + shared/naturalcrit/markdown.js | 33 +++------------------------------ 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 649c6597c..165f4d343 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^4.0.1", "marked-smartypants-lite": "^1.0.3", + "marked-subsuper-text": "^1.0.1", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.9.6", @@ -9837,6 +9838,15 @@ "marked": ">=4 <16" } }, + "node_modules/marked-subsuper-text": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/marked-subsuper-text/-/marked-subsuper-text-1.0.1.tgz", + "integrity": "sha512-VxKzXdijXd/smeoBcKBJstzxCuTddSvDpsIs1EPhEXCHYfk1MenDxqPXzRrC5kksZe47eptUzg+Bd6EK9HmMbw==", + "license": "MIT", + "peerDependencies": { + "marked": ">=3 <16" + } + }, "node_modules/markedLegacy": { "name": "marked", "version": "0.3.19", diff --git a/package.json b/package.json index 2bf3a0a93..0e2ca72c1 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^4.0.1", "marked-smartypants-lite": "^1.0.3", + "marked-subsuper-text": "^1.0.1", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.9.6", diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 99766b536..181cc55bd 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -7,6 +7,7 @@ import MarkedExtendedTables from 'marked-extended-tables'; import { markedSmartypantsLite as MarkedSmartypantsLite } from 'marked-smartypants-lite'; import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHeadingIDs } from 'marked-gfm-heading-id'; import { markedEmoji as MarkedEmojis } from 'marked-emoji'; +import MarkedSubSuperText from 'marked-subsuper-text'; //Icon fonts included so they can appear in emoji autosuggest dropdown import diceFont from '../../themes/fonts/iconFonts/diceFont.js'; @@ -333,35 +334,6 @@ const mustacheInjectBlock = { } }; -const superSubScripts = { - name : 'superSubScript', - level : 'inline', - start(src) { return src.match(/\^/m)?.index; }, // Hint to Marked.js to stop and check for a match - tokenizer(src, tokens) { - const superRegex = /^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^/m; - const subRegex = /^\^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^\^/m; - let isSuper = false; - let match = subRegex.exec(src); - if(!match){ - match = superRegex.exec(src); - if(match) - isSuper = true; - } - if(match?.length) { - return { - type : 'superSubScript', // Should match "name" above - raw : match[0], // Text to consume from the source - tag : isSuper ? 'sup' : 'sub', - tokens : this.lexer.inlineTokens(match[1]) - }; - } - }, - renderer(token) { - return `<${token.tag}>${this.parser.parseInline(token.tokens)}`; - } -}; - - const justifiedParagraphClasses = []; justifiedParagraphClasses[2] = 'Left'; justifiedParagraphClasses[4] = 'Right'; @@ -796,8 +768,9 @@ const tableTerminators = [ Marked.use(MarkedVariables()); Marked.use({ extensions : [justifiedParagraphs, definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, - nonbreakingSpaces, superSubScripts, mustacheSpans, mustacheDivs, mustacheInjectInline] }); + nonbreakingSpaces, mustacheSpans, mustacheDivs, mustacheInjectInline] }); Marked.use(mustacheInjectBlock); +Marked.use(MarkedSubSuperText()); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions)); From c080e5b1915eea919c2f683aa4445a759b381ff4 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 10 Feb 2025 22:20:12 -0500 Subject: [PATCH 105/393] Add author to snippetBundle --- server/homebrew.api.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 8b4175491..17e9ae7fe 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -279,7 +279,8 @@ const api = { let currentTheme; const completeStyles = []; const completeSnippets = []; - let themePath = ''; + let themeName; + let themeAuthor; while (req.params.id) { //=== User Themes ===// @@ -293,17 +294,18 @@ const api = { currentTheme = req.brew; splitTextStyleAndMetadata(currentTheme); - if(themePath === '') themePath = currentTheme.title; + themeName ??= currentTheme.title; + themeAuthor ??= currentTheme.authors?.[0]; // If there is anything in the snippets or style members, append them to the appropriate array - // if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); + if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`); req.params.id = currentTheme.theme; req.params.renderer = currentTheme.renderer; } else { //=== Static Themes ===// - if(themePath === '') themePath = req.params.id; + themeName ??= req.params.id; const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; completeSnippets.push(localSnippets); @@ -317,7 +319,8 @@ const api = { // Reverse the order of the arrays so they are listed oldest parent to youngest child. styles : completeStyles.reverse(), snippets : completeSnippets.reverse(), - path : themePath + name : themeName, + author : themeAuthor }; res.setHeader('Content-Type', 'application/json'); From 1aed7539110badb8c7b3429f4dd30db113238905 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 10 Feb 2025 22:20:54 -0500 Subject: [PATCH 106/393] Use ComboBox component for Theme Selector --- .../editor/metadataEditor/metadataEditor.jsx | 86 +++++------ .../editor/metadataEditor/metadataEditor.less | 136 ++++++++---------- 2 files changed, 94 insertions(+), 128 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 199d2c4b7..141e1ab92 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -49,12 +49,8 @@ const MetadataEditor = createClass({ }, getInitialState : function(){ - mergedThemes = _.merge(Themes, this.props.userThemes); return { - showThumbnail : true, - showThemeWritein : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? false : true, - lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme].path : '', - lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : this.props.metadata.theme + showThumbnail : true }; }, @@ -64,15 +60,6 @@ const MetadataEditor = createClass({ }); }, - toggleThemeWritein : function(){ - if(!this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; - else this.props.metadata.theme = this.state.lastThemePulldown; - this.props.onChange(this.props.metadata, 'theme'); - this.setState({ - showThemeWritein : !this.state.showThemeWritein - }); - }, - renderThumbnail : function(){ if(!this.state.showThumbnail) return; return ; @@ -128,21 +115,15 @@ const MetadataEditor = createClass({ handleTheme : function(theme){ this.props.metadata.renderer = theme.renderer; this.props.metadata.theme = theme.path; - this.setState({ - lastThemePulldown : theme.path - }); this.props.onChange(this.props.metadata, 'theme'); }, handleThemeWritein : function(e) { - this.props.metadata.renderer = 'V3'; this.props.metadata.theme = e.target.value; - this.setState({ - lastThemeWriteIn : e.target.value - }); - this.props.onChange(this.props.metadata, 'renderer'); + + this.props.onChange(this.props.metadata, 'theme'); }, @@ -224,12 +205,14 @@ const MetadataEditor = createClass({ renderThemeDropdown : function(){ if(!global.enable_themes) return; + const mergedThemes = _.merge(Themes, this.props.userThemes); + const listThemes = (renderer)=>{ return _.map(_.values(mergedThemes[renderer]), (theme)=>{ if(theme.path == this.props.metadata.shareId) return; const preview = theme.thumbnail || `/themes/${theme.renderer}/${theme.path}/dropdownPreview.png`; const texture = theme.thumbnail || `/themes/${theme.renderer}/${theme.path}/dropdownTexture.png`; - return
this.handleTheme(theme)} title={''}> + return
{theme.author ?? renderer} : {theme.name}
@@ -242,45 +225,45 @@ const MetadataEditor = createClass({ }); }; + console.log(this.props.themeBundle); + const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `${this.props.themeBundle?.path || ''}`, author: '!!!' }; + ?? { name: `${this.props.themeBundle?.name || ''}`, author: `${this.props.themeBundle?.author || ''}` }; let dropdown; if(currentRenderer == 'legacy') { dropdown = - -
{`Themes are not supported in the Legacy Renderer`}
-
; +
+
Themes are not supported in the Legacy Renderer
+
; } else { dropdown = - -
{currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name}
- - {listThemes(currentRenderer)} -
; +
+ this.handleTheme(value)} + onEntry={(e)=>{ + e.target.setCustomValidity(''); //Clear the validation popup while typing + //debouncedHandleFieldChange('theme', e); + this.handleThemeWritein(e); + }} + options={listThemes(currentRenderer)} + autoSuggest={{ + suggestMethod : 'includes', + clearAutoSuggestOnClick : true, + filterOn : ['value', 'title'] + }} + /> + Select from the list below (built-in themes and brews you have tagged "meta:theme"), or paste in the Share URL or Share ID of any brew. +
; } return
- {!this.state.showThemeWritein?dropdown:''} - - {this.renderThemeWritein()} -
; - }, - - renderThemeWritein : function(){ - if(!this.state.showThemeWritein) return; - return
- this.handleThemeWritein(e)} /> - {`${this.state.lastThemeWriteIn ? this.props.themeBundle?.path || '' : ''}`} + {dropdown}
; }, @@ -317,8 +300,7 @@ const MetadataEditor = createClass({ clearAutoSuggestOnClick : true, filterOn : ['value', 'detail', 'title'] }} - > - + /> Sets the HTML Lang property for your brew. May affect hyphenation or spellcheck.
diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index d06e420ae..d76220e48 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -171,89 +171,73 @@ } .themes.field { - .navDropdownContainer { + & .dropdown-container { position : relative; z-index : 100; background-color : white; - &.disabled { - font-style : italic; - color : dimgray; - background-color : darkgray; - } - & > div:first-child { - padding : 3px 3px; - background-color : inherit; - border : 1px solid gray; - i { float : right; } - &:hover { - color : white; - background-color : @blue; + } + & .dropdown-options { + overflow-y : visible; + } + .disabled { + font-style : italic; + color : dimgray; + background-color : darkgray; + } + .item { + position : relative; + padding : 3px 3px; + overflow : visible; + background-color : white; + border-top : 1px solid rgb(118, 118, 118); + .preview { + position : absolute; + top : 0; + right : 0; + z-index : 1; + display : flex; + flex-direction : column; + width : 200px; + overflow : hidden; + color : black; + background : #CCCCCC; + border-radius : 5px; + box-shadow : 0 0 5px black; + opacity : 0; + transition : opacity 250ms ease; + h6 { + padding-block : 0.5em; + padding-inline : 1em; + font-weight : 900; + border-bottom : 2px solid hsl(0,0%,40%); } } - .navDropdown .item > p { - width : 45%; - height : 1.1em; - overflow : hidden; - text-overflow : ellipsis; - white-space : nowrap; - } - .navDropdown { - position : absolute; - width : 100%; - box-shadow : 0px 5px 10px rgba(0, 0, 0, 0.3); - .item { - position : relative; - padding : 3px 3px; - overflow : visible; - background-color : white; - border-top : 1px solid rgb(118, 118, 118); - .preview { - position : absolute; - top : 0; - right : 0; - z-index : 1; - display : flex; - flex-direction : column; - width : 200px; - overflow : hidden; - color : black; - background : #CCCCCC; - border-radius : 5px; - box-shadow : 0 0 5px black; - opacity : 0; - transition : opacity 250ms ease; - h6 { - padding-block : 0.5em; - padding-inline : 1em; - font-weight : 900; - border-bottom : 2px solid hsl(0,0%,40%); - } - } - &:hover { - color : white; - background-color : @blue; - } - &:hover > .preview { opacity : 1; } - .texture-container { - position : absolute; - top : 0; - left : 0; - width : 100%; - height : 100%; - min-height : 100%; - overflow : hidden; - > img { - position : absolute; - top : 0px; - right : 0; - width : 50%; - min-height : 100%; - -webkit-mask-image : linear-gradient(90deg, transparent, black 20%); - mask-image : linear-gradient(90deg, transparent, black 20%); - } - } + + .texture-container { + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + min-height : 100%; + overflow : hidden; + > img { + position : absolute; + top : 0; + right : 0; + width : 50%; + min-height : 100%; + -webkit-mask-image : linear-gradient(90deg, transparent, black 20%); + mask-image : linear-gradient(90deg, transparent, black 20%); } } + + &:hover { + color : white; + background-color : @blue; + filter : unset; + } + &:hover > .preview { opacity : 1; } } } From 6d0d0057f6ef18a222a0ffccef3695ad2a580528 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:22:28 +0000 Subject: [PATCH 107/393] Bump eslint from 9.19.0 to 9.20.0 Bumps [eslint](https://github.com/eslint/eslint) from 9.19.0 to 9.20.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.19.0...v9.20.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 31 ++++++++++++++++++++++--------- package.json | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index f005f9ec9..baf696afe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.19.0", + "eslint": "^9.20.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^15.14.0", @@ -1906,9 +1906,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", - "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", "dev": true, "license": "MIT", "engines": { @@ -5634,18 +5634,18 @@ "license": "MIT" }, "node_modules/eslint": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", - "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.0.tgz", + "integrity": "sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.19.0", + "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -5810,6 +5810,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", diff --git a/package.json b/package.json index c5bae6369..9bf60842b 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.19.0", + "eslint": "^9.20.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^15.14.0", From 9d16f4556e12d2a6a9786150aab2160bce5b3462 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:23:08 +0000 Subject: [PATCH 108/393] Bump mongoose from 8.9.6 to 8.10.0 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.9.6 to 8.10.0. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.9.6...8.10.0) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 75 ++++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index f005f9ec9..6f48c6812 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "marked-smartypants-lite": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.9.6", + "mongoose": "^8.10.0", "nanoid": "5.0.9", "nconf": "^0.12.1", "react": "^18.3.1", @@ -2701,9 +2701,10 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", - "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.0.tgz", + "integrity": "sha512-+ywrb0AqkfaYuhHs6LxKWgqbh3I72EpEgESCw37o+9qPx9WTCkgDm2B+eMrwehGtHBWHFU4GXvnSCNiFhhausg==", + "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -2922,12 +2923,14 @@ "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", "dependencies": { "@types/webidl-conversions": "*" } @@ -4144,9 +4147,10 @@ } }, "node_modules/bson": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz", - "integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.2.tgz", + "integrity": "sha512-5afhLTjqDSA3akH56E+/2J6kTDuSIlBxyXPdQslj9hcIgOUE378xdOfZvC/9q3LifJNI6KR/juZ+d0NRNYBwXg==", + "license": "Apache-2.0", "engines": { "node": ">=16.20.1" } @@ -9900,7 +9904,8 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" }, "node_modules/meow": { "version": "13.2.0", @@ -10149,54 +10154,58 @@ } }, "node_modules/mongodb-connection-string-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", - "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz", + "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==", + "license": "Apache-2.0", "dependencies": { "@types/whatwg-url": "^11.0.2", - "whatwg-url": "^13.0.0" + "whatwg-url": "^14.1.0 || ^13.0.0" } }, "node_modules/mongodb-connection-string-url/node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "license": "MIT", "dependencies": { - "punycode": "^2.3.0" + "punycode": "^2.3.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" } }, "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz", + "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==", + "license": "MIT", "dependencies": { - "tr46": "^4.1.1", + "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/mongoose": { - "version": "8.9.6", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.6.tgz", - "integrity": "sha512-ipLvXwNPVuuuq5H3lnSD0lpaRH3DlCoC6emnMVJvweTwxU29uxDJWxMsNpERDQt8JMvYF1HGVuTK+Id2BlQLCA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.0.tgz", + "integrity": "sha512-nLhk3Qrv6q/HpD2k1O7kbBqsq+/kmKpdv5KJ+LLhQlII3e1p/SSLoLP6jMuSiU6+iLK7zFw4T1niAk3mA3QVug==", "license": "MIT", "dependencies": { "bson": "^6.10.1", "kareem": "2.6.3", - "mongodb": "~6.12.0", + "mongodb": "~6.13.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -10214,6 +10223,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -10227,6 +10237,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -10243,6 +10254,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -10257,6 +10269,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -10268,9 +10281,10 @@ } }, "node_modules/mongoose/node_modules/mongodb": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.12.0.tgz", - "integrity": "sha512-RM7AHlvYfS7jv7+BXund/kR64DryVI+cHbVAy9P61fnb1RcWZqOW1/Wj2YhqMCx+MuYhqTRGv7AwHBzmsCKBfA==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.0.tgz", + "integrity": "sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==", + "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", "bson": "^6.10.1", @@ -12651,6 +12665,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" } diff --git a/package.json b/package.json index c5bae6369..d1ac71c14 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "marked-smartypants-lite": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.9.6", + "mongoose": "^8.10.0", "nanoid": "5.0.9", "nconf": "^0.12.1", "react": "^18.3.1", From d1c0557341795e82c0e343e91a1c370f735690f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:04:52 +0000 Subject: [PATCH 109/393] Bump @babel/core from 7.26.7 to 7.26.8 Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.7 to 7.26.8. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.8/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 76 ++++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index e33618722..914b656da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.7", + "@babel/core": "^7.26.8", "@babel/plugin-transform-runtime": "^7.26.8", "@babel/preset-env": "^7.26.7", "@babel/preset-react": "^7.26.3", @@ -110,21 +110,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz", - "integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz", + "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", + "@babel/generator": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", "@babel/helpers": "^7.26.7", - "@babel/parser": "^7.26.7", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.26.7", - "@babel/types": "^7.26.7", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/traverse": "^7.26.8", + "@babel/types": "^7.26.8", + "@types/gensync": "^1.0.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -140,13 +141,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", - "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", + "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.5", - "@babel/types": "^7.26.5", + "@babel/parser": "^7.26.8", + "@babel/types": "^7.26.8", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -389,12 +390,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", - "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", + "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.7" + "@babel/types": "^7.26.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -1683,29 +1684,30 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", + "integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.8", + "@babel/types": "^7.26.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", - "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", + "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", - "@babel/parser": "^7.26.7", - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7", + "@babel/generator": "^7.26.8", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/types": "^7.26.8", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1723,9 +1725,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", - "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", + "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2854,6 +2856,12 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/gensync": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz", + "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==", + "license": "MIT" + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", diff --git a/package.json b/package.json index a27f46524..69d651752 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ ] }, "dependencies": { - "@babel/core": "^7.26.7", + "@babel/core": "^7.26.8", "@babel/plugin-transform-runtime": "^7.26.8", "@babel/preset-env": "^7.26.7", "@babel/preset-react": "^7.26.3", From 45d188fea1ddd079c92d4436e7729c0244d3bc7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:19:50 +0000 Subject: [PATCH 110/393] Bump @babel/preset-env from 7.26.7 to 7.26.8 Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.26.7 to 7.26.8. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.8/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 125 ++++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 73 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index 914b656da..bd3f71491 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "dependencies": { "@babel/core": "^7.26.8", "@babel/plugin-transform-runtime": "^7.26.8", - "@babel/preset-env": "^7.26.7", + "@babel/preset-env": "^7.26.8", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", "body-parser": "^1.20.2", @@ -101,9 +101,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", - "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -220,9 +220,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -739,13 +739,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", - "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/traverse": "^7.26.8" }, "engines": { "node": ">=6.9.0" @@ -1468,11 +1469,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", - "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", + "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1556,12 +1558,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.7.tgz", - "integrity": "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.8.tgz", + "integrity": "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", + "@babel/compat-data": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", @@ -1575,7 +1577,7 @@ "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.26.8", "@babel/plugin-transform-async-to-generator": "^7.25.9", "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", @@ -1618,7 +1620,7 @@ "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.26.8", "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", @@ -1626,9 +1628,9 @@ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.38.1", + "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "engines": { @@ -1638,6 +1640,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", @@ -4114,9 +4129,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "funding": [ { "type": "opencollective", @@ -4131,11 +4146,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -4316,9 +4332,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001699", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz", + "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==", "funding": [ { "type": "opencollective", @@ -4332,7 +4348,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/char-regex": { "version": "1.0.2", @@ -4680,11 +4697,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", - "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", + "license": "MIT", "dependencies": { - "browserslist": "^4.23.3" + "browserslist": "^4.24.3" }, "funding": { "type": "opencollective", @@ -5373,9 +5391,10 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.32", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz", - "integrity": "sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==" + "version": "1.5.97", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.97.tgz", + "integrity": "sha512-HKLtaH02augM7ZOdYRuO19rWDeY+QSJ1VxnXFa/XDFLf07HvM90pALIJFgrO+UVaajI3+aJMMpojoUTLZyQ7JQ==", + "license": "ISC" }, "node_modules/elliptic": { "version": "6.6.0", @@ -5631,9 +5650,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -10580,9 +10599,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, "node_modules/nodemon": { @@ -14082,9 +14101,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "funding": [ { "type": "opencollective", @@ -14101,8 +14120,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" diff --git a/package.json b/package.json index 69d651752..342af4d6e 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "dependencies": { "@babel/core": "^7.26.8", "@babel/plugin-transform-runtime": "^7.26.8", - "@babel/preset-env": "^7.26.7", + "@babel/preset-env": "^7.26.8", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", "body-parser": "^1.20.2", From e89920bd1e0a3949f56b9218dde87eb9fdc703b2 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Feb 2025 07:41:53 +1300 Subject: [PATCH 111/393] Remove unneeded `.then()` Co-authored-by: Trevor Buckner --- client/admin/authorUtils/authorLookup/authorLookup.jsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/client/admin/authorUtils/authorLookup/authorLookup.jsx b/client/admin/authorUtils/authorLookup/authorLookup.jsx index 50226d93d..b5b7735e7 100644 --- a/client/admin/authorUtils/authorLookup/authorLookup.jsx +++ b/client/admin/authorUtils/authorLookup/authorLookup.jsx @@ -14,12 +14,9 @@ const authorLookup = ()=>{ setSearching(true); setResults([]); - await request.get(`/admin/user/list/${author}`) - .then((brews)=>{ - setResults(brews.body); - setSearching(false); - }); - }; + const brews = await request.get(`/admin/user/list/${author}`); + setResults(brews.body); + setSearching(false); const renderResults = ()=>{ if(results.length == 0) return <> From bbc601cf47d8d7bd1e52944709a9fb229dc099e5 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Feb 2025 07:42:35 +1300 Subject: [PATCH 112/393] Simplify sort algorithm Co-authored-by: Trevor Buckner --- client/admin/authorUtils/authorLookup/authorLookup.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/admin/authorUtils/authorLookup/authorLookup.jsx b/client/admin/authorUtils/authorLookup/authorLookup.jsx index b5b7735e7..8cbe31176 100644 --- a/client/admin/authorUtils/authorLookup/authorLookup.jsx +++ b/client/admin/authorUtils/authorLookup/authorLookup.jsx @@ -40,8 +40,7 @@ const authorLookup = ()=>{ {results .sort((a, b)=>{ // Sort brews from most recently updated if(a.updatedAt > b.updatedAt) return -1; - if(a.updatedAt < b.updatedAt) return 1; - return 0; + return 1; }) .map((brew, idx)=>{ return From d48d5260a4f5b044befa03e830921a37efc89710 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Feb 2025 07:54:15 +1300 Subject: [PATCH 113/393] Fix missing } --- client/admin/authorUtils/authorLookup/authorLookup.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/admin/authorUtils/authorLookup/authorLookup.jsx b/client/admin/authorUtils/authorLookup/authorLookup.jsx index 8cbe31176..d4d117147 100644 --- a/client/admin/authorUtils/authorLookup/authorLookup.jsx +++ b/client/admin/authorUtils/authorLookup/authorLookup.jsx @@ -17,6 +17,7 @@ const authorLookup = ()=>{ const brews = await request.get(`/admin/user/list/${author}`); setResults(brews.body); setSearching(false); + }; const renderResults = ()=>{ if(results.length == 0) return <> From 64b7527ad0fcd3fa2b5bc18d1bd577246f505b68 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Feb 2025 08:01:07 +1300 Subject: [PATCH 114/393] Convert space indentation to tabs --- .../authorUtils/authorLookup/authorLookup.jsx | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/client/admin/authorUtils/authorLookup/authorLookup.jsx b/client/admin/authorUtils/authorLookup/authorLookup.jsx index d4d117147..a239f901f 100644 --- a/client/admin/authorUtils/authorLookup/authorLookup.jsx +++ b/client/admin/authorUtils/authorLookup/authorLookup.jsx @@ -39,19 +39,19 @@ const authorLookup = ()=>{ {results - .sort((a, b)=>{ // Sort brews from most recently updated - if(a.updatedAt > b.updatedAt) return -1; - return 1; - }) - .map((brew, idx)=>{ - return - {brew.title} - {brew.shareId} - {brew.editId} - {brew.updatedAt} - {brew.googleId ? 'Google' : 'Homebrewery'} - ; - })} + .sort((a, b)=>{ // Sort brews from most recently updated + if(a.updatedAt > b.updatedAt) return -1; + return 1; + }) + .map((brew, idx)=>{ + return + {brew.title} + {brew.shareId} + {brew.editId} + {brew.updatedAt} + {brew.googleId ? 'Google' : 'Homebrewery'} + ; + })} ; @@ -70,7 +70,7 @@ const authorLookup = ()=>{

Author Lookup

diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx index ef98e8425..ef309a613 100644 --- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx +++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx @@ -30,11 +30,11 @@ const BrewItem = ({ } request.delete(`/api/${brew.googleId ?? ''}${brew.editId}`).send().end((err, res)=>{ - if (err) reportError(err); else window.location.reload(); - }); + if(err) reportError(err); else window.location.reload(); + }); }, [brew, reportError]); - const updateFilter = useCallback((type, term)=> updateListFilter(type, term), [updateListFilter]); + const updateFilter = useCallback((type, term)=>updateListFilter(type, term), [updateListFilter]); const renderDeleteBrewLink = ()=>{ if(!brew.editId) return null; diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 00d0c801d..b9c1b7371 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -100,32 +100,32 @@ const HomePage = createClass({ return
{this.renderNavbar()} -
- - - - +
+ + + +
Save current diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 1d5887b8a..7aaeb3fd3 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -223,39 +223,39 @@ const NewPage = createClass({ render : function(){ return
{this.renderNavbar()} -
- - - - +
+ + + +
; } diff --git a/shared/naturalcrit/nav/nav.jsx b/shared/naturalcrit/nav/nav.jsx index d9b403239..50dff4c33 100644 --- a/shared/naturalcrit/nav/nav.jsx +++ b/shared/naturalcrit/nav/nav.jsx @@ -12,8 +12,8 @@ const Nav = { displayName : 'Nav.base', render : function(){ return ; + {this.props.children} + ; } }), logo : function(){ diff --git a/shared/naturalcrit/splitPane/splitPane.jsx b/shared/naturalcrit/splitPane/splitPane.jsx index 1500c759f..4c77d81a5 100644 --- a/shared/naturalcrit/splitPane/splitPane.jsx +++ b/shared/naturalcrit/splitPane/splitPane.jsx @@ -29,8 +29,8 @@ const SplitPane = (props)=>{ const limitPosition = (x, min = 1, max = window.innerWidth - 13)=>Math.round(Math.min(max, Math.max(min, x))); //when resizing, the divider should grow smaller if less space is given, then grow back if the space is restored, to the original position - const handleResize = () =>setDividerPos(limitPosition(window.localStorage.getItem(storageKey), 0.1 * (window.innerWidth - 13), 0.9 * (window.innerWidth - 13))); - + const handleResize = ()=>setDividerPos(limitPosition(window.localStorage.getItem(storageKey), 0.1 * (window.innerWidth - 13), 0.9 * (window.innerWidth - 13))); + const handleUp =(e)=>{ e.preventDefault(); if(isDragging) { From 962d98543ebd9e2dfb447851e07dd0a8934bd2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Wed, 19 Mar 2025 10:56:16 +0100 Subject: [PATCH 235/393] initial fix --- client/homebrew/editor/editor.jsx | 17 +---------------- client/homebrew/editor/editor.less | 13 +++++++++++++ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 9e6178f3e..d00a126e3 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -13,7 +13,6 @@ const MetadataEditor = require('./metadataEditor/metadataEditor.jsx'); const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME'; const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m; -const SNIPPETBAR_HEIGHT = 25; const DEFAULT_STYLE_TEXT = dedent` /*=======--- Example CSS styling ---=======*/ /* Any CSS here will apply to your document! */ @@ -65,9 +64,7 @@ const Editor = createClass({ componentDidMount : function() { - this.updateEditorSize(); this.highlightCustomMarkdown(); - window.addEventListener('resize', this.updateEditorSize); document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys); document.addEventListener('keydown', this.handleControlKeys); @@ -82,10 +79,6 @@ const Editor = createClass({ } }, - componentWillUnmount : function() { - window.removeEventListener('resize', this.updateEditorSize); - }, - componentDidUpdate : function(prevProps, prevState, snapshot) { this.highlightCustomMarkdown(); @@ -118,13 +111,6 @@ const Editor = createClass({ } }, - updateEditorSize : function() { - if(this.codeEditor.current) { - let paneHeight = this.editor.current.parentNode.clientHeight; - paneHeight -= SNIPPETBAR_HEIGHT; - this.codeEditor.current.codeMirror.setSize(null, paneHeight); - } - }, updateCurrentCursorPage : function(cursor) { const lines = this.props.brew.text.split('\n').slice(1, cursor.line + 1); @@ -150,8 +136,7 @@ const Editor = createClass({ view : newView }, ()=>{ this.codeEditor.current?.codeMirror.focus(); - this.updateEditorSize(); - }); //TODO: not sure if updateeditorsize needed + }); }, highlightCustomMarkdown : function(){ diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index 5511bee6e..974403447 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -1,11 +1,16 @@ @import 'themes/codeMirror/customEditorStyles.less'; .editor { + height:100%; position : relative; width : 100%; container : editor / inline-size; .codeEditor { height : 100%; + + .CodeMirror { + height:100%; + } .pageLine { background : #33333328; border-top : #333399 solid 1px; @@ -104,3 +109,11 @@ } } + + +@container editor (width < 553px) { + + .editor .codeEditor .CodeMirror { + height:calc(100% - 51px) ; + } +} \ No newline at end of file From 07ff9a114ed8121d47676d300f42761f8230a7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Wed, 19 Mar 2025 13:26:58 +0100 Subject: [PATCH 236/393] lint --- client/homebrew/editor/editor.less | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index 974403447..b9acaa8c0 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -1,16 +1,14 @@ @import 'themes/codeMirror/customEditorStyles.less'; .editor { - height:100%; position : relative; width : 100%; + height : 100%; container : editor / inline-size; .codeEditor { height : 100%; - .CodeMirror { - height:100%; - } + .CodeMirror { height : 100%; } .pageLine { background : #33333328; border-top : #333399 solid 1px; @@ -113,7 +111,5 @@ @container editor (width < 553px) { - .editor .codeEditor .CodeMirror { - height:calc(100% - 51px) ; - } + .editor .codeEditor .CodeMirror { height : calc(100% - 51px) ; } } \ No newline at end of file From d2507fe99f1dad25ab2b18048f2a03d3883cc8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Wed, 19 Mar 2025 13:29:16 +0100 Subject: [PATCH 237/393] remove empty lines --- client/homebrew/editor/editor.jsx | 1 - client/homebrew/editor/editor.less | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index d00a126e3..a58980377 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -111,7 +111,6 @@ const Editor = createClass({ } }, - updateCurrentCursorPage : function(cursor) { const lines = this.props.brew.text.split('\n').slice(1, cursor.line + 1); const pageRegex = this.props.brew.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\page/; diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index b9acaa8c0..79859f5db 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -4,10 +4,8 @@ width : 100%; height : 100%; container : editor / inline-size; - .codeEditor { height : 100%; - .CodeMirror { height : 100%; } .pageLine { background : #33333328; @@ -108,8 +106,6 @@ } - @container editor (width < 553px) { - - .editor .codeEditor .CodeMirror { height : calc(100% - 51px) ; } + .editor .codeEditor .CodeMirror { height : calc(100% - 51px);} } \ No newline at end of file From 551763fecbc27ba6d51043fbcaab54aa4e955bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Wed, 19 Mar 2025 14:04:29 +0100 Subject: [PATCH 238/393] initial commit --- client/homebrew/brewRenderer/brewRenderer.jsx | 8 ++++++++ client/homebrew/brewRenderer/toolBar/toolBar.jsx | 14 +++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 21c0608bd..c288aecf5 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -117,6 +117,13 @@ const BrewRenderer = (props)=>{ pageShadows : true }); + //useEffect to store or gather toolbar state from storage + useEffect(()=>{ + const toolbarState = JSON.parse(window.localStorage.getItem('hb_toolbarState')); + console.log('toolbar state:', toolbarState); + toolbarState && setDisplayOptions(toolbarState); + }, []); + const [headerState, setHeaderState] = useState(false); const mainRef = useRef(null); @@ -271,6 +278,7 @@ const BrewRenderer = (props)=>{ const handleDisplayOptionsChange = (newDisplayOptions)=>{ setDisplayOptions(newDisplayOptions); + localStorage.setItem('hb_toolbarState', JSON.stringify(newDisplayOptions)); }; const pagesStyle = { diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.jsx b/client/homebrew/brewRenderer/toolBar/toolBar.jsx index f11d1f127..102057ca9 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.jsx +++ b/client/homebrew/brewRenderer/toolBar/toolBar.jsx @@ -20,6 +20,11 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa setPageNum(pageRange); }, [visiblePages]); + useEffect(()=>{ + const visibility = localStorage.getItem('hb_toolbarVisibility'); + setToolsVisible(visibility); + }, []); + const handleZoomButton = (zoom)=>{ handleOptionChange('zoomLevel', _.round(_.clamp(zoom, MIN_ZOOM, MAX_ZOOM))); }; @@ -77,7 +82,10 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa return ( ); diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index b5c94399a..5f8a4ba39 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -4,7 +4,7 @@ const React = require('react'); const createClass = require('create-react-class'); // const request = require('superagent'); -const request = require('../../homebrew/utils/request-middleware.js'); +import request from '../../homebrew/utils/request-middleware.js'; const LockTools = createClass({ getInitialState : function() { @@ -226,7 +226,7 @@ const LockTable = createClass({ ; })} {navigator.clipboard.writeText(result.shareId.toString());}}> - + ; })} diff --git a/client/homebrew/utils/request-middleware.js b/client/homebrew/utils/request-middleware.js index 22609dadb..deb08d265 100644 --- a/client/homebrew/utils/request-middleware.js +++ b/client/homebrew/utils/request-middleware.js @@ -1,8 +1,8 @@ -const version = require('../../../package.json').version; +import packageJSON from '../../../package.json' with { type: 'json' }; import request from 'superagent'; -const addHeader = (request)=>request.set('Homebrewery-Version', version); +const addHeader = (request)=>request.set('Homebrewery-Version', packageJSON.version); const requestMiddleware = { get : (path)=>addHeader(request.get(path)), diff --git a/server/admin.api.js b/server/admin.api.js index 3685492d5..96a21c8a7 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -305,6 +305,8 @@ router.put('/api/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ } catch (error) { console.error(error); return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); + }; +}); // ####################### NOTIFICATIONS From 7525e087ff0264f9ae28508b2b3f3619a3528511 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 29 Mar 2025 18:47:03 -0500 Subject: [PATCH 262/393] Regression Fix WIP --- client/homebrew/editor/snippetbar/snippetbar.jsx | 9 +++------ client/homebrew/pages/editPage/editPage.jsx | 1 + client/homebrew/pages/homePage/homePage.jsx | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index c8c8fb590..ac3062ecf 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -101,10 +101,11 @@ const Snippetbar = createClass({ if(key == 'snippets') { const result = _.reverse(_.unionBy(_.reverse(newValue), _.reverse(oldValue), 'name')); // Join snippets together, with preference for the child theme over the parent theme return result.filter((snip)=>snip.gen || snip.subsnippets); - } + }; }, compileSnippets : function() { + console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); @@ -122,6 +123,7 @@ const Snippetbar = createClass({ } const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title || 'New Document', this.props.brew.snippets, this.props.themeBundle.snippets); + console.log(userSnippetsasJSON); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; @@ -283,11 +285,6 @@ const Snippetbar = createClass({ module.exports = Snippetbar; - - - - - const SnippetGroup = createClass({ displayName : 'SnippetGroup', getDefaultProps : function() { diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index b209e7ef7..a4d8a1ed4 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -451,6 +451,7 @@ const EditPage = createClass({ }, render : function(){ + console.log(this.state.themeBundle); return
{this.renderNavbar()} diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index b9c1b7371..47cb23d50 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -97,6 +97,7 @@ const HomePage = createClass({ }, render : function(){ + console.log(this.state.themeBundle); return
{this.renderNavbar()} @@ -108,7 +109,7 @@ const HomePage = createClass({ onTextChange={this.handleTextChange} renderer={this.state.brew.renderer} showEditButtons={false} - snippetBundle={this.state.themeBundle.snippets} + themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} currentEditorViewPageNum={this.state.currentEditorViewPageNum} From 9d1601f4244813407321ba6bfc24946644e530a6 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 29 Mar 2025 19:14:10 -0500 Subject: [PATCH 263/393] Seems to be working - no idea why... --- client/homebrew/editor/snippetbar/snippetbar.jsx | 2 -- client/homebrew/pages/editPage/editPage.jsx | 1 - client/homebrew/pages/homePage/homePage.jsx | 1 - 3 files changed, 4 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index ac3062ecf..8c6872ab4 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -105,7 +105,6 @@ const Snippetbar = createClass({ }, compileSnippets : function() { - console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); @@ -123,7 +122,6 @@ const Snippetbar = createClass({ } const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title || 'New Document', this.props.brew.snippets, this.props.themeBundle.snippets); - console.log(userSnippetsasJSON); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index a4d8a1ed4..b209e7ef7 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -451,7 +451,6 @@ const EditPage = createClass({ }, render : function(){ - console.log(this.state.themeBundle); return
{this.renderNavbar()} diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 47cb23d50..d03e30c91 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -97,7 +97,6 @@ const HomePage = createClass({ }, render : function(){ - console.log(this.state.themeBundle); return
{this.renderNavbar()} From 2ce7c6c2be86e89b22e794472e5da344d1234459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:14:03 +0200 Subject: [PATCH 264/393] css breakpoint changed --- client/homebrew/editor/snippetbar/snippetbar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 7a39173e6..5c98ccfda 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -237,7 +237,7 @@ } } -@container editor (width < 553px) { +@container editor (width < 681px) { .snippetBar { .editors { flex : 1; From b9b45632b0ac714ab948268f37ad2facd728c92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:19:43 +0200 Subject: [PATCH 265/393] fix package-lock --- package-lock.json | 123 +++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d060d210..450d4e364 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,11 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.9", - "@babel/plugin-transform-runtime": "^7.26.9", + "@babel/core": "^7.26.10", + "@babel/plugin-transform-runtime": "^7.26.10", "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", - "@googleapis/drive": "^8.16.0", + "@googleapis/drive": "^11.0.0", "body-parser": "^1.20.2", "classnames": "^2.5.1", "codemirror": "^5.65.6", @@ -33,7 +33,7 @@ "jwt-simple": "^0.5.6", "less": "^3.13.1", "lodash": "^4.17.21", - "marked": "14.0.0", + "marked": "15.0.0", "marked-emoji": "^2.0.0", "marked-extended-tables": "^2.0.1", "marked-gfm-heading-id": "^4.0.1", @@ -41,21 +41,21 @@ "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.12.1", - "nanoid": "5.1.3", + "mongoose": "^8.13.0", + "nanoid": "5.1.5", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", - "react-router": "^7.3.0", + "react-router": "^7.4.0", "sanitize-filename": "1.6.3", - "superagent": "^10.1.1", + "superagent": "^10.2.0", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.22.0", + "eslint": "^9.23.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^16.0.0", @@ -63,10 +63,10 @@ "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.16.0", + "stylelint": "^16.17.0", "stylelint-config-recess-order": "^6.0.0", "stylelint-config-recommended": "^15.0.0", - "supertest": "^7.0.0" + "supertest": "^7.1.0" }, "engines": { "node": "^20.18.x", @@ -1863,9 +1863,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", - "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.0.tgz", + "integrity": "sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1886,9 +1886,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", - "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1923,9 +1923,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", - "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", + "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "dev": true, "license": "MIT", "engines": { @@ -1957,9 +1957,9 @@ } }, "node_modules/@googleapis/drive": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-8.16.0.tgz", - "integrity": "sha512-Xi2mMrUTQ+gsfyouRGd0pfnL+jjg4n4sjKsJruM1y4DknuRfdSBTk5E//WrL0YJ/CqpcBgyd7L8DvaPRtxZD3Q==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-11.0.0.tgz", + "integrity": "sha512-vhkl6/MZ8k5h5XOyenWOD4ys+SNdb8wKYvzU6OBGFx/TzJyHRm4JwgvE8uVDFU6efzNRS0mOiNRfY6nrmHOTtg==", "license": "Apache-2.0", "dependencies": { "googleapis-common": "^7.0.0" @@ -5690,19 +5690,19 @@ "license": "MIT" }, "node_modules/eslint": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", - "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", + "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", - "@eslint/config-helpers": "^0.1.0", + "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", - "@eslint/eslintrc": "^3.3.0", - "@eslint/js": "9.22.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.23.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -9915,9 +9915,9 @@ } }, "node_modules/marked": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", - "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.0.tgz", + "integrity": "sha512-0mouKmBROJv/WSHJBPZZyYofUgawMChnD5je/g+aOBXsHDjb/IsnTQj7mnhQZu+qPJmRQ0ecX3mLGEUm3BgwYA==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -10297,9 +10297,9 @@ } }, "node_modules/mongodb-connection-string-url/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz", + "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==", "license": "MIT", "dependencies": { "punycode": "^2.3.1" @@ -10318,12 +10318,12 @@ } }, "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz", - "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "license": "MIT", "dependencies": { - "tr46": "^5.0.0", + "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" }, "engines": { @@ -10331,14 +10331,14 @@ } }, "node_modules/mongoose": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.12.1.tgz", - "integrity": "sha512-UW22y8QFVYmrb36hm8cGncfn4ARc/XsYWQwRTaj0gxtQk1rDuhzDO1eBantS+hTTatfAIS96LlRCJrcNHvW5+Q==", + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.13.1.tgz", + "integrity": "sha512-sRqlXI+6jhr9/KicCOjet1VVPONFsOxTrh14tfueX5y3GJ2ihswc5ewUUojuwdSS/5koGXLIPmGivDSApVXflA==", "license": "MIT", "dependencies": { "bson": "^6.10.3", "kareem": "2.6.3", - "mongodb": "~6.14.0", + "mongodb": "~6.15.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -10414,9 +10414,9 @@ } }, "node_modules/mongoose/node_modules/mongodb": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.14.2.tgz", - "integrity": "sha512-kMEHNo0F3P6QKDq17zcDuPeaywK/YaJVCEQRzPF3TOM/Bl9MFg64YE5Tu7ifj37qZJMhwU1tl2Ioivws5gRG5Q==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.15.0.tgz", + "integrity": "sha512-ifBhQ0rRzHDzqp9jAQP6OwHSH7dbYIQjD3SbJs9YYk9AikKEettW/9s/tbSFDTpXcRbF+u1aLrhHxDFaYtZpFQ==", "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", @@ -10493,9 +10493,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.3.tgz", - "integrity": "sha512-zAbEOEr7u2CbxwoMRlz/pNSpRP0FdAU4pRaYunCdEezWohXFs+a0Xw7RfkKaezMsmSM1vttcLthJtwRnVtOfHQ==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", "funding": [ { "type": "github", @@ -11770,9 +11770,9 @@ "license": "MIT" }, "node_modules/react-router": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.3.0.tgz", - "integrity": "sha512-466f2W7HIWaNXTKM5nHTqNxLrHTyXybm7R0eBlVSt0k/u55tTCDO194OIx/NrYD4TS5SXKTNekXfT37kMKUjgw==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.4.1.tgz", + "integrity": "sha512-Vmizn9ZNzxfh3cumddqv3kLOKvc7AskUT0dC1prTabhiEi0U4A33LmkDOJ79tXaeSqCqMBXBU/ySX88W85+EUg==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", @@ -13169,9 +13169,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.16.0.tgz", - "integrity": "sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==", + "version": "16.17.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.17.0.tgz", + "integrity": "sha512-I9OwVIWRMqVm2Br5iTbrfSqGRPWQUlvm6oXO1xZuYYu0Gpduy67N8wXOZv15p6E/JdlZiAtQaIoLKZEWk5hrjw==", "dev": true, "funding": [ { @@ -13428,9 +13428,10 @@ } }, "node_modules/superagent": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.1.1.tgz", - "integrity": "sha512-9pIwrHrOj3uAnqg9gDlW7EA2xv+N5au/dSM0kM22HTqmUu8jBxNT+8uA7tA3UoCnmiqzpSbu8rasIUZvbyamMQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.0.tgz", + "integrity": "sha512-IKeoGox6oG9zyDeizaezkJ2/aK0wc5la9st7WsAKyrAkfJ56W3whVbVtF68k6wuc87/y9T85NyON5FLz7Mrzzw==", + "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", @@ -13459,9 +13460,9 @@ } }, "node_modules/supertest": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz", - "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.0.tgz", + "integrity": "sha512-5QeSO8hSrKghtcWEoPiO036fxH0Ii2wVQfFZSP0oqQhmjk8bOLhDFXr4JrvaFmPuEWUoq4znY3uSi8UzLKxGqw==", "dev": true, "license": "MIT", "dependencies": { From de1773361ae0d0f2977e221c0e3a7fe9feb597e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:40:00 +0200 Subject: [PATCH 266/393] final css fix --- client/homebrew/editor/snippetbar/snippetbar.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 5c98ccfda..d7c8d3847 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -14,13 +14,13 @@ .snippets { display : flex; justify-content : flex-start; - min-width : 327.58px; + min-width : 432.18px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied } .editors { display : flex; justify-content : flex-end; - min-width : 225px; + min-width : 250px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied &:only-child {min-width : unset; margin-left : auto;} @@ -237,7 +237,7 @@ } } -@container editor (width < 681px) { +@container editor (width < 682px) { .snippetBar { .editors { flex : 1; From f5fc106d0184660fea8a2c13c99d6e1289789963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:52:41 +0200 Subject: [PATCH 267/393] pixel frame fix --- client/homebrew/editor/snippetbar/snippetbar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index d7c8d3847..a0691f8b6 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -237,7 +237,7 @@ } } -@container editor (width < 682px) { +@container editor (width < 683px) { .snippetBar { .editors { flex : 1; From 4eeaa7c650e7becbca773833c0a1efcea0779e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 17:11:25 +0200 Subject: [PATCH 268/393] default text for snippet tab --- client/homebrew/editor/editor.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 7800717d5..411476131 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -22,7 +22,13 @@ const DEFAULT_STYLE_TEXT = dedent` color: black; }`; -const DEFAULT_SNIPPET_TEXT = ``; +const DEFAULT_SNIPPET_TEXT = dedent` + \snippet example snippet + + The text between \`\snippet title\` lines will become a snippet of name \`title\` as this example provides. + + This snippet is accessible in the brew tab, and will be inherited if the brew is used as a theme. +`; let isJumping = false; const Editor = createClass({ From 8e8f520eaaed2b8929b8e7a19905890912ea4399 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 31 Mar 2025 20:50:54 -0500 Subject: [PATCH 269/393] Fix Highlighting issue with new brew sample snippets --- client/homebrew/editor/editor.jsx | 32 +++++++++++++------------------ 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 411476131..7112aa4b9 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -13,6 +13,7 @@ const MetadataEditor = require('./metadataEditor/metadataEditor.jsx'); const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME'; const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m; +const SNIPPETBREAK_REGEX_V3 = /^\\snippet\ .*$/; const SNIPPETBAR_HEIGHT = 25; const DEFAULT_STYLE_TEXT = dedent` /*=======--- Example CSS styling ---=======*/ @@ -155,6 +156,7 @@ const Editor = createClass({ handleViewChange : function(newView){ this.props.setMoveArrows(newView === 'text'); + this.setState({ view : newView }, ()=>{ @@ -190,6 +192,9 @@ const Editor = createClass({ const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; _.forEach(whichSource?.split('\n'), (line, lineNumber)=>{ + const tabHighlight = this.state.view === 'text' ? 'pageLine' : 'snippetLine'; + const textOrSnip = this.state.view === 'text'; + //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); codeMirror.removeLineClass(lineNumber, 'background', 'snippetLine'); @@ -203,40 +208,28 @@ const Editor = createClass({ // Styling for \page breaks if((this.props.renderer == 'legacy' && line.includes('\\page')) || - (this.props.renderer == 'V3' && line.match(PAGEBREAK_REGEX_V3))) { + (this.props.renderer == 'V3' && line.match(textOrSnip ? PAGEBREAK_REGEX_V3 : SNIPPETBREAK_REGEX_V3))) { - if(lineNumber > 0) // Since \page is optional on first line of document, + if((lineNumber > 0) && (textOrSnip)) // Since \page is optional on first line of document, editorPageCount += 1; // don't use it to increment page count; stay at 1 + else if(this.state.view !== 'text') userSnippetCount += 1; // add back the original class 'background' but also add the new class '.pageline' - codeMirror.addLineClass(lineNumber, 'background', 'pageLine'); + codeMirror.addLineClass(lineNumber, 'background', tabHighlight); const pageCountElement = Object.assign(document.createElement('span'), { className : 'editor-page-count', - textContent : editorPageCount + textContent : textOrSnip ? editorPageCount : userSnippetCount }); codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement); }; // New Codemirror styling for V3 renderer - if(this.props.renderer == 'V3') { + if(this.props.renderer === 'V3') { if(line.match(/^\\column$/)){ codeMirror.addLineClass(lineNumber, 'text', 'columnSplit'); } - // Styling for \snippet breaks - if(this.state.view === 'snip' && line.match(/^\\snippet\ .*$/)) { - - // add back the original class 'background' but also add the new class '.snippetLine' - codeMirror.addLineClass(lineNumber, 'background', 'snippetLine'); - const userSnippetCountElement = Object.assign(document.createElement('span'), { - className : 'editor-snippet-count', - textContent : userSnippetCount - }); - codeMirror.setBookmark({ line: lineNumber, ch: line.length }, userSnippetCountElement); - - userSnippetCount += 1; - }; // definition lists if(line.includes('::')){ if(/^:*$/.test(line) == true){ return; }; @@ -490,12 +483,13 @@ const Editor = createClass({ } if(this.isSnip()){ + if(!this.props.brew.snippets) { this.props.brew.snippets = DEFAULT_SNIPPET_TEXT; } return <> Date: Sun, 6 Apr 2025 19:09:11 +1200 Subject: [PATCH 270/393] Shift request calls to import --- .../pages/editPage/lockNotification/lockNotification.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx index da79ff265..ed3802c4c 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx @@ -1,6 +1,6 @@ -require('./lockNotification.less'); -const React = require('react'); -const request = require('../../../utils/request-middleware.js'); +import './lockNotification.less'; +import * as React from 'react'; +import request from '../../../utils/request-middleware.js'; import Dialog from '../../../../components/dialog.jsx'; function LockNotification(props) { From cb060ae8b11525db420053f1cfb964458096917b Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 6 Apr 2025 19:26:39 +1200 Subject: [PATCH 271/393] Fix state of "Request Review" button on page load --- client/homebrew/pages/editPage/editPage.jsx | 2 +- .../pages/editPage/lockNotification/lockNotification.jsx | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index dc2520373..856a0e347 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -443,7 +443,7 @@ const EditPage = createClass({ {this.renderNavbar()} - {this.props.brew.lock && } + {this.props.brew.lock && }
{}, - lock : {}, + shareId : 0, + disableLock : ()=>{}, + lock : {}, + reviewRequested : false, ...props }; - const [reviewState, setReviewState] = React.useState(false); + const [reviewState, setReviewState] = React.useState(props.reviewRequested); const removeLock = async ()=>{ await request.put(`/admin/lock/review/request/${props.shareId}`) From 0a4ac7a35a01acd47b545167a1e3dbff40fac137 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sun, 6 Apr 2025 19:48:32 +1200 Subject: [PATCH 272/393] Adjust location of package.json --- server/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/app.js b/server/app.js index 6bd0c7c9a..fc0954efd 100644 --- a/server/app.js +++ b/server/app.js @@ -2,10 +2,11 @@ // Set working directory to project root import { dirname } from 'path'; import { fileURLToPath } from 'url'; -import packageJSON from './../package.json' with { type: 'json' }; const __dirname = dirname(fileURLToPath(import.meta.url)); process.chdir(`${__dirname}/..`); + +import packageJSON from '../package.json' with { type: 'json' }; const version = packageJSON.version; import _ from 'lodash'; From e2b38829f2ac7db54b551f5019cd63a8f4ed87bf Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 08:25:42 +1200 Subject: [PATCH 273/393] Refactor /api/lock/count --- server/admin.api.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 96a21c8a7..9207daf71 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -165,21 +165,18 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ }); router.get('/api/lock/count', mw.adminOnly, async (req, res)=>{ - try { - const countLocksQuery = { - lock : { $exists: true } - }; - const count = await HomebrewModel.countDocuments(countLocksQuery) - .then((result)=>{ - return result; - }); - return res.json({ - count + + const countLocksQuery = { + lock : { $exists: true } + }; + const count = await HomebrewModel.countDocuments(countLocksQuery) + .catch((error)=>{ + console.error(error); + return res.json({ status: 'ERROR', detail: 'Unable to get lock count', error }); }); - } catch (error) { - console.error(error); - return res.json({ status: 'ERROR', detail: 'Unable to get lock count', error }); - } + + return res.json({ count }); + }); router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ From fa4b2ae0e362895b888337da96a9b6775aa41c38 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 08:27:32 +1200 Subject: [PATCH 274/393] Refactor /api/lock --- server/admin.api.js | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 9207daf71..30396d1db 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -180,32 +180,33 @@ router.get('/api/lock/count', mw.adminOnly, async (req, res)=>{ }); router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ - try { - const lock = req.body; - lock.applied = new Date; - const filter = { - shareId : req.params.id - }; + const lock = req.body; + lock.applied = new Date; - const brew = await HomebrewModel.findOne(filter); + const filter = { + shareId : req.params.id + }; - if(brew.lock) { - // console.log('ALREADY LOCKED'); - return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); - } + const brew = await HomebrewModel.findOne(filter); - brew.lock = lock; - brew.markModified('lock'); - - await brew.save(); - - // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); - } catch (error) { - console.error(error); - return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); + if(brew.lock) { + // console.log('ALREADY LOCKED'); + return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); } + + brew.lock = lock; + brew.markModified('lock'); + + await brew.save() + .catch((error)=>{ + console.error(error); + return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); + }); + + // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); + }); router.put('/api/unlock/:id', mw.adminOnly, async (req, res)=>{ From 3cf98617f5b8ee0f4a1c82f5f8a8b247ba19ed82 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 08:33:39 +1200 Subject: [PATCH 275/393] Refactor /api/lock/reviews --- server/admin.api.js | 53 +++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 30396d1db..45e8ecc57 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -210,47 +210,48 @@ router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ }); router.put('/api/unlock/:id', mw.adminOnly, async (req, res)=>{ - try { - const filter = { - shareId : req.params.id - }; - const brew = await HomebrewModel.findOne(filter); + const filter = { + shareId : req.params.id + }; - if(!brew.lock) return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); + const brew = await HomebrewModel.findOne(filter); - brew.lock = undefined; - brew.markModified('lock'); + if(!brew.lock) return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); - await brew.save(); + brew.lock = undefined; + brew.markModified('lock'); + + await brew.save() + .catch((error)=>{ + console.error(error); + return res.json({ status: 'ERROR', detail: `Unable to clear lock on brew ${req.params.id}`, error }); + }); + + // console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); - // console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); - } catch (error) { - console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to clear lock on brew ${req.params.id}`, error }); - } return res.json({ status: 'UNLOCKED', detail: `Lock removed from brew ID ${req.params.id}` }); }); router.get('/api/lock/reviews', mw.adminOnly, async (req, res)=>{ - try { - const countReviewsPipeline = [ - { + const countReviewsPipeline = [ + { $match : { 'lock.reviewRequested' : { '$exists': 1 } }, - } - ]; - const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline); - return res.json({ - reviewDocuments + } + ]; + const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) + .catch((error)=>{ + console.error(error); + return res.json({ status: 'ERROR', detail: 'Unable to get review collection', error }); }); - } catch (error) { - console.error(error); - return res.json({ status: 'ERROR', detail: 'Unable to get review collection', error }); - } + return res.json({ + reviewDocuments + }); + }); router.put('/admin/lock/review/request/:id', async (req, res)=>{ From 30430cb8cbcf43032df3a14b9c6283f647d9f339 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 08:36:33 +1200 Subject: [PATCH 276/393] Refactor /admin/lock/review/request --- server/admin.api.js | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 45e8ecc57..dbfe4bc5c 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -257,31 +257,31 @@ router.get('/api/lock/reviews', mw.adminOnly, async (req, res)=>{ router.put('/admin/lock/review/request/:id', async (req, res)=>{ // === This route is NOT Admin only === // Any user can request a review of their document - try { - const filter = { - shareId : req.params.id, - lock : { $exists: 1 } - }; + const filter = { + shareId : req.params.id, + lock : { $exists: 1 } + }; - const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); }; + const brew = await HomebrewModel.findOne(filter); + if(!brew) { return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); }; - if(brew.lock.reviewRequested){ - // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'ALREADY REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); - }; + if(brew.lock.reviewRequested){ + // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'ALREADY REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + }; - brew.lock.reviewRequested = new Date(); - brew.markModified('lock'); + brew.lock.reviewRequested = new Date(); + brew.markModified('lock'); - await brew.save(); + await brew.save() + .catch((error)=>{ + console.error(error); + return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); + }); + + // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); - // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); - } catch (error) { - console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); - } }); router.put('/api/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ From 41bd27b573d25b3dda910b1fca95646eaf271b31 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 08:37:35 +1200 Subject: [PATCH 277/393] Refactor /api/lock/review/remove --- server/admin.api.js | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index dbfe4bc5c..2526a5951 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -285,26 +285,27 @@ router.put('/admin/lock/review/request/:id', async (req, res)=>{ }); router.put('/api/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ - try { - const filter = { - shareId : req.params.id, - 'lock.reviewRequested' : { $exists: 1 } - }; - const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.json({ status: 'REVIEW REQUEST NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; - - brew.lock.reviewRequested = undefined; - brew.markModified('lock'); - - await brew.save(); - - // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); - } catch (error) { - console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); + const filter = { + shareId : req.params.id, + 'lock.reviewRequested' : { $exists: 1 } }; + + const brew = await HomebrewModel.findOne(filter); + if(!brew) { return res.json({ status: 'REVIEW REQUEST NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; + + brew.lock.reviewRequested = undefined; + brew.markModified('lock'); + + await brew.save() + .catch((error)=>{ + console.error(error); + return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); + }); + + // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); + return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); + }); // ####################### NOTIFICATIONS From 0bca3393d4f70cfd8caa080372e31771dd41d362 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 08:39:33 +1200 Subject: [PATCH 278/393] Add LOCK header in comment --- server/admin.api.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index 2526a5951..a2dc76498 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -164,6 +164,8 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ } }); +// ####################### LOCKS + router.get('/api/lock/count', mw.adminOnly, async (req, res)=>{ const countLocksQuery = { From 99c342f19b89c777875c725f2fabd54024e2a479 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 14:38:25 +1200 Subject: [PATCH 279/393] Use throw in Lock API calls --- client/admin/lockTools/lockTools.jsx | 15 ++++-- .../pages/errorPage/errors/errorIndex.js | 22 ++++++++ server/admin.api.js | 52 ++++++++++--------- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 5f8a4ba39..a1cffce24 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -7,6 +7,7 @@ const createClass = require('create-react-class'); import request from '../../homebrew/utils/request-middleware.js'; const LockTools = createClass({ + displayName : 'LockTools', getInitialState : function() { return { fetching : false, @@ -48,6 +49,7 @@ const LockTools = createClass({ }); const LockBrew = createClass({ + displayName : 'LockBrew', getInitialState : function() { // Default values return { @@ -80,6 +82,9 @@ const LockBrew = createClass({ .set('Content-Type', 'application/json') .then((response)=>{ this.setState({ result: response.body }); + }) + .catch((err)=>{ + this.setState({ result: err.response.body }); }); }, @@ -166,6 +171,7 @@ const LockBrew = createClass({ }); const LockTable = createClass({ + displayName : 'LockTable', getDefaultProps : function() { return { title : '', @@ -188,7 +194,7 @@ const LockTable = createClass({ request.get(this.props.fetchURL) .then((res)=>this.setState({ result: res.body })) - .catch((err)=>this.setState({ error: err })) + .catch((err)=>this.setState({ result: err.response.body })) .finally(()=>{ this.setState({ searching: false }); }); @@ -239,6 +245,7 @@ const LockTable = createClass({ }); const LockLookup = createClass({ + displayName : 'LockLookup', getDefaultProps : function() { return { fetchURL : '/api/lookup' @@ -263,14 +270,14 @@ const LockLookup = createClass({ request.put(`${this.props.fetchURL}/${this.state.query}`) .then((res)=>this.setState({ result: res.body })) - .catch((err)=>this.setState({ error: err })) + .catch((err)=>this.setState({ result: err.response.body })) .finally(()=>{ this.setState({ searching: false }); }); }, renderResult : function(){ - return <> + return

Result:

@@ -283,7 +290,7 @@ const LockLookup = createClass({ })}
- ; +
; }, render : function() { diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js index 9584a14b9..d00aec8d5 100644 --- a/client/homebrew/pages/errorPage/errors/errorIndex.js +++ b/client/homebrew/pages/errorPage/errors/errorIndex.js @@ -201,6 +201,28 @@ const errorIndex = (props)=>{ ## Access Denied You need to provide correct administrator credentials to access this page.`, + // ####### Lock Errors + + '60' : dedent`General Lock Error`, + + '61' : dedent`Lock Error: Unable to get lock count`, + + '62' : dedent`Lock Error: Cannot lock`, + + '63' : dedent`Lock Error: Cannot lock - brew not found`, + + '64' : dedent`Lock Error: Cannot lock - already locked`, + + '65' : dedent`Lock Error: Cannot unlock`, + + '66' : dedent`Lock Error: Cannot unlock - brew not found`, + + '67' : dedent`Lock Error: Cannot unlock - not locked`, + + '68' : dedent`Lock Error: Cannot get pending reviews`, + + // ####### Other Errors + '90' : dedent` An unexpected error occurred while looking for these brews. Try again in a few minutes.`, diff --git a/server/admin.api.js b/server/admin.api.js index a2dc76498..12a35cf89 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -166,22 +166,25 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ // ####################### LOCKS -router.get('/api/lock/count', mw.adminOnly, async (req, res)=>{ +router.get('/api/lock/throw', asyncHandler(async ()=>{ + throw { HBErrorCode: '60', code: 500, message: 'Thrown deliberately' }; +})); + +router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ const countLocksQuery = { lock : { $exists: true } }; const count = await HomebrewModel.countDocuments(countLocksQuery) .catch((error)=>{ - console.error(error); - return res.json({ status: 'ERROR', detail: 'Unable to get lock count', error }); + throw { name: 'Lock Count Error', message: 'Unable to get lock count', status: 500, HBErrorCode: '61', error }; }); return res.json({ count }); -}); +})); -router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ +router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ const lock = req.body; lock.applied = new Date; @@ -192,9 +195,11 @@ router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ const brew = await HomebrewModel.findOne(filter); + if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; + if(brew.lock) { // console.log('ALREADY LOCKED'); - return res.json({ status: 'ALREADY LOCKED', detail: `Lock already exists on brew ${req.params.id} - ${brew.title}` }); + throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; } brew.lock = lock; @@ -202,16 +207,15 @@ router.post('/api/lock/:id', mw.adminOnly, async (req, res)=>{ await brew.save() .catch((error)=>{ - console.error(error); - return res.json({ status: 'ERROR', error, message: `Unable to set lock on brew ${req.params.id}` }); + throw { name: 'Already Locked', message: 'Unable to set lock', shareId: req.params.id, status: 500, HBErrorCode: '62', error }; }); // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'LOCKED', detail: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); + return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); -}); +})); -router.put('/api/unlock/:id', mw.adminOnly, async (req, res)=>{ +router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ const filter = { shareId : req.params.id @@ -219,24 +223,25 @@ router.put('/api/unlock/:id', mw.adminOnly, async (req, res)=>{ const brew = await HomebrewModel.findOne(filter); - if(!brew.lock) return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); + if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to unlock', shareId: req.params.id, status: 500, HBErrorCode: '66' }; + + if(!brew.lock) throw { name: 'Not Locked', message: 'Cannot unlock as brew is not locked', shareId: req.params.id, status: 500, HBErrorCode: '67' }; brew.lock = undefined; brew.markModified('lock'); await brew.save() .catch((error)=>{ - console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to clear lock on brew ${req.params.id}`, error }); + throw { name: 'Cannot Unlock', message: 'Unable to clear lock', shareId: req.params.id, status: 500, HBErrorCode: '65', error }; }); // console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'UNLOCKED', detail: `Lock removed from brew ID ${req.params.id}` }); -}); + return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` }); +})); -router.get('/api/lock/reviews', mw.adminOnly, async (req, res)=>{ +router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ const countReviewsPipeline = [ { $match : @@ -247,16 +252,15 @@ router.get('/api/lock/reviews', mw.adminOnly, async (req, res)=>{ ]; const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) .catch((error)=>{ - console.error(error); - return res.json({ status: 'ERROR', detail: 'Unable to get review collection', error }); + throw { name: 'Unable to get reviews', message: 'Unable to get review collection', status: 500, HBErrorCode: '68', error }; }); return res.json({ reviewDocuments }); -}); +})); -router.put('/admin/lock/review/request/:id', async (req, res)=>{ +router.put('/admin/lock/review/request/:id', asyncHandler(async (req, res)=>{ // === This route is NOT Admin only === // Any user can request a review of their document const filter = { @@ -284,9 +288,9 @@ router.put('/admin/lock/review/request/:id', async (req, res)=>{ // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); -}); +})); -router.put('/api/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ +router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ const filter = { shareId : req.params.id, @@ -308,7 +312,7 @@ router.put('/api/lock/review/remove/:id', mw.adminOnly, async (req, res)=>{ // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); -}); +})); // ####################### NOTIFICATIONS From bd145f17da5b7af3cfd0106e8d38a0e1c2cfb8f8 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 14:38:37 +1200 Subject: [PATCH 280/393] Tweak styling --- client/admin/lockTools/lockTools.less | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 5737a32e0..0b6cb615d 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -39,6 +39,7 @@ } .lockTable{ + break-inside: avoid; cursor: default; .row:hover { background-color: #ccc; @@ -56,11 +57,12 @@ padding: 4px 10px; text-align: center; } - td{ + table, td{ border: 1px solid #333333; } .brewLookup{ + break-inside: avoid; min-height: 175px; h2 { margin-top: 0px; From 1e35e1096fd426197b712b84faec82e9d049eba0 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 14:39:33 +1200 Subject: [PATCH 281/393] Reduce data retrieved for brews with requested reviews --- server/admin.api.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index 12a35cf89..6a3a943d5 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -248,6 +248,12 @@ router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ { 'lock.reviewRequested' : { '$exists': 1 } }, + }, + { + $project : { + shareId : 1, + title : 1 + } } ]; const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) From 4c4a023f34305073f8677331aca0fe6e475ac7a6 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 15:59:06 +1200 Subject: [PATCH 282/393] Fix lock notification message --- .../pages/editPage/lockNotification/lockNotification.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx index cc77e6204..9c8bb2c47 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx @@ -8,6 +8,7 @@ function LockNotification(props) { shareId : 0, disableLock : ()=>{}, lock : {}, + message : 'Unable to retrieve Lock Message', reviewRequested : false, ...props }; @@ -31,7 +32,7 @@ function LockNotification(props) {

This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.


LOCK REASON

-

{props.lock.editMessage || 'Unable to retrieve Lock Message'}

+

{props.message}


Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.

Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.

From a594d456116dfb069ae9c750605884c072474fc0 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 15:59:34 +1200 Subject: [PATCH 283/393] Remove unnecessary default option --- .../pages/editPage/lockNotification/lockNotification.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx index 9c8bb2c47..0750a599c 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.jsx @@ -23,7 +23,7 @@ function LockNotification(props) { }; const renderReviewButton = function(){ - if(reviewState || props.lock.reviewRequested){ return ; }; + if(reviewState){ return ; }; return ; }; From ef6f022ea3fb6781488c6a8aed311a8ca008aa72 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 15:59:54 +1200 Subject: [PATCH 284/393] Tweak lock notification styling --- .../pages/editPage/lockNotification/lockNotification.less | 1 + 1 file changed, 1 insertion(+) diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.less b/client/homebrew/pages/editPage/lockNotification/lockNotification.less index de2692ec0..88133ea98 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.less +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.less @@ -14,6 +14,7 @@ margin : 10px; color : white; background-color : #333333; + padding : 2px 15px; &.inactive, &:hover { From a218b87215305e4828454191859f0eda63796cf7 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 16:32:33 +1200 Subject: [PATCH 285/393] Shift remaining lock API functions to use throw --- .../pages/errorPage/errors/errorIndex.js | 28 +++++++++++++------ server/admin.api.js | 18 ++++++------ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js index d00aec8d5..2f0d4599b 100644 --- a/client/homebrew/pages/errorPage/errors/errorIndex.js +++ b/client/homebrew/pages/errorPage/errors/errorIndex.js @@ -203,23 +203,33 @@ const errorIndex = (props)=>{ // ####### Lock Errors - '60' : dedent`General Lock Error`, + '60' : dedent`Lock Error: General`, - '61' : dedent`Lock Error: Unable to get lock count`, + '61' : dedent`Lock Get Error: Unable to get lock count`, - '62' : dedent`Lock Error: Cannot lock`, + '62' : dedent`Lock Set Error: Cannot lock`, - '63' : dedent`Lock Error: Cannot lock - brew not found`, + '63' : dedent`Lock Set Error: Brew not found`, - '64' : dedent`Lock Error: Cannot lock - already locked`, + '64' : dedent`Lock Set Error: Already locked`, - '65' : dedent`Lock Error: Cannot unlock`, + '65' : dedent`Lock Remove Error: Cannot unlock`, - '66' : dedent`Lock Error: Cannot unlock - brew not found`, + '66' : dedent`Lock Remove Error: Brew not found`, - '67' : dedent`Lock Error: Cannot unlock - not locked`, + '67' : dedent`Lock Remove Error: Not locked`, - '68' : dedent`Lock Error: Cannot get pending reviews`, + '68' : dedent`Lock Get Review Error: Cannot get review requests`, + + '69' : dedent`Lock Set Review Error: Cannot set review request`, + + '70' : dedent`Lock Set Review Error: Brew not found`, + + '71' : dedent`Lock Set Review Error: Review already requested`, + + '72' : dedent`Lock Remove Review Error: Cannot clear review request`, + + '73' : dedent`Lock Remove Review Error: Brew not found`, // ####### Other Errors diff --git a/server/admin.api.js b/server/admin.api.js index 6a3a943d5..77de3fd52 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -258,7 +258,7 @@ router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ ]; const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) .catch((error)=>{ - throw { name: 'Unable to get reviews', message: 'Unable to get review collection', status: 500, HBErrorCode: '68', error }; + throw { name: 'Can Not Get Reviews', message: 'Unable to get review collection', status: 500, HBErrorCode: '68', error }; }); return res.json({ reviewDocuments @@ -275,11 +275,11 @@ router.put('/admin/lock/review/request/:id', asyncHandler(async (req, res)=>{ }; const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.json({ status: 'NOT LOCKED', detail: `Brew ID ${req.params.id} is not locked!` }); }; + if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; }; if(brew.lock.reviewRequested){ // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'ALREADY REQUESTED', detail: `Review already requested for brew ${brew.shareId} - ${brew.title}` }); + throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' }; }; brew.lock.reviewRequested = new Date(); @@ -287,12 +287,11 @@ router.put('/admin/lock/review/request/:id', asyncHandler(async (req, res)=>{ await brew.save() .catch((error)=>{ - console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to set request for review on brew ID ${req.params.id}`, error }); + throw { name: 'Can Not Set Review Request', message: `Unable to set request for review on brew ID ${req.params.id}`, code: 500, HBErrorCode: '69', error }; }); // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUESTED', detail: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); })); @@ -304,19 +303,18 @@ router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, }; const brew = await HomebrewModel.findOne(filter); - if(!brew) { return res.json({ status: 'REVIEW REQUEST NOT REMOVED', detail: `Brew ID ${req.params.id} does not have a review pending!` }); }; + if(!brew) { throw { name: 'Can Not Clear Review Request', message: `Brew ID ${req.params.id} does not have a review pending!`, HBErrorCode: '73' }; }; brew.lock.reviewRequested = undefined; brew.markModified('lock'); await brew.save() .catch((error)=>{ - console.error(error); - return res.json({ status: 'ERROR', detail: `Unable to remove request for review on brew ID ${req.params.id}`, error }); + throw { name: 'Can Not Clear Review Request', message: `Unable to remove request for review on brew ID ${req.params.id}`, HBErrorCode: '72', error }; }); // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); - return res.json({ status: 'REVIEW REQUEST REMOVED', detail: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); })); From e2f2b2962f47532df8079e2294718f0b62a0cc27 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 17:34:31 +1200 Subject: [PATCH 286/393] Revert request middleware change as it is no longer necessary --- client/homebrew/utils/request-middleware.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/homebrew/utils/request-middleware.js b/client/homebrew/utils/request-middleware.js index deb08d265..01a9d2571 100644 --- a/client/homebrew/utils/request-middleware.js +++ b/client/homebrew/utils/request-middleware.js @@ -1,8 +1,6 @@ -import packageJSON from '../../../package.json' with { type: 'json' }; import request from 'superagent'; - -const addHeader = (request)=>request.set('Homebrewery-Version', packageJSON.version); +const addHeader = (request)=>request.set('Homebrewery-Version', global.version); const requestMiddleware = { get : (path)=>addHeader(request.get(path)), From 26aa302714ad9364ee34008741543f1e6a1f9399 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 20:04:45 +1200 Subject: [PATCH 287/393] Remove debugging test route --- server/admin.api.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 77de3fd52..8d8500c37 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -166,10 +166,6 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ // ####################### LOCKS -router.get('/api/lock/throw', asyncHandler(async ()=>{ - throw { HBErrorCode: '60', code: 500, message: 'Thrown deliberately' }; -})); - router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ const countLocksQuery = { From ab9b151b8a583e85806b2ebde33b17c99335f0e3 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 20:52:35 +1200 Subject: [PATCH 288/393] Add API route to return all locked brews --- server/admin.api.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/server/admin.api.js b/server/admin.api.js index 8d8500c37..f770e4adf 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -180,6 +180,31 @@ router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ })); +router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ + const countLocksPipeline = [ + { + $match : + { + 'lock' : { '$exists': 1 } + }, + }, + { + $project : { + shareId : 1, + title : 1 + } + } + ]; + const lockedDocuments = await HomebrewModel.aggregate(countLocksPipeline) + .catch((error)=>{ + throw { name: 'Can Not Get Locked Brews', message: 'Unable to get locked brew collection', status: 500, HBErrorCode: '68', error }; + }); + return res.json({ + lockedDocuments + }); + +})); + router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ const lock = req.body; From 7451dda632415a875360d4ca6ba0e9fc29eca1cf Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 20:54:21 +1200 Subject: [PATCH 289/393] Add locked brews table --- client/admin/lockTools/lockTools.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index a1cffce24..253d5f006 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -35,7 +35,9 @@ const LockTools = createClass({

Number of brews currently locked: {this.state.reviewCount}


- + +
+

@@ -175,6 +177,7 @@ const LockTable = createClass({ getDefaultProps : function() { return { title : '', + text : '', fetchURL : '/api/locks', resultName : '', propertyNames : ['shareId'] @@ -212,7 +215,7 @@ const LockTable = createClass({
{this.state.result[this.props.resultName] && <> -

Total Reviews Waiting: {this.state.result[this.props.resultName].length}

+

{this.props.text}: {this.state.result[this.props.resultName].length}

From f74c2049a767e4d751b9f279c7a93e37bf9b5609 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 20:54:44 +1200 Subject: [PATCH 290/393] Rename Edit and Share page message fields --- client/admin/lockTools/lockTools.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 253d5f006..7c7580edf 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -127,12 +127,12 @@ const LockBrew = createClass({


From 61efc2d1522aba1fa24118a68bf431f3d7a86f23 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 21:12:37 +1200 Subject: [PATCH 291/393] Tweak styling --- client/admin/lockTools/lockTools.less | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 0b6cb615d..2666b4bb0 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -12,7 +12,7 @@ line-height: 1.5em; input { float: right; - width: 70%; + width: 65%; margin-left: 10px; } } @@ -68,4 +68,8 @@ margin-top: 0px; } } + + button i { + padding-left: 5px; + } } \ No newline at end of file From 7a1042fedd7abec5161783bb668d14a3d87f7fef Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 22:02:08 +1200 Subject: [PATCH 292/393] Stylelint fixes --- client/admin/lockTools/lockTools.less | 118 ++++++++---------- .../lockNotification/lockNotification.less | 6 +- 2 files changed, 55 insertions(+), 69 deletions(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index 2666b4bb0..f6e7ea9dd 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -1,75 +1,63 @@ .lockTools { - .lockBrew { - columns: 2; + .lockBrew { + columns : 2; - .lockForm { - break-inside: avoid; + .lockForm { + break-inside : avoid; - label { - width: 100%; - display: inline-block; - text-align: right; - line-height: 1.5em; - input { - float: right; - width: 65%; - margin-left: 10px; - } - } - } + label { + display : inline-block; + width : 100%; + line-height : 1.5em; + text-align : right; + input { + float : right; + width : 65%; + margin-left : 10px; + } + input.checkbox { + width : 1.5em; + height : 1.5em; + } + } + } - .lockSuggestions { - break-inside: avoid; - columns: 2; - line-height: 1.2em; - h2 { - column-span: all; - } - h3 { - margin-top: 0px; - } - b { - font-weight: 600; - } + .lockSuggestions { + line-height : 1.2em; + break-inside : avoid; + columns : 2; + h2 { column-span : all; } + h3 { margin-top : 0px; } + b { font-weight : 600; } - .lockCodes { - break-inside: avoid; - } - } - } + .lockCodes { break-inside : avoid; } + } + } - .lockTable{ - break-inside: avoid; - cursor: default; - .row:hover { - background-color: #ccc; - color: #000; - } - .icon { - cursor: pointer; - &:hover{ - text-shadow: 0px 0px 6px black; - } - } - } + .lockTable { + cursor : default; + break-inside : avoid; + .row:hover { + color : #000000; + background-color : #CCCCCC; + } + .icon { + cursor : pointer; + &:hover { text-shadow : 0px 0px 6px black; } + } + } - th, td { - padding: 4px 10px; - text-align: center; - } - table, td{ - border: 1px solid #333333; - } + th, td { + padding : 4px 10px; + text-align : center; + } + table, td { border : 1px solid #333333; } - .brewLookup{ - break-inside: avoid; - min-height: 175px; - h2 { - margin-top: 0px; - } - } + .brewLookup { + min-height : 175px; + break-inside : avoid; + h2 { margin-top : 0px; } + } - button i { - padding-left: 5px; - } + button i { padding-left : 5px; } } \ No newline at end of file diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.less b/client/homebrew/pages/editPage/lockNotification/lockNotification.less index 88133ea98..930b070c4 100644 --- a/client/homebrew/pages/editPage/lockNotification/lockNotification.less +++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.less @@ -11,15 +11,13 @@ &::backdrop { background-color : #000000AA; } button { + padding : 2px 15px; margin : 10px; color : white; background-color : #333333; - padding : 2px 15px; &.inactive, - &:hover { - background-color : #777777; - } + &:hover { background-color : #777777; } } h1, h3 { From f8566392f6ec9fcf8e12cfb07eefbfd7693cd747 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 22:02:28 +1200 Subject: [PATCH 293/393] Add overwrite option for updating locks --- client/admin/lockTools/lockTools.jsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index 7c7580edf..c528fb13d 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -59,7 +59,8 @@ const LockBrew = createClass({ code : 455, editMessage : '', shareMessage : 'This Brew has been locked.', - result : {} + result : {}, + overwrite : false }; }, @@ -73,6 +74,7 @@ const LockBrew = createClass({ e.preventDefault(); if(!this.state.editMessage) return; const newLock = { + overwrite : this.state.overwrite, code : parseInt(this.state.code) || 100, editMessage : this.state.editMessage, shareMessage : this.state.shareMessage, @@ -136,6 +138,10 @@ const LockBrew = createClass({ {this.renderInput('shareMessage')}
+ @@ -163,8 +169,8 @@ const LockBrew = createClass({

Messages

    -
  • Edit Message: This is the private message that is ONLY displayed to the authors of the locked brew. This message MUST specify exactly what actions must be taken in order to have the brew unlocked.
  • -
  • Share Message: This is the public message that is displayed to the EVERYONE that attempts to view the locked brew.
  • +
  • Private Message: This is the private message that is ONLY displayed to the authors of the locked brew. This message MUST specify exactly what actions must be taken in order to have the brew unlocked.
  • +
  • Public Message: This is the public message that is displayed to the EVERYONE that attempts to view the locked brew.
From ec6258a2a5b219f518f2bc4b4672431e64391fff Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Mon, 7 Apr 2025 22:02:53 +1200 Subject: [PATCH 294/393] Add overwrite option to API function --- server/admin.api.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/admin.api.js b/server/admin.api.js index f770e4adf..8942a4675 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -208,6 +208,10 @@ router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ const lock = req.body; + + const overwrite = lock.overwrite || false; + lock.overwrite = undefined; + lock.applied = new Date; const filter = { @@ -218,7 +222,7 @@ router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; - if(brew.lock) { + if(brew.lock && !overwrite) { // console.log('ALREADY LOCKED'); throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; } From 1ded1cad5a123ac7fb4f74a7a89eadba21e293b0 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Tue, 8 Apr 2025 09:28:54 +1200 Subject: [PATCH 295/393] Change accessType check --- server/homebrew.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 055d72eba..c59c6c4d7 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -118,7 +118,7 @@ const api = { throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04' }; } - if(stub?.lock && accessType != 'edit') { + if(stub?.lock && accessType === 'share') { throw { HBErrorCode: '51', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title }; } From d0c3765f8f82959bf7bffd597448dc66f18a0836 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 7 Apr 2025 23:22:47 -0500 Subject: [PATCH 296/393] Move Snippets store to metadata block. Note this still stores the snippets as a string for the passed about brew object. --- server/homebrew.api.js | 7 +------ shared/helpers.js | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 4534c5cb7..84e338ef4 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -170,12 +170,6 @@ const api = { mergeBrewText : (brew)=>{ let text = brew.text; - if(brew.snippets !== undefined) { - text = `\`\`\`snippets\n` + - `${yaml.dump(brewSnippetsToJSON('brew_snippets', brew.snippets, null, false))}` + - `\`\`\`\n\n` + - `${text}`; - } if(brew.style !== undefined) { text = `\`\`\`css\n` + `${brew.style || ''}\n` + @@ -183,6 +177,7 @@ const api = { `${text}`; } const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); + metadata.snippets = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false); text = `\`\`\`metadata\n` + `${yaml.dump(metadata)}\n` + `\`\`\`\n\n` + diff --git a/shared/helpers.js b/shared/helpers.js index 997d77cec..e4dc9eba8 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -91,6 +91,7 @@ const splitTextStyleAndMetadata = (brew)=>{ const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); + brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { @@ -98,11 +99,6 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.style = brew.text.slice(7, index + 1); brew.text = brew.text.slice(index + 6); } - if(brew.text.startsWith('```snippets')) { - const index = brew.text.indexOf('\n```\n\n'); - brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index + 1))).slice(0, -1); - brew.text = brew.text.slice(index + 6); - } // Handle old brews that still have empty strings in the tags metadata if(typeof brew.tags === 'string') brew.tags = brew.tags ? [brew.tags] : []; From 9f56d100aaf5a250715fc70872e3410237378625 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 8 Apr 2025 00:32:11 -0500 Subject: [PATCH 297/393] change tab --- client/homebrew/editor/editor.jsx | 6 +++--- client/homebrew/editor/snippetbar/snippetbar.jsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 7112aa4b9..77da1fcd9 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -61,7 +61,7 @@ const Editor = createClass({ getInitialState : function() { return { editorTheme : this.props.editorTheme, - view : 'text' //'text', 'style', 'meta', 'snip' + view : 'text' //'text', 'style', 'meta', 'snippet' }; }, @@ -71,7 +71,7 @@ const Editor = createClass({ isText : function() {return this.state.view == 'text';}, isStyle : function() {return this.state.view == 'style';}, isMeta : function() {return this.state.view == 'meta';}, - isSnip : function() {return this.state.view == 'snip';}, + isSnip : function() {return this.state.view == 'snippet';}, componentDidMount : function() { @@ -167,7 +167,7 @@ const Editor = createClass({ highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; - if((this.state.view === 'text') ||(this.state.view === 'snip')) { + if((this.state.view === 'text') ||(this.state.view === 'snippet')) { const codeMirror = this.codeEditor.current.codeMirror; codeMirror.operation(()=>{ // Batch CodeMirror styling diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 8c6872ab4..5e2051a86 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -259,8 +259,8 @@ const Snippetbar = createClass({ onClick={()=>this.props.onViewChange('style')}> -
this.props.onViewChange('snip')}> +
this.props.onViewChange('snippet')}>
Date: Tue, 8 Apr 2025 17:22:37 +0000 Subject: [PATCH 298/393] Bump eslint-plugin-react from 7.37.4 to 7.37.5 Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.37.4 to 7.37.5. - [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases) - [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md) - [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.4...v7.37.5) --- updated-dependencies: - dependency-name: eslint-plugin-react dependency-version: 7.37.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 74 +++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e3af673a..582306d8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "babel-plugin-transform-import-meta": "^2.3.2", "eslint": "^9.23.0", "eslint-plugin-jest": "^28.11.0", - "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react": "^7.37.5", "globals": "^16.0.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", @@ -4300,9 +4300,10 @@ } }, "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -4312,12 +4313,13 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -5618,9 +5620,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -5773,10 +5775,11 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.37.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", - "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -5788,7 +5791,7 @@ "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.8", + "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", @@ -6694,20 +6697,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", - "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "dunder-proto": "^1.0.0", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "math-intrinsics": "^1.0.0" + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6726,6 +6730,19 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -10844,15 +10861,16 @@ } }, "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.1" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index 8e88a3fd4..587ba6b1d 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "babel-plugin-transform-import-meta": "^2.3.2", "eslint": "^9.23.0", "eslint-plugin-jest": "^28.11.0", - "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react": "^7.37.5", "globals": "^16.0.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", From 08946ce5d46069f0dfd64ac1c2be81c357d1acf0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:22:50 +0000 Subject: [PATCH 299/393] Bump marked from 15.0.0 to 15.0.8 Bumps [marked](https://github.com/markedjs/marked) from 15.0.0 to 15.0.8. - [Release notes](https://github.com/markedjs/marked/releases) - [Changelog](https://github.com/markedjs/marked/blob/master/.releaserc.json) - [Commits](https://github.com/markedjs/marked/compare/v15.0.0...v15.0.8) --- updated-dependencies: - dependency-name: marked dependency-version: 15.0.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e3af673a..3f1117e44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "jwt-simple": "^0.5.6", "less": "^3.13.1", "lodash": "^4.17.21", - "marked": "15.0.0", + "marked": "15.0.8", "marked-emoji": "^2.0.0", "marked-extended-tables": "^2.0.1", "marked-gfm-heading-id": "^4.0.1", @@ -9894,9 +9894,9 @@ } }, "node_modules/marked": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.0.tgz", - "integrity": "sha512-0mouKmBROJv/WSHJBPZZyYofUgawMChnD5je/g+aOBXsHDjb/IsnTQj7mnhQZu+qPJmRQ0ecX3mLGEUm3BgwYA==", + "version": "15.0.8", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.8.tgz", + "integrity": "sha512-rli4l2LyZqpQuRve5C0rkn6pj3hT8EWPC+zkAxFTAJLxRbENfTAhEQq9itrmf1Y81QtAX5D/MYlGlIomNgj9lA==", "license": "MIT", "bin": { "marked": "bin/marked.js" diff --git a/package.json b/package.json index 8e88a3fd4..fba5fca50 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "jwt-simple": "^0.5.6", "less": "^3.13.1", "lodash": "^4.17.21", - "marked": "15.0.0", + "marked": "15.0.8", "marked-emoji": "^2.0.0", "marked-extended-tables": "^2.0.1", "marked-gfm-heading-id": "^4.0.1", From 9a57b407a595773218449ca536348f843212df21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:46:52 +0000 Subject: [PATCH 300/393] Bump mongoose from 8.13.0 to 8.13.2 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.13.0 to 8.13.2. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.13.0...8.13.2) --- updated-dependencies: - dependency-name: mongoose dependency-version: 8.13.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f1117e44..183b68410 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.13.0", + "mongoose": "^8.13.2", "nanoid": "5.1.5", "nconf": "^0.12.1", "react": "^18.3.1", @@ -10308,9 +10308,9 @@ } }, "node_modules/mongoose": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.13.0.tgz", - "integrity": "sha512-e/iYV1mPeOkg+SWAMHzt3t42/EZyER3OB1H2pjP9C3vQ+Qb5DMeV9Kb+YCUycKgScA3fbwL7dKG4EpinGlg21g==", + "version": "8.13.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.13.2.tgz", + "integrity": "sha512-riCBqZmNkYBWjXpM3qWLDQw7QmTKsVZDPhLXFJqC87+OjocEVpvS3dA2BPPUiLAu+m0/QmEj5pSXKhH+/DgerQ==", "license": "MIT", "dependencies": { "bson": "^6.10.3", diff --git a/package.json b/package.json index fba5fca50..834c15f58 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.13.0", + "mongoose": "^8.13.2", "nanoid": "5.1.5", "nconf": "^0.12.1", "react": "^18.3.1", From 518bc7030d73067b59032426962def95afa73595 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:51:04 +0000 Subject: [PATCH 301/393] Bump eslint from 9.23.0 to 9.24.0 Bumps [eslint](https://github.com/eslint/eslint) from 9.23.0 to 9.24.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.23.0...v9.24.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 9.24.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 183b68410..e3caa64b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.23.0", + "eslint": "^9.24.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^16.0.0", @@ -1852,9 +1852,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", - "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1927,9 +1927,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", - "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", + "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", "dev": true, "license": "MIT", "engines": { @@ -5687,19 +5687,19 @@ "license": "MIT" }, "node_modules/eslint": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", - "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", + "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.2", + "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.23.0", + "@eslint/js": "9.24.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", diff --git a/package.json b/package.json index 834c15f58..9589576a5 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.23.0", + "eslint": "^9.24.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^16.0.0", From 512eedfc3986ed2f03a24ffe6c5e4745c5883bec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:51:04 +0000 Subject: [PATCH 302/393] Bump stylelint from 16.17.0 to 16.18.0 Bumps [stylelint](https://github.com/stylelint/stylelint) from 16.17.0 to 16.18.0. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/16.17.0...16.18.0) --- updated-dependencies: - dependency-name: stylelint dependency-version: 16.18.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 183b68410..4e3b46355 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.17.0", + "stylelint": "^16.18.0", "stylelint-config-recess-order": "^6.0.0", "stylelint-config-recommended": "^15.0.0", "supertest": "^7.1.0" @@ -13135,9 +13135,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.17.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.17.0.tgz", - "integrity": "sha512-I9OwVIWRMqVm2Br5iTbrfSqGRPWQUlvm6oXO1xZuYYu0Gpduy67N8wXOZv15p6E/JdlZiAtQaIoLKZEWk5hrjw==", + "version": "16.18.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.18.0.tgz", + "integrity": "sha512-OXb68qzesv7J70BSbFwfK3yTVLEVXiQ/ro6wUE4UrSbKCMjLLA02S8Qq3LC01DxKyVjk7z8xh35aB4JzO3/sNA==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index 834c15f58..4694e6ae8 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.17.0", + "stylelint": "^16.18.0", "stylelint-config-recess-order": "^6.0.0", "stylelint-config-recommended": "^15.0.0", "supertest": "^7.1.0" From b461ac0a683d1b3ff0a647ee7b181597baae3096 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:55:07 +0000 Subject: [PATCH 303/393] Bump react-router from 7.4.0 to 7.5.0 Bumps [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) from 7.4.0 to 7.5.0. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router@7.5.0/packages/react-router) --- updated-dependencies: - dependency-name: react-router dependency-version: 7.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3caa64b9..429262ac7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", - "react-router": "^7.4.0", + "react-router": "^7.5.0", "romans": "^3.0.0", "sanitize-filename": "1.6.3", "superagent": "^10.2.0", @@ -11743,9 +11743,9 @@ "license": "MIT" }, "node_modules/react-router": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.4.0.tgz", - "integrity": "sha512-Y2g5ObjkvX3VFeVt+0CIPuYd9PpgqCslG7ASSIdN73LwA1nNWzcMLaoMRJfP3prZFI92svxFwbn7XkLJ+UPQ6A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.0.tgz", + "integrity": "sha512-estOHrRlDMKdlQa6Mj32gIks4J+AxNsYoE0DbTTxiMy2mPzZuWSDU+N85/r1IlNR7kGfznF3VCUlvc5IUO+B9g==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", diff --git a/package.json b/package.json index 9589576a5..976ebcc6c 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", - "react-router": "^7.4.0", + "react-router": "^7.5.0", "romans": "^3.0.0", "sanitize-filename": "1.6.3", "superagent": "^10.2.0", From 075fdb194ecec97c7ebab8dcfd31f8e9812e50bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 18:41:53 +0000 Subject: [PATCH 304/393] Bump stylelint-config-recommended from 15.0.0 to 16.0.0 Bumps [stylelint-config-recommended](https://github.com/stylelint/stylelint-config-recommended) from 15.0.0 to 16.0.0. - [Release notes](https://github.com/stylelint/stylelint-config-recommended/releases) - [Changelog](https://github.com/stylelint/stylelint-config-recommended/blob/main/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint-config-recommended/compare/15.0.0...16.0.0) --- updated-dependencies: - dependency-name: stylelint-config-recommended dependency-version: 16.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 ++++++----- package.json | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06923181b..eb5ceec82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,7 @@ "postcss-less": "^6.0.0", "stylelint": "^16.18.0", "stylelint-config-recess-order": "^6.0.0", - "stylelint-config-recommended": "^15.0.0", + "stylelint-config-recommended": "^16.0.0", "supertest": "^7.1.0" }, "engines": { @@ -13210,9 +13210,9 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-15.0.0.tgz", - "integrity": "sha512-9LejMFsat7L+NXttdHdTq94byn25TD+82bzGRiV1Pgasl99pWnwipXS5DguTpp3nP1XjvLXVnEJIuYBfsRjRkA==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-16.0.0.tgz", + "integrity": "sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==", "dev": true, "funding": [ { @@ -13224,11 +13224,12 @@ "url": "https://github.com/sponsors/stylelint" } ], + "license": "MIT", "engines": { "node": ">=18.12.0" }, "peerDependencies": { - "stylelint": "^16.13.0" + "stylelint": "^16.16.0" } }, "node_modules/stylelint-order": { diff --git a/package.json b/package.json index 6be967070..29d9cec56 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "postcss-less": "^6.0.0", "stylelint": "^16.18.0", "stylelint-config-recess-order": "^6.0.0", - "stylelint-config-recommended": "^15.0.0", + "stylelint-config-recommended": "^16.0.0", "supertest": "^7.1.0" } } From 0be5c6c57673b88a6de00fa5c8d7c3eb41845155 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 20:57:29 +0000 Subject: [PATCH 305/393] Bump body-parser from 1.20.3 to 2.2.0 Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.20.3 to 2.2.0. - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.20.3...v2.2.0) --- updated-dependencies: - dependency-name: body-parser dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 195 ++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 138 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81cb9c6c0..8828ff7c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^11.0.0", - "body-parser": "^1.20.2", + "body-parser": "^2.2.0", "classnames": "^2.5.1", "codemirror": "^5.65.6", "cookie-parser": "^1.4.7", @@ -3885,42 +3885,83 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" + "node_modules/body-parser/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/body-parser/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -5100,9 +5141,10 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -6201,6 +6243,30 @@ "serve-static": "^1.16.2" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/express/node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", @@ -6218,12 +6284,39 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -7304,12 +7397,12 @@ } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" @@ -11703,14 +11796,14 @@ } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", - "iconv-lite": "0.4.24", + "iconv-lite": "0.6.3", "unpipe": "1.0.0" }, "engines": { @@ -14749,20 +14842,6 @@ "node": ">=18" } }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/whatwg-mimetype": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", diff --git a/package.json b/package.json index be15f22ad..171434945 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^11.0.0", - "body-parser": "^1.20.2", + "body-parser": "^2.2.0", "classnames": "^2.5.1", "codemirror": "^5.65.6", "cookie-parser": "^1.4.7", From 0dbbc469e1d8316c90744414b42c3797a47fd568 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 21:12:15 +0000 Subject: [PATCH 306/393] Bump express from 4.21.2 to 5.1.0 Bumps [express](https://github.com/expressjs/express) from 4.21.2 to 5.1.0. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.21.2...v5.1.0) --- updated-dependencies: - dependency-name: express dependency-version: 5.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 420 ++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 203 insertions(+), 219 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8828ff7c8..9dd4a93c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.3", "expr-eval": "^2.0.2", - "express": "^4.21.2", + "express": "^5.1.0", "express-async-handler": "^1.2.0", "express-static-gzip": "2.2.0", "fs-extra": "11.3.0", @@ -3116,13 +3116,34 @@ } }, "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" }, "engines": { "node": ">= 0.6" @@ -3313,12 +3334,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, "node_modules/array-includes": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", @@ -3904,65 +3919,6 @@ "node": ">=18" } }, - "node_modules/body-parser/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/body-parser/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4679,9 +4635,9 @@ "license": "MIT" }, "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -6183,45 +6139,41 @@ "license": "MIT" }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "license": "MIT", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 18" }, "funding": { "type": "opencollective", @@ -6243,78 +6195,80 @@ "serve-static": "^1.16.2" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "node_modules/express/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=6.6.0" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "node_modules/express/node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/express/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", "license": "MIT", "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "mime-db": "^1.54.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "node_modules/express/node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 18" + } + }, + "node_modules/express/node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" } }, "node_modules/extend": { @@ -6504,35 +6458,22 @@ } }, "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -7925,6 +7866,12 @@ "license": "MIT", "peer": true }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -10113,12 +10060,12 @@ "dev": true }, "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/memory-pager": { @@ -10141,9 +10088,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -10750,9 +10701,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -11289,10 +11240,13 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } }, "node_modules/path-type": { "version": "4.0.0", @@ -11725,11 +11679,12 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -12239,6 +12194,22 @@ "integrity": "sha512-7DDsAfhtpRr/ZFQXiHDrC3Pe00agcAsFiNt5nNx4ZAQlsc6yJG0mvXA5WAvO8YZyOg349twm2GYhHLw7rCXAzw==", "license": "MIT" }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", @@ -14005,13 +13976,35 @@ } }, "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" }, "engines": { "node": ">= 0.6" @@ -14409,15 +14402,6 @@ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", "license": "ISC" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", diff --git a/package.json b/package.json index 171434945..b630070cb 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.3", "expr-eval": "^2.0.2", - "express": "^4.21.2", + "express": "^5.1.0", "express-async-handler": "^1.2.0", "express-static-gzip": "2.2.0", "fs-extra": "11.3.0", From be2f1786b59a23621e6c1058d1fb8fa96662298f Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 09:59:34 +1200 Subject: [PATCH 307/393] Add authors to locked brew error message --- client/homebrew/pages/errorPage/errors/errorIndex.js | 4 +++- server/homebrew.api.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js index 2f0d4599b..0315c021c 100644 --- a/client/homebrew/pages/errorPage/errors/errorIndex.js +++ b/client/homebrew/pages/errorPage/errors/errorIndex.js @@ -194,7 +194,9 @@ const errorIndex = (props)=>{ **Brew ID:** ${props.brew.brewId} - **Brew Title:** ${escape(props.brew.brewTitle)}`, + **Brew Title:** ${escape(props.brew.brewTitle)} + + **Brew Authors:** ${escape(props.brew.brewAuthors.length ? props.brew.brewAuthors.join(',') : 'No listed authors')}`, // ####### Admin page error ####### '52' : dedent` diff --git a/server/homebrew.api.js b/server/homebrew.api.js index c59c6c4d7..3c7566af7 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -119,7 +119,7 @@ const api = { } if(stub?.lock && accessType === 'share') { - throw { HBErrorCode: '51', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title }; + throw { HBErrorCode: '51', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title, brewAuthors: stub.authors }; } // If there's a google id, get it if requesting the full brew or if no stub found yet From e3de7b9f012770719aaf9933d2bcab1cfda540e6 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 10:17:35 +1200 Subject: [PATCH 308/393] Tweak lock styling --- client/admin/lockTools/lockTools.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/admin/lockTools/lockTools.less b/client/admin/lockTools/lockTools.less index f6e7ea9dd..94a27ac8e 100644 --- a/client/admin/lockTools/lockTools.less +++ b/client/admin/lockTools/lockTools.less @@ -8,7 +8,7 @@ label { display : inline-block; width : 100%; - line-height : 1.5em; + line-height : 2.25em; text-align : right; input { float : right; From dc724492efbf6debebbf6ae3584846fdf1c3c9b6 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 10:26:10 +1200 Subject: [PATCH 309/393] Prevent BrewUtils from loading when it is not the current Admin tab --- client/admin/admin.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index f59162e1d..29973d221 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -8,10 +8,10 @@ import LockTools from './lockTools/lockTools.jsx'; const tabGroups = ['brew', 'notifications', 'authors', 'locks']; const Admin = ()=>{ - const [currentTab, setCurrentTab] = useState('brew'); + const [currentTab, setCurrentTab] = useState(''); useEffect(()=>{ - setCurrentTab(localStorage.getItem('hbAdminTab')); + setCurrentTab(localStorage.getItem('hbAdminTab') || 'brew'); }, []); useEffect(()=>{ From b19d05fbf78d08955ccfa3a82ed79918e2303ad7 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 10:41:58 +1200 Subject: [PATCH 310/393] Remove commented out console.logs --- server/admin.api.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 8942a4675..bced73c83 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -223,7 +223,6 @@ router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; if(brew.lock && !overwrite) { - // console.log('ALREADY LOCKED'); throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; } @@ -235,7 +234,6 @@ router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ throw { name: 'Already Locked', message: 'Unable to set lock', shareId: req.params.id, status: 500, HBErrorCode: '62', error }; }); - // console.log(`Lock applied to brew ID ${brew.shareId} - ${brew.title}`); return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); })); @@ -260,9 +258,6 @@ router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ throw { name: 'Cannot Unlock', message: 'Unable to clear lock', shareId: req.params.id, status: 500, HBErrorCode: '65', error }; }); - // console.log(`Lock removed from brew ID ${brew.shareId} - ${brew.title}`); - - return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` }); })); @@ -303,7 +298,6 @@ router.put('/admin/lock/review/request/:id', asyncHandler(async (req, res)=>{ if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; }; if(brew.lock.reviewRequested){ - // console.log(`Review already requested for brew ${brew.shareId} - ${brew.title}`); throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' }; }; @@ -315,7 +309,6 @@ router.put('/admin/lock/review/request/:id', asyncHandler(async (req, res)=>{ throw { name: 'Can Not Set Review Request', message: `Unable to set request for review on brew ID ${req.params.id}`, code: 500, HBErrorCode: '69', error }; }); - // console.log(`Review requested on brew ${brew.shareId} - ${brew.title}`); return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); })); @@ -338,7 +331,6 @@ router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, throw { name: 'Can Not Clear Review Request', message: `Unable to remove request for review on brew ID ${req.params.id}`, HBErrorCode: '72', error }; }); - // console.log(`Review request removed on brew ID ${brew.shareId} - ${brew.title}`); return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); })); From bd68b9c0cb376f83e56960b5c60ac2de5fd9e0e9 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 10:48:02 +1200 Subject: [PATCH 311/393] Remove unnecessary variable --- server/admin.api.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index bced73c83..8327dfd49 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -209,9 +209,6 @@ router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ const lock = req.body; - const overwrite = lock.overwrite || false; - lock.overwrite = undefined; - lock.applied = new Date; const filter = { @@ -222,10 +219,12 @@ router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; - if(brew.lock && !overwrite) { + if(brew.lock && !lock.overwrite) { throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; } + lock.overwrite = undefined; + brew.lock = lock; brew.markModified('lock'); From 95f44f446036f9f182d9d63e315d660d223e3f98 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 11:04:57 +1200 Subject: [PATCH 312/393] Revert unnecessary change in app.js --- server/app.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/app.js b/server/app.js index fc0954efd..b7d990baf 100644 --- a/server/app.js +++ b/server/app.js @@ -2,11 +2,10 @@ // Set working directory to project root import { dirname } from 'path'; import { fileURLToPath } from 'url'; +import packageJSON from './../package.json' with { type: 'json' }; const __dirname = dirname(fileURLToPath(import.meta.url)); process.chdir(`${__dirname}/..`); - -import packageJSON from '../package.json' with { type: 'json' }; const version = packageJSON.version; import _ from 'lodash'; From 5e7e314baacd437685ae8b31050da8ac288b7dd9 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 11:38:57 +1200 Subject: [PATCH 313/393] Update fields returned for Lock and Review Tables --- server/admin.api.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/admin.api.js b/server/admin.api.js index 8327dfd49..ee859a3e0 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -191,7 +191,9 @@ router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ { $project : { shareId : 1, - title : 1 + editId : 1, + title : 1, + lock : 1 } } ]; @@ -271,7 +273,9 @@ router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ { $project : { shareId : 1, - title : 1 + editId : 1, + title : 1, + lock : 1 } } ]; From c6cd6e9864fb1911eea84d2602ff52cefb008bf9 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 8 Apr 2025 20:29:32 -0500 Subject: [PATCH 314/393] A little bit of cleanup and structure flattening Fixes failed tests. --- server/homebrew.api.js | 3 ++- shared/helpers.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 84e338ef4..8a98d50a8 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -177,7 +177,8 @@ const api = { `${text}`; } const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); - metadata.snippets = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false); + const snippetsArray = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false).snippets; + metadata.snippets = snippetsArray.length > 0 ? snippetsArray : undefined; text = `\`\`\`metadata\n` + `${yaml.dump(metadata)}\n` + `\`\`\`\n\n` + diff --git a/shared/helpers.js b/shared/helpers.js index e4dc9eba8..0ca681dfb 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -76,7 +76,8 @@ const yamlSnippetsToText = (yamlObj)=>{ if(typeof yamlObj == 'string') return yamlObj; let snippetsText = ''; - for (let snippet of yamlObj.snippets) { + + for (let snippet of yamlObj) { for (let subSnippet of snippet.subsnippets) { snippetsText = `${snippetsText}\\snippet ${subSnippet.name}\n${subSnippet.gen || ''}\n`; } @@ -91,7 +92,7 @@ const splitTextStyleAndMetadata = (brew)=>{ const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); - brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets); + brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets || ''); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { From da4f6c9307d8e2853713529b7e6c5c729372de1e Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 17:54:51 +1200 Subject: [PATCH 315/393] Load lock details to the Lock Brew form --- client/admin/lockTools/lockTools.jsx | 50 +++++++++++++++++++--------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index c528fb13d..c639adaca 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -1,9 +1,8 @@ -/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/ +/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/ require('./lockTools.less'); const React = require('react'); const createClass = require('create-react-class'); -// const request = require('superagent'); import request from '../../homebrew/utils/request-middleware.js'; const LockTools = createClass({ @@ -29,17 +28,23 @@ const LockTools = createClass({ } }, + updateLockData : function(lock){ + this.setState({ + lock : lock + }); + }, + render : function() { return

Lock Count

Number of brews currently locked: {this.state.reviewCount}


- +
- +
- +
@@ -55,12 +60,12 @@ const LockBrew = createClass({ getInitialState : function() { // Default values return { - brewId : '', - code : 455, - editMessage : '', - shareMessage : 'This Brew has been locked.', + brewId : this.props.lock?.shareId || '', + code : this.props.lock?.code || 455, + editMessage : this.props.lock?.editMessage || '', + shareMessage : this.props.lock?.shareMessage || 'This Brew has been locked.', result : {}, - overwrite : false + overwrite : false, }; }, @@ -186,7 +191,8 @@ const LockTable = createClass({ text : '', fetchURL : '/api/locks', resultName : '', - propertyNames : ['shareId'] + propertyNames : ['shareId'], + loadBrew : ()=>{} }; }, @@ -198,7 +204,9 @@ const LockTable = createClass({ }; }, - clickFn(){ + lockKey : React.createRef(0), + + clickFn : function (){ this.setState({ searching: true, error: null }); request.get(this.props.fetchURL) @@ -209,6 +217,18 @@ const LockTable = createClass({ }); }, + updateBrewLockData : function (lockData){ + this.lockKey.current++; + const brewData = { + key : this.lockKey.current, + shareId : lockData.shareId, + code : lockData.lock.code, + editMessage : lockData.lock.editMessage, + shareMessage : lockData.lock.shareMessage + }; + this.props.loadBrew(brewData); + }, + render : function () { return <>
@@ -229,7 +249,7 @@ const LockTable = createClass({ return
; })} - + @@ -240,8 +260,8 @@ const LockTable = createClass({ {result[name].toString()} ; })} - - + + ; })} From 04defb97b09e99def4a56e35b1f154cf71e89b92 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 9 Apr 2025 20:10:48 +1200 Subject: [PATCH 316/393] Tweak styling for Overwrite checkbox --- client/admin/lockTools/lockTools.jsx | 2 +- client/admin/lockTools/lockTools.less | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/client/admin/lockTools/lockTools.jsx b/client/admin/lockTools/lockTools.jsx index c639adaca..9a28d330f 100644 --- a/client/admin/lockTools/lockTools.jsx +++ b/client/admin/lockTools/lockTools.jsx @@ -143,7 +143,7 @@ const LockBrew = createClass({ {this.renderInput('shareMessage')}
-
{name}clipviewload
{navigator.clipboard.writeText(result.shareId.toString());}}>{navigator.clipboard.writeText(result.shareId.toString());}}>{this.updateBrewLockData(result);}}>