diff --git a/src/Layout/Routes.js b/src/Layout/Routes.js index c7d9880d..573c4d5a 100644 --- a/src/Layout/Routes.js +++ b/src/Layout/Routes.js @@ -4,20 +4,19 @@ import { Route, Routes } from "react-router-dom"; // eslint-disable-next-line import/no-unresolved import config from "config"; import AuthorsRoute from "pages/AuthorsRoute"; +import CorpImport from "pages/CorpImport"; import { CreateCorpus, CreateDictionary } from "pages/CreateDictionary"; import { CorpusDashboard, DictionaryDashboard, ParallelCorporaDashboard } from "pages/Dashboard"; import DashboardRoute from "pages/DashboardRoute"; import Desktop from "pages/Desktop"; import DialeqtImport from "pages/DialeqtImport"; import DictImport from "pages/DictImport"; -import CorpImport from "pages/CorpImport"; import DictionariesAll from "pages/DictionariesAll"; import DistanceMap from "pages/DistanceMap"; import MapSelectedLanguages from "pages/DistanceMap/map"; import SelectedLanguages from "pages/DistanceMap/selectorLangGroup"; import Docx2Eaf from "pages/Docx2Eaf"; import Docx2Xlsx from "pages/Docx2Xlsx"; -import ListCognates from "pages/ListCognates"; import EditTranslations from "pages/EditTranslations"; import Files from "pages/Files"; import Grants from "pages/Grants"; @@ -25,6 +24,7 @@ import GrantsRoute from "pages/GrantsRoute"; import Info from "pages/Info"; import Languages from "pages/Languages"; import LanguagesDatabasesRoute from "pages/LanguagesDatabasesRoute"; +import ListCognates from "pages/ListCognates"; import Map from "pages/Map"; import NotFound from "pages/NotFound"; import Organizations from "pages/Organizations"; diff --git a/src/components/CognateAnalysisModal/index.js b/src/components/CognateAnalysisModal/index.js index c83b1c57..7e1aa9ce 100644 --- a/src/components/CognateAnalysisModal/index.js +++ b/src/components/CognateAnalysisModal/index.js @@ -12,7 +12,9 @@ import { Loader, Modal, Pagination, - Select + Select, + Input, + Label } from "semantic-ui-react"; import { gql } from "@apollo/client"; import { graphql, withApollo } from "@apollo/client/react/hoc"; @@ -176,6 +178,7 @@ const computeCognateAnalysisMutation = gql` translation_count result xlsx_url + json_url figure_url minimum_spanning_tree embedding_2d @@ -208,6 +211,7 @@ const computeSwadeshAnalysisMutation = gql` transcription_count result xlsx_url + json_url minimum_spanning_tree embedding_2d embedding_3d @@ -236,6 +240,7 @@ const computeMorphCognateAnalysisMutation = gql` transcription_count result xlsx_url + json_url minimum_spanning_tree embedding_2d embedding_3d @@ -244,6 +249,26 @@ const computeMorphCognateAnalysisMutation = gql` } `; +const computeComplexDistanceMutation = gql` + mutation complexDistance ( + $resultPool: [ObjectVal]! + $debugFlag: Boolean + ) { + complex_distance( + result_pool: $resultPool + debug_flag: $debugFlag + ) { + result + minimum_spanning_tree + embedding_2d + embedding_3d + perspective_name_list: language_name_list + message + triumph + } + } +`; + const SUGGESTIONS_PER_PAGE = 50; function equalIds(id_a, id_b) { @@ -1260,7 +1285,11 @@ class CognateAnalysisModal extends React.Component { result: null, xlsx_url: "", + json_url: "", figure_url: "", + fileSuite: null, + lang_mode: null, + cleanResult: false, minimum_spanning_tree: [], embedding_2d: [], @@ -1336,11 +1365,18 @@ class CognateAnalysisModal extends React.Component { this.admin_section_render = this.admin_section_render.bind(this); this.suggestions_render = this.suggestions_render.bind(this); + this.browse_files_render = this.browse_files_render.bind(this); this.sg_connect = this.sg_connect.bind(this); } componentDidMount() { + + if (this.props.mode === "complex_distance") { + this.setState({ lang_mode: "none", initialized: true }); + return; + } + const multi = this.props.mode === "multi_analysis" || this.props.mode === "multi_reconstruction" || @@ -1349,6 +1385,7 @@ class CognateAnalysisModal extends React.Component { this.props.mode === "multi_morphology"; (multi ? this.initialize_multi : this.initialize_single)(); + this.setState({ lang_mode: multi ? "multi" : "single" }); } initialize_common(allFields, columns, tree, english_status) { @@ -1796,13 +1833,7 @@ class CognateAnalysisModal extends React.Component { /* Selecting grouping field for many languages. */ - if ( - this.props.mode === "multi_analysis" || - this.props.mode === "multi_reconstruction" || - this.props.mode === "multi_suggestions" || - this.props.mode === "multi_swadesh" || - this.props.mode === "multi_morphology" - ) { + if (this.state.lang_mode === "multi") { this.state.groupFieldIdStr = value; const { perspectiveSelectionMap, perspectiveSelectionCountMap } = this.state; @@ -1841,7 +1872,7 @@ class CognateAnalysisModal extends React.Component { this.setState({ groupFieldIdStr: value }); - } else { + } else if (this.state.lang_mode === "single") { /* Selecting grouping field for a single language. */ this.setState({ groupFieldIdStr: value, @@ -1981,13 +2012,25 @@ class CognateAnalysisModal extends React.Component { } } + handleComplexDistanceResult({ data: { complex_distance }}) + { + this.setState({ + ...complex_distance, + /* Calculate plotly data */ + ...this.handleResult(complex_distance), + computing: false, + cleanResult: false + }); + } + handleSwadeshResult({ data: { swadesh_analysis }}) { this.setState({ ...swadesh_analysis, /* Calculate plotly data */ ...this.handleResult(swadesh_analysis), - computing: false + computing: false, + cleanResult: false }); } @@ -1997,7 +2040,8 @@ class CognateAnalysisModal extends React.Component { ...morph_cognate_analysis, /* Calculate plotly data */ ...this.handleResult(morph_cognate_analysis), - computing: false + computing: false, + cleanResult: false }); } @@ -2060,6 +2104,7 @@ class CognateAnalysisModal extends React.Component { ...this.handleResult(cognate_analysis), library_present: true, computing: false, + cleanResult: false, sg_select_list, sg_state_list, sg_count, @@ -2099,63 +2144,66 @@ class CognateAnalysisModal extends React.Component { } handleCreate() { - const { perspectiveId, computeCognateAnalysis, computeSwadeshAnalysis, computeMorphCognateAnalysis } = this.props; + const { + perspectiveId, + computeCognateAnalysis, + computeSwadeshAnalysis, + computeMorphCognateAnalysis, + computeComplexDistance + } = this.props; - const groupField = this.fieldDict[this.state.groupFieldIdStr]; + if (this.state.lang_mode === "single" || this.state.lang_mode === "multi") { + const groupField = this.fieldDict[this.state.groupFieldIdStr]; - /* Gathering info of perspectives we are to analyze. */ + /* Gathering info of perspectives we are to analyze. */ + let perspectiveInfoList = []; + const multiList = []; - let perspectiveInfoList = []; - const multiList = []; + if (this.state.lang_mode === "multi") { + for (const language of this.state.language_list) { + let p_count = 0; - if ( - this.props.mode === "multi_analysis" || - this.props.mode === "multi_reconstruction" || - this.props.mode === "multi_suggestions" || - this.props.mode === "multi_swadesh" || - this.props.mode === "multi_morphology" - ) { - for (const language of this.state.language_list) { - let p_count = 0; + for (const { perspective, treePathList: [subLanguage,] } of language.perspective_list) { + const p_key = id2str(perspective.id); - for (const { perspective } of language.perspective_list) { - const p_key = id2str(perspective.id); + if (this.state.perspectiveSelectionMap[p_key]) { + perspectiveInfoList.push([ + subLanguage.__typename === "Language" ? subLanguage.id : this.baseLanguageId, + perspective.id, + this.fieldDict[this.state.transcriptionFieldIdStrMap[p_key]].id, + this.fieldDict[this.state.translationFieldIdStrMap[p_key]].id, + this.fieldDict[this.state.lexemeFieldIdStrMap[p_key]].id + ]); - if (this.state.perspectiveSelectionMap[p_key]) { - perspectiveInfoList.push([ - perspective.id, - this.fieldDict[this.state.transcriptionFieldIdStrMap[p_key]].id, - this.fieldDict[this.state.translationFieldIdStrMap[p_key]].id, - this.fieldDict[this.state.lexemeFieldIdStrMap[p_key]].id - ]); - - p_count++; + p_count++; + } } + + multiList.push([language.id, p_count]); } + } else { + perspectiveInfoList = this.perspective_list + + .map(({ perspective, treePathList: [subLanguage,] }, index) => [ + subLanguage.__typename === "Language" ? subLanguage.id : this.baseLanguageId, + perspective.id, + this.fieldDict[this.state.transcriptionFieldIdStrList[index]].id, + this.fieldDict[this.state.translationFieldIdStrList[index]].id, + this.fieldDict[this.state.lexemeFieldIdStrList[index]].id + ]) - multiList.push([language.id, p_count]); + .filter((perspective_info, index) => this.state.perspectiveSelectionList[index]); } - } else { - perspectiveInfoList = this.perspective_list - .map(({ perspective }, index) => [ - perspective.id, - this.fieldDict[this.state.transcriptionFieldIdStrList[index]].id, - this.fieldDict[this.state.translationFieldIdStrList[index]].id, - this.fieldDict[this.state.lexemeFieldIdStrList[index]].id - ]) + /* Match translations parameter for suggestions. */ - .filter((perspective_info, index) => this.state.perspectiveSelectionList[index]); + const matchTranslationsValue = this.state.matchTranslationsFlag + ? this.state.matchTranslationsValue === "first_three" + ? 1 + : 2 + : 0; } - /* Match translations parameter for suggestions. */ - - const matchTranslationsValue = this.state.matchTranslationsFlag - ? this.state.matchTranslationsValue === "first_three" - ? 1 - : 2 - : 0; - /* If we are to perform acoustic analysis, we will try to launch it in the background. */ if (this.props.mode === "acoustic") { @@ -2208,11 +2256,38 @@ class CognateAnalysisModal extends React.Component { data => this.handleMorphologyResult(data), error_data => this.handleError(error_data) ); + } else if (this.props.mode === "complex_distance") { + this.setState({ computing: true }); + + const { fileSuite, debugFlag } = this.state; + const resultPool = new Array(fileSuite.length); + + for (const [index, file] of fileSuite.entries()) { + const reader = new FileReader(); + reader.onload = () => { + try { + resultPool[index] = JSON.parse(reader.result); + + if ((index + 1) == fileSuite.length) { + computeComplexDistance({ + variables: { + resultPool, + debugFlag + } + }).then( + data => this.handleComplexDistanceResult(data), + error_data => this.handleError(error_data) + ); + } + } catch(error_data) { + this.handleError(error_data) + } + }; + reader.readAsText(file); + } } else { /* Otherwise we will launch it as usual and then will wait for results to display them. */ - this.setState({ - computing: true - }); + this.setState({ computing: true }); const backend_mode = this.props.mode === "multi_analysis" @@ -2778,6 +2853,44 @@ class CognateAnalysisModal extends React.Component { ); } + browse_files_render() { + + const { fileSuite } = this.state; + + return ( +
- {this.context( - "Only authorized users can create new cognate connections based on cognate suggestions." - )} -
+ {this.props.user.id === undefined ? ( ++ {this.context( + "Only authorized users can create new cognate connections based on cognate suggestions." + )} +
+{this.state.result}