mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-13 05:48:36 +03:00
Merge pull request #98 from forensic-architecture/topic/fixes
Add key and optional cover
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,5 +3,10 @@ build/
|
|||||||
node_modules/
|
node_modules/
|
||||||
config.js
|
config.js
|
||||||
dev.config.js
|
dev.config.js
|
||||||
|
# ignore all covers but the default
|
||||||
|
src/components/presentational/covers/
|
||||||
|
!src/src/components/presentational/covers/Default.js
|
||||||
|
|
||||||
src/\.DS_Store
|
src/\.DS_Store
|
||||||
|
|
||||||
|
\.DS_Store
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ module.exports = {
|
|||||||
INCOMING_DATETIME_FORMAT: '%m/%d/%YT%H:%M',
|
INCOMING_DATETIME_FORMAT: '%m/%d/%YT%H:%M',
|
||||||
MAPBOX_TOKEN: 'pk.EXAMPLE_MAPBOX_TOKEN',
|
MAPBOX_TOKEN: 'pk.EXAMPLE_MAPBOX_TOKEN',
|
||||||
features: {
|
features: {
|
||||||
|
USE_COVER: false,
|
||||||
USE_TAGS: false,
|
USE_TAGS: false,
|
||||||
USE_SEARCH: false,
|
USE_SEARCH: false,
|
||||||
USE_SITES: true,
|
USE_SITES: true,
|
||||||
@@ -32,16 +33,15 @@ module.exports = {
|
|||||||
new Date(2014, 5, 9),
|
new Date(2014, 5, 9),
|
||||||
new Date(2018, 1, 6, 23)
|
new Date(2018, 1, 6, 23)
|
||||||
]
|
]
|
||||||
} }
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
style: {
|
|
||||||
categories: {},
|
|
||||||
shapes: {},
|
|
||||||
narratives: {},
|
|
||||||
selectedEvent: {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
ui: {
|
||||||
|
style: {
|
||||||
|
categories: {},
|
||||||
|
shapes: {},
|
||||||
|
narratives: {},
|
||||||
|
selectedEvent: {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -291,6 +291,13 @@ export function markNotificationsRead () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const TOGGLE_COVER = 'TOGGLE_COVER'
|
||||||
|
export function toggleCover () {
|
||||||
|
return {
|
||||||
|
type: TOGGLE_COVER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ERRORS
|
// ERRORS
|
||||||
|
|
||||||
export const FETCH_SOURCE_ERROR = 'FETCH_SOURCE_ERROR'
|
export const FETCH_SOURCE_ERROR = 'FETCH_SOURCE_ERROR'
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ export default (props) => {
|
|||||||
function renderCategoryTree () {
|
function renderCategoryTree () {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>{copy[props.language].toolbar.categories}</h2>
|
|
||||||
{props.categories.map(cat => {
|
{props.categories.map(cat => {
|
||||||
return (<li
|
return (<li
|
||||||
key={cat.category.replace(/ /g, '_')}
|
key={cat.category.replace(/ /g, '_')}
|
||||||
@@ -31,7 +30,7 @@ export default (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='react-innertabpanel'>
|
<div className='react-innertabpanel'>
|
||||||
<h2>{copy[props.language].toolbar.explore_by_category__title}</h2>
|
<h2>{copy[props.language].toolbar.categories}</h2>
|
||||||
<p>{copy[props.language].toolbar.explore_by_category__description}</p>
|
<p>{copy[props.language].toolbar.explore_by_category__description}</p>
|
||||||
{renderCategoryTree()}
|
{renderCategoryTree()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import NarrativeControls from './presentational/Narrative/Controls.js'
|
|||||||
import InfoPopUp from './InfoPopup.jsx'
|
import InfoPopUp from './InfoPopup.jsx'
|
||||||
import Timeline from './Timeline.jsx'
|
import Timeline from './Timeline.jsx'
|
||||||
import Notification from './Notification.jsx'
|
import Notification from './Notification.jsx'
|
||||||
|
import StaticPage from './StaticPage'
|
||||||
|
import DefaultCover from './presentational/covers/Default'
|
||||||
|
|
||||||
import { parseDate } from '../js/utilities'
|
import { parseDate } from '../js/utilities'
|
||||||
|
|
||||||
@@ -139,7 +141,9 @@ class Dashboard extends React.Component {
|
|||||||
<InfoPopUp
|
<InfoPopUp
|
||||||
ui={ui}
|
ui={ui}
|
||||||
app={app}
|
app={app}
|
||||||
toggle={() => actions.toggleInfoPopup()}
|
methods={{
|
||||||
|
onClose: actions.toggleInfoPopup
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Notification
|
<Notification
|
||||||
isNotification={app.flags.isNotification}
|
isNotification={app.flags.isNotification}
|
||||||
@@ -155,6 +159,13 @@ class Dashboard extends React.Component {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
{process.env.features.USE_COVER && (
|
||||||
|
<StaticPage showing={app.flags.isCover}>
|
||||||
|
{/* enable USE_COVER in config.js features, and customise your header */}
|
||||||
|
{/* pass 'actions.toggleCover' as a prop to your custom header */}
|
||||||
|
<DefaultCover showAppHandler={actions.toggleCover} />
|
||||||
|
</StaticPage>
|
||||||
|
)}
|
||||||
<LoadingOverlay
|
<LoadingOverlay
|
||||||
ui={app.flags.isFetchingDomain}
|
ui={app.flags.isFetchingDomain}
|
||||||
language={app.language}
|
language={app.language}
|
||||||
|
|||||||
@@ -1,84 +1,44 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import copy from '../js/data/copy.json'
|
import copy from '../js/data/copy.json'
|
||||||
// NB: should we make this componetn part of a future feature?
|
|
||||||
|
|
||||||
export default class InfoPopUp extends React.Component {
|
export default ({ ui, app, methods }) => {
|
||||||
renderView2DCopy () {
|
function renderIntro () {
|
||||||
return copy[this.props.app.language].legend.view2d.paragraphs.map(paragraph => <p>{paragraph}</p>)
|
return copy[app.language].legend.default.intro.map(txt => <p>{txt}</p>)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCategoryColors () {
|
function renderCategoryColors () {
|
||||||
const colors = copy[this.props.app.language].legend.view2d.colors.slice(0)
|
const categories = Object.keys(ui.style.categories).filter(label => label !== 'default')
|
||||||
colors.reverse()
|
|
||||||
return (
|
return categories.map(category => (
|
||||||
<div className='legend-labels' style={{ 'margin-left': '-10px' }}>
|
<div className='legend-section'>
|
||||||
{colors.map((color, idx) => {
|
<svg x='0px' y='0px' width='50px' height='20px' viewBox='0 0 100 30' enableBackground='new 0 0 100 30'>
|
||||||
return (
|
<circle opacity='1' fill={ui.style.categories[category]} cx='50' cy='15' r='15' />
|
||||||
<div className='label' style={{ 'margin-left': `${idx * 5}` }}>
|
</svg>
|
||||||
<div className={`color-category ${color.class}`} />
|
<div className='legend-labels'>
|
||||||
{color.label}
|
<div className='label'>{category}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
renderView2DLegend () {
|
function renderView2DLegend () {
|
||||||
return (
|
return (
|
||||||
<div className={`infopopup ${(this.props.app.flags.isInfopopup) ? '' : 'hidden'}`}>
|
<div className={`infopopup ${(app.flags.isInfopopup) ? '' : 'hidden'}`}>
|
||||||
<button onClick={() => this.props.toggle()} className='side-menu-burg over-white is-active'><span /></button>
|
<div className='legend-header'>
|
||||||
{this.renderView2DCopy()}
|
<button onClick={methods.onClose} className='side-menu-burg over-white is-active'><span /></button>
|
||||||
|
<h2>{copy[app.language].legend.default.header}</h2>
|
||||||
|
</div>
|
||||||
|
{renderIntro()}
|
||||||
<div className='legend'>
|
<div className='legend'>
|
||||||
<div className='legend-section' style={{ 'height': '100px' }}>
|
<div className='legend-container'>
|
||||||
<svg x='0px' y='0px' width='100px' height='100px' viewBox='0 0 100 100' enableBackground='new 0 0 100 100'>
|
{renderCategoryColors()}
|
||||||
<circle fill='#D2CD28' cx='50' cy='50' r='50' />
|
|
||||||
<circle fill='#662770' cx='50' cy='50' r='40' />
|
|
||||||
<circle fill='#2F409A' cx='50' cy='50' r='30' />
|
|
||||||
<circle fill='#256C36' cx='50' cy='50' r='20' />
|
|
||||||
<circle fill='#FF0000' cx='50' cy='50' r='10' />
|
|
||||||
</svg>
|
|
||||||
{this.renderCategoryColors()}
|
|
||||||
</div>
|
|
||||||
<div className='legend-section'>
|
|
||||||
<svg x='0px' y='0px' width='100px' height='30px' viewBox='0 0 100 30' enableBackground='new 0 0 100 30'>
|
|
||||||
<line fill='none' stroke='#2F409A' strokeDasharray='4,4' x1='30' y1='15' x2='70' y2='15' />
|
|
||||||
<circle fill='2F409A' fillOpacity='0.2' stroke='#2F409A' strokeDasharray='4,4' cx='80' cy='15' r='10' />
|
|
||||||
<circle fill='2F409A' fillOpacity='0.2' stroke='#2F409A' strokeDasharray='4,4' cx='20' cy='15' r='10' />
|
|
||||||
</svg>
|
|
||||||
<div className='legend-labels'>
|
|
||||||
<div className='label'>Comunicaciones</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='legend-section'>
|
|
||||||
<svg x='0px' y='0px' width='100px' height='30px' viewBox='0 0 100 30' enableBackground='new 0 0 100 30'>
|
|
||||||
<circle opacity='0.3' fill='#FF0000' cx='50' cy='15' r='15' />
|
|
||||||
</svg>
|
|
||||||
<div className='legend-labels'>
|
|
||||||
<div className='label'>Ataques</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='legend-section'>
|
|
||||||
<svg x='0px' y='0px' width='100px' height='30px' viewBox='0 40 100 30' enableBackground='new 0 0 100 70'>
|
|
||||||
<polyline fill='none' stroke='#000000' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' stroke-miterlimit='10' points='
|
|
||||||
8.376,63.723 47.287,63.723 60,46 106,46 ' />
|
|
||||||
<line stroke='#000000' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' x1='33.723' y1='59.663' x2='39.069' y2='63.723' />
|
|
||||||
<line stroke='#000000' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' x1='33.723' y1='67.782' x2='39.069' y2='63.723' />
|
|
||||||
<line stroke='#000000' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' x1='78.849' y1='41.94' x2='84.195' y2='46' />
|
|
||||||
<line stroke='#000000' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' x1='78.849' y1='50.06' x2='84.195' y2='46' />
|
|
||||||
</svg>
|
|
||||||
<div className='legend-labels'>
|
|
||||||
<div className='label'>Rutas de bus</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
return (
|
||||||
return (
|
<div>{renderView2DLegend()}</div>
|
||||||
<div>{this.renderView2DLegend()}</div>
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/components/StaticPage.js
Normal file
9
src/components/StaticPage.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default ({ showing, children }) => {
|
||||||
|
return (
|
||||||
|
<div className={`cover-container ${showing ? 'showing' : ''}`}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -63,7 +63,6 @@ class TagListPanel extends React.Component {
|
|||||||
renderTree () {
|
renderTree () {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>{copy[this.props.language].toolbar.tags}</h2>
|
|
||||||
{this.state.treeComponents.map(c => c)}
|
{this.state.treeComponents.map(c => c)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -72,7 +71,7 @@ class TagListPanel extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className='react-innertabpanel'>
|
<div className='react-innertabpanel'>
|
||||||
<h2>{copy[this.props.language].toolbar.explore_by_tag__title}</h2>
|
<h2>{copy[this.props.language].toolbar.tags}</h2>
|
||||||
<p>{copy[this.props.language].toolbar.explore_by_tag__description}</p>
|
<p>{copy[this.props.language].toolbar.explore_by_tag__description}</p>
|
||||||
{this.renderTree()}
|
{this.renderTree()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
16
src/components/presentational/covers/Default.js
Normal file
16
src/components/presentational/covers/Default.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default ({ showAppHandler }) => (
|
||||||
|
<div className='default-cover-container'>
|
||||||
|
<h3>Here's an example cover.</h3>
|
||||||
|
<p>Replace it with a more descriptive one:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Create a new component in <code>components/presentational/covers</code>.</li>
|
||||||
|
<li>Import in in <code>components/Dashboard.jsx</code> in the <code>render</code> function.</li>
|
||||||
|
</ul>
|
||||||
|
<br /><br />
|
||||||
|
<div>
|
||||||
|
<button onClick={showAppHandler}>Go to app</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
@@ -90,6 +90,14 @@
|
|||||||
{ "class": "category_group03", "label": "Category Group 03" },
|
{ "class": "category_group03", "label": "Category Group 03" },
|
||||||
{ "class": "other", "label": "Other categories" }
|
{ "class": "other", "label": "Other categories" }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"header": "Navigating the Platform",
|
||||||
|
"intro": [
|
||||||
|
"Each event represents an occurence that is distinct in either time, space, or both. An event is represented by a coloured circle on both the map and the timeline.",
|
||||||
|
"Select an event to reveal its content and sources. You can filter events by category or other specified filters in the top left toolbar.",
|
||||||
|
"Narratives compose events to reveal logical threads that emerge from them. Transition to narrative mode by selecting a narrative from the top left dashboard icon."
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"toolbar": {
|
"toolbar": {
|
||||||
|
|||||||
@@ -126,3 +126,13 @@ export function urlFromEnv (ext) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toggleFlagAC (flag) {
|
||||||
|
return (appState) => ({
|
||||||
|
...appState,
|
||||||
|
flags: {
|
||||||
|
...appState.flags,
|
||||||
|
[flag]: !appState.flags[flag]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* global d3 */
|
/* global d3 */
|
||||||
import initial from '../store/initial.js'
|
import initial from '../store/initial.js'
|
||||||
import { parseDate } from '../js/utilities'
|
import { parseDate, toggleFlagAC } from '../js/utilities'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
UPDATE_HIGHLIGHTED,
|
UPDATE_HIGHLIGHTED,
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
TOGGLE_FETCHING_SOURCES,
|
TOGGLE_FETCHING_SOURCES,
|
||||||
TOGGLE_INFOPOPUP,
|
TOGGLE_INFOPOPUP,
|
||||||
TOGGLE_NOTIFICATIONS,
|
TOGGLE_NOTIFICATIONS,
|
||||||
|
TOGGLE_COVER,
|
||||||
FETCH_ERROR,
|
FETCH_ERROR,
|
||||||
FETCH_SOURCE_ERROR
|
FETCH_SOURCE_ERROR
|
||||||
} from '../actions'
|
} from '../actions'
|
||||||
@@ -189,16 +190,6 @@ function toggleLanguage (appState, action) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleSites (appState, action) {
|
|
||||||
return {
|
|
||||||
...appState,
|
|
||||||
flags: {
|
|
||||||
...appState.flags,
|
|
||||||
isShowingSites: !appState.flags.isShowingSites
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSource (appState, action) {
|
function updateSource (appState, action) {
|
||||||
return {
|
return {
|
||||||
...appState,
|
...appState,
|
||||||
@@ -214,37 +205,12 @@ function fetchError (state, action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleFetchingDomain (appState, action) {
|
const toggleSites = toggleFlagAC('isShowingSites')
|
||||||
return Object.assign({}, appState, {
|
const toggleFetchingDomain = toggleFlagAC('isFetchingDomain')
|
||||||
flags: Object.assign({}, appState.flags, {
|
const toggleFetchingSources = toggleFlagAC('isFetchingSources')
|
||||||
isFetchingDomain: !appState.flags.isFetchingDomain
|
const toggleInfoPopup = toggleFlagAC('isInfopopup')
|
||||||
})
|
const toggleNotifications = toggleFlagAC('isNotification')
|
||||||
})
|
const toggleCover = toggleFlagAC('isCover')
|
||||||
}
|
|
||||||
|
|
||||||
function toggleFetchingSources (appState, action) {
|
|
||||||
return Object.assign({}, appState, {
|
|
||||||
flags: Object.assign({}, appState.flags, {
|
|
||||||
isFetchingSources: !appState.flags.isFetchingSources
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleInfoPopup (appState, action) {
|
|
||||||
return Object.assign({}, appState, {
|
|
||||||
flags: Object.assign({}, appState.flags, {
|
|
||||||
isInfopopup: !appState.flags.isInfopopup
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleNotifications (appState, action) {
|
|
||||||
return Object.assign({}, appState, {
|
|
||||||
flags: Object.assign({}, appState.flags, {
|
|
||||||
isNotification: !appState.flags.isNotification
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchSourceError (appState, action) {
|
function fetchSourceError (appState, action) {
|
||||||
return {
|
return {
|
||||||
@@ -278,20 +244,24 @@ function app (appState = initial.app, action) {
|
|||||||
return updateSource(appState, action)
|
return updateSource(appState, action)
|
||||||
case RESET_ALLFILTERS:
|
case RESET_ALLFILTERS:
|
||||||
return resetAllFilters(appState, action)
|
return resetAllFilters(appState, action)
|
||||||
|
/* toggles */
|
||||||
case TOGGLE_LANGUAGE:
|
case TOGGLE_LANGUAGE:
|
||||||
return toggleLanguage(appState, action)
|
return toggleLanguage(appState, action)
|
||||||
case TOGGLE_SITES:
|
case TOGGLE_SITES:
|
||||||
return toggleSites(appState, action)
|
return toggleSites(appState)
|
||||||
|
case TOGGLE_FETCHING_DOMAIN:
|
||||||
|
return toggleFetchingDomain(appState)
|
||||||
|
case TOGGLE_FETCHING_SOURCES:
|
||||||
|
return toggleFetchingSources(appState)
|
||||||
|
case TOGGLE_INFOPOPUP:
|
||||||
|
return toggleInfoPopup(appState)
|
||||||
|
case TOGGLE_NOTIFICATIONS:
|
||||||
|
return toggleNotifications(appState)
|
||||||
|
case TOGGLE_COVER:
|
||||||
|
return toggleCover(appState)
|
||||||
|
/* errors */
|
||||||
case FETCH_ERROR:
|
case FETCH_ERROR:
|
||||||
return fetchError(appState, action)
|
return fetchError(appState, action)
|
||||||
case TOGGLE_FETCHING_DOMAIN:
|
|
||||||
return toggleFetchingDomain(appState, action)
|
|
||||||
case TOGGLE_FETCHING_SOURCES:
|
|
||||||
return toggleFetchingSources(appState, action)
|
|
||||||
case TOGGLE_INFOPOPUP:
|
|
||||||
return toggleInfoPopup(appState, action)
|
|
||||||
case TOGGLE_NOTIFICATIONS:
|
|
||||||
return toggleNotifications(appState, action)
|
|
||||||
case FETCH_SOURCE_ERROR:
|
case FETCH_SOURCE_ERROR:
|
||||||
return fetchSourceError(appState, action)
|
return fetchSourceError(appState, action)
|
||||||
default:
|
default:
|
||||||
|
|||||||
26
src/scss/cover.scss
Normal file
26
src/scss/cover.scss
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.cover-container {
|
||||||
|
position: absolute;
|
||||||
|
top: -100%;
|
||||||
|
left: 0;
|
||||||
|
background-color: black;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0.95;
|
||||||
|
transition: top 0.4s ease;
|
||||||
|
z-index: $overheader + 1;
|
||||||
|
|
||||||
|
color: $offwhite;
|
||||||
|
|
||||||
|
&.showing {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.default-cover-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
@@ -24,87 +24,52 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.legend-section {
|
.legend {
|
||||||
width: 300px;
|
display: flex;
|
||||||
padding-left: 60px;
|
flex-direction: column;
|
||||||
height: 40px;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 100px;
|
|
||||||
float: left;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.legend-labels {
|
|
||||||
float: left;
|
|
||||||
display: inline-block;
|
|
||||||
width: calc(100% - 100px);
|
|
||||||
|
|
||||||
.label {
|
|
||||||
display: block;
|
|
||||||
font-size: $xsmall;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 10px;
|
|
||||||
|
|
||||||
.color-category {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
border-radius: 10px;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0px 5px 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
.legend-labels .label {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.legend-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
h2 {
|
||||||
|
display: flex;
|
||||||
|
font-size: 12pt;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
.side-menu-burg {
|
.side-menu-burg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.legend-item {
|
.legend-container {
|
||||||
display: block;
|
height: 100%;
|
||||||
width: 100%;
|
display: flex;
|
||||||
display: inline-block;
|
flex-direction: column;
|
||||||
margin-bottom: 3px;
|
}
|
||||||
padding-left: 80px;
|
|
||||||
|
|
||||||
.item-label {
|
.legend-section {
|
||||||
line-height: 15px;
|
width: 300px;
|
||||||
height: 15px;
|
height: 25px;
|
||||||
font-size: $normal;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
|
|
||||||
.color-marker {
|
svg {
|
||||||
display: inline-block;
|
width: 60px;
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
float: left;
|
float: left;
|
||||||
margin: 0 10px 0 0;
|
display: inline-block;
|
||||||
border-radius: 15px;
|
|
||||||
|
|
||||||
&.victims { background-color: #C90500; }
|
|
||||||
&.military { background-color: #319C31; }
|
|
||||||
&.nonstate { background-color: #AC28AC; }
|
|
||||||
&.state-police { background-color: #0000BF; }
|
|
||||||
&.iguala-municipal-police { background-color: #00558D; }
|
|
||||||
&.federal-police { background-color: #5756A2; }
|
|
||||||
&.huitzuco-municipal-police { background-color: #4ECAC1; }
|
|
||||||
&.cocula-municipal-police { background-color: #095959; }
|
|
||||||
&.ambulance { background-color: #ffffff; }
|
|
||||||
&.other { background-color: #D3CE2A; }
|
|
||||||
&.drivers { background-color: #822519; }
|
|
||||||
&.communications { background-color: #a6a6a6; }
|
|
||||||
&.GIEI { background-color: #ffffff; }
|
|
||||||
&.PGR { background-color: #000000; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.legend-labels {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: $xsmall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,3 +16,4 @@
|
|||||||
@import 'notification';
|
@import 'notification';
|
||||||
@import 'scene';
|
@import 'scene';
|
||||||
@import 'mediaplayer';
|
@import 'mediaplayer';
|
||||||
|
@import 'cover';
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const initial = {
|
|||||||
map: {
|
map: {
|
||||||
anchor: [31.356397, 34.784818],
|
anchor: [31.356397, 34.784818],
|
||||||
startZoom: 11,
|
startZoom: 11,
|
||||||
minZoom: 7,
|
minZoom: 6,
|
||||||
maxZoom: 18,
|
maxZoom: 18,
|
||||||
bounds: null,
|
bounds: null,
|
||||||
maxBounds: [[180, -180], [-180, 180]]
|
maxBounds: [[180, -180], [-180, 180]]
|
||||||
@@ -84,9 +84,9 @@ const initial = {
|
|||||||
flags: {
|
flags: {
|
||||||
isFetchingDomain: false,
|
isFetchingDomain: false,
|
||||||
isFetchingSources: false,
|
isFetchingSources: false,
|
||||||
|
isCover: true,
|
||||||
isCardstack: true,
|
isCardstack: true,
|
||||||
isInfopopup: false,
|
isInfopopup: true,
|
||||||
isShowingSites: true
|
isShowingSites: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user