Skip to content

Commit

Permalink
feat: Add ability to re-arrange job queue's items (#1692)
Browse files Browse the repository at this point in the history
* feat: Add job queue entry position change feature

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Add ability to move queue item to the queue top

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Allow to move queue item up

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Print button on the first queue item should be controlled via flag

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Allow to move queue item down

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Add ability to move queue item to the queue bottom

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Change the nomenclature of queue's start & end

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Do not display duplicated re-arrangement features
(second & next to last items)

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Formatting & linting fixes

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Simplify changePosition's code

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* feat: Add reusable convertJobToFilenames()

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>

* refactor: refactor some code syntax

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* refactor: refactor jobqueue entry and add draggable sort function

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* fix: fix job counter in status panel for jobqueue

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* feat: add function to start with every job in the jobqueue

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* fix: hide start button in jobqueue panel

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* refactor: remove unused style section

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* locale(en): remove unused keys

Signed-off-by: Stefan Dej <meteyou@gmail.com>

* locale(pl): remove unused keys

Signed-off-by: Stefan Dej <meteyou@gmail.com>

---------

Signed-off-by: Michał Dziekoński <michal.dziekonski+github@gmail.com>
Signed-off-by: Stefan Dej <meteyou@gmail.com>
Co-authored-by: Stefan Dej <meteyou@gmail.com>
  • Loading branch information
mdziekon and meteyou authored Feb 3, 2024
1 parent 36182d9 commit 9418603
Show file tree
Hide file tree
Showing 9 changed files with 500 additions and 471 deletions.
88 changes: 88 additions & 0 deletions src/components/dialogs/JobqueueEntryChangeCountDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<template>
<v-dialog :value="show" max-width="400">
<panel
:title="$t('JobQueue.ChangeCount')"
:icon="mdiCounter"
card-class="jobqueue-change-count-dialog"
:margin-bottom="false">
<template #buttons>
<v-btn icon tile @click="closeDialog">
<v-icon>{{ mdiCloseThick }}</v-icon>
</v-btn>
</template>

<v-card-text>
<v-text-field
ref="inputFieldAddToQueueCount"
v-model="count"
:label="$t('JobQueue.Count')"
required
:rules="countInputRules"
hide-spin-buttons
type="number"
@keyup.enter="update">
<template #append-outer>
<div class="_spin_button_group">
<v-btn class="mt-n3" icon plain small @click="count++">
<v-icon>{{ mdiChevronUp }}</v-icon>
</v-btn>
<v-btn :disabled="count <= 1" class="mb-n3" icon plain small @click="count--">
<v-icon>{{ mdiChevronDown }}</v-icon>
</v-btn>
</div>
</template>
</v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="" text @click="closeDialog">{{ $t('JobQueue.Cancel') }}</v-btn>
<v-btn color="primary" text @click="update">{{ $t('JobQueue.ChangeCount') }}</v-btn>
</v-card-actions>
</panel>
</v-dialog>
</template>
<script lang="ts">
import { Component, Mixins, Prop, Watch } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import Panel from '@/components/ui/Panel.vue'
import { mdiCloseThick, mdiChevronUp, mdiChevronDown, mdiCounter } from '@mdi/js'
import { ServerJobQueueStateJob } from '@/store/server/jobQueue/types'
@Component({
components: { Panel },
})
export default class JobqueueEntryChangeCountDialog extends Mixins(BaseMixin) {
mdiCloseThick = mdiCloseThick
mdiChevronUp = mdiChevronUp
mdiChevronDown = mdiChevronDown
mdiCounter = mdiCounter
@Prop({ type: Boolean, required: true }) show!: boolean
@Prop({ type: Object, required: true }) job!: ServerJobQueueStateJob
count = 1
countInputRules = [
(value: string) => !!value || this.$t('JobQueue.InvalidCountEmpty'),
(value: string) => parseInt(value) > 0 || this.$t('JobQueue.InvalidCountGreaterZero'),
]
update() {
this.$store.dispatch('server/jobQueue/changeCount', {
job_id: this.job.job_id,
count: this.count,
})
this.closeDialog()
}
closeDialog() {
this.$emit('close')
}
@Watch('show')
showChanged(show: boolean) {
if (show) this.count = (this.job.combinedIds?.length ?? 0) + 1
}
}
</script>
150 changes: 63 additions & 87 deletions src/components/panels/JobqueuePanel.vue
Original file line number Diff line number Diff line change
@@ -1,63 +1,53 @@
<template>
<div>
<panel
ref="jobqueuePanel"
:icon="mdiTrayFull"
:title="$t('JobQueue.JobQueue').toString()"
card-class="jobqueue-panel">
<template #buttons>
<v-btn
v-if="queueState === 'paused'"
color="success"
:loading="loadings.includes('startJobqueue')"
icon
tile
:disabled="!klipperReadyForGui"
@click="startJobqueue">
<v-tooltip top>
<template #activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on">{{ mdiPlay }}</v-icon>
</template>
<span>{{ $t('JobQueue.Start') }}</span>
</v-tooltip>
</v-btn>
<v-btn
v-if="['ready', 'loading'].includes(queueState)"
color="warning"
:loading="loadings.includes('pauseJobqueue')"
icon
tile
@click="pauseJobqueue">
<v-tooltip top>
<template #activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on">{{ mdiPause }}</v-icon>
</template>
<span>{{ $t('JobQueue.Pause') }}</span>
</v-tooltip>
</v-btn>
</template>
<v-data-table
:items="jobs"
class="jobqueue-table"
sort-by="time_added"
:items-per-page.sync="countPerPage"
:footer-props="{
itemsPerPageText: $t('JobQueue.Jobs'),
itemsPerPageAllText: $t('JobQueue.AllJobs'),
itemsPerPageOptions: [10, 25, 50, 100, -1],
}"
mobile-breakpoint="0">
<template #no-data>
<div class="text-center">{{ $t('JobQueue.Empty') }}</div>
</template>

<template #item="{ item }">
<jobqueue-entry :key="item.job_id" :item="item" :content-td-width="contentTdWidth" />
</template>
</v-data-table>
<resize-observer @notify="handleResize" />
</panel>
</div>
<panel :icon="mdiTrayFull" :title="$t('JobQueue.JobQueue')" card-class="jobqueue-panel">
<template #buttons>
<v-btn
v-if="queueState === 'paused'"
color="success"
:loading="loadings.includes('startJobqueue')"
icon
tile
:disabled="!klipperReadyForGui"
@click="startJobqueue">
<v-tooltip top>
<template #activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on">{{ mdiPlay }}</v-icon>
</template>
<span>{{ $t('JobQueue.Start') }}</span>
</v-tooltip>
</v-btn>
<v-btn
v-if="['ready', 'loading'].includes(queueState)"
color="warning"
:loading="loadings.includes('pauseJobqueue')"
icon
tile
@click="pauseJobqueue">
<v-tooltip top>
<template #activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on">{{ mdiPause }}</v-icon>
</template>
<span>{{ $t('JobQueue.Pause') }}</span>
</v-tooltip>
</v-btn>
</template>
<v-row v-if="jobs.length" class="mx-0 mt-0">
<v-col>
<draggable
v-model="joblist"
handle=".handle"
class="jobqueue-list"
ghost-class="ghost"
group="jobs"
@end="updateOrder">
<jobqueue-entry v-for="job in jobs" :key="job.job_id" :job="job" :show-handle="true" />
</draggable>
</v-col>
</v-row>
<v-card-text v-else>
<p>{{ $t('JobQueue.Empty') }}</p>
</v-card-text>
</panel>
</template>

<script lang="ts">
Expand All @@ -66,19 +56,16 @@ import BaseMixin from '@/components/mixins/base'
import Panel from '@/components/ui/Panel.vue'
import { mdiPlay, mdiPause, mdiTrayFull } from '@mdi/js'
import JobqueueEntry from '@/components/panels/Status/JobqueueEntry.vue'
import draggable from 'vuedraggable'
@Component({
components: { JobqueueEntry, Panel },
components: { draggable, JobqueueEntry, Panel },
})
export default class JobqueuePanel extends Mixins(BaseMixin) {
mdiPlay = mdiPlay
mdiPause = mdiPause
mdiTrayFull = mdiTrayFull
private contentTdWidth = 100
declare $refs: {
jobqueuePanel: any
}
joblist = []
get jobs() {
return this.$store.getters['server/jobQueue/getJobs']
Expand All @@ -88,14 +75,6 @@ export default class JobqueuePanel extends Mixins(BaseMixin) {
return this.$store.state.server.jobQueue.queue_state ?? ''
}
get countPerPage() {
return this.$store.state.gui.view.jobqueue.countPerPage
}
set countPerPage(newVal) {
this.$store.dispatch('gui/saveSetting', { name: 'view.jobqueue.countPerPage', value: newVal })
}
startJobqueue() {
this.$store.dispatch('server/jobQueue/start')
}
Expand All @@ -104,24 +83,21 @@ export default class JobqueuePanel extends Mixins(BaseMixin) {
this.$store.dispatch('server/jobQueue/pause')
}
mounted() {
this.calcContentTdWidth()
}
calcContentTdWidth() {
this.contentTdWidth = this.$refs.jobqueuePanel?.$el?.clientWidth - 48 - 32
}
handleResize() {
this.$nextTick(() => {
this.calcContentTdWidth()
updateOrder(event: { oldIndex: number; newIndex: number }) {
this.$store.dispatch('server/jobQueue/changePosition', {
newIndex: event.newIndex,
oldIndex: event.oldIndex,
})
}
}
</script>

<style scoped>
.jobqueue-panel {
position: relative;
<style lang="scss">
.jobqueue-list > div + div {
border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.jobqueue-list > div.ghost {
background-color: rgba(255, 255, 255, 0.12);
}
</style>
Loading

0 comments on commit 9418603

Please sign in to comment.