Skip to content

Commit

Permalink
implement multiple authors to articles and assign other user as autho…
Browse files Browse the repository at this point in the history
…rs and refactor some code
  • Loading branch information
dependabot[bot] authored and jonasdeluna committed Mar 21, 2023
1 parent 3a63488 commit 2ea8faf
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 109 deletions.
75 changes: 21 additions & 54 deletions app/components/Form/ObjectPermissions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SelectInput, CheckBox } from 'app/components/Form';
import Tooltip from 'app/components/Tooltip';
import type { PublicGroup } from 'app/store/models/Group';

/*
* Usage inside redux-form:
Expand All @@ -26,10 +27,10 @@ const ObjectPermissions = ({
requireAuth,
...props
}: {
canEditUsers?: any;
canEditGroups?: any;
canViewGroups?: any;
requireAuth?: any;
canEditUsers?: PublicGroup[];
canEditGroups?: PublicGroup[];
canViewGroups?: PublicGroup[];
requireAuth?: boolean;
}) => {
return [
requireAuth && (
Expand Down Expand Up @@ -78,67 +79,33 @@ export const normalizeObjectPermissions = ({
canViewGroups: initialCanViewGroups,
canEditGroups: initialCanEditGroups,
canEditUsers: initialCanEditUsers,
currentUser: currentUser,
}: Record<string, any>) => {
const canEditUsers = initialCanEditUsers && initialCanEditUsers.map(toIds);
const canViewGroups = initialCanViewGroups && initialCanViewGroups.map(toIds);
const canEditGroups = initialCanEditGroups && initialCanEditGroups.map(toIds);
return {
requireAuth: !!requireAuth,
...(canEditUsers
? {
canEditUsers,
}
: {}),
//$FlowFixMe
...(canEditGroups
? {
canEditGroups,
}
: {}),
...(canViewGroups
? {
canViewGroups,
}
: {}),
canEditUsers: initialCanEditUsers?.map(toIds) ?? {},
canViewGroups: initialCanViewGroups?.map(toIds) ?? {},
canEditGroups: initialCanEditGroups?.map(toIds) ?? {},
};
};
export const objectPermissionsToInitialValues = ({
canViewGroups: initialCanViewGroups,
canEditGroups: initialCanEditGroups,
canEditUsers: initialCanEditUsers,
}: Record<string, any>) => {
const canEditGroups =
initialCanEditGroups &&
initialCanEditGroups
.filter(Boolean)
.map((group) => ({ ...group, label: group.name, value: group.id }));
const canViewGroups =
initialCanViewGroups &&
initialCanViewGroups
.filter(Boolean)
.map((group) => ({ ...group, label: group.name, value: group.id }));
const canEditUsers =
initialCanEditUsers &&
initialCanEditUsers
.filter(Boolean)
.map((user) => ({ ...user, label: user.fullName, value: user.id }));
const canEditGroups = initialCanEditGroups
?.filter(Boolean)
.map((group) => ({ ...group, label: group.name, value: group.id }));
const canViewGroups = initialCanViewGroups
?.filter(Boolean)
.map((group) => ({ ...group, label: group.name, value: group.id }));
const canEditUsers = initialCanEditUsers
?.filter(Boolean)
.map((user) => ({ ...user, label: user.fullName, value: user.id }));
return {
...(canEditUsers
? {
canEditUsers,
}
: {}),
//$FlowFixMe
...(canEditGroups
? {
canEditGroups,
}
: {}),
...(canViewGroups
? {
canViewGroups,
}
: {}),
canEditUsers: canEditUsers ?? {},
canEditGroups: canEditGroups ?? {},
canViewGroups: canViewGroups ?? {},
};
};
export const objectPermissionsInitialValues = {
Expand Down
3 changes: 2 additions & 1 deletion app/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ export const reactionSchema = new schema.Entity('reactions');
export const articleSchema = new schema.Entity('articles', {
comments: [commentSchema],
reactions: [reactionSchema],
author: userSchema,
authors: [userSchema],
});

export const galleryPictureSchema = new schema.Entity('galleryPictures', {
comments: [commentSchema],
});
Expand Down
1 change: 1 addition & 0 deletions app/reducers/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const selectUserById = createSelector(
(state, props) => props.userId,
(usersById, userId) => usersById[userId] || {}
);

export const selectUserByUsername = createSelector(
(state) => state.users.byId,
(state, props) => props.username,
Expand Down
25 changes: 17 additions & 8 deletions app/routes/articles/ArticleCreateRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ import { compose } from 'redux';
import { createArticle } from 'app/actions/ArticleActions';
import { uploadFile } from 'app/actions/FileActions';
import { LoginPage } from 'app/components/LoginForm';
import { selectCurrentUser } from 'app/reducers/auth';
import replaceUnlessLoggedIn from 'app/utils/replaceUnlessLoggedIn';
import ArticleEditor from './components/ArticleEditor';

const mapStateToProps = () => ({
isNew: true,
article: {},
initialValues: {
content: '',
},
});

const mapStateToProps = (state, props) => {
const currentUser = selectCurrentUser(state);
const authors = [currentUser];
return {
isNew: true,
article: {},
initialValues: {
content: '',
authors: authors.map((user) => ({
...user,
label: user.fullName,
value: user.id,
})),
},
};
};
const mapDispatchToProps = {
submitArticle: createArticle,
uploadFile,
Expand Down
21 changes: 13 additions & 8 deletions app/routes/articles/ArticleDetailRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ const mapStateToProps = (state, props) => {
const comments = selectCommentsForArticle(state, {
articleId,
});
const author = selectUserById(state, {
userId: article.author,
const authors = article.authors?.map((e) => {
return selectUserById(state, {
userId: e,
});
});
const emojis = selectEmojis(state);
return {
Expand All @@ -35,7 +37,7 @@ const mapStateToProps = (state, props) => {
comments,
article,
articleId,
author,
authors,
emojis,
};
};
Expand All @@ -56,11 +58,17 @@ export default compose(
),
connect(mapStateToProps, mapDispatchToProps),
loadingIndicator(['article.content']),
helmet((props: { article: PublicArticle; author: PublicUser }, config) => {
helmet((props: { article: PublicArticle; authors: PublicUser[] }, config) => {
const tags = props.article.tags.map((content) => ({
content,
property: 'article:tag',
}));

const authors = props.authors.map((author) => ({
property: 'article:authors',
content: `${config.webUrl}/users/${author.username}`,
}));

return [
{
property: 'og:title',
Expand Down Expand Up @@ -103,10 +111,7 @@ export default compose(
property: 'og:description',
content: props.article.description,
},
{
property: 'article:author',
content: `${config.webUrl}/users/${props.author.username}`,
},
...authors,
...tags,
];
})
Expand Down
17 changes: 16 additions & 1 deletion app/routes/articles/ArticleEditRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
import { objectPermissionsToInitialValues } from 'app/components/Form/ObjectPermissions';
import { LoginPage } from 'app/components/LoginForm';
import { selectArticleById } from 'app/reducers/articles';
import { selectCurrentUser } from 'app/reducers/auth';
import { selectUserById } from 'app/reducers/users';
import loadingIndicator from 'app/utils/loadingIndicator';
import replaceUnlessLoggedIn from 'app/utils/replaceUnlessLoggedIn';
import withPreparedDispatch from 'app/utils/withPreparedDispatch';
Expand All @@ -19,13 +21,26 @@ const mapStateToProps = (state, props) => {
const article = selectArticleById(state, {
articleId,
});

const currentUser = selectCurrentUser(state);
const authors = article?.authors?.length
? article.authors.map((e) => selectUserById(state, { userId: e }))
: [currentUser];

return {
article,
articleId,
isNew: false,
initialValues: {
...article,
...objectPermissionsToInitialValues(article),
...objectPermissionsToInitialValues({
canViewGroups: article.canViewGroups,
canEditGroups: article.canEditGroups,
canEditUsers: article.canEditUsers,
}),
authors: authors
.filter(Boolean)
.map((user) => ({ user, label: user.fullName, value: user.id })),
tags: (article.tags || []).map((tag) => ({
label: tag,
value: tag,
Expand Down
10 changes: 6 additions & 4 deletions app/routes/articles/ArticleListRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import type { PublicUser } from 'app/store/models/User';
import withPreparedDispatch from 'app/utils/withPreparedDispatch';
import Overview from './components/Overview';

export type ArticleWithAuthorDetails = Omit<PublicArticle, 'author'> & {
author: PublicUser;
export type ArticleWithAuthorDetails = Omit<PublicArticle, 'authors'> & {
authors: Array<PublicUser>;
};

const mapStateToProps = (state, props) => {
Expand All @@ -34,8 +34,10 @@ const mapStateToProps = (state, props) => {
}
).map((article) => ({
...article,
author: selectUserById(state, {
userId: article.author,
authors: article.authors.map((e) => {
return selectUserById(state, {
userId: e,
});
}),
}));

Expand Down
40 changes: 27 additions & 13 deletions app/routes/articles/components/ArticleDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ type Props = {
article: DetailedArticle | AdminDetailedArticle;
comments: Comment[];
loggedIn: boolean;
author: DetailedUser;
authors: DetailedUser[];
currentUser: CurrentUser;
deleteComment: (id: ID, contentTarget: string) => Promise<void>;
emojis: Array<EmojiEntity>;
addReaction: (arg0: {
emoji: string;
contentTarget: string;
}) => Promise<unknown>;
reactionsGrouped: Array<ReactionEntity>;
reactionsGrouped: ReactionEntity[];
deleteReaction: (arg0: {
reactionId: ID;
contentTarget: string;
Expand All @@ -41,7 +41,7 @@ type Props = {

const ArticleDetail = ({
article,
author,
authors,
loggedIn,
currentUser,
comments,
Expand Down Expand Up @@ -70,16 +70,30 @@ const ArticleDetail = ({
)}
</NavigationTab>

<div className={styles.articleDetails}>
<span className={styles.detail}>
Skrevet av
<Link to={`/users/${author.username}`}> {author.fullName}</Link>
</span>
<span className={styles.detail}>
{moment(article.createdAt).format('lll')}
</span>
</div>

{
<div className={styles.articleDetails}>
<span className={styles.detail}>
Skrevet av{' '}
{authors?.map((e, i) => {
return (
<span key={e.username}>
<Link
to={`/users/${e.username}`}
className={styles.overviewAuthor}
>
{' '}
{e.fullName}
</Link>
{i === authors.length - 1 ? '' : ','}
</span>
);
})}
</span>
<span className={styles.detail}>
{moment(article.createdAt).format('lll')}
</span>
</div>
}
<DisplayContent content={article.content} />

<Tags>
Expand Down

0 comments on commit 2ea8faf

Please sign in to comment.