Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1940 from botpress/fl_qna_import_export_broken
feat(qna): QNA import and export use JSON format for QNA items
- Loading branch information
Showing
5 changed files
with
79 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,22 @@ | ||
import _ from 'lodash' | ||
|
||
import * as parsers from './parsers.js' | ||
|
||
const ANSWERS_SPLIT_CHAR = '†' | ||
|
||
export const importQuestions = async (questions, params) => { | ||
const { storage, config, format = 'json', statusCallback, uploadStatusId } = params | ||
import { QnaItem, QnaEntry } from './qna' | ||
import Storage from './storage' | ||
|
||
export const importQuestions = async (questions: QnaItem[], storage, statusCallback, uploadStatusId) => { | ||
statusCallback(uploadStatusId, 'Calculating diff with existing questions') | ||
|
||
const existingQuestions = (await storage.fetchAllQuestions()).map(item => | ||
JSON.stringify(_.omit(item.data, 'enabled')) | ||
) | ||
|
||
const hasCategory = storage.hasCategories() | ||
const parsedQuestions = | ||
typeof questions === 'string' ? parsers[`${format}Parse`](questions, { hasCategory }) : questions | ||
const questionsToSave = parsedQuestions.filter(item => !existingQuestions.includes(JSON.stringify(item))) | ||
|
||
if (config.qnaMakerApiKey) { | ||
return storage.insert(questionsToSave.map(question => ({ ...question, enabled: true }))) | ||
} | ||
const existingQuestionItems = (await (storage as Storage).fetchQNAs()).map(item => item.id) | ||
const itemsToSave = questions.filter(item => !existingQuestionItems.includes(item.id)) | ||
const entriesToSave = itemsToSave.map(q => q.data) | ||
|
||
let questionsSavedCount = 0 | ||
return Promise.each(questionsToSave, async question => { | ||
const answers = question['answer'].split(ANSWERS_SPLIT_CHAR) | ||
await storage.insert({ ...question, answers, enabled: true }) | ||
return Promise.each(entriesToSave, async (question: QnaEntry) => { | ||
await (storage as Storage).insert({ ...question, enabled: true }) | ||
questionsSavedCount += 1 | ||
statusCallback(uploadStatusId, `Saved ${questionsSavedCount}/${questionsToSave.length} questions`) | ||
statusCallback(uploadStatusId, `Saved ${questionsSavedCount}/${entriesToSave.length} questions`) | ||
}) | ||
} | ||
|
||
export const prepareExport = async (storage, { flat = false } = {}) => { | ||
const qnas = await storage.fetchAllQuestions() | ||
|
||
return _.flatMap(qnas, question => { | ||
const { data } = question | ||
const { questions, action, redirectNode, redirectFlow, category, answers, answer: textAnswer } = data | ||
|
||
// FIXME: Remove v11.2 answer support | ||
let answer = answers.join(ANSWERS_SPLIT_CHAR) || textAnswer // textAnswer allow to support v11.2 answer format | ||
let answer2 = undefined | ||
|
||
// FIXME: Refactor these answer, answer2 fieds for something more meaningful like a 'redirect' field. | ||
// redirect dont need text so answer is overriden with the redirect flow | ||
if (action === 'redirect') { | ||
answer = redirectFlow | ||
if (redirectNode) { | ||
answer += '#' + redirectNode | ||
} | ||
// text_redirect will display a text before redirecting to the desired flow | ||
} else if (action === 'text_redirect') { | ||
answer2 = redirectFlow | ||
if (redirectNode) { | ||
answer2 += '#' + redirectNode | ||
} | ||
} | ||
const categoryWrapper = storage.getCategories() ? { category } : {} | ||
|
||
if (!flat) { | ||
return { questions, action, answer, answer2, ...categoryWrapper } | ||
} | ||
return questions.map(question => ({ question, action, answer, answer2, ...categoryWrapper })) | ||
}) | ||
export const prepareExport = async (storage: Storage) => { | ||
const qnas = await storage.fetchQNAs() | ||
return JSON.stringify(qnas, undefined, 2) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters