Skip to content

Commit

Permalink
Tsakorpus -- #907 (#1150)
Browse files Browse the repository at this point in the history
* init

* next

* minor

* uploading

* correct rerendering

* fixed port

* minor

* cleanup
  • Loading branch information
vmonakhov authored Nov 15, 2024
1 parent c17c426 commit 63796d6
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/Layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import PlayerModal from "components/PlayerModal";
import RolesModal from "components/RolesModal";
import SaveDictionary from "components/SaveDictionaryModal";
import StatisticsModal from "components/StatisticsModal";
import UploadModal from "components/UploadModal";
import smoothScroll from "utils/smoothscroll";

import NavBar from "./NavBar";
Expand Down Expand Up @@ -73,6 +74,7 @@ class Layout extends React.Component {
<PhonologyModal />
<ConvertEafModal />
<StatisticsModal />
<UploadModal />
<BanModal />
<CreateFieldModal />
<RolesModal />
Expand Down
136 changes: 136 additions & 0 deletions src/components/UploadModal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import React, { useContext, useState, useEffect } from "react";
import { connect } from "react-redux";
import { Button, Loader, Message, Modal, Icon } from "semantic-ui-react";
import { gql } from "@apollo/client";
import { graphql } from "@apollo/client/react/hoc";
import PropTypes from "prop-types";
import { branch, compose, renderNothing, withProps } from "recompose";
import { bindActionCreators } from "redux";

import { closeUploadModal, updateUploadModal } from "ducks/upload";
import TranslationContext from "Layout/TranslationContext";

const getUploadDate = gql`
query getUploadDate($id: LingvodocID!) {
perspective(id: $id) {
id
additional_metadata {
uploaded_at
}
}
}
`;

const Upload = props => {

const getTranslation = useContext(TranslationContext);
const { id, title, data, actions, user, uploading, uploadPerspective } = props;
const { loading, error, refetch, perspective } = data;
useEffect(() => { refetch(); }, [uploading]);
if (loading) {
return (
<Modal open dimmer size="fullscreen" closeOnDimmerClick={false} closeIcon className="lingvo-modal2">
<Loader>{`${getTranslation("Loading")}...`}</Loader>
</Modal>
);
} else if (error || uploading === null) {
return (
<Modal closeIcon onClose={actions.closeUploadModal} open className="lingvo-modal2">
<Modal.Header>{title}</Modal.Header>
<Modal.Content>
<Message negative compact>
<Message.Header>{getTranslation("Perspective info loading error")}</Message.Header>
<div style={{ marginTop: "0.25em" }}>
{getTranslation("Try reloading the page; if the error persists, please contact administrators.")}
</div>
</Message>
</Modal.Content>
</Modal>
);
}

const { additional_metadata: { uploaded_at }} = perspective;

return (
<Modal
closeIcon
onClose={actions.closeUploadModal}
open
dimmer
size="50%"
className="lingvo-modal2"
>
<Modal.Header>{title}</Modal.Header>
<Modal.Content>
<p>
{getTranslation("Uploaded at")}
{": "}
{ uploaded_at
? new Date(uploaded_at).toLocaleString()
: "<never>"
}
{ user.id == 1 && (
<Button
content={uploading ? (
<span>
{getTranslation("Uploading")}... <Icon name="spinner" loading />
</span>
) : (
getTranslation(uploaded_at ? "Refresh" : "Upload")
)}
onClick={() => {
actions.updateUploadModal(true);
uploadPerspective();
}}
disabled={uploading}
className="lingvo-button-greenest"
style={{marginLeft: "1.5em"}}
/>
)}
</p>
</Modal.Content>
<Modal.Actions>
{ user.id !== undefined && uploaded_at && (
<Button
content={getTranslation("Uploaded corpora")}
className="lingvo-button-violet"
style={{float: 'left'}}
onClick={()=> window.open(`http://83.149.198.78/${id[0]}_${id[1]}/search`, "_blank")}
/>
)}
<Button
content={getTranslation("Close")}
onClick={actions.closeUploadModal}
className="lingvo-button-basic-black"
/>
</Modal.Actions>
</Modal>
);
};

Upload.propTypes = {
id: PropTypes.array.isRequired,
title: PropTypes.string.isRequired,
uploading: PropTypes.bool.isRequired,
uploadPerspective: PropTypes.func.isRequired,
data: PropTypes.shape({
loading: PropTypes.bool.isRequired
}).isRequired,
actions: PropTypes.shape({
closeUploadModal: PropTypes.func.isRequired,
updateUploadModal: PropTypes.func.isRequired
}).isRequired
};

export default compose(
connect(
state => state.user,
),
connect(
state => state.upload,
dispatch => ({ actions: bindActionCreators({ closeUploadModal, updateUploadModal }, dispatch) })
),
branch(({ upload }) => !upload, renderNothing),
withProps(({ upload: { id, title, uploading, uploadPerspective } }) => ({ id, title, uploading, uploadPerspective })),
graphql(getUploadDate, { options: { fetchPolicy: "network-only" }})
)(Upload);
2 changes: 2 additions & 0 deletions src/ducks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import search from "./search";
import snackbar from "./snackbar";
import statistics from "./statistics";
import task from "./task";
import upload from "./upload";
import user from "./user";

export default {
Expand Down Expand Up @@ -57,6 +58,7 @@ export default {
phonology,
apolloClient,
statistics,
upload,
ban,
modals,
createOrganization,
Expand Down
40 changes: 40 additions & 0 deletions src/ducks/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { combineReducers } from "redux";

// Actions
const OPEN_MODAL = "@upload/OPEN_MODAL";
const CLOSE_MODAL = "@upload/CLOSE_MODAL";
const UPDATE_MODAL = "@upload/UPDATE_MODAL";

export const openUploadModal = (id, title, uploading, uploadPerspective) => ({
type: OPEN_MODAL,
payload: {
id,
title,
uploading,
uploadPerspective
}
});

export const updateUploadModal = (uploading) => ({
type: UPDATE_MODAL,
payload: { uploading }
});

export const closeUploadModal = () => ({ type: CLOSE_MODAL });

const upload = (state = null, { type, payload }) => {
switch (type) {
case OPEN_MODAL:
return payload;
case UPDATE_MODAL:
return { ...state, uploading: payload.uploading };
case CLOSE_MODAL:
return null;
default:
return state;
}
};

export default combineReducers({
upload
});
1 change: 1 addition & 0 deletions src/pages/Dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { openPerspectivePropertiesModal } from "ducks/perspectiveProperties";
import { openRoles } from "ducks/roles";
import { openSaveDictionaryModal } from "ducks/saveDictionary";
import { openStatistics } from "ducks/statistics";
import { openUploadModal } from "ducks/upload";
import TranslationContext from "Layout/TranslationContext";
import { dictionaryQuery } from "pages/DialeqtImport";
import { compositeIdToString } from "utils/compositeId";
Expand Down
63 changes: 61 additions & 2 deletions src/pages/Perspective/PerspectivePath.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { openPerspectivePropertiesModal } from "ducks/perspectiveProperties";
import { openRoles } from "ducks/roles";
import { openSaveDictionaryModal } from "ducks/saveDictionary";
import { openStatistics } from "ducks/statistics";
import { openUploadModal, updateUploadModal } from "ducks/upload";
import TranslationContext from "Layout/TranslationContext";

const queryPerspectivePath = gql`
Expand All @@ -34,6 +35,7 @@ export const queryAvailablePerspectives = gql`
query availablePerspectives($dictionary_id: LingvodocID!) {
dictionary(id: $dictionary_id) {
id
category
perspectives {
id
parent_id
Expand All @@ -46,6 +48,14 @@ export const queryAvailablePerspectives = gql`
}
`;

const uploadPerspective = gql`
mutation uploadPerspective($id: LingvodocID!, $debugFlag: Boolean) {
tsakorpus(perspective_id: $id, debug_flag: $debugFlag) {
triumph
}
}
`;

const license_dict_translator = getTranslation => ({
proprietary: [getTranslation("Proprietary"), null],
"cc-by-4.0": ["CC-BY-4.0", "https://creativecommons.org/licenses/by/4.0/legalcode"],
Expand All @@ -57,6 +67,35 @@ const license_dict_translator = getTranslation => ({
* Perspective breadcrumb component.
*/
class PerspectivePath extends React.Component {
constructor(props) {
super(props);

this.state = {
uploading: false
};

this.uploadPerspectiveWrapper = this.uploadPerspectiveWrapper.bind(this);
};

uploadPerspectiveWrapper() {
const {id, actions, uploadPerspective} = this.props;

this.setState({ uploading: true });

uploadPerspective({
variables: { id }
}).then(
({ data }) => {
this.setState({ uploading: false });
actions.updateUploadModal(data.tsakorpus.triumph ? false : null);
},
() => {
this.setState({ uploading: false });
actions.updateUploadModal(null);
}
)
}

render() {
/* eslint-disable no-shadow */
const {
Expand Down Expand Up @@ -88,6 +127,7 @@ class PerspectivePath extends React.Component {
const dictionary_id_tree = tree[1].id;

const {
category,
perspectives,
additional_metadata: { license }
} = queryAvailablePerspectives.dictionary;
Expand All @@ -108,6 +148,7 @@ class PerspectivePath extends React.Component {
const roles_str = this.context("Roles").toLowerCase();
const properties_str = this.context("Properties").toLowerCase();
const statistics_str = this.context("Statistics").toLowerCase();
const upload_str = this.context("Upload").toLowerCase();

return (
<Header as="h2" className={className}>
Expand Down Expand Up @@ -171,6 +212,20 @@ class PerspectivePath extends React.Component {
actions.openStatistics(id, "perspective", `'${T(e.translations)}' ${statistics_str}`)
}
/>
{user.id !== undefined && category == 1 && (
<Dropdown.Item
key="upload"
icon={<i className="lingvo-icon lingvo-icon_published" />}
text={this.context("Upload")}
onClick={() =>
actions.openUploadModal(
id,
`'${T(e.translations)}' ${upload_str}`,
this.state.uploading,
this.uploadPerspectiveWrapper)
}
/>
)}
</Dropdown.Menu>
</Dropdown>
) : index === tree.length - 2 ? (
Expand Down Expand Up @@ -285,6 +340,7 @@ PerspectivePath.propTypes = {
dictionary_id: PropTypes.array.isRequired,
queryPerspectivePath: PropTypes.object.isRequired,
queryAvailablePerspectives: PropTypes.object.isRequired,
uploadPerspective: PropTypes.func.isRequired,
mode: PropTypes.string.isRequired,
className: PropTypes.string,
actions: PropTypes.object.isRequired,
Expand All @@ -310,7 +366,9 @@ export default compose(
openPerspectivePropertiesModal,
openRoles,
openSaveDictionaryModal,
openStatistics
openStatistics,
openUploadModal,
updateUploadModal
},
dispatch
)
Expand All @@ -323,5 +381,6 @@ export default compose(
graphql(queryAvailablePerspectives, {
name: "queryAvailablePerspectives",
options: props => ({ variables: { dictionary_id: props.dictionary_id } })
})
}),
graphql(uploadPerspective, { name: "uploadPerspective" })
)(PerspectivePath);
2 changes: 1 addition & 1 deletion src/pages/Perspective/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ const ModeSelector = compose(
</Menu.Item>
))}
{tsakorpusFlag && (
<Menu.Item key="corpus_search" href={`http://83.149.198.78:8080/${id[0]}_${id[1]}/search`}>
<Menu.Item key="corpus_search" href={`http://83.149.198.78/${id[0]}_${id[1]}/search`}>
{getTranslation("Corpus search")}
</Menu.Item>
)}
Expand Down

0 comments on commit 63796d6

Please sign in to comment.