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

Add CritiqueBrainz as Oauth Service #865

Merged
merged 39 commits into from Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
11055d8
chore(sql): Add external_service_oauth table
anshg1214 Jul 19, 2022
e348d42
feat: Add functions for connecting CB
anshg1214 Jul 19, 2022
1fede20
feat: Add routes and frontend components for external-service page
anshg1214 Jul 19, 2022
0b18efb
feat: Add propTypes
anshg1214 Jul 19, 2022
35eab07
feat: Add error handling for external services
anshg1214 Jul 20, 2022
cb3757f
feat: Add some comments
anshg1214 Jul 20, 2022
4ecaa13
chore: Add react-tooltip and i18n-iso-languages
anshg1214 Jul 28, 2022
41ae4ef
feat: Add function to count words for reviews
anshg1214 Jul 28, 2022
22381f5
fix: use post route for refreshing token
anshg1214 Jul 28, 2022
bc1b28e
feat: Add routes and functions to post CB Reviews
anshg1214 Jul 28, 2022
6728256
feat: Changed Error type
anshg1214 Jul 28, 2022
c123dcb
feat: Add CB Review Modal
anshg1214 Jul 28, 2022
fae5b10
feat: Show avg ratings returned by API
anshg1214 Aug 1, 2022
562f523
feat: Allow reviewing authors
anshg1214 Aug 3, 2022
de02547
feat: Allow reviewing works
anshg1214 Aug 3, 2022
d8a547a
fix: typo
anshg1214 Aug 4, 2022
c5bf688
feat: Handle CB modal if user is not authenticated
anshg1214 Aug 4, 2022
8778b17
feat: Allow reviewing series
anshg1214 Aug 5, 2022
73b6187
chore: Update bookbrainz ORM
anshg1214 Aug 5, 2022
6c55025
feat: Add CB config
anshg1214 Aug 7, 2022
eb0c34f
style: Update styling for external services
anshg1214 Aug 7, 2022
74ba5a9
feat: Encapsulate sql queries in a transaction
anshg1214 Aug 7, 2022
6b3423d
feat: Replaced error messages and fixed styling issues
anshg1214 Aug 7, 2022
26c4e62
feat: Use error type for error handling
anshg1214 Aug 7, 2022
0b0fd47
feat: Refresh all reviews when user has posted a review
anshg1214 Aug 7, 2022
38743d0
feat: Use state for updating alert messages
anshg1214 Aug 8, 2022
e758f7f
feat: Add Link to external service page
anshg1214 Aug 8, 2022
dd832e1
feat: Import External Services scss to main file
anshg1214 Aug 12, 2022
e8ca42d
feat: Improve Error Handling
anshg1214 Aug 12, 2022
e473b3a
feat: Don't show modal button for non-reviewable entity
anshg1214 Aug 12, 2022
b0943a8
feat: Encorporate average ratings API changes
anshg1214 Aug 18, 2022
87d7c17
feat: Log only essential information for error
anshg1214 Aug 18, 2022
a469d5c
fix: Display average ratings
anshg1214 Aug 23, 2022
6ce6d17
feat: Add Button disable styles
anshg1214 Aug 25, 2022
8a50462
feat: Refactor Code and add missing link maps
anshg1214 Aug 25, 2022
073c161
feat: Show total number of reviews
anshg1214 Aug 25, 2022
faa2cbc
feat: Show total review count
anshg1214 Aug 25, 2022
7c1fdca
feat: Refactor average ratings
anshg1214 Aug 26, 2022
fe2eaf7
feat: Extract Average ratings to a component
anshg1214 Aug 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/config.json.example
Expand Up @@ -9,6 +9,11 @@
"clientSecret": null,
"callbackURL": "http://localhost:9099/cb"
},
"critiquebrainz": {
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
"clientID": null,
"clientSecret": null,
"redirectURL": "http://localhost:9099/external-service/critiquebrainz/callback"
},
"session": {
"maxAge": 2592000000,
"secret": "Something here!",
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -30,13 +30,14 @@
"browserslist": "> 0.25%, not dead",
"dependencies": {
"@babel/runtime": "^7.17.7",
"@cospired/i18n-iso-languages": "^4.0.0",
"@elastic/elasticsearch": "^5.6.22",
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-brands-svg-icons": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
"@fortawesome/react-fontawesome": "^0.1.11",
"array-move": "^3.0.1",
"bookbrainz-data": "2.14.1",
"bookbrainz-data": "2.15.1",
"chart.js": "^2.9.4",
"chartjs-adapter-date-fns": "^1.0.0",
"classnames": "^2.3.1",
Expand Down Expand Up @@ -75,6 +76,7 @@
"react-simple-star-rating": "^4.0.5",
"react-sortable-hoc": "^2.0.0",
"react-sticky": "^6.0.1",
"react-tooltip": "^4.2.21",
"redis": "^3.1.2",
"redux": "^3.7.2",
"redux-debounce": "^1.0.1",
Expand Down
17 changes: 17 additions & 0 deletions sql/migrations/2022-07-19/up.sql
@@ -0,0 +1,17 @@
CREATE TYPE bookbrainz.external_service_oauth_type AS ENUM (
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
'critiquebrainz'
);

CREATE TABLE bookbrainz.external_service_oauth (
id SERIAL,
editor_id INTEGER NOT NULL,
service bookbrainz.external_service_oauth_type NOT NULL,
access_token TEXT NOT NULL,
refresh_token TEXT,
token_expires TIMESTAMP,
scopes TEXT[]
);

ALTER TABLE bookbrainz.external_service_oauth ADD CONSTRAINT external_service_oauth_editor_id_service UNIQUE (editor_id, service);

ALTER TABLE bookbrainz.external_service_oauth ADD FOREIGN KEY (editor_id) REFERENCES bookbrainz.editor (id);
18 changes: 18 additions & 0 deletions sql/schemas/bookbrainz.sql
Expand Up @@ -16,6 +16,10 @@ CREATE TYPE bookbrainz.entity_type AS ENUM (
'Series'
);

CREATE TYPE bookbrainz.external_service_oauth_type AS ENUM (
'critiquebrainz'
);

CREATE TABLE bookbrainz.editor_type (
id SERIAL PRIMARY KEY,
label VARCHAR(255) NOT NULL CHECK (label <> '')
Expand Down Expand Up @@ -806,6 +810,20 @@ CREATE TABLE bookbrainz.user_collection_collaborator (
ALTER TABLE bookbrainz.user_collection_collaborator ADD FOREIGN KEY (collection_id) REFERENCES bookbrainz.user_collection (id) ON DELETE CASCADE;
ALTER TABLE bookbrainz.user_collection_collaborator ADD FOREIGN KEY (collaborator_id) REFERENCES bookbrainz.editor (id);

CREATE TABLE bookbrainz.external_service_oauth (
id SERIAL,
editor_id INTEGER NOT NULL,
service bookbrainz.external_service_oauth_type NOT NULL,
access_token TEXT NOT NULL,
refresh_token TEXT,
token_expires TIMESTAMP,
scopes TEXT[]
);

ALTER TABLE bookbrainz.external_service_oauth ADD CONSTRAINT external_service_oauth_editor_id_service UNIQUE (editor_id, service);

ALTER TABLE bookbrainz.external_service_oauth ADD FOREIGN KEY (editor_id) REFERENCES bookbrainz.editor (id);

-- Views --

CREATE VIEW bookbrainz.author AS
Expand Down
89 changes: 69 additions & 20 deletions src/client/components/pages/entities/author.js
Expand Up @@ -18,16 +18,19 @@

import * as bootstrap from 'react-bootstrap';
import * as entityHelper from '../../../helpers/entity';
import React, {useCallback} from 'react';

import CBReviewModal from './cbReviewModal';
import EntityAnnotation from './annotation';
import EntityFooter from './footer';
import EntityImage from './image';
import EntityLinks from './links';
import EntityRelatedCollections from './related-collections';
import EntityReviews from './cb-review';
import EntityTitle from './title';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
import React from 'react';
import {Rating} from 'react-simple-star-rating';
import {kebabCase as _kebabCase} from 'lodash';
import {faPlus} from '@fortawesome/free-solid-svg-icons';
import {labelsForAuthor} from '../../../helpers/utils';
Expand All @@ -37,7 +40,7 @@ const {deletedEntityMessage, extractAttribute, getTypeAttribute, getEntityUrl,
ENTITY_TYPE_ICONS, getSortNameOfDefaultAlias, transformISODateForDisplay} = entityHelper;
const {Button, Col, Row} = bootstrap;

function AuthorAttributes({author}) {
function AuthorAttributes({author, averageRating}) {
if (author.deleted) {
return deletedEntityMessage;
}
Expand All @@ -64,6 +67,20 @@ function AuthorAttributes({author}) {
<dl>
<dt>Sort Name</dt>
<dd>{sortNameOfDefaultAlias}</dd>
<dt>Ratings</dt>
<dd>
<Rating
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
allowHalfIcon
readonly
allowHover={false}
className="rating-stars"
fillColor="#46433A"
initialValue={averageRating}
ratingValue={0}
size={20}
stars={5}
/>
</dd>
</dl>
</Col>
<Col lg={3}>
Expand Down Expand Up @@ -103,14 +120,28 @@ function AuthorAttributes({author}) {
}
AuthorAttributes.displayName = 'AuthorAttributes';
AuthorAttributes.propTypes = {
author: PropTypes.object.isRequired
author: PropTypes.object.isRequired,
averageRating: PropTypes.number.isRequired
};


function AuthorDisplayPage({entity, identifierTypes, user}) {
const [showCBReviewModal, setShowCBReviewModal] = React.useState(false);
const handleModalToggle = useCallback(() => {
setShowCBReviewModal(!showCBReviewModal);
}, [showCBReviewModal]);

const urlPrefix = getEntityUrl(entity);
return (
<div>
<CBReviewModal
entityBBID={entity.bbid}
entityName={entity.defaultAlias.name}
entityType={entity.type}
handleModalToggle={handleModalToggle}
showModal={showCBReviewModal}
userId={user?.id}
/>
<Row className="entity-display-background">
<Col className="entity-display-image-box text-center" lg={2}>
<EntityImage
Expand All @@ -120,27 +151,45 @@ function AuthorDisplayPage({entity, identifierTypes, user}) {
/>
</Col>
<Col lg={10}>
<EntityTitle entity={entity}/>
<AuthorAttributes author={entity}/>
<EntityTitle
entity={entity}
handleModalToggle={handleModalToggle}
/>
<AuthorAttributes
author={entity}
averageRating={entity.reviews?.reviews?.average_rating || 0}
/>
</Col>
</Row>
<EntityAnnotation entity={entity}/>
{!entity.deleted &&
<React.Fragment>
<EntityLinks
entity={entity}
identifierTypes={identifierTypes}
urlPrefix={urlPrefix}
/>
<EntityRelatedCollections collections={entity.collections}/>
<Button
className="margin-top-d15"
href={`/work/create?${_kebabCase(entity.type)}=${entity.bbid}`}
variant="success"
>
<FontAwesomeIcon className="margin-right-0-5" icon={faPlus}/>Add Work
</Button>
</React.Fragment>}
<React.Fragment>
<Row>
<Col lg={8}>
<EntityLinks
entity={entity}
identifierTypes={identifierTypes}
urlPrefix={urlPrefix}
/>
<EntityRelatedCollections collections={entity.collections}/>
<Button
className="margin-top-d15"
href={`/work/create?${_kebabCase(entity.type)}=${entity.bbid}`}
variant="success"
>
<FontAwesomeIcon className="margin-right-0-5" icon={faPlus}/>Add Work
</Button>
</Col>
<Col lg={4}>
<EntityReviews
entityBBID={entity.bbid}
entityReviews={entity.reviews}
entityType={entity.type}
handleModalToggle={handleModalToggle}
/>
</Col>
</Row>
</React.Fragment>}
<hr className="margin-top-d40"/>
<EntityFooter
bbid={entity.bbid}
Expand Down
6 changes: 4 additions & 2 deletions src/client/components/pages/entities/cb-review.js
Expand Up @@ -78,6 +78,7 @@ class EntityReviews extends React.Component {
};
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
this.entityType = props.entityType;
this.entityBBID = props.entityBBID;
this.handleModalToggle = props.handleModalToggle;
}

async handleClick() {
Expand Down Expand Up @@ -118,8 +119,8 @@ class EntityReviews extends React.Component {
<h4>No reviews yet.</h4>
<Button
className="margin-top-d15"
href={entityLink}
variant="success"
onClick={this.handleModalToggle}
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
>
<FontAwesomeIcon icon={faPlus}/>
{' Add a review'}
Expand Down Expand Up @@ -171,7 +172,8 @@ EntityReviews.displayName = 'EntityReviews';
EntityReviews.propTypes = {
entityBBID: PropTypes.string.isRequired,
entityReviews: PropTypes.object.isRequired,
entityType: PropTypes.string.isRequired
entityType: PropTypes.string.isRequired,
handleModalToggle: PropTypes.func.isRequired
};


Expand Down