Last active
July 27, 2020 12:57
-
-
Save alukos/c5760698f0c2eb1c7607877648c3ce55 to your computer and use it in GitHub Desktop.
Ex. vuetify + apollo
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
query Organizations ($where: organizations_bool_exp){ | |
organizations (where: $where, order_by: {id: asc}) { | |
id | |
name | |
phones_organizations (order_by: {phone_id:desc}) { | |
id | |
phone { | |
id | |
value | |
} | |
} | |
website | |
person | |
city { | |
id | |
name | |
} | |
address | |
clubs { | |
id | |
name | |
} | |
} | |
} |
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
<template> | |
<v-container> | |
<v-row> | |
<v-col cols="12" lg="10"> | |
<v-card outlined flat> | |
<v-card-text class="pb-0"> | |
<v-row> | |
<v-col cols="12" md="6" lg="4"> | |
<v-text-field | |
v-model="filter.search" | |
label="Организации" | |
placeholder="Поиск по таблице" | |
clearable | |
/> | |
</v-col> | |
<v-col cols="12" md="6" lg="4" class="py-0"> | |
<v-row> | |
<v-col class="align-self-end mb-2"> | |
{{ organizations.length }} результатов | |
</v-col> | |
<v-col class="d-flex justify-end"> | |
<v-btn @click="clearFilter" text>Очистить</v-btn> | |
</v-col> | |
</v-row> | |
</v-col> | |
</v-row> | |
</v-card-text> | |
</v-card> | |
</v-col> | |
<v-col cols="12" lg="2" class="text-right"> | |
<v-btn @click.stop="openOrganization(null)" color="primary" dark | |
>+ Организация</v-btn | |
> | |
</v-col> | |
</v-row> | |
<v-row> | |
<v-col> | |
<v-data-table | |
:headers="$options.headers" | |
:items="organizations" | |
class="table--fix_1th_col" | |
> | |
<template #item.name="{ item }"> | |
<v-btn @click="openOrganization(item)" text color="primary">{{ | |
item.name | |
}}</v-btn> | |
</template> | |
<template #item.phones_organizations="{ item }"> | |
<div v-for="po in item.phones_organizations" :key="po.id"> | |
{{ po.phone.value }} | |
</div> | |
</template> | |
<template #item.clubs="{ item }"> | |
<v-chip | |
v-for="club in item.clubs" | |
:key="club.id" | |
@click="openClub(club.id)" | |
small | |
class="mr-2 my-1" | |
> | |
{{ club.name }} | |
</v-chip> | |
<v-btn icon x-small @click="openClub(null)"> | |
<v-icon>mdi-plus</v-icon> | |
</v-btn> | |
</template> | |
</v-data-table> | |
</v-col> | |
</v-row> | |
<v-dialog | |
v-model="dialogOrganization" | |
scrollable | |
:fullscreen="!smAndUp" | |
max-width="700" | |
> | |
<formOrganization | |
:organization="organization" | |
v-model="dialogOrganization" | |
:cities="cities" | |
@close="closeOrganization" | |
></formOrganization> | |
</v-dialog> | |
<v-dialog | |
v-model="dialogClub" | |
scrollable | |
:fullscreen="!smAndUp" | |
max-width="700" | |
> | |
<formClub | |
:club="club" | |
v-model="dialogClub" | |
:cities="cities" | |
:organizations="organizations" | |
@close="closeClub" | |
></formClub> | |
</v-dialog> | |
</v-container> | |
</template> | |
<script> | |
const clone = require("rfdc")(); | |
import formOrganization from "./__formOrganization__"; | |
import formClub from "../clubs/__formClub__"; | |
const emptyFilter = { | |
search: null | |
}; | |
export default { | |
headers: [ | |
{ text: "Название", value: "name" }, | |
{ text: "Телефон", value: "phones_organizations", width: 150 }, | |
{ text: "email", value: "email" }, | |
{ text: "website", value: "website" }, | |
{ text: "Представитель", value: "person" }, | |
{ text: "Город", value: "city.name" }, | |
{ text: "Адрес", value: "address" }, | |
{ text: "Клубы", value: "clubs" } | |
], | |
components: { formOrganization, formClub }, | |
data() { | |
return { | |
filter: clone(emptyFilter), | |
searchDebounce: null, | |
organizations: [], | |
organization: null, | |
dialogOrganization: false, | |
cities: [], | |
clubId: null, | |
club: null, | |
dialogClub: false | |
}; | |
}, | |
apollo: { | |
organizations: { | |
query: require("./__gql__/organizations.gql"), | |
variables() { | |
return { | |
where: this.whereText | |
}; | |
} | |
}, | |
cities: { | |
query: require("./__gql__/cities.gql") | |
}, | |
club: { | |
query: require("./__gql__/club.gql"), | |
variables() { | |
return { id: this?.clubId }; | |
}, | |
skip() { | |
return !this?.clubId; | |
}, | |
update({ club }) { | |
return { | |
...club, | |
organization_id: club.organization?.id || null | |
}; | |
} | |
} | |
}, | |
watch: { | |
"filter.search"(val) { | |
clearTimeout(this._timerId); | |
this._timerId = setTimeout(() => { | |
this.searchDebounce = val; | |
}, 500); | |
} | |
}, | |
computed: { | |
whereText() { | |
return { | |
_or: (this.searchDebounce && [ | |
{ name: { _ilike: `%${this.searchDebounce}%` } }, | |
{ | |
phones_organizations: { | |
phone: { value: { _ilike: `%${this.searchDebounce}%` } } | |
} | |
}, | |
{ email: { _ilike: `%${this.searchDebounce}%` } }, | |
{ website: { _ilike: `%${this.searchDebounce}%` } }, | |
{ person: { _ilike: `%${this.searchDebounce}%` } }, | |
{ city: { name: { _ilike: `%${this.searchDebounce}%` } } }, | |
{ address: { _ilike: `%${this.searchDebounce}%` } }, | |
{ clubs: { name: { _ilike: `%${this.searchDebounce}%` } } } | |
]) || [null] | |
}; | |
} | |
}, | |
methods: { | |
openOrganization(organization) { | |
this.organization = organization; | |
this.dialogOrganization = true; | |
}, | |
closeOrganization() { | |
this.organization = null; | |
this.dialogOrganization = false; | |
}, | |
clearFilter() { | |
this.filter = clone(emptyFilter); | |
}, | |
openClub(id) { | |
if (id) { | |
this.clubId = id; | |
} else { | |
this.club = null; | |
} | |
this.dialogClub = true; | |
}, | |
closeClub() { | |
this.clubId = null; | |
this.club = null; | |
this.dialogClub = false; | |
} | |
} | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment