From dc5a377dcc77e0083c427ffcc60c593e67df2c24 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Wed, 23 Oct 2024 15:29:05 -0700 Subject: [PATCH 01/16] WFNEWS-2411 Add highlights widget to dashboard --- .../src/main/angular/package-lock.json | 4 +- .../src/main/angular/src/app/app.module.ts | 2 + .../dashboard.component.html | 1 + .../highlights-widget.component.html | 30 ++++ .../highlights-widget.component.scss | 137 ++++++++++++++++ .../highlights-widget.component.stories.ts | 128 +++++++++++++++ .../highlights-widget.component.ts | 150 ++++++++++++++++++ .../videos-widget.component.scss | 18 +++ 8 files changed, 468 insertions(+), 2 deletions(-) create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts diff --git a/client/wfnews-war/src/main/angular/package-lock.json b/client/wfnews-war/src/main/angular/package-lock.json index 49ecc538d5..f672b4d167 100644 --- a/client/wfnews-war/src/main/angular/package-lock.json +++ b/client/wfnews-war/src/main/angular/package-lock.json @@ -1,12 +1,12 @@ { "name": "wildfire", - "version": "2.3.9", + "version": "2.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wildfire", - "version": "2.3.9", + "version": "2.4.0", "license": "MIT", "dependencies": { "@angular/animations": "15.2.9", diff --git a/client/wfnews-war/src/main/angular/src/app/app.module.ts b/client/wfnews-war/src/main/angular/src/app/app.module.ts index afd29133bb..32546aa0d4 100644 --- a/client/wfnews-war/src/main/angular/src/app/app.module.ts +++ b/client/wfnews-war/src/main/angular/src/app/app.module.ts @@ -321,6 +321,7 @@ import { CustomReuseStrategy } from './shared/route/custom-route-reuse-strategy' import { initialRootState, rootEffects, rootReducers } from './store'; import { provideBootstrapEffects } from './utils'; import { ShareDialogComponent } from '@app/components/admin-incident-form/share-dialog/share-dialog.component'; +import { HighlightsWidgetComponent } from './components/dashboard-component/widgets/highlights-widget/highlights-widget.component'; // Copied from im-external.module TODO: consolidate in one place export const DATE_FORMATS = { @@ -553,6 +554,7 @@ export const DATE_FORMATS = { AreaRestrictionsCardComponent, PrimaryMediaCardComponent, ContactUsCoreComponent, + HighlightsWidgetComponent, ], imports: [ MatSortModule, diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/dashboard.component.html b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/dashboard.component.html index d540fd752b..978ef7f6f0 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/dashboard.component.html +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/dashboard.component.html @@ -14,6 +14,7 @@

B.C. Wildfire Dashboard

+ diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html new file mode 100644 index 0000000000..d38f0d3b00 --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html @@ -0,0 +1,30 @@ +
+
+ Highlights +
+
+
+
+
+ +
+
+
+ Prevention +
+
+ {{fireCentre}} +
+
+
+ {{post.title}} +
+
+ posted on {{post.date}} +
+
+
+
+
\ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss new file mode 100644 index 0000000000..8dbd0e63d9 --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss @@ -0,0 +1,137 @@ +@import "../../../../../styles/variables"; +@import "notosans-fontface/scss/notosans-fontface"; + +.container { + overflow: hidden; + font-family: "Noto sans", "BCSans", "Open Sans", Verdana, Arial, sans-serif; + display: flex; + flex: 1 0 0; + border-radius: 20px; + background: #fff; + box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1); + max-width: min(1480px, calc(100dvw - 104px)); + padding: var(--24, 24px); + flex-direction: column; + align-items: flex-start; + gap: var(--24, 24px); +} + +.content { + height: calc(100% - 78px); + width: 100%; + display: flex; + align-items: flex-start; + gap: var(--24, 24px); + align-self: stretch; + overflow-x: auto; + overflow-y: hidden; + padding-bottom: 15px; +} + +.widget-title { + color: #242424; + font-feature-settings: + "clig" off, + "liga" off; + font-family: "Noto sans", "BCSans", "Open Sans", Verdana, Arial, sans-serif; + font-size: 26px; + font-style: normal; + font-weight: 500; + line-height: 34px; + letter-spacing: 0.35px; + width: 100%; +} + + +.highlight-card { + border-radius: var(--8, 8px); + background: #f5f6f9; + display: flex; + height: 100%; + min-width: 270px; + max-width: 270px; + flex-direction: column; + align-items: flex-start; + flex: 1 0 0; + min-height: 470px; + max-width: 470px; + position: relative; + cursor: pointer; +} + +.highlight-info { + padding: 16px; + + &-title { + overflow: hidden; + color: var(--Secondary-800, #181A2A); + text-overflow: ellipsis; + font-family: "Noto sans", "BCSans", "Open Sans", Verdana, Arial, sans-serif; + font-size: 22px; + font-style: normal; + font-weight: 600; + line-height: 28px; + } +} + +.widget-header { + border-bottom: 1px solid #c4c4c4; + width: 100%; + padding-bottom: 16px; + display: flex; +} + +.highlight-thumbnail { + overflow: hidden; // Contain oversized images + margin-bottom: 16px; + + // Target the img directly + img, + .thumbnail-image { + width: 100%; + height: 135px; + object-fit: cover; + border-radius: var(--8, 8px); + } +} + +.highlight-tags { + display: flex; + flex-direction: row; + align-items: center; + color: #000; + text-align: center; + font-family: "Noto Sans"; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 21px; + border-radius: var(--4, 4px); + flex-wrap: wrap; + margin-bottom: 16px; +} + +.highlight-tag { + display: inline-block; + padding: 4px 12px; + border-radius: 4px; + font-size: 14px; + color: #333; + white-space: nowrap; // Prevents text from wrapping inside tags + background: #DFE5EE; + margin-right: 8px; +} + + +.highlight-date { + left: 16px; + bottom: 13px; + color: var(--Black-2, #484848); + font-family: "Noto Sans"; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 19px; + position: absolute; + bottom: 16px; +} \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts new file mode 100644 index 0000000000..661b41b16e --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts @@ -0,0 +1,128 @@ +import { HighlightsWidgetComponent } from './highlights-widget.component'; +import { moduleMetadata, type Meta, type StoryObj } from '@storybook/angular'; +import { HttpClient, HttpClientModule } from '@angular/common/http'; +import { Observable, of } from 'rxjs'; +import { CommonModule } from '@angular/common'; + +// Mock HTTP Client +class MockHttpClient { + get(): Observable { + // Mock tag response + const tagResponse = [{ id: 1, name: 'app' }]; + + // Mock posts response + const postsResponse = [ + { + id: 1, + date: '2024-03-20T12:00:00', + title: { rendered: 'Test Post 1' }, + link: 'https://example.com/post1', + tags: [1], + _embedded: { + 'wp:featuredmedia': [{ + source_url: 'https://placeholder.com/200x100', + alt_text: 'Test Image 1' + }], + 'wp:term': [ + [], // First array is empty (categories) + [ // Second array contains tags + { name: 'app' }, + { name: 'KFC' } + ] + ] + } + } + ]; + + // Return mock data based on URL + return of(postsResponse); + } +} + + +const meta: Meta = { + title: 'Widgets/HighlightsWidgetComponent', + component: HighlightsWidgetComponent, + tags: ['autodocs'], + decorators: [ + moduleMetadata({ + imports: [ + CommonModule, + HttpClientModule + ], + declarations: [HighlightsWidgetComponent], + providers: [ + { provide: HttpClient, useClass: MockHttpClient } + ] + }) + ] +}; + +export default meta; +type Story = StoryObj; + +export const SingleFireCentres: Story = { + args: { + posts: [{ + id: 1, + title: 'Smoke from pile burning visible in Kamloops Fire Centre', + date: 'October 21, 2024', + thumbnail: { + url: 'https://blog.gov.bc.ca/app/uploads/sites/786/2023/02/SocialMedia_PrescribedFire_KFC-FB.jpg', + alt: 'Forest fire prevention image' + }, + fireCentres: ['KFC'], + link: 'https://example.com/wildfire-prevention', + tags: [ + { name: 'app' }, + { name: 'KFC' } + ] + }] + } +}; + +export const MultipleFireCentres: Story = { + args: { + posts: [ + { + id: 2, + title: 'Super prescribed burn across multiple provinces', + date: 'October 23, 2024', + thumbnail: { + url: 'https://blog.gov.bc.ca/app/uploads/sites/786/2022/07/SocialMedia_PrescribedFire_KFC-FB.jpg', + alt: 'Emergency response team' + }, + fireCentres: ['VIFC', 'CFC', 'SEFC'], + link: 'https://example.com/emergency-response', + tags: [ + { name: 'app' }, + { name: 'VIFC' }, + { name: 'CFC' }, + { name: 'SEFC' }, + ] + } + ] + } +}; + +export const NoThumbnail: Story = { + args: { + posts: [ + { + id: 5, + title: 'Important Alert: prescribed burn smoke visible near Lac Le Jeune', + date: 'October 22, 2024', + thumbnail: { + url: '', + alt: 'Prescribed fire image' + }, + fireCentres: ['KFC'], + link: 'https://example.com/risk-assessment', + tags: [ + { name: 'app' }, + { name: 'KFC' } + ] + } + ] + } +}; \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts new file mode 100644 index 0000000000..ec15a3c8d1 --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -0,0 +1,150 @@ +import { HttpClient } from '@angular/common/http'; +import { Component, OnInit } from '@angular/core'; +import { readableDate } from '@app/utils'; +import { Observable, of } from 'rxjs'; +import { catchError, map, switchMap } from 'rxjs/operators'; + +type WordPressPost = { + id: number; + date: string; + title: { + rendered: string; + }; + link: string; + tags: number[]; + _embedded?: { + 'wp:featuredmedia'?: [{ + source_url: string; + alt_text?: string; + }]; + 'wp:term'?: Array>; + }; +} + +type Tag = { + name: string; +} + +type ProcessedPost = { + id: number; + date: string; + title: string; + link: string; + thumbnail: { + url: string | null; + alt: string; + }; + tags: Tag[]; + fireCentres: string[]; +} + +@Component({ + selector: 'highlights-widget', + templateUrl: './highlights-widget.component.html', + styleUrls: ['./highlights-widget.component.scss'] +}) +export class HighlightsWidgetComponent implements OnInit { + posts: ProcessedPost[] = []; + readableDate = readableDate; + + ngOnInit(): void { + this.populateTags(); + } + + populateTags() { + try { + this.getAllAppPosts().subscribe(result => { + console.log('result'); + console.log(result) + this.posts = result; + }) + } catch (error) { + console.log("Error retrieving blog posts: " + error) + } + } + + private apiUrl = 'https://blog.gov.bc.ca/bcwildfire/wp-json/wp/v2'; + private appTagSlug = 'app'; + + constructor(private http: HttpClient) { } + + // Get all posts with the app tag + getAllAppPosts(): Observable { + return this.getTagBySlug(this.appTagSlug).pipe( + switchMap(tagId => { + if (!tagId) { + throw new Error('App tag not found'); + } + return this.fetchAllPostsWithTag(tagId); + }), + catchError(error => { + console.error('Error fetching app posts:', error); + return of([]); + }) + ); + } + + // Helper to get tag ID from slug + private getTagBySlug(slug: string): Observable { + return this.http.get(`${this.apiUrl}/tags?slug=${slug}`).pipe( + map(tags => tags[0]?.id || null), + catchError(error => { + console.error('Error fetching tag:', error); + return of(null); + }) + ); + } + + // Helper to fetch all posts at once with tags + private fetchAllPostsWithTag(tagId: number): Observable { + // Include _embed to get tag information and set per_page to get all posts + return this.http.get( + `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100` + ).pipe( + map(posts => posts.map(post => this.processPost(post))), + catchError(error => { + console.error('Error fetching posts:', error); + return of([]); + }) + ); + } + + // Helper to process a post into a cleaner format + private processPost(post: WordPressPost): ProcessedPost { + const featuredMedia = post._embedded?.['wp:featuredmedia']?.[0]; + const tags = post._embedded?.['wp:term']?.[1] || []; // wp:term[1] contains tags + + // Find all fire centre tags (ending in FC) + const fireCentreTags = tags.filter(tag => tag.name.endsWith('FC')); + + const date = new Date(post.date); + const formattedDate = date.toLocaleDateString('en-US', { + month: 'long', + day: 'numeric', + year: 'numeric' + }); + + return { + id: post.id, + date: formattedDate, + title: post.title.rendered, + link: post.link, + thumbnail: { + url: featuredMedia?.source_url || null, + alt: featuredMedia?.alt_text || '' + }, + tags: tags.map(tag => ({ + name: tag.name, + })), + fireCentres: fireCentreTags.map(tag => tag.name) // Array of fire centre names + }; + } + + openLink(link: string){ + if (link) { + window.open(link, '_blank'); + } + } +} \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss index 061d4fb810..7c322f444b 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss @@ -1,6 +1,10 @@ @import "../../../../../styles/variables"; @import "notosans-fontface/scss/notosans-fontface"; +:host { + display: block; // This ensures the component itself has layout +} + @media (min-width: $desktop-md-min-width) { .container { overflow: hidden; @@ -231,3 +235,17 @@ padding-bottom: 16px; display: flex; } + +.video-thumbnail { + flex: 0 0 200px; // Fixed width + height: 150px; // Fixed height + overflow: hidden; // Contain oversized images + + // Target the img directly + img, .thumbnail-image { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 4px; + } +} \ No newline at end of file From 410f064568b48d529c02b762390abaf2cb10fc36 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Wed, 23 Oct 2024 15:37:20 -0700 Subject: [PATCH 02/16] Revert videos widget css changes --- .../videos-widget/videos-widget.component.scss | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss index 7c322f444b..7a1de4afc2 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/videos-widget/videos-widget.component.scss @@ -1,10 +1,6 @@ @import "../../../../../styles/variables"; @import "notosans-fontface/scss/notosans-fontface"; -:host { - display: block; // This ensures the component itself has layout -} - @media (min-width: $desktop-md-min-width) { .container { overflow: hidden; @@ -234,18 +230,4 @@ width: 100%; padding-bottom: 16px; display: flex; -} - -.video-thumbnail { - flex: 0 0 200px; // Fixed width - height: 150px; // Fixed height - overflow: hidden; // Contain oversized images - - // Target the img directly - img, .thumbnail-image { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 4px; - } } \ No newline at end of file From 5cd992f114156c52b5404c34baa08e6b3facb002 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Wed, 23 Oct 2024 15:43:54 -0700 Subject: [PATCH 03/16] Remove console logs --- .../widgets/highlights-widget/highlights-widget.component.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index ec15a3c8d1..b8fe647b27 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -56,12 +56,10 @@ export class HighlightsWidgetComponent implements OnInit { populateTags() { try { this.getAllAppPosts().subscribe(result => { - console.log('result'); - console.log(result) this.posts = result; }) } catch (error) { - console.log("Error retrieving blog posts: " + error) + console.error("Error retrieving blog posts: " + error) } } From a3b42f2f23cd6515842a824c45009f585d5f1eca Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Thu, 24 Oct 2024 13:48:54 -0700 Subject: [PATCH 04/16] WFBEWS-2411 Move highlights card to standalone component --- .../src/main/angular/src/app/app.module.ts | 2 + .../highlights-card.component.html | 23 ++++ .../highlights-card.component.scss | 92 +++++++++++++ .../highlights-card.component.stories.ts | 128 ++++++++++++++++++ .../highlights-card.component.ts | 18 +++ .../highlights-widget.component.html | 24 +--- .../highlights-widget.component.scss | 91 +------------ .../highlights-widget.component.stories.ts | 66 +-------- .../highlights-widget.component.ts | 8 +- 9 files changed, 269 insertions(+), 183 deletions(-) create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts create mode 100644 client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts diff --git a/client/wfnews-war/src/main/angular/src/app/app.module.ts b/client/wfnews-war/src/main/angular/src/app/app.module.ts index 32546aa0d4..9f1eef9cda 100644 --- a/client/wfnews-war/src/main/angular/src/app/app.module.ts +++ b/client/wfnews-war/src/main/angular/src/app/app.module.ts @@ -322,6 +322,7 @@ import { initialRootState, rootEffects, rootReducers } from './store'; import { provideBootstrapEffects } from './utils'; import { ShareDialogComponent } from '@app/components/admin-incident-form/share-dialog/share-dialog.component'; import { HighlightsWidgetComponent } from './components/dashboard-component/widgets/highlights-widget/highlights-widget.component'; +import { HighlightsCardComponent } from './components/dashboard-component/widgets/cards/highlights-card/highlights-card.component'; // Copied from im-external.module TODO: consolidate in one place export const DATE_FORMATS = { @@ -555,6 +556,7 @@ export const DATE_FORMATS = { PrimaryMediaCardComponent, ContactUsCoreComponent, HighlightsWidgetComponent, + HighlightsCardComponent, ], imports: [ MatSortModule, diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html new file mode 100644 index 0000000000..e59cb173a7 --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html @@ -0,0 +1,23 @@ +
+
+
+
+ +
+
+
+ Prevention +
+
+ {{fireCentre}} +
+
+
+ {{post.title}} +
+
+ posted on {{post.date}} +
+
+
+
\ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss new file mode 100644 index 0000000000..de51329fad --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss @@ -0,0 +1,92 @@ +@import "../../../../../../styles/variables"; +@import "notosans-fontface/scss/notosans-fontface"; + +.highlights-card-container { + display: flex; + flex-direction: row; + gap: 16px; + width: 100%; + overflow-x: auto; +} + +.highlight-card { + border-radius: var(--8, 8px); + font-family: "Noto sans", "BCSans", "Open Sans", Verdana, Arial, sans-serif; + background: #f5f6f9; + display: flex; + height: 100%; + min-width: 270px; + max-width: 270px; + flex-direction: column; + align-items: flex-start; + flex: 1 0 0; + min-height: 470px; + position: relative; + cursor: pointer; +} + +.highlight-info { + padding: 16px; + + &-title { + overflow: hidden; + color: var(--Secondary-800, #181A2A); + text-overflow: ellipsis; + font-size: 22px; + font-style: normal; + font-weight: 600; + line-height: 28px; + } +} + +.highlight-thumbnail { + overflow: hidden; // Contain oversized images + margin-bottom: 16px; + + // Target the img directly + img, + .thumbnail-image { + width: 100%; + height: 135px; + object-fit: cover; + border-radius: var(--8, 8px); + } +} + +.highlight-tags { + display: flex; + flex-direction: row; + align-items: center; + color: #000; + text-align: center; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 21px; + border-radius: var(--4, 4px); + flex-wrap: wrap; + margin-bottom: 8px; +} + +.highlight-tag { + display: inline-block; + padding: 4px 12px; + border-radius: 4px; + font-size: 14px; + color: #333; + white-space: nowrap; // Prevents text from wrapping inside tags + background: #DFE5EE; + margin: 0 8px 8px 0; +} + + +.highlight-date { + left: 16px; + color: var(--Black-2, #484848); + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 19px; + position: absolute; + bottom: 16px; +} \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts new file mode 100644 index 0000000000..992613ea79 --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts @@ -0,0 +1,128 @@ +import { HighlightsCardComponent } from './highlights-card.component'; +import { moduleMetadata, type Meta, type StoryObj } from '@storybook/angular'; +import { HttpClient, HttpClientModule } from '@angular/common/http'; +import { Observable, of } from 'rxjs'; +import { CommonModule } from '@angular/common'; + +// Mock HTTP Client +class MockHttpClient { + get(): Observable { + // Mock tag response + const tagResponse = [{ id: 1, name: 'app' }]; + + // Mock posts response + const postsResponse = [ + { + id: 1, + date: '2024-03-20T12:00:00', + title: { rendered: 'Test Post 1' }, + link: 'https://example.com/post1', + tags: [1], + _embedded: { + 'wp:featuredmedia': [{ + source_url: 'https://placeholder.com/200x100', + alt_text: 'Test Image 1' + }], + 'wp:term': [ + [], // First array is empty (categories) + [ // Second array contains tags + { name: 'app' }, + { name: 'KFC' } + ] + ] + } + } + ]; + + // Return mock data based on URL + return of(postsResponse); + } +} + + +const meta: Meta = { + title: 'Cards/HighlightsCardComponent', + component: HighlightsCardComponent, + tags: ['autodocs'], + decorators: [ + moduleMetadata({ + imports: [ + CommonModule, + HttpClientModule + ], + declarations: [HighlightsCardComponent], + providers: [ + { provide: HttpClient, useClass: MockHttpClient } + ] + }) + ] +}; + +export default meta; +type Story = StoryObj; + +export const SingleFireCentres: Story = { + args: { + posts: [{ + id: 1, + title: 'Smoke from pile burning visible in Kamloops Fire Centre', + date: 'October 21, 2024', + thumbnail: { + url: 'https://blog.gov.bc.ca/app/uploads/sites/786/2023/02/SocialMedia_PrescribedFire_KFC-FB.jpg', + alt: 'Forest fire prevention image' + }, + fireCentres: ['KFC'], + link: 'https://example.com/wildfire-prevention', + tags: [ + { name: 'app' }, + { name: 'KFC' } + ] + }] + } +}; + +export const MultipleFireCentres: Story = { + args: { + posts: [ + { + id: 2, + title: 'Super prescribed burn across multiple provinces', + date: 'October 23, 2024', + thumbnail: { + url: 'https://blog.gov.bc.ca/app/uploads/sites/786/2022/07/SocialMedia_PrescribedFire_KFC-FB.jpg', + alt: 'Emergency response team' + }, + fireCentres: ['VIFC', 'CFC', 'SEFC'], + link: 'https://example.com/emergency-response', + tags: [ + { name: 'app' }, + { name: 'VIFC' }, + { name: 'CFC' }, + { name: 'SEFC' }, + ] + } + ] + } +}; + +export const NoThumbnail: Story = { + args: { + posts: [ + { + id: 5, + title: 'Important Alert: prescribed burn smoke visible near Lac Le Jeune', + date: 'October 22, 2024', + thumbnail: { + url: '', + alt: 'Prescribed fire image' + }, + fireCentres: ['KFC'], + link: 'https://example.com/risk-assessment', + tags: [ + { name: 'app' }, + { name: 'KFC' } + ] + } + ] + } +}; \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts new file mode 100644 index 0000000000..17c617d054 --- /dev/null +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; +import { ProcessedPost } from '../../highlights-widget/highlights-widget.component'; + +@Component({ + selector: 'highlights-card', + templateUrl: './highlights-card.component.html', + styleUrls: ['./highlights-card.component.scss'] +}) +export class HighlightsCardComponent { + @Input() posts: ProcessedPost[] + + openLink(link: string){ + if (link) { + window.open(link, '_blank'); + } + } + +} diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html index d38f0d3b00..db8333cb4e 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html @@ -3,28 +3,6 @@ Highlights
-
-
-
- -
-
-
- Prevention -
-
- {{fireCentre}} -
-
-
- {{post.title}} -
-
- posted on {{post.date}} -
-
-
+
\ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss index 8dbd0e63d9..99939fd938 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss @@ -9,7 +9,7 @@ border-radius: 20px; background: #fff; box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1); - max-width: min(1480px, calc(100dvw - 104px)); + max-width: min(1460px, calc(100dvw - 104px)); padding: var(--24, 24px); flex-direction: column; align-items: flex-start; @@ -40,98 +40,11 @@ line-height: 34px; letter-spacing: 0.35px; width: 100%; -} - - -.highlight-card { - border-radius: var(--8, 8px); - background: #f5f6f9; - display: flex; - height: 100%; - min-width: 270px; - max-width: 270px; - flex-direction: column; - align-items: flex-start; - flex: 1 0 0; - min-height: 470px; - max-width: 470px; - position: relative; - cursor: pointer; -} - -.highlight-info { - padding: 16px; - - &-title { - overflow: hidden; - color: var(--Secondary-800, #181A2A); - text-overflow: ellipsis; - font-family: "Noto sans", "BCSans", "Open Sans", Verdana, Arial, sans-serif; - font-size: 22px; - font-style: normal; - font-weight: 600; - line-height: 28px; - } + margin: 12px 0px 14px 0px; } .widget-header { border-bottom: 1px solid #c4c4c4; width: 100%; - padding-bottom: 16px; display: flex; -} - -.highlight-thumbnail { - overflow: hidden; // Contain oversized images - margin-bottom: 16px; - - // Target the img directly - img, - .thumbnail-image { - width: 100%; - height: 135px; - object-fit: cover; - border-radius: var(--8, 8px); - } -} - -.highlight-tags { - display: flex; - flex-direction: row; - align-items: center; - color: #000; - text-align: center; - font-family: "Noto Sans"; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 21px; - border-radius: var(--4, 4px); - flex-wrap: wrap; - margin-bottom: 16px; -} - -.highlight-tag { - display: inline-block; - padding: 4px 12px; - border-radius: 4px; - font-size: 14px; - color: #333; - white-space: nowrap; // Prevents text from wrapping inside tags - background: #DFE5EE; - margin-right: 8px; -} - - -.highlight-date { - left: 16px; - bottom: 13px; - color: var(--Black-2, #484848); - font-family: "Noto Sans"; - font-size: 13px; - font-style: normal; - font-weight: 400; - line-height: 19px; - position: absolute; - bottom: 16px; } \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts index 661b41b16e..30e5969603 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.stories.ts @@ -61,68 +61,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -export const SingleFireCentres: Story = { - args: { - posts: [{ - id: 1, - title: 'Smoke from pile burning visible in Kamloops Fire Centre', - date: 'October 21, 2024', - thumbnail: { - url: 'https://blog.gov.bc.ca/app/uploads/sites/786/2023/02/SocialMedia_PrescribedFire_KFC-FB.jpg', - alt: 'Forest fire prevention image' - }, - fireCentres: ['KFC'], - link: 'https://example.com/wildfire-prevention', - tags: [ - { name: 'app' }, - { name: 'KFC' } - ] - }] - } -}; - -export const MultipleFireCentres: Story = { - args: { - posts: [ - { - id: 2, - title: 'Super prescribed burn across multiple provinces', - date: 'October 23, 2024', - thumbnail: { - url: 'https://blog.gov.bc.ca/app/uploads/sites/786/2022/07/SocialMedia_PrescribedFire_KFC-FB.jpg', - alt: 'Emergency response team' - }, - fireCentres: ['VIFC', 'CFC', 'SEFC'], - link: 'https://example.com/emergency-response', - tags: [ - { name: 'app' }, - { name: 'VIFC' }, - { name: 'CFC' }, - { name: 'SEFC' }, - ] - } - ] - } -}; - -export const NoThumbnail: Story = { - args: { - posts: [ - { - id: 5, - title: 'Important Alert: prescribed burn smoke visible near Lac Le Jeune', - date: 'October 22, 2024', - thumbnail: { - url: '', - alt: 'Prescribed fire image' - }, - fireCentres: ['KFC'], - link: 'https://example.com/risk-assessment', - tags: [ - { name: 'app' }, - { name: 'KFC' } - ] - } - ] - } +export const example: Story = { + args: {} }; \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index b8fe647b27..e5041c8bfd 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -27,7 +27,7 @@ type Tag = { name: string; } -type ProcessedPost = { +export type ProcessedPost = { id: number; date: string; title: string; @@ -139,10 +139,4 @@ export class HighlightsWidgetComponent implements OnInit { fireCentres: fireCentreTags.map(tag => tag.name) // Array of fire centre names }; } - - openLink(link: string){ - if (link) { - window.open(link, '_blank'); - } - } } \ No newline at end of file From 4703cc678d18dc5ae08e1556b5598a0367b2af3f Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Thu, 24 Oct 2024 15:09:24 -0700 Subject: [PATCH 05/16] WFNEWS-2411 Only bind single post to highlight card --- .../highlights-card/highlights-card.component.html | 7 +++---- .../highlights-card/highlights-card.component.scss | 8 +------- .../highlights-card.component.stories.ts | 10 ++++------ .../cards/highlights-card/highlights-card.component.ts | 2 +- .../highlights-widget/highlights-widget.component.html | 2 +- .../highlights-widget/highlights-widget.component.scss | 4 +++- 6 files changed, 13 insertions(+), 20 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html index e59cb173a7..b4ad7185fb 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.html @@ -1,5 +1,5 @@ -
-
+ +
@@ -19,5 +19,4 @@ posted on {{post.date}}
-
-
\ No newline at end of file +
\ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss index de51329fad..fc17adb4c4 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.scss @@ -1,13 +1,7 @@ @import "../../../../../../styles/variables"; @import "notosans-fontface/scss/notosans-fontface"; -.highlights-card-container { - display: flex; - flex-direction: row; - gap: 16px; - width: 100%; - overflow-x: auto; -} +:host { display: block; } .highlight-card { border-radius: var(--8, 8px); diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts index 992613ea79..811f51fb18 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.stories.ts @@ -63,7 +63,7 @@ type Story = StoryObj; export const SingleFireCentres: Story = { args: { - posts: [{ + post: { id: 1, title: 'Smoke from pile burning visible in Kamloops Fire Centre', date: 'October 21, 2024', @@ -77,13 +77,13 @@ export const SingleFireCentres: Story = { { name: 'app' }, { name: 'KFC' } ] - }] + } } }; export const MultipleFireCentres: Story = { args: { - posts: [ + post: { id: 2, title: 'Super prescribed burn across multiple provinces', @@ -101,13 +101,12 @@ export const MultipleFireCentres: Story = { { name: 'SEFC' }, ] } - ] } }; export const NoThumbnail: Story = { args: { - posts: [ + post: { id: 5, title: 'Important Alert: prescribed burn smoke visible near Lac Le Jeune', @@ -123,6 +122,5 @@ export const NoThumbnail: Story = { { name: 'KFC' } ] } - ] } }; \ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts index 17c617d054..930e9b0969 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/cards/highlights-card/highlights-card.component.ts @@ -7,7 +7,7 @@ import { ProcessedPost } from '../../highlights-widget/highlights-widget.compone styleUrls: ['./highlights-card.component.scss'] }) export class HighlightsCardComponent { - @Input() posts: ProcessedPost[] + @Input() post: ProcessedPost openLink(link: string){ if (link) { diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html index db8333cb4e..47c053bcc8 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.html @@ -3,6 +3,6 @@ Highlights
- +
\ No newline at end of file diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss index 99939fd938..9622ccfad0 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss @@ -1,6 +1,8 @@ @import "../../../../../styles/variables"; @import "notosans-fontface/scss/notosans-fontface"; +:host { display: block; } + .container { overflow: hidden; font-family: "Noto sans", "BCSans", "Open Sans", Verdana, Arial, sans-serif; @@ -21,7 +23,7 @@ width: 100%; display: flex; align-items: flex-start; - gap: var(--24, 24px); + gap: 16px; align-self: stretch; overflow-x: auto; overflow-y: hidden; From 27e54569e4d808871a39e6ea3b32d5a48a90f13d Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Fri, 25 Oct 2024 16:16:41 -0700 Subject: [PATCH 06/16] Add CORS headers for calls to wordpress API --- .../highlights-widget.component.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index e5041c8bfd..0b55d94af1 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -1,4 +1,4 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { readableDate } from '@app/utils'; import { Observable, of } from 'rxjs'; @@ -86,7 +86,12 @@ export class HighlightsWidgetComponent implements OnInit { // Helper to get tag ID from slug private getTagBySlug(slug: string): Observable { - return this.http.get(`${this.apiUrl}/tags?slug=${slug}`).pipe( + const headers = new HttpHeaders(); + headers.append('Access-Control-Allow-Origin', '*'); + headers.append('Accept', '*/*'); + const url = `${this.apiUrl}/tags?slug=${slug}`; + + return this.http.get(encodeURI(url), { headers }).pipe( map(tags => tags[0]?.id || null), catchError(error => { console.error('Error fetching tag:', error); @@ -97,9 +102,14 @@ export class HighlightsWidgetComponent implements OnInit { // Helper to fetch all posts at once with tags private fetchAllPostsWithTag(tagId: number): Observable { + const headers = new HttpHeaders(); + headers.append('Access-Control-Allow-Origin', '*'); + headers.append('Accept', '*/*'); + const url = `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100`; + // Include _embed to get tag information and set per_page to get all posts return this.http.get( - `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100` + encodeURI(url), { headers } ).pipe( map(posts => posts.map(post => this.processPost(post))), catchError(error => { From 9ebf29f453f33c8226884b3388e7519eb31fafb4 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Fri, 25 Oct 2024 16:59:57 -0700 Subject: [PATCH 07/16] Try with fetch API --- .../highlights-widget.component.ts | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index 0b55d94af1..b19ed91016 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -1,7 +1,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { readableDate } from '@app/utils'; -import { Observable, of } from 'rxjs'; +import { from, Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; type WordPressPost = { @@ -91,7 +91,14 @@ export class HighlightsWidgetComponent implements OnInit { headers.append('Accept', '*/*'); const url = `${this.apiUrl}/tags?slug=${slug}`; - return this.http.get(encodeURI(url), { headers }).pipe( + return from(fetch(encodeURI(url)) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) + ).pipe( map(tags => tags[0]?.id || null), catchError(error => { console.error('Error fetching tag:', error); @@ -108,10 +115,15 @@ export class HighlightsWidgetComponent implements OnInit { const url = `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100`; // Include _embed to get tag information and set per_page to get all posts - return this.http.get( - encodeURI(url), { headers } + return from(fetch(encodeURI(url)) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) ).pipe( - map(posts => posts.map(post => this.processPost(post))), + map((posts: WordPressPost[]) => posts.map(post => this.processPost(post))), catchError(error => { console.error('Error fetching posts:', error); return of([]); From 43e8e358e5211269a2ba22f62541b7a69ac956b5 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Fri, 25 Oct 2024 17:16:34 -0700 Subject: [PATCH 08/16] Add headers to fetch --- .../highlights-widget.component.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index b19ed91016..4460688bec 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -91,7 +91,13 @@ export class HighlightsWidgetComponent implements OnInit { headers.append('Accept', '*/*'); const url = `${this.apiUrl}/tags?slug=${slug}`; - return from(fetch(encodeURI(url)) + return from(fetch(encodeURI(url), { + method: 'GET', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Accept': '*/*' + } + }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); @@ -115,7 +121,13 @@ export class HighlightsWidgetComponent implements OnInit { const url = `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100`; // Include _embed to get tag information and set per_page to get all posts - return from(fetch(encodeURI(url)) + return from(fetch(encodeURI(url), { + method: 'GET', + headers: { + 'Access-Control-Allow-Origin': '*', + 'Accept': '*/*' + } + }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); From c34e2070d7f5b07fafc670e5275dfef9e71420e2 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Fri, 25 Oct 2024 18:06:45 -0700 Subject: [PATCH 09/16] Try with CapacitorHttp --- .../highlights-widget.component.ts | 57 +++++++------------ 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index 4460688bec..63088480b5 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -1,6 +1,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { readableDate } from '@app/utils'; +import { Capacitor, CapacitorHttp } from '@capacitor/core'; import { from, Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; @@ -86,25 +87,9 @@ export class HighlightsWidgetComponent implements OnInit { // Helper to get tag ID from slug private getTagBySlug(slug: string): Observable { - const headers = new HttpHeaders(); - headers.append('Access-Control-Allow-Origin', '*'); - headers.append('Accept', '*/*'); const url = `${this.apiUrl}/tags?slug=${slug}`; - return from(fetch(encodeURI(url), { - method: 'GET', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Accept': '*/*' - } - }) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - ).pipe( + return this.processRequest(url).pipe( map(tags => tags[0]?.id || null), catchError(error => { console.error('Error fetching tag:', error); @@ -115,27 +100,10 @@ export class HighlightsWidgetComponent implements OnInit { // Helper to fetch all posts at once with tags private fetchAllPostsWithTag(tagId: number): Observable { - const headers = new HttpHeaders(); - headers.append('Access-Control-Allow-Origin', '*'); - headers.append('Accept', '*/*'); const url = `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100`; - // Include _embed to get tag information and set per_page to get all posts - return from(fetch(encodeURI(url), { - method: 'GET', - headers: { - 'Access-Control-Allow-Origin': '*', - 'Accept': '*/*' - } - }) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - ).pipe( - map((posts: WordPressPost[]) => posts.map(post => this.processPost(post))), + return this.processRequest(url).pipe( + map(posts => posts.map(post => this.processPost(post))), catchError(error => { console.error('Error fetching posts:', error); return of([]); @@ -173,4 +141,21 @@ export class HighlightsWidgetComponent implements OnInit { fireCentres: fireCentreTags.map(tag => tag.name) // Array of fire centre names }; } + + private processRequest(url: string): Observable { + if (Capacitor.isNativePlatform()) { + return from(CapacitorHttp.request({ + method: 'GET', + url: encodeURI(url), + headers: { + 'Accept': '*', + 'Access-Control-Allow-Origin': '*' + } + })).pipe( + map(response => JSON.parse(response.data)) + ); + } else { + return this.http.get(encodeURI(url)); + } + } } \ No newline at end of file From f0f4d955c9dc06ff73a5e2aaebee686f9ac30e8c Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 11:24:32 -0700 Subject: [PATCH 10/16] WFNEWS-2411 Use CapacitorHttp on mobile to avoid CORS issues in highlights widget --- .../highlights-widget/highlights-widget.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index 63088480b5..6ace58d912 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -142,17 +142,17 @@ export class HighlightsWidgetComponent implements OnInit { }; } - private processRequest(url: string): Observable { + private processRequest(url: string): Observable { if (Capacitor.isNativePlatform()) { return from(CapacitorHttp.request({ method: 'GET', url: encodeURI(url), headers: { - 'Accept': '*', + 'Accept': '*/*', 'Access-Control-Allow-Origin': '*' } })).pipe( - map(response => JSON.parse(response.data)) + map(response => response.data) ); } else { return this.http.get(encodeURI(url)); From c6b02d5c6988a0340f2636265966115216bd7459 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 11:24:37 -0700 Subject: [PATCH 11/16] WFNEWS-2411 Use CapacitorHttp on mobile to avoid CORS issues in highlights widget --- .../widgets/highlights-widget/highlights-widget.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index 6ace58d912..4b5d463e67 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -1,4 +1,4 @@ -import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { readableDate } from '@app/utils'; import { Capacitor, CapacitorHttp } from '@capacitor/core'; From 364b421de46ff2c9b887cccf023e87e92c413247 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 11:29:46 -0700 Subject: [PATCH 12/16] Add comment --- .../widgets/highlights-widget/highlights-widget.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index 4b5d463e67..a8854ea707 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -142,6 +142,7 @@ export class HighlightsWidgetComponent implements OnInit { }; } + // Use CapacitorHttp if on mobile to avoid CORS issues private processRequest(url: string): Observable { if (Capacitor.isNativePlatform()) { return from(CapacitorHttp.request({ From c471587500f47901f24bd0d56b6fba6ed9fcf462 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 15:15:58 -0700 Subject: [PATCH 13/16] Move CapacitorHttp get request to service class, Lint clean up --- .../highlights-widget.component.ts | 55 +++++++------------ .../src/app/services/capacitor-service.ts | 29 +++++++--- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index a8854ea707..a440bedbb9 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -1,34 +1,38 @@ import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; +import { CapacitorService } from '@app/services/capacitor-service'; import { readableDate } from '@app/utils'; -import { Capacitor, CapacitorHttp } from '@capacitor/core'; -import { from, Observable, of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; -type WordPressPost = { +interface WordPressPost { id: number; date: string; title: { rendered: string; }; link: string; - tags: number[]; + tags: number[]; _embedded?: { + // eslint-disable-next-line @typescript-eslint/naming-convention 'wp:featuredmedia'?: [{ + // eslint-disable-next-line @typescript-eslint/naming-convention source_url: string; + // eslint-disable-next-line @typescript-eslint/naming-convention alt_text?: string; }]; + // eslint-disable-next-line @typescript-eslint/naming-convention 'wp:term'?: Array>; }; } -type Tag = { +interface Tag { name: string; } -export type ProcessedPost = { +export interface ProcessedPost { id: number; date: string; title: string; @@ -37,7 +41,7 @@ export type ProcessedPost = { url: string | null; alt: string; }; - tags: Tag[]; + tags: Tag[]; fireCentres: string[]; } @@ -49,6 +53,10 @@ export type ProcessedPost = { export class HighlightsWidgetComponent implements OnInit { posts: ProcessedPost[] = []; readableDate = readableDate; + apiUrl = 'https://blog.gov.bc.ca/bcwildfire/wp-json/wp/v2'; + appTagSlug = 'app'; + + constructor(private capacitorService: CapacitorService) { } ngOnInit(): void { this.populateTags(); @@ -58,17 +66,12 @@ export class HighlightsWidgetComponent implements OnInit { try { this.getAllAppPosts().subscribe(result => { this.posts = result; - }) + }); } catch (error) { - console.error("Error retrieving blog posts: " + error) + console.error('Error retrieving blog posts: ' + error); } } - private apiUrl = 'https://blog.gov.bc.ca/bcwildfire/wp-json/wp/v2'; - private appTagSlug = 'app'; - - constructor(private http: HttpClient) { } - // Get all posts with the app tag getAllAppPosts(): Observable { return this.getTagBySlug(this.appTagSlug).pipe( @@ -89,7 +92,7 @@ export class HighlightsWidgetComponent implements OnInit { private getTagBySlug(slug: string): Observable { const url = `${this.apiUrl}/tags?slug=${slug}`; - return this.processRequest(url).pipe( + return this.capacitorService.get(url).pipe( map(tags => tags[0]?.id || null), catchError(error => { console.error('Error fetching tag:', error); @@ -102,7 +105,7 @@ export class HighlightsWidgetComponent implements OnInit { private fetchAllPostsWithTag(tagId: number): Observable { const url = `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100`; - return this.processRequest(url).pipe( + return this.capacitorService.get(url).pipe( map(posts => posts.map(post => this.processPost(post))), catchError(error => { console.error('Error fetching posts:', error); @@ -141,22 +144,4 @@ export class HighlightsWidgetComponent implements OnInit { fireCentres: fireCentreTags.map(tag => tag.name) // Array of fire centre names }; } - - // Use CapacitorHttp if on mobile to avoid CORS issues - private processRequest(url: string): Observable { - if (Capacitor.isNativePlatform()) { - return from(CapacitorHttp.request({ - method: 'GET', - url: encodeURI(url), - headers: { - 'Accept': '*/*', - 'Access-Control-Allow-Origin': '*' - } - })).pipe( - map(response => response.data) - ); - } else { - return this.http.get(encodeURI(url)); - } - } -} \ No newline at end of file +} diff --git a/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts b/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts index d2e2cd2466..df82bfc2e1 100644 --- a/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts +++ b/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts @@ -12,7 +12,7 @@ import { PushNotifications, } from '@capacitor/push-notifications'; import { Store } from '@ngrx/store'; -import { BehaviorSubject, fromEvent } from 'rxjs'; +import { BehaviorSubject, from, fromEvent, Observable } from 'rxjs'; import { environment } from '../../environments/environment'; import { RootState } from '../store'; import { ApplicationStateService } from './application-state.service'; @@ -21,20 +21,22 @@ import { EventEmitterService } from './event-emitter.service'; import { ResourcesRoutes } from '@app/utils'; import { Preferences } from '@capacitor/preferences'; import { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component'; +import { CapacitorHttp } from '@capacitor/core'; +import { map } from 'rxjs/operators'; export interface CompassHeading { //The heading in degrees from 0-359.99 at a single moment in time. (Number) - magneticHeading?: number; + magneticHeading?: number; // The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. // A negative value indicates that the true heading can't be determined. (Number) - trueHeading?: number; - + trueHeading?: number; + //The deviation in degrees between the reported heading and the true heading. (Number) - headingAccuracy?: number; - + headingAccuracy?: number; + //The time at which this heading was determined. (DOMTimeStamp) - timestamp?: string; + timestamp?: string; error?: string; } @@ -570,6 +572,18 @@ export class CapacitorService { await Preferences.remove({ key }); } + get(url: string): Observable { + return from(CapacitorHttp.request({ + method: 'GET', + url: encodeURI(url), + headers: { + accept: '*/*', + } + })).pipe( + map(response => response.data) + ); + } + private async checkTwitterAppInstalled(): Promise { if (this.isMobilePlatform()) { @@ -593,6 +607,7 @@ export class CapacitorService { const ret = await AppLauncher.canOpenUrl({ url: scheme }); return ret.value; } + } From 165b4f460dc08df808362bcd95489442e5678af9 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 15:33:23 -0700 Subject: [PATCH 14/16] Use HttpClient for getRequest when native platform is not in use, move to common utility service --- .../highlights-widget.component.ts | 9 ++- .../src/app/services/capacitor-service.ts | 13 ---- .../app/services/common-utility.service.ts | 62 ++++++++++++------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts index a440bedbb9..f47df3fb8b 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.ts @@ -1,6 +1,5 @@ -import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; -import { CapacitorService } from '@app/services/capacitor-service'; +import { CommonUtilityService } from '@app/services/common-utility.service'; import { readableDate } from '@app/utils'; import { Observable, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; @@ -56,7 +55,7 @@ export class HighlightsWidgetComponent implements OnInit { apiUrl = 'https://blog.gov.bc.ca/bcwildfire/wp-json/wp/v2'; appTagSlug = 'app'; - constructor(private capacitorService: CapacitorService) { } + constructor(private commonUtilityService: CommonUtilityService) { } ngOnInit(): void { this.populateTags(); @@ -92,7 +91,7 @@ export class HighlightsWidgetComponent implements OnInit { private getTagBySlug(slug: string): Observable { const url = `${this.apiUrl}/tags?slug=${slug}`; - return this.capacitorService.get(url).pipe( + return this.commonUtilityService.getRequest(url).pipe( map(tags => tags[0]?.id || null), catchError(error => { console.error('Error fetching tag:', error); @@ -105,7 +104,7 @@ export class HighlightsWidgetComponent implements OnInit { private fetchAllPostsWithTag(tagId: number): Observable { const url = `${this.apiUrl}/posts?tags=${tagId}&_embed&per_page=100`; - return this.capacitorService.get(url).pipe( + return this.commonUtilityService.getRequest(url).pipe( map(posts => posts.map(post => this.processPost(post))), catchError(error => { console.error('Error fetching posts:', error); diff --git a/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts b/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts index df82bfc2e1..1cc214b957 100644 --- a/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts +++ b/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts @@ -572,19 +572,6 @@ export class CapacitorService { await Preferences.remove({ key }); } - get(url: string): Observable { - return from(CapacitorHttp.request({ - method: 'GET', - url: encodeURI(url), - headers: { - accept: '*/*', - } - })).pipe( - map(response => response.data) - ); - } - - private async checkTwitterAppInstalled(): Promise { if (this.isMobilePlatform()) { const scheme = this.isIOSPlatform ? 'twitter://' : 'com.twitter.android'; diff --git a/client/wfnews-war/src/main/angular/src/app/services/common-utility.service.ts b/client/wfnews-war/src/main/angular/src/app/services/common-utility.service.ts index 2d2e3daeb3..dbf6448529 100644 --- a/client/wfnews-war/src/main/angular/src/app/services/common-utility.service.ts +++ b/client/wfnews-war/src/main/angular/src/app/services/common-utility.service.ts @@ -4,7 +4,7 @@ import { Injectable, Injector } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; import { Geolocation } from '@capacitor/geolocation'; import { AppConfigService } from '@wf1/core-ui'; -import { Observable } from 'rxjs'; +import { from, Observable } from 'rxjs'; import { CapacitorService } from './capacitor-service'; import { IonicStorageService } from './ionic-storage.service'; import { ReportOfFireService } from './report-of-fire-service'; @@ -12,6 +12,8 @@ import { Router } from '@angular/router'; import { Share } from '@capacitor/share'; import { ShareDialogComponent } from '@app/components/admin-incident-form/share-dialog/share-dialog.component'; import { MatDialog } from '@angular/material/dialog'; +import { Capacitor, CapacitorHttp } from '@capacitor/core'; +import { map } from 'rxjs/operators'; const MAX_CACHE_AGE = 30 * 1000; @@ -292,7 +294,7 @@ export class CommonUtilityService { checkIfLandscapeMode() { // also return true if this is table portrait mode wfnews-2022. if ( - (window.innerWidth > window.innerHeight) || + (window.innerWidth > window.innerHeight) || (window.innerWidth <= 1024 && window.innerWidth >= 768 && window.innerHeight > window.innerWidth)) { return true; } else { @@ -313,10 +315,10 @@ export class CommonUtilityService { for (const element of response) { polygonData = polygonData.concat(element); } - + return polygonData; } - + createConvex(polygonData) { const turfPoints = polygonData.map(coord => window['turf'].point(coord)); const pointsFeatureCollection = window['turf'].featureCollection(turfPoints); @@ -335,24 +337,24 @@ export class CommonUtilityService { getMapOptions(bounds: any, location: number[]) { return bounds - ? { - attributionControl: false, - zoomControl: false, - dragging: false, - doubleClickZoom: false, - boxZoom: false, - trackResize: false, - scrollWheelZoom: false - } : { - attributionControl: false, - zoomControl: false, - dragging: false, - doubleClickZoom: false, - boxZoom: false, - trackResize: false, - scrollWheelZoom: false, - center: location, - zoom: 9 + ? { + attributionControl: false, + zoomControl: false, + dragging: false, + doubleClickZoom: false, + boxZoom: false, + trackResize: false, + scrollWheelZoom: false + } : { + attributionControl: false, + zoomControl: false, + dragging: false, + doubleClickZoom: false, + boxZoom: false, + trackResize: false, + scrollWheelZoom: false, + center: location, + zoom: 9 }; } @@ -384,6 +386,22 @@ export class CommonUtilityService { }); } + getRequest(url: string): Observable { + if (Capacitor.isNativePlatform()) { + return from(CapacitorHttp.request({ + method: 'GET', + url: encodeURI(url), + headers: { + accept: '*/*', + } + })).pipe( + map(response => response.data) + ); + } else { + return this.http.get(encodeURI(url)); + } + } + private deg2rad(deg: number): number { return deg * (Math.PI / 180); } From 3ff9329cbad32632df9914259a9b3fb3130e9a09 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 15:44:39 -0700 Subject: [PATCH 15/16] Remove unused imports in capacitor service --- .../src/main/angular/src/app/services/capacitor-service.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts b/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts index 1cc214b957..e634089787 100644 --- a/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts +++ b/client/wfnews-war/src/main/angular/src/app/services/capacitor-service.ts @@ -8,11 +8,11 @@ import { Browser } from '@capacitor/browser'; import { Device } from '@capacitor/device'; import { Geolocation, Position } from '@capacitor/geolocation'; import { - PushNotificationSchema, PushNotifications, + PushNotificationSchema, } from '@capacitor/push-notifications'; import { Store } from '@ngrx/store'; -import { BehaviorSubject, from, fromEvent, Observable } from 'rxjs'; +import { BehaviorSubject, fromEvent } from 'rxjs'; import { environment } from '../../environments/environment'; import { RootState } from '../store'; import { ApplicationStateService } from './application-state.service'; @@ -21,8 +21,6 @@ import { EventEmitterService } from './event-emitter.service'; import { ResourcesRoutes } from '@app/utils'; import { Preferences } from '@capacitor/preferences'; import { NotificationSnackbarComponent } from '../components/notification-snackbar/notification-snackbar.component'; -import { CapacitorHttp } from '@capacitor/core'; -import { map } from 'rxjs/operators'; export interface CompassHeading { //The heading in degrees from 0-359.99 at a single moment in time. (Number) From abbd89961835ee0ee260183fc5265331053d6415 Mon Sep 17 00:00:00 2001 From: Sean Sylver Date: Mon, 28 Oct 2024 17:49:37 -0700 Subject: [PATCH 16/16] WFNEWS-2411 Make highlights widget container wider on mobile --- .../highlights-widget.component.scss | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss index 9622ccfad0..5530b6396f 100644 --- a/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss +++ b/client/wfnews-war/src/main/angular/src/app/components/dashboard-component/widgets/highlights-widget/highlights-widget.component.scss @@ -1,7 +1,9 @@ @import "../../../../../styles/variables"; @import "notosans-fontface/scss/notosans-fontface"; -:host { display: block; } +:host { + display: block; +} .container { overflow: hidden; @@ -11,11 +13,18 @@ border-radius: 20px; background: #fff; box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1); - max-width: min(1460px, calc(100dvw - 104px)); padding: var(--24, 24px); flex-direction: column; align-items: flex-start; gap: var(--24, 24px); + + @media (max-width: $mobile-max-width) { + max-width: min(1460px, calc(100dvw - 90px)); + } + + @media (min-width: $desktop-sm-min-width) { + max-width: min(1460px, calc(100dvw - 104px)); + } } .content {