From 33d6e10065bd92aedc94d6d9882f019ff1594a14 Mon Sep 17 00:00:00 2001 From: Philippe Ozil Date: Wed, 6 Nov 2024 00:05:53 +0100 Subject: [PATCH 1/2] feat: LWC best practices and various fixes --- .../lwc/experiencesPanel/experiencesPanel.css | 2 +- .../experiencesPanel/experiencesPanel.html | 49 +++++------ .../lwc/experiencesPanel/experiencesPanel.js | 86 +++++++++++-------- .../lwc/experiencesTile/experiencesTile.css | 28 +++--- .../lwc/experiencesTile/experiencesTile.html | 31 ++----- .../lwc/experiencesTile/experiencesTile.js | 25 ++---- .../experienceSchedule/experienceSchedule.js | 11 ++- 7 files changed, 111 insertions(+), 121 deletions(-) diff --git a/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.css b/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.css index 3d57842..0039e90 100644 --- a/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.css +++ b/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.css @@ -13,8 +13,8 @@ } c-experiences-tile { - min-width: 200px; flex: 1; + display: flex; } c-paginator { diff --git a/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.html b/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.html index 371f5b5..51ea056 100644 --- a/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.html +++ b/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.html @@ -7,36 +7,29 @@ class="search-bar" > - - diff --git a/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.js b/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.js index 802a035..e9889fa 100644 --- a/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.js +++ b/cc-service-app/main/default/lwc/experiencesPanel/experiencesPanel.js @@ -1,50 +1,62 @@ -import { LightningElement, wire } from 'lwc'; +import { LightningElement, wire, track } from 'lwc'; import { publish, MessageContext } from 'lightning/messageService'; +import { getPicklistValues } from 'lightning/uiObjectInfoApi'; +import EXPERIENCE_TYPE_FIELD from '@salesforce/schema/Experience__c.Type__c'; import EXPERIENCE_SELECTED_MESSAGE from '@salesforce/messageChannel/ExperienceSelected__c'; import getExperiences from '@salesforce/apex/ExperienceController.getExperiences'; export default class ExperiencePanel extends LightningElement { - pageNumber = 1; + types = []; + type; pageSize; - totalItemCount = 0; - types = [ - { label: 'Adventure Activities', value: 'Adventure Activities' }, - { label: 'Beaches & Snorkeling', value: 'Beaches & Snorkeling' }, - { - label: 'Cultural Tours & Workshops', - value: 'Cultural Tours & Workshops' - }, - { label: 'Dining Experiences', value: 'Dining Experiences' }, - { - label: "Family & Kids' Activities", - value: "Family & Kids' Activities" - }, - { label: 'Fitness & Exercise', value: 'Fitness & Exercise' }, - { label: 'Golf', value: 'Golf' }, - { label: 'Nature & Eco Tours', value: 'Nature & Eco Tours' }, - { - label: 'Nightlife & Entertainment', - value: 'Nightlife & Entertainment' - }, - { - label: 'Relaxation & Quiet Zones', - value: 'Relaxation & Quiet Zones' - }, - { label: 'Spa & Wellness', value: 'Spa & Wellness' }, - { label: 'Swimming Pools', value: 'Swimming Pools' }, - { label: 'Tennis & Pickleball', value: 'Tennis & Pickleball' }, - { label: 'Water Sports', value: 'Water Sports' } - ]; - type = 'Adventure Activities'; - recordTypeId; + totalItemCount; + pageNumber = 1; + error; + + @track experiences; + @wire(MessageContext) messageContext; @wire(getExperiences, { type: '$type', pageNumber: '$pageNumber' }) - experiences; + wiredExperiences({ error, data }) { + if (data) { + this.pageSize = data.pageSize; + this.totalItemCount = data.totalItemCount; + this.experiences = data.records.map((experienceRecord) => { + const experience = { ...experienceRecord }; + experience.isSelected = false; + return experience; + }); + } else if (error) { + this.experiences = undefined; + this.error = error; + } + } + + @wire(getPicklistValues, { + recordTypeId: '012000000000000AAA', // Default record type Id + fieldApiName: EXPERIENCE_TYPE_FIELD + }) + getExperienceTypePicklistValues({ error, data }) { + if (data) { + this.types = data.values; + if (data.values.length > 0) { + this.type = data.values[0].value; + } + } else if (error) { + this.error = error; + } + } handleExperienceSelected(event) { + const experienceId = event.detail; + // Update selection + this.experiences.forEach((experience) => { + experience.isSelected = experience.Id === experienceId; + }); + // Send Lightning message to notify selection publish(this.messageContext, EXPERIENCE_SELECTED_MESSAGE, { - experienceId: event.detail + experienceId }); } @@ -65,4 +77,8 @@ export default class ExperiencePanel extends LightningElement { handleNextPage() { this.pageNumber = this.pageNumber + 1; } + + get hasNoExperiences() { + return this.experiences && this.experiences.length === 0; + } } diff --git a/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.css b/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.css index ceb3d1a..b41c8a6 100644 --- a/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.css +++ b/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.css @@ -1,26 +1,24 @@ -.container { - height: 100% !important; -} - -.content { +button { + display: flex; + flex-direction: column; + align-items: center; + color: inherit; padding: 8px; background-color: #ffffff; border-radius: 0.25rem; + border-width: 0; text-align: center; - height: 100% !important; } -a { - color: inherit; -} -a:hover { - text-decoration: none !important; +.selected { + background-color: #04545f; + color: #ffffff; } -img.experience { +.experience-picture { border-radius: 0.25rem; height: 120px; - width: 100% !important; + width: 100%; pointer-events: none; object-fit: cover; } @@ -29,3 +27,7 @@ img.experience { font-weight: bold; text-transform: uppercase; } + +.description { + text-overflow: ellipsis; +} diff --git a/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.html b/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.html index 17a5f81..adb8e3b 100644 --- a/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.html +++ b/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.html @@ -1,24 +1,11 @@ diff --git a/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.js b/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.js index 6d417fa..6e2f0f1 100644 --- a/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.js +++ b/cc-service-app/main/default/lwc/experiencesTile/experiencesTile.js @@ -5,32 +5,17 @@ import { LightningElement, api } from 'lwc'; * Experience__c data must contain all fields used by this component. */ export default class ExperiencesTile extends LightningElement { - _experience; - /** Experience__c to display. */ - @api - get experience() { - return this._experience; - } - set experience(value) { - this._experience = value; - this.pictureUrl = value.Picture_URL__c; - this.name = value.Name; - this.description = value.Description__c; - this.rating = value.Rating__c; - } - - /** Experience__c field values to display. */ - pictureUrl; - name; - description; - rating; + @api experience; handleClick() { const selectedEvent = new CustomEvent('selected', { detail: this.experience.Id }); this.dispatchEvent(selectedEvent); - this.template.querySelector('a').style.color = 'rgb(238, 137, 111)'; + } + + get tileClasses() { + return this.experience.isSelected ? 'selected' : ''; } } diff --git a/force-app/main/default/lwc/experienceSchedule/experienceSchedule.js b/force-app/main/default/lwc/experienceSchedule/experienceSchedule.js index ef4b91f..425fc23 100644 --- a/force-app/main/default/lwc/experienceSchedule/experienceSchedule.js +++ b/force-app/main/default/lwc/experienceSchedule/experienceSchedule.js @@ -8,7 +8,14 @@ import isCommunity from '@salesforce/apex/ContextService.isCommunity'; export default class ExperienceSchedule extends NavigationMixin( LightningElement ) { - @api recordId; + @api + get recordId() { + return this._recordId; + } + set recordId(value) { + this._recordId = value; + } + _recordId; sessions = []; error; @@ -39,7 +46,7 @@ export default class ExperienceSchedule extends NavigationMixin( } @wire(getExperienceSessionsForDate, { - experienceId: '$recordId', + experienceId: '$_recordId', timestamp: '$timestamp' }) wiredSessions({ error, data }) { From d0db4aa93de6805588b9868b60299d28677f57fa Mon Sep 17 00:00:00 2001 From: Philippe Ozil Date: Wed, 6 Nov 2024 00:06:18 +0100 Subject: [PATCH 2/2] fix: remove special char from sample data --- data/data-Experience__c-large.json | 6 +++--- data/data-Experience__c.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/data-Experience__c-large.json b/data/data-Experience__c-large.json index 018c849..15b5123 100644 --- a/data/data-Experience__c-large.json +++ b/data/data-Experience__c-large.json @@ -153,7 +153,7 @@ "Activity_Level__c": "Medium", "Capacity__c": 55, "Default_Start_Time__c": "15:00:00.000Z", - "Description__c": "Take part in a cooking class where you'll harvest fresh ingredients from our organic garden and learn to cook a delicious meal.", + "Description__c": "Take part in a cooking class where you'll harvest fresh ingredients from our organic garden and learn to cook a delicious meal.", "Duration_Hours__c": 3, "Location__c": "Organic Garden", "Picture_URL__c": "https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/coral-clouds/sjahfb9mmbzzyogf87fk.jpg", @@ -217,7 +217,7 @@ "Activity_Level__c": "Low", "Capacity__c": 20, "Default_Start_Time__c": "15:30:00.000Z", - "Description__c": "A baking class for kids where they'll learn to make and decorate cupcakes and cookies.", + "Description__c": "A baking class for kids where they'll learn to make and decorate cupcakes and cookies.", "Duration_Hours__c": 1, "Location__c": "Resort Kitchen", "Picture_URL__c": "https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/coral-clouds/sjahfb9mmbzzyogf87fk.jpg", @@ -745,7 +745,7 @@ "Activity_Level__c": "Medium", "Capacity__c": 30, "Default_Start_Time__c": "16:00:00.000Z", - "Description__c": "Board our 4x4 vehicles for an adventurous off-road journey through the jungle's heart.", + "Description__c": "Board our 4x4 vehicles for an adventurous off-road journey through the jungle's heart.", "Duration_Hours__c": 4, "Location__c": "Jungle Trails", "Picture_URL__c": "https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/coral-clouds/gzzr2klphfxmfoomupzp.jpg", diff --git a/data/data-Experience__c.json b/data/data-Experience__c.json index 8fb8d31..3f60b37 100644 --- a/data/data-Experience__c.json +++ b/data/data-Experience__c.json @@ -473,7 +473,7 @@ "Activity_Level__c": "Medium", "Capacity__c": 30, "Default_Start_Time__c": "16:00:00.000Z", - "Description__c": "Board our 4x4 vehicles for an adventurous off-road journey through the jungle's heart.", + "Description__c": "Board our 4x4 vehicles for an adventurous off-road journey through the jungle's heart.", "Duration_Hours__c": 4, "Location__c": "Jungle Trails", "Picture_URL__c": "https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/coral-clouds/gzzr2klphfxmfoomupzp.jpg",