Files
enterprise-addons/website_appointment/views/appointment_templates_appointments.xml
T

317 lines
21 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Templates inherited -->
<template id="appointments_list_layout" name="Appointment: Appointments List Layout"
inherit_id="appointment.appointments_list_layout" track="1">
<xpath expr="//t[@t-call='portal.portal_layout']" position="attributes">
<attribute name="t-call">website.layout</attribute>
</xpath>
<xpath expr="//div[hasclass('o_appointment_choice')]" position="before">
<t t-call="website_appointment.website_calendar_index"/>
</xpath>
<xpath expr="//div[hasclass('o_appointment_index')]" position="attributes">
<attribute name="class">o_appointment_index bg-o-color-4</attribute>
</xpath>
<xpath expr='//div[hasclass("o_appointment_svg")]' position="before">
<div class="alert alert-info text-center d-none" groups="appointment.group_appointment_manager">
<p class="m-0">Use the top button '<b>+ New</b>' to create an appointment type.</p>
</div>
</xpath>
</template>
<record id="appointment.appointments_list_layout" model="ir.ui.view">
<!-- As the track field is not properly overridden (the value is different whether you get it by the base class
name or the overridden name), write it to the base class as well -->
<field name="track">1</field>
</record>
<template id="appointment_info" name="Appointment: Appointment Info" inherit_id="appointment.appointment_info" track="1">
<xpath expr="//t[@t-call='portal.portal_layout']" position="attributes">
<attribute name="t-call">website.layout</attribute>
</xpath>
<xpath expr="//div[@id='wrap']" position="attributes">
<attribute name="class">o_wappointment_wrap h-100 overflow-x-hidden</attribute>
</xpath>
<xpath expr="//t[@t-set='o_portal_fullwidth_alert']" position="replace"/>
<xpath expr="//t[@t-call='appointment.staff_user_select']" position="attributes">
<attribute name="t-if">
is_manual_assign_user_resource_first and based_on_users and not skip_resource_selection
</attribute>
</xpath>
<xpath expr="//div[@name='resource_select']" position="attributes">
<attribute name="t-if">
is_manual_assign_user_resource_first and not based_on_users and not skip_resource_selection
</attribute>
</xpath>
<xpath expr="//t[@t-call='appointment.appointment_progress_bar']" position="before">
<a t-if="len(available_appointments) != 1"
class="text-truncate"
t-attf-href="/appointment?#{keep_query('filter_appointment_type_ids', 'filter_staff_user_ids', 'invite_token')}">
<i class="fa fa-long-arrow-left me-2"/>All Appointments
</a>
</xpath>
<xpath expr="//t[@t-set='selectionPossible']" position="after">
<!-- Selection is no longer possible if a selection screen was shown beforehand -->
<t t-set="selectionPossible"
t-value="selectionPossible and not (is_manual_assign_user_resource_first and appointment_type.show_avatars)"/>
</xpath>
</template>
<record id="appointment.appointment_info" model="ir.ui.view">
<!-- Write track=1 to the base class as well (see explanation above) -->
<field name="track">1</field>
</record>
<template id="appointment_progress_bar" inherit_id="appointment.appointment_progress_bar">
<xpath expr="//a[contains(@t-att-class, 'step==STEP_TIME')]" position="before">
<t t-set="is_manual_assign_user_resource_first" t-value="not appointment_type.is_auto_assign and not appointment_type.is_date_first"/>
<t t-set="STEP_OPERATOR_SELECT" t-value="10"/>
<t t-set="show_operator_select" t-value="step==STEP_OPERATOR_SELECT or is_manual_assign_user_resource_first and len(users_or_resources_possible) > 1"/>
<t t-if="show_operator_select">
<li class="d-flex align-items-center">
<a t-att-class="'text-decoration-none text-truncate ' + (step==STEP_OPERATOR_SELECT and 'fw-bold text-reset cursor-default' or step&gt;STEP_OPERATOR_SELECT and ' ' or 'cursor-default text-muted')"
t-att-href="'#' if step&lt;STEP_OPERATOR_SELECT or step==STEP_OPERATOR_SELECT else '/appointment/%s?%s' % (appointment_type.id, keep_query('filter_appointment_type_ids', 'filter_resource_ids', 'filter_staff_user_ids', 'invite_token'))">
<span t-if="appointment_type.schedule_based_on == 'users'">Operator</span>
<span t-else="">Meeting</span>
</a>
<span class="d-inline-block mx-sm-3 fa fa-angle-right text-muted fs-5"/>
</li>
</t>
</xpath>
</template>
<!-- Pages -->
<template id="appointment_select_operator" name="Appointment: Appointment Operators">
<t t-set="no_breadcrumbs" t-value="True"/>
<t t-call="website.layout">
<div id="wrap" class="o_wappointment_wrap h-100 overflow-x-hidden">
<div class="container-lg o_appointment o_wappointment_select_operator o_wappointment_type_options h-100" t-att-data-appointment-type-id="appointment_type.id">
<div class="row mt-4">
<div class="col-12 col-md-8">
<nav class="d-print-none d-flex justify-content-between mb-4">
<a t-if="len(available_appointments) != 1"
class="text-truncate"
t-attf-href="/appointment?#{keep_query('filter_appointment_type_ids', 'filter_staff_user_ids', 'invite_token')}">
<i class="fa fa-long-arrow-left me-2"/>All Appointments
</a>
<t t-call="appointment.appointment_progress_bar">
<t t-set="step" t-value="10"/>
</t>
</nav>
<div class="d-flex flex-wrap justify-content-between align-items-center pb-3">
<h4 class="me-2" t-if="appointment_type.schedule_based_on == 'users'">Choose who you will meet</h4>
<h4 class="me-2" t-else="">Choose what you would like to book</h4>
<a t-attf-href="/appointment/#{ appointment_type.id }?#{keep_query('*', skip_resource_selection=1)}"
class="o_wappointment_select_btn ms-auto">
<span>See all availabilities <i class="fa fa-long-arrow-right"/></span>
</a>
</div>
<div class="row">
<t t-set="showAvatars" t-value="appointment_type.show_avatars"/>
<div t-if="appointment_type.schedule_based_on == 'users'"
t-foreach="users_possible" t-as="staff_user"
class="col-md-6 col-lg-4 mb-4">
<div class="o_wappointment_card card h-100" itemscope="itemscope" itemtype="http://schema.org/Employee">
<a t-attf-href="/appointment/#{appointment_type.id}?staff_user_id=#{staff_user.id}&amp;#{keep_query('*')}"
class="d-flex d-md-block h-100 text-reset text-decoration-none">
<header t-attf-class="o_appointment_avatar_container w-25 w-md-auto bg-secondary ratio {{'ratio-4x3' if showAvatars else 'ratio-16x9'}}">
<div t-if="showAvatars"
t-attf-style="background-image: url('/appointment/#{appointment_type.id}/avatar?user_id=#{staff_user.id}');"
class="o_appointment_avatar_background"/>
<div t-else="" class="o_appointment_avatar_background d-flex justify-content-center align-items-center">
<img class="o_appointment_avatar_background h-75 w-75 m-auto" src="/appointment/static/src/img/guy.svg"/>
</div>
</header>
<div class="card-body">
<h5 class="mb-1" t-out="staff_user.name"/>
<div class="o_wappointment_card_user_fct mb-2">
<div t-field="staff_user.partner_id.function" placeholder="Add a function here..."/>
</div>
<div class="o_wappointment_card_user_dsc text-muted small">
<div t-field="staff_user.partner_id.website_description" placeholder="Add a user description here..."/>
</div>
</div>
</a>
</div>
</div>
<div t-if="appointment_type.schedule_based_on == 'resources'"
t-foreach="resources_possible" t-as="resource"
class="col-md-6 col-lg-4 mb-4">
<div class="o_wappointment_card card h-100">
<a t-attf-href="/appointment/#{appointment_type.id}?#{keep_query('*', resource_selected_id=resource.id)}"
class="d-flex d-md-block text-reset text-decoration-none h-100">
<header t-attf-class="o_appointment_avatar_container w-25 w-md-auto bg-secondary ratio {{'ratio-4x3' if showAvatars else 'ratio-16x9'}}">
<div t-if="showAvatars"
t-attf-style="background-image: url('/appointment/#{appointment_type.id}/resource_avatar?resource_id=#{resource.id}');"
class="o_appointment_avatar_background"/>
<div t-else="" class="o_appointment_avatar_background d-flex justify-content-center align-items-center">
<img class="o_appointment_avatar_background h-75 w-75 m-auto" src="/appointment/static/src/img/clock.svg"/>
</div>
</header>
<div class="card-body">
<h5 class="mb-0" t-out="resource.name"/>
<div class="o_wappointment_card_user_dsc mb-2 text-muted">
<div t-field="resource.description" placeholder="Add a resource description here..."/>
</div>
</div>
</a>
</div>
</div>
<!-- Prevent using 'resource' from the loop above as the selected one in other templates -->
<t t-set="resource" t-value="False"/>
</div>
<div class="oe_structure"/>
</div>
<t t-call="appointment.appointment_details_column"/>
</div>
</div>
</div>
</t>
</template>
<template id="appointments_cards_layout" name="Appointment Types" track="1">
<t t-call="website.layout">
<div id="wrap" class="o_appointment_index">
<div class="oe_structure"/>
<t t-call="website_appointment.website_calendar_index"/>
<t t-call="website_appointment.website_calendar_index_topbar"/>
<div class="o_appointment_choice o_appointment_appointments_list">
<div class="container">
<div id="o_appointment_index_main_col" class="col-md px-0 o_wappointment_appointment_list_columns">
<div class="row row-gap-3">
<t t-call="website_appointment.appointments_cards"/>
</div>
</div>
</div>
<div class="oe_structure oe_empty"/>
</div>
</div>
</t>
</template>
<!-- Enable the customize option for the 2 layouts (cards and list)-->
<template id="website_calendar_index" name="Appointment"/>
<template id="opt_appointments_list_cards" inherit_id="website_appointment.website_calendar_index" active="True" name="Card Design"/>
<!-- Top bar -->
<template id="website_calendar_index_topbar" name="Topbar">
<div class="container">
<section class="d-flex d-print-none align-items-center justify-content-lg-end flex-wrap gap-2 mt-4 mb-3" t-if="appointment_types">
<h1 class="me-auto mb-0 h4">Choose your appointment</h1>
<div class="d-flex w-100 w-lg-25">
<t t-call="website.website_search_box_input">
<t t-set="_form_classes" t-valuef="flex-grow-1"/>
<t t-set="_classes" t-valuef="#{_classes}"/>
<t t-set="_input_classes" t-valuef="bg-light"/>
<t t-set="_submit_classes" t-valuef="btn-light"/>
<t t-set="search_type" t-valuef="appointments"/>
<t t-set="action" t-valuef="/appointment"/>
<t t-set="display_description" t-valuef="true"/>
<t t-set="display_detail" t-valuef="false"/>
<t t-set="placeholder">Search...</t>
<t t-set="search" t-value="current_search"/>
<t t-foreach="searches" t-as="search">
<input t-if="item != 'search' and item_value != 'all'" type="hidden"
t-att-name="item" t-att-value="item_value"/>
</t>
<input type="hidden" name="filter_appointment_type_ids" t-att-value="filter_appointment_type_ids"/>
<input type="hidden" name="filter_staff_user_ids" t-att-value="filter_staff_user_ids"/>
<input type="hidden" name="filter_resource_ids" t-att-value="filter_resource_ids"/>
<input type="hidden" name="invite_token" t-att-value="invite_token"/>
<t t-out="0"/>
</t>
</div>
</section>
</div>
</template>
<template id="appointments_cards" name="Appointments Cards">
<div t-if="not appointment_types" class="col-12 o_appointment_not_found">
<div class="alert alert-info text-center d-none mt-4" groups="appointment.group_appointment_manager">
<p class="m-0">Use the top button '<b>+ New</b>' to create an appointment type.</p>
</div>
<div class="o_appointment_svg mx-auto text-center py-3 w-75">
<i class="mx-auto h3 fa fa-circle-o-notch fa-spin"/>
</div>
<div class="mt-4 text-center d-none">
<t t-if="current_search">
<h4>No result for "<t t-out="current_search"/>"</h4>
<a href="/appointment">See all appointments <i class="fa fa-long-arrow-right"/></a>
</t>
<h4 t-else="">There is currently no appointment available</h4>
</div>
</div>
<div t-foreach="appointment_types" t-as="appointment" class="col-md-6 col-lg-4 col-xl-3">
<div class="o_wappointment_card card h-100" itemscope="itemscope" itemtype="http://schema.org/Appointments">
<t t-call="website_appointment.appointment_card_top"/>
<t t-call="website_appointment.appointment_card_body"/>
</div>
</div>
<div class="d-flex justify-content-center my-3">
<t t-call="website.pager"/>
</div>
</template>
<template id="appointment_card_top">
<div class="card-img-top position-relative">
<a t-attf-href="/appointment/#{appointment.id}?#{keep_query('filter_appointment_type_ids', 'filter_staff_user_ids', 'filter_resource_ids', 'invite_token')}"
t-attf-title="Book {{appointment.name}}">
<div t-field="appointment.image_1920" class="d-block h-100 w-100 overflow-hidden ratio ratio-16x9 object-fit-cover" t-options="{'widget': 'image', 'class': 'object-fit-cover', 'preview_image': 'image_512'}"/>
</a>
<small t-if="not appointment.website_published" class="o_appointment_unpublished badge bg-danger position-absolute top-0 end-0 mt-2 me-2" groups="base.group_user">
<i class="fa fa-ban me-2" role="presentation"/>Unpublished
</small>
<div t-if="appointment.schedule_based_on == 'users' and appointment.staff_user_ids" class="o_wappointment_card_staff_users position-absolute bottom-0 d-flex align-items-center">
<t t-if="len(appointment.staff_user_ids)" t-call="website_appointment.appointment_booking_resource_description"/>
</div>
</div>
</template>
<template id="appointment_card_body">
<div class="card-body d-flex flex-column gap-2">
<div class="d-flex align-items-start justify-content-between gap-3">
<h5 class="card-title m-0 text-break" t-field="appointment.name" itemprop="name"/>
</div>
<div class="d-flex gap-2 flex-wrap align-items-center">
<div itemprop="location" class="o_wappointment_card_location d-flex gap-1 fw-bold smaller text-muted text-break">
<t t-if="appointment.location_id">
<i class="fa fa-map-marker lh-base" role="presentation"/>
<span t-field="appointment.location_id" t-options="{'widget': 'contact', 'fields': ['name']}"/>
</t>
<t t-else="">
<i class="fa fa-video-camera lh-base" role="presentation"/>
<span class="o_not_editable">Online</span>
</t>
</div>
</div>
<span t-if="not is_html_empty(appointment.message_intro)" class="o_wappointment_message_intro card-text text-muted overflow-hidden" t-field="appointment.message_intro" itemprop="message_intro" placeholder="Add an intro message here..."/>
<div class="mt-auto">
<a t-attf-href="/appointment/#{appointment.id}?#{keep_query('filter_appointment_type_ids', 'filter_staff_user_ids', 'filter_resource_ids', 'invite_token')}"
t-attf-title="Book {{appointment.name}}" role="button" class="btn btn-primary w-100 mt-3 o_not_editable" contenteditable="false">Book now</a>
</div>
</div>
</template>
<template id='appointment_booking_resource_description' name="Avatars">
<t t-set="avatars_max_count" t-value="avatars_max_count or 6"/>
<t t-set="booking_count" t-value="len(appointment.staff_user_ids)"/>
<t t-if="appointment.show_avatars and appointment.schedule_based_on == 'users'">
<div t-att-class="booking_count == 1 and 'badge d-flex align-items-center rounded-pill py-0 ps-0 bg-light fw-normal' or ''">
<span class="o_appointment_user_avatars d-flex">
<t t-foreach="appointment.staff_user_ids[:(avatars_max_count - 1)]" t-as="staff_user">
<img t-attf-src="/appointment/#{appointment.id}/avatar?user_id=#{staff_user.id}&amp;avatar_size=128" t-att-title="staff_user.name"
class="rounded-circle o_appointment_avatar_background o_appointment_user_avatar"/>
</t>
<span t-if="booking_count == avatars_max_count" class="o_appointment_user_avatar d-flex align-items-center justify-content-center rounded-circle bg-light"> +1 </span>
<span t-if="booking_count > avatars_max_count" class="o_appointment_user_avatar d-flex align-items-center justify-content-center rounded-circle bg-light"> +<t t-out="booking_count - (avatars_max_count - 1)"/></span>
</span>
<span t-if="booking_count == 1"><t t-out="appointment.staff_user_ids[0].name"/></span>
</div>
</t>
</template>
</odoo>