Uname: Linux webm012.cluster130.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Software: Apache
PHP version: 8.0.30 [ PHP INFO ] PHP os: Linux
Server Ip: 145.239.37.162
Your Ip: 216.73.216.190
User: dreampi (1009562) | Group: users (100)
Safe Mode: OFF
Disable Function:
_dyuweyrj4,_dyuweyrj4r,dl

name : WorkingHours.vue
<template>
  <div class="am-working-hours" ref="workingHours">

    <div class="am-dialog-table" v-for="(workDay, workDayIndex) in weekSchedule" :key="workDay.id">

      <el-row class="am-dialog-table-head hours">
        <el-col :span="12"><span>{{ workDay.day }}</span></el-col>
        <el-col :span="12" class="am-align-right">
          <span class="am-add-element" @click="applyToAllDays(workDay)" v-if="workDayIndex === 0">
            {{ $root.labels.apply_to_all_days }}
          </span>
          <div class="am-add-element" @click="showNewHoursForm(workDay)">
            <i class="el-icon-plus"></i>
          </div>
        </el-col>
      </el-row>

      <!-- Add Work Hours -->
      <transition name="fade">
        <div class="am-add-period" v-if="workDay.form.show">
          <el-form label-position="top" :model="workDay" ref="workDay">
            <el-row :gutter="10" v-if="workDay.form.isNew" class="am-add-period-type">
              <el-col>
                <el-radio v-model="workDay.form.type" label="Work">{{ $root.labels.work_hours }}</el-radio>
                <el-radio v-model="workDay.form.type" label="Break">{{ $root.labels.breaks }}</el-radio>
              </el-col>
            </el-row>

            <el-row v-if="workDay.form.type === 'Work'" :gutter="10" type="flex" style="flex-wrap: wrap">

              <!-- Working Hours -->
              <el-col :span="responsiveGrid.editHours.workHours">
                <el-row :gutter="10" type="flex" style="flex-wrap: wrap">
                  <el-col :span="24" style="margin-bottom: 4px">
                    <span>{{ $root.labels.work_hours }}</span>
                  </el-col>

                  <!-- Work Hours Start -->
                  <el-col :span="responsiveGrid.editHours.hour">
                    <el-form-item :rules="rules.startTime" :prop="'form.data.time.0'">
                      <el-time-select
                        v-model="workDay.form.data.time[0]"
                        :picker-options="getPeriodBorderTime(workDay.form.data.time[0], workDay.form.data.time[1], true)"
                        size="mini"
                        style="margin-bottom: 12px;"
                        :popper-class="'am-dropdown-cabinet'"
                        @change="startTimeChanged(workDay.form.data.time[0], workDay.form.data.time[1], getWorkingPeriodsInSeconds(workDay), function (value) {workDay.form.data.time[1] = value})"
                        @focus="startTimeChanged(workDay.form.data.time[0], workDay.form.data.time[1], getWorkingPeriodsInSeconds(workDay), function (value) {workDay.form.data.time[1] = value})"
                      >
                      </el-time-select>
                    </el-form-item>
                  </el-col>

                  <!-- Work Hours End -->
                  <el-col :span="responsiveGrid.editHours.hour">
                    <el-form-item :rules="rules.endTime" :prop="'form.data.time.1'">
                      <el-time-select
                        v-model="workDay.form.data.time[1]"
                        :picker-options="getPeriodBorderTime(workDay.form.data.time[0], workDay.form.data.time[1], false)"
                        size="mini"
                        style="margin-bottom: 12px;"
                        :popper-class="'am-dropdown-cabinet'"
                        :disabled="workDay.form.data.time[0] === null"
                      >
                      </el-time-select>
                    </el-form-item>
                  </el-col>

                </el-row>
              </el-col>
              <!-- /Working Hours -->

              <!-- Services -->
              <el-col v-if="categorizedServiceList && servicesCount > 1" :span="responsiveGrid.editHours.services">
                <el-row :gutter="10" type="flex" style="flex-wrap: wrap">
                  <el-col :span="24" style="margin-bottom: 4px">
                    <span>{{ $root.labels.services.charAt(0).toUpperCase() + $root.labels.services.slice(1) }}</span>
                      <el-tooltip placement="top">
                        <div slot="content" v-html="$root.labels.period_services_filter1_tooltip"></div>
                        <i class="el-icon-question am-tooltip-icon"></i>
                      </el-tooltip>
                  </el-col>

                  <el-col :span="24">
                    <el-select
                      v-model="workDay.form.data.serviceIds"
                      multiple
                      filterable
                      :placeholder="$root.labels.period_services_filter"
                      :popper-class="'am-dropdown-cabinet'"
                      collapse-tags
                      size="mini"
                      class="am-select-service"
                    >
                      <div
                        v-if="category.serviceList.filter(service => service.state).length > 0"
                        v-for="category in categorizedServiceList"
                        :key="category.id"
                      >
                        <div
                          class="am-drop-parent"
                          @click="selectAllInCategory(workDay.form.data, category.id)"
                        >
                          <span>{{ category.name }}</span>
                        </div>
                        <el-option
                          v-if="service.state"
                          v-for="service in category.serviceList"
                          :key="service.id"
                          :label="service.name"
                          :value="service.id"
                          class="am-drop-child"
                        >
                        </el-option>
                      </div>
                    </el-select>
                  </el-col>
                </el-row>
              </el-col>
              <!-- /Services -->

              <!-- Locations -->
              <el-col v-if="locations && locations.length > 1" :span="responsiveGrid.editHours.location">
                <el-row :gutter="10" type="flex" style="flex-wrap: wrap">
                  <el-col :span="24" style="margin-bottom: 4px">
                    <span>{{ $root.labels.location }}</span>
                    <el-tooltip placement="top">
                      <div slot="content" v-html="$root.labels.period_location_filter1_tooltip"></div>
                      <i class="el-icon-question am-tooltip-icon"></i>
                    </el-tooltip>
                  </el-col>

                  <el-col :span="24">
                    <el-select
                      v-model="workDay.form.data.locationIds"
                      multiple
                      class="am-select-service"
                      size="mini"
                      filterable
                      clearable
                      collapse-tags
                      :placeholder="$root.labels.location"
                      :popper-class="'am-dropdown-cabinet'"
                    >
                      <el-option
                        v-for="location in locations"
                        :key="location.id"
                        :label="location.name"
                        :value="location.id"
                      >
                      </el-option>
                    </el-select>
                  </el-col>
                </el-row>
              </el-col>
              <!-- /Location -->
            </el-row>

            <!-- Break -->
            <el-row v-else-if="workDay.form.type === 'Break'" :gutter="10">
              <el-col :span="24" style="margin-bottom: 4px">
                <span>{{ $root.labels.break_hours }}</span>
              </el-col>
              <p style="display: none;">{{ $root.labels.break_hours }}</p>

              <el-col :span="12">
                <el-form-item :rules="rules.startTime" :prop="'form.data.time.0'">
                  <el-time-select
                    v-model="workDay.form.data.time[0]"
                    :picker-options="getTimeSelectOptionsForBreaks(workDay.periods.length ? workDay.periods[0].time[0] : '00:00', workDay.periods.length ? workDay.periods[workDay.periods.length - 1].time[1] : '24:00', '', workDay.form.data.time[1])"
                    size="mini"
                    :popper-class="'am-dropdown-cabinet'"
                    style="margin-bottom: 14px;"
                  >
                  </el-time-select>
                </el-form-item>
              </el-col>

              <el-col :span="12">
                <el-form-item :rules="rules.endTime" :prop="'form.data.time.1'">
                  <el-time-select
                    v-model="workDay.form.data.time[1]"
                    :picker-options="getTimeSelectOptionsForBreaks(workDay.periods.length ? workDay.periods[0].time[0] : '00:00', workDay.periods.length ? workDay.periods[workDay.periods.length - 1].time[1] : '24:00', workDay.form.data.time[0], '')"
                    size="mini"
                    :popper-class="'am-dropdown-cabinet'"
                    style="margin-bottom: 14px;"
                  >
                  </el-time-select>
                </el-form-item>
              </el-col>
            </el-row>

            <div class="am-working-hours-buttons">
              <div class="align-left">
                <el-button size="small" @click="hideHoursForm(workDay)">
                  {{ $root.labels.cancel }}
                </el-button>
                <el-button size="small" type="primary" @click="saveHoursForm(workDay)">
                  {{ $root.labels.save }}
                </el-button>
              </div>
            </div>
          </el-form>
        </div>
      </transition>

      <!-- Periods -->
      <transition-group name="fade" tag="div">
        <div class="am-period" v-for="(hoursData, indexHours) in getDayHours(workDay)" :key="indexHours + 1">
          <el-row :gutter="10" type="flex">

            <!-- Hours -->
            <el-col :span="responsiveGrid.periods.hours" class="am-period__services">
              <span class="am-overflow-ellipsis">
                <span :class="{'am-period-break': hoursData.type === 'Break'}">{{ hoursData.data.time[0] }} - {{ hoursData.data.time[1] }}</span>
              </span>
            </el-col>
            <!-- /Hours -->

            <!-- Services -->
            <el-col :span="responsiveGrid.periods.services" class="am-flexed2 am-period__services">
                <span
                  class="am-overflow-ellipsis"
                  v-if="hoursData.type === 'Work' && hoursData.data.serviceIds.length > 0"
                >
                  <span
                    :ref="'serviceName-' + workDayIndex + '-' + indexHours"
                    :title="getServicesNames(hoursData.data.serviceIds).join(', ')"
                  >
                    {{ getServicesNames(hoursData.data.serviceIds).join(', ') }}
                  </span>
              </span>
            </el-col>
            <!-- /Services -->

            <!-- Location -->
            <el-col :span="responsiveGrid.periods.locations" class="am-flexed2 am-period__locations">
              <span
                  v-if="hoursData.type === 'Work' && getPeriodLocationsIds(hoursData.data).length > 0"
                  :title="getLocationsNames(getPeriodLocationsIds(hoursData.data)).join(', ')" class="am-overflow-ellipsis"
              >
                {{ getLocationsNames(getPeriodLocationsIds(hoursData.data)).join(', ') }}
              </span>
            </el-col>
            <!-- /Location -->

            <!-- Edit Hours -->
            <el-col style="margin: auto" :span="responsiveGrid.periods.edit" :class="{'mobile': responsiveGrid.periods.edit === 24}" class="am-flexed2 am-period__services">
              <div class="am-edit-element" @click="editHours(workDay, hoursData.type, hoursData.index)">
                <img :src="$root.getUrl + 'public/img/edit-pen.svg'">
              </div>

              <!-- Delete Hours -->
              <div class="am-delete-element" @click="deleteHours(workDay, hoursData.type, hoursData.index)">
                <img :src="$root.getUrl + 'public/img/delete.svg'">
              </div>
            </el-col>

          </el-row>
        </div>

      </transition-group>

    </div>

  </div>
</template>

<script>
  import imageMixin from '../../../js/common/mixins/imageMixin'
  import dateMixin from '../../../js/common/mixins/dateMixin'
  import durationMixin from '../../../js/common/mixins/durationMixin'
  import periodMixin from '../../../js/backend/mixins/periodMixin'

  export default {

    mixins: [periodMixin, imageMixin, dateMixin, durationMixin],

    props: {
      activeTab: '',
      weekSchedule: null,
      categorizedServiceList: null,
      locations: null
    },

    data () {
      return {
        rules: {
          startTime: [
            {
              required: true, message: this.$root.labels.select_time_warning, trigger: 'submit'
            }
          ],
          endTime: [
            {
              required: true, message: this.$root.labels.select_time_warning, trigger: 'submit'
            }
          ]
        },
        responsiveGrid: {
          editHours: {
            workHours: 24,
            hour: 24,
            services: 24,
            location: 24
          },
          periods: {
            hours: !this.categorizedServiceList ? 6 : 4,
            services: !this.categorizedServiceList ? 10 : 12,
            locations: 5,
            edit: 3
          }
        }
      }
    },

    methods: {
      getWorkingPeriodsInSeconds (workDay) {
        let workPeriods = this.getDayHours(workDay).filter(period => period.type === 'Work').map(period => period.data).map(periodData => periodData.time)

        let periodsInSeconds = []

        let $this = this

        workPeriods.forEach(function (period) {
          if (!(workDay.form.data.time[0] === period[0] && workDay.form.data.time[1] === period[1])) {
            periodsInSeconds.push([$this.getStringTimeInSeconds(period[0]), $this.getStringTimeInSeconds(period[1])])
          }
        })

        return periodsInSeconds
      },

      getDayHours (day) {
        let hours = []

        day.periods.forEach(function (dayPeriod, index) {
          hours.push({
            index: index,
            type: 'Work',
            data: dayPeriod
          })
        })

        day.breaks.forEach(function (dayBreak, index) {
          hours.push({
            index: index,
            type: 'Break',
            data: dayBreak
          })
        })

        return hours.sort((a, b) => this.$moment('2000-01-01 ' + a.data.time[0] + ':00', 'YYYY-MM-DD HH:mm:ss').diff(this.$moment('2000-01-01 ' + b.data.time[0] + ':00', 'YYYY-MM-DD HH:mm:ss')))
      },

      getServicesNames (serviceIds) {
        let services = []

        if (this.categorizedServiceList) {
          this.categorizedServiceList.forEach(function (category) {
            category.serviceList.forEach(function (service) {
              if (serviceIds.indexOf(service.id) !== -1) {
                services.push(service.name)
              }
            })
          })
        }

        return services
      },

      selectAllInCategory (period, id) {
        let servicesIds = this.categorizedServiceList.find(category => category.id === id).serviceList.filter(service => service.state).map(service => service.id)

        // Deselect all services if they are already selected
        if (_.isEqual(_.intersection(servicesIds, period.serviceIds), servicesIds)) {
          period.serviceIds = _.difference(period.serviceIds, servicesIds)
        } else {
          period.serviceIds = _.uniq(period.serviceIds.concat(servicesIds))
        }
      },

      getTimeSelectOptionsForBreaks: function (minTimeWorkingHour, maxTimeWorkingHour, minTimeBreak, maxTimeBreak) {
        return {
          start: '00:00',
          end: '24:00',
          step: this.secondsToTimeSelectStep(this.getTimeSlotLength()),
          minTime: minTimeBreak || minTimeWorkingHour,
          maxTime: maxTimeBreak || maxTimeWorkingHour
        }
      },

      editHours (day, type, index) {
        let $this = this

        switch (type) {
          case ('Work'):
            day.form.show = false

            setTimeout(function () {
              day.form = {
                data: day.periods[index],
                oldData: JSON.parse(JSON.stringify(day.periods[index])),
                isNew: false,
                type: 'Work',
                show: true,
                index: index
              }

              $this.findFreePeriods($this.getWorkingPeriodsInSeconds(day))
            }, 200)

            break

          case ('Break'):
            day.form.show = false

            setTimeout(function () {
              day.form = {
                data: day.breaks[index],
                oldData: JSON.parse(JSON.stringify(day.breaks[index])),
                isNew: false,
                type: 'Break',
                show: true,
                index: index
              }
            }, 200)

            break
        }
      },

      deleteHours (day, type, index) {
        switch (type) {
          case ('Work'):
            day.periods.splice(index, 1)

            break

          case ('Break'):
            day.breaks.splice(index, 1)

            break
        }
      },

      showNewHoursForm (day) {
        day.form = {
          data: {
            time: day.form.type === 'Work' ? [day.periods.length ? (day.periods[day.periods.length - 1].time[1]) : '', ''] : ['', ''],
            id: null,
            locationId: null,
            locationIds: [],
            serviceIds: [],
            periodLocationList: [],
            periodServiceList: []
          },
          isNew: true,
          type: 'Work',
          show: true,
          index: null
        }

        this.findFreePeriods(this.getWorkingPeriodsInSeconds(day))
      },

      hideHoursForm (day) {
        day.form.show = false

        switch (day.form.type) {
          case ('Work'):
            if (!day.form.isNew) {
              day.periods[day.form.index] = day.form.oldData
            }

            break

          case ('Break'):
            if (!day.form.isNew) {
              day.breaks[day.form.index] = day.form.oldData
            }

            break
        }
      },

      saveHoursForm (day) {
        this.$refs.workDay[0].validate((valid) => {
          if (valid) {
            switch (day.form.type) {
              case ('Work'):
                if (day.form.isNew) {
                  day.periods.push({
                    id: null,
                    time: day.form.data.time,
                    locationIds: day.form.data.locationIds,
                    serviceIds: day.form.data.serviceIds,
                    locationId: day.form.data.locationId,
                    periodLocationList: day.form.data.periodLocationList,
                    periodServiceList: day.form.data.periodServiceList
                  })
                } else {
                  day.periods[day.form.index] = day.form.data
                }

                break

              case ('Break'):
                if (day.form.isNew) {
                  day.breaks.push({
                    id: null,
                    time: day.form.data.time
                  })
                } else {
                  day.breaks[day.form.index] = day.form.data
                }

                break
            }

            day.form.show = false
          } else {
            return false
          }
        })
      },

      applyToAllDays (selectedWorkDay) {
        let periods = JSON.parse(JSON.stringify(selectedWorkDay.periods))

        periods.forEach(function (period) {
          period.id = null

          period.periodLocationList = []

          period.periodServiceList = []

          period.savedPeriodServiceList = []
        })

        let breaks = JSON.parse(JSON.stringify(selectedWorkDay.breaks))

        breaks.forEach(function (dayBreak) {
          dayBreak.id = null
        })

        this.weekSchedule.forEach(function (weekDay) {
          weekDay.id = null
          weekDay.periods = JSON.parse(JSON.stringify(periods))
          weekDay.breaks = JSON.parse(JSON.stringify(breaks))

          weekDay.time = JSON.parse(JSON.stringify(selectedWorkDay.time))
        })
      },

      getPeriodLocationsIds (data) {
        return data.locationIds.length ? data.locationIds : (data.locationId ? [data.locationId] : [])
      },

      getLocationsNames (locationIds) {
        let locations = []

        locationIds.forEach((locationId) => {
          let location = this.locations.find(location => location.id === locationId)

          if (location) {
            locations.push(location.name)
          }
        })

        return locations
      },

      getColumnLength (size = '') {
        if (this.categorizedServiceList && this.servicesCount > 1 && this.locations && this.locations.length > 1) {
          if (size === 'mini') {
            return {
              workHours: 24,
              hour: 24,
              services: 24,
              location: 24
            }
          }

          if (size === 'mobile') {
            return {
              workHours: 24,
              hour: 12,
              services: 24,
              location: 24
            }
          }

          return {
            workHours: 8,
            hour: 12,
            services: 8,
            location: 8
          }
        } else if (this.categorizedServiceList && this.servicesCount > 1) {
          if (size === 'mini') {
            return {
              workHours: 24,
              hour: 24,
              services: 24,
              location: 0
            }
          }

          if (size === 'mobile') {
            return {
              workHours: 24,
              hour: 12,
              services: 24,
              location: 0
            }
          }

          return {
            workHours: 10,
            hour: 12,
            services: 14,
            location: 0
          }
        } else if (this.locations && this.locations.length > 1) {
          if (size === 'mini') {
            return {
              workHours: 24,
              hour: 24,
              services: 0,
              location: 24
            }
          }

          if (size === 'mobile') {
            return {
              workHours: 24,
              hour: 12,
              services: 0,
              location: 24
            }
          }

          return {
            workHours: 10,
            hour: 12,
            services: 0,
            location: 14
          }
        } else {
          if (size === 'mini') {
            return {
              workHours: 24,
              hour: 24,
              services: 0,
              location: 0
            }
          }

          if (size === 'mobile') {
            return {
              workHours: 24,
              hour: 12,
              services: 0,
              location: 0
            }
          }

          return {
            workHours: 24,
            hour: 12,
            services: 0,
            location: 0
          }
        }
      },

      handleResize () {
        if (this.activeTab === 'workingHours' || this.activeTab === 'hours') {
          let amContainer = this.$refs.workingHours

          if (typeof amContainer !== 'undefined' && amContainer.offsetWidth < 320) {
            this.responsiveGrid.periods = {
              hours: 24,
              services: 24,
              locations: 24,
              edit: 24
            }
            this.responsiveGrid.editHours = this.getColumnLength('mini')
          } else if (typeof amContainer !== 'undefined' && amContainer.offsetWidth < 650) {
            this.responsiveGrid.periods = {
              hours: 24,
              services: 24,
              locations: 24,
              edit: 24
            }
            this.responsiveGrid.editHours = this.getColumnLength('mobile')
          } else {
            this.responsiveGrid.periods = {
              hours: !this.categorizedServiceList ? 6 : 4,
              services: !this.categorizedServiceList ? 10 : 12,
              locations: 5,
              edit: 3
            }
            this.responsiveGrid.editHours = this.getColumnLength()
          }
        }
      }
    },

    created () {
      window.addEventListener('resize', this.handleResize)
    },

    computed: {
      servicesCount () {
        let servicesCount = 0

        this.categorizedServiceList.forEach(function (category) {
          servicesCount += category.serviceList.length
        })

        return servicesCount
      }
    },

    watch: {
      'activeTab' () {
        if (this.activeTab === 'workingHours' || this.activeTab === 'hours') {
          this.handleResize()
        }
      }
    }
  }
</script>
© 2026 GrazzMean-Shell