Skip to content

Commit

Permalink
Added stars functionality -- #1180
Browse files Browse the repository at this point in the history
  • Loading branch information
vmonakhov committed Jan 20, 2025
1 parent 124deeb commit 763d9fd
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 50 deletions.
3 changes: 3 additions & 0 deletions src/api/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ export const stringsToTranslate = [
"Add OR condition",
"Add organization",
"Add perspective",
"Add red star",
"Add roles",
"Add to markup",
"Add to TOC",
"Add Translation",
"Add translation",
"Add variant",
"Add words and transcriptions from paradigms to lexical entries",
"Add yellow star",
"Adding",
"Additional code",
"additive",
Expand Down Expand Up @@ -162,6 +164,7 @@ export const stringsToTranslate = [
"Choose parallel corpora",
"Choose what?",
"classifier",
"Clean any star",
"Clear",
"Clear all",
"Clear completed",
Expand Down
37 changes: 37 additions & 0 deletions src/images/icon_star_empty.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions src/images/icon_star_filled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
193 changes: 143 additions & 50 deletions src/pages/Dashboard/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useContext } from "react";
import { connect } from "react-redux";
import { Confirm, Dimmer, Dropdown, Header, Icon, List, Popup, Tab } from "semantic-ui-react";
import { Confirm, Dimmer, Dropdown, Header, Icon, List, Popup, Tab, Button } from "semantic-ui-react";
import { gql } from "@apollo/client";
import { graphql } from "@apollo/client/react/hoc";
import { isEqual } from "lodash";
import { isEqual, cloneDeep } from "lodash";
import PropTypes from "prop-types";
import { branch, compose, onlyUpdateForKeys, renderNothing } from "recompose";
import { bindActionCreators } from "redux";
Expand Down Expand Up @@ -31,6 +31,9 @@ export const query = gql`
translations
status_translations
state_translation_gist_id
additional_metadata {
stars
}
perspectives {
id
parent_id
Expand All @@ -57,6 +60,14 @@ const updateDictionaryStatusMutation = gql`
}
`;

const updateDictionaryMutation = gql`
mutation updateDictionary($id: LingvodocID!, $additionalMetadata: ObjectVal!) {
update_dictionary(id: $id, additional_metadata: $additionalMetadata) {
triumph
}
}
`;

const updatePerspectiveStatusMutation = gql`
mutation updatePerspectiveStatus($id: LingvodocID!, $status_id: LingvodocID!) {
update_perspective_status(id: $id, state_translation_gist_id: $status_id) {
Expand Down Expand Up @@ -309,10 +320,21 @@ const Perspective = compose(
class D extends React.Component {
constructor(props) {
super(props);
const {user, additional_metadata: {stars}} = props;
let star = 0;

this.state = { confirmation: false };
if (stars && stars[user.id]) {
star = stars[user.id][0];
}

this.state = {
star,
starring: false,
confirmation: false
};

this.onRemoveDictionary = this.onRemoveDictionary.bind(this);
this.onUpdateFavorite = this.onUpdateFavorite.bind(this);
}

onRemoveDictionary() {
Expand All @@ -336,6 +358,42 @@ class D extends React.Component {
});
}

onUpdateFavorite() {
const { user, id, mode, category, updateDictionary } = this.props;
const { additional_metadata: { stars: oldStars }} = this.props;
const { star } = this.state;

const stars = oldStars ? cloneDeep(oldStars) : {};

const currentStar = (user.id in stars)
? [(stars[user.id][0] + 1) % 3, stars[user.id][1]]
: [1, ""];

stars[user.id] = currentStar;

this.setState({ star: currentStar[0], starring: true });

updateDictionary({
variables: {
id,
additionalMetadata: { stars }
},
refetchQueries: [
{
query,
variables: {
mode,
category
}
},
//{ query: dictionaryQuery }
],
awaitRefetchQueries: true
}).then(
() => this.setState({ starring: false })
);
}

render() {
const {
id,
Expand All @@ -349,47 +407,78 @@ class D extends React.Component {
category
} = this.props;

const { confirmation } = this.state;
const { confirmation, star, starring } = this.state;

return (
<List.Item>
<List.Content>
<div className="lingvo-dashboard-block">
<div className="lingvo-dashboard-block__big">
<Dropdown
text={T(translations)}
className="link item lingvo-dashboard-elem lingvo-dashboard-elem_main"
icon={<i className="lingvo-icon lingvo-icon_arrow" />}
>
<Dropdown.Menu>
<Dropdown.Item onClick={() => actions.openRoles(id, "dictionary", this.context("Roles"))}>
<i className="lingvo-icon lingvo-icon_roles" /> {this.context("Roles")}
</Dropdown.Item>
<Dropdown.Item
onClick={() =>
actions.openDictionaryPropertiesModal(
id,
`${this.context("Dictionary")} '${T(translations)}' ${this.context("Properties").toLowerCase()}`
)
<div className="lingvo-dashboard-group-elems">
<Dropdown
text={T(translations)}
className="link item lingvo-dashboard-elem lingvo-dashboard-elem_main"
icon={<i className="lingvo-icon lingvo-icon_arrow" />}
>
<Dropdown.Menu>
<Dropdown.Item onClick={() => actions.openRoles(id, "dictionary", this.context("Roles"))}>
<i className="lingvo-icon lingvo-icon_roles" /> {this.context("Roles")}
</Dropdown.Item>
<Dropdown.Item
onClick={() =>
actions.openDictionaryPropertiesModal(
id,
`${this.context("Dictionary")} '${T(translations)}' ${this.context("Properties").toLowerCase()}`
)
}
>
<i className="lingvo-icon lingvo-icon_properties" /> {this.context("Properties")}
</Dropdown.Item>
<Dropdown.Item onClick={() => actions.openDictionaryOrganizationsModal(id)}>
<i className="lingvo-icon lingvo-icon_organizations" /> {this.context("Organizations")}
</Dropdown.Item>
<Dropdown.Item onClick={() => actions.openStatistics(id, "dictionary", this.context("Statistics"))}>
<i className="lingvo-icon lingvo-icon_stats" /> {this.context("Statistics")}
</Dropdown.Item>
{/*<Dropdown.Item icon="circle" text={this.context("Create a new perspective...")} />*/}
<Dropdown.Item onClick={() => actions.openSaveDictionaryModal(id)}>
<i className="lingvo-icon lingvo-icon_save" /> {this.context("Save dictionary")}
</Dropdown.Item>
<Dropdown.Item onClick={() => this.setState({ confirmation: true })}>
<i className="lingvo-icon lingvo-icon_delete" /> {this.context("Remove dictionary")}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>

<div className="lingvo-dashboard-group-elems__block">
<Popup
trigger={
<Button
className="lingvo-dashboard-elem lingvo-dashboard-elem_button"
onClick={this.onUpdateFavorite}
>
<i className={starring
? "lingvo-icon lingvo-icon_spinner"
: star === 1
? "lingvo-icon lingvo-icon_star_yellow"
: star === 2
? "lingvo-icon lingvo-icon_star_red"
: "lingvo-icon lingvo-icon_star_empty"}
/>
</Button>
}
>
<i className="lingvo-icon lingvo-icon_properties" /> {this.context("Properties")}
</Dropdown.Item>
<Dropdown.Item onClick={() => actions.openDictionaryOrganizationsModal(id)}>
<i className="lingvo-icon lingvo-icon_organizations" /> {this.context("Organizations")}
</Dropdown.Item>
<Dropdown.Item onClick={() => actions.openStatistics(id, "dictionary", this.context("Statistics"))}>
<i className="lingvo-icon lingvo-icon_stats" /> {this.context("Statistics")}
</Dropdown.Item>
{/*<Dropdown.Item icon="circle" text={this.context("Create a new perspective...")} />*/}
<Dropdown.Item onClick={() => actions.openSaveDictionaryModal(id)}>
<i className="lingvo-icon lingvo-icon_save" /> {this.context("Save dictionary")}
</Dropdown.Item>
<Dropdown.Item onClick={() => this.setState({ confirmation: true })}>
<i className="lingvo-icon lingvo-icon_delete" /> {this.context("Remove dictionary")}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
disabled={starring}
content={star === 1
? this.context("Add red star")
: star === 2
? this.context("Clean any star")
: this.context("Add yellow star")
}
className="lingvo-popup-inverted"
hideOnScroll={true}
/>
</div>
</div>
</div>

<div className="lingvo-dashboard-block__small">
Expand Down Expand Up @@ -444,20 +533,24 @@ D.propTypes = {
};

const Dictionary = compose(
connect(null, dispatch => ({
actions: bindActionCreators(
{
openRoles,
openDictionaryPropertiesModal,
openStatistics,
openSaveDictionaryModal,
openDictionaryOrganizationsModal
},
dispatch
)
})),
connect(
state => state.user,
dispatch => ({
actions: bindActionCreators(
{
openRoles,
openDictionaryPropertiesModal,
openStatistics,
openSaveDictionaryModal,
openDictionaryOrganizationsModal
},
dispatch
)
})
),
graphql(updateDictionaryMutation, { name: "updateDictionary" }),
graphql(removeDictionaryMutation, { name: "removeDictionary" }),
onlyUpdateForKeys(["translations", "status_translations", "perspectives"])
onlyUpdateForKeys(["translations", "status_translations", "perspectives", "additional_metadata"])
)(D);

const Dashboard = ({ data, mode, category }) => {
Expand Down
20 changes: 20 additions & 0 deletions src/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,26 @@ body {
}
}

&_star {

&_empty {
-webkit-mask-image: url("../images/icon_star_empty.svg");
mask-image: url("../images/icon_star_empty.svg");
}

&_yellow {
-webkit-mask-image: url("../images/icon_star_filled.svg");
mask-image: url("../images/icon_star_filled.svg");
background-color: #ffd966;
}

&_red {
-webkit-mask-image: url("../images/icon_star_filled.svg");
mask-image: url("../images/icon_star_filled.svg");
background-color: #f44336;
}
}

&_sort_up {
-webkit-mask-image: url("../images/icon_arrow2.svg");
mask-image: url("../images/icon_arrow2.svg");
Expand Down

0 comments on commit 763d9fd

Please sign in to comment.