Skip to content

Commit

Permalink
Merge pull request #315 from NIAEFEUP/feature/collapsable-quick-edit-…
Browse files Browse the repository at this point in the history
…options-305

Quick offer edit actions collapsable in company offers management widget
  • Loading branch information
tomaspalma authored Apr 9, 2024
2 parents afc9b67 + cb8f75d commit 95729ba
Show file tree
Hide file tree
Showing 10 changed files with 2,237 additions and 5,468 deletions.
6,860 changes: 1,595 additions & 5,265 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"audit": "npm audit --production --audit-level=high"
},
"dependencies": {
"@babel/preset-env": "^7.23.3",
"@babel/preset-env": "^7.23.9",
"@date-io/date-fns": "^1.3.13",
"@hookform/resolvers": "^2.8.3",
"@material-ui/core": "^4.12.3",
Expand Down
40 changes: 40 additions & 0 deletions src/components/Company/Offers/Manage/CollapsedQuickOfferEdit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { Box, Button, Collapse, Typography } from "@material-ui/core";
import { KeyboardArrowDown, KeyboardArrowUp } from "@material-ui/icons";
import { QuickOfferEditForm } from "./QuickOfferEditForm";

const CollapsedQuickOfferEdit = ({ offerId, isMobile }) => {
const [collapse, setCollapse] = useState(false);

return isMobile ? (
<>
<Box
display="flex"
alignSelf="center"
alignItems="center"
flexDirection="row"
>
<Typography align="center">Quick Edit Offer</Typography>
<Button
onClick={() => setCollapse(!collapse)}
size="small"
margin="dense"
endIcon={collapse ? <KeyboardArrowUp /> : <KeyboardArrowDown />}
/>
</Box>
<Collapse in={collapse}>
<QuickOfferEditForm offerId={offerId} />
</Collapse>
</>
) : (
<QuickOfferEditForm offerId={offerId} showTitle={true} />
);
};

CollapsedQuickOfferEdit.propTypes = {
offerId: PropTypes.string.isRequired,
isMobile: PropTypes.bool.isRequired,
};

export default CollapsedQuickOfferEdit;
11 changes: 11 additions & 0 deletions src/components/Company/Offers/Manage/CompanyOffersActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ const CompanyOffersActions = ({
</IconButton>
</Link>
</Tooltip>
<Tooltip title="Quick Offer Edit Actions">
<IconButton
aria-label="More Actions"
edge="end"
onClick={(e) => {
e.stopPropagation(); toggleCollapse();
}}
>
{!isCollapseOpen ? <ExpandMore /> : <ExpandLess />}
</IconButton>
</Tooltip>
</>
) : (
<IconButton
Expand Down
183 changes: 106 additions & 77 deletions src/components/Company/Offers/Manage/CompanyOffersManagementWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,36 @@ import useSession from "../../../../hooks/useSession";
import { fetchCompanyOffers } from "../../../../services/companyOffersService";
import ControlledSortableSelectableTable from "../../../../utils/Table/ControlledSortableSelectableTable";
import FilterableTable from "../../../../utils/Table/FilterableTable";
import { alphabeticalSorter, GenerateTableCellFromField } from "../../../../utils/Table/utils";
import {
alphabeticalSorter,
GenerateTableCellFromField,
} from "../../../../utils/Table/utils";
import { columns } from "./CompanyOffersManagementSchema";
import {
OfferTitleFilter,
PublishDateFilter,
PublishEndDateFilter,
LocationFilter,
} from "../Filters/index";
import Offer from "../../../HomePage/SearchResultsArea/Offer/Offer";
import { OfferConstants } from "../../../Offers/Form/OfferUtils";
import { LocationFilter, OfferTitleFilter, PublishDateFilter, PublishEndDateFilter } from "../Filters/index";
import { RowActions } from "./CompanyOffersActions";
import { columns } from "./CompanyOffersManagementSchema";
import OfferTitle from "./CompanyOffersTitle";
import CompanyOffersVisibilityActions from "./CompanyOffersVisibilityActions";
import CollapsedQuickOfferEdit from "./CollapsedQuickOfferEdit";

const generateRow = ({
title, location, publishDate, publishEndDate, isHidden, isArchived, hiddenReason,
ownerName, getOfferVisibility, setOfferVisibility, offerId, _id, ...args }) => ({
fields: {
title: { value: (
<OfferTitle
title={title}
getOfferVisibility={getOfferVisibility}
offerId={offerId}
/>), align: "left", linkDestination: `/offer/${_id}` },
title: {
value: (
<OfferTitle
title={title}
getOfferVisibility={getOfferVisibility}
offerId={offerId}
/>), align: "left", linkDestination: `/offer/${_id}`,
},
publishStartDate: { value: format(parseISO(publishDate), "yyyy-MM-dd") },
publishEndDate: { value: format(parseISO(publishEndDate), "yyyy-MM-dd") },
location: { value: location },
Expand All @@ -53,25 +64,35 @@ const sorters = {

const filters = [
{ id: "offer-title-filter", render: OfferTitleFilter },
{ id: "publish-date-filter",
{
id: "publish-date-filter",
render: PublishDateFilter,
props: {
onChange: (date, filtersContext, setFiltersContext) => {
setFiltersContext((filtersContext) => ({ ...filtersContext, minDate: date }));
setFiltersContext((filtersContext) => ({
...filtersContext,
minDate: date,
}));
},
},
},
{ id: "publish-end-date-filter",
{
id: "publish-end-date-filter",
render: PublishEndDateFilter,
props: {
onChange: (date, filtersContext, setFiltersContext) => {
setFiltersContext((filtersContext) => ({ ...filtersContext, minDate: date }));
setFiltersContext((filtersContext) => ({
...filtersContext,
minDate: date,
}));
},
},
},
{ id: "location-filter", render: LocationFilter },
];

export const OfferManagementContext = React.createContext();

const CompanyOffersManagementWidget = ({ addSnackbar, isMobile }) => {
const { data, isLoggedIn } = useSession();
const [offers, setOffers] = useState({});
Expand Down Expand Up @@ -176,80 +197,88 @@ const CompanyOffersManagementWidget = ({ addSnackbar, isMobile }) => {
const offerRoute = `/offer/${rowKey}`;
const mobileFieldKeys = ["location", "publishEndDate"];

return (
isMobile && (
<>
<div className={classes.payloadSection}>
<Grid container alignItems="center">
<Grid item xs={6}>
<Typography className={classes.collapsableTitles} variant="body1">
Actions
</Typography>
</Grid>
<Grid item xs={6} justifyContent="center">
<CompanyOffersVisibilityActions
offer={row?.payload.offer}
getOfferVisibility={row?.payload.getOfferVisibility}
setOfferVisibility={row?.payload.setOfferVisibility}
offerId={row?.payload.offerId}
/>
<Tooltip title="Edit Offer">
<Link to={offerRoute}>
<IconButton aria-label="Edit Offer">
<EditIcon color="secondary" fontSize="medium" />
</IconButton>
</Link>
</Tooltip>
</Grid>
</Grid>
</div>

{mobileFieldKeys.map((colKey) => (
<div key={colKey} className={classes.payloadSection}>
<Divider />
return !isMobile ? (
<CollapsedQuickOfferEdit
offerId={rowKey}
isMobile={isMobile}
/>
) : (
<>
<div className={classes.payloadSection}>
<Grid container alignItems="center">
<Grid item xs={6}>
<Typography className={classes.collapsableTitles} variant="body1">
{columns[colKey]?.label}
Actions
</Typography>
<Typography variant="body2">
{row.fields[colKey].value}
</Typography>
</div>
))}
</>
)
</Grid>
<Grid item xs={6} justifyContent="center">
<CompanyOffersVisibilityActions
offer={row?.payload.offer}
getOfferVisibility={row?.payload.getOfferVisibility}
setOfferVisibility={row?.payload.setOfferVisibility}
offerId={row?.payload.offerId}
/>
<Tooltip title="Edit Offer">
<Link to={offerRoute}>
<IconButton aria-label="Edit Offer">
<EditIcon color="secondary" fontSize="medium" />
</IconButton>
</Link>
</Tooltip>
</Grid>
</Grid>
<CollapsedQuickOfferEdit
offerId={rowKey}
isMobile={isMobile}
/>
</div>

{mobileFieldKeys.map((colKey) => (
<div key={colKey} className={classes.payloadSection}>
<Divider />
<Typography className={classes.collapsableTitles} variant="body1">
{columns[colKey]?.label}
</Typography>
<Typography variant="body2">
{row.fields[colKey].value}
</Typography>
</div>
))}
</>
);
}, [classes.collapsableTitles, classes.payloadSection, isMobile, offers]);

RowCollapseComponent.propTypes = {
rowKey: PropTypes.string.isRequired,
};


return (
<FilterableTable
title="Offers Management"
tableComponent={ControlledSortableSelectableTable}
defaultSort="publishStartDate"
defaultOrderAscending={false}
rows={offers}
setInitialRows={setOffers}
columns={columns}
sorters={sorters}
filters={filters}
RowActions={RowActions}
rowsPerPage={5}
stickyHeader
emptyMessage="No offers here."
RowContent={RowContent}
RowCollapseComponent={RowCollapseComponent}
handleSelect={() => {}}
handleSelectAll={() => {}}
isSelectableTable={false}
isLoading={isLoading}
error={error}
mobileColumns={mobileCols}
hasMaxHeight={false}
/>
<OfferManagementContext.Provider value={{ offers, setOffers }}>
<FilterableTable
title="Offers Management"
tableComponent={ControlledSortableSelectableTable}
defaultSort="publishStartDate"
defaultOrderAscending={false}
rows={offers}
setInitialRows={setOffers}
columns={columns}
sorters={sorters}
filters={filters}
RowActions={RowActions}
rowsPerPage={5}
stickyHeader
emptyMessage="No offers here."
RowContent={RowContent}
RowCollapseComponent={RowCollapseComponent}
handleSelect={() => { }}
handleSelectAll={() => { }}
isSelectableTable={false}
isLoading={isLoading}
error={error}
mobileColumns={mobileCols}
hasMaxHeight={false}
/>
</OfferManagementContext.Provider>
);
};

Expand Down
Loading

0 comments on commit 95729ba

Please sign in to comment.