feat(fusion_clock): open shifts + self-assign + bulk apply [B4-B5]
Model: fclk_create_open_shifts/claim_open_shift/release_shift (days-before cutoff + role eligibility)/bulk_apply. Planner: Open Shift… panel, open-shifts strip with delete, Apply-to-dept; load includes open shifts. Portal: claim open shifts + release own upcoming shifts with feedback banners. Tests for claim/role-gate/release/bulk. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,9 @@
|
||||
<button class="btn btn-outline-success" t-on-click="() => this.togglePublishPanel()" t-att-disabled="state.loading or state.saving" title="Publish a custom date range and notify employees">
|
||||
<i class="fa fa-calendar-check-o me-1"/> Publish…
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" t-on-click="() => this.toggleOpenShiftPanel()" t-att-disabled="state.loading or state.saving" title="Create an open shift employees can claim">
|
||||
<i class="fa fa-plus me-1"/> Open Shift…
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -49,6 +52,35 @@
|
||||
<button class="btn btn-light btn-sm" t-on-click="() => this.togglePublishPanel()">Cancel</button>
|
||||
</div>
|
||||
|
||||
<div t-if="state.openShift.open" class="fclk-planner__publish-panel">
|
||||
<label>Date <input type="date" t-att-value="state.openShift.date" t-on-change="(ev) => this.onOpenShiftField('date', ev)"/></label>
|
||||
<label>Start <input type="time" t-att-value="state.openShift.start" t-on-change="(ev) => this.onOpenShiftField('start', ev)"/></label>
|
||||
<label>End <input type="time" t-att-value="state.openShift.end" t-on-change="(ev) => this.onOpenShiftField('end', ev)"/></label>
|
||||
<label>Count <input type="number" min="1" class="fclk-planner__repeat-int" t-att-value="state.openShift.count" t-on-change="(ev) => this.onOpenShiftField('count', ev)"/></label>
|
||||
<button class="btn btn-secondary btn-sm" t-on-click="() => this.addOpenShift()" t-att-disabled="state.saving">
|
||||
<i class="fa fa-plus me-1"/> Add Open Shift
|
||||
</button>
|
||||
<button class="btn btn-light btn-sm" t-on-click="() => this.toggleOpenShiftPanel()">Cancel</button>
|
||||
</div>
|
||||
|
||||
<div t-if="hasOpenShifts" class="fclk-planner__open-strip">
|
||||
<div class="fclk-planner__open-strip-title"><i class="fa fa-bullhorn me-1"/> Open Shifts (employees can claim)</div>
|
||||
<div class="fclk-planner__open-cols">
|
||||
<t t-foreach="state.days" t-as="day" t-key="'open_' + day.date">
|
||||
<div class="fclk-planner__open-col" t-if="getOpenShiftsForDay(day.date).length">
|
||||
<div class="fclk-planner__open-day"><t t-esc="day.weekday"/> <t t-esc="day.label"/></div>
|
||||
<t t-foreach="getOpenShiftsForDay(day.date)" t-as="op" t-key="op.id">
|
||||
<div class="fclk-planner__open-chip">
|
||||
<span><t t-esc="op.label"/></span>
|
||||
<span t-if="op.role_name" class="fclk-planner__open-role"><t t-esc="op.role_name"/></span>
|
||||
<button class="fclk-planner__open-del" t-on-click="() => this.deleteOpenShift(op.id)" title="Remove open shift">×</button>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t t-if="state.error">
|
||||
<div class="alert alert-danger mx-3 mt-3"><t t-esc="state.error"/></div>
|
||||
</t>
|
||||
@@ -254,6 +286,12 @@
|
||||
t-on-click="() => this.clearRecurrence()">
|
||||
<i class="fa fa-ban me-1"/> Stop repeat
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-light"
|
||||
t-on-click="() => this.bulkApplyDept()"
|
||||
title="Apply this shift to everyone in the same department">
|
||||
<i class="fa fa-users me-1"/> Apply to dept
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-primary"
|
||||
t-on-click="() => this.applyEditorRange(true)">
|
||||
|
||||
Reference in New Issue
Block a user