Case modal
Этот коммит содержится в:
		
							родитель
							
								
									3ddd9c467a
								
							
						
					
					
						Коммит
						ad33923c37
					
				
							
								
								
									
										20
									
								
								src/lib/components/CardModal.svelte
									
									
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										20
									
								
								src/lib/components/CardModal.svelte
									
									
									
									
									
										Обычный файл
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | <script> | ||||||
|  |     import CaseCard from "./CaseCard.svelte"; | ||||||
|  |     export let modalOpen | ||||||
|  |     export let activeCaseData | ||||||
|  | 
 | ||||||
|  |     function closeModal(){ | ||||||
|  |         modalOpen = false | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <div id="card-modal" class={modalOpen ? "modal is-active" : "modal"}> | ||||||
|  | 	<div class="modal-background" on:click={closeModal}></div> | ||||||
|  | 	<div class="modal-content"> | ||||||
|  |         {#if activeCaseData} | ||||||
|  | 		 <CaseCard cardData={activeCaseData} expanded={true} ></CaseCard> | ||||||
|  |         {/if} | ||||||
|  | 	</div> | ||||||
|  |     <div class="modal-close" on:click={closeModal}></div> | ||||||
|  | </div> | ||||||
| @ -3,7 +3,16 @@ | |||||||
| 	import { utcFormat } from 'd3-time-format'; | 	import { utcFormat } from 'd3-time-format'; | ||||||
| 	import { platformFilter, actorNationFilter, sourceFilter } from '../../stores/filters'; | 	import { platformFilter, actorNationFilter, sourceFilter } from '../../stores/filters'; | ||||||
| 	import ScoreBar from '$lib/components/ScoreBar.svelte'; | 	import ScoreBar from '$lib/components/ScoreBar.svelte'; | ||||||
|  | 
 | ||||||
| 	export let cardData; | 	export let cardData; | ||||||
|  | 	export let expanded; | ||||||
|  | 	export let modalOpen; | ||||||
|  | 	export let activeCaseData | ||||||
|  | 
 | ||||||
|  | 	let openCase = function(caseID){ | ||||||
|  | 		modalOpen = true | ||||||
|  | 		activeCaseData = cardData | ||||||
|  | 	} | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <div class="card" transition:fade id={'case-' + cardData.attribution_id}> | <div class="card" transition:fade id={'case-' + cardData.attribution_id}> | ||||||
| @ -12,6 +21,7 @@ | |||||||
| 			<h2 class="is-size-5">{cardData.short_title}</h2> | 			<h2 class="is-size-5">{cardData.short_title}</h2> | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  | 	{#if expanded} | ||||||
| 		<div class="score-bars"> | 		<div class="score-bars"> | ||||||
| 			<div class="score-bar-wrapper"> | 			<div class="score-bar-wrapper"> | ||||||
| 				<ScoreBar value={cardData.credibility} maxValue={5} /> | 				<ScoreBar value={cardData.credibility} maxValue={5} /> | ||||||
| @ -33,6 +43,7 @@ | |||||||
| 		  {scoreQuestionsExpanded ? 'X' : '?'} | 		  {scoreQuestionsExpanded ? 'X' : '?'} | ||||||
| 		</span--> | 		</span--> | ||||||
| 		</div> | 		</div> | ||||||
|  | 	{/if} | ||||||
| 	<div class="card-image"> | 	<div class="card-image"> | ||||||
| 		<figure class="image"> | 		<figure class="image"> | ||||||
| 			<img src={`/images/${cardData.attribution_id}.jpg`} /> | 			<img src={`/images/${cardData.attribution_id}.jpg`} /> | ||||||
| @ -40,9 +51,12 @@ | |||||||
| 	</div> | 	</div> | ||||||
| 	<div class="card-content"> | 	<div class="card-content"> | ||||||
| 		<div class="content"> | 		<div class="content"> | ||||||
|  | 			{#if expanded} | ||||||
| 				<p>{utcFormat('%B %d, %Y')(new Date(cardData.attribution_date))}</p> | 				<p>{utcFormat('%B %d, %Y')(new Date(cardData.attribution_date))}</p> | ||||||
| 				<p><a href={cardData.attribution_url} target="_blank">{cardData.source}</a></p> | 				<p><a href={cardData.attribution_url} target="_blank">{cardData.source}</a></p> | ||||||
|  | 			{/if} | ||||||
| 			<p>{cardData.short_description}</p> | 			<p>{cardData.short_description}</p> | ||||||
|  | 			{#if expanded} | ||||||
| 				<p> | 				<p> | ||||||
| 					<button class="button is-info is-small" on:click={sourceFilter.selectOne(cardData.source)} | 					<button class="button is-info is-small" on:click={sourceFilter.selectOne(cardData.source)} | ||||||
| 						>{cardData.source}</button | 						>{cardData.source}</button | ||||||
| @ -58,15 +72,19 @@ | |||||||
| 						> | 						> | ||||||
| 					{/each} | 					{/each} | ||||||
| 				</p> | 				</p> | ||||||
|  | 			{/if} | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  | 	{#if !expanded} | ||||||
|  | 	<footer class="card-footer"> | ||||||
|  | 		<button on:click={openCase(cardData.attribution_id)} class="card-footer-item">Open case</button> | ||||||
|  | 	  </footer> | ||||||
|  | 	{/if} | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <style> | <style> | ||||||
| 	div.card { | 	div.card { | ||||||
| 		max-width: 780px; | 		max-width: 780px; | ||||||
| 		/*max-height: 600px; |  | ||||||
| 		overflow-y: scroll;*/ |  | ||||||
| 	} | 	} | ||||||
| 	.score-bars { | 	.score-bars { | ||||||
| 		display: flex; | 		display: flex; | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ | |||||||
| 	import Timeline from '$lib/components/Timeline.svelte'; | 	import Timeline from '$lib/components/Timeline.svelte'; | ||||||
| 	import TimelineMobile from '$lib/components/TimelineMobile.svelte'; | 	import TimelineMobile from '$lib/components/TimelineMobile.svelte'; | ||||||
| 	import Controls from '$lib/components/Controls.svelte'; | 	import Controls from '$lib/components/Controls.svelte'; | ||||||
|  |     import CardModal from '$lib/components/CardModal.svelte'; | ||||||
| 	import AnimatedFilterIcon from '$lib/components/AnimatedFilterIcon.svelte'; | 	import AnimatedFilterIcon from '$lib/components/AnimatedFilterIcon.svelte'; | ||||||
| 	import { splitString, haveOverlap, withinRange, includesTextSearch } from '$lib/utils/misc'; | 	import { splitString, haveOverlap, withinRange, includesTextSearch } from '$lib/utils/misc'; | ||||||
| 	//import { setScales } from '$lib/utils/scales'; | 	//import { setScales } from '$lib/utils/scales'; | ||||||
| @ -29,7 +30,7 @@ | |||||||
| 		fullTimeRange | 		fullTimeRange | ||||||
| 	} from '../stores/filters'; | 	} from '../stores/filters'; | ||||||
| 
 | 
 | ||||||
|     $: console.log($timeRangeFilter) | 	//$: console.log($timeRangeFilter) | ||||||
| 	//$: console.log($fullTimeRange) | 	//$: console.log($fullTimeRange) | ||||||
| 
 | 
 | ||||||
| 	$: innerWidth = 0; | 	$: innerWidth = 0; | ||||||
| @ -49,11 +50,11 @@ | |||||||
| 		cases = cases.filter((d) => d.attribution_id != ''); | 		cases = cases.filter((d) => d.attribution_id != ''); | ||||||
| 		cases.forEach((d) => { | 		cases.forEach((d) => { | ||||||
| 			d.platform = splitString(d.platforms); | 			d.platform = splitString(d.platforms); | ||||||
|             d.medium = splitString(d.medium) | 			d.medium = splitString(d.medium); | ||||||
| 			d.actor_nation = splitString(d.actor_nation); | 			d.actor_nation = splitString(d.actor_nation); | ||||||
| 			d.source = splitString(d.source); | 			d.source = splitString(d.source); | ||||||
| 			d.methods = splitString(d.methods); | 			d.methods = splitString(d.methods); | ||||||
|             d.campaign = splitString(d.campaign) | 			d.campaign = splitString(d.campaign); | ||||||
| 			d.attribution_total_score = +d.attribution_score; | 			d.attribution_total_score = +d.attribution_score; | ||||||
| 			d.attribution_date = new Date(d.attribution_date); | 			d.attribution_date = new Date(d.attribution_date); | ||||||
| 			d.search = [ | 			d.search = [ | ||||||
| @ -79,7 +80,7 @@ | |||||||
| 		sourceFilter.init(cases, 'source'); | 		sourceFilter.init(cases, 'source'); | ||||||
| 		sourceCategoryFilter.init(cases, 'source_category'); | 		sourceCategoryFilter.init(cases, 'source_category'); | ||||||
| 		methodFilter.init(cases, 'methods'); | 		methodFilter.init(cases, 'methods'); | ||||||
|         campaignFilter.init(cases, 'campaign') | 		campaignFilter.init(cases, 'campaign'); | ||||||
| 		$attributionScoreFilter = attributionScoreDef; | 		$attributionScoreFilter = attributionScoreDef; | ||||||
| 		$timeRangeFilter = extent(cases.map((d) => new Date(d.attribution_date))); | 		$timeRangeFilter = extent(cases.map((d) => new Date(d.attribution_date))); | ||||||
| 		//$timeRangeFilter = [new Date('2024-01-01'), max(cases.map((d) => new Date(d.attribution_date)))]; | 		//$timeRangeFilter = [new Date('2024-01-01'), max(cases.map((d) => new Date(d.attribution_date)))]; | ||||||
| @ -188,6 +189,9 @@ | |||||||
| 	]; | 	]; | ||||||
| 
 | 
 | ||||||
| 	let selectedSorting = { id: 'attribution_date', label: 'Attribution Date', type: 'date' }; | 	let selectedSorting = { id: 'attribution_date', label: 'Attribution Date', type: 'date' }; | ||||||
|  | 
 | ||||||
|  | 	let modalOpen = false; | ||||||
|  | 	let activeCaseData; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <svelte:window bind:innerWidth /> | <svelte:window bind:innerWidth /> | ||||||
| @ -198,8 +202,8 @@ | |||||||
| 	<meta property="og:description" content={copy.meta.og_description} /> | 	<meta property="og:description" content={copy.meta.og_description} /> | ||||||
| 	<meta property="og:url" content={copy.meta.og_url} /> | 	<meta property="og:url" content={copy.meta.og_url} /> | ||||||
| 	<meta property="og:image" content={copy.meta.og_image} /> | 	<meta property="og:image" content={copy.meta.og_image} /> | ||||||
|     <meta property="og:type" content="website"> | 	<meta property="og:type" content="website" /> | ||||||
|     <meta property="og:locale" content="en_US"> | 	<meta property="og:locale" content="en_US" /> | ||||||
| </svelte:head> | </svelte:head> | ||||||
| 
 | 
 | ||||||
| {#if isMobile} | {#if isMobile} | ||||||
| @ -233,6 +237,7 @@ | |||||||
| 	</div> | 	</div> | ||||||
| </section> | </section> | ||||||
| 
 | 
 | ||||||
|  | {#if !modalOpen} | ||||||
| <section | <section | ||||||
| 	class={isMobile && sidebarOpen | 	class={isMobile && sidebarOpen | ||||||
| 		? 'section sidebar open controls' | 		? 'section sidebar open controls' | ||||||
| @ -240,8 +245,10 @@ | |||||||
| 			? 'section sidebar closed controls' | 			? 'section sidebar closed controls' | ||||||
| 			: 'section sticky controls'} | 			: 'section sticky controls'} | ||||||
| > | > | ||||||
|  |      | ||||||
| 	<Controls {cases}></Controls> | 	<Controls {cases}></Controls> | ||||||
| </section> | </section> | ||||||
|  | {/if} | ||||||
| 
 | 
 | ||||||
| <section class="section"> | <section class="section"> | ||||||
| 	<div> | 	<div> | ||||||
| @ -293,12 +300,15 @@ | |||||||
| {#if displayDataAs == 'Cards'} | {#if displayDataAs == 'Cards'} | ||||||
| 	<section class="section"> | 	<section class="section"> | ||||||
| 		<div class="container"> | 		<div class="container"> | ||||||
|             <a href="https://fiat-2024-processed-data.s3.us-west-2.amazonaws.com/fiat_2024_attribution_data.csv">Download the data</a> | 			<a | ||||||
|  | 				href="https://fiat-2024-processed-data.s3.us-west-2.amazonaws.com/fiat_2024_attribution_data.csv" | ||||||
|  | 				>Download the data</a | ||||||
|  | 			> | ||||||
| 			<div class="grid is-col-min-16"> | 			<div class="grid is-col-min-16"> | ||||||
| 				{#each sortedCases as attrCase} | 				{#each sortedCases as attrCase} | ||||||
| 					{#if attrCase.show} | 					{#if attrCase.show} | ||||||
| 						<div class="cell"> | 						<div class="cell"> | ||||||
| 							<CaseCard cardData={attrCase}></CaseCard> | 							<CaseCard cardData={attrCase} expanded={false} bind:modalOpen bind:activeCaseData></CaseCard> | ||||||
| 						</div> | 						</div> | ||||||
| 					{/if} | 					{/if} | ||||||
| 				{/each} | 				{/each} | ||||||
| @ -310,7 +320,10 @@ | |||||||
| {#if displayDataAs == 'Table' && sortedCases.length > 0} | {#if displayDataAs == 'Table' && sortedCases.length > 0} | ||||||
| 	<section class="section"> | 	<section class="section"> | ||||||
| 		<div class="container"> | 		<div class="container"> | ||||||
|             <a href="https://fiat-2024-processed-data.s3.us-west-2.amazonaws.com/fiat_2024_attribution_data.csv">Download the data</a> | 			<a | ||||||
|  | 				href="https://fiat-2024-processed-data.s3.us-west-2.amazonaws.com/fiat_2024_attribution_data.csv" | ||||||
|  | 				>Download the data</a | ||||||
|  | 			> | ||||||
| 			<CaseTable cases={sortedCases}></CaseTable> | 			<CaseTable cases={sortedCases}></CaseTable> | ||||||
| 		</div> | 		</div> | ||||||
| 	</section> | 	</section> | ||||||
| @ -329,17 +342,11 @@ | |||||||
| 	</div> | 	</div> | ||||||
| </section> | </section> | ||||||
| 
 | 
 | ||||||
|  | <CardModal bind:modalOpen {activeCaseData}></CardModal> | ||||||
|  | 
 | ||||||
| <style> | <style> | ||||||
| 	section { | 	section { | ||||||
| 		font-family: var(--font-02); | 		font-family: var(--font-02); | ||||||
|     } |  | ||||||
|     .title { |  | ||||||
|         font-family: var(--font-01); |  | ||||||
|         color: var(--usa-blue) |  | ||||||
|     } |  | ||||||
|     .subtitle { |  | ||||||
|         font-family: var(--font-02); |  | ||||||
|         color: var(--usa-blue) |  | ||||||
| 	} | 	} | ||||||
| 	.intro { | 	.intro { | ||||||
| 		max-width: 800px; | 		max-width: 800px; | ||||||
|  | |||||||
		Загрузка…
	
	
			
			x
			
			
		
	
		Ссылка в новой задаче
	
	Block a user
	 Maarten
						Maarten