Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: EcrituresNumeriques/stylo
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b0a9cd99bd36dc7c92eae0b98ede8ccf6888037b
Choose a base ref
..
head repository: EcrituresNumeriques/stylo
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8e2974ffc3f3b36f6cba4b631a494f43f0231249
Choose a head ref
1 change: 0 additions & 1 deletion .github/workflows/deploy-tag.yml
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ on:
env:
SNOWPACK_PUBLIC_BACKEND_ENDPOINT: https://stylo.huma-num.fr
SNOWPACK_PUBLIC_GRAPHQL_ENDPOINT: https://stylo.huma-num.fr/graphql
SNOWPACK_PUBLIC_PROCESS_ENDPOINT: https://stylo-export.ecrituresnumeriques.ca
SNOWPACK_PUBLIC_PANDOC_EXPORT_ENDPOINT: https://export.stylo.huma-num.fr
SNOWPACK_PUBLIC_HUMAN_ID_REGISTER_ENDPOINT: https://humanid.huma-num.fr/register?service=https://stylo.huma-num.fr/authorization-code/callback
SNOWPACK_MATOMO_URL: https://analyseweb.huma-num.fr/
1 change: 0 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ on:
env:
SNOWPACK_PUBLIC_BACKEND_ENDPOINT: https://stylo-dev.huma-num.fr
SNOWPACK_PUBLIC_GRAPHQL_ENDPOINT: https://stylo-dev.huma-num.fr/graphql
SNOWPACK_PUBLIC_PROCESS_ENDPOINT: https://stylo-export.ecrituresnumeriques.ca
SNOWPACK_PUBLIC_PANDOC_EXPORT_ENDPOINT: https://export.stylo-dev.huma-num.fr
SNOWPACK_PUBLIC_HUMAN_ID_REGISTER_ENDPOINT: https://auth-test.huma-num.fr/register?service=https://stylo-dev.huma-num.fr/authorization-code/callback
SNOWPACK_MATOMO_URL: https://analyseweb.huma-num.fr/
1 change: 0 additions & 1 deletion front/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -35,7 +35,6 @@ module.exports = {
__ANNOTATIONS_CANONICAL_BASE_URL__: true,
__BACKEND_ENDPOINT__: true,
__GRAPHQL_ENDPOINT__: true,
__PROCESS_ENDPOINT__: true,
__PANDOC_EXPORT_ENDPOINT__: true,
__HUMANID_REGISTER_ENDPOINT__: true,
},
192 changes: 95 additions & 97 deletions front/src/components/Export.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo, useState } from 'react'
import React, { useCallback, useMemo } from 'react'
import { useDispatch, 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'
@@ -13,30 +13,56 @@ import styles from './export.module.scss'
import buttonStyles from './button.module.scss'
import formStyles from './form.module.scss'

export default function Export({
bookId,
articleVersionId,
articleId,
bib,
name,
}) {
const { processEndpoint, exportEndpoint, pandocExportEndpoint } =
applicationConfig
const [format, setFormat] = useState(bookId ? 'html5' : 'html')
const [csl, setCsl] = useState('chicagomodified')
const [toc, setToc] = useState('0')
const [unnumbered, setUnnumbered] = useState('false')
const [tld, setTld] = useState('false')
/**
* @typedef {Object} ExportProps
* @property {string?} bookId
* @property {string?} articleVersionId
* @property {string?} articleId
* @property {string} bib
* @property {string} name
*/

/**
*
* @param {ExportProps} props
* @returns {React.ReactElement}
*/
export default function Export(props) {
const { t } = useTranslation()
const dispatch = useDispatch()

const { bookId, articleVersionId = '', articleId, bib, name } = props
const { pandocExportHost, pandocExportEndpoint } = applicationConfig

const {
bibliography_style,
with_toc,
link_citations,
with_nocite,
formats,
unnumbered,
book_division,
} = useSelector((state) => state.exportPreferences, shallowEqual)

const setPreference = useCallback(
(key) => (event) =>
dispatch({
type: 'SET_EXPORT_PREFERENCES',
key,
value: event.target.value,
}),
[]
)

const { exportFormats, exportStyles, exportStylesPreview, isLoading } =
useStyloExport({ csl, bib })
const { host } = window.location
useStyloExport({ bibliography_style, bib })

const exportId = useMemo(
() =>
slugify(name, { strict: true, lower: true }) ||
(articleVersionId ?? articleId ?? bookId),
[name]
)
const { t } = useTranslation()
const groupedExportStyles = useMemo(() => {
return exportStyles?.map(({ key, name }, index) => ({
key,
@@ -48,24 +74,24 @@ export default function Export({
}))
}, [exportStyles])

const exportUrl = bookId
? `${processEndpoint}/cgi-bin/exportBook/exec.cgi?id=${exportId}&book=${bookId}&processor=xelatex&source=${exportEndpoint}/&format=${format}&bibstyle=${csl}&toc=${Boolean(
toc
)}&tld=${tld}&unnumbered=${unnumbered}`
: `${pandocExportEndpoint}/generique/article/export/${host}/${articleId}/${exportId}/?with_toc=${toc}&with_ascii=0&bibliography_style=${csl}&formats=originals&formats=${format}&version=${
articleVersionId ?? ''
}`
const exportUrl = useMemo(() => {
return `${pandocExportEndpoint}/generique/${
articleId ? 'article' : 'corpus'
}/export/${pandocExportHost}/${
articleId ?? bookId
}/${exportId}/?with_toc=${with_toc}&with_nocite=${with_nocite}&with_link_citations=${link_citations}&with_ascii=0&bibliography_style=${bibliography_style}&formats=originals&formats=${formats}&version=${articleVersionId}`
}, [with_toc, bibliography_style, formats, with_nocite, link_citations])

return (
<section className={styles.export}>
<form className={clsx(formStyles.form, formStyles.verticalForm)}>
{articleId && !exportFormats.length && <Loading inline size="24" />}
{articleId && exportFormats.length && (
{!exportFormats.length && <Loading inline size="24" />}
{exportFormats.length && (
<Select
id="export-formats"
label="Formats"
value={format}
onChange={(e) => setFormat(e.target.value)}
label={t('export.format.label')}
value={formats}
onChange={setPreference('formats')}
>
{exportFormats.map(({ key, name }) => (
<option value={key} key={key}>
@@ -74,39 +100,18 @@ export default function Export({
))}
</Select>
)}
{bookId && (
<Select
id="export-formats"
label={t('export.format.label')}
value={format}
onChange={(e) => setFormat(e.target.value)}
>
<option value="html5">HTML5</option>
<option value="zip">ZIP</option>
<option value="pdf">PDF</option>
<option value="tex">LATEX</option>
<option value="xml">XML (érudit)</option>
<option value="odt">ODT</option>
<option value="docx">DOCX</option>
<option value="epub">EPUB</option>
<option value="tei">TEI</option>
<option value="icml">ICML</option>
</Select>
)}

{articleId && bib && !exportStyles.length && (
<Loading inline size="24" />
)}
{articleId && bib && exportStyles.length && (
{bib && !exportStyles.length && <Loading inline size="24" />}
{bib && exportStyles.length && (
<Combobox
id="export-styles"
label="Bibliography style"
label={t('export.bibliography.label')}
items={groupedExportStyles}
value={csl}
onChange={setCsl}
value={bibliography_style}
onChange={setPreference('bibliography_style')}
/>
)}
{articleId && bib && (
{bib && (
<div className={styles.bibliographyPreview}>
{isLoading && <Loading inline size="24" />}
{!isLoading && (
@@ -115,39 +120,38 @@ export default function Export({
</div>
)}

{bookId && bib && (
<Select
id="export-styles"
label="Bibliography style"
value={csl}
setCsl={setCsl}
>
<option value="chicagomodified">chicagomodified</option>
<option value="lettres-et-sciences-humaines-fr">
{' '}
lettres-et-sciences-humaines-fr
</option>
<option value="chicago-fullnote-bibliography-fr">
{' '}
chicago-fullnote-bibliography-fr
</option>
</Select>
)}
<Select
label={t('export.toc.label')}
value={with_toc}
onChange={setPreference('with_toc')}
>
<option value="1">{t('export.toc.yes')}</option>
<option value="0">{t('export.toc.no')}</option>
</Select>

<Select
id="export-toc"
label="Additional options"
value={toc}
onChange={(e) => setToc(parseInt(e.target.value, 10))}
label={t('export.nocite.label')}
value={with_nocite}
onChange={setPreference('with_nocite')}
>
<option value="1">{t('export.additionnalOptions.toc')}</option>
<option value="0">{t('export.additionnalOptions.notoc')}</option>
<option value="1">{t('export.nocite.all')}</option>
<option value="0">{t('export.nocite.onlyUsed')}</option>
</Select>
{bookId && (

<Select
label={t('export.linkCitations.label')}
value={link_citations}
onChange={setPreference('link_citations')}
>
<option value="1">{t('export.linkCitations.yes')}</option>
<option value="0">{t('export.linkCitations.no')}</option>
</Select>

{/*bookId && (
<Select
id="export-numbering"
value={unnumbered}
onChange={(e) => setUnnumbered(e.target.value)}
onChange={setPreference('unnumbered')}
>
<option value="false">
{t('export.sectionChapters.numbered')}
@@ -156,13 +160,16 @@ export default function Export({
{t('export.sectionChapters.unnumbered')}
</option>
</Select>
)}
{bookId && (
<Select value={tld} onChange={(e) => setTld(e.target.value)}>
)*/}
{/*bookId && (
<Select
value={book_division}
onChange={setPreference('book_division')}
>
<option value="part">{t('export.bookDivision.part')}</option>
<option value="chapter">{t('export.bookDivision.chapter')}</option>
</Select>
)}
)*/}
</form>

<nav className={styles.actions}>
@@ -179,12 +186,3 @@ export default function Export({
</section>
)
}

// TODO use "shapes" to either have bookId, or articleId, or articleId and articleVersionId
Export.propTypes = {
bookId: PropTypes.string,
articleVersionId: PropTypes.string,
articleId: PropTypes.string,
name: PropTypes.string.isRequired,
bib: PropTypes.string,
}
37 changes: 24 additions & 13 deletions front/src/components/Field.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
import clsx from 'clsx'
import React, { forwardRef } from 'react'
import React, { forwardRef, useEffect, useRef } from 'react'
import styles from './field.module.scss'

export default forwardRef(function Field(
{ hasError, className, prefix, children, label, id, type, ...otherProps },
{
hasError,
className,
prefix,
children,
label,
id,
type,
autoFocus = false,
...otherProps
},
forwardedRef
) {
const classNames = [
const inputRef = forwardedRef ?? useRef()
const classNames = clsx(
styles.field,
prefix && styles.withPrefix,
'control-field',
]

if (className) {
classNames.push(className)
}
if (hasError) {
classNames.push(styles.error)
}
className && className,
hasError && styles.error
)

const computedStyles = { '--chars-count': prefix?.length }
useEffect(() => {
if (autoFocus) {
inputRef.current.focus()
}
}, [])

return (
<div className={clsx(classNames)}>
<div className={classNames}>
{label && <label htmlFor={id}>{label}</label>}
<div
className={clsx('control', otherProps.icon && 'has-icons-left')}
@@ -36,7 +47,7 @@ export default forwardRef(function Field(
{...otherProps}
className="input"
type={type || 'text'}
ref={forwardedRef}
ref={inputRef}
/>
{otherProps.icon && (
<span className="icon is-small is-left">
1 change: 1 addition & 0 deletions front/src/components/TagCreate.jsx
Original file line number Diff line number Diff line change
@@ -61,6 +61,7 @@ export default function TagCreate() {
<section className={styles.create}>
<form onSubmit={handleCreateTag}>
<Field
autoFocus={true}
label={t('tag.createForm.nameField')}
type="text"
{...nameBindings}
1 change: 1 addition & 0 deletions front/src/components/workspace/CreateWorkspace.jsx
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ export default function CreateWorkspace() {
<section>
<form onSubmit={handleSubmit}>
<Field
autoFocus={true}
ref={nameInputRef}
{...nameBindings}
label={t('workspace.createForm.nameField')}
3 changes: 2 additions & 1 deletion front/src/config.js
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@ export const applicationConfig = {
backendEndpoint: __BACKEND_ENDPOINT__,
canonicalBaseUrl: __ANNOTATIONS_CANONICAL_BASE_URL__,
graphqlEndpoint: __GRAPHQL_ENDPOINT__,
processEndpoint: __PROCESS_ENDPOINT__,
pandocExportEndpoint: __PANDOC_EXPORT_ENDPOINT__,
pandocExportHost:
import.meta.env.SNOWPACK_PUBLIC_PANDOC_EXPORT_HOST ?? window.location.host,
humanIdRegisterEndpoint: __HUMANID_REGISTER_ENDPOINT__,
websocketEndpoint: toWebsocketEndpoint(__BACKEND_ENDPOINT__),
}
Loading