Customers.vue
656 lines
| 1 | <template> |
| 2 | <div class="am-wrap"> |
| 3 | <div id="am-customers" class="am-body"> |
| 4 | |
| 5 | <!-- Page Header --> |
| 6 | <page-header :customersTotal="options.count" @newCustomerBtnClicked="showDialogNewCustomer()"></page-header> |
| 7 | |
| 8 | <!-- Spinner --> |
| 9 | <div class="am-spinner am-section" v-show="!fetched"> |
| 10 | <img :src="$root.getUrl + 'public/img/spinner.svg'"/> |
| 11 | </div> |
| 12 | |
| 13 | <!-- Empty State --> |
| 14 | <EmptyState |
| 15 | :visible="fetched && customers.length === 0 && !filterApplied && fetchedFiltered" |
| 16 | :title="$root.labels.no_customers_yet" |
| 17 | :description="$root.labels.click_add_customers" |
| 18 | :importing="$root.labels.import_customers" |
| 19 | @import="dialogImport = true" |
| 20 | > |
| 21 | </EmptyState> |
| 22 | |
| 23 | <!-- Customers --> |
| 24 | <div v-show="fetched && (customers.length !== 0 || customers.length === 0 && filterApplied || !fetchedFiltered)"> |
| 25 | |
| 26 | <!-- Filter --> |
| 27 | <div class="am-customers-filter am-section"> |
| 28 | <el-form class="demo-form-inline" :action="exportAction" method="POST"> |
| 29 | <el-row :gutter="10"> |
| 30 | |
| 31 | <!-- Global Search --> |
| 32 | <el-col :lg="$root.settings.roles.enableNoShowTag ? 13 : 15" :md="$root.settings.roles.enableNoShowTag ? 12 : 14"> |
| 33 | <div class="am-search"> |
| 34 | <el-input |
| 35 | :placeholder="searchPlaceholder" |
| 36 | v-model="params.search" |
| 37 | name="search" |
| 38 | > |
| 39 | </el-input> |
| 40 | </div> |
| 41 | </el-col> |
| 42 | |
| 43 | <!-- Sort --> |
| 44 | <transition name="fade"> |
| 45 | <el-col :lg="7" :md="8" :sm="20"> |
| 46 | <el-form-item> |
| 47 | <el-select |
| 48 | v-model="params.sort" |
| 49 | :placeholder="$root.labels.sort" |
| 50 | class="sort" |
| 51 | @change="filterData" |
| 52 | name="sort" |
| 53 | clearable |
| 54 | > |
| 55 | <el-option |
| 56 | v-for="option in options.sort" |
| 57 | :key="option.value" |
| 58 | :label="option.label" |
| 59 | :value="option.value" |
| 60 | > |
| 61 | </el-option> |
| 62 | </el-select> |
| 63 | </el-form-item> |
| 64 | </el-col> |
| 65 | </transition> |
| 66 | |
| 67 | |
| 68 | <transition name="fade"> |
| 69 | <el-col :sm="4" :md="4" :lg="2" v-if="$root.settings.roles.enableNoShowTag"> |
| 70 | <el-form-item> |
| 71 | <el-select |
| 72 | v-model="params.noShow" |
| 73 | clearable |
| 74 | class="am-customers-filter-no-show" |
| 75 | @change="filterData" |
| 76 | :placeholder="$root.labels['no-show']" |
| 77 | > |
| 78 | <el-option |
| 79 | v-for="item in noShowStatuses" |
| 80 | :key="item.count" |
| 81 | :value="item.count" |
| 82 | :label="' '" |
| 83 | style="display: flex; justify-content: center; align-items: center; margin-top: 5px; margin-bottom: 5px" |
| 84 | > |
| 85 | <img style="width: 24px; height: 24px" class="svg-amelia" :alt="'no-show-'+item.type" :src="$root.getUrl+'public/img/am-user-' + item.type + '-no-show.svg'"/> |
| 86 | </el-option> |
| 87 | |
| 88 | <template v-if="params.noShow && noShowStatuses.find(n => n.count === params.noShow)" #prefix class="am-no-show-selected"> |
| 89 | <img style="width: 24px; height: 24px" class="svg-amelia" :alt="'no-show-'+noShowStatuses.find(n => n.count === params.noShow).type" :src="$root.getUrl+'public/img/am-user-' + noShowStatuses.find(n => n.count === params.noShow).type + '-no-show.svg'"/> |
| 90 | </template> |
| 91 | |
| 92 | </el-select> |
| 93 | </el-form-item> |
| 94 | </el-col> |
| 95 | |
| 96 | </transition> |
| 97 | |
| 98 | |
| 99 | <el-col :lg="2" :md="3" :sm="4" class="am-buttons"> |
| 100 | <!-- Export --> |
| 101 | <el-tooltip placement="top"> |
| 102 | <div slot="content" v-html="$root.labels.export_tooltip_customers"></div> |
| 103 | <el-button |
| 104 | class="button-export am-button-icon" |
| 105 | @click="dialogExport = true" |
| 106 | > |
| 107 | <img class="svg-amelia" alt="Export" :src="$root.getUrl+'public/img/export.svg'"/> |
| 108 | </el-button> |
| 109 | </el-tooltip> |
| 110 | <!-- Import --> |
| 111 | <el-tooltip placement="top"> |
| 112 | <div slot="content" v-html="$root.labels.import_tooltip_customers"></div> |
| 113 | <el-button |
| 114 | class="button-export am-button-icon" |
| 115 | @click="dialogImport = true" |
| 116 | > |
| 117 | <img class="svg-amelia" alt="Import" :src="$root.getUrl+'public/img/import.svg'"/> |
| 118 | </el-button> |
| 119 | </el-tooltip> |
| 120 | </el-col> |
| 121 | </el-row> |
| 122 | |
| 123 | <!-- Dialog Export --> |
| 124 | <transition name="slide"> |
| 125 | <el-dialog |
| 126 | class="am-side-dialog am-dialog-export" |
| 127 | :visible.sync="dialogExport" |
| 128 | :show-close="false" |
| 129 | v-if="dialogExport" |
| 130 | :close-on-click-modal="false" |
| 131 | > |
| 132 | <dialog-export |
| 133 | :data="Object.assign(params, exportParams)" |
| 134 | :action="$root.getAjaxUrl + '/report/customers'" |
| 135 | @updateAction="(action) => {this.exportAction = action}" |
| 136 | @closeDialogExport="dialogExport = false" |
| 137 | > |
| 138 | </dialog-export> |
| 139 | </el-dialog> |
| 140 | </transition> |
| 141 | |
| 142 | </el-form> |
| 143 | </div> |
| 144 | |
| 145 | <!-- No Results --> |
| 146 | <div class="am-empty-state am-section" |
| 147 | v-show="fetched && customers.length === 0 && filterApplied && fetchedFiltered"> |
| 148 | <img :src="$root.getUrl+'public/img/emptystate.svg'"> |
| 149 | <h2>{{ $root.labels.no_results }}</h2> |
| 150 | </div> |
| 151 | |
| 152 | <!-- Customer List --> |
| 153 | <div class="am-customers am-section" v-show="fetchedFiltered && customers.length !== 0"> |
| 154 | |
| 155 | <!-- Customer List Header --> |
| 156 | <div class="am-customers-list-head"> |
| 157 | <el-row> |
| 158 | <el-col :lg="12"> |
| 159 | <el-row :gutter="10" class="am-customers-flex-row-middle-align"> |
| 160 | <el-col |
| 161 | v-if="$root.settings.capabilities.canDelete === true" |
| 162 | :lg="2" |
| 163 | :md="2" |
| 164 | > |
| 165 | <p> |
| 166 | <el-checkbox |
| 167 | v-model="checkCustomerData.allChecked" |
| 168 | @change="checkCustomerData = handleCheckAll(customers, checkCustomerData)"> |
| 169 | </el-checkbox> |
| 170 | </p> |
| 171 | </el-col> |
| 172 | <el-col :lg="8" :md="8"> |
| 173 | <p>{{ $root.labels.customer }}:</p> |
| 174 | </el-col> |
| 175 | <el-col :lg="8" :md="8"> |
| 176 | <p>{{ $root.labels.wp_user }}:</p> |
| 177 | </el-col> |
| 178 | <el-col :lg="6" :md="6"> |
| 179 | <p>{{ $root.labels.phone }}:</p> |
| 180 | </el-col> |
| 181 | </el-row> |
| 182 | </el-col> |
| 183 | |
| 184 | <el-col :lg="12"> |
| 185 | <el-row :gutter="10" class="am-customers-flex-row-middle-align"> |
| 186 | <el-col :lg="0" :md="1"></el-col> |
| 187 | <el-col :lg="10" :md="10"> |
| 188 | <p>{{ $root.labels.note }}:</p> |
| 189 | </el-col> |
| 190 | <el-col :lg="10" :md="10"> |
| 191 | <p>{{ $root.labels.last_appointment }}:</p> |
| 192 | </el-col> |
| 193 | <el-col :lg="4" :md="4"></el-col> |
| 194 | </el-row> |
| 195 | </el-col> |
| 196 | |
| 197 | </el-row> |
| 198 | </div> |
| 199 | |
| 200 | <!-- Customer List Content --> |
| 201 | <div class="am-customers-list"> |
| 202 | |
| 203 | <!-- Customers --> |
| 204 | <el-collapse> |
| 205 | <el-collapse-item |
| 206 | v-for="(customer, index) in customers" |
| 207 | :key="customer.id" |
| 208 | :name="customer.id" |
| 209 | class="am-customer" |
| 210 | :class="customer.status === 'blocked' ? 'am-customer-blocked' : ''" |
| 211 | > |
| 212 | <template slot="title"> |
| 213 | <div class="am-customer-data"> |
| 214 | <el-row :gutter="10"> |
| 215 | |
| 216 | <el-col :lg="12"> |
| 217 | <el-row :gutter="10" class="am-customers-flex-row-middle-align"> |
| 218 | |
| 219 | <!-- Checkbox --> |
| 220 | <el-col :lg="2" :sm="1" v-if="$root.settings.capabilities.canDelete === true"> |
| 221 | <span @click.stop> |
| 222 | <el-checkbox |
| 223 | v-model="customer.checked" |
| 224 | @change="checkCustomerData = handleCheckSingle(customers, checkCustomerData)"> |
| 225 | </el-checkbox> |
| 226 | </span> |
| 227 | </el-col> |
| 228 | |
| 229 | <!-- Customer Name --> |
| 230 | <el-col :lg="8" :sm="8"> |
| 231 | <p class="am-col-title">{{ $root.labels.customer }}:</p> |
| 232 | <h3 :class="getNoShowClass(null, null, customer, customer.status)"> |
| 233 | {{ customer.firstName + ' ' + customer.lastName }} |
| 234 | </h3> |
| 235 | <el-tooltip class="item" :content=" customer.email" placement="top"> |
| 236 | <span>{{ customer.email }}</span> |
| 237 | </el-tooltip> |
| 238 | </el-col> |
| 239 | |
| 240 | <!-- WordPress User --> |
| 241 | <el-col :lg="8" :sm="8"> |
| 242 | <p class="am-col-title">{{ $root.labels.wp_user }}:</p> |
| 243 | <div class="am-assigned"> |
| 244 | <img :src="customer.wpUserPhotoUrl"/> |
| 245 | <el-tooltip class="item" :content="customer.wpName" placement="top"> |
| 246 | <h4>{{ customer.wpName }}</h4> |
| 247 | </el-tooltip> |
| 248 | </div> |
| 249 | </el-col> |
| 250 | |
| 251 | <!-- Phone --> |
| 252 | <el-col :lg="6" :sm="7"> |
| 253 | <p class="am-col-title">{{ $root.labels.phone }}:</p> |
| 254 | <el-tooltip class="item" :content="customer.phone" placement="top"> |
| 255 | <h4>{{ customer.phone }}</h4> |
| 256 | </el-tooltip> |
| 257 | </el-col> |
| 258 | |
| 259 | </el-row> |
| 260 | </el-col> |
| 261 | |
| 262 | <el-col :lg="12"> |
| 263 | <el-row :gutter="10" class="am-customers-flex-row-middle-align"> |
| 264 | <el-col :lg="0" :sm="1" class="hide-on-mobile"></el-col> |
| 265 | |
| 266 | <!-- Note --> |
| 267 | <el-col :lg="10" :sm="8" class="hide-on-mobile"> |
| 268 | <p class="am-col-title">{{ $root.labels.note }}:</p> |
| 269 | <p>{{ customer.note ? customer.note.substring(0, 20)+'...' : ''}}</p> |
| 270 | </el-col> |
| 271 | |
| 272 | <!-- Last Appointment --> |
| 273 | <el-col :lg="10" :sm="8"> |
| 274 | <p class="am-col-title">{{ $root.labels.last_appointment }}:</p> |
| 275 | <h4 v-if="customer.lastAppointment"> |
| 276 | {{ getFrontedFormattedDateTime(customer.lastAppointment) }} |
| 277 | </h4> |
| 278 | <h4 v-else>/</h4> |
| 279 | </el-col> |
| 280 | |
| 281 | <!-- Edit Button --> |
| 282 | <el-col :lg="4" :sm="7" class="align-right"> |
| 283 | <div @click.stop> |
| 284 | <el-button v-if="$root.settings.capabilities.canWrite === true" @click="showDialogEditCustomer(index)">{{ $root.labels.edit }}</el-button> |
| 285 | </div> |
| 286 | </el-col> |
| 287 | |
| 288 | </el-row> |
| 289 | </el-col> |
| 290 | |
| 291 | </el-row> |
| 292 | </div> |
| 293 | </template> |
| 294 | |
| 295 | <!-- Collapsed Data --> |
| 296 | <div class="am-customer-details"> |
| 297 | <el-row> |
| 298 | |
| 299 | <el-col :md="12"> |
| 300 | |
| 301 | <!-- Total Appointments --> |
| 302 | <el-row :gutter="10" class="am-customers-flex-row-top-align"> |
| 303 | <el-col :md="2" :sm="1"></el-col> |
| 304 | <el-col :md="10" :sm="10"> |
| 305 | <p class="am-data">{{ $root.labels.total_appointments }}:</p> |
| 306 | </el-col> |
| 307 | <el-col :md="10" :sm="13"> |
| 308 | <p class="am-value">{{ customer.totalAppointments }}</p> |
| 309 | </el-col> |
| 310 | </el-row> |
| 311 | |
| 312 | <!-- Last Appointment --> |
| 313 | <el-row :gutter="10" class="am-customers-flex-row-top-align"> |
| 314 | <el-col :md="2" :sm="1"></el-col> |
| 315 | <el-col :md="10" :sm="10"> |
| 316 | <p class="am-data">{{ $root.labels.last_appointment }}:</p> |
| 317 | </el-col> |
| 318 | <el-col :md="10" :sm="13"> |
| 319 | <p class="am-value" v-if="customer.lastAppointment"> |
| 320 | {{ getFrontedFormattedDateTime(customer.lastAppointment) }} |
| 321 | </p> |
| 322 | <h4 v-else>/</h4> |
| 323 | </el-col> |
| 324 | </el-row> |
| 325 | |
| 326 | </el-col> |
| 327 | |
| 328 | <el-col :md="12"> |
| 329 | |
| 330 | <!-- Note --> |
| 331 | <el-row :gutter="10" class="am-customers-flex-row-top-align"> |
| 332 | <el-col :md="0" :sm="1"></el-col> |
| 333 | <el-col :md="10" :sm="10"> |
| 334 | <p class="am-data">{{ $root.labels.note }}:</p> |
| 335 | </el-col> |
| 336 | <el-col :md="14" :sm="13"> |
| 337 | <p class="am-value">{{ customer.note }}</p> |
| 338 | </el-col> |
| 339 | </el-row> |
| 340 | |
| 341 | </el-col> |
| 342 | |
| 343 | </el-row> |
| 344 | </div> |
| 345 | |
| 346 | </el-collapse-item> |
| 347 | </el-collapse> |
| 348 | |
| 349 | </div> |
| 350 | </div> |
| 351 | |
| 352 | <!-- Selected Popover Delete --> |
| 353 | <group-delete |
| 354 | name="users/customers" |
| 355 | :entities="customers" |
| 356 | :checkGroupData="checkCustomerData" |
| 357 | :confirmDeleteMessage="$root.labels.confirm_delete_customer" |
| 358 | :successMessage="{single: $root.labels.customer_deleted, multiple: $root.labels.customers_deleted}" |
| 359 | :errorMessage="{single: $root.labels.customer_not_deleted, multiple: $root.labels.customers_not_deleted}" |
| 360 | @groupDeleteCallback="groupDeleteCallback" |
| 361 | > |
| 362 | </group-delete> |
| 363 | |
| 364 | <!-- Pagination --> |
| 365 | <pagination-block |
| 366 | :params="params" |
| 367 | :show="$root.settings.general.itemsPerPageBackEnd" |
| 368 | :count="options.filteredCount" |
| 369 | :label="$root.labels.customers_lower" |
| 370 | :visible="fetched && customers.length !== 0 && fetchedFiltered" |
| 371 | @change="filterData" |
| 372 | > |
| 373 | </pagination-block> |
| 374 | |
| 375 | <!-- Content Spinner --> |
| 376 | <div class="am-spinner am-section" v-show="!fetchedFiltered"> |
| 377 | <img :src="$root.getUrl+'public/img/spinner.svg'"/> |
| 378 | </div> |
| 379 | |
| 380 | </div> |
| 381 | |
| 382 | <!-- Dialog Import --> |
| 383 | <transition name="slide"> |
| 384 | <el-dialog |
| 385 | class="am-side-dialog am-dialog-import" |
| 386 | :visible.sync="dialogImport" |
| 387 | :show-close="false" |
| 388 | v-if="dialogImport" |
| 389 | :close-on-click-modal="false" |
| 390 | > |
| 391 | <dialog-import |
| 392 | :fields="fields" |
| 393 | :action="$root.getAjaxUrl + '/import/customers'" |
| 394 | :required-fields="requiredFields" |
| 395 | :values-overwrite="valuesOverwrite" |
| 396 | :values-saved="valuesSaved" |
| 397 | @closeDialogImport="dialogImport = false" |
| 398 | @getEntities="getCustomers" |
| 399 | > |
| 400 | </dialog-import> |
| 401 | </el-dialog> |
| 402 | </transition> |
| 403 | |
| 404 | <!-- Button New --> |
| 405 | <div v-if="$root.settings.capabilities.canWrite === true" id="am-button-new" class="am-button-new"> |
| 406 | <el-button id="am-plus-symbol" type="primary" icon="el-icon-plus" @click="showDialogNewCustomer()"></el-button> |
| 407 | </div> |
| 408 | |
| 409 | <!-- Dialog New Customer --> |
| 410 | <transition name="slide"> |
| 411 | <el-dialog |
| 412 | :close-on-click-modal="false" |
| 413 | class="am-side-dialog" |
| 414 | :visible.sync="dialogCustomer" |
| 415 | :show-close="false" |
| 416 | v-if="dialogCustomer"> |
| 417 | <dialog-customer |
| 418 | :customer="customer" |
| 419 | @saveCallback="updateCustomerCallback" |
| 420 | @closeDialog="dialogCustomer = false" |
| 421 | > |
| 422 | </dialog-customer> |
| 423 | </el-dialog> |
| 424 | </transition> |
| 425 | |
| 426 | <!-- Help Button --> |
| 427 | <el-col :md="6" class=""> |
| 428 | <a class="am-help-button" href="https://wpamelia.com/customers/" target="_blank" rel="nofollow"> |
| 429 | <i class="el-icon-question"></i> {{ $root.labels.need_help }}? |
| 430 | </a> |
| 431 | </el-col> |
| 432 | |
| 433 | <!-- <dialog-new-customize></dialog-new-customize>--> |
| 434 | |
| 435 | </div> |
| 436 | </div> |
| 437 | </template> |
| 438 | |
| 439 | <script> |
| 440 | import DialogCustomer from './DialogCustomer.vue' |
| 441 | import DialogExport from '../parts/DialogExport.vue' |
| 442 | import DialogImport from '../parts/DialogImport.vue' |
| 443 | import PageHeader from '../parts/PageHeader.vue' |
| 444 | import imageMixin from '../../../js/common/mixins/imageMixin' |
| 445 | import dateMixin from '../../../js/common/mixins/dateMixin' |
| 446 | import notifyMixin from '../../../js/backend/mixins/notifyMixin' |
| 447 | import checkMixin from '../../../js/backend/mixins/checkMixin' |
| 448 | import customerMixin from '../../../js/backend/mixins/customerMixin' |
| 449 | import GroupDelete from '../parts/GroupDelete.vue' |
| 450 | import PaginationBlock from '../parts/PaginationBlock.vue' |
| 451 | //import DialogNewCustomize from '../parts/DialogNewCustomize.vue' |
| 452 | |
| 453 | export default { |
| 454 | |
| 455 | mixins: [imageMixin, dateMixin, notifyMixin, checkMixin, customerMixin], |
| 456 | |
| 457 | data () { |
| 458 | return { |
| 459 | noShowStatuses: [ |
| 460 | { |
| 461 | count: 1, |
| 462 | type: 'single' |
| 463 | }, |
| 464 | { |
| 465 | count: 2, |
| 466 | type: 'double' |
| 467 | }, |
| 468 | { |
| 469 | count: 3, |
| 470 | type: 'multiple' |
| 471 | } |
| 472 | ], |
| 473 | fields: [ |
| 474 | {label: this.$root.labels.first_name, value: 'firstName'}, |
| 475 | {label: this.$root.labels.last_name, value: 'lastName'}, |
| 476 | {label: this.$root.labels.email, value: 'email'}, |
| 477 | {label: this.$root.labels.phone, value: 'phone'}, |
| 478 | {label: this.$root.labels.gender, value: 'gender'}, |
| 479 | {label: this.$root.labels.birthday, value: 'birthday'}, |
| 480 | {label: this.$root.labels.note, value: 'note'}, |
| 481 | {label: this.$root.labels.dont_import, value: 'dontImport'} |
| 482 | ], |
| 483 | requiredFields: [ |
| 484 | {label: this.$root.labels.first_name, value: 'firstName'}, |
| 485 | {label: this.$root.labels.last_name, value: 'lastName'} |
| 486 | ], |
| 487 | valuesSaved: [this.$root.labels.number_of_appointments, this.$root.labels.date_created, this.$root.labels.last_appointment_date, this.$root.labels.all_customer_appointments], |
| 488 | valuesOverwrite: [this.$root.labels.first_name, this.$root.labels.last_name, this.$root.labels.phone, this.$root.labels.gender, this.$root.labels.birthday, this.$root.labels.note], |
| 489 | checkCustomerData: { |
| 490 | toaster: false, |
| 491 | allChecked: false |
| 492 | }, |
| 493 | fetchedFiltered: false, |
| 494 | customers: [], |
| 495 | dialogExport: false, |
| 496 | dialogImport: false, |
| 497 | isIndeterminate: true, |
| 498 | customer: null, |
| 499 | fetched: false, |
| 500 | params: { |
| 501 | page: 1, |
| 502 | sort: '', |
| 503 | search: '', |
| 504 | noShow: '' |
| 505 | }, |
| 506 | |
| 507 | exportParams: { |
| 508 | fields: [ |
| 509 | {label: this.$root.labels.first_name, value: 'firstName', checked: true}, |
| 510 | {label: this.$root.labels.last_name, value: 'lastName', checked: true}, |
| 511 | {label: this.$root.labels.email, value: 'email', checked: true}, |
| 512 | {label: this.$root.labels.phone, value: 'phone', checked: true}, |
| 513 | {label: this.$root.labels.gender, value: 'gender', checked: true}, |
| 514 | {label: this.$root.labels.date_of_birth, value: 'birthday', checked: true}, |
| 515 | {label: this.$root.labels.customer_note, value: 'note', checked: true}, |
| 516 | {label: this.$root.labels.last_appointment, value: 'lastAppointment', checked: true}, |
| 517 | {label: this.$root.labels.total_appointments, value: 'totalAppointments', checked: true}, |
| 518 | {label: this.$root.labels.pending_appointments, value: 'pendingAppointments', checked: true} |
| 519 | ] |
| 520 | }, |
| 521 | exportAction: '', |
| 522 | |
| 523 | searchPlaceholder: this.$root.labels.customers_search_placeholder, |
| 524 | timer: null, |
| 525 | options: { |
| 526 | filteredCount: 0, |
| 527 | fetched: false, |
| 528 | count: 0, |
| 529 | sort: [ |
| 530 | { |
| 531 | value: 'customer', |
| 532 | label: this.$root.labels.name_ascending |
| 533 | }, |
| 534 | { |
| 535 | value: '-customer', |
| 536 | label: this.$root.labels.name_descending |
| 537 | }, |
| 538 | { |
| 539 | value: 'last-appointment', |
| 540 | label: this.$root.labels.last_appointment_ascending |
| 541 | }, |
| 542 | { |
| 543 | value: '-last-appointment', |
| 544 | label: this.$root.labels.last_appointment_descending |
| 545 | } |
| 546 | ] |
| 547 | } |
| 548 | } |
| 549 | }, |
| 550 | |
| 551 | created () { |
| 552 | this.fetchData() |
| 553 | }, |
| 554 | |
| 555 | mounted () { |
| 556 | this.inlineSVG() |
| 557 | }, |
| 558 | |
| 559 | methods: { |
| 560 | fetchData () { |
| 561 | this.fetched = false |
| 562 | this.getCustomers() |
| 563 | }, |
| 564 | |
| 565 | filterData () { |
| 566 | this.fetchedFiltered = false |
| 567 | this.getCustomers() |
| 568 | }, |
| 569 | |
| 570 | getCustomers () { |
| 571 | Object.keys(this.params).forEach((key) => (!this.params[key]) && delete this.params[key]) |
| 572 | |
| 573 | this.$http.get(`${this.$root.getAjaxUrl}/users/customers`, { |
| 574 | params: this.params |
| 575 | }) |
| 576 | .then(response => { |
| 577 | let customers = response.data.data.users |
| 578 | |
| 579 | customers.forEach(function (cusItem) { |
| 580 | cusItem.checked = false |
| 581 | |
| 582 | if (cusItem.translations) { |
| 583 | cusItem.language = JSON.parse(cusItem.translations).defaultLanguage |
| 584 | } |
| 585 | |
| 586 | if (cusItem.customFields) { |
| 587 | cusItem.customFields = JSON.parse(cusItem.customFields) |
| 588 | } |
| 589 | }) |
| 590 | |
| 591 | this.customers = customers |
| 592 | this.options.count = response.data.data.totalCount |
| 593 | this.options.filteredCount = response.data.data.filteredCount |
| 594 | this.fetched = true |
| 595 | this.fetchedFiltered = true |
| 596 | }) |
| 597 | .catch(e => { |
| 598 | console.log(e.message) |
| 599 | this.fetched = true |
| 600 | this.fetchedFiltered = true |
| 601 | }) |
| 602 | }, |
| 603 | |
| 604 | showDialogNewCustomer () { |
| 605 | this.customer = this.getInitCustomerObject() |
| 606 | this.dialogCustomer = true |
| 607 | }, |
| 608 | |
| 609 | showDialogEditCustomer (id) { |
| 610 | this.customer = this.customers[id] |
| 611 | this.dialogCustomer = true |
| 612 | }, |
| 613 | |
| 614 | updateCustomerCallback () { |
| 615 | this.dialogCustomer = false |
| 616 | this.allChecked = false |
| 617 | this.fetchData() |
| 618 | }, |
| 619 | |
| 620 | groupDeleteCallback () { |
| 621 | this.checkCustomerData.allChecked = false |
| 622 | this.checkCustomerData.toaster = false |
| 623 | this.fetchData() |
| 624 | } |
| 625 | }, |
| 626 | |
| 627 | computed: { |
| 628 | filterApplied () { |
| 629 | return !!this.params.search || !!this.params.noShow |
| 630 | } |
| 631 | }, |
| 632 | |
| 633 | watch: { |
| 634 | 'params.search' () { |
| 635 | if (typeof this.params.search !== 'undefined') { |
| 636 | this.fetchedFiltered = false |
| 637 | clearTimeout(this.timer) |
| 638 | this.timer = setTimeout(this.filterData, 500) |
| 639 | } |
| 640 | } |
| 641 | }, |
| 642 | |
| 643 | components: { |
| 644 | PageHeader, |
| 645 | DialogCustomer, |
| 646 | DialogExport, |
| 647 | DialogImport, |
| 648 | GroupDelete, |
| 649 | PaginationBlock |
| 650 | // DialogNewCustomize |
| 651 | } |
| 652 | |
| 653 | } |
| 654 | </script> |
| 655 | |
| 656 |