Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <template>
- <div>
- <heading class="mb-6">Clc Sync</heading>
- <ClcBar
- :isImportAllowed="isImportAllowed"
- :totalJobs="totalJobs"
- @searchCars="searchCars()"
- @importCars="importCars()"
- @clearFilters="clearFilters()"
- ></ClcBar>
- <div class="flex flex-row items-start p-4">
- <form class="flex flex-col items-start justify-center filters" v-on:keyup.enter="searchCars">
- <ClcRangedFilter header="Цена" filter-name="cost"></ClcRangedFilter>
- <ClcRangedFilter header="Год" filter-name="year"></ClcRangedFilter>
- <ClcRangedFilter header="Пробег" filter-name="mileage"></ClcRangedFilter>
- <ClcArrayFilter header="Марки" filter-name="mark" :original-values="marks"></ClcArrayFilter>
- <ClcArrayFilter header="Модели" filter-name="model" :original-values="models"></ClcArrayFilter>
- <ClcArrayFilter header="Источники" filter-name="import_source" :original-values="sources"></ClcArrayFilter>
- <ClcArrayFilter header="Регионы" filter-name="seller_region" :original-values="regions"></ClcArrayFilter>
- <div class="header">Параметры поиска</div>
- <div class="filter-box m-2 p-2 flex flex-col items-start justify-start">
- <div class="filter-field flex flex-row items-center justify-start m-1">
- <label class="m-1" for="limit">Выбрать машин:</label>
- <input
- type="number"
- class="filter-textbox m-1"
- v-model="limit"
- id="limit"
- >
- </div>
- <div class="m-1 randomize">
- <input
- type="checkbox"
- v-model="randomizeSelection"
- id="randomizeSelection"
- >
- <label for="randomizeSelection">Рандомизировать выборку</label>
- </div>
- </div>
- </form>
- <div class="search-results" v-if="searchResult.length > 0">
- <div class="left flex flex-row center justify-start m-1">
- <input
- type="checkbox"
- id="checkAll"
- class="m-1"
- @change="selectAll"
- v-model="selectedAll"
- :class="{inactive: selectedCustom}"
- />
- <label
- for="checkAll"
- class="m-1"
- :class="{inactive: selectedCustom}"
- >
- Все на всех страницах
- </label>
- </div>
- <ClcCar
- v-for="car in pagedCars"
- :car="car"
- :key="car.id"
- :excluded="excludedCars[car.id]"
- @carChecked="onCarChecked"
- ></ClcCar>
- <ClcPaging
- :current-page="currentPage"
- :items-per-page="itemsPerPage"
- :total-items="searchResult.length"
- @pageChanged="onPageChanged"
- ></ClcPaging>
- </div>
- <div class="search-results flex justify-center fixed" v-if="searchResult.length === 0 && !searchInProgress">
- <h3>{{ emptySearchMessage }}</h3>
- </div>
- <div class="search-results flex justify-center fixed" v-if="searchInProgress">
- <div class="loader">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
- <path fill="currentColor"
- d="M10 4.5a5.5 5.5 0 1 0 5.5 5.5A5.5 5.5 0 0 0 10 4.5zm4 3.6l-2.3.8a2 2 0 0 0-1.2-.8V5.6A4.5 4.5 0 0 1 14.1 8zM9 10a1 1 0 1 1 1 1 1 1 0 0 1-1-1zm.5-4.5v2.6a2 2 0 0 0-1.2.8L6 8.2a4.5 4.5 0 0 1 3.6-2.7zm-4 4.5a4.5 4.5 0 0 1 0-.9l2.5.8v.1a2 2 0 0 0 .5 1.3l-1.5 2A4.5 4.5 0 0 1 5.5 10zm2.3 4l1.5-2.1a2 2 0 0 0 1.5 0l1.4 2a4.3 4.3 0 0 1-4.4 0zm5.3-.7l-1.5-2A2 2 0 0 0 12 10v-.1l2.4-.8a4.5 4.5 0 0 1-1.3 4.2zM10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm0 18.5a8.5 8.5 0 1 1 8.5-8.5 8.5 8.5 0 0 1-8.5 8.5z"
- fill-rule="evenodd"/>
- </svg>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import api from "../api";
- import ClcCar from "./ClcCar.vue";
- import ClcBar from "./ClcBar.vue";
- import ClcPaging from "./ClcPaging.vue";
- import ClcRangedFilter from "./ClcRangedFilter.vue";
- import SelectedFilters from "../shared/selectedFilters";
- import ClcArrayFilter from "./ClcArrayFilter.vue";
- export default {
- components: {ClcArrayFilter, ClcRangedFilter, ClcPaging, ClcBar, ClcCar},
- data() {
- return {
- searchResult: [],
- excludedCars: {},
- itemsPerPage: 20,
- currentPage: 1,
- marks: [],
- models: [],
- sources: [],
- regions: [],
- emptySearchMessage: "Выберите фильтры для поиска",
- limit: 1000,
- randomizeSelection: true,
- selectedAll: true,
- selectedCustom: false,
- isImporting: true,
- totalJobs: 0,
- totalJobsIntervalHandle: null,
- totalJobsIntervalPeriod: 1000,
- searchInProgress: false,
- };
- },
- async mounted() {
- this.startTotalJobsMonitoring();
- await this.prepareFilters();
- },
- beforeDestroy() {
- if (this.totalJobsIntervalHandle) {
- clearInterval(this.totalJobsIntervalHandle);
- }
- },
- computed: {
- pagedCars() {
- const start = (this.currentPage - 1) * this.itemsPerPage;
- const end = this.currentPage * this.itemsPerPage;
- return this.searchResult.slice(start, end);
- },
- isImportAllowed() {
- return !this.isImporting
- && this.totalJobs === 0
- && this.searchResult.length > 0;
- }
- },
- methods: {
- async prepareFilters() {
- const filters = await api.getFilters();
- filters.marks.forEach((item, index) => {
- this.marks.push({
- id: index,
- filterKey: item.mark,
- name: item.mark,
- value: item.mark,
- textId: `mark${item.mark}`
- });
- });
- filters.models.forEach((item, index) => {
- this.models.push({
- id: index,
- filterKey: item.model,
- name: `${item.mark} ${item.model}`,
- value: item.model,
- textId: `model${item.mark}${item.model}`
- });
- });
- filters.sources.forEach((item, index) => {
- this.sources.push({
- id: item.id,
- filterKey: item.id,
- name: item.name,
- value: item.id,
- textId: `source${item.id}`
- });
- });
- filters.regions.forEach((item, index) => {
- this.regions.push({
- id: item.id,
- filterKey: item.id,
- name: item.name,
- value: item.id,
- textId: `region${item.id}`
- });
- });
- },
- async searchCars() {
- if (this.searchInProgress) {
- return;
- }
- if (SelectedFilters.isEmpty() && !confirm("Вы уверены, что хотите запустить поиск с пустыми фильтрами?")) {
- return;
- }
- const filters = SelectedFilters.getFilters();
- this.searchInProgress = true;
- filters.limit = this.limit;
- filters.randomize = this.randomizeSelection;
- this.clearSearch();
- this.searchResult = await api.search(filters);
- this.searchResult.forEach(car => this.$set(this.excludedCars, car.id, false));
- this.searchInProgress = false;
- if (window) {
- window.scrollTo(0, 0);
- }
- },
- async importCars() {
- if (this.isImporting) {
- return;
- }
- this.isImporting = true;
- const ids = this
- .searchResult
- .map(car => car.id)
- .filter(id => this.excludedCars[id] === false);
- await api
- .import(ids)
- .then(Nova.success('Синхронизация запущена'));
- },
- async getTotalJobs() {
- const status = await api.getJobStatus();
- this.totalJobs = status.total;
- this.isImporting = this.totalJobs !== 0;
- },
- startTotalJobsMonitoring() {
- if (this.totalJobsIntervalHandle) {
- return;
- }
- this.totalJobsIntervalHandle = setInterval(
- () => this.getTotalJobs(),
- this.totalJobsIntervalPeriod
- );
- },
- clearSearch() {
- this.emptySearchMessage = "Ничего не найдено";
- this.currentPage = 1;
- this.excludedCars = {};
- this.selectedCustom = false;
- this.selectedAll = true;
- this.searchResult = [];
- },
- selectAll(value) {
- this.selectedCustom = false;
- this.searchResult.forEach(car => this.$set(this.excludedCars, car.id, !this.selectedAll));
- },
- onPageChanged(pageNumber) {
- this.currentPage = pageNumber;
- },
- onCarChecked(carId, excluded) {
- this.selectedCustom = true;
- this.$set(this.excludedCars, carId, excluded);
- },
- clearFilters() {
- SelectedFilters.clearFilters();
- },
- probablyTooMuchToSearch() {
- return
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .header {
- font-weight: bold;
- }
- .filters {
- .filter-box {
- border: 1px solid #f1f3f6;
- width: 360px;
- .filter-textbox {
- width: 160px;
- outline: 1px solid #ddd;
- margin-top: 2px;
- height: 22px;
- &:focus {
- outline: 1px solid #aaa;
- }
- }
- }
- .randomize {
- margin-top: 20px;
- }
- }
- .search-results {
- width: 100%;
- margin-left: 20px;
- }
- .inactive {
- opacity: 50%;
- }
- .loader {
- width: 100px;
- height: 100px;
- animation-name: spin;
- animation-duration: 5000ms;
- animation-iteration-count: infinite;
- animation-timing-function: linear;
- }
- .px-view {
- >div {
- margin-left: -30px;
- margin-right: -30px;
- }
- }
- </style>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement