cartodb-4.42/lib/assets/javascripts/new-dashboard/pages/Data/Catalog.vue
2024-04-06 05:25:13 +00:00

265 lines
7.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<section class="catalog-section">
<div class="container grid">
<div class="full-width">
<SectionTitle class="grid-cell">
<template slot="icon">
<img src="../../assets/icons/section-title/catalog.svg" width="18" height="20" />
</template>
<template slot="title">
<VisualizationsTitle :defaultTitle="$t('DataPage.tabs.catalog')"/>
</template>
</SectionTitle>
</div>
</div>
<div class="container grid">
<div class="grid-cell grid-cell--col12">
<div class="grid u-flex__justify--center">
<div
class="u-pr--10 grid-cell--col4 grid-cell--col12--tablet dynamic-filtering"
:class="{ 'filter-expanded': filterDetail }"
>
<div class="header-mobile">
<img
@click="hideFilters()"
src="../../assets/icons/catalog/close-filters.svg"
alt="Close"
/>
</div>
<FilterBox
v-for="category in filterCategories"
:key="category"
class="u-mt--36--tablet"
:title="getFilterLabel(category)"
:filter="category"
:placeholder="category"
></FilterBox>
</div>
<div class="grid-cell grid-cell--col8 grid-cell--col12--tablet">
<SearchBox></SearchBox>
<FilterSummary
class="u-mt--4"
v-on:toggle-filter-detail="toggleFilterDetail()"
></FilterSummary>
<div v-if="loading">
<LoadingBar></LoadingBar>
</div>
<div v-if="datasetsList.length > 0" class="results-container u-mb--48">
<ul class="datasets-list">
<DatasetListItem
v-for="dataset in datasetsList"
:key="dataset.slug"
:dataset="dataset"
></DatasetListItem>
</ul>
<Pager :count="count" :currentPage="currentPage" @goToPage="goToPage" class="pager u-mt--48"></Pager>
</div>
<div v-else-if="!loading">
<div class="empty-result u-mt--36">
<img :src="icon_by_environment('empty-search.svg')" alt="No results" />
<h3 class="title is-body is-txtNavyBlue u-mt--16">
We couldnt find anything for your search:
</h3>
<p class="text is-caption is-txtNavyBlue u-mt--16">
Try again with another keyword or clear your filters
</p>
<hr class="u-mt--24" />
<p class="text is-caption is-txtNavyBlue u-mt--24">
Still cant find what youre looking for? <br />Get help from our
team
</p>
<Button
class="u-mt--24"
@click.native="navigateToContact()"
>Contact us</Button
>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script>
import SectionTitle from 'new-dashboard/components/SectionTitle';
import { mapState } from 'vuex';
import Button from 'new-dashboard/components/Button';
import DatasetListItem from 'new-dashboard/components/Catalog/browser/DatasetListItem';
import FilterBox from 'new-dashboard/components/Catalog/browser/FilterBox';
import FilterSummary from 'new-dashboard/components/Catalog/browser/FilterSummary';
import LoadingBar from 'new-dashboard/components/Catalog/browser/LoadingBar';
import Pager from 'new-dashboard/components/Catalog/browser/Pager';
import SearchBox from 'new-dashboard/components/Catalog/browser/SearchBox';
import { filtersMetadata } from 'new-dashboard/utils/catalog/constants';
import { toTitleCase } from 'new-dashboard/utils/catalog/string-to-title-case';
import icon_by_environment from 'new-dashboard/mixins/catalog/icon_by_environment';
import VisualizationsTitle from 'new-dashboard/components/VisualizationsTitle';
export default {
name: 'CatalogPage',
mixins: [icon_by_environment],
components: {
SectionTitle,
VisualizationsTitle,
Button,
DatasetListItem,
FilterBox,
FilterSummary,
LoadingBar,
Pager,
SearchBox
},
data () {
return {
filterDetail: false
};
},
watch: {
filter: {
deep: true,
handler () {
this.fetchDatasetsList();
}
},
currentPage: {
handler () {
window.scrollTo(0, 0);
}
}
},
computed: {
...mapState({
datasetsList: state => state.catalog.datasetsList,
count: state => state.catalog.datasetsListCount,
loading: state => state.catalog.isFetching,
filtersAvailable: state => state.catalog.filtersAvailable,
filter: state => state.catalog.filter,
currentPage: state => state.catalog.filter.page
}),
filterCategories () {
return Object.keys(this.filtersAvailable).sort((a, b) => {
const orderA = filtersMetadata[a] ? filtersMetadata[a].order : Number.MAX_VALUE;
const orderB = filtersMetadata[b] ? filtersMetadata[b].order : Number.MAX_VALUE;
return orderA - orderB;
});
}
},
methods: {
initFilters () {
const query = this.$route.query;
if (Object.keys(query).length) {
this.$store.dispatch('catalog/initFilter', this.$route.query);
}
},
fetchDatasetsList () {
this.$store.dispatch('catalog/fetchDatasetsList');
},
toggleFilterDetail () {
this.filterDetail = !this.filterDetail;
},
hideFilters () {
this.filterDetail = false;
},
getFilterLabel (filterId) {
return filtersMetadata[filterId]
? filtersMetadata[filterId].label
: toTitleCase(filterId);
},
navigateToContact () {
window.open('https://carto.com/contact/', '_blank');
},
goToPage (pageNum) {
this.$store.dispatch('catalog/setPage', pageNum);
}
},
mounted () {
this.initFilters();
this.fetchDatasetsList();
}
};
</script>
<style scoped lang="scss">
@import 'new-dashboard/styles/variables';
.catalog-section {
min-height: 640px;
margin-top: 64px;
&__filter {
justify-content: space-between;
height: 168px;
&--dropdown {
position: relative;
}
}
}
.full-width {
width: 100%;
}
.results-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
.datasets-list {
width: 100%;
margin-top: 12px;
border-top: 1px solid $neutral--300;
}
}
.empty-result {
padding: 64px;
border-radius: 12px;
background-color: $neutral--100;
text-align: center;
hr {
width: 78px;
border: 1px solid $neutral--400;
margin-left: auto;
margin-right: auto;
}
}
.header-mobile {
display: none;
}
@media (max-width: $layout-tablet) {
.dynamic-filtering {
position: fixed;
z-index: 11;
top: 100%;
width: 100%;
height: 100%;
overflow: scroll;
transition: top 0.2s ease-out;
background-color: $white;
&.filter-expanded {
top: 0;
}
}
.header-mobile {
display: block;
position: fixed;
z-index: 1;
right: 0;
width: 100%;
padding: 20px 20px 4px;
background-color: $white;
text-align: right;
}
}
</style>