diff --git a/src/actions/company-actions.js b/src/actions/company-actions.js index f45a1756e..c0a9bd4c8 100644 --- a/src/actions/company-actions.js +++ b/src/actions/company-actions.js @@ -20,16 +20,14 @@ import { createAction, stopLoading, startLoading, - showMessage, - showSuccessMessage, - authErrorHandler, escapeFilterValue, fetchResponseHandler, fetchErrorHandler } from "openstack-uicore-foundation/lib/utils/actions"; -import * as _ from "lodash"; +import debounce from "lodash/debounce"; import URI from "urijs"; import history from "../history"; +import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions"; import { getAccessTokenSafely } from "../utils/methods"; import { DEBOUNCE_WAIT, @@ -92,9 +90,9 @@ export const getCompanies = createAction(REQUEST_COMPANIES), createAction(RECEIVE_COMPANIES), `${window.API_BASE_URL}/api/v1/companies`, - authErrorHandler, - { order, orderDir, page, term } - )(params)(dispatch).then(() => { + snackbarErrorHandler, + { order, orderDir, page, perPage, term } + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -114,8 +112,8 @@ export const getCompany = (companyId) => async (dispatch) => { null, createAction(RECEIVE_COMPANY), `${window.API_BASE_URL}/api/v1/companies/${companyId}`, - authErrorHandler - )(params)(dispatch).then(() => { + snackbarErrorHandler + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -134,8 +132,8 @@ export const deleteCompany = (companyId) => async (dispatch) => { createAction(COMPANY_DELETED)({ companyId }), `${window.API_BASE_URL}/api/v1/companies/${companyId}`, null, - authErrorHandler - )(params)(dispatch).then(() => { + snackbarErrorHandler + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -160,32 +158,36 @@ export const saveCompany = (entity) => async (dispatch) => { createAction(COMPANY_UPDATED), `${window.API_BASE_URL}/api/v1/companies/${entity.id}`, normalizedEntity, - authErrorHandler, + snackbarErrorHandler, entity - )(params)(dispatch).then(() => { - dispatch(showSuccessMessage(T.translate("edit_company.company_saved"))); - }); + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("edit_company.company_saved") + }) + ); + }) + .finally(() => dispatch(stopLoading())); } else { - const success_message = { - title: T.translate("general.done"), - html: T.translate("edit_company.company_created"), - type: "success" - }; - postRequest( createAction(UPDATE_COMPANY), createAction(COMPANY_ADDED), `${window.API_BASE_URL}/api/v1/companies`, normalizedEntity, - authErrorHandler, + snackbarErrorHandler, entity - )(params)(dispatch).then(() => { - dispatch( - showMessage(success_message, () => { - history.push("/app/companies"); - }) - ); - }); + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("edit_company.company_created") + }) + ); + }) + .finally(() => dispatch(stopLoading())); } }; @@ -210,7 +212,7 @@ export const attachLogo = (entity, file, picAttr) => async (dispatch) => { createAction(COMPANY_ADDED), `${window.API_BASE_URL}/api/v1/companies`, normalizedEntity, - authErrorHandler, + snackbarErrorHandler, entity )(params)(dispatch).then((payload) => { dispatch(uploadFile(payload.response, file)); @@ -230,12 +232,13 @@ const uploadLogo = (entity, file) => async (dispatch) => { createAction(LOGO_ATTACHED), `${window.API_BASE_URL}/api/v1/companies/${entity.id}/logo`, file, - authErrorHandler, + snackbarErrorHandler, { pic: entity.pic } - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - history.push(`/app/companies/${entity.id}`); - }); + )(params)(dispatch) + .then(() => { + history.push(`/app/companies/${entity.id}`); + }) + .finally(() => dispatch(stopLoading())); }; const uploadBigLogo = (entity, file) => async (dispatch) => { @@ -250,12 +253,13 @@ const uploadBigLogo = (entity, file) => async (dispatch) => { createAction(BIG_LOGO_ATTACHED), `${window.API_BASE_URL}/api/v1/companies/${entity.id}/logo/big`, file, - authErrorHandler, + snackbarErrorHandler, { pic: entity.pic } - )(params)(dispatch).then(() => { - dispatch(stopLoading()); - history.push(`/app/companies/${entity.id}`); - }); + )(params)(dispatch) + .then(() => { + history.push(`/app/companies/${entity.id}`); + }) + .finally(() => dispatch(stopLoading())); }; const normalizeEntity = (entity) => { @@ -270,7 +274,7 @@ const normalizeEntity = (entity) => { return normalizedEntity; }; -export const queryCompanies = _.debounce(async (input, callback) => { +export const queryCompanies = debounce(async (input, callback) => { const accessToken = await getAccessTokenSafely(); const endpoint = URI(`${window.API_BASE_URL}/api/v1/companies`); input = escapeFilterValue(input); diff --git a/src/components/mui/formik-inputs/mui-formik-async-select.js b/src/components/mui/formik-inputs/mui-formik-async-select.js index 852417e1a..c534237d1 100644 --- a/src/components/mui/formik-inputs/mui-formik-async-select.js +++ b/src/components/mui/formik-inputs/mui-formik-async-select.js @@ -18,7 +18,8 @@ const MuiFormikAsyncAutocomplete = ({ formatOption = (item) => ({ value: item.id.toString(), label: item.name }), formatSelectedValue = null, queryParams = [], - isMulti = false + isMulti = false, + defaultOptions }) => { const [field, meta, helpers] = useField(name); const [options, setOptions] = useState([]); @@ -45,7 +46,7 @@ const MuiFormikAsyncAutocomplete = ({ }; useEffect(() => { - if (searchTerm) { + if (!defaultOptions && searchTerm) { const delayDebounce = setTimeout(() => { fetchOptions(searchTerm); }, DEBOUNCE_WAIT_250); @@ -86,7 +87,17 @@ const MuiFormikAsyncAutocomplete = ({ fullWidth getOptionLabel={(option) => option.label || ""} isOptionEqualToValue={(option, value) => option.value === value.value} - onInputChange={(e, newInput) => setSearchTerm(newInput)} + onInputChange={ + !defaultOptions ? (e, newInput) => setSearchTerm(newInput) : undefined + } + filterOptions={ + defaultOptions + ? (options, { inputValue }) => + options.filter((opt) => + opt.label.toLowerCase().includes(inputValue.toLowerCase()) + ) + : undefined // MUI usa su default que no filtra (deja que la API filtre) + } renderInput={(params) => ( { + const [field, meta, helpers] = useField(name); + const [localValue, setLocalValue] = useState(field.value || "#000000"); + const isDirtyRef = useRef(false); + + const handleChange = (e) => { + setLocalValue(e.target.value); + isDirtyRef.current = true; + helpers.setValue(e.target.value); + }; + + const handleBlur = (e) => { + field.onBlur(e); + helpers.setTouched(true); + if (isDirtyRef.current) { + helpers.setValue(localValue); + isDirtyRef.current = false; + } + }; + + return ( + + ); +}; + +MuiFormikColorInput.propTypes = { + name: PropTypes.string.isRequired +}; + +export default MuiFormikColorInput; diff --git a/src/i18n/en.json b/src/i18n/en.json index d1c6e1402..91e439a60 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -765,7 +765,8 @@ "companies": "Companies", "add_company": "Add Company", "member_level": "Member Level", - "delete_company_warning": "Are you sure you want to delete company", + "delete_company_warning": "Are you sure you want to delete company {name}", + "no_results": "No items found for this search criteria.", "placeholders": { "search_companies": "Search by Company Name" } @@ -801,7 +802,9 @@ "placeholders": { "select_country": "Select Country", "sponsored_project": "Select Sponsored Project", - "sponsorship_type": "Select Tier" + "sponsorship_type": "Select Tier", + "select_project_first": "Select a project first", + "no_options": "No options" } }, "tag_list": { diff --git a/src/pages/companies/company-list-page.js b/src/pages/companies/company-list-page.js index cb956c3f3..755079598 100644 --- a/src/pages/companies/company-list-page.js +++ b/src/pages/companies/company-list-page.js @@ -9,165 +9,223 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ -import React from "react"; +import React, { useEffect, useState } from "react"; import { connect } from "react-redux"; import T from "i18n-react/dist/i18n-react"; -import Swal from "sweetalert2"; -import { Pagination } from "react-bootstrap"; +import { Box, Button, Grid2 } from "@mui/material"; +import AddIcon from "@mui/icons-material/Add"; +import MuiTable from "openstack-uicore-foundation/lib/components/mui/table"; +import SearchInput from "openstack-uicore-foundation/lib/components/mui/search-input"; import { - FreeTextSearch, - Table -} from "openstack-uicore-foundation/lib/components"; -import { getCompanies, deleteCompany } from "../../actions/company-actions"; - -class CompanyListPage extends React.Component { - constructor(props) { - super(props); - - props.getCompanies(); - - this.handleEdit = this.handleEdit.bind(this); - this.handleDelete = this.handleDelete.bind(this); - this.handlePageChange = this.handlePageChange.bind(this); - this.handleSort = this.handleSort.bind(this); - this.handleSearch = this.handleSearch.bind(this); - this.handleNewCompany = this.handleNewCompany.bind(this); - - this.state = {}; - } - - handleEdit(company_id) { - const { history } = this.props; - history.push(`/app/companies/${company_id}`); - } - - handleDelete(companyId) { - const { deleteCompany, companies } = this.props; - let company = companies.find((s) => s.id === companyId); - - Swal.fire({ - title: T.translate("general.are_you_sure"), - text: - T.translate("company_list.delete_company_warning") + " " + company.name, - type: "warning", - showCancelButton: true, - confirmButtonColor: "#DD6B55", - confirmButtonText: T.translate("general.yes_delete") - }).then(function (result) { - if (result.value) { - deleteCompany(companyId); - } + getCompanies, + getCompany, + deleteCompany, + saveCompany, + resetCompanyForm +} from "../../actions/company-actions"; +import { + getSponsoredProjects, + saveSupportingCompany, + deleteSupportingCompany +} from "../../actions/sponsored-project-actions"; +import { DEFAULT_CURRENT_PAGE, MAX_PER_PAGE } from "../../utils/constants"; +import CompanyDialog from "./components/company-dialog"; + +const CompanyListPage = ({ + companies, + currentCompany, + term, + order, + orderDir, + currentPage, + perPage, + totalCompanies, + getCompanies, + getCompany, + deleteCompany, + saveCompany, + resetCompanyForm, + getSponsoredProjects, + saveSupportingCompany, + deleteSupportingCompany, + sponsoredProjects +}) => { + const [companyPopup, setCompanyPopup] = useState(false); + + useEffect(() => { + if (window.APP_CLIENT_NAME === "openstack") + getSponsoredProjects("", 1, MAX_PER_PAGE); + }, []); + + const columns = [ + { columnKey: "id", header: "Id", sortable: true }, + { columnKey: "name", header: T.translate("general.name"), sortable: true }, + { columnKey: "contact_email", header: T.translate("general.email") }, + { + columnKey: "member_level", + header: T.translate("company_list.member_level") + } + ]; + + const table_options = { + sortCol: order, + sortDir: orderDir + }; + + useState(() => { + getCompanies(); + }, []); + + const handleEdit = (company) => { + getCompany(company.id).then(() => setCompanyPopup(true)); + }; + + const handleDelete = (companyId) => { + deleteCompany(companyId).then(() => + getCompanies(term, DEFAULT_CURRENT_PAGE, perPage, order, orderDir) + ); + }; + + const handlePageChange = (page) => { + getCompanies(term, page, perPage, order, orderDir); + }; + + const handlePerPageChange = (newPerPage) => { + getCompanies(term, DEFAULT_CURRENT_PAGE, newPerPage, order, orderDir); + }; + + const handleSort = (key, dir) => { + getCompanies(term, currentPage, perPage, key, dir); + }; + + const handleSearch = (searchTerm) => { + getCompanies(searchTerm, DEFAULT_CURRENT_PAGE, perPage, order, orderDir); + }; + + const handleNewCompany = () => { + resetCompanyForm(); + setCompanyPopup(true); + }; + + const handleSave = (entity) => { + saveCompany(entity).then(() => { + setCompanyPopup(false); + getCompanies(term, DEFAULT_CURRENT_PAGE, perPage, order, orderDir); }); - } - - handlePageChange(page) { - const { term, order, orderDir, perPage } = this.props; - this.props.getCompanies(term, page, perPage, order, orderDir); - } - - handleSort(index, key, dir, func) { - const { term, page, perPage } = this.props; - this.props.getCompanies(term, page, perPage, key, dir); - } - - handleSearch(term) { - const { order, orderDir, page, perPage } = this.props; - this.props.getCompanies(term, page, perPage, order, orderDir); - } - - handleNewCompany(ev) { - const { history } = this.props; - history.push(`/app/companies/new`); - } - - render() { - const { - companies, - lastPage, - currentPage, - term, - order, - orderDir, - totalCompanies - } = this.props; - - const columns = [ - { columnKey: "id", value: "Id", sortable: true }, - { columnKey: "name", value: T.translate("general.name"), sortable: true }, - { columnKey: "contact_email", value: T.translate("general.email") }, - { - columnKey: "member_level", - value: T.translate("company_list.member_level") - } - ]; - - const table_options = { - sortCol: order, - sortDir: orderDir, - actions: { - edit: { onClick: this.handleEdit }, - delete: { onClick: this.handleDelete } - } - }; - - return ( -
-

- {" "} - {T.translate("company_list.company_list")} ({totalCompanies}){" "} -

-
-
- { + setCompanyPopup(false); + }; + + return ( +
+

{T.translate("company_list.company_list")}

+ + + + {totalCompanies} {T.translate("company_list.companies")} + + + + + -
-
- -
-
- - {companies.length > 0 && ( -
- - - - )} - - ); - } -} - -const mapStateToProps = ({ currentCompanyListState }) => ({ - ...currentCompanyListState + + + + + + {companies.length > 0 && ( + + T.translate("company_list.delete_company_warning", { name }) + } + /> + )} + + {companies.length === 0 && ( +
{T.translate("company_list.no_results")}
+ )} + + {companyPopup && ( + + )} + + ); +}; + +const mapStateToProps = ({ + currentCompanyListState, + sponsoredProjectListState, + currentCompanyState +}) => ({ + ...currentCompanyListState, + currentCompany: currentCompanyState.entity, + sponsoredProjects: sponsoredProjectListState.sponsoredProjects }); export default connect(mapStateToProps, { getCompanies, - deleteCompany + getCompany, + deleteCompany, + saveCompany, + resetCompanyForm, + getSponsoredProjects, + saveSupportingCompany, + deleteSupportingCompany })(CompanyListPage); diff --git a/src/pages/companies/components/company-dialog.js b/src/pages/companies/components/company-dialog.js new file mode 100644 index 000000000..750b4969d --- /dev/null +++ b/src/pages/companies/components/company-dialog.js @@ -0,0 +1,478 @@ +/** + * Copyright 2024 OpenStack Foundation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * */ + +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import T from "i18n-react/dist/i18n-react"; +import { FormikProvider, useFormik } from "formik"; +import * as yup from "yup"; +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Divider, + FormControl, + Grid2, + IconButton, + InputLabel, + MenuItem, + Select, + Typography +} from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import { UploadInputV3 } from "openstack-uicore-foundation/lib/components"; +import { getCountryList } from "openstack-uicore-foundation/lib/utils/query-actions"; +import Table from "openstack-uicore-foundation/lib/components/mui/table"; +import MuiFormikTextField from "openstack-uicore-foundation/lib/components/mui/formik-inputs/textfield"; +import MuiFormikSelect from "openstack-uicore-foundation/lib/components/mui/formik-inputs/select"; +// import MuiFormikAsyncAutocomplete from "openstack-uicore-foundation/lib/components/mui/formik-inputs/async-select"; +import useScrollToError from "../../../hooks/useScrollToError"; +import FormikTextEditor from "../../../components/inputs/formik-text-editor"; +import MuiFormikColorInput from "../../../components/mui/formik-inputs/mui-formik-color-input"; +import MuiFormikAsyncAutocomplete from "../../../components/mui/formik-inputs/mui-formik-async-select"; +import showConfirmDialog from "../../../components/mui/showConfirmDialog"; + +const MEMBER_LEVELS = [ + { label: "Platinum", value: "Platinum" }, + { label: "Gold", value: "Gold" }, + { label: "StartUp", value: "StartUp" }, + { label: "Corporate", value: "Corporate" }, + { label: "Mention", value: "Mention" }, + { label: "None", value: "None" } +]; + +const getLogoValue = (value) => + value ? [{ filename: value, file_path: value }] : []; + +const CompanyDialog = ({ + entity: initialEntity, + sponsoredProjects = [], + onSave, + onClose, + onDeleteSponsorship, + onAddSponsorship +}) => { + const [selectedSponsoredProject, setSelectedSponsoredProject] = + useState(null); + const [selectedSponsorShipType, setSelectedSponsorShipType] = useState(null); + const [sponsorShipTypes, setSponsorShipTypes] = useState([]); + + const formik = useFormik({ + initialValues: { + id: initialEntity?.id ?? 0, + name: initialEntity?.name ?? "", + url: initialEntity?.url ?? "", + contact_email: initialEntity?.contact_email ?? "", + member_level: initialEntity?.member_level ?? "", + color: initialEntity?.color ?? "", + admin_email: initialEntity?.admin_email ?? "", + city: initialEntity?.city ?? "", + state: initialEntity?.state ?? "", + industry: initialEntity?.industry ?? "", + products: initialEntity?.products ?? "", + contributions: initialEntity?.contributions ?? "", + description: initialEntity?.description ?? "", + overview: initialEntity?.overview ?? "", + commitment: initialEntity?.commitment ?? "", + logo: initialEntity?.logo ?? "", + big_logo: initialEntity?.big_logo ?? "" + }, + enableReinitialize: true, + validationSchema: yup.object().shape({ + name: yup.string().required(T.translate("validation.required")) + }), + onSubmit: (values) => onSave(values) + }); + + useScrollToError(formik, true); + + const title = initialEntity?.id + ? `${T.translate("general.edit")} ${T.translate("edit_company.company")}` + : `${T.translate("general.add")} ${T.translate("edit_company.company")}`; + + const handleLogoUploadComplete = (field) => (response) => { + const path = + response.path && response.name + ? `${response.path}${response.name}` + : response.file_url ?? response.path ?? ""; + formik.setFieldValue(field, path); + }; + + const handleLogoRemove = (field) => () => { + formik.setFieldValue(field, ""); + }; + + const handleSelectedSponsoredProject = (ev) => { + const { value } = ev.target; + const project = sponsoredProjects.find((p) => p.id == value); + setSelectedSponsoredProject(value); + setSponsorShipTypes( + project + ? project.sponsorship_types.map((s) => ({ label: s.name, value: s.id })) + : [] + ); + setSelectedSponsorShipType(null); + }; + + const handleAddSponsorshipType = () => { + if (!selectedSponsoredProject || !selectedSponsorShipType) return; + onAddSponsorship( + formik.values.id, + selectedSponsoredProject, + selectedSponsorShipType + ); + }; + + const handleDeleteSponsorship = (sponsorshipId) => { + const sponsorship = initialEntity?.project_sponsorships?.find( + (ps) => ps.id === sponsorshipId + ); + if (!sponsorship) return; + const supportingCompany = sponsorship.supporting_companies?.find( + (sc) => sc.company_id === formik.values.id + ); + if (!supportingCompany) return; + + const confirm = showConfirmDialog({ + title: T.translate("general.are_you_sure"), + text: T.translate("edit_company.delete_supporting_company_warning") + }); + + if (confirm) + onDeleteSponsorship( + sponsorship.sponsored_project.id, + sponsorshipId, + supportingCompany.id + ); + }; + + const sponsored_project_columns = [ + { + columnKey: "project_name", + header: T.translate("edit_company.project_name") + }, + { columnKey: "name", header: T.translate("edit_company.sponsorship_type") } + ]; + + const sponsored_projects_ddl = sponsoredProjects.map((sp) => ({ + label: sp.name, + value: sp.id + })); + + const showOpenStackSection = + formik.values.id > 0 && window.APP_CLIENT_NAME === "openstack"; + + return ( + + + {title} + + + + + + + + + + + + {T.translate("edit_company.name")} * + + + + + + {T.translate("edit_company.url")} + + + + + + {T.translate("edit_company.contact_email")} + + + + + + + {T.translate("edit_company.member_level")} + + + {MEMBER_LEVELS.map((lvl) => ( + + {lvl.label} + + ))} + + + + + {T.translate("edit_company.color")} + + + + + + {T.translate("edit_company.admin_email")} + + + + + + + {T.translate("edit_company.city")} + + + + + + {T.translate("edit_company.state")} + + + + + + {T.translate("edit_company.country")} + + getCountryList(callback)} + formatOption={(country) => ({ + value: country.iso_code, + label: country.name + })} + defaultOptions + /> + + + + {T.translate("edit_company.industry")} + + + + + + {T.translate("edit_company.products")} + + + + + + {T.translate("edit_company.contributions")} + + + + + + + {T.translate("edit_company.description")} + + + + + + {T.translate("edit_company.overview")} + + + + + + {T.translate("edit_company.commitment")} + + + + + {showOpenStackSection && ( + + + + {T.translate("edit_company.project_name")} + + + + + + + + + {T.translate("edit_company.sponsorship_type")} + + + + + + + +   + + + + + )} + + {initialEntity.project_sponsorships.length > 0 && + window.APP_CLIENT_NAME == "openstack" && ( + +
({ + ...sp, + project_name: sp.sponsored_project.name + }))} + columns={sponsored_project_columns} + onDelete={handleDeleteSponsorship} + /> + + )} + + + {T.translate("edit_company.logo")} + + + {T.translate("edit_company.big_logo")} + + + + + + + + + + + ); +}; + +CompanyDialog.propTypes = { + entity: PropTypes.object.isRequired, + sponsoredProjects: PropTypes.array, + onClose: PropTypes.func.isRequired, + onSave: PropTypes.func.isRequired, + onDeleteSponsorship: PropTypes.func, + onAddSponsorship: PropTypes.func +}; + +export default CompanyDialog; diff --git a/src/reducers/companies/company-list-reducer.js b/src/reducers/companies/company-list-reducer.js index 3cc82da53..b4967af3a 100644 --- a/src/reducers/companies/company-list-reducer.js +++ b/src/reducers/companies/company-list-reducer.js @@ -9,7 +9,9 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ + +import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; import { REQUEST_COMPANIES, @@ -17,11 +19,9 @@ import { COMPANY_DELETED } from "../../actions/company-actions"; -import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; - const DEFAULT_STATE = { - companies: {}, - term: null, + companies: [], + term: "", order: "id", orderDir: 1, currentPage: 1, @@ -37,25 +37,25 @@ const companyListReducer = (state = DEFAULT_STATE, action) => { return DEFAULT_STATE; } case REQUEST_COMPANIES: { - let { order, orderDir, term, page } = payload; - return { ...state, order, orderDir, term, currentPage: page }; + const { order, orderDir, term, page, perPage } = payload; + return { ...state, order, orderDir, term, currentPage: page, perPage }; } case RECEIVE_COMPANIES: { - let { current_page, total, last_page } = payload.response; - let companies = payload.response.data.map((c) => ({ + const { current_page, total, last_page } = payload.response; + const companies = payload.response.data.map((c) => ({ ...c })); return { ...state, - companies: companies, + companies, currentPage: current_page, totalCompanies: total, lastPage: last_page }; } case COMPANY_DELETED: { - let { companyId } = payload; + const { companyId } = payload; return { ...state, companies: state.companies.filter((s) => s.id !== companyId) diff --git a/src/reducers/companies/company-reducer.js b/src/reducers/companies/company-reducer.js index 408fcb3a9..3f2a049c4 100644 --- a/src/reducers/companies/company-reducer.js +++ b/src/reducers/companies/company-reducer.js @@ -9,7 +9,10 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - **/ + * */ + +import { VALIDATE } from "openstack-uicore-foundation/lib/utils/actions"; +import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; import { RECEIVE_COMPANY, @@ -25,9 +28,6 @@ import { SPONSORED_PROJECT_SPONSORSHIP_TYPE_SUPPORTING_COMPANY_ADDED } from "../../actions/sponsored-project-actions"; -import { VALIDATE } from "openstack-uicore-foundation/lib/utils/actions"; -import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; - export const DEFAULT_ENTITY = { id: 0, name: "", @@ -49,7 +49,7 @@ export const DEFAULT_ENTITY = { commitment_author: "", logo: "", big_logo: "", - color: "#DADADA", + color: "", project_sponsorships: [] }; @@ -63,65 +63,46 @@ const companyReducer = (state = DEFAULT_STATE, action) => { const { type, payload } = action; switch (type) { case LOGOUT_USER: - { - // we need this in ce the token expired while editing the form - if (payload.hasOwnProperty("persistStore")) { - return state; - } else { - return { ...state, entity: { ...DEFAULT_ENTITY }, errors: {} }; - } + // we need this in ce the token expired while editing the form + if (payload.hasOwnProperty("persistStore")) { + return state; } - break; + return { ...state, entity: { ...DEFAULT_ENTITY }, errors: {} }; case RESET_COMPANY_FORM: - { - return DEFAULT_STATE; - } - break; + return DEFAULT_STATE; case UPDATE_COMPANY: - { - return { ...state, entity: { ...payload }, errors: {} }; - } - break; + return { ...state, entity: { ...payload }, errors: {} }; case COMPANY_ADDED: - case RECEIVE_COMPANY: - { - let entity = { ...payload.response }; - - for (var key in entity) { - if (entity.hasOwnProperty(key)) { - entity[key] = entity[key] == null ? "" : entity[key]; - } + case RECEIVE_COMPANY: { + const entity = { ...payload.response }; + for (const key in entity) { + if (entity.hasOwnProperty(key)) { + entity[key] = entity[key] == null ? "" : entity[key]; } - - return { - ...state, - entity: { ...DEFAULT_ENTITY, ...entity }, - errors: {} - }; } - break; + + return { + ...state, + entity: { ...DEFAULT_ENTITY, ...entity }, + errors: {} + }; + } case LOGO_ATTACHED: { - let logo = state.entity.logo + "?" + new Date().getTime(); - return { ...state, entity: { ...state.entity, logo: logo } }; + const logo = `${state.entity.logo}?${new Date().getTime()}`; + return { ...state, entity: { ...state.entity, logo } }; } case BIG_LOGO_ATTACHED: { - let logo = state.entity.big_logo + "?" + new Date().getTime(); + const logo = `${state.entity.big_logo}?${new Date().getTime()}`; return { ...state, entity: { ...state.entity, big_logo: logo } }; } case COMPANY_UPDATED: - { - return state; - } - break; + return state; case VALIDATE: - { - return { ...state, errors: payload.errors }; - } - break; + return { ...state, errors: payload.errors }; case SPONSORED_PROJECT_SPONSORSHIP_TYPE_SUPPORTING_COMPANY_DELETED: { let { project_sponsorships } = state.entity; - let f = project_sponsorships.find((ps) => { - let e = ps.supporting_companies.find( + const f = project_sponsorships.find((ps) => { + const e = ps.supporting_companies.find( (sp) => sp.id == payload.supportingCompanyId ); return e; @@ -129,15 +110,15 @@ const companyReducer = (state = DEFAULT_STATE, action) => { project_sponsorships = project_sponsorships.filter((e) => e.id != f.id); return { ...state, - entity: { ...state.entity, project_sponsorships: project_sponsorships } + entity: { ...state.entity, project_sponsorships } }; } case SPONSORED_PROJECT_SPONSORSHIP_TYPE_SUPPORTING_COMPANY_ADDED: { - let entity = { ...payload.response }; - let { project_sponsorships } = entity.company; + const entity = { ...payload.response }; + const { project_sponsorships } = entity.company; return { ...state, - entity: { ...state.entity, project_sponsorships: project_sponsorships } + entity: { ...state.entity, project_sponsorships } }; } default: