-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into dependabot/npm_and_yarn/nuxt-3.12.4
- Loading branch information
Showing
22 changed files
with
1,062 additions
and
833 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,125 @@ | ||
<script setup lang="ts"> | ||
import { VueFinalModal } from 'vue-final-modal' | ||
const props = defineProps<{ | ||
title?: string | ||
allCallback: (newIsEnabled: boolean) => void | ||
cityCallback: (newIsEnabled: boolean, city: string) => void | ||
countyCallback: (newIsEnabled: boolean, county: string) => void | ||
}>() | ||
const emit = defineEmits<{ | ||
(e: 'confirm'): void | ||
}>() | ||
// There's a lot of redundancy with the cities and counties between this component and the App component. | ||
// Try to reduce it in the future. | ||
import { ref, inject, computed } from 'vue'; | ||
import { VueFinalModal } from 'vue-final-modal'; | ||
import TopicFilterItem from './TopicFilterItem.vue'; | ||
import TagFilterItem from './TagFilterItem.vue'; | ||
import eventSourcesJSON from '@/assets/event_sources.json'; | ||
// Use composable. | ||
const isAllCitiesInMarinCountyEnabled = useIsAllCitiesInMarinCountyEnabled(); | ||
const isSanFranciscoEnabled = useIsSanFranciscoEnabled(); | ||
const isOthersInSFSanMateoCountyEnabled = useIsOthersInSFSanMateoCountyEnabled(); | ||
const isOaklandEnabled = useIsOaklandEnabled(); | ||
const isBerkeleyEnabled = useIsBerkeleyEnabled(); | ||
const isOthersInAlamedaCountyEnabled = useIsOthersInAlamedaCountyEnabled(); | ||
const isSanJoseEnabled = useIsSanJoseEnabled(); | ||
const isOthersInSantaClaraCountyEnabled = useIsOthersInSantaClaraCountyEnabled(); | ||
const isSantaCruzEnabled = useIsSantaCruzEnabled(); | ||
const isOthersInSantaCruzCountyEnabled = useIsOthersInSantaCruzCountyEnabled(); | ||
const tags = inject('tags'); //Grabs the 'tags' array, which features all tags and whether they're hidden, from App.vue | ||
const countyIdToCitiesRefs = { | ||
[MARIN_COUNTY_ID]: [isAllCitiesInMarinCountyEnabled], | ||
[SF_SAN_MATEO_COUNTY_ID]: [isSanFranciscoEnabled, isOthersInSFSanMateoCountyEnabled], | ||
[ALAMEDA_COUNTY_ID]: [isOaklandEnabled, isBerkeleyEnabled, isOthersInAlamedaCountyEnabled], | ||
[SANTA_CLARA_COUNTY_ID]: [isSanJoseEnabled, isOthersInSantaClaraCountyEnabled], | ||
[SANTA_CRUZ_COUNTY_ID]: [isSantaCruzEnabled, isOthersInSantaCruzCountyEnabled], | ||
}; | ||
// This function is needed because, since the CityFilterItem component is nested within this component, | ||
// the changes to the state from the App component will not cause a re-render of the CityFilterItem components. | ||
const updateIsCityEnabledLocally = (newIsEnabled, county) => { | ||
countyIdToCitiesRefs[county].forEach((city) => { | ||
city.value = newIsEnabled; | ||
}); | ||
function getTagVisibility(tagName) { | ||
const tag = tags.value.find(t => t.name === tagName); | ||
return tag ? tag.isVisible : false; | ||
} | ||
const countyWrapper = (newIsEnabled: boolean, county: string) => { | ||
updateIsCityEnabledLocally(newIsEnabled, county); | ||
props.countyCallback(newIsEnabled, county); | ||
function updateTagVisibility(tagName, visibility) { | ||
const tag = tags.value.find(t => t.name === tagName); | ||
if (tag) { | ||
tag.isVisible = visibility; | ||
} | ||
} | ||
const allWrapper = (newIsEnabled: boolean) => { | ||
updateAllIsCityEnabledLocally(newIsEnabled); | ||
props.allCallback(newIsEnabled); | ||
function setVisibilityForGroup(tagsInGroup, visibility) { | ||
tagsInGroup.forEach(tagName => { | ||
const tag = tags.value.find(t => t.name === tagName.name); | ||
if (tag) { | ||
tag.isVisible = visibility; | ||
} | ||
}); | ||
} | ||
const updateAllIsCityEnabledLocally = (newIsEnabled) => { | ||
Object.values(countyIdToCitiesRefs).forEach((cities) => { | ||
cities.forEach((city) => { | ||
city.value = newIsEnabled; | ||
}); | ||
}); | ||
} | ||
const { enableEventSource, disableEventSource } = defineProps<{ | ||
enableEventSource: (name: string) => void; | ||
disableEventSource: (name: string) => void; | ||
}>(); | ||
</script> | ||
<template> | ||
<VueFinalModal class="popper-box-wrapper" content-class="popper-box-inner" overlay-transition="vfm-fade" | ||
content-transition="vfm-fade"> | ||
<CountyFilterItem :label="ALL_ID" @on-yes="allWrapper(true)" @on-no="allWrapper(false)"> | ||
</CountyFilterItem> | ||
const emit = defineEmits<{ | ||
(e: 'confirm'): void; | ||
}>(); | ||
<CountyFilterItem :label="MARIN_COUNTY_ID" | ||
@on-yes="countyWrapper(true, MARIN_COUNTY_ID); (() => { useIsAllCitiesInMarinCountyEnabled.value = true })()" | ||
@on-no="countyWrapper(false, MARIN_COUNTY_ID); "> | ||
<CityFilterItem v-model="isAllCitiesInMarinCountyEnabled" :label="ALL_CITIES_IN_MARIN_COUNTY_ID" | ||
@on-input="cityCallback($event.target.checked, ALL_CITIES_IN_MARIN_COUNTY_ID)"> | ||
</CityFilterItem> | ||
</CountyFilterItem> | ||
// Development environment flag | ||
const isDevelopment = process.env.NODE_ENV === 'development'; | ||
<CountyFilterItem :label="SF_SAN_MATEO_COUNTY_ID" @on-yes="countyWrapper(true, SF_SAN_MATEO_COUNTY_ID)" | ||
@on-no="countyWrapper(false, SF_SAN_MATEO_COUNTY_ID)"> | ||
<CityFilterItem v-model="isSanFranciscoEnabled" :label="SAN_FRANCISCO_ID" | ||
@on-input="cityCallback($event.target.checked, SAN_FRANCISCO_ID)"> | ||
</CityFilterItem> | ||
<CityFilterItem v-model="isOthersInSFSanMateoCountyEnabled" :label="OTHERS_IN_SF_SAN_MATEO_COUNTY_ID" | ||
@on-input="cityCallback($event.target.checked, OTHERS_IN_SF_SAN_MATEO_COUNTY_ID)"> | ||
</CityFilterItem> | ||
</CountyFilterItem> | ||
// Accessing tags from the imported JSON | ||
const tagsHeader = ref(eventSourcesJSON.appConfig.tagsHeader); | ||
const tagsHidden = ref(eventSourcesJSON.appConfig.tagsHidden); | ||
const tagsToShow = ref(eventSourcesJSON.appConfig.tagsToShow); | ||
<CountyFilterItem :label="ALAMEDA_COUNTY_ID" @on-yes="countyWrapper(true, ALAMEDA_COUNTY_ID)" | ||
@on-no="countyWrapper(false, ALAMEDA_COUNTY_ID)"> | ||
<CityFilterItem v-model="isOaklandEnabled" :label="OAKLAND_ID" | ||
@on-input="cityCallback($event.target.checked, OAKLAND_ID)"> | ||
</CityFilterItem> | ||
<CityFilterItem v-model="isBerkeleyEnabled" :label="BERKELEY_ID" | ||
@on-input="cityCallback($event.target.checked, BERKELEY_ID)"> | ||
</CityFilterItem> | ||
<CityFilterItem v-model="isOthersInAlamedaCountyEnabled" :label="OTHERS_IN_ALAMEDA_COUNTY_ID" | ||
@on-input="cityCallback($event.target.checked, OTHERS_IN_ALAMEDA_COUNTY_ID)"> | ||
</CityFilterItem> | ||
</CountyFilterItem> | ||
// Computed property to flatten tagsToShow into a 1D array of strings, for the purpose of debugging to make sure there's no tags missing | ||
const tagsAllShown = computed(() => { | ||
let flattened = []; | ||
for (let i = 0; i < tagsToShow.value.length; i++) { | ||
if (tagsToShow.value[i].length === 1) { | ||
flattened.push(tagsToShow.value[i][0].map(tag => tag.name)); | ||
} else { | ||
flattened.push(...tagsToShow.value[i].slice(1).map(tag => tag.name)); // Skip the first element (label) and add rest | ||
} | ||
} | ||
flattened.push(...tagsHeader.value.map(tag => tag.name)); //Add the tagsHeader values to the array, ensuring that they're not left out from the list of ALL TAGS SHOWN | ||
flattened.push(...tagsHidden.value); //Add the tagsHidden values to the array, ensuring that they're not left out from the list of ALL TAGS SHOWN | ||
return flattened; | ||
}); | ||
<CountyFilterItem :label="SANTA_CLARA_COUNTY_ID" @on-yes="countyWrapper(true, SANTA_CLARA_COUNTY_ID)" | ||
@on-no="countyWrapper(false, SANTA_CLARA_COUNTY_ID)"> | ||
<CityFilterItem v-model="isSanJoseEnabled" :label="SAN_JOSE_ID" | ||
@on-input="cityCallback($event.target.checked, SAN_JOSE_ID)"> | ||
</CityFilterItem> | ||
<CityFilterItem v-model="isOthersInSantaClaraCountyEnabled" :label="OTHERS_IN_SANTA_CLARA_COUNTY_ID" | ||
@on-input="cityCallback($event.target.checked, OTHERS_IN_SANTA_CLARA_COUNTY_ID)"> | ||
</CityFilterItem> | ||
</CountyFilterItem> | ||
// | ||
const tagsNotShown = computed(() => { //A 1D array of tags that aren't featured in tagsAllShown but ARE featured in tags; used to show any tags that maybe should be visible in the UI or should be wiped from event_sources.json altogether. | ||
const shownSet = new Set(tagsAllShown.value); | ||
return tags.value.filter(tag => !shownSet.has(tag.name)); | ||
}); | ||
<CountyFilterItem :label="SANTA_CRUZ_COUNTY_ID" @on-yes="countyWrapper(true, SANTA_CRUZ_COUNTY_ID)" | ||
@on-no="countyWrapper(false, SANTA_CRUZ_COUNTY_ID)"> | ||
<CityFilterItem v-model="isSantaCruzEnabled" :label="SANTA_CRUZ_ID" | ||
@on-input="cityCallback($event.target.checked, SANTA_CRUZ_ID)"> | ||
</CityFilterItem> | ||
<CityFilterItem v-model="isOthersInSantaCruzCountyEnabled" :label="OTHERS_IN_SANTA_CRUZ_COUNTY_ID" | ||
@on-input="cityCallback($event.target.checked, OTHERS_IN_SANTA_CRUZ_COUNTY_ID)"> | ||
</CityFilterItem> | ||
</CountyFilterItem> | ||
<div class="bottom"> | ||
function handleEventSourceChange(tag: string, isEnabled: boolean) { | ||
if (isEnabled) { | ||
enableEventSource(tag); | ||
} else { | ||
disableEventSource(tag); | ||
} | ||
} | ||
// Example function to toggle visibility | ||
function toggleTagVisibility(tagName: string) { | ||
const tag = tags.value.find(t => t.name === tagName); | ||
if (tag) { | ||
tag.isVisible = !tag.isVisible; | ||
} | ||
} | ||
<button @click="emit('confirm')"> | ||
Done | ||
</button> | ||
</div> | ||
</VueFinalModal> | ||
</template> | ||
</script> | ||
|
||
<template> | ||
<VueFinalModal class="popper-box-wrapper" content-class="popper-box-inner" overlay-transition="vfm-fade" content-transition="vfm-fade"> | ||
<span class="event-headers"> | ||
Event Purpose | ||
</span> | ||
<div class="county-header"> | ||
<TagFilterItem v-for="tag in tagsHeader" :key="tag.name" class="tag-group" :label="tag.fullName" :modelValue="getTagVisibility(tag.name)" @update:modelValue="updateTagVisibility(tag.name, $event)"> | ||
</TagFilterItem> | ||
</div> | ||
<span class="event-headers"> | ||
Event Type | ||
</span> | ||
<div v-for="group in tagsToShow" :key="group[0] || group" class="tag-group"> | ||
<template v-if="Array.isArray(group)"> | ||
<TopicFilterItem class="tag-header" :label="group[0].fullName" @checkAll="setVisibilityForGroup(group.slice(1), true)" @uncheckAll="setVisibilityForGroup(group.slice(1), false)"> | ||
<TagFilterItem v-for="tag in group.slice(1)" :key="tag.name" :label="tag.fullName" :modelValue="getTagVisibility(tag.name)" @update:modelValue="updateTagVisibility(tag.name, $event)"> | ||
</TagFilterItem> | ||
</TopicFilterItem> | ||
</template> | ||
<template v-else> | ||
<TagFilterItem class="tag-sub-item" :label="group.fullName" :modelValue="getTagVisibility(group.name)" @update:modelValue="updateTagVisibility(group.name, $event)"> | ||
</TagFilterItem> | ||
</template> | ||
</div> | ||
<span v-if="isDevelopment"> | ||
<span class="event-headers"> | ||
Tags Not Shown | ||
</span> | ||
<div v-for="tag in tagsNotShown" :key="tag"> | ||
<input type="checkbox" | ||
:checked="getTagVisibility(tag.name)" | ||
@change="updateTagVisibility(tag.name, $event.target.checked)" /> {{ tag.name }} | ||
</div> | ||
</span> | ||
<div class="bottom filterButton"> | ||
<button @click="emit('confirm')">Apply</button> | ||
</div> | ||
</VueFinalModal> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<script setup> | ||
const props = defineProps({ | ||
label: String, | ||
modelValue: Boolean, | ||
isVisible: Boolean | ||
}); | ||
const emit = defineEmits(['update:modelValue']); | ||
// Emitting visibility changes if needed | ||
function updateVisibility(checked) { | ||
emit('update:modelValue', checked); | ||
} | ||
</script> | ||
|
||
<template> | ||
<label class="city-header" :class="{ 'is-hidden': !props.isVisible }"> | ||
<input type="checkbox" :checked="props.modelValue" @change="updateVisibility($event.target.checked)"> | ||
{{ props.label }} | ||
</label> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<script setup lang="ts"> | ||
const props = defineProps({ | ||
label: String | ||
}); | ||
const emit = defineEmits(['checkAll', 'uncheckAll']); | ||
function checkAllTags() { | ||
emit('checkAll'); | ||
} | ||
function uncheckAllTags() { | ||
emit('uncheckAll'); | ||
} | ||
</script> | ||
|
||
<template> | ||
<div class="county-header"> | ||
<span> | ||
<button class="county-input" @click="checkAllTags">+</button> | ||
<button class="county-input" @click="uncheckAllTags">-</button> | ||
{{ label }} | ||
</span> | ||
<slot></slot> | ||
</div> | ||
</template> |
Oops, something went wrong.