Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Answer post UI #84

Draft
wants to merge 64 commits into
base: f24
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
aeb83cb
add deadline
github-classroom[bot] Sep 9, 2024
62a393a
Test changing README to ensure branch working
philliparaujo Sep 16, 2024
c62ad7a
added spaces to readme test change
heyanuja Sep 16, 2024
9fd93e1
reduce code depth
KesterTan Sep 18, 2024
56cce13
Adding changes from project 1
philliparaujo Sep 19, 2024
b348683
New custom theme, added search bar in category page
philliparaujo Sep 19, 2024
1698047
Added listeners to new search components
philliparaujo Sep 20, 2024
3bc3ede
Renamed theme
philliparaujo Sep 22, 2024
634b9a3
Removed old theme name
philliparaujo Sep 22, 2024
a2dbab8
Updated README to use theme
philliparaujo Sep 22, 2024
e20be27
npm run lint
philliparaujo Sep 22, 2024
b6385c3
Removing test README
philliparaujo Sep 22, 2024
a81893e
Merge pull request #15 from CMU-313/search-bar
philliparaujo Sep 22, 2024
db8f3f9
Merging changes
philliparaujo Sep 23, 2024
59843e2
npm run lint
philliparaujo Sep 23, 2024
c0c83be
Merge pull request #16 from CMU-313/phillip-project1
philliparaujo Sep 23, 2024
e690920
Merge pull request #14 from CMU-313/kester-project1
KesterTan Sep 23, 2024
f735317
Adding answered field to post objects
katcday Sep 24, 2024
57eec9c
Adding API to toggle if a post is answered or not
katcday Sep 24, 2024
cd7b505
Adding unit testing for the answering API
katcday Sep 24, 2024
53ac399
Fixing lint errors
katcday Sep 24, 2024
5185f9d
Added project 1 Changes
katcday Sep 24, 2024
7826762
frontend and functional backend for verifying message
KesterTan Sep 24, 2024
95c1bd5
changed theme to reflect post schema
KesterTan Sep 24, 2024
653c107
added openapi documentation
KesterTan Sep 24, 2024
5bca90a
Adding meaningful message to console log in toggleAnswered event
katcday Sep 25, 2024
e0e965d
Merge pull request #18 from CMU-313/camille-project-1
katcday Sep 25, 2024
8f79466
project 1 changes
heyanuja Sep 25, 2024
64d9e6f
Merge pull request #17 from CMU-313/answered-field
katcday Sep 25, 2024
7512a1d
search algorithm to sort through categories
heyanuja Sep 25, 2024
f126389
Merge branch 'f24' into searchalg
heyanuja Sep 25, 2024
2a447be
Merge branch 'f24' into verify-message
KesterTan Sep 25, 2024
7c993a8
Merge branch 'f24' into anuja-project1
heyanuja Sep 25, 2024
8fde2f4
addresses lints from git merge
KesterTan Sep 25, 2024
2a6bbcd
Merge pull request #26 from CMU-313/anuja-project1
heyanuja Sep 25, 2024
9405093
Merge branch 'f24' into searchalg
heyanuja Sep 25, 2024
ba5e266
Merge pull request #25 from CMU-313/searchalg
heyanuja Sep 25, 2024
0de0dac
Merge pull request #20 from CMU-313/verify-message
KesterTan Sep 25, 2024
cd495fb
passing linter, removed trailing spaces etc
heyanuja Sep 29, 2024
95ca18f
Add or update the Azure App Service build and deployment workflow config
yerimsong Oct 6, 2024
1872b1a
reverting changes from search bar to experiment on test passing
heyanuja Oct 7, 2024
93c0479
lint space fix
heyanuja Oct 7, 2024
e33ee67
Merge pull request #27 from CMU-313/searchalgfixes
philliparaujo Oct 7, 2024
88a5ed9
Started adding post updating on search query
philliparaujo Oct 8, 2024
9dce96b
Outputting topics without using query :)
philliparaujo Oct 8, 2024
ebe4bb1
Searching now works mostly
philliparaujo Oct 8, 2024
f70f7a6
Final search for now
philliparaujo Oct 8, 2024
d4a2d61
npm run lint
philliparaujo Oct 8, 2024
a205c22
Merge pull request #29 from CMU-313/search-combine
heyanuja Oct 9, 2024
a351cde
Added UserGuide template and filled in my information
philliparaujo Oct 10, 2024
e1705fb
unverify api tests
KesterTan Oct 10, 2024
bf98345
Merge pull request #30 from CMU-313/user-guide
philliparaujo Oct 10, 2024
72ab338
Merge pull request #32 from CMU-313/verified-tests
KesterTan Oct 10, 2024
75f0ec8
added user guide, permissions feature
KesterTan Oct 10, 2024
bd9ad77
removed dump file
KesterTan Oct 10, 2024
27250fe
added newline for posttools
KesterTan Oct 10, 2024
df3ac08
Merge pull request #34 from CMU-313/unverify-message
KesterTan Oct 10, 2024
6aedc3c
Merge branch 'CMU-313:f24' into answer-post-ui
katcday Oct 10, 2024
a9ac00c
Added Answer Question Button
katcday Oct 11, 2024
9b7f092
Added API to mark a topic as answered
katcday Oct 11, 2024
0e274c1
Adding Frontend Answer Functionality
katcday Oct 11, 2024
c044d16
Fixing Lint Issue
katcday Oct 11, 2024
49897d4
Fixing lint error
katcday Oct 11, 2024
2216c0a
Fixed unanswered test case
katcday Oct 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/f24_nodebb-yerim-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js app to Azure Web App - nodebb-yerim-test

on:
push:
branches:
- f24
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Node.js version
uses: actions/setup-node@v3
with:
node-version: '20.x'

- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm run test --if-present

- name: Zip artifact for deployment
run: zip release.zip ./* -r

- name: Upload artifact for deployment job
uses: actions/upload-artifact@v3
with:
name: node-app
path: release.zip

deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

steps:
- name: Download artifact from build job
uses: actions/download-artifact@v3
with:
name: node-app

- name: Unzip artifact for deployment
run: unzip release.zip

- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'nodebb-yerim-test'
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_7987CBBA808B4A44A7974B909CC34E48 }}
package: .
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/ithVU1OO)
# ![NodeBB](public/images/sm-card.png)

[![Workflow](https://github.com/CMU-313/NodeBB/actions/workflows/test.yaml/badge.svg)](https://github.com/CMU-313/NodeBB/actions/workflows/test.yaml)
Expand Down Expand Up @@ -81,3 +82,31 @@ Interested in a sublicense agreement for use of NodeBB in a non-free/restrictive
* Unofficial IRC community – channel `#nodebb` on Libera.chat
* [Follow us on Twitter](http://www.twitter.com/NodeBB/ "NodeBB Twitter")
* [Like us on Facebook](http://www.facebook.com/NodeBB/ "NodeBB Facebook")

=======
## Team Members
Kester Tan
Anuja Uppuluri
Phillip Araujo
Camille Day

## Using nodebb-theme-slackers
We have a custom theme called `nodebb-theme-slackers` to incorporate new front-end UI features into our project.

Here is how to set it up:
#### Add it to node_modules
1. Make sure the directory `nodebb-theme-slackers` is located in the root directory (along with `public`, `src` for example)
2. Navigate to `nodebb-theme-slackers` (run `cd nodebb-theme-slackers/` from the root directory)
3. Run `npm link`
4. Navigate back to the root directory (run `cd ..`)
5. Run `npm link nodebb-theme-slackers`

#### Use the new custom theme
1. After making sure NodeBB is not running (run `./nodebb stop`), run `./nodebb reset -t nodebb-theme-slackers`. Now our new custom theme will be used when NodeBB is relaunched.
2. Make sure `redis-server` is running so that we can launch our project.
3. Launch NodeBB in your preferred way:
```
./nodebb stop && ./nodebb reset -t nodebb-theme-slackers && ./nodebb build && ./nodebb start
```
4. Go to http://localhost:4567/ to see the new theme in action!

49 changes: 49 additions & 0 deletions UserGuide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# User Guide
In this project, we added two new features:

1. A search bar that can search for topics within a category.
2. A system to tag questions as answered/closed and tag answers as verified by a teacher (similar to Piazza)

The front-end components of these new features are implemented using our custom theme: `nodebb-theme-slackers`.

## Using our custom theme
Here is how to set up and use our custom theme.

#### Add it to node_modules
1. Make sure the directory `nodebb-theme-slackers` is located in the root directory (along with `public`, `src` for example)
2. Navigate to `nodebb-theme-slackers` (run `cd nodebb-theme-slackers/` from the root directory)
3. Run `npm link`
4. Navigate back to the root directory (run `cd ..`)
5. Run `npm link nodebb-theme-slackers`

#### Use the new custom theme
1. After making sure NodeBB is not running (run `./nodebb stop`), run `./nodebb reset -t nodebb-theme-slackers`. Now our new custom theme will be used when NodeBB is relaunched.
2. Make sure `redis-server` is running so that we can launch our project.
3. Launch NodeBB in your preferred way:
```
./nodebb reset -t nodebb-theme-slackers && ./nodebb build && ./nodebb start
```
4. Go to http://localhost:4567/ to see the new theme in action!

## Search bar
### How to use
Our search bar component is found under any category. After launching the local NodeBB app, **navigate to a category** (such as General Discussion or Announcements).

If you set up the theme properly, you should see a search bar in between the title and the tags/filters. Simply click on this search bar and type a search query. If there are existing topics within this category that contain that search query, they will be displayed. You can still click on any of these topics after being filtered and it will properly navigate you to within the topic.

### Automated testing
TODO (include file location of automated tests)

## Tags
### How to use
TODO
### Automated testing
TODO (include file location of automated tests)


## Verify Message
### How to use
Our verify message component is found under the dropdown beside a post. Notice how there is a cross beside the post/comment. This indicates that the post/comment is not yet verified. If you are an administrator or moderator, you can click verify message to verify the post/comment. Refresh the page to notice that the cross has now been changed to a tick.

### Automated testing
Automated tests for permissions and for backend APIs for verify/unverify message can be found in `tests/posts.js`.
1 change: 1 addition & 0 deletions nodebb-theme-slackers/languages/harmony.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
29 changes: 29 additions & 0 deletions nodebb-theme-slackers/lib/controllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

const Controllers = module.exports;

const accountHelpers = require.main.require('./src/controllers/accounts/helpers');
const helpers = require.main.require('./src/controllers/helpers');

Controllers.renderAdminPage = (req, res) => {
res.render('admin/plugins/harmony', {
title: '[[themes/harmony:theme-name]]',
});
};

Controllers.renderThemeSettings = async (req, res, next) => {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
const lib = require('../library');
userData.theme = await lib.loadThemeConfig(userData.uid);

userData.title = '[[themes/harmony:settings.title]]';
userData.breadcrumbs = helpers.buildBreadcrumbs([
{ text: userData.username, url: `/user/${userData.userslug}` },
{ text: '[[themes/harmony:settings.title]]' },
]);

res.render('account/theme', userData);
};
190 changes: 190 additions & 0 deletions nodebb-theme-slackers/library.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
'use strict';

const nconf = require.main.require('nconf');
const meta = require.main.require('./src/meta');
const _ = require.main.require('lodash');
const user = require.main.require('./src/user');

const controllers = require('./lib/controllers');

const library = module.exports;

const defaults = {
enableQuickReply: 'on',
enableBreadcrumbs: 'on',
centerHeaderElements: 'off',
mobileTopicTeasers: 'off',
stickyToolbar: 'on',
autohideBottombar: 'on',
openSidebars: 'off',
chatModals: 'off',
};

library.init = async function (params) {
const { router, middleware } = params;
const routeHelpers = require.main.require('./src/routes/helpers');

routeHelpers.setupAdminPageRoute(router, '/admin/plugins/harmony', [], controllers.renderAdminPage);

routeHelpers.setupPageRoute(router, '/user/:userslug/theme', [
middleware.exposeUid,
middleware.ensureLoggedIn,
middleware.canViewUsers,
middleware.checkAccountPermissions,
], controllers.renderThemeSettings);

if (nconf.get('isPrimary') && process.env.NODE_ENV === 'production') {
setTimeout(buildSkins, 0);
}
};

async function buildSkins() {
try {
const plugins = require.main.require('./src/plugins');
await plugins.prepareForBuild(['client side styles']);
for (const skin of meta.css.supportedSkins) {
// eslint-disable-next-line no-await-in-loop
await meta.css.buildBundle(`client-${skin}`, true);
}
require.main.require('./src/meta/minifier').killAll();
} catch (err) {
console.error(err.stack);
}
}

library.addAdminNavigation = async function (header) {
header.plugins.push({
route: '/plugins/harmony',
icon: 'fa-paint-brush',
name: '[[themes/harmony:theme-name]]',
});
return header;
};

library.addProfileItem = async (data) => {
data.links.push({
id: 'theme',
route: 'theme',
icon: 'fa-paint-brush',
name: '[[themes/harmony:settings.title]]',
visibility: {
self: true,
other: false,
moderator: false,
globalMod: false,
admin: false,
},
});

return data;
};

library.defineWidgetAreas = async function (areas) {
const locations = ['header', 'sidebar', 'footer'];
const templates = [
'categories.tpl', 'category.tpl', 'topic.tpl', 'users.tpl',
'unread.tpl', 'recent.tpl', 'popular.tpl', 'top.tpl', 'tags.tpl', 'tag.tpl',
'login.tpl', 'register.tpl',
];
function capitalizeFirst(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
templates.forEach((template) => {
locations.forEach((location) => {
areas.push({
name: `${capitalizeFirst(template.split('.')[0])} ${capitalizeFirst(location)}`,
template: template,
location: location,
});
});
});

areas = areas.concat([
{
name: 'Main post header',
template: 'topic.tpl',
location: 'mainpost-header',
},
{
name: 'Main post footer',
template: 'topic.tpl',
location: 'mainpost-footer',
},
{
name: 'Sidebar Footer',
template: 'global',
location: 'sidebar-footer',
},
{
name: 'Brand Header',
template: 'global',
location: 'brand-header',
},
{
name: 'About me (before)',
template: 'account/profile.tpl',
location: 'profile-aboutme-before',
},
{
name: 'About me (after)',
template: 'account/profile.tpl',
location: 'profile-aboutme-after',
},
]);

return areas;
};

library.loadThemeConfig = async function (uid) {
const [themeConfig, userConfig] = await Promise.all([
meta.settings.get('harmony'),
user.getSettings(uid),
]);

const config = { ...defaults, ...themeConfig, ...(_.pick(userConfig, Object.keys(defaults))) };
config.enableQuickReply = config.enableQuickReply === 'on';
config.enableBreadcrumbs = config.enableBreadcrumbs === 'on';
config.centerHeaderElements = config.centerHeaderElements === 'on';
config.mobileTopicTeasers = config.mobileTopicTeasers === 'on';
config.stickyToolbar = config.stickyToolbar === 'on';
config.autohideBottombar = config.autohideBottombar === 'on';
config.openSidebars = config.openSidebars === 'on';
config.chatModals = config.chatModals === 'on';
return config;
};

library.getThemeConfig = async function (config) {
config.theme = await library.loadThemeConfig(config.uid);
config.openDraftsOnPageLoad = false;
return config;
};

library.getAdminSettings = async function (hookData) {
if (hookData.plugin === 'harmony') {
hookData.values = {
...defaults,
...hookData.values,
};
}
return hookData;
};

library.saveUserSettings = async function (hookData) {
Object.keys(defaults).forEach((key) => {
if (hookData.data.hasOwnProperty(key)) {
hookData.settings[key] = hookData.data[key] || undefined;
}
});
return hookData;
};

library.filterMiddlewareRenderHeader = async function (hookData) {
hookData.templateData.bootswatchSkinOptions = await meta.css.getSkinSwitcherOptions(hookData.req.uid);
return hookData;
};

library.filterTeasersConfigureStripTags = function (hookData) {
// teasers have a stretched-link to go to last post, the anchors in them are not clickable
hookData.tags.push('a');
return hookData;
};
Loading