Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
57c9d37f
Unverified
Commit
57c9d37f
authored
Jun 05, 2023
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: admin locales UI + auto locales update + auto version check
parent
2587778e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
90 additions
and
63 deletions
+90
-63
3.0.0.mjs
server/db/migrations/3.0.0.mjs
+3
-1
en.json
server/locales/en.json
+5
-0
check-version.mjs
server/tasks/simple/check-version.mjs
+9
-1
update-locales.mjs
server/tasks/simple/update-locales.mjs
+41
-1
apollo.js
ux/src/boot/apollo.js
+1
-1
AdminLocale.vue
ux/src/pages/AdminLocale.vue
+29
-57
user.js
ux/src/stores/user.js
+2
-2
No files found.
server/db/migrations/3.0.0.mjs
View file @
57c9d37f
...
...
@@ -514,7 +514,9 @@ export async function up (knex) {
{
key
:
'update'
,
value
:
{
locales
:
true
lastCheckedAt
:
null
,
version
:
null
,
versionDate
:
null
}
},
{
...
...
server/locales/en.json
View file @
57c9d37f
...
...
@@ -356,6 +356,7 @@
"admin.instances.lastSeen"
:
"Last Seen"
,
"admin.instances.subtitle"
:
"View a list of active instances"
,
"admin.instances.title"
:
"Instances"
,
"admin.locale.active"
:
"Active Locales"
,
"admin.locale.activeNamespaces"
:
"Active Namespaces"
,
"admin.locale.autoUpdate.hint"
:
"Automatically download updates to this locale as they become available."
,
"admin.locale.autoUpdate.hintWithNS"
:
"Automatically download updates to all namespaced locales enabled below."
,
...
...
@@ -368,6 +369,8 @@
"admin.locale.download"
:
"Download"
,
"admin.locale.downloadNew"
:
"Install New Locale"
,
"admin.locale.downloadTitle"
:
"Download Locale"
,
"admin.locale.forcePrefix"
:
"Force Locale Prefix"
,
"admin.locale.forcePrefixHint"
:
"Paths without a locale code will always be redirected to the primary locale."
,
"admin.locale.name"
:
"Name"
,
"admin.locale.namespaces.hint"
:
"Enables multiple language versions of the same page."
,
"admin.locale.namespaces.label"
:
"Multilingual Namespaces"
,
...
...
@@ -375,6 +378,8 @@
"admin.locale.namespacingPrefixWarning.subtitle"
:
"Paths without a locale code will be automatically redirected to the base locale defined above."
,
"admin.locale.namespacingPrefixWarning.title"
:
"The locale code will be prefixed to all paths. (e.g. /{langCode}/page-name)"
,
"admin.locale.nativeName"
:
"Native Name"
,
"admin.locale.primary"
:
"Primary Locale"
,
"admin.locale.primaryHint"
:
"The locale to use as default / fallback for this site."
,
"admin.locale.rtl"
:
"RTL"
,
"admin.locale.settings"
:
"Locale Settings"
,
"admin.locale.sideload"
:
"Sideload Locale Package"
,
...
...
server/tasks/simple/check-version.mjs
View file @
57c9d37f
...
...
@@ -2,7 +2,15 @@ export async function task (payload) {
WIKI
.
logger
.
info
(
'Checking for latest version...'
)
try
{
// TODO: Fetch latest version
const
resp
=
await
fetch
(
'https://api.github.com/repos/requarks/wiki/releases/latest'
).
then
(
r
=>
r
.
json
())
WIKI
.
logger
.
info
(
`Latest version is
${
resp
.
tag_name
}
.`
)
await
WIKI
.
db
.
knex
(
'settings'
).
where
(
'key'
,
'update'
).
update
({
value
:
{
lastCheckedAt
:
(
new
Date
).
toISOString
(),
version
:
resp
.
tag_name
,
versionDate
:
resp
.
published_at
}
})
WIKI
.
logger
.
info
(
'Checked for latest version: [ COMPLETED ]'
)
}
catch
(
err
)
{
...
...
server/tasks/simple/update-locales.mjs
View file @
57c9d37f
import
{
setTimeout
}
from
'node:timers/promises'
export
async
function
task
(
payload
)
{
if
(
WIKI
.
config
.
update
?.
locales
===
false
)
{
return
}
WIKI
.
logger
.
info
(
'Fetching latest localization data...'
)
try
{
// TODO: Fetch locale updates
const
metadata
=
await
fetch
(
'https://github.com/requarks/wiki-locales/raw/main/locales/metadata.json'
).
then
(
r
=>
r
.
json
())
for
(
const
lang
of
metadata
.
languages
)
{
// -> Build filename
const
langFilenameParts
=
[
lang
.
language
]
if
(
lang
.
region
)
{
langFilenameParts
.
push
(
lang
.
region
)
}
if
(
lang
.
script
)
{
langFilenameParts
.
push
(
lang
.
script
)
}
const
langFilename
=
langFilenameParts
.
join
(
'-'
)
WIKI
.
logger
.
debug
(
`Fetching updates for language
${
langFilename
}
...`
)
const
strings
=
await
fetch
(
`https://github.com/requarks/wiki-locales/raw/main/locales/
${
langFilename
}
.json`
).
then
(
r
=>
r
.
json
())
if
(
strings
)
{
await
WIKI
.
db
.
knex
(
'locales'
).
insert
({
code
:
langFilename
,
name
:
lang
.
name
,
nativeName
:
lang
.
localizedName
,
language
:
lang
.
language
,
region
:
lang
.
region
,
script
:
lang
.
script
,
isRTL
:
lang
.
isRtl
,
strings
}).
onConflict
(
'code'
).
merge
({
strings
,
updatedAt
:
new
Date
()
})
}
WIKI
.
logger
.
debug
(
`Updated strings for language
${
langFilename
}
.`
)
await
setTimeout
(
100
)
}
WIKI
.
logger
.
info
(
'Fetched latest localization data: [ COMPLETED ]'
)
}
catch
(
err
)
{
...
...
ux/src/boot/apollo.js
View file @
57c9d37f
...
...
@@ -29,7 +29,7 @@ export default boot(({ app }) => {
}
// -> Refresh Token
if
(
!
userStore
.
isTokenValid
())
{
if
(
!
userStore
.
isTokenValid
(
{
minutes
:
1
}
))
{
if
(
!
fetching
)
{
refreshPromise
=
new
Promise
((
resolve
,
reject
)
=>
{
(
async
()
=>
{
...
...
ux/src/pages/AdminLocale.vue
View file @
57c9d37f
...
...
@@ -7,15 +7,6 @@ q-page.admin-locale
.text-h5.text-primary.animated.fadeInLeft
{{
t
(
'admin.locale.title'
)
}}
.text-subtitle1.text-grey.animated.fadeInLeft.wait-p2s
{{
t
(
'admin.locale.subtitle'
)
}}
.col-auto.flex
q-btn.q-mr-md(
icon='las la-download'
:label='t(`admin.locale.downloadNew`)'
unelevated
color='primary'
:disabled='state.loading > 0'
@click='installNewLocale'
)
q-separator.q-mr-md(vertical)
q-btn.q-mr-sm.acrylic-btn(
icon='las la-question-circle'
flat
...
...
@@ -55,73 +46,65 @@ q-page.admin-locale
q-item
blueprint-icon(icon='translation')
q-item-section
q-item-label
{{
state
.
namespacing
?
t
(
`admin.locale.base.labelWithNS`
)
:
t
(
`admin.locale.base.label
`
)
}}
q-item-label(caption)
{{
t
(
`admin.locale.
base.h
int`
)
}}
q-item-label
{{
t
(
`admin.locale.primary
`
)
}}
q-item-label(caption)
{{
t
(
`admin.locale.
primaryH
int`
)
}}
q-item-section
q-select(
outlined
v-model='state.primary'
:options='
installedL
ocales'
:options='
state.l
ocales'
option-value='code'
option-label='name'
emit-value
map-options
dense
:aria-label='t(`admin.locale.
base.label
`)'
:aria-label='t(`admin.locale.
primary
`)'
)
q-separator.q-my-sm(inset)
q-item(tag='label')
blueprint-icon(icon='unit')
q-item-section
q-item-label
{{
t
(
`admin.locale.
namespaces.label
`
)
}}
q-item-label(caption)
{{
t
(
`admin.locale.
namespaces.h
int`
)
}}
q-item-label
{{
t
(
`admin.locale.
forcePrefix
`
)
}}
q-item-label(caption)
{{
t
(
`admin.locale.
forcePrefixH
int`
)
}}
q-item-section(avatar)
q-toggle(
v-model='state.
namespacing
'
v-model='state.
forcePrefix
'
color='primary'
checked-icon='las la-check'
unchecked-icon='las la-times'
:aria-label='t(`admin.locale.
namespaces.label
`)'
:aria-label='t(`admin.locale.
forcePrefixHint
`)'
)
q-item
q-item-section
q-card.bg-info.text-white.rounded-borders(flat)
q-card-section.items-center(horizontal)
q-card-section.col-auto.q-pr-none
q-icon(name='las la-info-circle', size='sm')
q-card-section
span
{{
t
(
'admin.locale.namespacingPrefixWarning.title'
,
{
langCode
:
state
.
selectedLocale
}
)
}}
.
text
-
caption
.
text
-
yellow
-
1
{{
t
(
'admin.locale.namespacingPrefixWarning.subtitle'
)
}}
.
col
-
12
.
col
-
lg
-
5
//- -----------------------
//-
Namespacing
//-
Active Locales
//- -----------------------
q
-
card
.
q
-
pb
-
sm
(
v
-
if
=
'state.namespacing'
)
q-card.q-pb-sm
.q-mt-md
q-card-section
.
text
-
subtitle1
{{
t
(
'admin.locale.activeNamespaces'
)
}}
.text-subtitle1
{{
t
(
'admin.locale.active'
)
}}
.text-caption(:class='$q.dark.isActive ? `text-grey-4` : `text-grey-7`') Select the locales that can be used on this site.
q-item(
v
-
for
=
'(lc, idx) of
installedL
ocales'
v-for='(lc, idx) of
state.l
ocales'
:key='lc.code'
:tag='lc.code !== state.selectedLocale ? `label` : null'
)
blueprint
-
icon
(:
text
=
'lc.
cod
e'
)
blueprint-icon(:text='lc.
languag
e')
q-item-section
q
-
item
-
label
{{
lc
.
name
}}
q
-
item
-
label
(
caption
)
{{
lc
.
na
tiveName
}}
q-item-label
{{
lc
.
na
tiveNa
me
}}
q-item-label(caption)
{{
lc
.
na
me
}}
(
{{
lc
.
code
}}
)
q-item-section(avatar)
q-toggle(
:
disable
=
'lc.code === state.
selectedLocale
'
v
-
model
=
'state.
namespaces
'
:disable='lc.code === state.
primary
'
v-model='state.
active
'
:val='lc.code'
color
=
'primary
'
:color='lc.code === state.primary ? `secondary` : `primary`
'
checked-icon='las la-check'
unchecked-icon='las la-times'
:aria-label='lc.name'
)
.
q
-
pa
-
md
.
text
-
center
.
gt
-
md
(
v
-
else
)
.col-12.col-lg-5
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_world.svg', style='width: 80%;')
//- q-separator.q-my-sm(inset)
...
...
@@ -150,7 +133,7 @@ q-page.admin-locale
<
script
setup
>
import
gql
from
'graphql-tag'
import
{
cloneDeep
,
filter
}
from
'lodash-es'
import
{
cloneDeep
,
sortBy
}
from
'lodash-es'
import
LocaleInstallDialog
from
'../components/LocaleInstallDialog.vue'
...
...
@@ -186,15 +169,10 @@ const state = reactive({
loading
:
0
,
locales
:
[],
primary
:
'en'
,
forcePrefix
:
false
,
active
:
[]
})
// COMPUTED
const
installedLocales
=
computed
(()
=>
{
return
filter
(
state
.
locales
,
[
'isInstalled'
,
true
])
}
)
// WATCHERS
watch
(()
=>
adminStore
.
currentSiteId
,
(
newValue
)
=>
{
...
...
@@ -226,9 +204,8 @@ async function load () {
completeness
code
createdAt
isInstalled
installDate
isRTL
language
name
nativeName
region
...
...
@@ -241,7 +218,9 @@ async function load () {
id
locales {
primary
active
active {
code
}
}
}
}
...
...
@@ -251,9 +230,9 @@ async function load () {
},
fetchPolicy
:
'network-only'
})
state
.
locales
=
cloneDeep
(
resp
?.
data
?.
locales
)
state
.
locales
=
sortBy
(
cloneDeep
(
resp
?.
data
?.
locales
),
[
'nativeName'
,
'name'
]
)
state
.
primary
=
cloneDeep
(
resp
?.
data
?.
siteById
?.
locales
?.
primary
)
state
.
active
=
cloneDeep
(
resp
?.
data
?.
siteById
?.
locales
?.
active
??
[])
state
.
active
=
cloneDeep
(
resp
?.
data
?.
siteById
?.
locales
?.
active
??
[])
.
map
(
l
=>
l
.
code
)
if
(
!
state
.
active
.
includes
(
state
.
primary
))
{
state
.
active
.
push
(
state
.
primary
)
}
...
...
@@ -337,17 +316,10 @@ async function save () {
})
const
resp
=
respRaw
?.
data
?.
localization
?.
updateLocale
?.
responseResult
||
{}
if
(
resp
.
succeeded
)
{
// Change UI language
this
.
$i18n
.
locale
=
state
.
selectedLocale
$q
.
notify
({
type
:
'positive'
,
message
:
'Locale settings updated successfully.'
})
setTimeout
(()
=>
{
window
.
location
.
reload
(
true
)
}
,
1000
)
}
else
{
$q
.
notify
({
type
:
'negative'
,
...
...
ux/src/stores/user.js
View file @
57c9d37f
...
...
@@ -40,8 +40,8 @@ export const useUserStore = defineStore('user', {
}
},
actions
:
{
isTokenValid
()
{
return
this
.
exp
&&
this
.
exp
>
DateTime
.
now
(
)
isTokenValid
(
offset
)
{
return
this
.
exp
&&
this
.
exp
>
(
offset
?
DateTime
.
now
().
plus
(
offset
)
:
DateTime
.
now
()
)
},
loadToken
()
{
if
(
!
this
.
token
)
{
return
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment