Edits to usability

This commit is contained in:
2024-05-09 12:57:21 -04:00
parent ea785887a1
commit 77619b0741
3 changed files with 139 additions and 91 deletions

View File

@@ -1,72 +1,87 @@
<template>
<q-card>
<q-card-section horizontal>
<div>
<q-expansion-item
expand-icon-toggle
draggable="true"
@dragstart="onDragStart($event, template)"
>
<template v-slot:header>
<q-item-section>
<q-input
label="Template name"
filled
:borderless="!edit"
dense
v-model="template.name"
v-if="editable"
/>
<q-list dense>
<q-item v-for="item in template.timeTuples" :key="item[0]">
<q-input
dense
:filled="editable"
v-model="item[0]"
type="time"
label="Start"
:readonly="!editable"
/>
<q-input
:filled="editable"
dense
v-model="item[1]"
type="time"
label="End"
:readonly="!editable"
/> </q-item></q-list
><q-btn
v-if="editable"
v-if="edit"
/><q-item-label v-if="!edit" class="cursor-pointer">{{
template.name
}}</q-item-label></q-item-section
>
</template>
<q-card flat>
<q-card-section horizontal>
<q-card-section class="q-pt-xs">
<q-list dense>
<q-item v-for="item in template.timeTuples" :key="item[0]">
<q-input
class="q-mx-sm"
dense
v-model="item[0]"
type="time"
label="Start"
:borderless="!edit"
:readonly="!edit"
/>
<q-input
class="q-mx-sm"
dense
v-model="item[1]"
type="time"
label="End"
:borderless="!edit"
:readonly="!edit"
/> </q-item></q-list
></q-card-section>
<q-btn
v-if="edit"
dense
color="primary"
size="sm"
label="Add interval"
@click="template.timeTuples.push(['00:00', '00:00'])"
/>
</div>
<q-card-actions align="right" vertical>
<q-btn
v-if="!editable"
color="primary"
icon="edit"
label="Edit"
@click="editable = !editable"
/>
<q-btn
v-if="editable"
color="primary"
icon="save"
label="Save"
@click="saveTemplate($event, template)"
/>
<q-btn
v-if="editable"
color="secondary"
icon="cancel"
label="Cancel"
@click="revert"
/>
<q-btn
color="negative"
icon="delete"
label="Delete"
@click="deleteTemplate($event, template)"
/>
</q-card-actions>
</q-card-section>
</q-card>
<q-card-actions align="right" vertical>
<q-btn
v-if="!edit"
color="primary"
icon="edit"
label="Edit"
@click="toggleEdit"
/>
<q-btn
v-if="edit"
color="primary"
icon="save"
label="Save"
@click="saveTemplate($event, template)"
/>
<q-btn
v-if="edit"
color="secondary"
icon="cancel"
label="Cancel"
@click="revert"
/>
<q-btn
color="negative"
icon="delete"
label="Delete"
v-if="template.$id !== ''"
@click="deleteTemplate($event, template)"
/>
</q-card-actions>
</q-card-section>
</q-card>
</q-expansion-item>
<q-dialog v-model="alert">
<q-card>
<q-card-section>
@@ -89,17 +104,31 @@
</template>
<script setup lang="ts">
import { timeTuplesOverlapped, useScheduleStore } from 'src/stores/schedule';
import {
copyTimeBlockTemplate,
timeTuplesOverlapped,
useScheduleStore,
} from 'src/stores/schedule';
import { TimeBlockTemplate } from 'src/stores/schedule.types';
import { ref } from 'vue';
const editable = ref(false);
const alert = ref(false);
const overlapped = ref();
const scheduleStore = useScheduleStore();
const template = defineModel<TimeBlockTemplate>({ required: true });
const props = defineProps<{ edit?: boolean; modelValue: TimeBlockTemplate }>();
const edit = ref(props.edit);
const template = ref(copyTimeBlockTemplate(props.modelValue));
const emit = defineEmits<{ (e: 'cancel'): void }>();
const revert = () => {
editable.value = false;
template.value = copyTimeBlockTemplate(props.modelValue);
console.log(template.value, props.modelValue);
edit.value = false;
emit('cancel');
};
const toggleEdit = () => {
edit.value = !edit.value;
};
const deleteTemplate = (
@@ -108,22 +137,29 @@ const deleteTemplate = (
) => {
if (template?.$id) scheduleStore.deleteTimeBlockTemplate(template.$id);
};
// const edit = () => {
// // TODO: Make it so that editing the template does not affect the store. Need to be able to "cancel" editing, and revert to original data
// };
function onDragStart(e: DragEvent, template: TimeBlockTemplate) {
if (e.dataTransfer) {
console.log('Drag start: ', e);
e.dataTransfer.dropEffect = 'copy';
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('ID', template.$id || '');
}
}
const saveTemplate = (evt: Event, template: TimeBlockTemplate | undefined) => {
if (!template) return false;
overlapped.value = timeTuplesOverlapped(template.timeTuples);
if (overlapped.value.length > 0) {
alert.value = true;
} else {
if (template.$id) {
if (template.$id && template.$id !== 'unsaved') {
console.log(template.$id);
scheduleStore.updateTimeBlockTemplate(template, template.$id);
} else {
scheduleStore.createTimeBlockTemplate(template);
template.$id = '';
}
editable.value = false;
edit.value = false;
}
};
</script>

View File

@@ -19,6 +19,7 @@
:drag-leave-func="onDragLeave"
:drop-func="onDrop"
:day-min-height="50"
:cell-width="140"
:day-height="0"
>
<template #day="{ scope }">
@@ -59,24 +60,21 @@
</q-item-section>
</q-item>
<q-card-actions align="right">
<q-btn label="Add Template" color="primary" @click="addTemplate" />
<q-btn label="Add Template" color="primary" @click="createTemplate" />
</q-card-actions>
<q-item v-if="newTemplate.$id === 'unsaved'"
><TimeBlockTemplateComponent
:model-value="newTemplate"
:edit="true"
@cancel="cancelNewTemplate"
/></q-item>
<q-separator spaced />
<q-expansion-item
<TimeBlockTemplateComponent
v-for="template in timeblockTemplates"
:key="template.$id"
dense
dense-toggle
expand-separator
:label="template.name"
style="font-size: 0.8em"
draggable="true"
@dragstart="onDragStart($event, template)"
>
<TimeBlockTemplateComponent
:model-value="template"
/> </q-expansion-item
></q-list>
:model-value="template"
/>
</q-list>
</div>
</div>
</template>
@@ -103,6 +101,12 @@ const { getTimeBlocks, fetchTimeBlocks, fetchTimeBlockTemplates } =
const { boats } = storeToRefs(useBoatStore());
const { timeblockTemplates } = storeToRefs(useScheduleStore());
const calendar = ref();
const blankTemplate: TimeBlockTemplate = {
$id: '',
name: 'NewTemplate',
timeTuples: [['00:00', '00:00']],
};
const newTemplate = ref<TimeBlockTemplate>({ ...blankTemplate });
onMounted(async () => {
await fetchBoats();
@@ -110,8 +114,12 @@ onMounted(async () => {
await fetchTimeBlockTemplates();
});
function addTemplate() {
timeblockTemplates.value.push({ name: 'New Template', timeTuples: [] });
function cancelNewTemplate() {
newTemplate.value = { ...blankTemplate };
console.log(newTemplate.value);
}
function createTemplate() {
newTemplate.value.$id = 'unsaved';
}
function createTimeBlock(boat: Boat, templateId: string, date: string) {
const timeBlock = timeblockTemplates.value.find((t) => t.$id === templateId);
@@ -120,14 +128,6 @@ function createTimeBlock(boat: Boat, templateId: string, date: string) {
);
}
function onDragStart(e: DragEvent, template: TimeBlockTemplate) {
if (e.dataTransfer) {
console.log('Drag start: ', e);
e.dataTransfer.dropEffect = 'copy';
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('ID', template.$id || '');
}
}
function onDragEnter(e: DragEvent, type: string) {
console.log('onDragEnter', e, type);
if (type === 'day' || type === 'head-day') {

View File

@@ -57,6 +57,18 @@ export function blocksOverlapped(blocks: TimeBlock[] | Interval[]): Interval[] {
);
}
export function copyTimeTuples(tuples: TimeTuple[]): TimeTuple[] {
return tuples.map((t) => Object.assign([], t));
}
export function copyTimeBlockTemplate(
template: TimeBlockTemplate
): TimeBlockTemplate {
return {
...template,
timeTuples: copyTimeTuples(template.timeTuples),
};
}
export function buildTimeBlock(
resource: Boat,
time: TimeTuple,