Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/@/map/map.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,5 @@ export const CountryPaintData = {
}
}
} as const;

export const MaxAllowedDublicateSchoolIds = 500;
28 changes: 18 additions & 10 deletions src/@/map/map.init.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { $isCheckedLastDate, $lastAvailableDates } from '~/@/sidebar/history-graph.model';
import { combine, guard, merge, sample, createEffect } from 'effector';
import { combine, createEffect, guard, merge, sample } from 'effector';
import { Map } from 'mapbox-gl';
import { $isCheckedLastDate, $lastAvailableDates } from '~/@/sidebar/history-graph.model';

import { $admin1Data, $country, countryReceived, setSchoolFocusLatLng, $admin1Id, $countrySearchString, $countryId, $countryMapping } from '~/@/country/country.model';
import { $connectivityBenchMark, $isPauseTimeplayer, $isTimeplayer, $layerUtils, $staticLegendsSelected, $selectedLayerId, onLoadTimePlayerData, onTimeoutTimePlayer, $timePlayerInfo, $isLoadedTimePlayer, $isLoadingTimeplayer, $schoolStatsMap, $schoolAdminId, schoolStatsMap, $schoolStatusSelectedLayer } from '~/@/sidebar/sidebar.model';
import { $admin1Data, $admin1Id, $country, $countryId, $countryMapping, $countrySearchString, countryReceived, setSchoolFocusLatLng } from '~/@/country/country.model';
import { $connectivityBenchMark, $isLoadedTimePlayer, $isLoadingTimeplayer, $isPauseTimeplayer, $isTimeplayer, $layerUtils, $schoolAdminId, $schoolStatsMap, $schoolStatusSelectedLayer, $selectedLayerId, $staticLegendsSelected, $timePlayerInfo, onLoadTimePlayerData, onTimeoutTimePlayer, schoolStatsMap } from '~/@/sidebar/sidebar.model';
import {
fetchAdvanceFilterFx,
fetchCountriesFx,
Expand All @@ -21,11 +21,18 @@ import {
} from '@/map/effects';
import { $connectivityFilter, $connectivitySpeedFilter, $coverageFilter, $selectedLayers } from '@/sidebar/init';

import { languageStore } from '~/core/i18n/store';
import { $theme } from '~/core/theme.model';
import { $isMobile } from '../admin/models/media-query';
import { mapLabelLayerList } from '../country/country.constant';
import { countryTranslationFx, filterTranslationFx } from '../sidebar/effects/all-translation-fx';
import { changeStaticLayerFx, updateConnectivityFilter, updateConnectivityStatus } from './effects/add-layers-fx';
import { addSchoolMarkers } from './effects/add-marker-fx';
import { clearTimeplayer, nextTimePlayerIteration, onLoadStartTimePlayer, onPausePlayTimeplayerFx, timePlayerFx, timePlayerSourceFx } from './effects/time-player.fx';
import { stylePaintData } from './map.constant';
import {
$activeSchoolPopup,
$dublicateSchoolClickData,
$filterListMapping,
$map,
$multipleSchoolPopup,
Expand All @@ -50,12 +57,6 @@ import {
} from './map.model';
import { createLoadingPopupFx, navigateToSchool } from './popup/effects/create-school-popup-fx';
import { updateSchoolPopupFx } from './popup/effects/update-school-popup.fx';
import { $theme } from '~/core/theme.model';
import { clearTimeplayer, nextTimePlayerIteration, onLoadStartTimePlayer, onPausePlayTimeplayerFx, timePlayerFx, timePlayerSourceFx } from './effects/time-player.fx';
import { $isMobile } from '../admin/models/media-query';
import { $lng, languageStore } from '~/core/i18n/store';
import { mapLabelLayerList } from '../country/country.constant';
import { countryTranslationFx, filterTranslationFx } from '../sidebar/effects/all-translation-fx';

sample({
source: $theme,
Expand Down Expand Up @@ -314,6 +315,13 @@ export const $schoolPopupData = combine({
layerUtils: $layerUtils,
})

export const $dublicateSchoolPopupConnectivityMap = $dublicateSchoolClickData.map((data) => data?.length ? data.map(item => schoolStatsMap(item)) : null)
export const $dublicateSchoolPopupData = combine({
feature: $dublicateSchoolPopupConnectivityMap,
stylePaintData: $stylePaintData,
layerUtils: $layerUtils,
})

sample({
clock: merge([fetchSchoolPopupDataFx.doneData]),
source: combine({ popup: $popup, schoolPopupData: $schoolPopupData, country: $country }),
Expand Down
29 changes: 23 additions & 6 deletions src/@/map/map.model.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { createEvent, createStore, restore } from 'effector';

import { fetchAdvanceFilterFx, fetchGlobalStatsFx, fetchSchoolPopupDataFx } from '~/api/project-connect';
import { fetchAdvanceFilterFx, fetchDublicateSchoolPopupDataFx, fetchGlobalStatsFx, fetchSchoolPopupDataFx } from '~/api/project-connect';
import { AdvanceFilterType, GlobalStats, SchoolStatsType } from '~/api/types';
import { GeoJSONPoint } from '~/core/global-types';
import { map } from '~/core/routes';
import { setPayload, setPayloadResults } from '~/lib/effector-kit';

import { getLocalStorage, setLocalStorage } from '~/lib/utils';
import { extractDataWithMapping, reconstructJson } from '~/lib/utils/json-mapper.util';
import { filterTranslationFx } from '../sidebar/effects/all-translation-fx';
import {
defaultGigaLayers,
defaultGlobalStats,
defaultStyle,
filterListMapping,
stylePaintData,
} from './map.constant';
import { Center, Map, MapType, Marker, SchoolMarker, Style, StylePaintData } from './map.types';
import { filterTranslationFx } from '../sidebar/effects/all-translation-fx';
import { extractDataWithMapping, reconstructJson } from '~/lib/utils/json-mapper.util';
import { getLocalStorage, setLocalStorage } from '~/lib/utils';
import { Center, DuplicateSchoolsRequestPayload, Map, MapType, Marker, SchoolMarker, Style, StylePaintData } from './map.types';

export const $reloadStyle = createStore<boolean>(false);
export const onReloadedMap = createEvent();
Expand Down Expand Up @@ -86,9 +86,18 @@ $realtimeSchoolConnectedOpenStatus.on(changeRealtimeSchoolConnectedOpenStatus, s
export const changeGigaSelection = createEvent<{ layerId: number | null }>();
export const $selectedGigaLayers = restore(changeGigaSelection, defaultGigaLayers);

export const setPopupOnClickDot = createEvent<{ id: number; geopoint: GeoJSONPoint } | null>();
export const setPopupOnClickDot = createEvent<{ id: number; geopoint?: GeoJSONPoint | null; allowDublicateSchoolIds?: boolean; } | null>();
export const $activeSchoolPopup = restore(setPopupOnClickDot, null);

export const setSchoolIdsOnPopupClickDot = createEvent<DuplicateSchoolsRequestPayload | null>();
export const $activeDublicateSchoolsPopup = createStore<DuplicateSchoolsRequestPayload | null>(null)
.on(setSchoolIdsOnPopupClickDot, (prev, next) => {
return prev && next && prev.requestId === next.requestId ? prev : next;
});

export const setAllowedDublicateSchoolIds = createEvent<boolean>();
export const $allowDublicateSchoolIds = createStore<boolean>(false).on(setAllowedDublicateSchoolIds, (_, v) => v);

export const onCreateSchoolPopup = createEvent<null | mapboxgl.Popup>();
export const $popup = createStore<mapboxgl.Popup | null>(null);
$popup.on(onCreateSchoolPopup, setPayload);
Expand All @@ -100,6 +109,7 @@ type SchoolClickupPopupType = {
}

export const $schoolClickedId = $activeSchoolPopup.map((data) => data?.id ?? 0);
export const $dublicateSchoolsClickedId = $activeDublicateSchoolsPopup.map((data) => data);
export const setSchoolCLickupPopupDiv = createEvent<SchoolClickupPopupType[] | null>();
export const $schoolClickedPopupDiv = restore<SchoolClickupPopupType[] | null>(setSchoolCLickupPopupDiv, null);

Expand All @@ -108,6 +118,13 @@ export const $multipleSchoolPopup = restore(setMultipleSchoolPopup, null);
export const $schoolClickData = createStore<SchoolStatsType[] | null>(null)
$schoolClickData.on(fetchSchoolPopupDataFx.doneData, setPayload);

export const resetDublicateSchoolClickData = createEvent();
export const setDublicateSchoolCLickupPopupDiv = createEvent<SchoolClickupPopupType[] | null>();
export const $dublicateSchoolClickedPopupDiv = restore<SchoolClickupPopupType[] | null>(setDublicateSchoolCLickupPopupDiv, null);
export const $dublicateSchoolClickData = createStore<SchoolStatsType[] | null>(null)
$dublicateSchoolClickData.on(fetchDublicateSchoolPopupDataFx.doneData, setPayload);
$dublicateSchoolClickData.reset(resetDublicateSchoolClickData);

export const $advanceFilterList = createStore<AdvanceFilterType[]>([]);
$advanceFilterList.on(fetchAdvanceFilterFx.doneData, setPayloadResults);
$advanceFilterList.on(filterTranslationFx.doneData, (state, payload) => {
Expand Down
8 changes: 7 additions & 1 deletion src/@/map/map.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,10 @@ export type UpdateConnectivityType = Pick<ChangeLayerOptions, "map" | "lastSelec
export type SchoolMarker = {
id: number;
marker: Marker;
}
}

export type DuplicateSchoolsRequestPayload = {
ids: number[];
allowDublicateSchoolIds?: boolean;
requestId?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { SkeletonText } from '@carbon/react';
import { SchoolListItem } from './dublicate-school-popup.style';

function DublicateSchoolLoader() {
return (
<SchoolListItem>
<SkeletonText
lineCount={5}
width="100%"
/>
<SkeletonText
lineCount={5}
width="100%"
/>

<SkeletonText
lineCount={5}
width="70%"
/>
</SchoolListItem>
)
}

export default DublicateSchoolLoader
107 changes: 107 additions & 0 deletions src/@/map/ui/map-school-popup/dublicate-school-popup.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { InlineLoading } from "@carbon/react";
import styled from "styled-components";
import { Scroll } from "~/@/scroll";

export const DublicateSchoolListWrapper = styled.div`
font-family: Open Sans;
width: 17.3125rem;
background: ${props => props.theme.grayDark};
border-radius: 0.125rem;
box-shadow: 0 0.5rem 1.25rem 0 rgba(0, 0, 0, 0.55);
display: flex;
flex-direction: column;
`;

export const TotalCountLabel = styled.p`
background: ${props => props.theme.grayDark};
padding: 1rem;
font-size: 0.875rem;
color: #d8d8d8;
font-weight: 400;
vertical-align: middle;
line-height: 1rem;
border-bottom: 0.0625rem solid #525252;
.data-source-tooltip .cds--tooltip-content {
background-color: ${props => props.theme.grayDark} !important;
color: ${props => props.theme.white} !important;
}
.data-source-tooltip .cds--tooltip-caret {
background-color: ${props => props.theme.grayDark} !important;
}
`;

export const DublicateSchoolList = styled(Scroll)`
max-height: 50vh;
overflow-y: auto;
padding: 0 1rem;
`;

export const SchoolListItem = styled.div`
width: 100%;
display: block;
gap: 0.75rem;
padding: 1rem 0;
background: transparent;
border: none;
border-bottom: 0.0625rem solid #525252;
text-align: left;
overflow: hidden;
`;

export const ItemTopSection = styled.div`
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 0.25rem;
`;

export const ItemBottomSection = styled.div`
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-left: 0.375rem;
`;

export const SchoolInternetSpeed = styled.div`
display: flex;
flex-direction: row;
gap: 0.625rem;
align-items: center;
`;

export const SchoolName = styled.div`
font-size: 1.25rem;
font-weight: 400;
color: ${props => props.theme.filterText};
line-height: 1.75rem;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
`;

export const SchoolItemCount = styled.div`
color: ${props => props.theme.filterText};
font-family: 'Open Sans';
font-size: 0.75rem;
font-weight: 500;
line-height: 1.75rem;
min-width: 4.25rem;
text-align: right;
`;

export const GoToSchoolInfo = styled.button`
width: 2.5rem;
height: 2.5rem;
min-height: 2.5rem;
align-items: center;
justify-content: center;
padding: 0.75rem;
`;

export const LoadingList = styled(InlineLoading)`
padding: 16px;
`
Loading