Airline Crew Scheduling
This is just a very basic project about scheduling crews for flights. The user can create flight assignments and assign crews to them. I built this project to demonstrate some skills using Lightning Web Components just right after I finished the Udemy course on how to Pass PD1. There's only two Custom Objects I created, Crew and Crew Assignments, or could be called Flight Assignments if you want.
View on GithubThe Challenge
This timeline was the hardest part to design. It took me a couple of days to wrap my head around how to make the CSS dynamic. Probably spent more time designing than just throwing around some lightning components. Only LWC is the easy part because it doesn't require much CSS.
The main struggle was to make sure the assignment boxes were aligned with the timeline. Another struggle was that the width of each box had to be calculated based on the duration of the flight.
And man, debugging in Salesforce is a whole different beast compared to React. There are so many limitations on building things in Salesforce.
But hey, I made it work! I found some workarounds and practices that are way more suitable for making those features happen anyway. This project was a great learning experience for me, indeed.
Next up, I'm thinking of adding maps to this project so users can see where the flights are headed. That'd be a sick feature to add, right? I'll be breaking that component out from the main timeline component, but I'll be using pub/sub to allow the two components to communicate to each other.
Crews
Crews can be either a Pilot or a Flight Attendant. The reason why I separated them into two types is because I need to know which one is which because the number of Pilots and Flight Attendants required for a flight must be different.
This was much easier to design because it's only a list and some basic fetching of data. I was able to get away with not using any of the complex features of LWC like the lightning-tree-grid component. I was able to just use a simple list and it worked great. Although now that I've mentioned it, I'm planning to use the lightning-tree-grid component for another project in the future just to demonstrate how it works.
But there's also a challenge here where I have to make these boxes draggable and drop them in the timeline, on the assignment boxes to be exact.
Custom Attributes
Surprisingly, I was also able to add custom attributes to Crew Assignments. Fields that weren't part of the Crew Assignment object.
1// Wire the assignments data
2@wire(getAssignments, { dateTimeVar: '$currentDate' })
3wiredAssignments(result) {
4 this.wiredAssignmentsResult = result;
5 const { data, error } = result;
6
7 if (data) {
8 this.assignments = data.map(assignment => {
9 // Some calculations and formatting
10 . . . . .
11
12 return {
13 // fields inside Crew Assignment object
14 ...assignment,
15 // fields outside Crew Assignment object added by way of formatting and calculations and further object mapping
16 formattedDepartureTime,
17 formattedArrivalTime,
18 flightInfoStyle,
19 crew
20 };
21 });
22 this.error = undefined;
23
24 } else if (error) {
25 this.error = error;
26 this.assignments = [];
27 this.handleError(error);
28 }
29}
Trigger
The crew's availability is updated whenever a crew is assigned or removed from a flight simply by the use of Apex Triggers.
1trigger UpdateCrewAvailability on Crew_Assignment__c (before update) {
2 Set<Id> crewIdsToAssign = new Set<Id>();
3 Set<Id> crewIdsToRemove = new Set<Id>();
4
5 // Loop through the assignments to check for changes
6 for (Integer i = 0; i < Trigger.new.size(); i++) {
7 Crew_Assignment__c newAssignment = Trigger.new[i];
8 Crew_Assignment__c oldAssignment = Trigger.old[i];
9
10 // Check if a crew member is being assigned
11 if (newAssignment.Crew__c != null && oldAssignment.Crew__c == null) {
12 crewIdsToAssign.add(newAssignment.Crew__c);
13 }
14 // Check if a crew member is being removed
15 else if (newAssignment.Crew__c == null && oldAssignment.Crew__c != null) {
16 crewIdsToRemove.add(oldAssignment.Crew__c);
17 }
18 }
19
20 // Update availability for assigned crew members
21 if (!crewIdsToAssign.isEmpty()) {
22 List<Crew__c> crewsToUpdate = [SELECT Id, Availability_Status__c FROM Crew__c WHERE Id IN :crewIdsToAssign];
23 for (Crew__c crew : crewsToUpdate) {
24 crew.Availability_Status__c = false; // Set to false when assigned
25 }
26 update crewsToUpdate;
27 }
28
29 // Update availability for removed crew members
30 if (!crewIdsToRemove.isEmpty()) {
31 List<Crew__c> crewsToUpdate = [SELECT Id, Availability_Status__c FROM Crew__c WHERE Id IN :crewIdsToRemove];
32 for (Crew__c crew : crewsToUpdate) {
33 crew.Availability_Status__c = true; // Set to true when unassigned
34 }
35 update crewsToUpdate;
36 }
37}