|
| 1 | +<!-- |
| 2 | +Copyright (c) 2025 The Linux Foundation and each contributor. |
| 3 | +SPDX-License-Identifier: MIT |
| 4 | +--> |
| 5 | +<template> |
| 6 | + <lfx-drawer |
| 7 | + v-model="isDrawerOpen" |
| 8 | + position="right" |
| 9 | + > |
| 10 | + <div class="relative flex flex-col justify-start h-full"> |
| 11 | + <div class="pt-4 sm:pt-6 px-4 sm:px-6"> |
| 12 | + <h3 class="text-heading-3 font-semibold font-secondary pb-3"> |
| 13 | + {{ geographicalDistribution.name }} |
| 14 | + </h3> |
| 15 | + <p class="text-body-2 text-neutral-500 mb-6"> |
| 16 | + {{ geographicalDistribution.description(project!, props.model) }} |
| 17 | + <a |
| 18 | + :href="geographicalDistribution.learnMoreLink" |
| 19 | + class="text-brand-500" |
| 20 | + target="_blank" |
| 21 | + >Learn more</a |
| 22 | + > |
| 23 | + </p> |
| 24 | + |
| 25 | + <hr /> |
| 26 | + </div> |
| 27 | + <section class="mt-5 flex flex-col flex-grow overflow-auto"> |
| 28 | + <div class="flex flex-wrap gap-4 items-center justify-between mb-6 px-4 sm:px-6 pt-[1px]"> |
| 29 | + <lfx-tabs |
| 30 | + :tabs="tabs" |
| 31 | + :model-value="activeTab" |
| 32 | + width-type="inline" |
| 33 | + @update:model-value="activeTab = $event" |
| 34 | + /> |
| 35 | + <div class="max-w-max"> |
| 36 | + <lfx-activities-dropdown |
| 37 | + v-model="metric" |
| 38 | + placement="bottom-end" |
| 39 | + :full-width="false" |
| 40 | + :match-width="false" |
| 41 | + width="25rem" |
| 42 | + :include-collaborations="props.model.includeCollaborations" |
| 43 | + /> |
| 44 | + </div> |
| 45 | + </div> |
| 46 | + |
| 47 | + <div class="px-4 sm:px-6"> |
| 48 | + <lfx-project-load-state |
| 49 | + :status="status" |
| 50 | + :error="error" |
| 51 | + error-message="Error fetching geographical distribution" |
| 52 | + :is-empty="isEmpty" |
| 53 | + > |
| 54 | + <lfx-geo-distribution-view |
| 55 | + :geo-map-data="geoMapData" |
| 56 | + :label="label" |
| 57 | + /> |
| 58 | + </lfx-project-load-state> |
| 59 | + </div> |
| 60 | + </section> |
| 61 | + </div> |
| 62 | + </lfx-drawer> |
| 63 | +</template> |
| 64 | + |
| 65 | +<script setup lang="ts"> |
| 66 | +import { useRoute } from 'nuxt/app'; |
| 67 | +import { ref, computed, watch } from 'vue'; |
| 68 | +import { storeToRefs } from 'pinia'; |
| 69 | +import LfxGeoDistributionView from './geo-distribution-view.vue'; |
| 70 | +import LfxDrawer from '~/components/uikit/drawer/drawer.vue'; |
| 71 | +import LfxTabs from '~/components/uikit/tabs/tabs.vue'; |
| 72 | +import { useProjectStore } from '~/components/modules/project/store/project.store'; |
| 73 | +import { isEmptyData } from '~/components/shared/utils/helper'; |
| 74 | +import LfxActivitiesDropdown from '~/components/modules/widget/components/contributors/fragments/activities-dropdown.vue'; |
| 75 | +import LfxProjectLoadState from '~/components/modules/project/components/shared/load-state.vue'; |
| 76 | +import geographicalDistribution from '~/components/modules/widget/config/contributor/geographical-distribution/geographical-distribution.config'; |
| 77 | +import type { |
| 78 | + GeoMapData, |
| 79 | + GeoMapResponse, |
| 80 | +} from '~/components/modules/widget/components/contributors/types/geo-map.types'; |
| 81 | +import { |
| 82 | + CONTRIBUTORS_API_SERVICE, |
| 83 | + type GeographicalDistributionQueryParams, |
| 84 | +} from '~~/app/components/modules/widget/services/contributors.api.service'; |
| 85 | +
|
| 86 | +const props = withDefaults( |
| 87 | + defineProps<{ |
| 88 | + modelValue: boolean; |
| 89 | + selectedTab?: string; |
| 90 | + selectedMetric?: string; |
| 91 | + model: { includeCollaborations?: boolean }; |
| 92 | + }>(), |
| 93 | + { |
| 94 | + modelValue: false, |
| 95 | + selectedTab: 'organizations', |
| 96 | + selectedMetric: 'all:all', |
| 97 | + model: () => ({ includeCollaborations: false }), |
| 98 | + }, |
| 99 | +); |
| 100 | +
|
| 101 | +const emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>(); |
| 102 | +
|
| 103 | +const isDrawerOpen = computed({ |
| 104 | + get: () => props.modelValue, |
| 105 | + set: (value: boolean) => emit('update:modelValue', value), |
| 106 | +}); |
| 107 | +
|
| 108 | +const route = useRoute(); |
| 109 | +const activeTab = ref(props.selectedTab); |
| 110 | +const metric = ref(props.selectedMetric); |
| 111 | +const platform = computed(() => metric.value.split(':')[0]); |
| 112 | +const activityType = computed(() => metric.value.split(':')[1]); |
| 113 | +
|
| 114 | +const { isCollectionScope, startDate, endDate, selectedReposValues, project } = storeToRefs(useProjectStore()); |
| 115 | +
|
| 116 | +const params = computed<GeographicalDistributionQueryParams>(() => ({ |
| 117 | + projectSlug: isCollectionScope.value ? undefined : (route.params.slug as string), |
| 118 | + collectionSlug: isCollectionScope.value ? (route.params.slug as string) : undefined, |
| 119 | + type: activeTab.value, |
| 120 | + platform: platform.value, |
| 121 | + activityType: activityType.value, |
| 122 | + repos: selectedReposValues.value, |
| 123 | + startDate: startDate.value, |
| 124 | + endDate: endDate.value, |
| 125 | + includeCollaborations: props.model.includeCollaborations, |
| 126 | +})); |
| 127 | +
|
| 128 | +const { data, status, error } = CONTRIBUTORS_API_SERVICE.fetchGeographicalDistribution(params); |
| 129 | +
|
| 130 | +const geoMapData = computed<GeoMapData[] | undefined>(() => (data.value as GeoMapResponse)?.data); |
| 131 | +
|
| 132 | +const isEmpty = computed(() => isEmptyData(geoMapData.value as unknown as Record<string, unknown>[])); |
| 133 | +
|
| 134 | +const tabs = [ |
| 135 | + { |
| 136 | + label: 'Organizations', |
| 137 | + value: 'organizations', |
| 138 | + }, |
| 139 | + { |
| 140 | + label: 'Contributors', |
| 141 | + value: 'contributors', |
| 142 | + }, |
| 143 | +]; |
| 144 | +
|
| 145 | +const label = computed(() => (activeTab.value === 'contributors' ? 'Contributor' : 'Organization')); |
| 146 | +
|
| 147 | +watch(isDrawerOpen, (isOpen) => { |
| 148 | + if (isOpen) { |
| 149 | + activeTab.value = props.selectedTab; |
| 150 | + metric.value = props.selectedMetric; |
| 151 | + } |
| 152 | +}); |
| 153 | +</script> |
| 154 | + |
| 155 | +<script lang="ts"> |
| 156 | +export default { |
| 157 | + name: 'LfxGeographicalDistributionDrawer', |
| 158 | +}; |
| 159 | +</script> |
0 commit comments