Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
W
Wiki
Manage
Activity
Members
Labels
Plan
Issues
53
Issue boards
Milestones
Wiki
Code
Merge requests
6
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
MDM Lab
Wiki
Commits
8d33275f
Commit
8d33275f
authored
1 year ago
by
Remi PLANEL
Browse files
Options
Downloads
Patches
Plain Diff
get article from meilisearch + cache
parent
4d4bba17
No related branches found
Branches containing commit
No related tags found
1 merge request
!224
Resolve "Rework references"
Pipeline
#124708
canceled with stages
in 1 minute and 5 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
components/content/ArticleDoi.vue
+8
-13
8 additions, 13 deletions
components/content/ArticleDoi.vue
composables/useFetchArticle.ts
+42
-87
42 additions, 87 deletions
composables/useFetchArticle.ts
with
50 additions
and
100 deletions
components/content/ArticleDoi.vue
+
8
−
13
View file @
8d33275f
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
useDisplay
}
from
"
vuetify
"
;
import
{
useDisplay
}
from
"
vuetify
"
;
import
{
use
Article
sStore
}
from
'
@/
stor
es/articles
'
import
type
{
Wiki
Article
}
from
'
@/
typ
es/articles
'
;
export
interface
Props
{
export
interface
Props
{
index
?:
number
;
index
?:
number
;
...
@@ -19,11 +19,14 @@ const props = withDefaults(defineProps<Props>(), {
...
@@ -19,11 +19,14 @@ const props = withDefaults(defineProps<Props>(), {
isRelevant
:
false
,
isRelevant
:
false
,
});
});
const
{
article
}
=
useFetchArticle
(
props
.
doi
);
const
article
=
ref
<
WikiArticle
|
undefined
>
(
undefined
)
const
{
mobile
}
=
useDisplay
();
const
{
mobile
}
=
useDisplay
();
const
show
=
ref
(
false
);
const
show
=
ref
(
false
);
onMounted
(
async
()
=>
{
const
{
article
:
articleOnMounted
}
=
await
useFetchArticle
(
props
.
doi
);
article
.
value
=
articleOnMounted
.
value
})
const
articleTitle
=
computed
(()
=>
{
const
articleTitle
=
computed
(()
=>
{
return
props
?.
title
??
article
?.
value
?.
title
??
props
.
doi
;
return
props
?.
title
??
article
?.
value
?.
title
??
props
.
doi
;
});
});
...
@@ -32,16 +35,11 @@ const articleAbstract = computed(() => {
...
@@ -32,16 +35,11 @@ const articleAbstract = computed(() => {
});
});
</
script
>
</
script
>
<
template
>
<
template
>
<v-list-item
:href=
"article?.href"
:id=
"`ref-$
{props.doi}`" :target="article?.target" density="compact"
color="transparent"
<v-list-item
:href=
"article?.href"
:id=
"`ref-$
{props.doi}`" :target="article?.target" density="compact"
class="px-1">
color="transparent"
class="px-1">
<template
v-if=
"!mobile"
#prepend
>
<template
v-if=
"!mobile"
#prepend
>
<v-icon
icon=
"md:star"
:color=
"props.isRelevant ? 'info' : 'transparent'"
></v-icon>
<v-icon
icon=
"md:star"
:color=
"props.isRelevant ? 'info' : 'transparent'"
></v-icon>
</
template
>
</
template
>
<!-- <template v-if="!mobile" #append>
<v-btn v-if="articleAbstract" size="x-small" variant="plain"
:append-icon="show ? 'mdi-chevron-up' : 'mdi-chevron-down'" class="px-0"
@click.stop.prevent="show = !show">Abstract</v-btn>
</template> -->
<v-card
flat
color=
"transparent"
density=
"compact"
class=
"my-0 article-ref"
>
<v-card
flat
color=
"transparent"
density=
"compact"
class=
"my-0 article-ref"
>
<v-card-item
density=
"compact"
class=
"pa-0"
>
<v-card-item
density=
"compact"
class=
"pa-0"
>
<v-toolbar
class=
"py-0 d-flex align-start article-toolbar"
color=
"transparent"
:height=
"20"
>
<v-toolbar
class=
"py-0 d-flex align-start article-toolbar"
color=
"transparent"
:height=
"20"
>
...
@@ -51,9 +49,6 @@ const articleAbstract = computed(() => {
...
@@ -51,9 +49,6 @@ const articleAbstract = computed(() => {
:append-icon=
"show ? 'mdi-chevron-up' : 'mdi-chevron-down'"
class=
"px-1 align-center"
:append-icon=
"show ? 'mdi-chevron-up' : 'mdi-chevron-down'"
class=
"px-1 align-center"
@
click.stop.prevent=
"show = !show"
>
Abstract
</v-btn>
@
click.stop.prevent=
"show = !show"
>
Abstract
</v-btn>
</v-toolbar>
</v-toolbar>
<!-- <v-card-title class="py-0"><span class="font-weight-bold">{{
articleTitle
}}</span></v-card-title> -->
<v-card-subtitle
class=
"py-0"
>
<v-card-subtitle
class=
"py-0"
>
{{ article?.subtitle ?? "no authors" }}
</v-card-subtitle>
{{ article?.subtitle ?? "no authors" }}
</v-card-subtitle>
<v-card-subtitle
class=
"py-0"
>
<v-card-subtitle
class=
"py-0"
>
...
...
This diff is collapsed.
Click to expand it.
composables/useFetchArticle.ts
+
42
−
87
View file @
8d33275f
import
{
useArticlesStore
}
from
'
../stores/articles
'
import
{
ref
,
toValue
}
from
"
vue
"
import
{
ref
,
computed
,
watchEffect
,
toValue
}
from
"
vue
"
import
{
StorageSerializers
}
from
"
@vueuse/core
"
// import { useFetch } from '#app';
import
type
{
CslJson
,
WikiArticle
}
from
'
@/types/articles
'
;
// import { useFetch } from "nuxt"
import
type
{
SearchParams
}
from
'
meilisearch
'
import
{
type
MaybeRef
,
useFetch
}
from
'
#imports
'
import
type
{
CslJson
,
CrossrefArticle
,
SrcArticle
}
from
'
@/types/articles
'
;
export
async
function
useFetchArticle
(
doi
:
string
=
""
)
{
export
function
useFetchArticle
(
doi
:
MaybeRef
<
string
>
=
ref
(
""
))
{
// const article = ref<Article>()
// const rawArticle = ref<RawArticle>()
const
srcArticle
=
ref
<
SrcArticle
|
null
>
(
null
)
const
store
=
useArticlesStore
()
const
pending
=
ref
(
false
)
const
doiBaseUrl
=
ref
(
new
URL
(
"
https://doi.org/
"
));
const
doiBaseUrl
=
ref
(
new
URL
(
"
https://doi.org/
"
));
const
url
=
ref
(
new
URL
(
`/works/
${
toValue
(
doi
)}
`
,
"
https://api.crossref.org/
"
).
href
);
// const article = ref<WikiArticle | undefined>(undefined)
const
article
=
ref
()
const
article
=
useSessionStorage
<
WikiArticle
>
(
doi
,
null
,
{
serializer
:
StorageSerializers
.
object
})
const
zoteroArticles
=
ref
()
const
client
=
useMeiliSearchRef
()
const
index
=
ref
(
"
article
"
)
const
params
=
ref
<
SearchParams
>
({
facets
:
[
"
*
"
],
filter
:
[
`DOI='
${
doi
}
'`
],
limit
:
1
})
function
getReferenceUrl
(
doi
:
string
)
{
return
new
URL
(
doi
,
doiBaseUrl
.
value
).
href
;
}
function
toAuthorsString
(
authors
:
Array
<
{
family
:
string
;
given
:
string
}
>
)
{
function
toAuthorsString
(
authors
:
Array
<
{
family
:
string
;
given
:
string
}
>
)
{
return
authors
return
authors
.
map
((
curr
)
=>
{
.
map
((
curr
)
=>
{
...
@@ -28,12 +24,7 @@ export function useFetchArticle(doi: MaybeRef<string> = ref("")) {
...
@@ -28,12 +24,7 @@ export function useFetchArticle(doi: MaybeRef<string> = ref("")) {
})
})
.
join
(
"
,
"
);
.
join
(
"
,
"
);
}
}
function
zoteroArticleToArticle
(
zoteroArticle
:
CslJson
):
WikiArticle
|
undefined
{
function
getReferenceUrl
(
doi
:
string
)
{
return
new
URL
(
doi
,
doiBaseUrl
.
value
).
href
;
}
function
zoteroArticleToArticle
(
zoteroArticle
:
CslJson
)
{
if
(
zoteroArticle
!=
undefined
)
{
if
(
zoteroArticle
!=
undefined
)
{
const
{
const
{
DOI
,
DOI
,
...
@@ -56,74 +47,38 @@ export function useFetchArticle(doi: MaybeRef<string> = ref("")) {
...
@@ -56,74 +47,38 @@ export function useFetchArticle(doi: MaybeRef<string> = ref("")) {
target
:
"
_blank
"
,
target
:
"
_blank
"
,
prependIcon
:
"
mdi-newspaper-variant-outline
"
,
prependIcon
:
"
mdi-newspaper-variant-outline
"
,
}
}
}
}
else
{
return
undefined
}
}
if
(
!
article
.
value
)
{
const
{
data
,
error
}
=
await
useAsyncData
(
doi
,
async
()
=>
{
return
await
client
.
index
(
toValue
(
index
)).
search
<
CslJson
>
(
""
,
toValue
(
params
))
},
{
transform
:
function
(
data
)
{
if
(
data
!==
undefined
&&
data
?.
hits
.
length
>=
1
)
{
return
zoteroArticleToArticle
(
data
.
hits
[
0
])
}
}
}
)
}
if
(
error
.
value
)
{
function
crossrefToArticle
(
article
:
CrossrefArticle
):
WikiArticle
{
throw
createError
({
const
{
title
,
DOI
,
type
,
"
container-title
"
:
ct
,
"
short-container-title
"
:
sct
,
abstract
,
author
,
issued
}
=
article
...
error
.
value
,
// let sanitizedAbstract = abstract
statusMessage
:
`Could not fetch article
${
doi
}
`
const
sanitizedAbstract
=
abstract
?
/
(?:\<
jats
\:
p
\>)?(
.*
)(?:\<\/
jats
\:
p
\>)?
/
.
exec
(
abstract
)?.[
1
]
??
''
:
''
})
const
sanitizedContainerTitle
=
sct
?.
length
>
0
?
sct
[
0
]
:
ct
?.
length
>
0
?
ct
[
0
]
:
""
return
{
title
:
title
?.
length
>
0
?
title
[
0
]
:
""
,
DOI
,
abstract
:
sanitizedAbstract
,
containerTitle
:
sanitizedContainerTitle
,
subtitle
:
toAuthorsString
(
author
||
[]),
author
,
year
:
issued
?.[
"
date-parts
"
][
0
][
0
]
??
''
,
href
:
getReferenceUrl
(
DOI
),
target
:
"
_blank
"
,
prependIcon
:
"
mdi-newspaper-variant-outline
"
}
}
article
.
value
=
data
.
value
}
}
return
{
article
}
}
function
crossrefToCsl
(
article
:
CrossrefArticle
):
CslJson
{
const
{
title
,
DOI
,
type
,
"
container-title
"
:
ct
,
"
short-container-title
"
:
sct
,
abstract
,
author
,
issued
}
=
article
// let sanitizedAbstract = abstract
const
sanitizedAbstract
=
abstract
?
/
(?:\<
jats
\:
p
\>)?(
.*
)(?:\<\/
jats
\:
p
\>)?
/
.
exec
(
abstract
)?.[
1
]
??
''
:
''
const
sanitizedContainerTitle
=
sct
?.
length
>
0
?
sct
[
0
]
:
ct
?.
length
>
0
?
ct
[
0
]
:
""
return
{
title
:
title
?.
length
>
0
?
title
[
0
]
:
""
,
type
,
DOI
,
abstract
:
sanitizedAbstract
,
author
,
"
container-title
"
:
sanitizedContainerTitle
,
issued
}
}
if
(
store
.
articles
.
has
(
toValue
(
doi
)))
{
const
cslArticle
=
store
.
articles
.
get
(
toValue
(
doi
))
article
.
value
=
cslArticle
?
zoteroArticleToArticle
(
cslArticle
)
:
undefined
}
else
{
useFetch
<
RawArticle
>
(
toValue
(
url
),
{
lazy
:
true
,
server
:
false
,
}).
then
(({
data
,
pending
:
pendingUseFetch
})
=>
{
if
(
data
.
value
?.
message
)
{
article
.
value
=
crossrefToArticle
(
data
.
value
.
message
)
store
.
add
(
crossrefToCsl
(
data
.
value
.
message
))
}
pending
.
value
=
pendingUseFetch
.
value
})
}
// const fetchCrossRef = () => {
// useFetch<RawArticle>(toValue(url), {
// lazy: true, server: false,
// }).then(({ data, pending: pendingUseFetch }) => {
// if (data.value?.message) {
// srcArticle.value = data.value.message
// }
// pending.value = pendingUseFetch.value
// })
// }
return
{
article
,
pending
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment