Skip to content

Instantly share code, notes, and snippets.

@alukos
Last active July 27, 2020 12:57
Show Gist options
  • Save alukos/c5760698f0c2eb1c7607877648c3ce55 to your computer and use it in GitHub Desktop.
Save alukos/c5760698f0c2eb1c7607877648c3ce55 to your computer and use it in GitHub Desktop.
Ex. vuetify + apollo
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
}
}
email
website
person
city {
id
name
}
address
clubs {
id
name
}
}
}
<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