Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow companies to be able to quickly edit publish end date from MyOffers menu #312

Closed
wants to merge 7 commits into from
105 changes: 105 additions & 0 deletions src/components/Offers/Edit/OfferEndDateQuickEdit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React, { useCallback, useState } from "react";
import PropTypes from "prop-types";
import { editOffer } from "../../../services/offerService";
import { DatePicker } from "@material-ui/pickers";
import { makeStyles } from "@material-ui/core/styles";
import { ArrowDownward, Edit } from "@material-ui/icons";
import { getHumanError } from "../Form/OfferUtils";
import { useDispatch } from "react-redux";
import { addSnackbar } from "../../../actions/notificationActions";

const useStyles = makeStyles((theme) => ({
datePicker: {
display: "none",
},
icon: {
height: "0.55em",
cursor: "pointer",
},
submitEditIcon: {
cursor: "pointer",
marginTop: theme.spacing(1),
},
}));

const OfferEndDateQuickEdit = ({ offerId, dateValue }) => {
const stylings = useStyles();
const [isEditingDate, setEditingDate] = useState(false);
const [currentDate, setCurrentDate] = useState(dateValue);

const [editAbilityEnabled, setEditAbilityEnabled] = useState(true);

const dispatch = useDispatch();
const dispatchAddSnackbarAction = useCallback((notification) => {
dispatch(addSnackbar(notification));
}, [dispatch]);

const changeOfferPublishEndDateTo = (newPublishEndDate) => {
editOffer({ offerId: offerId, publishEndDate: newPublishEndDate })
.then(() => {
setCurrentDate(newPublishEndDate.split("T")[0]);
})
.catch((err) => {
dispatchAddSnackbarAction({
message: `${getHumanError(err[0].msg)}`,
});
}).finally(() => {
setEditingDate(false);
setEditAbilityEnabled(true);
});
};

const triggerStartChoosingDate = () => {
if (editAbilityEnabled) {
setEditingDate(true);
setEditAbilityEnabled(false);
}
};

return (
<>
<span id={`end-publish-date-${offerId}`}>
{currentDate.split("T")[0]}
</span>

{isEditingDate ?
<>
<DatePicker
open={isEditingDate}
value={Date.parse(currentDate)}
data-testid={`quickEditPublishEndDate-input-${offerId}`}
name="quickEditPublishEndDate-input"
onChange={(event) => {
changeOfferPublishEndDateTo(event.toISOString());
setEditingDate(false);
}}
variant="inline"
autoOk
format="yyyy-MM-dd"
className={stylings.datePicker}
PopoverProps={{
anchorEl: document.getElementById(`end-publish-date-${offerId}`),
}}
/>
<ArrowDownward
className={stylings.icon}
/>
</> :
<>
<Edit
className={stylings.icon}
onClick={triggerStartChoosingDate}
data-testid="QuickEndDateEditIcon"
/>
</>
}
</>
);
};

OfferEndDateQuickEdit.propTypes = {
offerId: PropTypes.string.isRequired,
dateValue: PropTypes.string.isRequired,
};

export default OfferEndDateQuickEdit;
42 changes: 42 additions & 0 deletions src/components/Offers/Edit/OfferEndDateQuickEdit.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";
import { createTheme } from "@material-ui/core";
import { fireEvent } from "@testing-library/dom";
import { renderWithStoreAndTheme } from "../../../test-utils";
import { MuiPickersUtilsProvider } from "@material-ui/pickers";
import DateFnsUtils from "@date-io/date-fns";
import PropTypes from "prop-types";

import OfferEndDateQuickEdit from "./OfferEndDateQuickEdit";

const OfferEndDateQuickEditWrapper = ({
offerId = "mockid", dateValue = "",
}) => (
<OfferEndDateQuickEdit
offerId={offerId}
dateValue={dateValue}
/>
);

OfferEndDateQuickEditWrapper.propTypes = {
offerId: PropTypes.string.isRequired,
dateValue: PropTypes.string.isRequired,
};

describe("Quick Edit Publish End Date", () => {
const initialState = {};
const theme = createTheme({});

it("Should display datepicker calendar when edit button is clicked", () => {
const quickEditComponent = renderWithStoreAndTheme(
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<OfferEndDateQuickEditWrapper />
</MuiPickersUtilsProvider>,
{ initialState: initialState, theme: theme }
);

const editIcon = quickEditComponent.getByTestId("QuickEndDateEditIcon");
fireEvent.click(editIcon);

expect(quickEditComponent.getByTestId("quickEditPublishEndDate-input-mockid")).toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions src/components/Offers/Form/OfferUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const HumanReadableErrors = Object.freeze({
"must-be-ISO8601-date": () => HumanValidationReasons.DATE,
"date-already-past": () => HumanValidationReasons.DATE_EXPIRED,
"invalid-apply-url": () => "Invalid application URL. Ensure your URL starts with 'http(s):' or is a valid email",
"must-be-before": () => HumanValidationReasons.PUBLISH_END_DATE(),
});

export const getHumanError = (error) => generalHumanError(error, HumanReadableErrors);
Expand Down
22 changes: 17 additions & 5 deletions src/utils/Table/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import React, { useState } from "react";
import { TableCell, makeStyles } from "@material-ui/core";
import { Link } from "react-router-dom";
import OfferEndDateQuickEdit from "../../components/Offers/Edit/OfferEndDateQuickEdit";

export const getFieldValue = (row, column) => row.fields[column].value;

Expand All @@ -22,6 +23,7 @@ const useStyles = makeStyles({
});

export const GenerateTableCellFromField = (id, fieldId, fieldOptions, labelId) => {
const [colValue, setColValue] = useState(fieldOptions?.value);
const classes = useStyles();

const linkDestination = fieldOptions?.linkDestination;
Expand All @@ -34,10 +36,20 @@ export const GenerateTableCellFromField = (id, fieldId, fieldOptions, labelId) =
id={id === 0 ? `${labelId}-label` : undefined}
align={fieldOptions.align || "right"}
>
{fieldOptions?.linkDestination ?
<Link to={linkDestination} className={classes.fieldLink}>
{fieldOptions?.value}
</Link> : fieldOptions.value}

{ /* eslint-disable no-nested-ternary */
fieldOptions?.linkDestination ?
<Link to={linkDestination} className={classes.fieldLink}>
{colValue}
</Link> : fieldId === "publishEndDate" ?
<OfferEndDateQuickEdit
offerId={labelId.split("-")[2]}
setOfferId={setColValue}
dateValue={colValue}
/> : colValue
/* eslint-enable no-nested-ternary */
}

</TableCell>
);
}
Expand Down