@publidata/utils-mapper
Version:
Collection of methods to extract data from publidata
1,417 lines (1,263 loc) • 41 kB
JavaScript
import React from "react";
import dayjs from "dayjs";
import customParseFormat from "dayjs/plugin/customParseFormat";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
dayjs.extend(customParseFormat);
dayjs.extend(isSameOrAfter);
import i18next from "i18next";
import isEmpty from "lodash/isEmpty";
import { removeHTML } from "@publidata/utils-core";
import { sortByStartDate, sortObjectByNumber } from "@publidata/utils-sorts";
import {
translateModel,
poiColorTranslation
} from "@publidata/utils-translation";
import { cleanTimezone } from "@publidata/utils-dates";
import kebabCase from "lodash/kebabCase";
import iconsTypes from "./icons-types.json";
import colorsTypes from "./colors-types.json";
import i18n from "./i18n";
i18n.init();
/** Extract Object custom Breadcum object
* @param : object (usually object page)
* @return : arrayOf<Object> [{url: ..., name: ..., position: ...}]
*/
export const getBreadcumb = object => {
if (!object) return null;
if (object.jsonLd) {
const breadCumbObject = object.jsonLd.find(
item => item["@type"] === "BreadcrumbList"
);
if (breadCumbObject && breadCumbObject.itemListElement) {
const result = breadCumbObject.itemListElement.reduce(
(acc, curr) => [
...acc,
{
url: curr.item["@id"],
name: curr.item.name,
position: curr.position
}
],
[]
);
return result.sort(sortObjectByNumber("position", false));
}
return null;
}
return null;
};
/** Extract Object data from an object
* @param : object
* @return : object
*/
export const getData = object => {
if (!object) return null;
if (object._source) return object._source;
if (object.data && object.data.content) {
return {
...object.data,
...object.data.content,
page: object
};
} else if (object && object.content) {
return {
...object.content,
page: object
};
}
return object;
};
/**
* Extract object's blurb
* @param : object (usually object page.content.blurb)
* @return : String
*/
export const getBlurb = object => {
if (!object) return null;
const data = getData(object);
if (data && data.blurb) return removeHTML(data.blurb || "");
if (data && data.pageable) return removeHTML(data.pageable.body || "");
return null;
};
/**
* Extract object's tags
* @param : object (usually object page.content.tags)
* @return : arrayOf<Object> [{ ... }] Tags
*/
export const getTags = object => {
if (!object) return null;
const data = getData(object);
const relicat = /(slug|layout-|www-|sortir-|projet-|color-)/g;
if (data && data.tags) {
if (typeof data.tags === "string") {
return data.tags.split(",").map(name => ({ name }));
} else if (data.tags.length) {
return data.tags.filter(tag => {
if (relicat.test(tag.name)) return null;
return tag;
});
}
}
return [];
};
/**
* Extract Object id
* @param : object
* @return : arrayOf<Object> [{...}] Data of linked object
*/
export const getId = object => {
if (!object) return null;
const data = getData(object);
return data.id;
};
/** Extract Object name from an object
* @param : object
* @return : string , (Example: "Machin")
*/
export const getName = object => {
if (!object) return null;
const data = getData(object);
if (data.name) return data.name;
else if (data.person_id)
return `${data.civility} ${data.first_name} ${data.last_name}`;
return null;
};
/** Extract Object date from an object
* @param : object
* @return : string , (Example: "03/07/2017")
*/
export const getDate = object => {
if (!object) return null;
const data = getData(object);
if (data.date) return dayjs(data.date);
else if (data.release_raw_date)
return dayjs(cleanTimezone(data.release_raw_date), "YYYY-MM-DD");
else if (data.raw_start_date)
return dayjs(cleanTimezone(data.raw_start_date), "YYYY-MM-DD");
return null;
};
/** Extract Object geoShape from an object
* @param : object
* @param : options, added option to shape (such as onClick or popup)
* @return : array of geo shapes, (Example: "[{type: "Polygon", ...}]")
*/
export const getGeoShape = (object, options = {}) => {
if (!object) return null;
let shapesList = [];
const shape = getData(object).geo_shape;
if (shape && Object.keys(shape).length) {
if (shape.geometries) shapesList = shape.geometries;
else shapesList = [shape];
return shapesList.map(data => ({
data,
context: object,
...options
}));
}
return [];
};
/** Extract Object logo from an object
* @param : object
* @param : size, small - medium - large
* @return : string , (Example: "Machin")
*/
export const getLogo = (object, size = "large") => {
if (!object) return null;
if (getData(object).profile_picture) {
const url = getData(object).profile_picture[size];
const dimensions = getData(object).profile_picture[`${size}_dimensions`];
if (dimensions === "x") return "";
return url;
}
return null;
};
/** Extract Object opening hours from an object
* @param : object
* @return : string , (Example: "Machin")
*/
export const getOpeningHours = object => {
if (!object) return null;
const data = getData(object);
if (data.opening_hours) return data.opening_hours;
if (data.schedules && data.schedules.all) return data.schedules.all;
return null;
};
/** Return the best url ever of an object depending of the current instance
* @param : object
* @param : instance
* @return : string , (Example: "http://...")
*/
export const getPage = (object, instance) => {
if (!object) return null;
const data = getData(object);
let url = null;
if (typeof data.page === "object") {
/* eslint-disable prefer-destructuring */
url = data.page.url;
if (!url && data.page.page) url = data.page.page.url;
/* eslint-enable prefer-destructuring */
}
if (!url || !data.pages || data.pages.length === 0) {
url = data.url || null;
}
if (url) return url;
else if (data.pages && data.pages.length) {
if (instance) {
const matchedPage = data.pages
.filter(page => page != null)
.find(page => {
const { name, id, slug } = page.instance;
if (
(name !== undefined && name === instance.name) ||
(id !== undefined && id === instance.id) ||
(slug !== undefined && slug === instance.slug)
)
return true;
return false;
});
url = matchedPage ? matchedPage.url : data.pages[0].url;
} else if (
(!instance || url === null) &&
data.pages !== undefined &&
data.pages[0]
) {
[{ url }] = data.pages;
} else url = null;
} else if (object.url) return object.url;
return url;
};
/** Extract Object model from an object
* @param : object
* @return : string , (Example: "Facility" or "Event")
*/
export const getModel = (object, plural = false, lower = true) => {
if (!object) return null;
const data = getData(object);
if (data.model) return data.model;
if (data._info && data._info.type)
return plural ? data._info.plural : data._info.type;
if (typeof data.type === "string")
return lower ? data.type.toLowerCase() : data.type; // ES case
return null;
};
/** Return page uuid
* @param : object
* @return : string
*/
export const getPageUuid = object => {
if (!object) return null;
if (getModel(object) === "page" || object.template) {
return object.uuid || object.id;
} else if (object.pages && object.pages[0]) {
return object.pages[0].uuid || object.pages[0].id;
}
return null;
};
/** Extract Object nav from a Section
* @param : section object
* @param : type, nav type (Example: "footer_pages_nav")
* @return : object
*/
export const getNav = (settings, type = "instance_nav") => {
if (!type || !settings.navs) return null;
return settings.navs.find(item => item.type === type);
};
/** Extract Object main type from an object
* @param : object
* @return : string , (Example: "event")
*/
export const getType = (object, getSubType = true) => {
if (!object) return null;
const data = getData(object);
const model = getModel(data) ? getModel(data).toLowerCase() : null;
if (getSubType) {
if (data[`${model}_types`] && data[`${model}_types`].length)
return data[`${model}_types`];
if (data[`${model}_type`]) return data[`${model}_type`].name;
if (data.type) {
if (data.type.name) return data.type.name;
}
}
return model;
};
/** Extract Object sub Type from an object
* @param : object
* @return : string , (Example: "Piscine")
*/
export const getSubType = object => {
if (!object) return null;
const data = getData(object);
const model = getModel(object) ? getModel(object).toLowerCase() : null;
if (data[`${model}_types`] && data[`${model}_types`].length)
return data[`${model}_types`];
if (data.type) {
if (data.type.name) return data.type.name;
}
return translateModel(getType(object));
};
/**
* Extract Object linked objects
* @param : object (usually object page.content.linked_objects)
* @param : filters (list of model you want to filter linked objects with)
* @return : arrayOf<Object> [{...}] Data of linked object
*/
export const getLinkedObjects = (object, filters = []) => {
if (!object) return null;
const result = [];
const data = getData(object);
for (const type in data.linked_objects) {
if (data.linked_objects[type].length > 0) {
result.push(...data.linked_objects[type]);
}
}
if (filters.length) {
return result.filter(item => filters.indexOf(getModel(item, true)) !== -1);
}
return result;
};
/** Extract Object type from an object
* @param : object
* @return : array of object types
*/
export const getObjectTypes = object => {
if (!object) return null;
const data = getData(object);
const model = getModel(object) ? getModel(object).toLowerCase() : null;
if (data[`${model}_type`]) return [data[`${model}_type`]];
else if (data[`${model}_types`]) return data[`${model}_types`];
else if (data[`${model}_type_and_ancestors`])
return data[`${model}_type_and_ancestors`];
return model;
};
/** Extract Object cover image from an object
* @param : object
* @param : size (optionnal) - prefer size of image
* @return : string , (Example: "http://... .png")
*/
export const getCover = (object, size = "large") => {
if (!object) return null;
const data = getData(object);
let image = "";
let imageObject = object;
if (data.cover_picture) imageObject = data.cover_picture;
else if (data.profile_picture) imageObject = data.profile_picture;
if (imageObject) {
if (imageObject.large) image = imageObject[size];
if (
imageObject.image_urls_as_json &&
imageObject.image_urls_as_json[`image_${size}_url`]
) {
image = imageObject.image_urls_as_json[`image_${size}_url`];
}
if (imageObject[`image_${size}_url`]) {
image = imageObject[`image_${size}_url`];
}
if (imageObject[`image_${size}`]) {
image = imageObject[`image_${size}`];
}
}
return image.replace("-dev", "-prod");
};
/** Extract Object location from an object
* @param : object
* @param : postalAddress, do you want geocode or postal address
* @param : checkMultiples, do you want to check for multiples positions ?
* @return : object, ex : {lat: 48.6294167, lng: 2.4293747}
*/
export const getLocation = (
object,
postalAddress = false,
checkMultiples = false,
facilityName = false
) => {
if (!object) return null;
let defaultIndex = 0;
if (typeof object.index === "number") defaultIndex = object.index;
const data = getData(object);
if (postalAddress) {
if (data.address) return data.address;
else if (data.locations && data.locations[defaultIndex]) {
if (checkMultiples) return data.locations.map(address => address.address);
return data.locations[defaultIndex].address;
} else if (object.event_dates) {
if (checkMultiples)
return object.event_dates.map(address => address.address);
return object.event_dates[defaultIndex].address;
} else if (object.linked_objects && object.linked_objects.cities) {
const addresses = [];
let address = "";
object.linked_objects.cities.forEach((city, index) => {
if (index) addresses.push(`${address}, ${city.name}`);
else addresses.push(city.name);
address = "";
});
if (checkMultiples) return addresses[defaultIndex];
return addresses.join();
}
return null;
}
if (facilityName) {
if (data.locations && data.locations[defaultIndex]) {
if (checkMultiples) return data.locations.map(address => address.name);
return data.locations[defaultIndex].name !==
data.locations[defaultIndex].address
? data.locations[defaultIndex].name
: null;
}
}
if (data.locations && data.locations[0]) {
if (checkMultiples) return data.locations.map(address => address.location);
return data.locations[0].location;
}
if (getGeoShape(object).length > 0) {
const coords = {
lat: getGeoShape(object)[0].data.coordinates[0][0][1],
lon: getGeoShape(object)[0].data.coordinates[0][0][0]
};
if (checkMultiples) return [coords];
return coords;
}
if (!data.geocode) return null;
const coords = {
lat: data.geocode.lat,
lon: data.geocode.lng
};
if (checkMultiples) return [coords];
return coords;
};
/** Extract Object address from an object
* @param : object
* @return : string , (Example: "6 rue de lagny")
*/
export const getAddress = object => getLocation(object, true);
/** Extract the name of an address from an object
* @param : object
* @return : string , (Example: "La P'tite criée" or "6 rue de lagny")
*/
export const getAddressName = object => getLocation(object, false, false, true);
/** return font awesome icon from social name
* @param : social
* @return : string , (Example: "fas fa-facebook-f")
*/
export const getSocialIcon = social => {
switch (social) {
case "allocine":
return "fas fa-ticket-alt";
case "dailymotion":
return "fas fa-video";
case "facebook":
return "fab fa-facebook-f";
case "flickr":
return "fab fa-flickr";
case "googleplus":
return "fab fa-google-plus-g";
case "instagram":
return "fab fa-instagram";
case "linkedin":
return "fab fa-linkedin-in";
case "medium":
return "fab fa-medium-m";
case "messenger":
return "fab fa-facebook-messenger";
case "rss":
return "fas fa-rss";
case "snapcode_svg":
return "fab fa-snapchat-ghost";
case "twitter":
return "fab fa-twitter";
case "video":
return "fas fa-video";
case "viadeo":
return "fab fa-viadeo";
case "vimeo":
return "fab fa-vimeo-v";
case "youtube":
return "fab fa-youtube";
default: {
return "fas fa-share-alt";
}
}
};
/** return font awesome icon from contact object
* @param : string: "phone"
* @return : string , (Example: "fas fa-facebook-f")
*/
export const getContactIcon = contact => {
if (!contact) return "";
const cleanedContact = contact.toLowerCase();
switch (cleanedContact) {
case "phone":
return "fas fa-phone";
case "email":
return "fas fa-envelope";
case "website":
return "fas fa-globe";
case "phonenumber":
return "fas fa-phone";
case "tollfreephonenumber":
return "fas fa-phone";
case "toll_free_phone_number":
return "fas fa-phone";
case "form":
return "fas fa-link";
case "document":
return "fas fa-file-alt";
case "fax":
return "fas fa-fax";
default: {
return "";
}
}
};
/** return font awesome icon from social name
* @param : social
* @return : string , (Example: "fas fa-facebook-f")
*/
export const getTypeIcon = (type, icons) => {
const matchIcon = str => {
if (icons) {
const matchedIcon = Object.keys(icons).filter(icon => icon === str);
if (matchedIcon.length && icons[matchedIcon[0]])
return icons[matchedIcon[0]];
return null;
}
return null;
};
const sanitizedType = type ? type.toLowerCase() : "";
if (matchIcon(sanitizedType)) {
return matchIcon(sanitizedType);
}
// Get type's associated icons in the icons-types.json file
return iconsTypes[sanitizedType] || "";
};
/**
*
* @param {string} garbageType - The type of garbage (e.g., "glass", "plastic")
* @param {object} instanceColors - An object containing custom colors for different garbage types
* @returns {string} - The color associated with the garbage type, either from instanceColors or colorsTypes
*/
export const getGarbageTypeColorFromInstance = (
garbageType,
instanceColors
) => {
return (
instanceColors[garbageType] ?? colorsTypes[garbageType] ?? "var(--primary)"
);
};
/**
* Get the color associated to a type
* @param {string} type - The type
* @param {object} colors - The custom_settings.colors object
* @returns {string} - The color
*/
export const getTypeColor = (facilityType, colors) => {
const { name, id } = facilityType;
// if a translation is configured in utils-translation, use it
const translation = poiColorTranslation(name, "");
if (translation.length) return translation;
// else, if a color is configured in the instance's custom_settings,
// use the kebabCase of the type name as the color
const customSettingsHasTypeNameColor = colors && colors[kebabCase(name)];
if (customSettingsHasTypeNameColor) return `var(--${kebabCase(name)})`;
// else, if a color is configured in the instance's custom_settings,
// use the kebabCase of the type id as the color
const customSettingsHasIdColor = colors && colors[id];
if (customSettingsHasIdColor) return `var(--${id})`;
return "var(--primary)";
};
/** return correct JSX template according to istance data
* @param {object} instance : instance object
* @param {string} icon : icon string
* @param {array} iconType : iconType array of strings
* @param {string} image : image string
* @param {string} color : color string
* @return {JSX} : JSX template => <i className={icons[item]} />
*/
export const getIconFromInstance = (
icons,
icon,
iconType,
image,
color,
className
) => {
if (icon)
return (
<i style={{ color }} className={`${className}__icon-custom ${icon}`} />
);
if (icons && !image) {
if (iconType.length === 1) {
const item = Object.keys(icons).filter(el => el === iconType[0])[0];
if (icons[item] && icons[item].includes("http")) {
return (
<div
className={`${className}__svg u-bg-cover`}
style={{ backgroundImage: `url(${icons[item]})` }}
/>
);
}
return (
<i className={`${className}__icon ${icons[item]} u-color-white`} />
);
}
return (
<i className={`${className}__icon-fallback fas fa-plus u-color-white`} />
);
}
return <i className={`${className}__icon ${iconType[0]} u-color-white`} />;
};
/** Extract Themes from an object
* @param : object
* @return : Array of objects , (Example: [{id: 1, name: "Culture"}])
*/
export const getThemes = object => {
if (!object) return null;
const data = getData(object);
if (data.themes) return data.themes;
else if (data.thematics) return data.thematics;
return null;
};
/** Extract Punchline from an object
* @param { 0bject } object - object
* @return { String } - content
*/
export const getPunchline = object => {
if (!object) return null;
const data = getData(object);
if (data.punchline) return data.punchline;
else if (data.blurb) return getBlurb(object);
return null;
};
/** return most upcoming event object
* @param : array of events
* @return : object ,
Example: {
event : id: 90571, date: "14-12-2018"
raw_start_date : "2019-02-03T14:30:00.000+00:00"
raw_end_date: "2019-02-03T14:30:00.000+00:00"
}
*/
export const getUpComingEvent = events => {
if (!events) return null;
let upComingEvent;
if (events.length === 1) [upComingEvent] = events;
else {
const eventDates = Array.from(events);
const sortedEvents = eventDates.sort((a, b) => sortByStartDate(a, b));
const today = dayjs();
upComingEvent =
sortedEvents.find(event =>
dayjs(
event.raw_start_date ? event.raw_start_date : event.start_date
).isSameOrAfter(today)
) || sortedEvents[sortedEvents.length - 1];
}
return {
event: upComingEvent,
raw_start_date: upComingEvent.raw_start_date
? cleanTimezone(upComingEvent.raw_start_date)
: cleanTimezone(upComingEvent.start_date),
raw_end_date: upComingEvent.raw_end_date
? cleanTimezone(upComingEvent.raw_end_date)
: cleanTimezone(upComingEvent.end_date)
};
};
export const getSocialAuthor = post => {
if (!post) return null;
if (post.type) {
if (post.type === "facebook" && post.from) return post.from.name;
else if (post.type === "twitter" && post.user) return post.user.name;
else if (post.type === "instagram" && post.user) return post.user.full_name;
}
return null;
};
export const getSocialImage = post => {
if (!post) return null;
if (post.type) {
if (post.type === "facebook") return post.full_picture;
else if (post.type === "twitter") {
if (post.entities && post.entities.media && post.entities.media.length) {
return post.entities.media[0].media_url_https;
} else if (
post.retweeted_status &&
post.retweeted_status.entities &&
post.retweeted_status.entities.media &&
post.retweeted_status.entities.media.length
) {
return post.retweeted_status.entities.media[0].media_url_https;
}
} else if (post.type === "instagram")
return post.images.standard_resolution.url;
}
return null;
};
export const getSocialText = post => {
if (!post) return null;
if (post.type) {
if (post.type === "facebook") return post.message || post.description;
else if (post.type === "twitter") return post.full_text;
else if (post.type === "instagram") return post.caption.text;
}
return null;
};
export const getSocialUrl = post => {
if (!post) return null;
if (post.type) {
if (post.type === "facebook") return post.link;
else if (post.type === "twitter") {
if (
post.retweeted_status &&
post.retweeted_status.entities &&
post.retweeted_status.entities.media &&
post.retweeted_status.entities.media[0] &&
post.retweeted_status.entities.media[0].expanded_url
) {
return post.retweeted_status.entities.media[0].expanded_url.replace(
"/photo/1",
""
);
}
return `https://twitter.com/${post.user.screen_name}/status/${post.id_str}`;
} else if (post.type === "instagram") return post.link;
}
return null;
};
/** return city of an address from Publidata api
* @param {string} address : "20 Rue d'Alsace, 67140 Barr, France"
* @return {object} : { group, postalCode, city }
getCity(address).group => "67140 Barr"
getCity(address).postalCode => "67140"
getCity(address).city => "Barr"
*/
export const getCity = address => {
if (!address) return null;
if (address.split(" ").length === 1) return address;
const postalCodeRegexFr = /[0-9]{5}/;
const postalCodeRegexCa = /[A-Z]\d[A-Z] \d[A-Z]\d/;
const cityNameRegex = /[^,]+/;
const regexFr = new RegExp(
`(${postalCodeRegexFr.source}) (${cityNameRegex.source})`
);
const regexCa = new RegExp(
`(${cityNameRegex.source}) (${postalCodeRegexCa.source})`
);
// FR Format
let match = address.match(regexFr);
if (match) {
const [group, postalCode, city] = match;
return { group, postalCode, city: city.trim() };
}
match = address.match(regexCa);
if (match) {
const [_, city, postalCode] = match;
return {
group: `${postalCode} ${city?.trim()}`,
postalCode,
city: city?.trim()
};
}
const splittedAddress = address.split(", ");
return { city: splittedAddress.reverse()[1]?.trim() };
};
/** return street name of an address from Publidata api
* @param {string} address : "20 Rue d'Alsace, 67140 Barr, France"
* @return {string} : String => "20 Rue d'Alsace"
*/
export const getStreet = address => {
if (!address) return null;
const postalCodeRegexFr = /[0-9]{5}/;
const postalCodeRegexCa = /[A-Z]\d[A-Z] \d[A-Z]\d/;
const postalCodeRegex = new RegExp(
`(${postalCodeRegexFr.source})|(${postalCodeRegexCa.source})`
);
const matchedAddress = address.match(postalCodeRegex);
if (matchedAddress) {
const postalCode = matchedAddress[0];
const splittedAddress = address.split(postalCode);
const street = splittedAddress[0];
return street.replace(/,/g, "")?.trim();
}
const splittedAddress = address.split(", ");
return splittedAddress[0]?.trim() || address;
};
/**
* Extract info from meta
* @param { Object } object : Object
* @param { String } key : Key wanted
* @return { Boolean }
*/
export const getInfoFromMeta = (object, key) => {
if (!object) return null;
const data = getData(object);
if (!data.metas) return null;
return data.metas[key];
};
/**
* Extract Facility secured access
* @param { Object } object : Facility object
* @return { Boolean }
*/
export const getSecuredAccess = object =>
getInfoFromMeta(object, "secured_access");
/**
* Extract Facility delivery date
* @param { Object } : Facility object
* @return { Boolean }
*/
export const getDeliveryDate = object =>
getInfoFromMeta(object, "delivery_date");
/**
* Extract website value
* @param { Object } : Facility object
* @return { Boolean }
*/
export const getWebsite = object => {
if (!object) return null;
const data = getData(object);
if (!data.contacts) return null;
const website = data.contacts.find(({ type }) => type === "Website");
if (!website) return null;
return getInfoFromMeta(website, "value");
};
/**
* Extract Housing type id
* @param { Object } : Housing object
* @return { Integer }
*/
export const getHousingTypeId = object => {
if (!object) return null;
const data = getData(object);
if (!data.facility_type_and_ancestors) return null;
const housingTypes = [356, 450, 93];
const housingType = data.facility_type_and_ancestors.find(type =>
housingTypes.includes(type.id)
);
if (!housingType) return null;
return housingType.id;
};
/**
* Getter for Housing Icon
* @param { Integer } : Housing type id
* @return { String }
*/
export const getHousingIcon = id => {
switch (id) {
case 93:
return "far fa-graduation-cap";
case 356:
return "fal fa-home-heart";
case 450:
default:
return "far fa-home";
}
};
export const arrayReducer = (array, key) => {
if (!array) return null;
return array.reduce((object, current) => {
const newObject = object;
newObject[current[key]] = current;
return newObject;
}, {});
};
export const getMaintainers = object => {
if (!object) return null;
const data = getData(object);
const { maintainers } = data;
if (maintainers) return maintainers;
return null;
};
export const getSource = (object, account, slug) => {
if (!object || !account) return null;
const source = {};
const data = getData(object);
const maintainers = getMaintainers(data);
const owner = maintainers.find(maintainer => maintainer.role === "owner");
source.name = owner.name;
if (owner.name === account)
source.url = data.pages.find(page => page.instance.slug === slug).url;
else source.url = data.pages[0].url;
return source;
};
/** Get an icon (font awesome or image href) from an "icons" dictionnary based on wastecollection objects properties such as collection_mode / garbage_types
* @Param Object, object is the wastecollection object
* @Param Object, icons is the icon dictionnary (icons objet comes from the instance)
* @Return String, a font awesome class or an image href
*/
export const getIconFromWasteCollection = (object, icons) => {
if (!object || !icons) return "fas fa-plus";
if (object.parent && icons[object.parent.id]) return icons[object.parent.id];
if (object.id && icons[object.id]) return icons[object.id];
const { icon } = object.facility;
if (icon) return icon;
const { collectionMode, garbageTypes } = object;
if (collectionMode === "mobile" && garbageTypes.length === 1)
return icons[garbageTypes[0]];
if (
(collectionMode === "mobile" && garbageTypes.length > 1) ||
(collectionMode === "recycling_center" && garbageTypes.length !== 1)
)
return icons[collectionMode];
if (garbageTypes && !isEmpty(garbageTypes)) {
return icons[garbageTypes[0]];
}
return "fas fa-plus";
};
/** Get the color variable associated to a wastecollection object
* @Param Object, object is the wastecollection object
* @Param Object, colors optional param of a color dictionnary to allow hexa returning value (colors object comes from instance object)
* @Return String, a string containing the css variable of a color (ex: var(--primary)), can also be an hexa if you use the optionnal colors param
*/
export const getColorFromWasteCollection = (
wasteCollection,
colors = undefined
) => {
const { garbageTypes, collectionMode, facility, id, instance } =
wasteCollection;
const isMultiFlow =
(collectionMode === "truck" || collectionMode === "recycling_bin") &&
garbageTypes.length > 1;
const fallback = "#A0A0A0";
if (isMultiFlow)
return instance.colors && instance.colors[id]
? instance.colors[id]
: "var(--primary)";
if (!collectionMode && !garbageTypes) return fallback;
if (!colors && facility.color) return facility.color;
const firstGarbageCollectionModeColor = () => {
if (garbageTypes && garbageTypes.length) {
if (colors) return colors[`${garbageTypes[0]}`];
return `var(--${garbageTypes[0]})`;
}
return fallback;
};
// If we collecte only one waste type then we use this collection mode color
if (garbageTypes && garbageTypes.length === 1)
return firstGarbageCollectionModeColor();
// Otherwise we use fallbacks because we can't choose a predominant waste collection mode
if (collectionMode === "recycling_center") {
if (colors) return colors.facility;
return "var(--facility)";
} else if (collectionMode === "mobile") {
if (colors) return colors.mobile;
return "var(--mobile)";
}
// Out of despair, let's at least returning something (ultime fallback)
return firstGarbageCollectionModeColor();
};
export const getTranslationFromMenuAndInstance = (menu, instance) => {
if (!menu || !instance) return null;
const { translationDictionary } = instance;
if (
translationDictionary &&
translationDictionary.fr &&
translationDictionary.fr.translation &&
translationDictionary.fr.translation.canteenMenuName
) {
const { canteenMenuName } = translationDictionary.fr.translation;
return canteenMenuName[menu.id];
}
return null;
};
/** return the string of the collection_mode key in a collect object
* @param { Object } type : { collect }
* @return { String } : String => "recycling_bin"
*/
export const getCollectionMode = object =>
getInfoFromMeta(object, "collection_mode");
/** return an array of the accepted_waste key in a collect object
* @param { Object } type : { collect }
* @return { Array } : Array => ["Pneus", "Piles", "..."]
*/
export const getAcceptedWastes = object =>
getInfoFromMeta(object, "accepted_waste");
/** return an array of the rejected_waste key in a collect object
* @param { Object } type : { collect }
* @return { Array } : Array => ["Pneus", "Piles", "..."]
*/
export const getRejectedWastes = object =>
getInfoFromMeta(object, "rejected_waste");
/** return the array of the garbage_types key in a collect object
* @param { Object } type : { collect }
* @return { Array } : Array => ["text", "emb", "omr"]
*/
export const getGarbageTypes = object => {
const garbageTypes = getInfoFromMeta(object, "garbage_types");
if (!garbageTypes) return [];
return garbageTypes;
};
/**
*
* @param {Object} object - The waste collection object
* @param {Object} metas - The metas object containing garbage types details
* @param {*} instanceSettings - The instance settings containing icons, colors, and translation dictionary
* @returns {Array} - An array of formatted garbage types details, each containing type, icon, color, translation, and additional metas.
*/
export const getGarbageTypesDetails = (object, metas, instanceSettings) => {
const { icons, colors, translationDictionary } = instanceSettings || {};
const { wasteCollection } = translationDictionary?.fr?.translation || {};
const garbageTypes = getGarbageTypes(object);
const formatGarbageTypes = garbageTypes.map(type => {
const icon = getTypeIcon(type, icons);
const color = getGarbageTypeColorFromInstance(type, colors);
return {
type,
icon,
color,
translation:
wasteCollection?.[type] ?? i18next.t(`wasteCollection:${type}`) ?? type,
...(metas?.[type] ?? {})
};
});
return formatGarbageTypes;
};
export const getWasteBlurb = object => getInfoFromMeta(object, "waste_blurb");
export const getObjectBlurb = collect => {
if (!collect || isEmpty(collect)) return null;
const data = getData(collect);
if (data) {
const { blurb } = data;
if (blurb) return blurb;
}
return null;
};
export const getCollectionModeIcon = object => {
if (!object) return null;
const { collectionMode } = object;
const icon = getTypeIcon(collectionMode);
return icon;
};
export const getTranslationFromWastecollectionAndInstance = (
wastecollection,
instance,
facility
) => {
if (!wastecollection || !instance) return null;
const { metas } = wastecollection;
const { collection_mode } = metas;
const { translationDictionary } = instance;
if (
translationDictionary &&
translationDictionary.fr &&
translationDictionary.fr.translation &&
translationDictionary.fr.translation.wastecollectionName
) {
const { wastecollectionName } = translationDictionary.fr.translation;
if (wastecollectionName[wastecollection.id]) {
return wastecollectionName[wastecollection.id];
} else if (
wastecollection.parent &&
wastecollectionName[wastecollection.parent.id]
) {
return wastecollectionName[wastecollection.parent.id];
}
}
if (!isEmpty(facility)) {
if (collection_mode === "recycling_bin") {
if (facility.facilityTypeIdTranslation)
return facility.facilityTypeIdTranslation;
}
if (
collection_mode === "reuse" ||
collection_mode === "mobile" ||
collection_mode === "recycling_center"
) {
return facility.name;
}
}
const garbageTypes = getGarbageTypes(wastecollection);
if (garbageTypes && garbageTypes[0])
return i18next.t(`wasteCollection:${garbageTypes[0]}`);
return null;
};
export const getRedirection = object => {
if (!object) return null;
const redirect = getInfoFromMeta(object, "redirect_to");
const { contacts, documents } = object._source;
const reducedContacts = arrayReducer(contacts, "type");
if (redirect === "website" && reducedContacts.Website) {
return {
url: reducedContacts.Website.metas.value,
text: i18next.t("see_on_the_website"),
icon: "fas fa-external-link"
};
}
if (redirect === "website" && reducedContacts.Form) {
return {
url: reducedContacts.Form.metas.value,
text: i18next.t("see_on_the_website"),
icon: "fas fa-external-link"
};
}
if (redirect === "email" && reducedContacts.Email) {
return {
url: `mailto:${reducedContacts.Email.metas.value}`,
text: i18next.t("send_an_email"),
icon: "fas fa-envelope"
};
}
if (redirect === "media" && !isEmpty(documents)) {
return {
url: documents[0].url,
text: `${i18next.t("download_the")} ${i18next.t(
"wasteCollection:collects_calendar"
)}`,
icon: "fas fa-download"
};
}
if (redirect === "phone" && reducedContacts.PhoneNumber) {
return {
url: `tel:${reducedContacts.PhoneNumber.metas.value}`,
text: reducedContacts.PhoneNumber.metas.value,
icon: "fas fa-phone"
};
}
return null;
};
export const getFacilityTypeIdTranslation = (facilityTypeId, instance) => {
if (!facilityTypeId || !instance) return null;
const { translationDictionary } = instance;
if (
translationDictionary &&
translationDictionary.fr &&
translationDictionary.fr.translation &&
translationDictionary.fr.translation.wastecollectionName
) {
const { wastecollectionName } = translationDictionary.fr.translation;
if (wastecollectionName[`${facilityTypeId}`])
return wastecollectionName[`${facilityTypeId}`];
return i18next.t(`wasteCollection:${facilityTypeId}`);
}
return i18next.t(`wasteCollection:${facilityTypeId}`);
};
export const getAllTheFacilityTypeIdTranslation = (
facilityTypeId,
instance
) => {
if (!facilityTypeId || !instance) return null;
const { translationDictionary } = instance;
if (
translationDictionary &&
translationDictionary.fr &&
translationDictionary.fr.translation &&
translationDictionary.fr.translation.wastecollectionName
) {
const { wastecollectionName } = translationDictionary.fr.translation;
if (wastecollectionName[`all_the_${facilityTypeId}`])
return wastecollectionName[`all_the_${facilityTypeId}`];
return i18next.t(`wasteCollection:all_the_${facilityTypeId}`);
}
return i18next.t(`wasteCollection:all_the_${facilityTypeId}`);
};
export const getFacilityTypeIdPluralTranslation = (
facilityTypeId,
instance
) => {
if (!facilityTypeId || !instance) return null;
const { translationDictionary } = instance;
if (
translationDictionary &&
translationDictionary.fr &&
translationDictionary.fr.translation &&
translationDictionary.fr.translation.wastecollectionName
) {
const { wastecollectionName } = translationDictionary.fr.translation;
if (wastecollectionName[`${facilityTypeId}_plural`])
return wastecollectionName[`${facilityTypeId}_plural`];
return i18next.t(`wasteCollection:${facilityTypeId}_plural`);
}
return i18next.t(`wasteCollection:${facilityTypeId}_plural`);
};
export const getFacilityTypeIdTranslationShort = (facilityTypeId, instance) => {
if (!facilityTypeId || !instance) return null;
const { translationDictionary } = instance;
if (
translationDictionary &&
translationDictionary.fr &&
translationDictionary.fr.translation &&
translationDictionary.fr.translation.wastecollectionName
) {
const { wastecollectionName } = translationDictionary.fr.translation;
if (wastecollectionName[`${facilityTypeId}_short`])
return wastecollectionName[`${facilityTypeId}_short`];
return i18next.t(`wasteCollection:${facilityTypeId}_short`);
}
return i18next.t(`wasteCollection:${facilityTypeId}_short`);
};
export const getWasteCollectionDisplayDistance = (
wasteCollection,
instance
) => {
const defaultValue = 100000;
if (!instance.wasteCollectionDisplayDistances) return defaultValue;
return (
instance.wasteCollectionDisplayDistances[wasteCollection?.id] ||
instance.wasteCollectionDisplayDistances[wasteCollection?.parent?.id] ||
instance.wasteCollectionDisplayDistances[wasteCollection?.collectionMode] ||
defaultValue
);
};
export default {
getPage,
getUrl: getPage,
getBreadcumb,
getData,
getBlurb,
getTags,
getId,
getName,
getDate,
getGeoShape,
getLogo,
getOpeningHours,
getModel,
getPageUuid,
getNav,
getType,
getSubType,
getLinkedObjects,
getObjectTypes,
getCover,
getLocation,
getAddress,
getAddressName,
getSocialIcon,
getContactIcon,
getTypeIcon,
getTypeColor,
getIconFromInstance,
getThemes,
getPunchline,
getUpComingEvent,
getSocialAuthor,
getSocialImage,
getSocialText,
getSocialUrl,
getCity,
getStreet,
getInfoFromMeta,
getSecuredAccess,
getDeliveryDate,
getWebsite,
getHousingTypeId,
getHousingIcon,
arrayReducer,
getMaintainers,
getSource,
getIconFromWasteCollection,
getColorFromWasteCollection,
getTranslationFromMenuAndInstance,
getCollectionMode,
getAcceptedWastes,
getRejectedWastes,
getGarbageTypes,
getWasteBlurb,
getObjectBlurb,
getCollectionModeIcon,
getTranslationFromWastecollectionAndInstance,
getRedirection,
getFacilityTypeIdTranslation,
getAllTheFacilityTypeIdTranslation,
getFacilityTypeIdPluralTranslation,
getFacilityTypeIdTranslationShort,
getWasteCollectionDisplayDistance
};