@@ -32,8 +32,10 @@ AddEmployeeModal(
|
||||
td(
|
||||
v-for="(date, dIndex) in row.dates"
|
||||
:key="dIndex"
|
||||
:class="{'bg-secondary bg-opacity-10' : row.dates[dIndex] === null, 'selected' : isSelected(new Coordinates(mIndex, rIndex, eIndex, dIndex))}"
|
||||
@click="select(new Coordinates(mIndex, rIndex, eIndex, dIndex), $event)"
|
||||
:class="{'bg-secondary bg-opacity-10' : row.dates[dIndex] === null, 'selected' : isSelected(mIndex, rIndex, eIndex, dIndex)}"
|
||||
@click.exact="select(mIndex, rIndex, eIndex, dIndex)"
|
||||
@click.ctrl.exact="ctrlSelect(mIndex, rIndex, eIndex, dIndex)"
|
||||
@click.shift.exact="shiftSelect(mIndex, rIndex, eIndex, dIndex)"
|
||||
)
|
||||
tr()
|
||||
td.text-end
|
||||
@@ -51,11 +53,11 @@ AddEmployeeModal(
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRef, watch, computed, ref, h, render } from 'vue'
|
||||
import { watch, computed, ref } from 'vue'
|
||||
import type { Ref, ComputedRef } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useEmployees } from '../stores/employees'
|
||||
import { addMonths, eachMonthOfInterval, subDays, addDays, format, getISODay, getYear, getMonth, isValid, eachDayOfInterval, getDaysInMonth } from 'date-fns'
|
||||
import { addMonths, eachMonthOfInterval, subDays, addDays, format, getISODay, getYear, getMonth, getDaysInMonth } from 'date-fns'
|
||||
import { de } from 'date-fns/locale'
|
||||
import AddEmployeeModal from './AddEmployeeModal.vue'
|
||||
import Coordinates from '../types/coordinates'
|
||||
@@ -132,7 +134,7 @@ AddEmployeeModal(
|
||||
const scheduleData : Ref<ScheduleData> = ref(getScheduleData())
|
||||
const { employees } = storeToRefs(store)
|
||||
|
||||
const selected : Ref<Coordinates[]> = ref([])
|
||||
const selected : Ref<Set<string>> = ref(new Set())
|
||||
const shiftAnchor : Ref<Coordinates | undefined> = ref(undefined)
|
||||
/**
|
||||
* End Refs
|
||||
@@ -186,22 +188,11 @@ AddEmployeeModal(
|
||||
}
|
||||
}
|
||||
|
||||
function isSelected(c : Coordinates) : boolean {
|
||||
return selected.value.some(el => {
|
||||
return el.toString() === c.toString()
|
||||
})
|
||||
function isSelected(m : number, r : number, e : number, d : number) : boolean {
|
||||
return selected.value.has(Coordinates.toString(m,r,e,d))
|
||||
}
|
||||
function removeFromSelected(c : Coordinates) : boolean {
|
||||
let i = selected.value.findIndex(e => {
|
||||
return e.toString() === c.toString()
|
||||
})
|
||||
|
||||
if (i > -1){
|
||||
selected.value.splice(i, 1)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
function removeFromSelected(m : number, r : number, e : number, d : number) : boolean {
|
||||
return selected.value.delete(Coordinates.toString(m,r,e,d))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,33 +205,43 @@ AddEmployeeModal(
|
||||
}
|
||||
}
|
||||
|
||||
function select(coord : Coordinates, e : MouseEvent) {
|
||||
if(e.ctrlKey){
|
||||
if(isSelected(coord)){
|
||||
removeFromSelected(coord)
|
||||
shiftAnchor.value = selected.value[selected.value.length - 1]
|
||||
}
|
||||
else {
|
||||
selected.value.push(coord)
|
||||
shiftAnchor.value = coord
|
||||
}
|
||||
}
|
||||
else if(e.shiftKey && shiftAnchor.value !== undefined &&
|
||||
shiftAnchor.value.mIndex === coord.mIndex &&
|
||||
shiftAnchor.value.rIndex === coord.rIndex
|
||||
){
|
||||
// TODO: #8 Figure out how to select all cells between anchor and click
|
||||
|
||||
function select(m : number, r : number, e : number, d : number) : void {
|
||||
if(selected.value.size > 1 || !isSelected(m,r,e,d)) {
|
||||
selected.value.clear()
|
||||
selected.value.add(Coordinates.toString(m,r,e,d))
|
||||
shiftAnchor.value = new Coordinates(m,r,e,d)
|
||||
}
|
||||
else {
|
||||
if(selected.value.length > 1 || !isSelected(coord)) {
|
||||
selected.value = []
|
||||
selected.value.push(coord)
|
||||
shiftAnchor.value = coord
|
||||
}
|
||||
else {
|
||||
selected.value = []
|
||||
shiftAnchor.value = undefined
|
||||
selected.value.clear()
|
||||
shiftAnchor.value = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function ctrlSelect(m : number, r : number, e : number, d : number) : void {
|
||||
if(isSelected(m,r,e,d)){
|
||||
removeFromSelected(m,r,e,d)
|
||||
shiftAnchor.value = new Coordinates(m,r,e,d)
|
||||
}
|
||||
else {
|
||||
selected.value.add(Coordinates.toString(m,r,e,d))
|
||||
shiftAnchor.value = new Coordinates(m,r,e,d)
|
||||
}
|
||||
}
|
||||
|
||||
function shiftSelect(m : number, r : number, e : number, d : number) : void {
|
||||
if(shiftAnchor.value !== undefined &&
|
||||
shiftAnchor.value.mIndex === m &&
|
||||
shiftAnchor.value.rIndex === r &&
|
||||
shiftAnchor.value.toString() === [...selected.value].pop()
|
||||
){
|
||||
// TODO: #8 Figure out how to select all cells between anchor and click
|
||||
let [eBig, eSmall] : number[] = shiftAnchor.value.eIndex > e ? [shiftAnchor.value.eIndex, e] : [e, shiftAnchor.value.eIndex]
|
||||
let [dBig, dSmall] : number[] = shiftAnchor.value.dIndex > d ? [shiftAnchor.value.dIndex, d] : [d, shiftAnchor.value.dIndex]
|
||||
|
||||
for(let eIt = eSmall; eIt <= eBig; eIt++){
|
||||
for(let dIt = dSmall; dIt <= dBig; dIt++){
|
||||
selected.value.add(Coordinates.toString(m,r,eIt,dIt))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,7 +257,13 @@ AddEmployeeModal(
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
table-layout: fixed
|
||||
table-layout: fixed;
|
||||
-ms-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
-khtml-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
table td {
|
||||
cursor: pointer;
|
||||
|
||||
33
src/types/coordinates.ts
Normal file
33
src/types/coordinates.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export default class Coordinates {
|
||||
mIndex : number
|
||||
rIndex : number
|
||||
eIndex : number
|
||||
dIndex : number
|
||||
|
||||
constructor(m : number, r : number, e : number, d : number){
|
||||
this.mIndex = m
|
||||
this.rIndex = r
|
||||
this.eIndex = e
|
||||
this.dIndex = d
|
||||
}
|
||||
|
||||
toString() : string {
|
||||
return `${this.mIndex}-${this.rIndex}-${this.eIndex}-${this.dIndex}`
|
||||
}
|
||||
|
||||
static toString(m : number, r : number, e : number, d : number) : string {
|
||||
return `${m}-${r}-${e}-${d}`
|
||||
}
|
||||
|
||||
static stringToCoord(strRepr : string) : Coordinates | undefined {
|
||||
let re = /^[0-9]+-[0-9]+-[0-9]+-[0-9]+$/
|
||||
let numbers = []
|
||||
|
||||
if(re.test(strRepr)){
|
||||
numbers = strRepr.split('-')
|
||||
|
||||
return new Coordinates(+numbers[0], +numbers[1], +numbers[2], +numbers[3])
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user