Initial commit: Hr packages
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.PersonaImStatusIcon" t-inherit-mode="extension">
|
||||
<xpath expr="//*[@name='root']" position="inside">
|
||||
<t t-if="personaImStatusIconView.persona.im_status === 'leave_online'">
|
||||
<i class="o_PersonaImStatusIcon_icon o-online fa fa-plane fa-stack-1x text-primary" title="Online" role="img" aria-label="User is online"/>
|
||||
</t>
|
||||
<t t-if="personaImStatusIconView.persona.im_status === 'leave_away'">
|
||||
<i class="o_PersonaImStatusIcon_icon o-away fa fa-plane fa-stack-1x text-warning" title="Away" role="img" aria-label="User is away"/>
|
||||
</t>
|
||||
<t t-if="personaImStatusIconView.persona.im_status === 'leave_offline'">
|
||||
<i class="o_PersonaImStatusIcon_icon o-offline fa fa-plane fa-stack-1x text-700" title="Out of office" role="img" aria-label="User is out of office"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.ThreadIcon" t-inherit-mode="extension">
|
||||
<xpath expr="//*[@name='noImStatusCondition']" position="before">
|
||||
<t t-elif="thread.channel.correspondent.im_status === 'leave_online'">
|
||||
<div class="o_ThreadIcon_online fa fa-fw fa-plane" title="Online"/>
|
||||
</t>
|
||||
<t t-elif="thread.channel.correspondent.im_status === 'leave_away'">
|
||||
<div class="o_ThreadIcon_away fa fa-fw fa-plane text-warning" title="Away"/>
|
||||
</t>
|
||||
<t t-elif="thread.channel.correspondent.im_status === 'leave_offline'">
|
||||
<div class="o_ThreadIcon_offline fa fa-fw fa-plane" title="Out of office"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// Layout
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
.o_ThreadView_outOfOffice {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.ThreadView" t-inherit-mode="extension">
|
||||
<xpath expr="//*[@name='loadingCondition']" position="before">
|
||||
<t t-if="threadView.thread.channel and threadView.thread.channel.correspondent and threadView.thread.channel.correspondent.outOfOfficeText">
|
||||
<div class="o_ThreadView_outOfOffice alert alert-primary" t-esc="threadView.thread.channel.correspondent.outOfOfficeText" role="alert"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// = HR Holidays
|
||||
// ============================================================================
|
||||
// No CSS hacks, variables overrides only
|
||||
.o_timeoff_card, .o_time_off_icon_types {
|
||||
--timeOffCard-icon-filter: invert(1) brightness(2);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/* @odoo-module */
|
||||
|
||||
import Popover from "web.Popover";
|
||||
|
||||
const { Component } = owl;
|
||||
|
||||
export class TimeOffCardPopover extends Component {}
|
||||
TimeOffCardPopover.components = { Popover };
|
||||
|
||||
TimeOffCardPopover.template = 'hr_holidays.TimeOffCardPopover';
|
||||
TimeOffCardPopover.props = ['allocated', 'approved', 'planned', 'left', 'usable'];
|
||||
|
||||
export class TimeOffCard extends Component {}
|
||||
|
||||
TimeOffCard.components = { TimeOffCardPopover };
|
||||
TimeOffCard.template = 'hr_holidays.TimeOffCard';
|
||||
TimeOffCard.props = ['name', 'id', 'data', 'requires_allocation'];
|
||||
|
||||
export class TimeOffCardMobile extends TimeOffCard {}
|
||||
|
||||
TimeOffCardMobile.template = 'hr_holidays.TimeOffCardMobile';
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
.o_timeoff_card {
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right: 2px solid $border-color;
|
||||
}
|
||||
|
||||
span {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.o_timeoff_name {
|
||||
color: $body-color;
|
||||
font-size: 15px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.o_timeoff_duration {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
|
||||
img {
|
||||
height: 30px;
|
||||
filter: var(--timeOffCard-icon-filter);
|
||||
}
|
||||
}
|
||||
|
||||
.o_timeoff_validity {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.o_timeoff_info {
|
||||
display: inline-block;
|
||||
margin-right: -10px;
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_timeoff_card_mobile {
|
||||
.o_timeoff_green {
|
||||
color: $o-enterprise-primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.o_timeoff_popover {
|
||||
background-color: $o-view-background-color;
|
||||
font-size: 12px;
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
span {
|
||||
padding-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_time_off_icon_types img {
|
||||
filter: var(--timeOffCard-icon-filter);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<div t-name="hr_holidays.TimeOffCard" owl="1" class="o_timeoff_card py-3 text-odoo">
|
||||
<t t-set="data" t-value="props.data"/>
|
||||
<t t-set="duration" t-value="props.requires_allocation ? data.virtual_remaining_leaves : data.virtual_leaves_taken"/>
|
||||
<t t-set="show_popover" t-value="true"/>
|
||||
|
||||
<strong class="o_timeoff_name"><t t-esc="props.name"/></strong>
|
||||
<span class="o_timeoff_duration">
|
||||
<t t-if="data and data.icon">
|
||||
<img t-att-src="data.icon" />
|
||||
</t>
|
||||
<t t-esc="duration"/>
|
||||
</span>
|
||||
<div class="text-uppercase">
|
||||
<t t-if="data.request_unit == 'hour'" name="duration_unit">hours</t>
|
||||
<t t-else="">days</t>
|
||||
<t t-if="props.requires_allocation" name="duration_type">
|
||||
available
|
||||
</t>
|
||||
<t t-else="">
|
||||
taken
|
||||
</t>
|
||||
<t t-if="show_popover">
|
||||
<TimeOffCardPopover
|
||||
allocated="data.max_leaves"
|
||||
approved="data.leaves_approved"
|
||||
planned="data.leaves_requested"
|
||||
left="data.virtual_remaining_leaves"
|
||||
usable="data.usable_remaining_leaves" />
|
||||
</t>
|
||||
</div>
|
||||
<span t-if="props.requires_allocation and data.closest_allocation_expire !== false" class="text-uppercase o_timeoff_validity">
|
||||
<t t-if="data.closest_allocation_remaining != data.virtual_remaining_leaves">
|
||||
(<t t-esc="data.closest_allocation_remaining"/> <t t-if="data.request_unit == 'hour'">hours</t><t t-else="">days</t>
|
||||
valid until <span t-esc="data.closest_allocation_expire"/>)
|
||||
</t>
|
||||
<t t-else="">
|
||||
(valid until <span t-esc="data.closest_allocation_expire"/>)
|
||||
</t>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<t t-name="hr_holidays.TimeOffCardMobile" owl="1">
|
||||
<t t-set="data" t-value="props.data"/>
|
||||
<t t-set="duration" t-value="props.requires_allocation ? data.virtual_remaining_leaves : data.virtual_leaves_taken" />
|
||||
|
||||
<span class="float-end o_timeoff_card_mobile">
|
||||
<t t-if="props.requires_allocation" name="duration_type">
|
||||
<strong t-esc="duration" class="o_timeoff_green"/> / <span t-esc="data.max_leaves"/> <t t-if="data.request_unit == 'hour'">Hours</t><t t-else="">Days</t> <span class="o_timeoff_green">Available</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<strong t-esc="duration"/> <t t-if="data.request_unit == 'hour'">Hours</t><t t-else="">Days</t> <span class="text-odoo">Taken</span>
|
||||
</t>
|
||||
</span>
|
||||
</t>
|
||||
|
||||
<t t-name="hr_holidays.TimeOffCardPopover" owl="1">
|
||||
<div class="o_timeoff_info">
|
||||
<Popover position="'right'" popoverClass="'o_timeoff_popover'">
|
||||
<span class="fa fa-question-circle-o"/>
|
||||
<t t-set-slot="opened">
|
||||
<ul>
|
||||
<li>Allocated: <span t-esc="props.allocated"/></li>
|
||||
<li>Approved: <span t-esc="props.approved"/></li>
|
||||
<li style="border-bottom: 1px solid gray;">Planned: <span t-esc="props.planned"/></li>
|
||||
<li>Left: <span t-esc="props.left"/></li>
|
||||
<li t-if="props.left != props.usable">Usable: <span t-esc="props.usable"/></li>
|
||||
</ul>
|
||||
</t>
|
||||
</Popover>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* @odoo-module */
|
||||
|
||||
import { TimeOffCard } from './time_off_card';
|
||||
import { useBus, useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { Component, useState, onWillStart } = owl;
|
||||
|
||||
export class TimeOffDashboard extends Component {
|
||||
setup() {
|
||||
this.orm = useService("orm");
|
||||
this.state = useState({
|
||||
holidays: [],
|
||||
});
|
||||
useBus(this.env.timeOffBus, 'update_dashboard', async () => {
|
||||
await this.loadDashboardData()
|
||||
});
|
||||
|
||||
onWillStart(async () => {
|
||||
await this.loadDashboardData();
|
||||
});
|
||||
}
|
||||
|
||||
async loadDashboardData() {
|
||||
const context = {};
|
||||
if (this.props.employeeId !== null) {
|
||||
context['employee_id'] = this.props.employeeId;
|
||||
}
|
||||
|
||||
this.state.holidays = await this.orm.call(
|
||||
'hr.leave.type',
|
||||
'get_days_all_request',
|
||||
[],
|
||||
{
|
||||
context: context
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TimeOffDashboard.components = { TimeOffCard };
|
||||
TimeOffDashboard.template = 'hr_holidays.TimeOffDashboard';
|
||||
TimeOffDashboard.props = ['employeeId'];
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.o_timeoff_dashboard {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
height: auto;
|
||||
box-shadow: inset 0 -1px 0 $border-color;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background-color: $o-webclient-background-color;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<div t-name="hr_holidays.TimeOffDashboard" owl="1" class="o_timeoff_dashboard">
|
||||
<t t-foreach="state.holidays" t-as="holiday" t-key="holiday[3]">
|
||||
<TimeOffCard name="holiday[0]" data="holiday[1]" requires_allocation="holiday[2] == 'yes'" id="holiday[3]"/>
|
||||
</t>
|
||||
</div>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Annual_Time_Off" data-name="Annual Time Off">
|
||||
<g>
|
||||
<rect x="13.34" y="24.39" width="73.32" height="59.4" rx="6.37" stroke-width="5" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
<g>
|
||||
<path d="M30.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M52.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,1,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M74.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,1,0,5,0Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<path d="M13.35,43.32h73.3c3.22,0,3.22-5,0-5H13.35c-3.22,0-3.22,5,0,5Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<polyline points="28.57 55.08 36.01 55.08 36.01 69.96 28.56 69.96" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"/>
|
||||
<g>
|
||||
<line x1="28.56" y1="62.47" x2="35.54" y2="62.47" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"/>
|
||||
<polyline points="46.29 62.47 53.73 62.47 53.73 69.96 46.29 69.96 46.29 55.08 53.74 55.08" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"/>
|
||||
<polyline points="71.44 55.08 64 55.08 64 62.47 71.44 62.47 71.44 69.96 64 69.96" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,16 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Annual_Time_Off" data-name="Annual Time Off">
|
||||
<g>
|
||||
<rect x="13.34" y="24.39" width="73.32" height="59.4" rx="6.37" stroke-width="5" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
<g>
|
||||
<path d="M30.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M52.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,1,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M74.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,1,0,5,0Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M86.65,40.82H13.35v36.6l3.32,6.21,63.63.16,7.62-3.5ZM38,70a2,2,0,0,1-2,2H28.56a2,2,0,0,1,0-4H34V64.47H28.56a2,2,0,0,1,0-4H34V57.08H28.57a2,2,0,0,1,0-4H36a2,2,0,0,1,2,2Zm15.72-9.49a2,2,0,0,1,2,2V70a2,2,0,0,1-2,2H46.29a2,2,0,0,1-2-2V55.08a2,2,0,0,1,2-2h7.45a2,2,0,0,1,0,4H48.29v3.39Zm17.71,0a2,2,0,0,1,2,2V70a2,2,0,0,1-2,2H64a2,2,0,1,1,0-4h5.44V64.47H64a2,2,0,0,1-2-2V55.08a2,2,0,0,1,2-2h7.44a2,2,0,0,1,0,4H66v3.39Z" fill="#875b7b"/>
|
||||
<rect x="48.29" y="64.47" width="3.44" height="3.49" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,20 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Annual_Time_Off" data-name="Annual Time Off">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M30.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M52.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,1,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M74.5,32.12V16.21a2.5,2.5,0,0,0-5,0V32.12a2.5,2.5,0,1,0,5,0Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M36,72H28.56a2,2,0,0,1,0-4H34V57.08H28.57a2,2,0,0,1,0-4H36a2,2,0,0,1,2,2V70A2,2,0,0,1,36,72Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M35.54,64.47h-7a2,2,0,0,1,0-4h7a2,2,0,0,1,0,4Z" fill="#875b7b"/>
|
||||
<path d="M53.73,72H46.29a2,2,0,0,1-2-2V55.08a2,2,0,0,1,2-2h7.45a2,2,0,0,1,0,4H48.29v3.39h5.44a2,2,0,0,1,2,2V70A2,2,0,0,1,53.73,72Zm-5.44-4h3.44V64.47H48.29Z" fill="#875b7b"/>
|
||||
<path d="M71.44,72H64a2,2,0,1,1,0-4h5.44V64.47H64a2,2,0,0,1-2-2V55.08a2,2,0,0,1,2-2h7.44a2,2,0,0,1,0,4H66v3.39h5.44a2,2,0,0,1,2,2V70A2,2,0,0,1,71.44,72Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M80.29,21.89H79.5V32.12a7.53,7.53,0,0,1-7.27,7.49h-.32a7.56,7.56,0,0,1-7.41-7.5V21.89h-7V32.12a7.53,7.53,0,0,1-7.27,7.49h-.32a7.56,7.56,0,0,1-7.41-7.5V21.89h-7V32.12a7.53,7.53,0,0,1-7.27,7.49h-.32a7.56,7.56,0,0,1-7.41-7.5V21.89h-.79a8.88,8.88,0,0,0-8.87,8.87V77.42a8.88,8.88,0,0,0,8.87,8.87H80.29a8.88,8.88,0,0,0,8.87-8.87V30.76A8.88,8.88,0,0,0,80.29,21.89Zm3.87,55.53a3.87,3.87,0,0,1-3.87,3.87H19.71a3.87,3.87,0,0,1-3.87-3.87V43.32H84.16Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Compensatory_Time_Off" data-name="Compensatory Time Off">
|
||||
<g>
|
||||
<line x1="23.12" y1="26.88" x2="76.88" y2="26.88" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="23.12" y1="84.74" x2="76.88" y2="84.74" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="50" y1="15.26" x2="50" y2="84.66" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="23.45" y1="27.4" x2="11.73" y2="58.24" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="35.24" y1="57.87" x2="23.52" y2="27.03" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M23.92,75.75a16.87,16.87,0,0,0,16.55-13.6,2.67,2.67,0,0,0-2.6-3.2H10a2.67,2.67,0,0,0-2.6,3.2A16.87,16.87,0,0,0,23.92,75.75Z" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
<line x1="75.62" y1="27.4" x2="63.9" y2="58.24" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="87.41" y1="57.87" x2="75.69" y2="27.03" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M76.08,75.75a16.87,16.87,0,0,0,16.56-13.6A2.67,2.67,0,0,0,90,59H62.13a2.67,2.67,0,0,0-2.6,3.2A16.87,16.87,0,0,0,76.08,75.75Z" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Compensatory_Time_Off" data-name="Compensatory Time Off">
|
||||
<g>
|
||||
<line x1="23.12" y1="26.88" x2="76.88" y2="26.88" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="23.12" y1="84.74" x2="76.88" y2="84.74" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="50" y1="15.26" x2="50" y2="84.66" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="23.45" y1="27.4" x2="11.73" y2="61.24" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="35.24" y1="60.87" x2="23.52" y2="27.03" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M23.92,75.75a16.87,16.87,0,0,0,16.55-13.6,2.67,2.67,0,0,0-2.6-3.2H10a2.67,2.67,0,0,0-2.6,3.2A16.87,16.87,0,0,0,23.92,75.75Z" fill="#875b7b"/>
|
||||
<line x1="75.62" y1="27.4" x2="63.9" y2="61.24" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="87.41" y1="60.87" x2="75.69" y2="27.03" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M76.08,75.75a16.87,16.87,0,0,0,16.56-13.6A2.67,2.67,0,0,0,90,59H62.13a2.67,2.67,0,0,0-2.6,3.2A16.87,16.87,0,0,0,76.08,75.75Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Compensatory_Time_Off" data-name="Compensatory Time Off">
|
||||
<g>
|
||||
<polyline points="23.12 66.91 23.12 29.88 76.88 19.88 76.88 59.29" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="23.12" y1="84.74" x2="76.88" y2="84.74" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="50" y1="15.26" x2="50" y2="84.66" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M23.92,75.75a16.87,16.87,0,0,0,16.55-13.6,2.67,2.67,0,0,0-2.6-3.2H10a2.67,2.67,0,0,0-2.6,3.2A16.87,16.87,0,0,0,23.92,75.75Z" fill="#875b7b"/>
|
||||
<path d="M76.08,65.75a16.87,16.87,0,0,0,16.56-13.6A2.67,2.67,0,0,0,90,49H62.13a2.67,2.67,0,0,0-2.6,3.2A16.87,16.87,0,0,0,76.08,65.75Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 940 B |
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Credit_Time" data-name="Credit Time">
|
||||
<g>
|
||||
<path d="M50,88.84A36.55,36.55,0,1,1,86.55,52.29,36.59,36.59,0,0,1,50,88.84Zm0-68.09A31.55,31.55,0,1,0,81.55,52.29,31.59,31.59,0,0,0,50,20.75Z" fill="#875b7b"/>
|
||||
<path d="M41.35,16.66h17.3a2.5,2.5,0,0,0,0-5H41.35a2.5,2.5,0,0,0,0,5Z" fill="#875b7b"/>
|
||||
<path d="M41.35,13.66h17.3a2.5,2.5,0,0,0,0-5H41.35a2.5,2.5,0,0,0,0,5Z" fill="#875b7b"/>
|
||||
<path d="M70.66,22.86l2.23,2.23a1.92,1.92,0,0,0,.8.52,2.32,2.32,0,0,0,1.93,0,2,2,0,0,0,.81-.52l.39-.51a2.5,2.5,0,0,0,.34-1.26l-.09-.66a2.5,2.5,0,0,0-.64-1.1l-2.24-2.24a1.83,1.83,0,0,0-.8-.51,2.23,2.23,0,0,0-1.93,0,1.83,1.83,0,0,0-.8.51l-.39.51a2.43,2.43,0,0,0-.34,1.26l.08.67a2.52,2.52,0,0,0,.65,1.1Z" fill="#875b7b"/>
|
||||
<path d="M60.78,36.56a13.49,13.49,0,0,0-8.6-3.94V29.87c0-3.21-5-3.22-5,0V33A11.57,11.57,0,0,0,38.43,43.3a11.44,11.44,0,0,0,8.75,11.9V68.42a8.48,8.48,0,0,1-4.42-2.36,2.18,2.18,0,0,1-.64-1.55V61.46A2.5,2.5,0,0,0,39.64,59h0a2.51,2.51,0,0,0-2.5,2.49v3a7.25,7.25,0,0,0,2.1,5.11,13.49,13.49,0,0,0,8,3.87v1.24c0,3.22,5,3.22,5,0V73.34a11.59,11.59,0,0,0,9.39-10.49,11.46,11.46,0,0,0-9.39-12V37.64a8.5,8.5,0,0,1,5.06,2.45,2.15,2.15,0,0,1,.64,1.55v3a2.49,2.49,0,0,0,2.49,2.51h0a2.51,2.51,0,0,0,2.5-2.49V41.66A7.21,7.21,0,0,0,60.78,36.56ZM45.16,48.49a6.4,6.4,0,0,1,2-10.24V50A6.52,6.52,0,0,1,45.16,48.49Zm11.42,14a6.5,6.5,0,0,1-4.4,5.63V56a6.49,6.49,0,0,1,4.4,6.58Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Credit_Time" data-name="Credit Time">
|
||||
<path d="M50,88.84A36.55,36.55,0,1,1,86.55,52.29,36.59,36.59,0,0,1,50,88.84Zm0-68.09A31.55,31.55,0,1,0,81.55,52.29,31.59,31.59,0,0,0,50,20.75Z" fill="#875b7b"/>
|
||||
<path d="M41.35,16.66h17.3a2.5,2.5,0,0,0,0-5H41.35a2.5,2.5,0,0,0,0,5Z" fill="#875b7b"/>
|
||||
<path d="M41.35,13.66h17.3a2.5,2.5,0,0,0,0-5H41.35a2.5,2.5,0,0,0,0,5Z" fill="#875b7b"/>
|
||||
<path d="M70.66,22.86l2.23,2.23a1.92,1.92,0,0,0,.8.52,2.32,2.32,0,0,0,1.93,0,2,2,0,0,0,.81-.52l.39-.51a2.5,2.5,0,0,0,.34-1.26l-.09-.66a2.5,2.5,0,0,0-.64-1.1l-2.24-2.24a1.83,1.83,0,0,0-.8-.51,2.23,2.23,0,0,0-1.93,0,1.83,1.83,0,0,0-.8.51l-.39.51a2.43,2.43,0,0,0-.34,1.26l.08.67a2.52,2.52,0,0,0,.65,1.1Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M43.42,43.62A6.5,6.5,0,0,0,47.18,50V38.25A6.47,6.47,0,0,0,43.42,43.62Z" fill="#875b7b"/>
|
||||
<path d="M52.18,68.16a6.44,6.44,0,0,0,0-12.21Z" fill="#875b7b"/>
|
||||
<path d="M50,24.51A27.49,27.49,0,1,0,77.49,52,27.49,27.49,0,0,0,50,24.51Zm12.87,20.2a2.51,2.51,0,0,1-2.5,2.49h0a2.49,2.49,0,0,1-2.49-2.51v-3a2.15,2.15,0,0,0-.64-1.55,8.5,8.5,0,0,0-5.06-2.45V50.81a11.45,11.45,0,0,1,0,22.53v1.37c0,3.22-5,3.22-5,0V73.47a13.49,13.49,0,0,1-8-3.87,7.25,7.25,0,0,1-2.1-5.11v-3A2.51,2.51,0,0,1,39.63,59h0a2.5,2.5,0,0,1,2.49,2.51v3.05a2.18,2.18,0,0,0,.64,1.55,8.48,8.48,0,0,0,4.42,2.36V55.2a11.43,11.43,0,0,1,0-22.23v-3.1c0-3.22,5-3.21,5,0v2.75a13.49,13.49,0,0,1,8.6,3.94,7.21,7.21,0,0,1,2.1,5.1Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,14 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Extra_Time_Off" data-name="Extra Time Off">
|
||||
<g>
|
||||
<path d="M56.9,12.07a2.73,2.73,0,0,1,2.79,2.63l.46,9.13A2.77,2.77,0,0,0,64.5,26L72,20.75a2.71,2.71,0,0,1,1.58-.52A2.78,2.78,0,0,1,76,24.28l-4.16,8.13a2.77,2.77,0,0,0,2.45,4h.24l9.11-.76.26,0a2.77,2.77,0,0,1,1.47,5.1l-7.67,5a2.77,2.77,0,0,0,.33,4.83l8.26,3.89a2.76,2.76,0,0,1-1,5.26l-9.13.46A2.77,2.77,0,0,0,74,64.5L79.25,72A2.78,2.78,0,0,1,77,76.36,2.82,2.82,0,0,1,75.72,76l-8.13-4.16a2.82,2.82,0,0,0-1.26-.31,2.77,2.77,0,0,0-2.76,3l.76,9.11a2.74,2.74,0,0,1-2.79,3,2.67,2.67,0,0,1-2.29-1.27l-5-7.67A2.72,2.72,0,0,0,52,76.48a2.75,2.75,0,0,0-2.51,1.59l-3.89,8.26a2.66,2.66,0,0,1-2.47,1.6,2.73,2.73,0,0,1-2.79-2.63l-.46-9.13A2.77,2.77,0,0,0,35.5,74L28,79.25a2.71,2.71,0,0,1-1.58.52,2.78,2.78,0,0,1-2.46-4l4.16-8.13a2.77,2.77,0,0,0-2.45-4h-.24l-9.11.76-.26,0a2.77,2.77,0,0,1-1.47-5.1l7.67-5a2.77,2.77,0,0,0-.33-4.83l-8.26-3.89a2.76,2.76,0,0,1,1-5.26l9.13-.46A2.77,2.77,0,0,0,26,35.5L20.75,28A2.78,2.78,0,0,1,23,23.64a2.82,2.82,0,0,1,1.28.32l8.13,4.16a2.76,2.76,0,0,0,4-2.69l-.76-9.11a2.74,2.74,0,0,1,2.79-3,2.67,2.67,0,0,1,2.29,1.27l5,7.67A2.72,2.72,0,0,0,48,23.52a2.75,2.75,0,0,0,2.51-1.59l3.89-8.26a2.66,2.66,0,0,1,2.47-1.6m0-4h0A6.67,6.67,0,0,0,50.81,12l-3,6.26L44.1,12.41a6.69,6.69,0,0,0-5.64-3.09,6.88,6.88,0,0,0-5.05,2.2,6.67,6.67,0,0,0-1.73,5.14l.58,6.89L26.1,20.4a6.67,6.67,0,0,0-3.1-.76,6.78,6.78,0,0,0-6,3.67,6.65,6.65,0,0,0,.46,7L21.41,36l-6.91.35A6.77,6.77,0,0,0,12,49.19l6.26,3L12.41,55.9a6.77,6.77,0,0,0,3.65,12.45l.6,0,6.89-.58L20.4,73.9a6.68,6.68,0,0,0,.22,6.58,6.85,6.85,0,0,0,5.8,3.29,6.75,6.75,0,0,0,3.86-1.23l5.68-4,.35,6.91A6.76,6.76,0,0,0,49.19,88l3-6.26,3.76,5.81a6.69,6.69,0,0,0,5.64,3.09,6.88,6.88,0,0,0,5.05-2.2,6.68,6.68,0,0,0,1.73-5.14l-.58-6.89L73.9,79.6a6.67,6.67,0,0,0,3.1.76,6.78,6.78,0,0,0,6-3.67,6.65,6.65,0,0,0-.46-7l-4-5.68,6.91-.35A6.77,6.77,0,0,0,88,50.81l-6.26-3,5.81-3.76a6.77,6.77,0,0,0-3.65-12.45l-.6,0-6.89.58L79.6,26.1a6.68,6.68,0,0,0-.22-6.58,6.85,6.85,0,0,0-5.8-3.29,6.75,6.75,0,0,0-3.86,1.23L64,21.41l-.35-6.91A6.71,6.71,0,0,0,56.9,8.07Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M34.89,56.11a1.26,1.26,0,0,0,.35-1.73A1.28,1.28,0,0,0,33.5,54l-2.75,1.84a1.23,1.23,0,0,0-.41.49,1.08,1.08,0,0,0-.06,1,1,1,0,0,0,.11.2s0,0,0,0l5.13,7.64a1.17,1.17,0,0,0,1.61.37,1.73,1.73,0,0,0,.24-.1L40,63.75a1.25,1.25,0,0,0-1.39-2.08l-1.72,1.15L35.66,61l1.69-1.13A1.25,1.25,0,0,0,36,57.75l-1.68,1.13-1.09-1.62Z" fill="#875b7b"/>
|
||||
<path d="M41.05,49.06a1.51,1.51,0,0,0-1,1.85v0h0a1.5,1.5,0,0,0-1.84,2.36l3.22,2.52,1.1,3.93a1.5,1.5,0,0,0,1.85,1,1.48,1.48,0,0,0,1-1.85h0a1.5,1.5,0,0,0,1.76.06,1.32,1.32,0,0,0,.35-.32,1.51,1.51,0,0,0-.26-2.11L44,54,42.9,50.1A1.51,1.51,0,0,0,41.05,49.06Z" fill="#875b7b"/>
|
||||
<path d="M48.13,44.21l-2.79,1.87A1.26,1.26,0,0,0,45,47.81a1.28,1.28,0,0,0,1.74.35l.31-.22,4.46,6.65a1.25,1.25,0,0,0,2.08-1.39l-4.46-6.65.39-.26a1.25,1.25,0,0,0-1.39-2.08Z" fill="#875b7b"/>
|
||||
<path d="M58.44,45.63l.82-.55a1.29,1.29,0,0,0,.53-.8,1.25,1.25,0,0,0-.19-.94l-.07-.07-2.36-3.51a1.26,1.26,0,0,0-1.73-.34l-2.58,1.73a1.22,1.22,0,0,0-.63,1.63s0,0,0,0l.08.15,5.11,7.61a1.25,1.25,0,0,0,2.08-1.39l-.42-.63,1.74.65a1.23,1.23,0,0,0,1.6-.74,1.23,1.23,0,0,0-.73-1.6Zm-1.63-1.92-.67.45-1-1.52.66-.45Z" fill="#875b7b"/>
|
||||
<path d="M62.5,34.6l-2.58,1.73a1.27,1.27,0,0,0-.48.66,1,1,0,0,0,0,.62.44.44,0,0,0,0,.1.76.76,0,0,0,0,.11.85.85,0,0,0,.13.25l5.1,7.6a1.25,1.25,0,0,0,2.08-1.39L64.83,41.4l.72-.49,2,2.93a1.25,1.25,0,0,0,2.08-1.4l-5.17-7.7A1.21,1.21,0,0,0,62.5,34.6Zm.93,4.72-1.08-1.61.73-.49,1.08,1.62Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -0,0 +1,9 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Extra_Time_Off" data-name="Extra Time Off">
|
||||
<g>
|
||||
<path d="M62.35,37.71l1.08,1.61.73-.48-1.08-1.62Z" fill="#875b7b"/>
|
||||
<path d="M55.13,42.64c.34.5.68,1,1,1.52l.67-.45-1-1.52Z" fill="#875b7b"/>
|
||||
<path d="M86.33,54.43l-8.26-3.89a2.77,2.77,0,0,1-.33-4.83l7.67-5a2.76,2.76,0,0,0-1.73-5.08l-9.11.76a2.77,2.77,0,0,1-2.69-4L76,24.28a2.77,2.77,0,0,0-4-3.53L64.5,26a2.77,2.77,0,0,1-4.35-2.13l-.46-9.13a2.76,2.76,0,0,0-5.26-1l-3.89,8.26a2.77,2.77,0,0,1-4.83.33l-5-7.67a2.76,2.76,0,0,0-5.08,1.73l.76,9.11a2.77,2.77,0,0,1-4,2.69L24.28,24a2.77,2.77,0,0,0-3.53,4L26,35.5a2.77,2.77,0,0,1-2.13,4.35l-9.13.46a2.76,2.76,0,0,0-1,5.26l8.26,3.89a2.77,2.77,0,0,1,.33,4.83l-7.67,5a2.76,2.76,0,0,0,1.73,5.08l9.11-.76a2.77,2.77,0,0,1,2.69,4L24,75.72a2.77,2.77,0,0,0,4,3.53L35.5,74a2.77,2.77,0,0,1,4.35,2.13l.46,9.13a2.76,2.76,0,0,0,5.26,1l3.89-8.26a2.77,2.77,0,0,1,4.83-.33l5,7.67a2.76,2.76,0,0,0,5.08-1.73l-.76-9.11a2.77,2.77,0,0,1,4-2.69L75.72,76a2.77,2.77,0,0,0,3.53-4L74,64.5a2.77,2.77,0,0,1,2.13-4.35l9.13-.46A2.76,2.76,0,0,0,86.33,54.43ZM40,63.75l-2.64,1.77a1.73,1.73,0,0,1-.24.1,1.17,1.17,0,0,1-1.61-.37L30.4,57.61s0,0,0,0a1,1,0,0,1-.11-.2,1.08,1.08,0,0,1,.06-1,1.23,1.23,0,0,1,.41-.49L33.5,54a1.28,1.28,0,0,1,1.74.34,1.26,1.26,0,0,1-.35,1.73l-1.71,1.15,1.09,1.62L36,57.75a1.25,1.25,0,0,1,1.4,2.08L35.66,61l1.25,1.86,1.72-1.15A1.25,1.25,0,0,1,40,63.75Zm7.47-5.09a1.52,1.52,0,0,1-2.11.26h0a1.5,1.5,0,1,1-2.89.81l-1.1-3.93-3.22-2.52A1.5,1.5,0,0,1,40,50.92h0v0a1.5,1.5,0,1,1,2.89-.81L44,54l3.23,2.51A1.51,1.51,0,0,1,47.49,58.66Zm4-4.07c-1.49-2.21-3-4.43-4.46-6.65l-.31.22A1.28,1.28,0,0,1,45,47.81a1.26,1.26,0,0,1,.34-1.73l2.79-1.87a1.25,1.25,0,0,1,1.39,2.08l-.39.26c1.48,2.22,3,4.43,4.46,6.65A1.25,1.25,0,0,1,51.51,54.59Zm10.92-6.14a1.23,1.23,0,0,1-1.6.74l-1.74-.65.42.63a1.25,1.25,0,0,1-2.08,1.39L52.32,43l-.08-.15v0a1.22,1.22,0,0,1,.63-1.63l2.58-1.73a1.26,1.26,0,0,1,1.73.34l2.36,3.51.07.07a1.25,1.25,0,0,1,.19.94,1.29,1.29,0,0,1-.53.8l-.82.55,3.26,1.22A1.23,1.23,0,0,1,62.43,48.45Zm5.08-4.61-2-2.93-.72.49,1.93,2.88a1.25,1.25,0,0,1-2.08,1.39l-5.1-7.6a.85.85,0,0,1-.13-.25.76.76,0,0,1,0-.11.44.44,0,0,1,0-.1,1,1,0,0,1,0-.62,1.27,1.27,0,0,1,.48-.66L62.5,34.6a1.21,1.21,0,0,1,1.92.14l5.17,7.7A1.25,1.25,0,0,1,67.51,43.84Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
|
@ -0,0 +1,17 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Maternity_Time_Off" data-name="Maternity Time Off">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M63,11.81H53.58V38.42H20.75v2.35a24,24,0,0,0,24,24H63a24,24,0,0,0,24-24v-5A24,24,0,0,0,63,11.81Z" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M46.1,40.92H86.75c3.21,0,3.22-5,0-5H46.1c-3.22,0-3.23,5,0,5Z" fill="#875b7b"/>
|
||||
<path d="M23.25,38.52V23.4a2.53,2.53,0,0,0-2.5-2.5H13a2.5,2.5,0,0,0,0,5h7.71l-2.5-2.5V38.52a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<circle cx="28.65" cy="79.82" r="8.37" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<circle cx="78.1" cy="79.82" r="8.37" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M80.64,71.45V59.26a2.5,2.5,0,0,0-5,0V71.45a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M31.25,71.45V59.68a2.5,2.5,0,0,0-5,0V71.45a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<path d="M28.66,82.27c3.22,0,3.22-5,0-5s-3.22,5,0,5Z" fill="#875b7b"/>
|
||||
<path d="M78.08,82.27c3.21,0,3.22-5,0-5s-3.23,5,0,5Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Maternity_Time_Off" data-name="Maternity Time Off">
|
||||
<g>
|
||||
<path d="M89.46,40.77v-5A26.51,26.51,0,0,0,63,9.31H53.58a2.5,2.5,0,0,0-2.5,2.5V35.92H23.25V23.4a2.53,2.53,0,0,0-2.5-2.5H13a2.5,2.5,0,0,0,0,5h5.21V40.77a26.41,26.41,0,0,0,8,18.94v9.51a10.89,10.89,0,1,0,5,0V63.55a26.38,26.38,0,0,0,13.48,3.7H63A26.25,26.25,0,0,0,75.64,64v5.22a10.87,10.87,0,1,0,5,0V60.48A26.41,26.41,0,0,0,89.46,40.77ZM63,14.31A21.49,21.49,0,0,1,84.46,35.79v.13H56.08V14.31ZM44.73,62.25A21.5,21.5,0,0,1,23.25,40.92h61.2a21.39,21.39,0,0,1-7.64,16.26,2.89,2.89,0,0,0-.47.38A21.33,21.33,0,0,1,63,62.25Z" fill="#875b7b"/>
|
||||
<polygon points="21.36 39.59 22.89 51.45 32.66 62.33 55.54 65.12 78.42 60.8 86.94 47.4 86.94 37.63 21.36 39.59" fill="#875b7b"/>
|
||||
<line x1="54.7" y1="36.38" x2="69.77" y2="13.5" fill="#875b7b" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
<path d="M28.66,82.27c3.22,0,3.22-5,0-5s-3.22,5,0,5Z" fill="#875b7b"/>
|
||||
<path d="M78.08,82.27c3.21,0,3.22-5,0-5s-3.23,5,0,5Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<line x1="85.12" y1="24.8" x2="54.7" y2="36.38" fill="#875b7b" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,19 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Maternity_Time_Off" data-name="Maternity Time Off">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M23.25,38.52V23.4a2.53,2.53,0,0,0-2.5-2.5H13a2.5,2.5,0,0,0,0,5h7.71l-2.5-2.5V38.52a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M28.65,90.69A10.87,10.87,0,1,1,39.53,79.82,10.89,10.89,0,0,1,28.65,90.69Zm0-16.74a5.87,5.87,0,1,0,5.88,5.87A5.87,5.87,0,0,0,28.65,74Z" fill="#875b7b"/>
|
||||
<path d="M78.1,90.69A10.87,10.87,0,1,1,89,79.82,10.89,10.89,0,0,1,78.1,90.69ZM78.1,74A5.87,5.87,0,1,0,84,79.82,5.88,5.88,0,0,0,78.1,74Z" fill="#875b7b"/>
|
||||
<path d="M80.64,71.45V59.26a2.5,2.5,0,0,0-5,0V71.45a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M31.25,71.45V59.68a2.5,2.5,0,0,0-5,0V71.45a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M63,14.31H56.08V35.92H84.46v-.13A21.49,21.49,0,0,0,63,14.31Z" fill="none"/>
|
||||
<path d="M89.46,35.79A26.51,26.51,0,0,0,63,9.31H53.58a2.5,2.5,0,0,0-2.5,2.5V35.92H20.75a2.5,2.5,0,0,0-2.5,2.5v2.35a26.36,26.36,0,0,0,4.39,14.59,7.65,7.65,0,0,1,5.88-3.17h.32a7.55,7.55,0,0,1,7.41,7.5v6.17a26.41,26.41,0,0,0,8.48,1.4H63a26.13,26.13,0,0,0,7.65-1.14V59.26a7.54,7.54,0,0,1,7.28-7.49h.32a7.49,7.49,0,0,1,6.53,4,26.31,26.31,0,0,0,4.69-15Zm-5,.13H56.08V14.31H63A21.49,21.49,0,0,1,84.46,35.79Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M28.66,82.27c3.22,0,3.22-5,0-5s-3.22,5,0,5Z" fill="#875b7b"/>
|
||||
<path d="M78.08,82.27c3.21,0,3.22-5,0-5s-3.23,5,0,5Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Paid_Time_Off" data-name="Paid Time Off">
|
||||
<g>
|
||||
<path d="M21.46,61.83a3,3,0,0,1,4.24-.27L39.5,73.7H78.9a3,3,0,0,1,0,6H74.37v4.81a3,3,0,0,1-6,0V79.7H45.48v4.81a3,3,0,0,1-6,0V79.7H38.37a3,3,0,0,1-2-.75L21.73,66.07A3,3,0,0,1,21.46,61.83Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<rect x="46.5" y="67.63" width="6" height="0.07" fill="#875b7b"/>
|
||||
<path d="M78.87,41.86c0-.18-.09-.36-.09-.54,0-32.94-58-32.94-58,0a5.58,5.58,0,0,1-.1.59c-.2,2.4,2.94,3.29,4.29,1.3,2.45-3.62,10.12-3.71,12.86-.29.57.71,1.84.95,2.26.14,1.88-3.62,17.81-3.54,18.69,0,.21.88,1.66.59,2.23-.11,2.83-3.48,10.92-3.39,13.51.24C76,45.18,79.12,44.25,78.87,41.86Z" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
<path d="M46.5,40.62v27h6v-27A23.17,23.17,0,0,0,46.5,40.62Z" fill="#875b7b"/>
|
||||
<path d="M52.5,11.6a3.08,3.08,0,0,0-2.41-3.06,3,3,0,0,0-3.59,3v3h6Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M40.13,43.06c-4.26-10.68,0-19.27,9.55-26.59" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
<path d="M59.57,43.33c4.26-10.67,0-19.26-9.55-26.58" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Paid_Time_Off" data-name="Paid Time Off">
|
||||
<g>
|
||||
<path d="M21.46,61.83a3,3,0,0,1,4.24-.27L39.5,73.7H78.9a3,3,0,0,1,0,6H74.37v4.81a3,3,0,0,1-6,0V79.7H45.48v4.81a3,3,0,0,1-6,0V79.7H38.37a3,3,0,0,1-2-.75L21.73,66.07A3,3,0,0,1,21.46,61.83Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<rect x="46.5" y="67.63" width="6" height="0.07" fill="#875b7b"/>
|
||||
<path d="M78.87,41.86c0-.18-.09-.36-.09-.54,0-32.94-58-32.94-58,0a5.58,5.58,0,0,1-.1.59c-.2,2.4,2.94,3.29,4.29,1.3,2.45-3.62,10.12-3.71,12.86-.29.57.71,1.84.95,2.26.14,1.88-3.62,17.81-3.54,18.69,0,.21.88,1.66.59,2.23-.11,2.83-3.48,10.92-3.39,13.51.24C76,45.18,79.12,44.25,78.87,41.86Z" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
<path d="M46.5,40.62v27h6v-27A23.17,23.17,0,0,0,46.5,40.62Z" fill="#875b7b"/>
|
||||
<path d="M52.5,11.6a3.08,3.08,0,0,0-2.41-3.06,3,3,0,0,0-3.59,3v3h6Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M21.77,43.82c-3.22-18.89,18.49-25.37,27.4-24.71C43.73,22.74,39,25.49,39,40.56,29.28,37.67,26.2,40.61,21.77,43.82Z" fill="#875b7b"/>
|
||||
<path d="M76,43.91c3.32-19.85-17.83-26.36-26.84-24.8,5.44,3.63,9.12,7.5,9.12,22.57C65.64,39.83,69.39,41.65,76,43.91Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Paid_Time_Off" data-name="Paid Time Off">
|
||||
<g>
|
||||
<path d="M21.46,61.83a3,3,0,0,1,4.24-.27L39.5,73.7H78.9a3,3,0,0,1,0,6H74.37v4.81a3,3,0,0,1-6,0V79.7H45.48v4.81a3,3,0,0,1-6,0V79.7H38.37a3,3,0,0,1-2-.75L21.73,66.07A3,3,0,0,1,21.46,61.83Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<rect x="46.5" y="67.63" width="6" height="0.07" fill="#875b7b"/>
|
||||
<path d="M78.78,41.32A29.93,29.93,0,0,0,52.5,19V15.6a3.08,3.08,0,0,0-2.41-3.06,3,3,0,0,0-3.59,3V19A29.92,29.92,0,0,0,20.82,41.32a4.28,4.28,0,0,0-.1.59c-.2,2.4,2.94,3.29,4.29,1.3,2.45-3.62,10.12-3.71,12.86-.29a1.53,1.53,0,0,0,2.26.14c3.79-3.52,14.93-3.52,18.69,0A1.5,1.5,0,0,0,61.05,43c2.83-3.48,10.92-3.39,13.51.24,1.39,2,4.56,1,4.31-1.35A3.38,3.38,0,0,0,78.78,41.32Z" fill="#875b7b"/>
|
||||
<rect x="46.5" y="38.79" width="6" height="28.84" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 920 B |
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Parental_Time_Off" data-name="Parental Time Off">
|
||||
<path d="M94.89,52.33,87.17,34.94a3.76,3.76,0,0,0-3.86-2.2,5.87,5.87,0,1,0-7.52.21,3.76,3.76,0,0,0-3.11.75,2,2,0,0,0-1.05,1L58.9,47.42A3.74,3.74,0,0,0,58,49.07l-4,1.81A3.74,3.74,0,0,0,52.19,50a4.28,4.28,0,1,0-5.52,0,3.8,3.8,0,0,0-1.89.72l-2.86-2a3.91,3.91,0,0,0-.82-1.22L27.65,34a3.75,3.75,0,0,0-2.81-1.09l-.19-.05a5.88,5.88,0,1,0-7.64,0,3.77,3.77,0,0,0-4.18,2.16L5.11,52.33A3.77,3.77,0,0,0,12,55.38l.4-.89A5.12,5.12,0,0,0,13,56.62V73.69a3.77,3.77,0,0,0,3.77,3.77h0a3.77,3.77,0,0,0,3.77-3.77V59.29h.15V73.67a3.77,3.77,0,1,0,7.54,0V56.41a5.19,5.19,0,0,0,.54-2.26V45.76l7,7a3.74,3.74,0,0,0,3.74.93l3.75,2.67v9.2a3.69,3.69,0,0,0,.48,1.8v7.44a2.75,2.75,0,1,0,5.49,0v-5.5h.11v5.49a2.75,2.75,0,0,0,5.49,0V67.19a3.64,3.64,0,0,0,.4-1.64V56.34l5.6-2.55a3.75,3.75,0,0,0,3.38-1l8.64-8.64.74,4.59a1.61,1.61,0,0,1-.2,1.07L65.7,63.28a1.86,1.86,0,0,0,1.89,2.65h4v7.76a3.77,3.77,0,0,0,7.54,0V65.93h.15v7.74a3.77,3.77,0,0,0,7.54,0V65.93h3.43a1.85,1.85,0,0,0,1.88-2.65l-5.47-9.66a3.78,3.78,0,0,0-.9-1.57l-1.21-2.14a1.62,1.62,0,0,1-.18-1.14l.22-1.07L88,55.38a3.77,3.77,0,0,0,6.89-3.05Z" fill="none" stroke="#875b7b" stroke-linejoin="round" stroke-width="3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Parental_Time_Off" data-name="Parental Time Off">
|
||||
<path d="M94.89,52.33,87.17,34.94a3.76,3.76,0,0,0-3.86-2.2,5.87,5.87,0,1,0-7.52.21,3.76,3.76,0,0,0-3.11.75,2,2,0,0,0-1.05,1L58.9,47.42A3.74,3.74,0,0,0,58,49.07l-4,1.81A3.74,3.74,0,0,0,52.19,50a4.28,4.28,0,1,0-5.52,0,3.8,3.8,0,0,0-1.89.72l-2.86-2a3.91,3.91,0,0,0-.82-1.22L27.65,34a3.75,3.75,0,0,0-2.81-1.09l-.19-.05a5.88,5.88,0,1,0-7.64,0,3.77,3.77,0,0,0-4.18,2.16L5.11,52.33A3.77,3.77,0,0,0,12,55.38l.4-.89A5.12,5.12,0,0,0,13,56.62V73.69a3.77,3.77,0,0,0,3.77,3.77h0a3.77,3.77,0,0,0,3.77-3.77V59.29h.15V73.67a3.77,3.77,0,1,0,7.54,0V56.41a5.19,5.19,0,0,0,.54-2.26V45.76l7,7a3.74,3.74,0,0,0,3.74.93l3.75,2.67v9.2a3.69,3.69,0,0,0,.48,1.8v7.44a2.75,2.75,0,1,0,5.49,0v-5.5h.11v5.49a2.75,2.75,0,0,0,5.49,0V67.19a3.64,3.64,0,0,0,.4-1.64V56.34l5.6-2.55a3.75,3.75,0,0,0,3.38-1l8.64-8.64.74,4.59a1.61,1.61,0,0,1-.2,1.07L65.7,63.28a1.86,1.86,0,0,0,1.89,2.65h4v7.76a3.77,3.77,0,0,0,7.54,0V65.93h.15v7.74a3.77,3.77,0,0,0,7.54,0V65.93h3.43a1.85,1.85,0,0,0,1.88-2.65l-5.47-9.66a3.78,3.78,0,0,0-.9-1.57l-1.21-2.14a1.62,1.62,0,0,1-.18-1.14l.22-1.07L88,55.38a3.77,3.77,0,0,0,6.89-3.05Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,14 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Recovery_Bank_Holiday" data-name="Recovery Bank Holiday">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M57.46,55.29V43.75a2.5,2.5,0,0,0-5,0V55.29a2.5,2.5,0,0,0,5,0Z" fill="#875b7b"/>
|
||||
<path d="M54.78,53.33l-14.85-.08a2.5,2.5,0,0,0,0,5l14.85.08a2.5,2.5,0,0,0,0-5Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M40.52,24.65A30.41,30.41,0,1,1,19.6,53.55c0-.36,0-.72,0-1.07" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M47.38,14.28l-8.52,8.61a2.53,2.53,0,0,0,.51,3.92l9.37,6.05a2.52,2.52,0,0,0,3.42-.9,2.56,2.56,0,0,0-.9-3.42l-9.37-6,.5,3.92,8.53-8.6a2.5,2.5,0,1,0-3.54-3.54Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 771 B |
|
|
@ -0,0 +1,8 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Recovery_Bank_Holiday" data-name="Recovery Bank Holiday">
|
||||
<g>
|
||||
<path d="M20,45a7.48,7.48,0,0,1,7.23,7.76c0,.27,0,.53,0,.8A22.91,22.91,0,1,0,57.55,31.86a7.74,7.74,0,0,1-.81,2.43,7.52,7.52,0,0,1-6.62,3.9,7.19,7.19,0,0,1-3.93-1.14l-8.87-5.72a7.44,7.44,0,0,1-4.07-7.59A34.22,34.22,0,0,0,16.93,45.55,7.42,7.42,0,0,1,19.79,45ZM40.1,53.24l12.52.07V43.74a2.5,2.5,0,0,1,5,0V55.28a2.34,2.34,0,0,1-.21,1,2.56,2.56,0,0,1-2.46,2L40.1,58.24a2.5,2.5,0,0,1,0-5Z" fill="#875b7b"/>
|
||||
<path d="M50.16,20.63c-.65,0-1.3,0-1.95.08,1-1,1.92-1.93,2.87-2.9a2.5,2.5,0,1,0-3.53-3.53l-8.16,8.23a2.48,2.48,0,0,0,.35,4.43l9.16,5.91a2.52,2.52,0,0,0,3.42-.9,2.56,2.56,0,0,0-.89-3.42L47.2,25.81a26.57,26.57,0,0,1,3-.18,27.91,27.91,0,1,1-27.9,27.91c0-.33,0-.65,0-1A2.49,2.49,0,0,0,19.87,50a2.52,2.52,0,0,0-2.59,2.4c0,.39,0,.77,0,1.16a32.91,32.91,0,1,0,32.9-32.91Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 956 B |
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Sick_Time_Off" data-name="Sick Time Off">
|
||||
<g>
|
||||
<path d="M44.38,10.28h6.89a3.1,3.1,0,0,1,3.1,3.1V38.33A21.07,21.07,0,0,1,33.3,59.4h0A21.08,21.08,0,0,1,12.23,38.33V13.39a3.1,3.1,0,0,1,3.11-3.1l6.6,0" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M32.63,59.93v7.84c0,29.27,44.79,29.27,44.79,0V57.82" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<g>
|
||||
<circle cx="77.16" cy="45.77" r="10.6" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M77.19,48.27c3.21,0,3.22-5,0-5s-3.23,5,0,5Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 802 B |
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Sick_Time_Off" data-name="Sick Time Off">
|
||||
<g>
|
||||
<path d="M44.38,10.28h6.89a3.1,3.1,0,0,1,3.1,3.1V38.33A21.07,21.07,0,0,1,33.3,59.4h0A21.08,21.08,0,0,1,12.23,38.33V13.39a3.1,3.1,0,0,1,3.11-3.1l6.6,0" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M32.63,59.93v7.84c0,29.27,44.79,29.27,44.79,0V57.82" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<g>
|
||||
<circle cx="77.16" cy="45.77" r="10.6" fill="#875b7b" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M77.19,48.27c3.21,0,3.22-5,0-5s-3.23,5,0,5Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 805 B |
|
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Small_Unemployement" data-name="Small Unemployement">
|
||||
<path d="M50,86.88A36.88,36.88,0,1,1,86.88,50,36.93,36.93,0,0,1,50,86.88Zm0-68.76A31.88,31.88,0,1,0,81.88,50,31.91,31.91,0,0,0,50,18.12Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M34.9,64.53a2.14,2.14,0,0,1-2.14-2.14V54a49.9,49.9,0,0,0,13.75,3l-7.53-5a45.14,45.14,0,0,1-6.22-2V48l-4-2.63v17a6.14,6.14,0,0,0,6.14,6.14H64l-6.08-4Z" fill="#875b7b"/>
|
||||
<path d="M45.37,35.47h9.26v3.38H46.16L52.49,43H65.1a2.14,2.14,0,0,1,2.14,2.14V50c-.89.33-1.8.63-2.71.91l6.71,4.41V45.15A6.14,6.14,0,0,0,65.1,39H58.63V33.47a2,2,0,0,0-2-2H43.37a2,2,0,0,0-2,2V35.7l4,2.63Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<path d="M78.42,71.53a2.46,2.46,0,0,1-1.37-.41L20.59,34a2.5,2.5,0,0,1,2.74-4.18L79.8,66.94a2.5,2.5,0,0,1-1.38,4.59Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 864 B |
|
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Small_Unemployement" data-name="Small Unemployement">
|
||||
<path d="M50,86.88A36.88,36.88,0,1,1,86.88,50,36.92,36.92,0,0,1,50,86.88Zm0-68.76A31.88,31.88,0,1,0,81.88,50,31.91,31.91,0,0,0,50,18.12Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M71.74,45.15a6.65,6.65,0,0,0-6.64-6.64h-6v-5a2.5,2.5,0,0,0-2.5-2.5H43.37a2.5,2.5,0,0,0-2.5,2.5v1.9L71.74,55.66Zm-17.61-6.8H45.87V36h8.26Z" fill="#875b7b"/>
|
||||
<path d="M28.26,45.15V62.39A6.65,6.65,0,0,0,34.9,69H64.77L28.26,45Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<path d="M78.42,71.53a2.46,2.46,0,0,1-1.37-.41L20.59,34a2.5,2.5,0,0,1,2.74-4.18L79.8,66.94a2.5,2.5,0,0,1-1.38,4.59Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 717 B |
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Small_Unemployement" data-name="Small Unemployement">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M76.31,41.83a8.05,8.05,0,0,0-8-8H61.05v-6.1a3,3,0,0,0-3-3H42a3,3,0,0,0-3,3v6.1h-.74l38.1,25ZM55,33.6H45V30.72H55Z" fill="#875b7b"/>
|
||||
<path d="M23.69,62.69a8,8,0,0,0,8,8H65.67l-42-27.59Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<path d="M82.64,75.33a2.89,2.89,0,0,1-1.59-.47L15.77,31.94A2.89,2.89,0,1,1,19,27.11L84.23,70a2.89,2.89,0,0,1-1.59,5.3Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 549 B |
|
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Training_Time_Off" data-name="Training Time Off">
|
||||
<g>
|
||||
<path d="M47,42.25,8.09,29.61,47.66,17a8.69,8.69,0,0,1,5.22,0l39,12.15L52.44,42.23A8.59,8.59,0,0,1,47,42.25Z" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M24.23,37.5v7.42c0,15.69,51.54,15.69,51.54,0V37.31" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="35.89" y1="38.87" x2="35.89" y2="71.8" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<circle cx="35.94" cy="77.78" r="5.68" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 816 B |
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Training_Time_Off" data-name="Training Time Off">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M21.73,41.93v3c0,2.84,1.25,6.66,6.66,9.72V44.09Z" fill="#875b7b"/>
|
||||
<path d="M49.7,50.18a16.43,16.43,0,0,1-5-.79L43.39,49v9.88a64.34,64.34,0,0,0,6.61.35c14.07,0,28.27-4.41,28.27-14.27V41.53L54.81,49.35A16.23,16.23,0,0,1,49.7,50.18Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<path d="M92.65,26.69l-39-12.14a11.12,11.12,0,0,0-6.73,0L7.33,27.23a2.5,2.5,0,0,0,0,4.76l26.07,8.47V70a8.16,8.16,0,1,0,5,0V42.08l7.86,2.55a11.06,11.06,0,0,0,7,0L92.7,31.45a2.5,2.5,0,0,0,0-4.76Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 666 B |
|
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Unpaid_Time_Off" data-name="Unpaid Time Off">
|
||||
<path d="M50,86.55A36.55,36.55,0,1,1,86.55,50,36.6,36.6,0,0,1,50,86.55Zm0-68.1A31.55,31.55,0,1,0,81.55,50,31.59,31.59,0,0,0,50,18.45Z" fill="#875b7b"/>
|
||||
<path d="M60.78,34.26a13.53,13.53,0,0,0-8.6-3.93V27.58c0-3.22-5-3.22-5,0v3.09A11.57,11.57,0,0,0,38.43,41a11.4,11.4,0,0,0,3.08,8.61,11.55,11.55,0,0,0,5.67,3.29V66.13a8.48,8.48,0,0,1-4.42-2.36,2.2,2.2,0,0,1-.64-1.55v-3a2.5,2.5,0,0,0-2.49-2.51h0a2.51,2.51,0,0,0-2.5,2.49V62.2a7.25,7.25,0,0,0,2.1,5.11,13.55,13.55,0,0,0,8,3.87v1.24c0,3.22,5,3.22,5,0V71.05a11.6,11.6,0,0,0,9.39-10.49,11.46,11.46,0,0,0-9.39-12V35.35a8.5,8.5,0,0,1,5.06,2.45,2.15,2.15,0,0,1,.64,1.55v3a2.49,2.49,0,0,0,2.49,2.51h0a2.51,2.51,0,0,0,2.5-2.49V39.37A7.25,7.25,0,0,0,60.78,34.26ZM45.16,46.2a6.4,6.4,0,0,1,2-10.24v11.7A6.68,6.68,0,0,1,45.16,46.2Zm11.42,14a6.5,6.5,0,0,1-4.4,5.63V53.66a6.38,6.38,0,0,1,2.66,1.71A6.46,6.46,0,0,1,56.58,60.24Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M33.44,40.68a16.67,16.67,0,0,1,.74-3.87L23,29.43a2.49,2.49,0,1,0-2.75,4.15l13.13,8.69C33.4,41.74,33.41,41.21,33.44,40.68Z" fill="#875b7b"/>
|
||||
<path d="M78.88,66.42,66.5,58.22a16.83,16.83,0,0,1,.06,2.66,15.9,15.9,0,0,1-.5,3l10.08,6.67a2.48,2.48,0,1,0,2.74-4.14Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Unpaid_Time_Off" data-name="Unpaid Time Off">
|
||||
<g>
|
||||
<path d="M61.24,34.26a13.53,13.53,0,0,0-8.6-3.93V27.58c0-3.22-5-3.22-5,0v3.09A11.57,11.57,0,0,0,38.89,41a11.44,11.44,0,0,0,8.75,11.9V66.13a8.5,8.5,0,0,1-4.43-2.36,2.19,2.19,0,0,1-.63-1.55v-3a2.5,2.5,0,0,0-2.49-2.51h0a2.5,2.5,0,0,0-2.5,2.49V62.2a7.21,7.21,0,0,0,2.1,5.11,13.52,13.52,0,0,0,8,3.87v1.24c0,3.22,5,3.22,5,0V71.05A11.58,11.58,0,0,0,62,60.56a11.46,11.46,0,0,0-9.38-12V35.35A8.5,8.5,0,0,1,57.7,37.8a2.2,2.2,0,0,1,.64,1.55v3a2.49,2.49,0,0,0,2.48,2.51h0a2.51,2.51,0,0,0,2.5-2.49V39.37A7.25,7.25,0,0,0,61.24,34.26Zm-13.6,13.4a6.56,6.56,0,0,1-2-1.46,6.4,6.4,0,0,1,2-10.24Zm7.66,7.71a6.42,6.42,0,0,1-2.66,10.5V53.66A6.38,6.38,0,0,1,55.3,55.37Z" fill="#875b7b"/>
|
||||
<g>
|
||||
<path d="M80.8,64,66.12,54.35A16.47,16.47,0,0,1,67,60.88a15.83,15.83,0,0,1-1.24,5.22l9.53,6.27a4.93,4.93,0,0,0,2.74.82A5,5,0,0,0,80.8,64Z" fill="#875b7b"/>
|
||||
<path d="M33.9,40.68a16.07,16.07,0,0,1,1.78-6.37L24.42,26.9a5,5,0,0,0-5.5,8.35L34.25,45.34A16.79,16.79,0,0,1,33.9,40.68Z" fill="#875b7b"/>
|
||||
</g>
|
||||
<g>
|
||||
<line x1="78.33" y1="31.08" x2="21.67" y2="68.47" fill="#875b7b"/>
|
||||
<path d="M21.68,73.47a5,5,0,0,1-2.76-9.17L75.57,26.9a5,5,0,0,1,5.51,8.35L24.43,72.64A5,5,0,0,1,21.68,73.47Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Credit_Time" data-name="Credit Time">
|
||||
<path d="M90.13,38.78a5.33,5.33,0,0,0-.28-1.44,1,1,0,0,0,0-.16c-.06-.18-.13-.35-.2-.51a6,6,0,0,0-.3-.56L89.21,36a4.82,4.82,0,0,0-4.15-2.26l-.43.06a4.3,4.3,0,0,0-.62,0H71a5,5,0,0,0,0,10H72.3L61.63,54.44,51.26,44.21s-.08-.06-.12-.1l-9-8.88a4.84,4.84,0,0,0-1.78-1.1,4.94,4.94,0,0,0-5.63.93L19.94,49.85v-2.7a5,5,0,0,0-10,0v13.1a3.93,3.93,0,0,0-.07,1,5.33,5.33,0,0,0,.28,1.44,1.09,1.09,0,0,0,0,.17c.06.17.13.34.2.5a6,6,0,0,0,.3.56l.09.14a4.82,4.82,0,0,0,4.15,2.26l.43-.06a4.3,4.3,0,0,0,.62,0H29a5,5,0,0,0,0-10H27.7L38.37,45.56,48.74,55.79s.08.06.12.1l9,8.88a4.84,4.84,0,0,0,1.78,1.1,4.94,4.94,0,0,0,5.63-.93L80.06,50.15v2.7a5,5,0,0,0,10,0V39.75A3.93,3.93,0,0,0,90.13,38.78Z" fill="none" stroke="#875b7b" stroke-miterlimit="10" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 869 B |
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Credit_Time" data-name="Credit Time">
|
||||
<path d="M90.13,38.78a5.33,5.33,0,0,0-.28-1.44,1,1,0,0,0,0-.16c-.06-.18-.13-.35-.2-.51a6,6,0,0,0-.3-.56L89.21,36a4.82,4.82,0,0,0-4.15-2.26l-.43.06a4.3,4.3,0,0,0-.62,0H71a5,5,0,0,0,0,10H72.3L61.63,54.44,51.26,44.21s-.08-.06-.12-.1l-9-8.88a4.84,4.84,0,0,0-1.78-1.1,4.94,4.94,0,0,0-5.63.93L19.94,49.85v-2.7a5,5,0,0,0-10,0v13.1a3.93,3.93,0,0,0-.07,1,5.33,5.33,0,0,0,.28,1.44,1.09,1.09,0,0,0,0,.17c.06.17.13.34.2.5a6,6,0,0,0,.3.56l.09.14a4.82,4.82,0,0,0,4.15,2.26l.43-.06a4.3,4.3,0,0,0,.62,0H29a5,5,0,0,0,0-10H27.7L38.37,45.56,48.74,55.79s.08.06.12.1l9,8.88a4.84,4.84,0,0,0,1.78,1.1,4.94,4.94,0,0,0,5.63-.93L80.06,50.15v2.7a5,5,0,0,0,10,0V39.75A3.93,3.93,0,0,0,90.13,38.78Z" fill="#875b7b"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 815 B |
|
|
@ -0,0 +1,11 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Work_Accident_Time_Off" data-name="Work Accident Time Off">
|
||||
<g>
|
||||
<path d="M39,44.17H61A20.59,20.59,0,0,1,81.63,64.75V89.91a0,0,0,0,1,0,0H27.2a8.82,8.82,0,0,1-8.82-8.82V64.75A20.59,20.59,0,0,1,39,44.17Z" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<circle cx="50" cy="27.11" r="17.02" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M63.63,89.8c11.79,0,11.79-16.12,0-16.12H58.5" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="26.87" y1="48.15" x2="37.68" y2="88.75" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<line x1="38.96" y1="44.17" x2="67.63" y2="89.68" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 998 B |
|
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<g id="Work_Accident_Time_Off" data-name="Work Accident Time Off">
|
||||
<g>
|
||||
<path d="M39,44.17H61A20.59,20.59,0,0,1,81.63,64.75V89.91a0,0,0,0,1,0,0H27.2a8.82,8.82,0,0,1-8.82-8.82V64.75A20.59,20.59,0,0,1,39,44.17Z" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<circle cx="50" cy="27.11" r="17.02" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<path d="M34,73.68H63.63c11.79,0,11.79,16.12,0,16.12" fill="none" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
<polygon points="37.68 88.75 26.87 48.15 38.96 44.17 67.64 89.68 37.68 88.75" fill="#875b7b" stroke="#875b7b" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 877 B |
|
|
@ -0,0 +1,17 @@
|
|||
/** @odoo-module **/
|
||||
import FieldRegistry from 'web.field_registry';
|
||||
import basic_fields from 'web.basic_fields';
|
||||
|
||||
var FieldFloat = basic_fields.FieldFloat;
|
||||
|
||||
var FloatWithoutTrailingZeros = FieldFloat.extend({
|
||||
_renderReadonly: function () {
|
||||
var value = this._formatValue(this.value);
|
||||
var parsed_value = parseFloat(value);
|
||||
value = parsed_value.toString().replace(/\.0+$/, '');
|
||||
this.$el.text(value);
|
||||
}
|
||||
});
|
||||
|
||||
FieldRegistry.add('float_without_trailing_zeros', FloatWithoutTrailingZeros);
|
||||
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/* @odoo-module */
|
||||
|
||||
import { useService } from '@web/core/utils/hooks';
|
||||
import { registry } from '@web/core/registry'
|
||||
|
||||
import { formatDate } from "@web/core/l10n/dates";
|
||||
|
||||
const { Component, useState, onWillStart, onWillUpdateProps } = owl;
|
||||
const { DateTime } = luxon;
|
||||
|
||||
export class LeaveStatsComponent extends Component {
|
||||
setup() {
|
||||
this.orm = useService('orm');
|
||||
|
||||
this.state = useState({
|
||||
leaves: [],
|
||||
departmentLeaves: [],
|
||||
});
|
||||
|
||||
this.date = this.props.record.data.date_from || DateTime.now();
|
||||
this.department = this.props.record.data.department_id;
|
||||
this.employee = this.props.record.data.employee_id;
|
||||
|
||||
onWillStart(async () => {
|
||||
await this.loadLeaves(this.date, this.employee);
|
||||
await this.loadDepartmentLeaves(this.date, this.department, this.employee);
|
||||
});
|
||||
onWillUpdateProps(async (nextProps) => {
|
||||
const dateFrom = nextProps.record.data.date_from || DateTime.now();
|
||||
const dateChanged = this.date !== dateFrom;
|
||||
const employee = nextProps.record.data.employee_id;
|
||||
const department = nextProps.record.data.department_id;
|
||||
|
||||
if (dateChanged || employee && (this.employee && this.employee[0]) !== employee[0]) {
|
||||
await this.loadLeaves(dateFrom, employee);
|
||||
}
|
||||
|
||||
if (dateChanged || department && (this.department && this.department[0]) !== department[0]) {
|
||||
await this.loadDepartmentLeaves(dateFrom, department, employee);
|
||||
}
|
||||
|
||||
this.date = dateFrom;
|
||||
this.employee = employee;
|
||||
this.department = department;
|
||||
})
|
||||
}
|
||||
|
||||
get thisYear() {
|
||||
return this.date.toFormat('yyyy');
|
||||
}
|
||||
|
||||
async loadDepartmentLeaves(date, department, employee) {
|
||||
if (!(department && employee && date)) {
|
||||
this.state.departmentLeaves = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const dateFrom = date.startOf('month');
|
||||
const dateTo = date.endOf('month');
|
||||
|
||||
const departmentLeaves = await this.orm.searchRead(
|
||||
'hr.leave',
|
||||
[
|
||||
['department_id', '=', department[0]],
|
||||
['state', '=', 'validate'],
|
||||
['holiday_type', '=', 'employee'],
|
||||
['date_from', '<=', dateTo],
|
||||
['date_to', '>=', dateFrom],
|
||||
],
|
||||
['employee_id', 'date_from', 'date_to', 'number_of_days'],
|
||||
);
|
||||
|
||||
this.state.departmentLeaves = departmentLeaves.map((leave) => {
|
||||
return Object.assign({}, leave, {
|
||||
dateFrom: formatDate(DateTime.fromSQL(leave.date_from, { zone: 'utc' }).toLocal()),
|
||||
dateTo: formatDate(DateTime.fromSQL(leave.date_to, { zone: 'utc' }).toLocal()),
|
||||
sameEmployee: leave.employee_id[0] === employee[0],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async loadLeaves(date, employee) {
|
||||
if (!(employee && date)) {
|
||||
this.state.leaves = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const dateFrom = date.startOf('year');
|
||||
const dateTo = date.endOf('year');
|
||||
this.state.leaves = await this.orm.readGroup(
|
||||
'hr.leave',
|
||||
[
|
||||
['employee_id', '=', employee[0]],
|
||||
['state', '=', 'validate'],
|
||||
['date_from', '<=', dateTo],
|
||||
['date_to', '>=', dateFrom]
|
||||
],
|
||||
['holiday_status_id', 'number_of_days:sum'],
|
||||
['holiday_status_id'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveStatsComponent.template = 'hr_holidays.LeaveStatsComponent';
|
||||
registry.category('view_widgets').add('hr_leave_stats', LeaveStatsComponent);
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<div t-name="hr_holidays.LeaveStatsComponent" owl="1" class="o_leave_stats">
|
||||
<div t-if="employee" id="o_leave_stats_employee">
|
||||
<div class="o_hr_leave_subtitle">
|
||||
<t t-esc="employee[1]"/> in <t t-esc="thisYear"/>
|
||||
</div>
|
||||
<div t-if="state.leaves.length === 0">
|
||||
None
|
||||
</div>
|
||||
<div t-foreach="state.leaves" t-as="leave" t-key="leave_index" class="d-flex flex-row justify-content-between">
|
||||
<span t-esc="leave.holiday_status_id[1]"/>
|
||||
<span><t t-esc="leave.number_of_days"/> day(s)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-if="department" id="o_leave_stats_department">
|
||||
<div class="o_horizontal_separator o_hr_leave_subtitle">
|
||||
<t t-esc="department[1]"/>
|
||||
</div>
|
||||
<div t-if="state.departmentLeaves.length === 0">
|
||||
None
|
||||
</div>
|
||||
<div t-foreach="state.departmentLeaves" t-as="leave" t-key="leave_index" t-attf-class="d-flex flex-row justify-content-between {{leave.sameEmployee ? 'fw-bold': ''}}">
|
||||
<span><t t-esc="leave.employee_id[1]"/>: <t t-esc="leave.number_of_days"/> day(s)</span>
|
||||
<span><t t-esc="leave.dateFrom"/> - <t t-esc="leave.dateTo"/></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import { registerPatch } from '@mail/model/model_core';
|
||||
import { attr } from '@mail/model/model_field';
|
||||
import { clear } from '@mail/model/model_field_command';
|
||||
|
||||
import { str_to_date } from 'web.time';
|
||||
|
||||
registerPatch({
|
||||
name: 'Partner',
|
||||
fields: {
|
||||
isOnline: {
|
||||
compute() {
|
||||
if (['leave_online', 'leave_away'].includes(this.im_status)) {
|
||||
return true;
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
},
|
||||
/**
|
||||
* Date of end of the out of office period of the partner as string.
|
||||
* String is expected to use Odoo's date string format
|
||||
* (examples: '2011-12-01' or '2011-12-01').
|
||||
*/
|
||||
out_of_office_date_end: attr(),
|
||||
/**
|
||||
* Text shown when partner is out of office.
|
||||
*/
|
||||
outOfOfficeText: attr({
|
||||
compute() {
|
||||
if (!this.out_of_office_date_end) {
|
||||
return clear();
|
||||
}
|
||||
if (!this.messaging.locale || !this.messaging.locale.language) {
|
||||
return clear();
|
||||
}
|
||||
const currentDate = new Date();
|
||||
const date = str_to_date(this.out_of_office_date_end);
|
||||
const options = { day: 'numeric', month: 'short' };
|
||||
if (currentDate.getFullYear() !== date.getFullYear()) {
|
||||
options.year = 'numeric';
|
||||
}
|
||||
let localeCode = this.messaging.locale.language.replace(/_/g, '-');
|
||||
if (localeCode === "sr@latin") {
|
||||
localeCode = "sr-Latn-RS";
|
||||
}
|
||||
const formattedDate = date.toLocaleDateString(localeCode, options);
|
||||
return _.str.sprintf(this.env._t("Out of office until %s"), formattedDate);
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { RadioField, preloadRadio } from "@web/views/fields/radio/radio_field";
|
||||
|
||||
class RadioImageField extends RadioField {}
|
||||
RadioImageField.template = "hr_holidays.RadioImageField";
|
||||
|
||||
registry.category("fields").add("hr_holidays_radio_image", RadioImageField);
|
||||
|
||||
registry.category("preloadedData").add("hr_holidays_radio_image", {
|
||||
loadOnTypes: ["many2one"],
|
||||
preload: preloadRadio,
|
||||
});
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t t-name="hr_holidays.RadioImageField" owl="1">
|
||||
<div role="radiogroup" class="d-flex flex-wrap" t-att-aria-label="string">
|
||||
<t t-if="props.readonly">
|
||||
<t t-if="value !== false">
|
||||
<div>
|
||||
<img t-attf-src="/hr_holidays/static/src/img/icons/{{items.find((item) => item[0] === value)[1]}}" width="48" height="48" />
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-foreach="items" t-as="item" t-key="item[0]">
|
||||
<div class="form-check o_radio_item" aria-atomic="true">
|
||||
<input
|
||||
type="radio"
|
||||
class="form-check-input o_radio_input"
|
||||
t-att-checked="item[0] === value"
|
||||
t-att-disabled="props.readonly"
|
||||
t-att-name="id"
|
||||
t-att-data-value="item[0]"
|
||||
t-att-data-index="item_index"
|
||||
t-att-id="`${id}_${item[0]}`"
|
||||
t-on-change="() => this.onChange(item)"
|
||||
/>
|
||||
<label class="form-check-label o_form_label" t-att-for="`${id}_${item[0]}`">
|
||||
<img t-attf-src="/hr_holidays/static/src/img/icons/{{item[1]}}" width="48" height="48" />
|
||||
</label>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
$o-hr-holidays-border-color: map-get($grays, '300');
|
||||
|
||||
.o_hr_holidays_hierarchy {
|
||||
margin-left: -$o-horizontal-padding;
|
||||
margin-right: -$o-horizontal-padding;
|
||||
@include media-breakpoint-up(lg, $o-extra-grid-breakpoints) {
|
||||
margin-left: -$o-horizontal-padding*2;
|
||||
margin-right: -$o-horizontal-padding*2;
|
||||
}
|
||||
margin-bottom:-24px;
|
||||
padding: 10px 0px 24px 16px;
|
||||
background-color: rgba(128, 128, 128, 0.15);
|
||||
box-shadow: 0px 1px 1px rgba(17, 17, 17, 0.23);
|
||||
overflow-x: auto;
|
||||
.o_hr_holidays_title {
|
||||
padding: 0px 0px 0px 86px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.o_hr_holidays_hierarchy_readonly {
|
||||
padding: 40px 0px 0px 40px;
|
||||
}
|
||||
|
||||
.o_hr_holidays_plan_level_container {
|
||||
counter-reset: o-hr-holidays-accrual-plan-level-counter;
|
||||
|
||||
.o-kanban-button-new {
|
||||
padding: 2px 12px;
|
||||
margin: 0px 0px 0px 44px;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.o_legacy_kanban_view.o_kanban_ungrouped .o_kanban_record,
|
||||
.o_kanban_renderer.o_kanban_ungrouped .o_kanban_record {
|
||||
counter-increment: o-hr-holidays-accrual-plan-level-counter;
|
||||
display: flex;
|
||||
flex: 0 0 100%;
|
||||
border: 0px;
|
||||
padding: 0px 0px 0px 100px;
|
||||
margin: 0px 0px 0px 0px;
|
||||
background-color: transparent;
|
||||
|
||||
// Timeline Border
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
@include o-position-absolute;
|
||||
height: 100%;
|
||||
margin-left: 8px;
|
||||
border-left: 1px dashed darken($o-hr-holidays-border-color, 10%);
|
||||
}
|
||||
|
||||
.o_hr_holidays_plan_level_level::before {
|
||||
content: counter(o-hr-holidays-accrual-plan-level-counter);
|
||||
}
|
||||
|
||||
// Whole record
|
||||
.o_hr_holidays_body {
|
||||
margin-left: 8px;
|
||||
padding-top: 20px;
|
||||
|
||||
// Left side 'Level'
|
||||
.o_hr_holidays_timeline {
|
||||
@include o-position-absolute($top: 32px, $left: 6px);
|
||||
width: 90px;
|
||||
padding: 3px 0px;
|
||||
border-radius: 3px;
|
||||
background-color: $o-btn-secondary-bg;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
// Actual kanban card
|
||||
.o_hr_holidays_card {
|
||||
position: relative;
|
||||
margin-left: 22px;
|
||||
margin-right: 2px;
|
||||
width: 500px;
|
||||
border-radius: 3px;
|
||||
background-color: $o-btn-secondary-bg;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.1);
|
||||
|
||||
// Triangle
|
||||
&:before {
|
||||
content: '';
|
||||
@include o-position-absolute($top: 12px, $left: -17px);
|
||||
margin-left: 10px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: $o-btn-secondary-bg;
|
||||
border-bottom: 1px solid $o-hr-holidays-border-color;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
// Circle
|
||||
&:after {
|
||||
content: '';
|
||||
@include o-position-absolute($top: 14px, $left: -36px);
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 2px solid $o-brand-primary;
|
||||
border-radius: 10px;
|
||||
background: $o-btn-secondary-bg;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
background-color: $o-btn-secondary-bg;
|
||||
padding: 5px 7px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
.o_hr_leave_form {
|
||||
.o_form_sheet {
|
||||
padding: 0!important;
|
||||
overflow: hidden;
|
||||
.ribbon-top-right {
|
||||
top: 16px;
|
||||
right: -8px;
|
||||
}
|
||||
}
|
||||
.o_hr_leave_content {
|
||||
margin: 0;
|
||||
.o_group {
|
||||
margin: 0;
|
||||
}
|
||||
.o_hr_leave_title, .o_hr_leave_subtitle {
|
||||
line-height: 1.2;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
* {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.o_hr_leave_title {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
.o_hr_leave_subtitle {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.o_hr_leave_column {
|
||||
padding: 16px;
|
||||
}
|
||||
.col_right {
|
||||
background-color: map-get($grays, '200');
|
||||
padding-top: 28px;
|
||||
}
|
||||
.o_hr_leave_date {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@include media-breakpoint-down(lg) {
|
||||
flex-direction: column;
|
||||
}
|
||||
@include media-breakpoint-down(md) {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
.o_leave_stats {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/** @odoo-module **/
|
||||
import tour from 'web_tour.tour';
|
||||
import { _t } from 'web.core';
|
||||
|
||||
const leaveType = "NotLimitedHR";
|
||||
const leaveDateFrom = "01/17/2022";
|
||||
const leaveDateTo = "01/17/2022";
|
||||
const description = 'Days off';
|
||||
|
||||
tour.register('hr_holidays_tour', {
|
||||
url: '/web',
|
||||
rainbowManMessage: _t("Congrats, we can see that your request has been validated."),
|
||||
test: false
|
||||
}, [
|
||||
tour.stepUtils.showAppsMenuItem(),
|
||||
{
|
||||
trigger: '.o_app[data-menu-xmlid="hr_holidays.menu_hr_holidays_root"]',
|
||||
content: _t("Let's discover the Time Off application"),
|
||||
position: 'bottom',
|
||||
},
|
||||
{
|
||||
trigger: 'button.btn-time-off',
|
||||
content: _t("Click on any date or on this button to request a time-off"),
|
||||
position: 'bottom',
|
||||
},
|
||||
{
|
||||
trigger: 'div[name="holiday_status_id"] input',
|
||||
content: _t("Let's try to create a Sick Time Off, select it in the list"),
|
||||
run: `text ${leaveType}`,
|
||||
},
|
||||
{
|
||||
trigger: `.ui-autocomplete .ui-menu-item a:contains("${leaveType}")`,
|
||||
run: "click",
|
||||
auto: true,
|
||||
in_modal: false,
|
||||
},
|
||||
{
|
||||
trigger: '.o_field_widget[name="request_date_from"] input',
|
||||
content: _t("You can select the period you need to take off, from start date to end date"),
|
||||
position: 'right',
|
||||
run: `text ${leaveDateFrom}`,
|
||||
},
|
||||
{
|
||||
trigger: '.o_field_widget[name="request_date_to"] input',
|
||||
content: _t("You can select the period you need to take off, from start date to end date"),
|
||||
position: 'right',
|
||||
run: `text ${leaveDateTo}`,
|
||||
},
|
||||
{
|
||||
trigger: 'div[name="name"] textarea',
|
||||
content: _t("Add some description for the people that will validate it"),
|
||||
run: `text ${description}`,
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
trigger: `button:contains(${_t('Save')})`,
|
||||
content: _t("Submit your request"),
|
||||
position: 'bottom',
|
||||
},
|
||||
{
|
||||
trigger: 'button[data-menu-xmlid="hr_holidays.menu_hr_holidays_approvals"]',
|
||||
content: _t("Let's go validate it"),
|
||||
position: 'bottom'
|
||||
},
|
||||
{
|
||||
trigger: 'a[data-menu-xmlid="hr_holidays.menu_open_department_leave_approve"]',
|
||||
content: _t("Select Time Off"),
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
trigger: 'table.o_list_table',
|
||||
content: _t("Select the request you just created"),
|
||||
position: 'bottom',
|
||||
run: function(actions) {
|
||||
const rows = this.$anchor.find('tr.o_data_row');
|
||||
actions.click(rows[0]);
|
||||
}
|
||||
},
|
||||
{
|
||||
trigger: 'button[name="action_approve"]',
|
||||
content: _t("Let's approve it"),
|
||||
position: 'bottom'
|
||||
},
|
||||
{
|
||||
trigger: 'a[data-menu-xmlid="hr_holidays.menu_hr_holidays_root"]',
|
||||
content: _t("State is now confirmed. We can go back to the calendar"),
|
||||
position: 'bottom'
|
||||
}
|
||||
]);
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||
import { CalendarController } from '@web/views/calendar/calendar_controller';
|
||||
import { FormViewDialog } from '@web/views/view_dialogs/form_view_dialog';
|
||||
|
||||
import { serializeDate } from "@web/core/l10n/dates";
|
||||
|
||||
import { TimeOffCalendarFilterPanel } from './filter_panel/calendar_filter_panel';
|
||||
import { TimeOffFormViewDialog } from '../view_dialog/form_view_dialog';
|
||||
import { useLeaveCancelWizard } from '../hooks';
|
||||
|
||||
const { EventBus, useSubEnv } = owl;
|
||||
|
||||
export class TimeOffCalendarController extends CalendarController {
|
||||
setup() {
|
||||
super.setup();
|
||||
useSubEnv({
|
||||
timeOffBus: new EventBus(),
|
||||
});
|
||||
this.leaveCancelWizard = useLeaveCancelWizard();
|
||||
}
|
||||
|
||||
get employeeId() {
|
||||
return this.model.employeeId;
|
||||
}
|
||||
|
||||
get filterPanelProps() {
|
||||
return {
|
||||
...super.filterPanelProps,
|
||||
employee_id: this.employeeId,
|
||||
};
|
||||
}
|
||||
|
||||
newTimeOffRequest() {
|
||||
const context = {};
|
||||
if (this.employeeId) {
|
||||
context['default_employee_id'] = this.employeeId;
|
||||
}
|
||||
if (this.model.meta.scale == 'day') {
|
||||
context['default_date_from'] = serializeDate(
|
||||
this.model.data.range.start.set({ hours: 7 }), "datetime"
|
||||
);
|
||||
context['default_date_to'] = serializeDate(
|
||||
this.model.data.range.end.set({ hours: 19 }), "datetime"
|
||||
);
|
||||
}
|
||||
|
||||
this.displayDialog(FormViewDialog, {
|
||||
resModel: 'hr.leave',
|
||||
title: this.env._t('New Time Off'),
|
||||
viewId: this.model.formViewId,
|
||||
onRecordSaved: () => {
|
||||
this.model.load();
|
||||
this.env.timeOffBus.trigger('update_dashboard');
|
||||
},
|
||||
context: context,
|
||||
});
|
||||
}
|
||||
|
||||
newAllocationRequest() {
|
||||
const context = {
|
||||
'form_view_ref': 'hr_holidays.hr_leave_allocation_view_form_dashboard',
|
||||
};
|
||||
if (this.employeeId) {
|
||||
context['default_employee_id'] = this.employeeId;
|
||||
context['default_employee_ids'] = [this.employeeId];
|
||||
context['form_view_ref'] = 'hr_holidays.hr_leave_allocation_view_form_manager_dashboard';
|
||||
}
|
||||
|
||||
this.displayDialog(FormViewDialog, {
|
||||
resModel: 'hr.leave.allocation',
|
||||
title: this.env._t('New Allocation'),
|
||||
context: context,
|
||||
});
|
||||
}
|
||||
|
||||
deleteRecord(record) {
|
||||
if (!record.can_cancel) {
|
||||
this.displayDialog(ConfirmationDialog, {
|
||||
title: this.env._t("Confirmation"),
|
||||
body: this.env._t("Are you sure you want to delete this record ?"),
|
||||
confirm: async () => {
|
||||
await this.model.unlinkRecord(record.id);
|
||||
this.env.timeOffBus.trigger('update_dashboard');
|
||||
},
|
||||
cancel: () => {},
|
||||
});
|
||||
} else {
|
||||
this.leaveCancelWizard(record.id, () => {
|
||||
this.model.load();
|
||||
this.env.timeOffBus.trigger('update_dashboard');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async editRecord(record, context = {}, shouldFetchFormViewId = true) {
|
||||
const onDialogClosed = () => {
|
||||
this.model.load();
|
||||
this.env.timeOffBus.trigger('update_dashboard');
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.displayDialog(
|
||||
TimeOffFormViewDialog, {
|
||||
resModel: this.model.resModel,
|
||||
resId: record.id || false,
|
||||
context,
|
||||
title: this.env._t("Time Off Request"),
|
||||
viewId: this.model.formViewId,
|
||||
onRecordSaved: onDialogClosed,
|
||||
onRecordDeleted: (record) => this.deleteRecord(record),
|
||||
onLeaveCancelled: onDialogClosed,
|
||||
},
|
||||
{ onClose: () => resolve() }
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
TimeOffCalendarController.template = "hr_holidays.CalendarController";
|
||||
TimeOffCalendarController.components = {
|
||||
...TimeOffCalendarController.components,
|
||||
FilterPanel: TimeOffCalendarFilterPanel,
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="hr_holidays.CalendarController" t-inherit="web.CalendarController" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//DatePicker" position="replace"/>
|
||||
</t>
|
||||
|
||||
<t t-name="hr_holidays.CalendarController.controlButtons" t-inherit="web.CalendarController.controlButtons" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//span[hasclass('o_calendar_scale_buttons')]" position="after">
|
||||
<span class="o_timeoff_buttons">
|
||||
<button class="btn btn-primary btn-time-off mx-1" t-on-click="newTimeOffRequest" type="button">
|
||||
New Time Off
|
||||
</button>
|
||||
<button class="btn btn-secondary" t-on-click="newAllocationRequest" type="button">
|
||||
<t t-if="employeeId">New</t> Allocation Request
|
||||
</button>
|
||||
</span>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { CalendarModel } from '@web/views/calendar/calendar_model';
|
||||
import { deserializeDateTime, serializeDate, serializeDateTime } from "@web/core/l10n/dates";
|
||||
|
||||
export class TimeOffCalendarModel extends CalendarModel {
|
||||
setup(params, services) {
|
||||
super.setup(params, services);
|
||||
|
||||
this.data.stressDays = {};
|
||||
if (this.env.isSmall) {
|
||||
this.meta.scale = 'month';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
normalizeRecord(rawRecord) {
|
||||
let result = super.normalizeRecord(...arguments);
|
||||
if (rawRecord.employee_id) {
|
||||
const employee = rawRecord.employee_id[1];
|
||||
result.title = [employee, result.title].join(' ');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
makeContextDefaults(record) {
|
||||
const { scale } = this.meta;
|
||||
const context = super.makeContextDefaults(record);
|
||||
if (this.employeeId) {
|
||||
context['default_employee_id'] = this.employeeId;
|
||||
}
|
||||
|
||||
if(['day', 'week'].includes(scale)) {
|
||||
if ('default_date_from' in context) {
|
||||
context['default_date_from'] = serializeDateTime(deserializeDateTime(context['default_date_from']).set({ hours: 7 }));
|
||||
}
|
||||
if ('default_date_to' in context) {
|
||||
context['default_date_to'] = serializeDateTime(deserializeDateTime(context['default_date_from']).set({ hours: 19 }));
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
async updateData(data) {
|
||||
await super.updateData(data);
|
||||
data.stressDays = await this.fetchStressDays(data);
|
||||
}
|
||||
|
||||
async fetchStressDays(data) {
|
||||
return this.orm.call("hr.employee", "get_stress_days", [
|
||||
this.employeeId,
|
||||
serializeDate(data.range.start, "datetime"),
|
||||
serializeDate(data.range.end, "datetime"),
|
||||
]);
|
||||
}
|
||||
|
||||
get stressDays() {
|
||||
return this.data.stressDays;
|
||||
}
|
||||
|
||||
get employeeId() {
|
||||
return this.meta.context.employee_id && this.meta.context.employee_id[0] || null;
|
||||
}
|
||||
|
||||
fetchRecords(data) {
|
||||
const { fieldNames, resModel } = this.meta;
|
||||
const context = {};
|
||||
if (!this.employeeId) {
|
||||
context['short_name'] = 1;
|
||||
}
|
||||
return this.orm.searchRead(resModel, this.computeDomain(data), fieldNames, { context });
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { CalendarRenderer } from '@web/views/calendar/calendar_renderer';
|
||||
|
||||
import { TimeOffCalendarCommonRenderer } from './common/calendar_common_renderer';
|
||||
import { TimeOffCalendarYearRenderer } from './year/calendar_year_renderer';
|
||||
|
||||
import { TimeOffDashboard } from '../../dashboard/time_off_dashboard';
|
||||
|
||||
export class TimeOffCalendarRenderer extends CalendarRenderer {
|
||||
get employeeId() {
|
||||
return this.props.model.employeeId;
|
||||
}
|
||||
|
||||
get showDashboard() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
TimeOffCalendarRenderer.template = 'hr_holidays.CalendarRenderer';
|
||||
TimeOffCalendarRenderer.components = {
|
||||
...TimeOffCalendarRenderer.components,
|
||||
day: TimeOffCalendarCommonRenderer,
|
||||
week: TimeOffCalendarCommonRenderer,
|
||||
month: TimeOffCalendarCommonRenderer,
|
||||
year: TimeOffCalendarYearRenderer,
|
||||
TimeOffDashboard,
|
||||
};
|
||||
|
||||
export class TimeOffDashboardCalendarRenderer extends TimeOffCalendarRenderer {
|
||||
get showDashboard() {
|
||||
return !this.env.isSmall;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
.o_timeoff_calendar {
|
||||
.o_calendar_renderer {
|
||||
height: unset;
|
||||
|
||||
@for $size from 1 through length($o-colors) {
|
||||
.o_calendar_widget {
|
||||
.hr_stress_day_top_#{$size - 1}:not(.fc-disabled-day) {
|
||||
.fc-day-number {
|
||||
color: nth($o-colors, $size) !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc-bgevent {
|
||||
border-radius: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="hr_holidays.CalendarRenderer" owl="1">
|
||||
<div class="o_timeoff_calendar">
|
||||
<TimeOffDashboard t-if="showDashboard" employeeId="employeeId"/>
|
||||
<t t-call="web.CalendarRenderer"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { calendarView } from '@web/views/calendar/calendar_view';
|
||||
|
||||
import { TimeOffCalendarController } from './calendar_controller';
|
||||
import { TimeOffCalendarModel } from './calendar_model';
|
||||
import { TimeOffCalendarRenderer, TimeOffDashboardCalendarRenderer } from './calendar_renderer';
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
|
||||
const TimeOffCalendarView = {
|
||||
...calendarView,
|
||||
|
||||
Controller: TimeOffCalendarController,
|
||||
Renderer: TimeOffCalendarRenderer,
|
||||
Model: TimeOffCalendarModel,
|
||||
|
||||
buttonTemplate: "hr_holidays.CalendarController.controlButtons",
|
||||
}
|
||||
|
||||
registry.category('views').add('time_off_calendar', TimeOffCalendarView);
|
||||
registry.category('views').add('time_off_calendar_dashboard', {
|
||||
...TimeOffCalendarView,
|
||||
Renderer: TimeOffDashboardCalendarRenderer,
|
||||
});
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { CalendarCommonPopover } from "@web/views/calendar/calendar_common/calendar_common_popover";
|
||||
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
export class TimeOffCalendarCommonPopover extends CalendarCommonPopover {
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.dialog = useService('dialog');
|
||||
this.action = useService('action');
|
||||
}
|
||||
|
||||
get isEventDeletable() {
|
||||
const record = this.props.record.rawRecord;
|
||||
const state = record.state;
|
||||
return record.can_cancel || state && !['validate', 'refuse'].includes(state);
|
||||
}
|
||||
|
||||
get isEventEditable() {
|
||||
const state = this.props.record.rawRecord.state;
|
||||
return state !== undefined;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { CalendarCommonRenderer } from '@web/views/calendar/calendar_common/calendar_common_renderer';
|
||||
|
||||
import { useStressDays } from '../../hooks';
|
||||
import { TimeOffCalendarCommonPopover } from './calendar_common_popover';
|
||||
|
||||
|
||||
export class TimeOffCalendarCommonRenderer extends CalendarCommonRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.stressDays = useStressDays(this.props);
|
||||
}
|
||||
|
||||
onDayRender(info) {
|
||||
super.onDayRender(info);
|
||||
this.stressDays(info);
|
||||
}
|
||||
}
|
||||
TimeOffCalendarCommonRenderer.components = {
|
||||
...TimeOffCalendarCommonRenderer,
|
||||
Popover: TimeOffCalendarCommonPopover,
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// = HR Holidays
|
||||
// ============================================================================
|
||||
// No CSS hacks, variables overrides only
|
||||
.o_calendar_filter {
|
||||
--calendarFilter-icon--plain: url("/hr/static/src/img/icons/plain_dark.svg");
|
||||
--calendarFilter-icon--hatched: url("/hr/static/src/img/icons/hatched_dark.svg");
|
||||
--calendarFilter-icon--line: url("/hr/static/src/img/icons/line_dark.svg");
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { CalendarFilterPanel } from "@web/views/calendar/filter_panel/calendar_filter_panel";
|
||||
import { TimeOffCardMobile } from "../../../dashboard/time_off_card";
|
||||
import { getFormattedDateSpan } from '@web/views/calendar/utils';
|
||||
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { serializeDate } from "@web/core/l10n/dates";
|
||||
|
||||
const { useState, onWillStart, onWillUpdateProps } = owl;
|
||||
|
||||
export class TimeOffCalendarFilterPanel extends CalendarFilterPanel {
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.orm = useService('orm');
|
||||
this.getFormattedDateSpan = getFormattedDateSpan;
|
||||
this.leaveState = useState({
|
||||
holidays: [],
|
||||
stressDays: [],
|
||||
bankHolidays: [],
|
||||
});
|
||||
|
||||
onWillStart(async () => {
|
||||
await this.loadFilterData();
|
||||
await this.updateSpecialDays();
|
||||
});
|
||||
onWillUpdateProps(this.updateSpecialDays);
|
||||
}
|
||||
|
||||
async updateSpecialDays() {
|
||||
const context = {
|
||||
'employee_id': this.props.employee_id,
|
||||
}
|
||||
const specialDays = await this.orm.call(
|
||||
'hr.employee', 'get_special_days_data', [
|
||||
serializeDate(this.props.model.rangeStart, "datetime"),
|
||||
serializeDate(this.props.model.rangeEnd, "datetime"),
|
||||
],
|
||||
{
|
||||
'context': context,
|
||||
},
|
||||
);
|
||||
specialDays['bankHolidays'].forEach(bankHoliday => {
|
||||
bankHoliday.start = luxon.DateTime.fromISO(bankHoliday.start)
|
||||
bankHoliday.end = luxon.DateTime.fromISO(bankHoliday.end)
|
||||
});
|
||||
specialDays['stressDays'].forEach(stressDay => {
|
||||
stressDay.start = luxon.DateTime.fromISO(stressDay.start)
|
||||
stressDay.end = luxon.DateTime.fromISO(stressDay.end)
|
||||
});
|
||||
this.leaveState.bankHolidays = specialDays['bankHolidays'];
|
||||
this.leaveState.stressDays = specialDays['stressDays'];
|
||||
}
|
||||
|
||||
async loadFilterData() {
|
||||
if(!this.env.isSmall) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filterData = {};
|
||||
const data = await this.orm.call(
|
||||
'hr.leave.type', 'get_days_all_request', [],
|
||||
);
|
||||
|
||||
data.forEach((leave) => {
|
||||
filterData[leave[3]] = leave;
|
||||
});
|
||||
this.leaveState.holidays = filterData;
|
||||
}
|
||||
}
|
||||
TimeOffCalendarFilterPanel.template = 'hr_holidays.CalendarFilterPanel';
|
||||
TimeOffCalendarFilterPanel.components = {
|
||||
...TimeOffCalendarFilterPanel.components,
|
||||
TimeOffCardMobile,
|
||||
}
|
||||
TimeOffCalendarFilterPanel.subTemplates = {
|
||||
filter: "hr_holidays.CalendarFilterPanel.filter",
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
.o_calendar_filter {
|
||||
span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
& img {
|
||||
width:30px;
|
||||
|
||||
&.o_calendar_filter_plain {
|
||||
content:var(--calendarFilter-icon--plain);
|
||||
}
|
||||
|
||||
&.o_calendar_filter_hatched {
|
||||
content:var(--calendarFilter-icon--hatched);
|
||||
}
|
||||
|
||||
&.o_calendar_filter_line {
|
||||
content:var(--calendarFilter-icon--line);
|
||||
}
|
||||
}
|
||||
|
||||
.o_timeoff_legend {
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 30px;
|
||||
margin: 0 3px;
|
||||
padding: 3px 0;
|
||||
text-align: center;
|
||||
|
||||
&_bankholiday {
|
||||
background-color: $gray-200;
|
||||
}
|
||||
|
||||
&_stressday {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
@for $size from 1 through length($o-colors) {
|
||||
.hr_stress_day_#{$size - 1}:not(.fc-disabled-day) {
|
||||
color: nth($o-colors, $size) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="hr_holidays.CalendarFilterPanel" t-inherit="web.CalendarFilterPanel" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//t[@t-foreach='props.model.filterSections']" position="after">
|
||||
<div class="o_calendar_filter">
|
||||
<h5>Legend</h5>
|
||||
|
||||
<div class="d-flex flex-column">
|
||||
<span><img class="o_calendar_filter_plain" src="/hr/static/src/img/icons/plain.svg"/> Validated</span>
|
||||
<span><img class="o_calendar_filter_hatched" src="/hr/static/src/img/icons/hatched.svg"/> To Approve</span>
|
||||
<span><img class="o_calendar_filter_line" src="/hr/static/src/img/icons/line.svg"/> Refused</span>
|
||||
<span><span class="o_timeoff_legend o_timeoff_legend_bankholiday">13</span> Public Holiday</span>
|
||||
<span><span class="o_timeoff_legend o_timeoff_legend_stressday text-odoo">13</span> Stress Day</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column mt-4" t-if="leaveState.stressDays.length">
|
||||
<h5>Stress Days</h5>
|
||||
<ul class="ps-2">
|
||||
<li t-foreach="leaveState.stressDays" t-as="stressDay" t-key="stressDay.id" class="mt-2 list-unstyled">
|
||||
<strong
|
||||
t-esc="getFormattedDateSpan(stressDay.start, stressDay.end)"
|
||||
t-att-class="'hr_stress_day_'+stressDay.colorIndex"/>
|
||||
: <t t-esc="stressDay.title"/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column mt-4" t-if="leaveState.bankHolidays.length">
|
||||
<h5>Public Holidays</h5>
|
||||
<ul class="ps-2">
|
||||
<li t-foreach="leaveState.bankHolidays" t-as="bankHoliday" t-key="bankHoliday.id" class="mt-2 list-unstyled">
|
||||
<strong
|
||||
t-esc="getFormattedDateSpan(bankHoliday.start, bankHoliday.end)"/>
|
||||
: <t t-esc="bankHoliday.title"/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
|
||||
<t t-name="hr_holidays.CalendarFilterPanel.filter" t-inherit="web.CalendarFilterPanel.filter" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//span[@t-esc='filter.label']" position="replace">
|
||||
<span class="o_cw_filter_title text-truncate flex-grow">
|
||||
<t t-esc="filter.label"/>
|
||||
|
||||
<t t-if="env.isSmall">
|
||||
<t t-set="holiday" t-value="leaveState.holidays[filter.value]"/>
|
||||
<TimeOffCardMobile t-if="holiday" name="holiday[0]" id="holiday[3]" data="holiday[1]" requires_allocation="holiday[2] === 'yes'" />
|
||||
</t>
|
||||
</span>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
|
||||
import { CalendarYearPopover } from "@web/views/calendar/calendar_year/calendar_year_popover";
|
||||
|
||||
export class TimeOffCalendarYearPopover extends CalendarYearPopover {}
|
||||
TimeOffCalendarYearPopover.components = { Dialog };
|
||||
TimeOffCalendarYearPopover.template = "web.CalendarYearPopover";
|
||||
TimeOffCalendarYearPopover.subTemplates = {
|
||||
...CalendarYearPopover.subTemplates,
|
||||
body: "hr_holidays.StressDayCalendarYearPopover.body",
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="hr_holidays.StressDayCalendarYearPopover.body" owl="1">
|
||||
<t t-foreach="recordGroups" t-as="recordGroup" t-key="recordGroup.title">
|
||||
<div class="fw-bold mt-2" t-esc="recordGroup.title" />
|
||||
<t t-foreach="recordGroup.records" t-as="record" t-key="record.id">
|
||||
<t t-if="record.id < 0">
|
||||
<p class="">
|
||||
<t t-if="record.startHour"><t t-esc="record.startHour" /> </t>
|
||||
<t t-esc="record.title"/>
|
||||
</p>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-call="{{ constructor.subTemplates.record }}" />
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { CalendarYearRenderer } from '@web/views/calendar/calendar_year/calendar_year_renderer';
|
||||
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { useStressDays } from '../../hooks';
|
||||
import { useCalendarPopover } from '@web/views/calendar/hooks';
|
||||
import { TimeOffCalendarYearPopover } from './calendar_year_popover';
|
||||
|
||||
const { useEffect } = owl;
|
||||
|
||||
export class TimeOffCalendarYearRenderer extends CalendarYearRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.orm = useService("orm");
|
||||
this.stressDays = useStressDays(this.props);
|
||||
this.stressDaysList = [];
|
||||
this.stressDayPopover = useCalendarPopover(TimeOffCalendarYearPopover);
|
||||
|
||||
useEffect((el) => {
|
||||
for (const week of el) {
|
||||
const row = week.parentElement;
|
||||
|
||||
// Remove the week number if the week is empty.
|
||||
// FullCalendar always displays 6 weeks even when empty.
|
||||
if (!row.children[1].classList.length &&
|
||||
!row.children[row.children.length - 1].classList.length) {
|
||||
row.remove();
|
||||
}
|
||||
}
|
||||
}, () => [this.rootRef.el && this.rootRef.el.querySelectorAll('.fc-content-skeleton td.fc-week-number')]);
|
||||
}
|
||||
|
||||
get options() {
|
||||
return Object.assign(super.options, {
|
||||
weekNumbers: true,
|
||||
weekNumbersWithinDays: false,
|
||||
weekLabel: this.env._t('Week'),
|
||||
});
|
||||
}
|
||||
|
||||
/** @override **/
|
||||
async onDateClick(info) {
|
||||
const is_stress_day = [...info.dayEl.classList].some(elClass => elClass.startsWith('hr_stress_day_'))
|
||||
this.stressDayPopover.close();
|
||||
if (is_stress_day && !this.env.isSmall) {
|
||||
this.popover.close();
|
||||
const date = luxon.DateTime.fromISO(info.dateStr);
|
||||
const target = info.dayEl;
|
||||
const stress_days_data = await this.orm.call("hr.employee", "get_stress_days_data", [date, date]);
|
||||
stress_days_data.forEach(stress_day_data => {
|
||||
stress_day_data['start'] = luxon.DateTime.fromISO(stress_day_data['start'])
|
||||
stress_day_data['end'] = luxon.DateTime.fromISO(stress_day_data['end'])
|
||||
});
|
||||
const records = Object.values(this.props.model.records).filter((r) =>
|
||||
luxon.Interval.fromDateTimes(r.start.startOf("day"), r.end.endOf("day")).contains(date)
|
||||
);
|
||||
const props = this.getPopoverProps(date, records)
|
||||
props['records'] = stress_days_data.concat(props['records'])
|
||||
this.stressDayPopover.open(target, props, "o_cw_popover");
|
||||
}
|
||||
else {
|
||||
super.onDateClick(info);
|
||||
}
|
||||
}
|
||||
|
||||
onDayRender(info) {
|
||||
super.onDayRender(info);
|
||||
this.stressDaysList = this.stressDays(info);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
.o_timeoff_calendar {
|
||||
.o_calendar_widget {
|
||||
.fc-dayGridYear-view {
|
||||
.fc-week-number {
|
||||
color: #adb5bd;
|
||||
font-size: 0.85rem;
|
||||
cursor: default;
|
||||
vertical-align: middle;
|
||||
|
||||
line-height: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { useEnv } = owl;
|
||||
|
||||
export function useStressDays(props) {
|
||||
return (info) => {
|
||||
const date = luxon.DateTime.fromJSDate(info.date).toISODate();
|
||||
const stressDay = props.model.stressDays[date];
|
||||
if (stressDay) {
|
||||
const dayNumberElTop = info.view.el.querySelector(`.fc-day-top[data-date="${info.el.dataset.date }"]`)
|
||||
const dayNumberEl = info.view.el.querySelector(`.fc-day[data-date="${info.el.dataset.date }"]`)
|
||||
if (dayNumberElTop) {
|
||||
dayNumberElTop.classList.add(`hr_stress_day_top_${stressDay}`);
|
||||
}
|
||||
if (dayNumberEl) {
|
||||
dayNumberEl.classList.add(`hr_stress_day_${stressDay}`);
|
||||
}
|
||||
}
|
||||
return props.model.stressDays;
|
||||
}
|
||||
}
|
||||
|
||||
export function useLeaveCancelWizard() {
|
||||
const action = useService('action');
|
||||
const env = useEnv();
|
||||
|
||||
return (leaveId, callback) => {
|
||||
action.doAction({
|
||||
name: env._t('Delete Confirmation'),
|
||||
type: "ir.actions.act_window",
|
||||
res_model: "hr.holidays.cancel.leave",
|
||||
target: "new",
|
||||
views: [[false, "form"]],
|
||||
context: {
|
||||
default_leave_id: leaveId,
|
||||
}
|
||||
}, {
|
||||
onClose: callback,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
|
||||
import { formView } from '@web/views/form/form_view';
|
||||
import { FormController } from '@web/views/form/form_controller';
|
||||
|
||||
import { useLeaveCancelWizard } from '../hooks';
|
||||
|
||||
export class TimeOffDialogFormController extends FormController {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.leaveCancelWizard = useLeaveCancelWizard();
|
||||
}
|
||||
|
||||
deleteRecord() {
|
||||
const record = this.model.root.data
|
||||
|
||||
this.props.onRecordDeleted(record)
|
||||
this.props.onCancelLeave();
|
||||
if (record.can_cancel) {
|
||||
this.leaveCancelWizard(record.id, () => {
|
||||
this.props.onLeaveCancelled();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get canDelete() {
|
||||
const record = this.model.root.data;
|
||||
return !this.model.root.isNew && (record.can_cancel || record.state && ['confirm', 'validate', 'validate1'].includes(record.state));
|
||||
}
|
||||
}
|
||||
|
||||
TimeOffDialogFormController.props = {
|
||||
...FormController.props,
|
||||
onCancelLeave: Function,
|
||||
onRecordDeleted: Function,
|
||||
onLeaveCancelled: Function,
|
||||
}
|
||||
|
||||
registry.category('views').add('timeoff_dialog_form', {
|
||||
...formView,
|
||||
Controller: TimeOffDialogFormController,
|
||||
});
|
||||
|
||||
|
||||
export class TimeOffFormViewDialog extends FormViewDialog {
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.viewProps = Object.assign(this.viewProps, {
|
||||
type: "timeoff_dialog_form",
|
||||
buttonTemplate: 'hr_holidays.FormViewDialog.buttons',
|
||||
onCancelLeave: () => {
|
||||
this.props.close();
|
||||
},
|
||||
onRecordDeleted: (record) => {
|
||||
this.props.onRecordDeleted(record)
|
||||
},
|
||||
onLeaveCancelled: this.props.onLeaveCancelled.bind(this),
|
||||
})
|
||||
}
|
||||
}
|
||||
TimeOffFormViewDialog.props = {
|
||||
...TimeOffFormViewDialog.props,
|
||||
onRecordDeleted: Function,
|
||||
onLeaveCancelled: Function,
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="hr_holidays.FormViewDialog.buttons" t-inherit="web.FormViewDialog.ToOne.buttons" owl="1">
|
||||
<xpath expr="//button[contains(@class, 'o_form_button_save')]" position="replace">
|
||||
<button class="btn btn-primary o_form_button_save" t-on-click="saveButtonClicked" data-hotkey="c">Save</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//button[contains(@class, 'o_form_button_cancel')]" position="after">
|
||||
<button class="btn btn-secondary" t-if="canDelete" t-on-click="deleteRecord" data-hotkey="x">Delete</button>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||