Add importing spreadsheet ability
This commit is contained in:
817
package-lock.json
generated
817
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,8 @@
|
||||
"markdown-it": "^13.0.1",
|
||||
"passport": "^0.5.2",
|
||||
"passport-local": "^1.0.0",
|
||||
"pug": "^3.0.2"
|
||||
"pug": "^3.0.2",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prompt": "^1.3.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const express = require('express')
|
||||
const XL = require('excel4node');
|
||||
const XLSX = require("xlsx");
|
||||
|
||||
module.exports = function (options) {
|
||||
const db = options.db;
|
||||
@@ -1394,5 +1395,146 @@ module.exports = function (options) {
|
||||
}
|
||||
}
|
||||
|
||||
router.route('/:id/import')
|
||||
.get(function(request, response, next) {
|
||||
db.Project.findByPk(request.params.id, {
|
||||
include: [
|
||||
{
|
||||
association: db.Project.Owner,
|
||||
include: [
|
||||
{
|
||||
association: db.Owner.OwnerEntities,
|
||||
include: [
|
||||
{
|
||||
association: db.OwnerEntity.Entity,
|
||||
include: [
|
||||
{
|
||||
association: db.Entity.EntityUsers,
|
||||
required: false,
|
||||
where: {
|
||||
userId: request.user?.id ?? null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}).then(async (project) => {
|
||||
if (project) {
|
||||
response.display("project-translation-importer", {
|
||||
user: request.user,
|
||||
project: project
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}).catch(error => {
|
||||
next(error)
|
||||
})
|
||||
})
|
||||
.post(function(request, response, next) {
|
||||
db.Project.findByPk(request.params.id, {
|
||||
include: [
|
||||
{
|
||||
association: db.Project.Owner,
|
||||
include: [
|
||||
{
|
||||
association: db.Owner.OwnerEntities,
|
||||
include: [
|
||||
{
|
||||
association: db.OwnerEntity.Entity,
|
||||
include: [
|
||||
{
|
||||
association: db.Entity.EntityUsers,
|
||||
required: false, // TODO: Make required...
|
||||
where: {
|
||||
userId: request.user?.id ?? null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}).then(async (project) => {
|
||||
if (project && request.files) {
|
||||
const file = request.files.translations
|
||||
|
||||
const workbook = XLSX.read(file.data, {
|
||||
|
||||
});
|
||||
|
||||
for (const sheetName in workbook.Sheets) {
|
||||
const sheet = workbook.Sheets[sheetName];
|
||||
|
||||
const artifactVersionId = sheet["D4"].v
|
||||
const translationArtifactVersionId = sheet["E4"].v
|
||||
|
||||
var lastTranslationChunkId = null
|
||||
var i = 6
|
||||
do {
|
||||
lastTranslationChunkId = null
|
||||
const translationChunkCell = sheet[`D${i}`]
|
||||
if (translationChunkCell) {
|
||||
lastTranslationChunkId = translationChunkCell.v
|
||||
const translatedText = sheet[`C${i}`].v
|
||||
|
||||
if (translatedText) {
|
||||
console.log("Text: ", translatedText)
|
||||
console.log("Chunk Id: ", lastTranslationChunkId)
|
||||
// TODO: Get translationChunk and create translation...
|
||||
const translationChunk = await db.TranslationChunk.findByPk(lastTranslationChunkId, {
|
||||
include: [
|
||||
{
|
||||
association: db.TranslationChunk.Translation
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
if (translationChunk) {
|
||||
// Create or update translation
|
||||
if (translationChunk.translation) {
|
||||
// Update translation
|
||||
if (translationChunk.translation.text != translatedText) {
|
||||
translationChunk.translation.text = translatedText
|
||||
// TODO: Update who made the update??
|
||||
await translationChunk.translation.save()
|
||||
}
|
||||
} else {
|
||||
// Create translation for this chunk
|
||||
const translation = await db.Translation.create({
|
||||
creatorId: request.user.id,
|
||||
translationChunkId: translationChunk.id,
|
||||
text: translatedText,
|
||||
translationArtifactVersionId: translationArtifactVersionId
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
|
||||
} while (lastTranslationChunkId);
|
||||
|
||||
// Chunks...
|
||||
|
||||
console.log("Done processing all...")
|
||||
}
|
||||
|
||||
response.redirect(`/project/${project.id}`)
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}).catch(error => {
|
||||
next(error)
|
||||
})
|
||||
})
|
||||
|
||||
return router;
|
||||
};
|
||||
@@ -29,7 +29,15 @@ block content
|
||||
each val, key in query
|
||||
if key != "sheets"
|
||||
input(type="hidden", name=key, value=val)
|
||||
button.btn.black(type="submit") export to spreadsheets
|
||||
button.btn.black(type="submit")
|
||||
i.material-icons.left file_download
|
||||
span export to spreadsheets
|
||||
.row
|
||||
.col.s12
|
||||
a.btn.black(href=`/projects/${project.id}/import`)
|
||||
i.material-icons.left file_upload
|
||||
span import spreadsheets
|
||||
|
||||
.divider
|
||||
|
||||
table.highlight
|
||||
|
||||
31
server/views/project-translation-importer.pug
Normal file
31
server/views/project-translation-importer.pug
Normal file
@@ -0,0 +1,31 @@
|
||||
extend templates/layout.pug
|
||||
|
||||
block content
|
||||
-
|
||||
const isOwnedByUser = project.owner.ownerEntities.some(ownerEntity => {
|
||||
return ownerEntity.entity.entityUsers.some(entityUser => {
|
||||
return entityUser.userId == user?.id
|
||||
})
|
||||
})
|
||||
.container
|
||||
.center
|
||||
h1
|
||||
small import
|
||||
span= project.name
|
||||
small translations
|
||||
p.flow-text= project.description
|
||||
|
||||
.row
|
||||
.col.s12
|
||||
form.row(action=`/projects/${project.id}/import`, method="post", encType="multipart/form-data")
|
||||
//- .col.s12.input-field
|
||||
textarea#textarea.materialize-textarea(name="text")
|
||||
label(for="textarea") Entire chapter text (markdown)
|
||||
.file-field.input-field.col.s12
|
||||
.btn
|
||||
span File
|
||||
input#file-input(type="file", name="translations")
|
||||
.file-path-wrapper
|
||||
input.file-path.validate(type="text", placeholder="Import translations")
|
||||
.col.s12
|
||||
button.btn.black(type="submit") import translations
|
||||
Reference in New Issue
Block a user