From 107578ef5130afaa087023b72575668388a1c74e Mon Sep 17 00:00:00 2001 From: Imane Date: Sun, 3 May 2020 12:05:19 +0200 Subject: [PATCH 01/15] Feat(utils/partner) : add is_destination_open parameter in partner.py and add transaction in utils.py Relates to #148 --- .../0003_partner_is_destination_open.py | 16 ++++ backend/backend_app/models/partner.py | 1 + .../management/commands/utils.py | 78 +++++++++++-------- 3 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 backend/backend_app/migrations/0003_partner_is_destination_open.py diff --git a/backend/backend_app/migrations/0003_partner_is_destination_open.py b/backend/backend_app/migrations/0003_partner_is_destination_open.py new file mode 100644 index 00000000..7fa86251 --- /dev/null +++ b/backend/backend_app/migrations/0003_partner_is_destination_open.py @@ -0,0 +1,16 @@ +# Generated by Django 2.1.7 on 2020-05-03 09:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [("backend_app", "0002_auto_20200417_1430")] + + operations = [ + migrations.AddField( + model_name="partner", + name="is_destination_open", + field=models.BooleanField(default=False), + ) + ] diff --git a/backend/backend_app/models/partner.py b/backend/backend_app/models/partner.py index 581068bb..4b4c6c70 100644 --- a/backend/backend_app/models/partner.py +++ b/backend/backend_app/models/partner.py @@ -21,6 +21,7 @@ class Partner(BaseModel): city = models.CharField(max_length=40, null=False) country = models.CharField(max_length=50, null=False) iso_code = models.CharField(max_length=2, null=False) + is_destination_open = models.BooleanField(null=False, default=False) # field that will have to be set manually university = models.ForeignKey( diff --git a/backend/external_data/management/commands/utils.py b/backend/external_data/management/commands/utils.py index 4e66f6ed..8256475e 100644 --- a/backend/external_data/management/commands/utils.py +++ b/backend/external_data/management/commands/utils.py @@ -2,6 +2,7 @@ import logging import os import requests +from django.db import transaction from backend_app.models.course import Course from backend_app.models.currency import Currency @@ -45,25 +46,27 @@ class FixerData(object): def update(self): logger.info("Updating currencies from Fixer API") - response = requests.get( - "http://data.fixer.io/api/latest?access_key={}".format(self.FIXER_API_TOKEN) - ) - data = response.json() + with transaction.atomic(): + response = requests.get( + "http://data.fixer.io/api/latest?access_key={}".format(self.FIXER_API_TOKEN) + ) - if data["success"]: - for (code, rate) in response.json()["rates"].items(): - Currency.objects.update_or_create( - code=code, defaults={"one_EUR_in_this_currency": rate} - ) - ExternalDataUpdateInfo.objects.create(source="fixer") - logger.info("Currency update was successful") + data = response.json() - else: - logger.error( - "Updating currency information from fixer failed, see response from the API below." - ) - logger.error(response.json()) + if data["success"]: + for (code, rate) in response.json()["rates"].items(): + Currency.objects.update_or_create( + code=code, defaults={"one_EUR_in_this_currency": rate} + ) + ExternalDataUpdateInfo.objects.create(source="fixer") + logger.info("Currency update was successful") + + else: + logger.error( + "Updating currency information from fixer failed, see response from the API below." + ) + logger.error(response.json()) class UtcData(object): @@ -75,21 +78,27 @@ class UtcData(object): def update(self): logger.info("Updating UTC Data") - self.update_partners() - paged_data_walk( - "{}/openedDestinations".format(self.UTC_API_ENDPOINT), - self.__import_opened_destinations, - ) - paged_data_walk( - "{}/exchanges".format(self.UTC_API_ENDPOINT), self.__import_exchange_data - ) - paged_data_walk( - "{}/courses".format(self.UTC_API_ENDPOINT), self.__import_course_data - ) - ExternalDataUpdateInfo.objects.create(source="utc") - logger.info("Updating invalidated") - self.__update_invalidated() - logger.info("Updating UTC info done !") + + with transaction.atomic(): + self.update_partners() + + # Reset destination open status on all partners + # before fetching open destinations + Partner.objects.all().update(is_destination_open=False) + paged_data_walk( + "{}/openedDestinations".format(self.UTC_API_ENDPOINT), + self.__import_opened_destinations, + ) + paged_data_walk( + "{}/exchanges".format(self.UTC_API_ENDPOINT), self.__import_exchange_data + ) + paged_data_walk( + "{}/courses".format(self.UTC_API_ENDPOINT), self.__import_course_data + ) + ExternalDataUpdateInfo.objects.create(source="utc") + logger.info("Updating invalidated") + self.__update_invalidated() + logger.info("Updating UTC info done !") update_denormalized_univ_major_minor() update_denormalized_univ_field() @@ -200,13 +209,14 @@ class UtcData(object): logger.info("Importing the list of opened destinations") for destination in response_content: - logger.info(destination["idEtab"]) + utc_partner_id = destination["idEtab"] + logger.info(utc_partner_id) semester = destination["semestre"][:1] year = destination["semestre"][1:] Offer.objects.update_or_create( - utc_partner_id=destination["idEtab"], + utc_partner_id=utc_partner_id, year=year, semester=semester, defaults=dict( @@ -217,6 +227,8 @@ class UtcData(object): majors=destination["branches"], ), ) + # Don't forget to update the destination open status + Partner.objects.filter(utc_id=utc_partner_id).update(is_destination_open=True) def __import_course_data(self, response_content): logger.info("Importing courses data") -- GitLab From 6436f3cb3b605f5feb5f6e2ad684ff0ac2bb008b Mon Sep 17 00:00:00 2001 From: Imane Date: Sun, 3 May 2020 12:21:32 +0200 Subject: [PATCH 02/15] docs(Changelog) : update changelog to add backend changes relates to #148 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef92e00a..4913d1f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ###### _TBD_ +###### _3 May 2020_ + +- [feat] add is_destination_open parameter in partner model and add transaction in utils.py + ## v2.2.0 ###### _26 April 2020_ -- GitLab From 825776979e1319c1634999626d29ba53f74ded04 Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Sun, 3 May 2020 16:22:56 +0200 Subject: [PATCH 03/15] style(backend): run black on entire backend * fixes small style relica --- backend/backend_app/models/exchangeFeedback.py | 2 +- backend/backend_app/models/version.py | 2 +- backend/external_data/management/commands/utils.py | 11 ++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/backend/backend_app/models/exchangeFeedback.py b/backend/backend_app/models/exchangeFeedback.py index 172a3cb2..31c1f19a 100644 --- a/backend/backend_app/models/exchangeFeedback.py +++ b/backend/backend_app/models/exchangeFeedback.py @@ -101,7 +101,7 @@ class ExchangeFeedbackViewSet(EssentialModuleViewSet): "university", "exchange__student_major", "exchange__student_minor", - "untouched" + "untouched", ) required_filterset_fields = ("university",) pagination_class = CustomPagination diff --git a/backend/backend_app/models/version.py b/backend/backend_app/models/version.py index 9c4ab872..b39e9b49 100644 --- a/backend/backend_app/models/version.py +++ b/backend/backend_app/models/version.py @@ -90,4 +90,4 @@ class VersionViewSet(BaseModelViewSet): ct = ContentType.objects.get_for_id(content_type_id) model = ct.model_class() obj = model.objects.get(pk=object_pk) - return Version.objects.get_for_object(obj).order_by('revision_id') + return Version.objects.get_for_object(obj).order_by("revision_id") diff --git a/backend/external_data/management/commands/utils.py b/backend/external_data/management/commands/utils.py index 8256475e..e2436bb3 100644 --- a/backend/external_data/management/commands/utils.py +++ b/backend/external_data/management/commands/utils.py @@ -49,7 +49,9 @@ class FixerData(object): with transaction.atomic(): response = requests.get( - "http://data.fixer.io/api/latest?access_key={}".format(self.FIXER_API_TOKEN) + "http://data.fixer.io/api/latest?access_key={}".format( + self.FIXER_API_TOKEN + ) ) data = response.json() @@ -90,7 +92,8 @@ class UtcData(object): self.__import_opened_destinations, ) paged_data_walk( - "{}/exchanges".format(self.UTC_API_ENDPOINT), self.__import_exchange_data + "{}/exchanges".format(self.UTC_API_ENDPOINT), + self.__import_exchange_data, ) paged_data_walk( "{}/courses".format(self.UTC_API_ENDPOINT), self.__import_course_data @@ -228,7 +231,9 @@ class UtcData(object): ), ) # Don't forget to update the destination open status - Partner.objects.filter(utc_id=utc_partner_id).update(is_destination_open=True) + Partner.objects.filter(utc_id=utc_partner_id).update( + is_destination_open=True + ) def __import_course_data(self, response_content): logger.info("Importing courses data") -- GitLab From 29739569ad73c3d545ba4e36cc71f6815b772e9a Mon Sep 17 00:00:00 2001 From: Estelle Veisemburger Date: Sun, 3 May 2020 17:21:47 +0200 Subject: [PATCH 04/15] fix(Read More Button):only show when necessary --- .../src/components/common/markdown/TruncatedMarkdown.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/markdown/TruncatedMarkdown.jsx b/frontend/src/components/common/markdown/TruncatedMarkdown.jsx index 507e9776..eee2a310 100644 --- a/frontend/src/components/common/markdown/TruncatedMarkdown.jsx +++ b/frontend/src/components/common/markdown/TruncatedMarkdown.jsx @@ -10,11 +10,12 @@ function TruncatedMarkdown(props) { const [truncated, setTruncated] = useState(false); const { source, truncateFromLength, classes } = props; const sourceAsString = source === null ? "" : source; - const truncatable = sourceAsString.length > truncateFromLength; + const truncatable = sourceAsString.length > 3 * truncateFromLength; if (!truncatable) { return ; } + return ( <> @@ -22,9 +23,10 @@ function TruncatedMarkdown(props) { {!truncated &&
} -- GitLab From d1c52109806263482d3391525fe097b913962d71 Mon Sep 17 00:00:00 2001 From: Estelle Veisemburger Date: Sun, 3 May 2020 17:27:48 +0200 Subject: [PATCH 05/15] docs(Changelog): update changelog and Closes #159 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4913d1f3..a44ee5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ###### _3 May 2020_ - [feat] add is_destination_open parameter in partner model and add transaction in utils.py +- [fix] only show Read More button when necessary ## v2.2.0 -- GitLab From 0268d12e28240214c3fe4393da0d478e1ff9d9b7 Mon Sep 17 00:00:00 2001 From: Gautier D Date: Sat, 25 Apr 2020 12:37:29 +0200 Subject: [PATCH 06/15] refacto(backend): update university serializer --- backend/backend_app/models/university.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/backend_app/models/university.py b/backend/backend_app/models/university.py index cf3e00f8..c2a78920 100644 --- a/backend/backend_app/models/university.py +++ b/backend/backend_app/models/university.py @@ -58,6 +58,10 @@ class UniversitySerializer(EssentialModuleSerializer): "acronym", "logo", "website", + "city", + "country", + "main_campus_lat", + "main_campus_lon", "denormalized_infos", ) -- GitLab From a3ad5631174acb3a78f90f1e982b2d18974974bb Mon Sep 17 00:00:00 2001 From: Gautier D Date: Sat, 25 Apr 2020 13:16:38 +0200 Subject: [PATCH 07/15] refacto(frontend): modify campus and city in MainMap --- .gitignore | 1 + frontend/src/components/map/MainMap.jsx | 24 ++++++++----------- .../src/services/data/UniversityService.js | 6 ++--- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index a8fc021e..bae03972 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ database.db-journal .idea npm-debug.log .env +.history diff --git a/frontend/src/components/map/MainMap.jsx b/frontend/src/components/map/MainMap.jsx index e7f5f80f..2a97dafd 100644 --- a/frontend/src/components/map/MainMap.jsx +++ b/frontend/src/components/map/MainMap.jsx @@ -15,25 +15,21 @@ const MAIN_MAP_ID = uuid(); function MainMap() { const [listUnivSel] = useSelectedUniversities(); - const mainCampusesSelection = useMemo(() => { + const univSelection = useMemo(() => { const out = []; - const mainCampuses = UniversityService.getMainCampuses(); + const universities = UniversityService.getUniversities(); - mainCampuses.forEach(campus => { - const univ = UniversityService.getUniversityById(campus.university); - - if (campus && univ) { - const { city, country } = UniversityService.getUnivCityAndCountry( - univ.id - ); + universities.forEach(university => { + const univ = UniversityService.getUniversityById(university.id); + if (univ) { out.push({ univName: univ.name, univLogoUrl: univ.logo, - cityName: city.name, - countryName: country.name, - lat: parseFloat(campus.lat), - lon: parseFloat(campus.lon), + cityName: univ.city, + countryName: univ.country, + lat: parseFloat(univ.main_campus_lat), + lon: parseFloat(univ.main_campus_lon), univId: univ.id, selected: listUnivSel === null || @@ -46,7 +42,7 @@ function MainMap() { }, [listUnivSel]); // create all the markers - return ; + return ; } MainMap.propTypes = {}; diff --git a/frontend/src/services/data/UniversityService.js b/frontend/src/services/data/UniversityService.js index 857118d8..380d866d 100644 --- a/frontend/src/services/data/UniversityService.js +++ b/frontend/src/services/data/UniversityService.js @@ -98,9 +98,9 @@ class UniversityService { * @returns {object} Object with city and country instance of the university (main campus) */ getUnivCityAndCountry(univId) { - const univMainCampus = this.getCampusForUnivId(univId); - const city = CityService.getCityForCityId(univMainCampus.city); - const country = CountryService.getCountryForCountryId(city.country); + const univ = this.getUniversityById(univId); + const city = univ.city; + const country = univ.country; return { city, -- GitLab From 820a74916c35e6cdcfe0cf78cae741506c23bada Mon Sep 17 00:00:00 2001 From: Gautier D Date: Sat, 25 Apr 2020 15:30:12 +0200 Subject: [PATCH 08/15] refacto(backend): modify main map --- frontend/src/components/map/BaseMap.jsx | 29 +++++++++++++++---------- frontend/src/components/map/MainMap.jsx | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/map/BaseMap.jsx b/frontend/src/components/map/BaseMap.jsx index 0c3bc46e..c8991e8a 100644 --- a/frontend/src/components/map/BaseMap.jsx +++ b/frontend/src/components/map/BaseMap.jsx @@ -49,7 +49,8 @@ const ALL_MAPS = {}; * * If an id is provided, the state of the map will be automatically saved and regenerated. */ -function BaseMap({ id, campuses }) { +function BaseMap({ id, universities }) { + console.log("iciciciiojoij", universities); const theme = useTheme(); const classes = useStyles(); @@ -68,7 +69,7 @@ function BaseMap({ id, campuses }) { [id, ALL_MAPS] ); - const openPopup = useCallback(campusInfo => setPopup(campusInfo), []); + const openPopup = useCallback(universityInfo => setPopup(universityInfo), []); const closePopup = useCallback(() => setPopup(undefined), []); const toggleHover = useCallback((mapInstance, cursor) => { @@ -81,21 +82,24 @@ function BaseMap({ id, campuses }) { return ( - {campuses + {universities .filter(c => c.selected === selected) - .map((campusInfo, idx) => ( + .map((universityInfo, idx) => ( openPopup(campusInfo)} + coordinates={[ + universityInfo.main_campus_lon, + universityInfo.main_campus_lat + ]} + onClick={() => openPopup(universityInfo)} onMouseEnter={({ map }) => toggleHover(map, "pointer")} onMouseLeave={({ map }) => toggleHover(map, "")} /> @@ -103,7 +107,7 @@ function BaseMap({ id, campuses }) { ); }, - [campuses, theme] + [universities, theme] ); const style = theme.palette.type === "light" ? "light" : "dark"; @@ -118,6 +122,7 @@ function BaseMap({ id, campuses }) { } return ( +
- {campuses && ( + {universities && ( <> {renderLayer(true)} {renderLayer(false)} )} {popup && ( - + )} @@ -147,12 +152,12 @@ function BaseMap({ id, campuses }) { BaseMap.propTypes = { id: PropTypes.string, - campuses: PropTypes.array + universities: PropTypes.array }; BaseMap.defaultProps = { id: undefined, - campuses: undefined + universities: undefined }; export default BaseMap; diff --git a/frontend/src/components/map/MainMap.jsx b/frontend/src/components/map/MainMap.jsx index 2a97dafd..ccbdda88 100644 --- a/frontend/src/components/map/MainMap.jsx +++ b/frontend/src/components/map/MainMap.jsx @@ -28,8 +28,8 @@ function MainMap() { univLogoUrl: univ.logo, cityName: univ.city, countryName: univ.country, - lat: parseFloat(univ.main_campus_lat), - lon: parseFloat(univ.main_campus_lon), + main_campus_lat: parseFloat(univ.main_campus_lat), + main_campus_lon: parseFloat(univ.main_campus_lon), univId: univ.id, selected: listUnivSel === null || -- GitLab From a023e005071a1053074faadd9849cca09be579ba Mon Sep 17 00:00:00 2001 From: Gautier D Date: Sat, 25 Apr 2020 17:26:09 +0200 Subject: [PATCH 09/15] refacto(frontend): removing city api call --- backend/backend_app/models/campus.py | 2 +- backend/backend_app/models/city.py | 2 +- frontend/src/components/app/App.jsx | 8 +-- frontend/src/components/map/BaseMap.jsx | 1 - frontend/src/components/map/MainMap.jsx | 3 +- .../university/UnivInfoProvider.jsx | 20 +++---- .../university/modules/UniversityGeneral.jsx | 6 +- frontend/src/services/FilterService.js | 2 +- frontend/src/services/data/CityService.js | 60 +++++++++---------- .../src/services/data/UniversityService.js | 52 +--------------- 10 files changed, 54 insertions(+), 102 deletions(-) diff --git a/backend/backend_app/models/campus.py b/backend/backend_app/models/campus.py index 95d94085..11775ae3 100644 --- a/backend/backend_app/models/campus.py +++ b/backend/backend_app/models/campus.py @@ -64,7 +64,7 @@ class CampusViewSet(BaseModelViewSet): permission_classes = (ReadOnly,) queryset = Campus.objects.all() # pylint: disable=E1101 serializer_class = CampusSerializer - end_point_route = "campuses" + end_point_route = "campuses-deprecated" class MainCampusViewSet(BaseModelViewSet): diff --git a/backend/backend_app/models/city.py b/backend/backend_app/models/city.py index b22b6471..8ab446a0 100644 --- a/backend/backend_app/models/city.py +++ b/backend/backend_app/models/city.py @@ -39,4 +39,4 @@ class CityViewSet(BaseModelViewSet): queryset = City.objects.all() # pylint: disable=E1101 serializer_class = CitySerializer permission_classes = (ReadOnly,) - end_point_route = "cities" + end_point_route = "cities-deprecated" diff --git a/frontend/src/components/app/App.jsx b/frontend/src/components/app/App.jsx index df5920ad..e7d182be 100644 --- a/frontend/src/components/app/App.jsx +++ b/frontend/src/components/app/App.jsx @@ -25,7 +25,7 @@ import PageAboutUnlinkedPartners from "../pages/PageAboutUnlinkedPartners"; import PageLogout from "../pages/PageLogout"; import withNetworkWrapper, { NetWrapParam } from "../../hoc/withNetworkWrapper"; import UniversityService from "../../services/data/UniversityService"; -import CityService from "../../services/data/CityService"; +// import CityService from "../../services/data/CityService"; import CountryService from "../../services/data/CountryService"; import CurrencyService from "../../services/data/CurrencyService"; import LanguageService from "../../services/data/LanguageService"; @@ -34,7 +34,7 @@ import useOnBeforeComponentMount from "../../hooks/useOnBeforeComponentMount"; const SERVICES_TO_INITIALIZE = [ UniversityService, - CityService, + // CityService, CountryService, CurrencyService, LanguageService, @@ -104,9 +104,9 @@ App.propTypes = {}; export default compose( withNetworkWrapper([ new NetWrapParam("countries", "all"), - new NetWrapParam("cities", "all"), + //new NetWrapParam("cities", "all"), new NetWrapParam("universities", "all"), - new NetWrapParam("mainCampuses", "all"), + //new NetWrapParam("mainCampuses", "all"), new NetWrapParam("currencies", "all"), new NetWrapParam("languages", "all"), new NetWrapParam("serverModerationStatus", "all") // not needed for server moderation status diff --git a/frontend/src/components/map/BaseMap.jsx b/frontend/src/components/map/BaseMap.jsx index c8991e8a..15b14500 100644 --- a/frontend/src/components/map/BaseMap.jsx +++ b/frontend/src/components/map/BaseMap.jsx @@ -50,7 +50,6 @@ const ALL_MAPS = {}; * If an id is provided, the state of the map will be automatically saved and regenerated. */ function BaseMap({ id, universities }) { - console.log("iciciciiojoij", universities); const theme = useTheme(); const classes = useStyles(); diff --git a/frontend/src/components/map/MainMap.jsx b/frontend/src/components/map/MainMap.jsx index ccbdda88..739b577d 100644 --- a/frontend/src/components/map/MainMap.jsx +++ b/frontend/src/components/map/MainMap.jsx @@ -5,6 +5,7 @@ import BaseMap from "./BaseMap"; import "./map.scss"; import UniversityService from "../../services/data/UniversityService"; +import CountryService from "../../services/data/CountryService"; import { useSelectedUniversities } from "../../hooks/wrappers/useSelectedUniversities"; const MAIN_MAP_ID = uuid(); @@ -27,7 +28,7 @@ function MainMap() { univName: univ.name, univLogoUrl: univ.logo, cityName: univ.city, - countryName: univ.country, + countryName: CountryService.getCountryForCountryId(univ.country).name, main_campus_lat: parseFloat(univ.main_campus_lat), main_campus_lon: parseFloat(univ.main_campus_lon), univId: univ.id, diff --git a/frontend/src/components/university/UnivInfoProvider.jsx b/frontend/src/components/university/UnivInfoProvider.jsx index d3f3f0e1..92c8a2fb 100644 --- a/frontend/src/components/university/UnivInfoProvider.jsx +++ b/frontend/src/components/university/UnivInfoProvider.jsx @@ -2,6 +2,7 @@ import React from "react"; import PropTypes from "prop-types"; import UnivContext from "../../contexts/UnivContext"; import UniversityService from "../../services/data/UniversityService"; +import CountryService from "../../services/data/CountryService"; /** * Univ info provider to pre-fetch some data and make it available down the tree very easily @@ -9,21 +10,18 @@ import UniversityService from "../../services/data/UniversityService"; function UnivInfoProvider({ univId, children }) { const univIdParsed = parseInt(univId, 10); const univ = UniversityService.getUniversityById(univIdParsed); - const { city, country } = UniversityService.getUnivCityAndCountry( - univIdParsed - ); + const country = CountryService.getCountryForCountryId(univ.country) + const city = univ.city const countryId = country.id; - const cityId = city.id; return ( {children} diff --git a/frontend/src/components/university/modules/UniversityGeneral.jsx b/frontend/src/components/university/modules/UniversityGeneral.jsx index 98d5661a..f3385e73 100644 --- a/frontend/src/components/university/modules/UniversityGeneral.jsx +++ b/frontend/src/components/university/modules/UniversityGeneral.jsx @@ -79,7 +79,7 @@ CoreComponent.propTypes = { }).isRequired }; -function UniversityGeneral({ university, city, country }) { +function UniversityGeneral({ university, country, city }) { return ( "Présentation"} @@ -88,7 +88,7 @@ function UniversityGeneral({ university, city, country }) { CoreComponent={props => ( )} @@ -97,7 +97,7 @@ function UniversityGeneral({ university, city, country }) { } UniversityGeneral.propTypes = { - city: PropTypes.object.isRequired, + city: PropTypes.string.isRequired, country: PropTypes.object.isRequired, university: PropTypes.object.isRequired }; diff --git a/frontend/src/services/FilterService.js b/frontend/src/services/FilterService.js index 022da85a..245e48ff 100644 --- a/frontend/src/services/FilterService.js +++ b/frontend/src/services/FilterService.js @@ -20,7 +20,7 @@ class FilterService { universities.forEach(univ => { this._universitiesCountriesCache.set( univ.id, - UniversityService.getUnivCityAndCountry(univ.id).country + CountryService.getCountryForCountryId(univ.country) ); }); diff --git a/frontend/src/services/data/CityService.js b/frontend/src/services/data/CityService.js index 5f70b515..45af78a9 100644 --- a/frontend/src/services/data/CityService.js +++ b/frontend/src/services/data/CityService.js @@ -1,35 +1,35 @@ -import arrayOfInstancesToMap from "../../utils/arrayOfInstancesToMap"; -import { getLatestApiReadData } from "../../hooks/useGlobalState"; +// import arrayOfInstancesToMap from "../../utils/arrayOfInstancesToMap"; +// import { getLatestApiReadData } from "../../hooks/useGlobalState"; -class CityService { - /** - * Stores the cities by its id - * @type {Map} - * @private - */ - _citiesById = new Map(); +// class CityService { +// /** +// * Stores the cities by its id +// * @type {Map} +// * @private +// */ +// _citiesById = new Map(); - /** - * Must be called once before accessing other methods. - */ - initialize() { - const cities = this.getCities(); - this._citiesById = arrayOfInstancesToMap(cities); - } +// /** +// * Must be called once before accessing other methods. +// */ +// initialize() { +// const cities = this.getCities(); +// this._citiesById = arrayOfInstancesToMap(cities); +// } - /** - * Get the city object for a city id - * - * @param {number} cityId - * @returns {Object} - */ - getCityForCityId(cityId) { - return this._citiesById.get(cityId); - } +// /** +// * Get the city object for a city id +// * +// * @param {number} cityId +// * @returns {Object} +// */ +// getCityForCityId(cityId) { +// return this._citiesById.get(cityId); +// } - getCities() { - return getLatestApiReadData("cities-all"); - } -} +// getCities() { +// return getLatestApiReadData("cities-all"); +// } +// } -export default new CityService(); +// export default new CityService(); diff --git a/frontend/src/services/data/UniversityService.js b/frontend/src/services/data/UniversityService.js index 380d866d..35fd0d5d 100644 --- a/frontend/src/services/data/UniversityService.js +++ b/frontend/src/services/data/UniversityService.js @@ -1,5 +1,5 @@ -import CityService from "./CityService"; -import CountryService from "./CountryService"; +// import CityService from "./CityService"; +// import CountryService from "./CountryService"; import arrayOfInstancesToMap from "../../utils/arrayOfInstancesToMap"; import { getLatestApiReadData } from "../../hooks/useGlobalState"; @@ -11,12 +11,7 @@ class UniversityService { */ _universitiesById = new Map(); - /** - * Stores the mainCampuses by university id for quick join - * @type {Map} - * @private - */ - _mainCampusesByUnivId = new Map(); + /** * @private @@ -31,12 +26,6 @@ class UniversityService { const universities = this.getUniversities(); this._universitiesById = arrayOfInstancesToMap(universities); - const mainCampuses = this.getMainCampuses(); - - mainCampuses.forEach(campus => { - this._mainCampusesByUnivId.set(campus.university, campus); - }); - this._options = universities.map(el => ({ value: el.id, label: el.name, @@ -56,14 +45,6 @@ class UniversityService { return this._options; } - /** - * Get the full list of main campuses in the app - * @returns {array} - */ - getMainCampuses() { - return getLatestApiReadData("mainCampuses-all"); - } - /** * @param {number} univId * @returns {Object} @@ -81,33 +62,6 @@ class UniversityService { return this._universitiesById.has(univId); } - /** - * Get the campus object associated with the university given its id. - * - * @param {number} univId - * @returns {Object} - */ - getCampusForUnivId(univId) { - return this._mainCampusesByUnivId.get(univId); - } - - /** - * Function to get the city and the country of a university given a university id - * - * @param {number} univId - * @returns {object} Object with city and country instance of the university (main campus) - */ - getUnivCityAndCountry(univId) { - const univ = this.getUniversityById(univId); - const city = univ.city; - const country = univ.country; - - return { - city, - country - }; - } - /** * * @param {number} univId -- GitLab From c947cc1ecdbd5bbfa8b909e1b58ae391115c1b91 Mon Sep 17 00:00:00 2001 From: Maxime Date: Sun, 3 May 2020 15:07:54 +0200 Subject: [PATCH 10/15] refacto(backend) : delete old campus and city models --- backend/backend_app/admin.py | 4 - .../migrations/0003_auto_20200503_1514.py | 17 +++++ backend/backend_app/models/campus.py | 74 ------------------- backend/backend_app/models/city.py | 42 ----------- backend/backend_app/viewsets.py | 5 -- frontend/src/components/app/App.jsx | 6 -- .../university/UnivInfoProvider.jsx | 4 +- frontend/src/services/data/CityService.js | 35 --------- .../src/services/data/UniversityService.js | 2 - 9 files changed, 19 insertions(+), 170 deletions(-) create mode 100644 backend/backend_app/migrations/0003_auto_20200503_1514.py delete mode 100644 backend/backend_app/models/campus.py delete mode 100644 backend/backend_app/models/city.py delete mode 100644 frontend/src/services/data/CityService.js diff --git a/backend/backend_app/admin.py b/backend/backend_app/admin.py index e39c0db3..5911fce0 100644 --- a/backend/backend_app/admin.py +++ b/backend/backend_app/admin.py @@ -4,8 +4,6 @@ from reversion_compare.admin import CompareVersionAdmin from backend_app.models.abstract.versionedEssentialModule import ( VersionedEssentialModule, ) -from backend_app.models.campus import Campus -from backend_app.models.city import City from backend_app.models.country import Country from backend_app.models.countryDri import CountryDri from backend_app.models.countryScholarship import CountryScholarship @@ -33,8 +31,6 @@ from base_app.models import SiteInformation ALL_MODELS = [ SiteInformation, - Campus, - City, Country, CountryDri, CountryScholarship, diff --git a/backend/backend_app/migrations/0003_auto_20200503_1514.py b/backend/backend_app/migrations/0003_auto_20200503_1514.py new file mode 100644 index 00000000..facd92bb --- /dev/null +++ b/backend/backend_app/migrations/0003_auto_20200503_1514.py @@ -0,0 +1,17 @@ +# Generated by Django 2.1.7 on 2020-05-03 13:14 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("backend_app", "0002_auto_20200417_1430")] + + operations = [ + migrations.AlterUniqueTogether(name="campus", unique_together=set()), + migrations.RemoveField(model_name="campus", name="city"), + migrations.RemoveField(model_name="campus", name="university"), + migrations.RemoveField(model_name="city", name="country"), + migrations.DeleteModel(name="Campus"), + migrations.DeleteModel(name="City"), + ] diff --git a/backend/backend_app/models/campus.py b/backend/backend_app/models/campus.py deleted file mode 100644 index 11775ae3..00000000 --- a/backend/backend_app/models/campus.py +++ /dev/null @@ -1,74 +0,0 @@ -from django.core.validators import MinValueValidator, MaxValueValidator -from django.db import models - -from backend_app.models.abstract.base import ( - BaseModel, - BaseModelSerializer, - BaseModelViewSet, -) -from backend_app.models.city import City -from backend_app.models.university import University -from backend_app.permissions.app_permissions import ReadOnly - - -class Campus(BaseModel): - is_main_campus = models.BooleanField(null=False) - name = models.CharField(max_length=200, default="", blank=True) - city = models.ForeignKey(City, on_delete=models.PROTECT, null=False) - university = models.ForeignKey( - University, - on_delete=models.PROTECT, - null=False, - related_name="university_campuses", - ) - - lat = models.DecimalField( - max_digits=10, - decimal_places=6, - validators=[MinValueValidator(-85.05112878), MaxValueValidator(85.05112878)], - ) - - lon = models.DecimalField( - max_digits=10, - decimal_places=6, - validators=[MinValueValidator(-180), MaxValueValidator(180)], - ) - - def location(self): - return {"lat": self.lat, "lon": self.lon} - - class Meta: - unique_together = ("is_main_campus", "university") - - def save(self, *args, **kwargs): - raise Exception("Can't edit model anymore") - - def delete(self, *args, **kwargs): - raise Exception("Can't edit model anymore") - - -class CampusSerializer(BaseModelSerializer): - class Meta: - model = Campus - fields = BaseModelSerializer.Meta.fields + ( - "is_main_campus", - "name", - "city", - "university", - "lat", - "lon", - ) - - -class CampusViewSet(BaseModelViewSet): - permission_classes = (ReadOnly,) - queryset = Campus.objects.all() # pylint: disable=E1101 - serializer_class = CampusSerializer - end_point_route = "campuses-deprecated" - - -class MainCampusViewSet(BaseModelViewSet): - queryset = Campus.objects.filter(is_main_campus=True) - serializer_class = CampusSerializer - permission_classes = (ReadOnly,) - end_point_route = "mainCampuses" diff --git a/backend/backend_app/models/city.py b/backend/backend_app/models/city.py deleted file mode 100644 index 8ab446a0..00000000 --- a/backend/backend_app/models/city.py +++ /dev/null @@ -1,42 +0,0 @@ -from django.db import models - -from backend_app.models.abstract.base import ( - BaseModel, - BaseModelSerializer, - BaseModelViewSet, -) -from backend_app.models.country import Country -from backend_app.permissions.app_permissions import ReadOnly - - -class City(BaseModel): - name = models.CharField(max_length=200) - local_name = models.CharField(max_length=200, default="", blank=True) - # We add an area to distinguish similarly named cities - # in a country - area = models.CharField(max_length=200, default="", blank=True) - country = models.ForeignKey(Country, on_delete=models.PROTECT) - - def save(self, *args, **kwargs): - raise Exception("Can't edit model anymore") - - def delete(self, *args, **kwargs): - raise Exception("Can't edit model anymore") - - -class CitySerializer(BaseModelSerializer): - class Meta: - model = City - fields = BaseModelSerializer.Meta.fields + ( - "name", - "local_name", - "area", - "country", - ) - - -class CityViewSet(BaseModelViewSet): - queryset = City.objects.all() # pylint: disable=E1101 - serializer_class = CitySerializer - permission_classes = (ReadOnly,) - end_point_route = "cities-deprecated" diff --git a/backend/backend_app/viewsets.py b/backend/backend_app/viewsets.py index f4b1309e..4533948f 100644 --- a/backend/backend_app/viewsets.py +++ b/backend/backend_app/viewsets.py @@ -8,8 +8,6 @@ from rest_framework.viewsets import ViewSet from backend_app.checks import check_viewsets from backend_app.models.abstract.base import BaseModelViewSet from backend_app.models.abstract.essentialModule import EssentialModuleViewSet -from backend_app.models.campus import CampusViewSet, MainCampusViewSet -from backend_app.models.city import CityViewSet from backend_app.models.country import CountryViewSet from backend_app.models.countryDri import CountryDriViewSet from backend_app.models.countryScholarship import CountryScholarshipViewSet @@ -121,9 +119,6 @@ class ExchangeViewSet(BaseModelViewSet): ALL_API_VIEWSETS = [ SiteInformationViewSet, UserViewset, - CampusViewSet, - MainCampusViewSet, - CityViewSet, CountryViewSet, CountryDriViewSet, CountryScholarshipViewSet, diff --git a/frontend/src/components/app/App.jsx b/frontend/src/components/app/App.jsx index e7d182be..ebab9ad9 100644 --- a/frontend/src/components/app/App.jsx +++ b/frontend/src/components/app/App.jsx @@ -25,7 +25,6 @@ import PageAboutUnlinkedPartners from "../pages/PageAboutUnlinkedPartners"; import PageLogout from "../pages/PageLogout"; import withNetworkWrapper, { NetWrapParam } from "../../hoc/withNetworkWrapper"; import UniversityService from "../../services/data/UniversityService"; -// import CityService from "../../services/data/CityService"; import CountryService from "../../services/data/CountryService"; import CurrencyService from "../../services/data/CurrencyService"; import LanguageService from "../../services/data/LanguageService"; @@ -34,15 +33,12 @@ import useOnBeforeComponentMount from "../../hooks/useOnBeforeComponentMount"; const SERVICES_TO_INITIALIZE = [ UniversityService, - // CityService, CountryService, CurrencyService, LanguageService, FilterService ]; -// import PageFiles from "../pages/PageFiles"; - /** * Main entry */ @@ -104,9 +100,7 @@ App.propTypes = {}; export default compose( withNetworkWrapper([ new NetWrapParam("countries", "all"), - //new NetWrapParam("cities", "all"), new NetWrapParam("universities", "all"), - //new NetWrapParam("mainCampuses", "all"), new NetWrapParam("currencies", "all"), new NetWrapParam("languages", "all"), new NetWrapParam("serverModerationStatus", "all") // not needed for server moderation status diff --git a/frontend/src/components/university/UnivInfoProvider.jsx b/frontend/src/components/university/UnivInfoProvider.jsx index 92c8a2fb..ede2517b 100644 --- a/frontend/src/components/university/UnivInfoProvider.jsx +++ b/frontend/src/components/university/UnivInfoProvider.jsx @@ -11,12 +11,12 @@ function UnivInfoProvider({ univId, children }) { const univIdParsed = parseInt(univId, 10); const univ = UniversityService.getUniversityById(univIdParsed); const country = CountryService.getCountryForCountryId(univ.country) - const city = univ.city + const {city} = univ.city const countryId = country.id; return ( } -// * @private -// */ -// _citiesById = new Map(); - -// /** -// * Must be called once before accessing other methods. -// */ -// initialize() { -// const cities = this.getCities(); -// this._citiesById = arrayOfInstancesToMap(cities); -// } - -// /** -// * Get the city object for a city id -// * -// * @param {number} cityId -// * @returns {Object} -// */ -// getCityForCityId(cityId) { -// return this._citiesById.get(cityId); -// } - -// getCities() { -// return getLatestApiReadData("cities-all"); -// } -// } - -// export default new CityService(); diff --git a/frontend/src/services/data/UniversityService.js b/frontend/src/services/data/UniversityService.js index 35fd0d5d..47f1a2e5 100644 --- a/frontend/src/services/data/UniversityService.js +++ b/frontend/src/services/data/UniversityService.js @@ -1,5 +1,3 @@ -// import CityService from "./CityService"; -// import CountryService from "./CountryService"; import arrayOfInstancesToMap from "../../utils/arrayOfInstancesToMap"; import { getLatestApiReadData } from "../../hooks/useGlobalState"; -- GitLab From 963aa367e4a42c7116c317f97d5729bf45365d2f Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Sun, 3 May 2020 17:55:54 +0200 Subject: [PATCH 11/15] fix(backend): merge migration --- .../migrations/0004_merge_20200503_1749.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 backend/backend_app/migrations/0004_merge_20200503_1749.py diff --git a/backend/backend_app/migrations/0004_merge_20200503_1749.py b/backend/backend_app/migrations/0004_merge_20200503_1749.py new file mode 100644 index 00000000..63b984a5 --- /dev/null +++ b/backend/backend_app/migrations/0004_merge_20200503_1749.py @@ -0,0 +1,13 @@ +# Generated by Django 2.1.7 on 2020-05-03 15:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("backend_app", "0003_partner_is_destination_open"), + ("backend_app", "0003_auto_20200503_1514"), + ] + + operations = [] -- GitLab From 037b78a5a2ea79e1ded24732da716fe548f63485 Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Sun, 3 May 2020 17:56:43 +0200 Subject: [PATCH 12/15] fix(front - univ info provider) --- .../src/components/university/UnivInfoProvider.jsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/university/UnivInfoProvider.jsx b/frontend/src/components/university/UnivInfoProvider.jsx index ede2517b..d5677ab3 100644 --- a/frontend/src/components/university/UnivInfoProvider.jsx +++ b/frontend/src/components/university/UnivInfoProvider.jsx @@ -10,18 +10,18 @@ import CountryService from "../../services/data/CountryService"; function UnivInfoProvider({ univId, children }) { const univIdParsed = parseInt(univId, 10); const univ = UniversityService.getUniversityById(univIdParsed); - const country = CountryService.getCountryForCountryId(univ.country) - const {city} = univ.city + const country = CountryService.getCountryForCountryId(univ.country); + const { city } = univ; const countryId = country.id; return ( {children} -- GitLab From 919427fe1201c2dfe2cd216cd27b456f12fdb1c5 Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Sun, 3 May 2020 18:04:57 +0200 Subject: [PATCH 13/15] chore(front): simplifed use of university --- frontend/src/components/map/MainMap.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/components/map/MainMap.jsx b/frontend/src/components/map/MainMap.jsx index 739b577d..a4c44404 100644 --- a/frontend/src/components/map/MainMap.jsx +++ b/frontend/src/components/map/MainMap.jsx @@ -20,9 +20,7 @@ function MainMap() { const out = []; const universities = UniversityService.getUniversities(); - universities.forEach(university => { - const univ = UniversityService.getUniversityById(university.id); - + universities.forEach(univ => { if (univ) { out.push({ univName: univ.name, -- GitLab From 10521594cd22268c523316cf1bf741d316f7cf52 Mon Sep 17 00:00:00 2001 From: Maxime Date: Sun, 3 May 2020 16:03:15 +0200 Subject: [PATCH 14/15] docs: update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a44ee5fd..5bbd22cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ###### _TBD_ +- [refacto] delete campus an city models +- [refacto] frontend modify API calls so that only the university model is used + ###### _3 May 2020_ - [feat] add is_destination_open parameter in partner model and add transaction in utils.py -- GitLab From 7fa2698072bf0e2bac215584d5ca8f98a0e263fd Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Sun, 3 May 2020 18:43:01 +0200 Subject: [PATCH 15/15] release(v.2.3.0) --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bbd22cb..74978af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,14 @@ ###### _TBD_ -- [refacto] delete campus an city models -- [refacto] frontend modify API calls so that only the university model is used +## v2.3.0 ###### _3 May 2020_ - [feat] add is_destination_open parameter in partner model and add transaction in utils.py - [fix] only show Read More button when necessary +- [refacto] delete campus an city models +- [refacto] frontend modify API calls so that only the university model is used ## v2.2.0 -- GitLab