Skip to content

Commit

Permalink
Events & Facilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Raajheer1 committed Oct 27, 2024
1 parent 241be0f commit 7e0d00f
Show file tree
Hide file tree
Showing 23 changed files with 1,340 additions and 48 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/upgrade.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Upgrade Dependencies

on:
schedule:
- cron: '1 0 * * 0'
workflow_dispatch:

jobs:
yarn-upgrade:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
cache: 'yarn'
- name: Install Yarn
run: npm install -g yarn
- name: Setup git and create branch
env:
GITHUB_TOKEN: ${{ secrets.G_TOKEN }}
run: |
git config --global user.name "Raajheer1"
git config --global user.email "raaj.patel229@gmail.com"
git checkout -b chore/upgrade-dependencies-$(date +%Y-%m-%d)
git push --set-upstream origin chore/upgrade-dependencies-$(date +%Y-%m-%d)
- name: Upgrade dependencies
run: yarn upgrade --latest
- name: Lint fix
run: yarn lint:fix
- name: Commit and push changes
env:
GITHUB_TOKEN: ${{ secrets.G_TOKEN }}
run: |
git add .
git commit -m "chore: upgrade dependencies"
git push
- name: Create PR
env:
GITHUB_TOKEN: ${{ secrets.G_TOKEN }}
run: |
gh pr create -t "Chore: Upgrade Dependencies" -B master -H chore/upgrade-dependencies-$(date +%Y-%m-%d) --body "Weekly automated PR to upgrade dependencies using \`yarn upgrade --latest\`. Please verify the changes and merge."
29 changes: 29 additions & 0 deletions src/components/Modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<template>
<div v-if="props.visible" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
<div class="bg-white p-10 rounded shadow-lg relative w-4/5 lg:w-1/2">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl text-usa-blue font-bold">{{ props.title }}</h2>
<span @click="close">
<i class="fa-solid fa-x text-gray-400 cursor-pointer hover:text-usa-blue"></i>
</span>
</div>
<slot> </slot>
</div>
</div>
</template>

<script setup lang="ts">
const props = defineProps<{
visible: boolean;
title: string;
}>();
const emit = defineEmits<{
close: [];
}>();
const close = (): void => {
emit("close");
};
</script>

<style scoped></style>
100 changes: 100 additions & 0 deletions src/components/event/EventPositions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<div class="grid grid-cols-1 lg:grid-cols-4 gap-x-5">
<div>
<h3 class="text-2xl font-bold text-usa-blue mb-3">TMU</h3>
<PositionList
:positions="miscPositions"
:facility_id="props.facility_id"
@assign="assignPositionPassthrough"
@update-positions="fetchPositions()"
/>
</div>
<div>
<h3 class="text-2xl font-bold text-usa-blue mb-3">Enroute</h3>
<PositionList
:positions="enroutePosition"
:facility_id="props.facility_id"
@assign="assignPositionPassthrough"
@update-positions="fetchPositions()"
/>
</div>
<div>
<h3 class="text-2xl font-bold text-usa-blue mb-3">TRACON</h3>
<PositionList
:positions="traconPosition"
:facility_id="props.facility_id"
@assign="assignPositionPassthrough"
@update-positions="fetchPositions()"
/>
</div>
<div>
<h3 class="text-2xl font-bold text-usa-blue mb-3">Local</h3>
<PositionList
:positions="localPosition"
:facility_id="props.facility_id"
@assign="assignPositionPassthrough"
@update-positions="fetchPositions()"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { EventPosition } from "@/types";
import useEventStore from "@/stores/event";
import { computed, onMounted, ref } from "vue";
import PositionList from "@/components/event/PositionList.vue";
const eventStore = useEventStore();
const props = defineProps<{
facility_id: string;

Check warning on line 50 in src/components/event/EventPositions.vue

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Prop "facility_id" is not in camelCase
event_id: number;

Check warning on line 51 in src/components/event/EventPositions.vue

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Prop "event_id" is not in camelCase
}>();
const emit = defineEmits<{
assign: [position: EventPosition];
}>();
const positions = ref<EventPosition[]>([]);
const miscPositions = computed<EventPosition[]>(() => {
return (
positions.value.filter(
(position) => !["CTR", "APP", "DEP", "TWR", "GND", "DEL"].some((type) => position.position.includes(`_${type}`))
) || []
);
});
const enroutePosition = computed<EventPosition[]>(() => {
return positions.value.filter((position) => position.position.includes("_CTR")) || [];
});
const traconPosition = computed<EventPosition[]>(() => {
return (
positions.value.filter((position) => position.position.includes("_APP") || position.position.includes("_DEP")) || []
);
});
const localPosition = computed<EventPosition[]>(() => {
return (
positions.value.filter(
(position) =>
position.position.includes("_TWR") || position.position.includes("_GND") || position.position.includes("_DEL")
) || []
);
});
async function fetchPositions(): Promise<void> {
positions.value = await eventStore.fetchEventPositions(props.facility_id, props.event_id);
}
function assignPositionPassthrough(position: EventPosition): void {
emit("assign", position);
}
onMounted(async () => {
await fetchPositions();
});
</script>

<style scoped></style>
136 changes: 136 additions & 0 deletions src/components/event/PositionList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<template>
<div class="space-y-3">
<h4 v-if="props.positions.length === 0" class="text-lg text-usa-grey">No Positions Posted</h4>
<div v-for="position in props.positions" :key="position.id">
<h5 class="text-lg text-usa-grey">{{ position.position }}</h5>
<div v-if="position.shifts" class="grid grid-cols-2 my-1 gap-x-0.5">
<button
v-for="idx in 2"
:key="idx"
class="hover:drop-shadow-sm text-sm bg-gray-200 font-semibold py-0.5 flex items-center justify-center"
:class="[
idx === 1 ? 'rounded-l-lg' : 'rounded-r-lg',
isAssigned(position, idx) ? 'border border-usa-red' : 'border border-gray-200',
]"
@mouseover="selected = position.position + idx"
@mouseleave="resetSelected"
>
<div v-if="idx == 1">
<span v-if="position.assignee == 0 && inSignups(position.signups, idx)" class="truncate"
>Vacant (Requested)</span
>
<span v-else-if="position.assignee == 0">Vacant</span>
<span v-else-if="position.assignee == userStore.self!.cid" class="font-bold">
{{ position.assignee_name }}
</span>
<span v-else-if="inSignups(position.signups, idx)" class="truncate">
{{ position.assignee_name }} (Requested)
</span>
<span v-else>{{ position.assignee_name }}</span>
</div>
<div v-else>
<span v-if="position.secondary_assignee == 0 && inSignups(position.signups, idx)" class="truncate"
>Vacant (Requested)</span
>
<span v-else-if="position.secondary_assignee == 0">Vacant</span>
<span v-else-if="position.secondary_assignee == userStore.self!.cid" class="font-bold">
{{ position.secondary_assignee_name }}
</span>
<span v-else-if="inSignups(position.signups, idx)" class="truncate">
{{ position.secondary_assignee_name }} (Requested)
</span>
<span v-else>{{ position.secondary_assignee_name }}</span>
</div>
<PositionTooltip
v-if="selected == position.position + idx"
:can-edit-event="canEditEvent()"
:shift="idx"
:is-signedup="inSignups(position.signups, idx)"
:is-assigned="isAssigned(position, idx)"
:position="position"
@update-positions="updatePositions()"
@assign="assignPositionPassthrough"
/>
</button>
</div>
<div v-else class="my-1">
<button
class="w-full hover:drop-shadow-sm text-sm rounded-lg bg-gray-200 font-semibold py-0.5 flex items-center justify-center"
:class="userStore.self!.cid == position.assignee ? 'border-1 border-usa-red' : ''"
@mouseover="selected = position.position"
@mouseleave="resetSelected"
>
<span v-if="position.assignee == 0 && inSignups(position.signups, 1)" class="truncate"
>Vacant (Requested)</span
>
<span v-else-if="position.assignee == 0">Vacant</span>
<span v-else-if="position.assignee == userStore.self!.cid" class="font-bold">
{{ position.assignee_name }}
</span>
<span v-else-if="inSignups(position.signups, 1)" class="truncate">
{{ position.assignee_name }} (Requested)
</span>
<span v-else>{{ position.assignee_name }}</span>

<PositionTooltip
v-if="selected == position.position"
:can-edit-event="canEditEvent()"
:shift="1"
:is-signedup="inSignups(position.signups, 1)"
:is-assigned="isAssigned(position, 1)"
:position="position"
@update-positions="updatePositions()"
@assign="assignPositionPassthrough"
/>
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { EventPosition, EventSignups } from "@/types";
import useUserStore from "@/stores/user";
import { ref } from "vue";
import hasRole from "@/utils/auth";
import PositionTooltip from "@/components/event/PositionTooltip.vue";
const emit = defineEmits<{
updatePositions: [];
assign: [position: EventPosition];
}>();
const userStore = useUserStore();
const props = defineProps<{
positions: EventPosition[];
facility_id: string;

Check warning on line 105 in src/components/event/PositionList.vue

View workflow job for this annotation

GitHub Actions / eslint (20.x)

Prop "facility_id" is not in camelCase
}>();
const selected = ref<string>("");
const inSignups = (signups: EventSignups[], shift: number): boolean => {
return signups.some((signup) => signup.cid === userStore.self!.cid && signup.shift === shift);
};
const isAssigned = (position: EventPosition, shift: number): boolean => {
return shift === 1 ? position.assignee === userStore.self!.cid : position.secondary_assignee === userStore.self!.cid;
};
// Wait 100ms then set select to empty string
const resetSelected = (): void => {
selected.value = "";
};
const canEditEvent = (): boolean => {
return hasRole(["ATM", "DATM", "EC", "AEC"], props.facility_id);
};
function updatePositions(): void {
emit("updatePositions");
}
function assignPositionPassthrough(position: EventPosition): void {
emit("assign", position);
}
</script>

<style scoped></style>
Loading

0 comments on commit 7e0d00f

Please sign in to comment.