Skip to content

Commit

Permalink
Corrige l'incrémentation des versions et corrige l'affichage des status
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Oct 2, 2023
1 parent 95c85d7 commit dafbec7
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 41 deletions.
54 changes: 44 additions & 10 deletions front/src/components/Write/CreateVersion.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,58 @@
import React, { useState } from 'react'
import { useToasts } from '@geist-ui/core'
import PropTypes from 'prop-types'
import React, { useCallback, useState } from 'react'
import { Link } from 'react-router-dom'
import { useDispatch } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'
import { ArrowLeft } from 'react-feather'
import { createVersion } from '../../services/ArticleService.graphql'

import { useMutation } from '../../hooks/graphql.js'

import styles from './createVersion.module.scss'
import buttonStyles from '../button.module.scss'
import Button from '../Button'
import Field from '../Field'

const CreateVersion = ({ articleId, readOnly, onClose }) => {
const { setToast } = useToasts()
const mutation = useMutation()
const activeUser = useSelector(state => state.activeUser)
const dispatch = useDispatch()

// create a new version
const [message, setMessage] = useState('')
const createVersion = async (e, major = false) => {
const handleCreateVersion = useCallback(async (e, major = false) => {
e.preventDefault()
dispatch({ type: 'CREATE_NEW_ARTICLE_VERSION', articleId, message, major })
setMessage('')
}
try {
const response = await mutation({
query: createVersion,
variables: {
userId: activeUser._id,
articleId,
major,
message
}
})
dispatch({ type: 'SET_ARTICLE_VERSIONS', versions: response.article.createVersion.versions })
setToast({
text: `Nouvelle version créée.`,
type: 'default',
})
} catch (err) {
const errorMessage = err.messages && err.messages.length
? err.messages[0].message
: err.message
setToast({
type: 'error',
text: errorMessage
})
}
}, [message, activeUser])

return (
<div className={styles.container}>
{readOnly && <Link className={[buttonStyles.button, buttonStyles.secondary].join(' ')} to={`/article/${articleId}`}> <ArrowLeft/> Edit Mode</Link>}
<form
className={styles.createForm}
onSubmit={(e) => createVersion(e, false)}
onSubmit={(e) => handleCreateVersion(e, false)}
>
<Field
className={styles.createVersionInput}
Expand All @@ -45,7 +73,7 @@ const CreateVersion = ({ articleId, readOnly, onClose }) => {
</Button>
</li>
<li>
<Button onClick={(e) => createVersion(e, true)}>
<Button onClick={(e) => handleCreateVersion(e, true)}>
Create Major
</Button>
</li>
Expand All @@ -56,3 +84,9 @@ const CreateVersion = ({ articleId, readOnly, onClose }) => {
}

export default CreateVersion

CreateVersion.propTypes = {
articleId: PropTypes.string,
readOnly: PropTypes.bool,
onClose: PropTypes.func,
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function CollaborativeSessionAction ({ collaborativeSession, arti
<>
<Button title="Collaborative editing" icon={true} onClick={() => setCollaborativeEditingVisible(true)}>
<Users/>
{collaborativeSession && <Badge type="error">Live</Badge>}
{collaborativeSession && collaborativeSession.id && <Badge type="error">Live</Badge>}
</Button>
<GeistModal width="35rem" visible={collaborativeEditingVisible} {...collaborativeEditingBinding}>
<h2>{collaborativeSessionDialogTitle}</h2>
Expand Down
17 changes: 12 additions & 5 deletions front/src/components/solo/SoloSessionAction.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import React, { useCallback, useState } from 'react'
import { Edit3 } from 'react-feather'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { useHistory } from 'react-router-dom'
import { useMutation } from '../../hooks/graphql.js'
import Button from '../Button.jsx'
Expand All @@ -11,6 +12,7 @@ import { startSoloSession, takeOverSoloSession } from './SoloSession.graphql'

export default function SoloSessionAction ({ collaborativeSession, soloSession, articleId }) {
const { t } = useTranslation()
const activeUser = useSelector(state => state.activeUser)
const { setToast } = useToasts()
const history = useHistory()
const [activeSoloSessionCreator, setActiveSoloSessionCreator] = useState('')
Expand All @@ -21,10 +23,13 @@ export default function SoloSessionAction ({ collaborativeSession, soloSession,
bindings: takeOverModalBinding
} = useModal()
const handleStartSoloEditing = useCallback(async () => {
console.log({soloSession})
if (soloSession && soloSession.id) {
setActiveSoloSessionCreator(soloSession.creatorUsername)
setTakeOverModalVisible(true)
if (soloSession.creator !== activeUser._id) {
setActiveSoloSessionCreator(soloSession.creatorUsername)
setTakeOverModalVisible(true)
} else {
history.push(`/article/${articleId}`)
}
} else {
// start a new solo session
try {
Expand Down Expand Up @@ -58,7 +63,7 @@ export default function SoloSessionAction ({ collaborativeSession, soloSession,
}
}, [setTakeOverModalVisible])

if (collaborativeSession) {
if (collaborativeSession && collaborativeSession.id) {
return <></>
}

Expand All @@ -69,7 +74,8 @@ export default function SoloSessionAction ({ collaborativeSession, soloSession,
<GeistModal.Content>
Would you like to take over the editing session from {activeSoloSessionCreator}?
</GeistModal.Content>
<GeistModal.Action passive onClick={() => setTakeOverModalVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
<GeistModal.Action passive
onClick={() => setTakeOverModalVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
<GeistModal.Action onClick={() => handleTakeOver()}>{t('modal.confirmButton.text')}</GeistModal.Action>
</GeistModal>
<Button title="Edit article" primary={true} onClick={handleStartSoloEditing}>
Expand All @@ -84,6 +90,7 @@ SoloSessionAction.propTypes = {
articleId: PropTypes.string.isRequired,
soloSession: PropTypes.shape({
id: PropTypes.string,
creator: PropTypes.string,
creatorUsername: PropTypes.string
}),
collaborativeSession: PropTypes.shape({
Expand Down
14 changes: 12 additions & 2 deletions front/src/createReduxStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const initialState = {
},
articleStructure: [],
articleVersions: [],
createArticleVersionError: null,
articleWriters: [],
articlePreferences: localStorage.getItem('articlePreferences') ? JSON.parse(localStorage.getItem('articlePreferences')) : {
expandSidebarLeft: true,
Expand Down Expand Up @@ -105,6 +106,7 @@ const reducer = createReducer(initialState, {
SET_WORKING_ARTICLE_METADATA: setWorkingArticleMetadata,
SET_WORKING_ARTICLE_BIBLIOGRAPHY: setWorkingArticleBibliography,
SET_WORKING_ARTICLE_STATE: setWorkingArticleState,
SET_CREATE_ARTICLE_VERSION_ERROR: setCreateArticleVersionError,

ARTICLE_PREFERENCES_TOGGLE: toggleArticlePreferences,

Expand Down Expand Up @@ -146,8 +148,12 @@ const createNewArticleVersion = store => {
const userId = userPreferences.currentUser ?? activeUser._id
const { articleId, major, message } = action
const articleService = new ArticleService(userId, articleId, sessionToken, applicationConfig)
const response = await articleService.createNewVersion(major, message)
store.dispatch({ type: 'SET_ARTICLE_VERSIONS', versions: response.article.createVersion.versions })
try {
const response = await articleService.createNewVersion(major, message)
store.dispatch({ type: 'SET_ARTICLE_VERSIONS', versions: response.article.createVersion.versions })
} catch (err) {
store.dispatch({ type: 'SET_CREATE_ARTICLE_VERSION_ERROR', err: err })
}
return next(action)
}
if (action.type === 'UPDATE_WORKING_ARTICLE_TEXT') {
Expand Down Expand Up @@ -374,6 +380,10 @@ function setArticleVersions (state, { versions }) {
return { ...state, articleVersions: versions }
}

function setCreateArticleVersionError (state, { err }) {
return { ...state, createArticleVersionError: err }
}

function setWorkingArticleUpdatedAt (state, { updatedAt }) {
const { workingArticle } = state
return { ...state, workingArticle: { ...workingArticle, updatedAt } }
Expand Down
47 changes: 24 additions & 23 deletions graphql/resolvers/articleResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,31 +120,29 @@ async function createSoloSession (article, user, force = false) {
async function createVersion (article, { major, message, userId, type }) {
const { bib, yaml, md } = article.workingVersion

console.log(article.versions)
/** @type {Query<Array<Article>>|Array<Article>} */
const latestVersions = await Version.find({ _id: { $in: article.versions.map((a) => a._id) } })
.sort({ createdAt: -1 })
.limit(1)

if (type !== 'userAction') {
if (latestVersions?.length > 0) {
const latestVersion = latestVersions[0]
if (bib === latestVersion.bib && yaml === latestVersion.yaml && md === latestVersion.md) {
logger.info("Won't create a new version since there's no change", {
action: "createVersion",
articleId: article._id
})
return false
}

if (latestVersions?.length > 0) {
const latestVersion = latestVersions[0]
if (bib === latestVersion.bib && yaml === latestVersion.yaml && md === latestVersion.md) {
logger.info('Won\'t create a new version since there\'s no change', {
action: 'createVersion',
articleId: article._id
})
return false
}
}

let mostRecentVersion = { version: 0, revision: 0 }
const latestUserVersions = latestVersions?.filter(v => v.type === undefined || v.type === 'userAction')
const latestUserVersions = latestVersions?.filter(v => !v.type || v.type === 'userAction')
if (latestUserVersions?.length > 0) {
const latestVersion = latestVersions[0]
const latestUserVersion = latestUserVersions[0]
mostRecentVersion = {
version: latestVersion.version,
revision: latestVersion.revision,
version: latestUserVersion.version,
revision: latestUserVersion.revision,
}
}
const { revision, version } = major
Expand Down Expand Up @@ -399,12 +397,15 @@ module.exports = {
},

async createVersion (article, { articleVersionInput }) {
await createVersion(article, articleVersionInput)
const result = await createVersion(article, { ...articleVersionInput, type: 'userAction' })
if (result === false) {
throw new ApiError('ILLEGAL_STATE', 'Unable to create a new version since there\'s no change')
}
await article.save()
return article
},

async startCollaborativeSession(article, _, { user }) {
async startCollaborativeSession (article, _, { user }) {
if (article.collaborativeSession && article.collaborativeSession.id) {
return article.collaborativeSession
}
Expand All @@ -428,7 +429,7 @@ module.exports = {
return collaborativeSession
},

async stopCollaborativeSession(article, _, { user }) {
async stopCollaborativeSession (article, _, { user }) {
if (article.collaborativeSession && article.collaborativeSession.id) {
const yDoc = getYDoc(`ws/${article.collaborativeSession.id.toString()}`)
const yState = yDoc.getText('state')
Expand All @@ -451,15 +452,15 @@ module.exports = {
return article
},

async startSoloSession(article, _, { user }) {
async startSoloSession (article, _, { user }) {
return createSoloSession(article, user, false)
},

async takeOverSoloSession(article, _, { user }) {
async takeOverSoloSession (article, _, { user }) {
return createSoloSession(article, user, true)
},

async stopSoloSession(article, _, { user }) {
async stopSoloSession (article, _, { user }) {
if (article.soloSession && article.soloSession.id) {
if (!article.soloSession.creator._id.equals(user._id)) {
throw new ApiError('UNAUTHORIZED', `Solo session ${article.soloSession.id} can only be ended by its creator ${article.soloSession.creator}.`)
Expand All @@ -480,7 +481,7 @@ module.exports = {
},

WorkingVersion: {
bibPreview({ bib }) {
bibPreview ({ bib }) {
return previewEntries(bib)
},
yaml ({ yaml }, { options }) {
Expand Down

0 comments on commit dafbec7

Please sign in to comment.