Skip to content

Commit

Permalink
Merge 3e86015 into 4a5bc91
Browse files Browse the repository at this point in the history
  • Loading branch information
karuhanga committed Jun 14, 2020
2 parents 4a5bc91 + 3e86015 commit a58cacc
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 67 deletions.
44 changes: 34 additions & 10 deletions src/apps/concepts/pages/ViewConceptsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ const useStyles = makeStyles((theme: Theme) =>
},
lightColour: {
color: theme.palette.background.default
},
largerTooltip: {
fontSize: "larger"
}
})
);
Expand Down Expand Up @@ -380,16 +383,37 @@ const ViewConceptsPage: React.FC<Props> = ({
>
Import existing concept
</MenuItem>
{!linkedSource ? null : (
<MenuItem
onClick={e => {
handleCustomClick(e);
handleAddNewClose();
}}
>
Create custom concept
</MenuItem>
)}
<Tooltip
interactive
title={
linkedSource ? (
""
) : (
<span className={classes.largerTooltip}>
This dictionary doesn't have a linked source attached to it.
You'll need to{" "}
<Link
to={`${containerUrl}edit/?createLinkedSource=true&next=${gimmeAUrl()}`}
>
create one
</Link>{" "}
to keep your custom concepts.
</span>
)
}
>
<span>
<MenuItem
disabled={!linkedSource}
onClick={e => {
handleCustomClick(e);
handleAddNewClose();
}}
>
Create custom concept
</MenuItem>
</span>
</Tooltip>
</Menu>
</>
)}
Expand Down
3 changes: 0 additions & 3 deletions src/apps/dictionaries/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from "./types";
import { authenticatedInstance, unAuthenticatedInstance } from "../../api";
import { AxiosResponse } from "axios";
import { OCL_DICTIONARY_TYPE } from "./constants";
import { buildPartialSearchQuery, CUSTOM_VALIDATION_SCHEMA } from "../../utils";
import { default as containerAPI } from "../containers/api";

Expand Down Expand Up @@ -35,7 +34,6 @@ const api = {
limit,
page,
q: buildPartialSearchQuery(q),
collection_type: OCL_DICTIONARY_TYPE,
customValidationSchema: CUSTOM_VALIDATION_SCHEMA,
timestamp: new Date().getTime() // work around seemingly unhelpful caching
}
Expand All @@ -51,7 +49,6 @@ const api = {
limit,
page,
q: buildPartialSearchQuery(q),
collection_type: OCL_DICTIONARY_TYPE,
customValidationSchema: CUSTOM_VALIDATION_SCHEMA,
timestamp: new Date().getTime() // work around seemingly unhelpful caching
}
Expand Down
7 changes: 1 addition & 6 deletions src/apps/dictionaries/constants.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
const OCL_DICTIONARY_TYPE = "OCLClientDictionary";
const OCL_SOURCE_TYPE = "OCLClientSource";

const CONTEXT = {
export const CONTEXT = {
create: "create",
view: "view",
edit: "edit"
};

export { OCL_DICTIONARY_TYPE, OCL_SOURCE_TYPE, CONTEXT };
123 changes: 99 additions & 24 deletions src/apps/dictionaries/pages/EditDictionaryPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React, { useEffect } from "react";
import { DictionaryForm } from "../components";
import { Fab, Grid, Paper, Tooltip } from "@material-ui/core";
import { Fab, Grid, Menu, MenuItem, Paper, Tooltip } from "@material-ui/core";
import { connect } from "react-redux";
import { Link, Redirect, useLocation } from "react-router-dom";
import {
createAndAddLinkedSourceAction,
createAndAddLinkedSourceLoadingSelector,
createAndAddLinkedSourceProgressSelector,
editDictionaryLoadingSelector,
editDictionaryProgressSelector,
editSourceAndDictionaryErrorsSelector,
Expand All @@ -15,37 +18,51 @@ import {
profileSelector
} from "../../authentication/redux/reducer";
import { APIOrg, APIProfile } from "../../authentication";
import { debug, usePrevious } from "../../../utils";
import { debug, useAnchor, usePrevious, useQueryParams } from "../../../utils";
import { CONTEXT } from "../constants";
import { ProgressOverlay } from "../../../utils/components";
import {
editSourceAndDictionaryAction,
makeRetrieveDictionaryAction
} from "../redux/actions";
import { Pageview as PageViewIcon } from "@material-ui/icons";
} from "../redux";
import { MoreVert as MenuIcon } from "@material-ui/icons";
import Header from "../../../components/Header";

interface Props {
interface StateProps {
errors?: {};
profile?: APIProfile;
usersOrgs?: APIOrg[];
loading: boolean;
editedDictionary?: APIDictionary;
dictionaryLoading: boolean;
dictionary?: APIDictionary;
}

interface ActionProps {
editSourceAndDictionary: (
...args: Parameters<typeof editSourceAndDictionaryAction>
) => void;
loading: boolean;
editedDictionary?: APIDictionary;
retrieveDictionary: (
...args: Parameters<ReturnType<typeof makeRetrieveDictionaryAction>>
) => void;
dictionaryLoading: boolean;
dictionary?: APIDictionary;
createAndAddLinkedSource: (
...args: Parameters<typeof createAndAddLinkedSourceAction>
) => void;
}

type Props = StateProps & ActionProps;

interface URLQueryParams {
next?: string;
createLinkedSource?: string;
}

const EditDictionaryPage: React.FC<Props> = ({
profile,
usersOrgs,
errors,
editSourceAndDictionary,
createAndAddLinkedSource,
loading,
dictionaryLoading,
dictionary,
Expand All @@ -54,15 +71,42 @@ const EditDictionaryPage: React.FC<Props> = ({
}: Props) => {
const { pathname: url } = useLocation();
const dictionaryUrl = url.replace("edit/", "");
const { next: nextUrl = editedDictionary?.url } = useQueryParams<
URLQueryParams
>();
const createLinkedSource =
useQueryParams<URLQueryParams>().createLinkedSource === "true";
const linkedSource = dictionary?.extras?.source;

const previouslyLoading = usePrevious(loading);

useEffect(() => {
retrieveDictionary(dictionaryUrl);
}, [dictionaryUrl, retrieveDictionary]);

useEffect(() => {
const dictionaryToUpdate = apiDictionaryToDictionary(dictionary);
if (
!loading &&
createLinkedSource &&
dictionary &&
dictionaryToUpdate &&
!linkedSource
) {
createAndAddLinkedSource(dictionary.url, dictionaryToUpdate);
}
}, [
loading,
createLinkedSource,
dictionary,
linkedSource,
createAndAddLinkedSource
]);

const [menuAnchor, handleMenuClick, handleMenuClose] = useAnchor();

if (!loading && previouslyLoading && editedDictionary) {
return <Redirect to={editedDictionary.url} />;
return <Redirect to={nextUrl || editedDictionary.url} />;
}

return (
Expand All @@ -83,24 +127,46 @@ const EditDictionaryPage: React.FC<Props> = ({
savedValues={apiDictionaryToDictionary(dictionary)}
onSubmit={(values: Dictionary) => {
if (dictionary)
editSourceAndDictionary(
dictionary?.url,
values,
dictionary?.extras
);
editSourceAndDictionary(dictionary.url, values, linkedSource);
else
debug("Could not edit dictionary. dictionary is undefined");
}}
/>
</Paper>
</Grid>
<Link to={dictionaryUrl}>
<Tooltip title="Discard changes and view">
<Fab color="primary" className="fab">
<PageViewIcon />
<>
<Tooltip title="Menu">
<Fab onClick={handleMenuClick} color="primary" className="fab">
<MenuIcon />
</Fab>
</Tooltip>
</Link>
<Menu
anchorEl={menuAnchor}
keepMounted
open={Boolean(menuAnchor)}
onClose={handleMenuClose}
>
<MenuItem>
<Link replace className="link" to={dictionaryUrl}>
Discard changes and view
</Link>
</MenuItem>
{createLinkedSource || linkedSource ? (
<span />
) : (
<MenuItem>
<Link
replace
className="link"
to={`${url}?createLinkedSource=true&next=${nextUrl ||
dictionaryUrl}`}
>
Create linked source
</Link>
</MenuItem>
)}
</Menu>
</>
</ProgressOverlay>
</Header>
);
Expand All @@ -109,16 +175,25 @@ const EditDictionaryPage: React.FC<Props> = ({
const mapStateToProps = (state: any) => ({
profile: profileSelector(state),
usersOrgs: orgsSelector(state),
loading: editDictionaryLoadingSelector(state),
progress: editDictionaryProgressSelector(state),
loading:
editDictionaryLoadingSelector(state) ||
createAndAddLinkedSourceLoadingSelector(state),
progress:
createAndAddLinkedSourceProgressSelector(state) ||
editDictionaryProgressSelector(state),
editedDictionary: state.dictionaries.editedDictionary,
errors: editSourceAndDictionaryErrorsSelector(state),
dictionaryLoading: retrieveDictionaryLoadingSelector(state),
dictionary: state.dictionaries.dictionary
});

const mapActionsToProps = {
editSourceAndDictionary: editSourceAndDictionaryAction,
retrieveDictionary: makeRetrieveDictionaryAction(false)
retrieveDictionary: makeRetrieveDictionaryAction(false),
createAndAddLinkedSource: createAndAddLinkedSourceAction
};

export default connect(mapStateToProps, mapActionsToProps)(EditDictionaryPage);
export default connect<StateProps, ActionProps, unknown>(
mapStateToProps,
mapActionsToProps
)(EditDictionaryPage);
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("Edit Dictionary", () => {
dictionary.otherLanguages.forEach(language => {
select("Other Languages", language);
cy.get("body").type("{esc}");
})
});

cy.findByText("Submit").click();
// redirects to view page
Expand Down
2 changes: 2 additions & 0 deletions src/apps/dictionaries/redux/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export const RETRIEVE_DICTIONARY_ACTION = "dictionaries/retrieveDictionary";
export const RETRIEVE_DICTIONARIES_ACTION = "dictionaries/retrieveDictionaries";
export const EDIT_SOURCE_AND_DICTIONARY_ACTION =
"dictionaries/editSourceAndDictionary";
export const CREATE_AND_ADD_LINKED_SOURCE_ACTION =
"dictionaries/createAndAddLinkedSource";
export const EDIT_DICTIONARY_ACTION = "dictionaries/edit";
export const RETRIEVE_DICTIONARY_VERSIONS_ACTION =
"dictionaries/retrieveVersions";
Expand Down

0 comments on commit a58cacc

Please sign in to comment.