Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close the queue item view dialog when the item is no longer in the queue #53

Merged
merged 5 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 6 additions & 89 deletions src/components/queue/QueueFrame.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,11 @@
<div class="g-breadcrumb">
<v-breadcrumbs :items="breadcrumb"> </v-breadcrumbs>
</div>
<div class="g-top pa-4 font-weight-light">
<p>
Python scripts in the queue are executed in the order when the auto mode is
<span class="font-italic"> Queue. </span>
<span v-if="!mobile">
The items in the queue are not stored in the database but in the memory of
the backend server. If the server is restarted, the queue will be empty.
</span>
</p>
<div class="g-top">
<top-frame> </top-frame>
</div>
<div class="g-table">
<v-data-table
:loading="loading"
:headers="headers"
:items="items"
:items-per-page="-1"
@click-:row="showViewDialog = true"
@click:row="onClickRow"
>
<template #no-data>
<div
class="text-left font-weight-light"
style="max-width: 480px; margin: auto"
>
<p class="text-center font-weight-regular">The queue is empty.</p>
<p class="font-weight-light mt-1">
The auto mode will be turned off if a script is tried to be pulled when
the queue is empty.
<a
@click="showAddDialog = true"
class="text-decoration-underline cursor-pointer"
>
Add the first item.
</a>
</p>
</div>
</template>
<template #item.index="{ index }">
<span class="text-primary font-weight-medium"> {{ index + 1 }} </span>
</template>
<template #item.script="{ item }">
<div class="item-script">
{{ item.script }}
</div>
</template>
<template #bottom></template>
</v-data-table>
<table-frame v-model:show-add-dialog="showAddDialog"> </table-frame>
</div>
</div>
<v-btn
Expand All @@ -63,49 +21,16 @@
@click="showAddDialog = true"
>
</v-btn>
<view-dialog v-model="showViewDialog" :item="viewItem" v-if="viewItem">
</view-dialog>
<add-dialog v-model="showAddDialog"> </add-dialog>
</div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { useDisplay } from "vuetify";
import { useItems } from "./items";
import type { Item } from "./items";

import ViewDialog from "./view/ViewDialog.vue";
import { ref } from "vue";
import TopFrame from "./TopFrame.vue";
import TableFrame from "./TableFrame.vue";
import AddDialog from "./add/AddDialog.vue";

const { mobile } = useDisplay();

const breadcrumb = [{ title: "Queue", disabled: false }];

const headersMobile = [
{ title: "Name", key: "name", sortable: false },
{ title: "Created At", key: "createdAt", sortable: false },
];

const headersNotMobile = [
{ title: "Order", key: "index", sortable: false },
{ title: "Name", key: "name", sortable: false },
{ title: "Created at", key: "createdAt", sortable: false },
{ title: "Python script", key: "script", sortable: false },
];

const headers = computed(() => (mobile.value ? headersMobile : headersNotMobile));

const { items, loading } = useItems();

const showViewDialog = ref(false);
const viewItem = ref<Item>();

function onClickRow(event: Event, value: { item: Item }) {
showViewDialog.value = true;
viewItem.value = value.item;
}

const showAddDialog = ref(false);
</script>

Expand Down Expand Up @@ -153,12 +78,4 @@ const showAddDialog = ref(false);
.g-table {
grid-area: table;
}

.item-script {
max-inline-size: 240px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: rgb(var(--v-theme-on-surface-variant));
}
</style>
96 changes: 96 additions & 0 deletions src/components/queue/TableFrame.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<template>
<v-data-table
:loading="loading"
:headers="headers"
:items="items"
:items-per-page="-1"
@click-:row="showViewDialog = true"
@click:row="onClickRow"
>
<template #no-data>
<div class="text-left font-weight-light" style="max-width: 480px; margin: auto">
<p class="text-center font-weight-regular">The queue is empty.</p>
<p class="font-weight-light mt-1">
The auto mode will be turned off if a script is tried to be pulled when the
queue is empty.
<a
@click="showAddDialog = true"
class="text-decoration-underline cursor-pointer"
>
Add the first item.
</a>
</p>
</div>
</template>
<template #item.index="{ index }">
<span class="text-primary font-weight-medium"> {{ index + 1 }} </span>
</template>
<template #item.script="{ item }">
<div class="item-script">
{{ item.script }}
</div>
</template>
<template #bottom></template>
</v-data-table>
<view-dialog v-model="showViewDialog" :item="viewItem" v-if="viewItem"> </view-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watchEffect } from "vue";
import { useDisplay } from "vuetify";
import { useItems } from "./items";
import type { Item } from "./items";

import ViewDialog from "./view/ViewDialog.vue";

const showAddDialog = defineModel<boolean>("showAddDialog");

const { mobile } = useDisplay();

const headersMobile = [
{ title: "Name", key: "name", sortable: false },
{ title: "Created At", key: "createdAt", sortable: false },
];

const headersNotMobile = [
{ title: "Order", key: "index", sortable: false },
{ title: "Name", key: "name", sortable: false },
{ title: "Created at", key: "createdAt", sortable: false },
{ title: "Python script", key: "script", sortable: false },
];

const headers = computed(() => (mobile.value ? headersMobile : headersNotMobile));

const { items, loading } = useItems();

const showViewDialog = ref(false);
const viewItem = ref<Item>();

function onClickRow(event: Event, value: { item: Item }) {
showViewDialog.value = true;
viewItem.value = value.item;
}

const viewItemInItems = computed(() => {
const id = viewItem.value?.id;
return id ? items.value?.some((item) => item.id === id) : false;
});

// Close the view dialog if the item is no longer in the queue.
// TODO: Show a notification after closing the dialog.
watchEffect(() => {
if (!viewItemInItems.value) {
showViewDialog.value = false;
}
});
</script>

<style scoped>
.item-script {
max-inline-size: 240px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: rgb(var(--v-theme-on-surface-variant));
}
</style>
15 changes: 15 additions & 0 deletions src/components/queue/TopFrame.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<p class="ma-4 font-weight-light">
Python scripts in the queue are executed in the order when the auto mode is
<span class="font-italic"> Queue. </span>
<span v-if="!mobile">
The items in the queue are not stored in the database but in the memory of the
backend server. If the server is restarted, the queue will be empty.
</span>
</p>
</template>

<script setup lang="ts">
import { useDisplay } from "vuetify";
const { mobile } = useDisplay();
</script>
10 changes: 5 additions & 5 deletions src/components/queue/add/AddDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
@confirm="discardConfirmed"
>
</discard-confirmation-dialog>
<progress-dialog v-model="dialogProgress"> </progress-dialog>
<LoadingIndicator v-model="loading"> </LoadingIndicator>
</v-dialog>
</template>

Expand All @@ -40,7 +40,7 @@ import { useDisplay } from "vuetify";
import ItemAdd from "./ItemAdd.vue";
import type { State } from "./ItemAdd.vue";
import DiscardConfirmationDialog from "./DiscardConfirmationDialog.vue";
import ProgressDialog from "./ProgressDialog.vue";
import LoadingIndicator from "../LoadingIndicator.vue";
import { useItems } from "../items";
const show = defineModel<boolean>();
const { mobile } = useDisplay();
Expand All @@ -51,7 +51,7 @@ const state = ref<State>();
const valid = ref<boolean>();
const dirty = ref<boolean>();
const dialogConfirmDiscard = ref<boolean>(false);
const dialogProgress = ref<boolean>(false);
const loading = ref<boolean>(false);

// Show the confirmation dialog if the form is edited
function onClickCancel() {
Expand All @@ -71,9 +71,9 @@ const { addItem } = useItems();

async function onClickAdd() {
if (state.value === undefined) return;
dialogProgress.value = true;
loading.value = true;
await addItem(state.value);
dialogProgress.value = false;
loading.value = false;
state.value = undefined;
show.value = false;
}
Expand Down
18 changes: 0 additions & 18 deletions src/components/queue/view/ProgressDialog.vue

This file was deleted.

10 changes: 5 additions & 5 deletions src/components/queue/view/ViewDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
@confirm="onDeleteConfirmed"
>
</delete-confirmation-dialog>
<progress-dialog v-model="dialogProgress"> </progress-dialog>
<LoadingIndicator v-model="loading"> </LoadingIndicator>
</v-dialog>
</template>

Expand All @@ -40,7 +40,7 @@ import ItemView from "./ItemView.vue";
import { useItems } from "../items";
import type { Item } from "../items";
import DeleteConfirmationDialog from "./DeleteConfirmationDialog.vue";
import ProgressDialog from "./ProgressDialog.vue";
import LoadingIndicator from "../LoadingIndicator.vue";

const { mobile } = useDisplay();

Expand All @@ -56,12 +56,12 @@ const { item } = toRefs(props);
const show = defineModel<boolean>();

const dialogConfirmDelete = ref(false);
const dialogProgress = ref<boolean>(false);
const loading = ref<boolean>(false);
const { deleteItem } = useItems();
async function onDeleteConfirmed() {
dialogProgress.value = true;
loading.value = true;
await deleteItem(item.value);
dialogProgress.value = false;
loading.value = false;
show.value = false;
}
</script>
Expand Down