mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
Merge branch 'main' of bitbucket.org:studiotem/jandl-taskmanager-app
This commit is contained in:
commit
6a8afc2dc4
5 files changed
+71
-32
No files matched your search
@@ -59,8 +59,8 @@
|
|||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"task_id": 1,
|
"task_id": 1,
|
||||||
"starts_at": "2022-12-12T08:01:00+00:00",
|
"starts_at": "2022-12-19T08:01:00+00:00",
|
||||||
"ends_at": "2022-12-12T09:00:00+00:00",
|
"ends_at": "2022-12-19T09:00:00+00:00",
|
||||||
"title": "Task 1",
|
"title": "Task 1",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#E9FFE6"
|
"master_task_color": "#E9FFE6"
|
||||||
@@ -69,8 +69,8 @@
|
|||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"task_id": 2,
|
"task_id": 2,
|
||||||
"starts_at": "2022-12-12T08:30:00+00:00",
|
"starts_at": "2022-12-19T08:30:00+00:00",
|
||||||
"ends_at": "2022-12-12T09:00:00+00:00",
|
"ends_at": "2022-12-19T09:00:00+00:00",
|
||||||
"title": "Kratky 30min Lorem ipsum dolor sit amet, consectetur adipiscing e",
|
"title": "Kratky 30min Lorem ipsum dolor sit amet, consectetur adipiscing e",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#f27e57"
|
"master_task_color": "#f27e57"
|
||||||
@@ -79,8 +79,8 @@
|
|||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"task_id": 3,
|
"task_id": 3,
|
||||||
"starts_at": "2022-12-12T10:30:00+00:00",
|
"starts_at": "2022-12-19T10:30:00+00:00",
|
||||||
"ends_at": "2022-12-12T10:45:00+00:00",
|
"ends_at": "2022-12-19T10:45:00+00:00",
|
||||||
"title": "Kratky 15min",
|
"title": "Kratky 15min",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#57e0f2"
|
"master_task_color": "#57e0f2"
|
||||||
@@ -89,8 +89,8 @@
|
|||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"task_id": 4,
|
"task_id": 4,
|
||||||
"starts_at": "2022-12-12T08:00:00+00:00",
|
"starts_at": "2022-12-19T08:00:00+00:00",
|
||||||
"ends_at": "2022-12-12T10:00:00+00:00",
|
"ends_at": "2022-12-19T10:00:00+00:00",
|
||||||
"title": "Task 2",
|
"title": "Task 2",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#FDE1FF"
|
"master_task_color": "#FDE1FF"
|
||||||
@@ -99,8 +99,8 @@
|
|||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"task_id": 5,
|
"task_id": 5,
|
||||||
"starts_at": "2022-12-13T07:00:00+00:00",
|
"starts_at": "2022-12-20T09:00:00+00:00",
|
||||||
"ends_at": "2022-12-13T11:00:00+00:00",
|
"ends_at": "2022-12-20T12:00:00+00:00",
|
||||||
"title": "Task 5",
|
"title": "Task 5",
|
||||||
"is_blocker": true,
|
"is_blocker": true,
|
||||||
"master_task_color": null
|
"master_task_color": null
|
||||||
@@ -109,8 +109,8 @@
|
|||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"task_id": 6,
|
"task_id": 6,
|
||||||
"starts_at": "2022-12-13T09:00:00+00:00",
|
"starts_at": "2022-12-20T09:00:00+00:00",
|
||||||
"ends_at": "2022-12-13T12:00:00+00:00",
|
"ends_at": "2022-12-20T12:00:00+00:00",
|
||||||
"title": "Task 6",
|
"title": "Task 6",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#E9FFE6"
|
"master_task_color": "#E9FFE6"
|
||||||
@@ -119,8 +119,8 @@
|
|||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
"task_id": 7,
|
"task_id": 7,
|
||||||
"starts_at": "2022-12-14T12:00:00+00:00",
|
"starts_at": "2022-12-21T12:00:00+00:00",
|
||||||
"ends_at": "2022-12-14T16:00:00+00:00",
|
"ends_at": "2022-12-21T16:00:00+00:00",
|
||||||
"title": "Task 7",
|
"title": "Task 7",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#E7DBF8"
|
"master_task_color": "#E7DBF8"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ transition-group.vuecal__cell(
|
|||||||
:event="event"
|
:event="event"
|
||||||
:all-day="allDay"
|
:all-day="allDay"
|
||||||
:cell-events="splitsCount ? split.events : events"
|
:cell-events="splitsCount ? split.events : events"
|
||||||
:overlaps="((splitsCount ? split.overlaps[event._eid] : cellOverlaps[event._eid]) || []).overlaps"
|
:cellOverlaps="((splitsCount ? split.overlaps[event._eid] : cellOverlaps[event._eid]) || [])"
|
||||||
:event-position="((splitsCount ? split.overlaps[event._eid] : cellOverlaps[event._eid]) || []).position"
|
:event-position="((splitsCount ? split.overlaps[event._eid] : cellOverlaps[event._eid]) || []).position"
|
||||||
:overlaps-streak="splitsCount ? split.overlapsStreak : cellOverlapsStreak")
|
:overlaps-streak="splitsCount ? split.overlapsStreak : cellOverlapsStreak")
|
||||||
template(#event="{ event, view }")
|
template(#event="{ event, view }")
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default {
|
|||||||
cellFormattedDate: { type: String, default: "" },
|
cellFormattedDate: { type: String, default: "" },
|
||||||
event: { type: Object, default: () => ({}) },
|
event: { type: Object, default: () => ({}) },
|
||||||
cellEvents: { type: Array, default: () => [] },
|
cellEvents: { type: Array, default: () => [] },
|
||||||
overlaps: { type: Array, default: () => [] },
|
cellOverlaps: { type: Object, default: () => ({}) },
|
||||||
// If multiple simultaneous events, the events are placed from left to right from the
|
// If multiple simultaneous events, the events are placed from left to right from the
|
||||||
// one starting first to the last. (See utils/event.js > checkCellOverlappingEvents)
|
// one starting first to the last. (See utils/event.js > checkCellOverlappingEvents)
|
||||||
eventPosition: { type: Number, default: 0 },
|
eventPosition: { type: Number, default: 0 },
|
||||||
@@ -225,6 +225,14 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
overlaps() {
|
||||||
|
return this.cellOverlaps.overlaps
|
||||||
|
},
|
||||||
|
|
||||||
|
sameOverlaps() {
|
||||||
|
return this.cellOverlaps.sameOverlaps
|
||||||
|
},
|
||||||
|
|
||||||
eventDimensions() {
|
eventDimensions() {
|
||||||
const { startTimeMinutes, endTimeMinutes } = this.segment || this.event;
|
const { startTimeMinutes, endTimeMinutes } = this.segment || this.event;
|
||||||
|
|
||||||
@@ -260,11 +268,18 @@ export default {
|
|||||||
return {};
|
return {};
|
||||||
// let width = 100 / Math.min(this.overlaps.length + 1, this.overlapsStreak)
|
// let width = 100 / Math.min(this.overlaps.length + 1, this.overlapsStreak)
|
||||||
// let left = (100 - ((this.overlaps.length + 1) * 10 )) * this.eventPosition
|
// let left = (100 - ((this.overlaps.length + 1) * 10 )) * this.eventPosition
|
||||||
|
|
||||||
let width = 100 - this.eventPosition * 10;
|
let width = 100 - this.eventPosition * 10;
|
||||||
let left = (10 * this.eventPosition) / 2;
|
let left = (10 * this.eventPosition) / 2;
|
||||||
let zIdnex = (this.eventPosition + 1) * 10;
|
let zIdnex = (this.eventPosition + 1) * 10;
|
||||||
let background = this.event.master_task_color;
|
let background = this.event.master_task_color;
|
||||||
|
|
||||||
|
if (Array.isArray(this.cellOverlaps.sameOverlaps) && this.cellOverlaps.sameOverlaps.length) {
|
||||||
|
width = 50
|
||||||
|
left = 50 * this.eventPosition
|
||||||
|
zIdnex = 10
|
||||||
|
}
|
||||||
|
|
||||||
if (this.vuecal.minEventWidth && width < this.vuecal.minEventWidth) {
|
if (this.vuecal.minEventWidth && width < this.vuecal.minEventWidth) {
|
||||||
width = this.vuecal.minEventWidth;
|
width = this.vuecal.minEventWidth;
|
||||||
left =
|
left =
|
||||||
|
|||||||
@@ -324,13 +324,14 @@ export default class EventUtils {
|
|||||||
// The array is smaller and smaller as we loop.
|
// The array is smaller and smaller as we loop.
|
||||||
_comparisonArray.shift()
|
_comparisonArray.shift()
|
||||||
|
|
||||||
if (!_cellOverlaps[e._eid]) _cellOverlaps[e._eid] = { overlaps: [], start: e.start, position: 0 }
|
if (!_cellOverlaps[e._eid]) _cellOverlaps[e._eid] = { overlaps: [], start: e.start, position: 0, sameOverlaps: [] }
|
||||||
_cellOverlaps[e._eid].position = 0
|
_cellOverlaps[e._eid].position = 0
|
||||||
|
|
||||||
_comparisonArray.forEach(e2 => {
|
_comparisonArray.forEach(e2 => {
|
||||||
if (!_cellOverlaps[e2._eid]) _cellOverlaps[e2._eid] = { overlaps: [], start: e2.start, position: 0 }
|
if (!_cellOverlaps[e2._eid]) _cellOverlaps[e2._eid] = { overlaps: [], start: e2.start, position: 0, sameOverlaps: [] }
|
||||||
|
|
||||||
const eventIsInRange = this.eventInRange(e2, e.start, e.end)
|
const eventIsInRange = this.eventInRange(e2, e.start, e.end)
|
||||||
|
const eventSameOverlap = this.eventSameRange(e2, e)
|
||||||
const eventsInSameTimeStep = options.overlapsPerTimeStep ? ud.datesInSameTimeStep(e.start, e2.start, options.timeStep) : 1
|
const eventsInSameTimeStep = options.overlapsPerTimeStep ? ud.datesInSameTimeStep(e.start, e2.start, options.timeStep) : 1
|
||||||
// Add to the overlaps array if overlapping.
|
// Add to the overlaps array if overlapping.
|
||||||
if (!e.background && !e.allDay && !e2.background && !e2.allDay && eventIsInRange && eventsInSameTimeStep) {
|
if (!e.background && !e.allDay && !e2.background && !e2.allDay && eventIsInRange && eventsInSameTimeStep) {
|
||||||
@@ -340,6 +341,14 @@ export default class EventUtils {
|
|||||||
_cellOverlaps[e2._eid].overlaps.push(e._eid)
|
_cellOverlaps[e2._eid].overlaps.push(e._eid)
|
||||||
_cellOverlaps[e2._eid].overlaps = [...new Set(_cellOverlaps[e2._eid].overlaps)] // Dedupe, most performant way.
|
_cellOverlaps[e2._eid].overlaps = [...new Set(_cellOverlaps[e2._eid].overlaps)] // Dedupe, most performant way.
|
||||||
_cellOverlaps[e2._eid].position++
|
_cellOverlaps[e2._eid].position++
|
||||||
|
|
||||||
|
if (eventSameOverlap) {
|
||||||
|
_cellOverlaps[e._eid].sameOverlaps.push(e2._eid)
|
||||||
|
_cellOverlaps[e._eid].sameOverlaps = [...new Set(_cellOverlaps[e._eid].sameOverlaps)] // Dedupe, most performant way.
|
||||||
|
|
||||||
|
_cellOverlaps[e2._eid].sameOverlaps.push(e._eid)
|
||||||
|
_cellOverlaps[e2._eid].sameOverlaps = [...new Set(_cellOverlaps[e2._eid].sameOverlaps)] // Dedupe, most performant way.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Remove from the overlaps array if not overlapping or if 1 of the 2 events is background or all-day long.
|
// Remove from the overlaps array if not overlapping or if 1 of the 2 events is background or all-day long.
|
||||||
else {
|
else {
|
||||||
@@ -425,4 +434,10 @@ export default class EventUtils {
|
|||||||
const endTimestamp = event.end.getTime()
|
const endTimestamp = event.end.getTime()
|
||||||
return startTimestamp < end.getTime() && endTimestamp > start.getTime()
|
return startTimestamp < end.getTime() && endTimestamp > start.getTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventSameRange(event1, event2) {
|
||||||
|
const isSameStart = event1.start.getTime() == event2.start.getTime()
|
||||||
|
const isSameEnd = event1.end.getTime() == event2.end.getTime()
|
||||||
|
return isSameStart && isSameEnd
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,15 +21,15 @@
|
|||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
<v-select
|
<v-select
|
||||||
v-model="selectedTeam"
|
v-model="selectedMasterTask"
|
||||||
@focus="onInputFocus"
|
@focus="onInputFocus"
|
||||||
class="modal-input border-select"
|
class="modal-input border-select"
|
||||||
label="MasterTask"
|
label="MasterTask"
|
||||||
variant="solo"
|
variant="solo"
|
||||||
:items="teamsOptions"
|
:items="masterTaskOptions"
|
||||||
></v-select>
|
></v-select>
|
||||||
|
|
||||||
<p v-if="subTask.team.employees" class="d-flex justify-start align-center w-100 mb-3">Priradení zamestnanci</p>
|
<p v-if="subTask.team.employees" class="d-flex justify-start align-center w-100 mb-3 text-grey">Priradení zamestnanci</p>
|
||||||
|
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-for="(employee, index) in subTask.employees"
|
v-for="(employee, index) in subTask.employees"
|
||||||
@@ -81,14 +81,25 @@
|
|||||||
variant="solo"
|
variant="solo"
|
||||||
type="number"
|
type="number"
|
||||||
label="Časový odhad"
|
label="Časový odhad"
|
||||||
|
:class="{ error: v$.subTask.duration.$errors.length }"
|
||||||
|
:hint="
|
||||||
|
v$.subTask.duration.$errors
|
||||||
|
? errorUtils.parseErrors(v$.subTask.duration.$errors)
|
||||||
|
: null
|
||||||
|
"
|
||||||
append-inner-icon="mdi-clock-outline"
|
append-inner-icon="mdi-clock-outline"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
<v-textarea
|
<v-textarea
|
||||||
:class="{ error: v$.subTask.description.$errors.length }"
|
|
||||||
label="Popis"
|
label="Popis"
|
||||||
class="modal-input"
|
class="modal-input"
|
||||||
variant="solo"
|
variant="solo"
|
||||||
|
:class="{ error: v$.subTask.description.$errors.length }"
|
||||||
|
:hint="
|
||||||
|
v$.subTask.description.$errors
|
||||||
|
? errorUtils.parseErrors(v$.subTask.description.$errors)
|
||||||
|
: null
|
||||||
|
"
|
||||||
v-model="subTask.description"
|
v-model="subTask.description"
|
||||||
></v-textarea>
|
></v-textarea>
|
||||||
|
|
||||||
@@ -134,20 +145,18 @@ export default {
|
|||||||
return {
|
return {
|
||||||
subTask: {
|
subTask: {
|
||||||
project_code: null,
|
project_code: null,
|
||||||
duration: null,
|
|
||||||
date: null,
|
date: null,
|
||||||
team: {},
|
team: {},
|
||||||
description: null,
|
|
||||||
employees: [],
|
employees: [],
|
||||||
|
duration: null,
|
||||||
|
description: null,
|
||||||
files: []
|
files: []
|
||||||
},
|
},
|
||||||
errorUtils,
|
errorUtils,
|
||||||
v$: useVuelidate(),
|
v$: useVuelidate(),
|
||||||
preventInputFocus: false,
|
preventInputFocus: false,
|
||||||
teams: null,
|
|
||||||
employees: null,
|
employees: null,
|
||||||
selectedTeam: '',
|
selectedMasterTask: '',
|
||||||
selectedMasterTaskCode: '',
|
|
||||||
showAddEmployeeInput: false,
|
showAddEmployeeInput: false,
|
||||||
masterTasks: null
|
masterTasks: null
|
||||||
}
|
}
|
||||||
@@ -157,9 +166,9 @@ export default {
|
|||||||
return {
|
return {
|
||||||
subTask: {
|
subTask: {
|
||||||
project_code: { required },
|
project_code: { required },
|
||||||
duration: { required },
|
|
||||||
date: { required },
|
date: { required },
|
||||||
team: { required },
|
team: { required },
|
||||||
|
duration: { required },
|
||||||
description: { required },
|
description: { required },
|
||||||
employees: { atLeastOne }
|
employees: { atLeastOne }
|
||||||
},
|
},
|
||||||
@@ -234,7 +243,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
teamsOptions() {
|
masterTaskOptions() {
|
||||||
return this.masterTasks.map(masterTask => `${masterTask.name} - ${masterTask.id}`)
|
return this.masterTasks.map(masterTask => `${masterTask.name} - ${masterTask.id}`)
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -266,10 +275,10 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
selectedTeam() {
|
selectedMasterTask() {
|
||||||
this.subTask.team = this.masterTasks.find(masterTask => `${masterTask.name} - ${masterTask.id}` == this.selectedTeam)
|
this.subTask.team = this.masterTasks.find(masterTask => `${masterTask.name} - ${masterTask.id}` == this.selectedMasterTask)
|
||||||
this.subTask.employees = this.subTask.team.employees
|
this.subTask.employees = this.subTask.team.employees
|
||||||
this.subTask.project_code = this.masterTasks.filter(x => `${x.name} - ${x.id}` == this.selectedTeam)[0].project_code
|
this.subTask.project_code = this.masterTasks.filter(x => `${x.name} - ${x.id}` == this.selectedMasterTask)[0].project_code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user