Skip to content

Commit

Permalink
feat: la configuration applicative est une constante (#1184)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie authored Jan 21, 2025
1 parent f59bc8e commit b31273b
Show file tree
Hide file tree
Showing 17 changed files with 96 additions and 179 deletions.
4 changes: 2 additions & 2 deletions front/src/components/ArticlePreview.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useState, useRef, useEffect } from 'react'
import { useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'
import { applicationConfig } from '../config.js'

import styles from './articles.module.scss'
import Loading from './Loading'

export default function ArticlePreview() {
const { id, version, bookId } = useParams()
const { exportEndpoint } = useSelector((state) => state.applicationConfig)
const { exportEndpoint } = applicationConfig
const [isLoaded, setLoaded] = useState(false)
const previewFrame = useRef()

Expand Down
6 changes: 2 additions & 4 deletions front/src/components/Articles.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CurrentUserContext } from '../contexts/CurrentUser'
import { Search } from 'react-feather'

import useGraphQL from '../hooks/graphql'
import { applicationConfig } from '../config.js'
import { getUserArticles, getWorkspaceArticles } from './Articles.graphql'
import etv from '../helpers/eventTargetValue'

Expand All @@ -22,9 +23,7 @@ import TagsList from './tag/TagsList.jsx'

export default function Articles() {
const { t } = useTranslation()
const backendEndpoint = useSelector(
(state) => state.applicationConfig.backendEndpoint
)
const { backendEndpoint } = applicationConfig
const currentUser = useSelector((state) => state.activeUser, shallowEqual)
const selectedTagIds = useSelector(
(state) => state.activeUser.selectedTagIds || []
Expand Down Expand Up @@ -252,7 +251,6 @@ export default function Articles() {
<Button primary onClick={() => setCreateArticleVisible(true)}>
{t('article.createAction.buttonText')}
</Button>

<div className={styles.articleCounter}>
{t('article.count', { count: keepArticles.length })}
</div>
Expand Down
8 changes: 3 additions & 5 deletions front/src/components/Export.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useMemo, useState } from 'react'
import { useSelector, shallowEqual } from 'react-redux'
import { useTranslation } from 'react-i18next'
import clsx from 'clsx'
import PropTypes from 'prop-types'
import slugify from 'slugify'
import useStyloExport from '../hooks/stylo-export.js'
import { applicationConfig } from '../config.js'

import Select from './Select'
import Combobox from './SelectCombobox.jsx'
Expand All @@ -20,10 +20,8 @@ export default function Export({
bib,
name,
}) {
const { processEndpoint, exportEndpoint, pandocExportEndpoint } = useSelector(
(state) => state.applicationConfig,
shallowEqual
)
const { processEndpoint, exportEndpoint, pandocExportEndpoint } =
applicationConfig
const [format, setFormat] = useState(bookId ? 'html5' : 'html')
const [csl, setCsl] = useState('chicagomodified')
const [toc, setToc] = useState('0')
Expand Down
10 changes: 3 additions & 7 deletions front/src/components/Login.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useCallback, useState, useEffect } from 'react'
import { Link, useHistory } from 'react-router-dom'
import { useSelector, useDispatch } from 'react-redux'
import { useDispatch } from 'react-redux'
import { applicationConfig } from '../config.js'

import styles from './login.module.scss'
import Field from './Field'
Expand All @@ -20,12 +21,7 @@ export default function Login() {
)
const authToken = new URLSearchParams(location.hash).get('#auth-token')

const backendEndpoint = useSelector(
(state) => state.applicationConfig.backendEndpoint
)
const humanIdRegisterEndpoint = useSelector(
(state) => state.applicationConfig.humanIdRegisterEndpoint
)
const { backendEndpoint, humanIdRegisterEndpoint } = applicationConfig

useEffect(() => {
if (authToken) {
Expand Down
1 change: 0 additions & 1 deletion front/src/components/Write/ArticleEditorMetadata.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { Sidebar } from 'react-feather'

import { toYaml } from './metadata/yaml.js'
import ArticleEditorMetadataForm from './yamleditor/ArticleEditorMetadataForm.jsx'
import NavTag from '../NavTab'
import MonacoYamlEditor from './providers/monaco/YamlEditor'

import styles from './articleEditorMetadata.module.scss'
Expand Down
5 changes: 2 additions & 3 deletions front/src/components/Write/Write.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PropTypes from 'prop-types'
import throttle from 'lodash.throttle'
import debounce from 'lodash.debounce'
import { useMutation } from '../../hooks/graphql.js'
import { applicationConfig } from '../../config.js'
import ArticleStats from '../ArticleStats.jsx'
import ErrorMessageCard from '../ErrorMessageCard.jsx'

Expand Down Expand Up @@ -48,9 +49,7 @@ export function deriveModeFrom({ path, currentVersion }) {

export default function Write() {
const { setToast } = useToasts()
const backendEndpoint = useSelector(
(state) => state.applicationConfig.backendEndpoint
)
const { backendEndpoint } = applicationConfig
const { t } = useTranslation()
const { version: currentVersion, id: articleId, compareTo } = useParams()
const workingArticle = useSelector(
Expand Down
9 changes: 3 additions & 6 deletions front/src/components/Write/bibliographe/ZoteroPanel.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import PropTypes from 'prop-types'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'

Expand All @@ -9,6 +8,7 @@ import {
} from '../../../helpers/zotero'
import { useGraphQL } from '../../../helpers/graphQL'
import { useProfile } from '../../../helpers/userProfile'
import { applicationConfig } from '../../../config.js'
import { linkToZotero as query } from '../../Article.graphql'

import Button from '../../Button'
Expand All @@ -31,10 +31,7 @@ export default function ZoteroPanel({
const { t } = useTranslation()
const zoteroToken = useSelector((state) => state.activeUser.zoteroToken)
const userId = useSelector((state) => state.activeUser._id)
const backendEndpoint = useSelector(
(state) => state.applicationConfig.backendEndpoint
)

const { backendEndpoint } = applicationConfig
const [zoteroLink, setZoteroLink] = useState(initialZoteroLink)
const [zoteroCollectionHref, setZoteroCollectionHref] = useState(null)
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import throttle from 'lodash.throttle'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { shallowEqual, useDispatch, useSelector } from 'react-redux'
import { MonacoBinding } from 'y-monaco'
import { applicationConfig } from '../../config.js'
import * as collaborating from './collaborating.js'
import CollaborativeEditorStatus from './CollaborativeEditorStatus.jsx'

Expand Down Expand Up @@ -53,10 +54,7 @@ export default function CollaborativeTextEditor({
const [collaborativeSessionState, setCollaborativeSessionState] = useState('')
const [yText, setYText] = useState(null)
const [awareness, setAwareness] = useState(null)
const { websocketEndpoint } = useSelector(
(state) => state.applicationConfig,
shallowEqual
)
const { websocketEndpoint } = applicationConfig
const activeUser = useSelector(
(state) => ({
_id: state.activeUser._id,
Expand Down
21 changes: 21 additions & 0 deletions front/src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// variables defined statically via vite.config.js
export const applicationConfig = {
backendEndpoint: __BACKEND_ENDPOINT__,
graphqlEndpoint: __GRAPHQL_ENDPOINT__,
exportEndpoint: __EXPORT_ENDPOINT__,
processEndpoint: __PROCESS_ENDPOINT__,
pandocExportEndpoint: __PANDOC_EXPORT_ENDPOINT__,
humanIdRegisterEndpoint: __HUMANID_REGISTER_ENDPOINT__,
websocketEndpoint: toWebsocketEndpoint(__BACKEND_ENDPOINT__),
}

function toWebsocketEndpoint(endpoint) {
if (endpoint) {
const endpointUrl = new URL(endpoint)
const protocol = endpointUrl.protocol
return `${protocol === 'https:' ? 'wss' : 'ws'}://${endpointUrl.hostname}:${
endpointUrl.port
}/ws`
}
return `ws://127.0.0.1:3030/ws`
}
64 changes: 15 additions & 49 deletions front/src/createReduxStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as Sentry from '@sentry/react'
import { toEntries } from './helpers/bibtex'
import ArticleService from './services/ArticleService'
import WorkspaceService from './services/WorkspaceService.js'
import { applicationConfig } from './config.js'
const { SNOWPACK_SESSION_STORAGE_ID: sessionTokenName = 'sessionToken' } =
import.meta.env

Expand All @@ -18,17 +19,6 @@ function createReducer(initialState, handlers) {
}
}

function toWebsocketEndpoint(endpoint) {
if (endpoint) {
const endpointUrl = new URL(endpoint)
const protocol = endpointUrl.protocol
return `${protocol === 'https:' ? 'wss' : 'ws'}://${endpointUrl.hostname}:${
endpointUrl.port
}/ws`
}
return `ws://127.0.0.1:3030/ws`
}

// Définition du store Redux et de l'ensemble des actions
export const initialState = {
hasBooted: false,
Expand All @@ -40,16 +30,6 @@ export const initialState = {
entries: [],
},
},
// they are defined statically via vite.config.js
applicationConfig: {
backendEndpoint: __BACKEND_ENDPOINT__,
graphqlEndpoint: __GRAPHQL_ENDPOINT__,
exportEndpoint: __EXPORT_ENDPOINT__,
processEndpoint: __PROCESS_ENDPOINT__,
pandocExportEndpoint: __PANDOC_EXPORT_ENDPOINT__,
humanIdRegisterEndpoint: __HUMANID_REGISTER_ENDPOINT__,
websocketEndpoint: toWebsocketEndpoint(__BACKEND_ENDPOINT__),
},
articleStructure: [],
articleVersions: [],
createArticleVersionError: null,
Expand Down Expand Up @@ -142,12 +122,9 @@ const createNewArticleVersion = (store) => {
return (next) => {
return async (action) => {
if (action.type === 'CREATE_WORKSPACE') {
const { activeUser, sessionToken, applicationConfig } = store.getState()
const { activeUser, sessionToken } = store.getState()
const workspaces = activeUser.workspaces
const workspaceService = new WorkspaceService(
sessionToken,
applicationConfig
)
const workspaceService = new WorkspaceService(sessionToken)
const response = await workspaceService.create(action.data)
store.dispatch({
type: 'SET_WORKSPACES',
Expand All @@ -156,12 +133,9 @@ const createNewArticleVersion = (store) => {
return next(action)
}
if (action.type === 'LEAVE_WORKSPACE') {
const { activeUser, sessionToken, applicationConfig } = store.getState()
const { activeUser, sessionToken } = store.getState()
const workspaces = activeUser.workspaces
const workspaceService = new WorkspaceService(
sessionToken,
applicationConfig
)
const workspaceService = new WorkspaceService(sessionToken)
const workspaceId = action.data.workspaceId
await workspaceService.leave(workspaceId)
store.dispatch({
Expand All @@ -171,15 +145,13 @@ const createNewArticleVersion = (store) => {
return next(action)
}
if (action.type === 'CREATE_NEW_ARTICLE_VERSION') {
const { activeUser, sessionToken, applicationConfig, userPreferences } =
store.getState()
const { activeUser, sessionToken, userPreferences } = store.getState()
const userId = userPreferences.currentUser ?? activeUser._id
const { articleId, major, message } = action
const articleService = new ArticleService(
userId,
articleId,
sessionToken,
applicationConfig
sessionToken
)
try {
const response = await articleService.createNewVersion(major, message)
Expand All @@ -193,16 +165,14 @@ const createNewArticleVersion = (store) => {
return next(action)
}
if (action.type === 'UPDATE_WORKING_ARTICLE_TEXT') {
const { activeUser, sessionToken, applicationConfig, userPreferences } =
store.getState()
const { activeUser, sessionToken, userPreferences } = store.getState()
const userId = userPreferences.currentUser ?? activeUser._id
const { articleId, text } = action
try {
const { article } = await new ArticleService(
userId,
articleId,
sessionToken,
applicationConfig
sessionToken
).saveText(text)
store.dispatch({
type: 'SET_WORKING_ARTICLE_STATE',
Expand All @@ -224,16 +194,14 @@ const createNewArticleVersion = (store) => {
return next(action)
}
if (action.type === 'UPDATE_WORKING_ARTICLE_METADATA') {
const { activeUser, sessionToken, applicationConfig, userPreferences } =
store.getState()
const { activeUser, sessionToken, userPreferences } = store.getState()
const userId = userPreferences.currentUser ?? activeUser._id
const { articleId, metadata } = action
try {
const { article } = await new ArticleService(
userId,
articleId,
sessionToken,
applicationConfig
sessionToken
).saveMetadata(metadata)
store.dispatch({
type: 'SET_WORKING_ARTICLE_STATE',
Expand All @@ -254,16 +222,14 @@ const createNewArticleVersion = (store) => {
return next(action)
}
if (action.type === 'UPDATE_WORKING_ARTICLE_BIBLIOGRAPHY') {
const { activeUser, sessionToken, applicationConfig, userPreferences } =
store.getState()
const { activeUser, sessionToken, userPreferences } = store.getState()
const userId = userPreferences.currentUser ?? activeUser._id
const { articleId, bibliography } = action
try {
const { article } = await new ArticleService(
userId,
articleId,
sessionToken,
applicationConfig
sessionToken
).saveBibliography(bibliography)
store.dispatch({
type: 'SET_WORKING_ARTICLE_STATE',
Expand Down Expand Up @@ -316,10 +282,10 @@ function persistStateIntoLocalStorage({ getState }) {

return
} else if (action.type === 'LOGOUT') {
const { applicationConfig } = getState()
const { backendEndpoint } = applicationConfig
localStorage.removeItem('articlePreferences')
localStorage.removeItem('userPreferences')
document.location.replace(applicationConfig.backendEndpoint + '/logout')
document.location.replace(backendEndpoint + '/logout')
}

if (action.type === 'LOGIN' || action.type === 'UPDATE_SESSION_TOKEN') {
Expand Down
25 changes: 7 additions & 18 deletions front/src/helpers/graphQL.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { shallowEqual, useSelector } from 'react-redux'
import { useSelector } from 'react-redux'
import { print } from 'graphql/language/printer'
import { applicationConfig } from '../config.js'

/**
* @typedef {import('graphql/language/ast').DocumentNode} DocumentNode
Expand All @@ -23,8 +24,7 @@ async function getErrorResponse(response) {
export default async function askGraphQL(
payload,
action = 'fetching from the server',
sessionToken = null,
applicationConfig
sessionToken = null
) {
const response = await fetch(applicationConfig.graphqlEndpoint, {
method: 'POST',
Expand Down Expand Up @@ -62,28 +62,17 @@ export default async function askGraphQL(

export function useGraphQL() {
const sessionToken = useSelector((state) => state.sessionToken)
const graphqlEndpoint = useSelector(
(state) => state.applicationConfig.graphqlEndpoint,
shallowEqual
)

return runQuery.bind(null, { sessionToken, graphqlEndpoint })
return runQuery.bind(null, { sessionToken })
}

/**
* @param {string}sessionToken
* @param {string} graphqlEndpoint
* @param {string} sessionToken
* @param {DocumentNode|string} queryOrAST
* @param {{[string: key]: value}} variables
* @return {Promise<string|object>}
*/
export function runQuery(
{ sessionToken, graphqlEndpoint },
{ query: queryOrAST, variables }
) {
export function runQuery({ sessionToken }, { query: queryOrAST, variables }) {
const query = typeof queryOrAST === 'string' ? queryOrAST : print(queryOrAST)

return askGraphQL({ query, variables }, null, sessionToken, {
graphqlEndpoint,
})
return askGraphQL({ query, variables }, null, sessionToken)
}
Loading

0 comments on commit b31273b

Please sign in to comment.