diff --git a/web/src/components/AuthenticatedImage.vue b/web/src/components/AuthenticatedImage.vue index 9e1a963..8b463b0 100644 --- a/web/src/components/AuthenticatedImage.vue +++ b/web/src/components/AuthenticatedImage.vue @@ -42,19 +42,27 @@ export default { url: this.src, data: this.image_data }); + }, + deferImage() { + setTimeout(() => { + if (this.cached) { + const c = this.getThumbnail(this.src); + if (c) { + this.image_data = c; + return; + } + } + this.loadImage(); + }, 0); + } + }, + watch: { + src: function (newVal, oldVal) { + this.deferImage() } }, mounted() { - setTimeout(() => { - if (this.cached) { - const c = this.getThumbnail(this.src); - if (c) { - this.image_data = c; - return; - } - } - this.loadImage(); - }, 0); + this.deferImage(); } } \ No newline at end of file diff --git a/web/src/components/CollapsableCards.vue b/web/src/components/CollapsableCards.vue index d1edab7..d38206a 100644 --- a/web/src/components/CollapsableCards.vue +++ b/web/src/components/CollapsableCards.vue @@ -52,7 +52,7 @@ export default { }; }, created() { - const query = this.$router.currentRoute ? (this.$router.currentRoute.query ? this.$router.currentRoute.query.collapsed : null) : null; + const query = this.route ? (this.route.query ? this.route.query.collapsed : null) : null; if (query !== null && query !== undefined) { this.collapsed = this.unpackInt(parseInt(query), this.sections.length); } else { @@ -84,8 +84,8 @@ export default { const encoded = this.packInt(this.collapsed).toString() if (this.route.query.collapsed !== encoded) this.$router.push({ - ...this.$router.currentRoute, - query: {...this.$router.currentRoute.query, collapsed: encoded} + ...this.route, + query: {...this.route.query, collapsed: encoded} }); }, deep: true, diff --git a/web/src/components/EditItem.vue b/web/src/components/EditItem.vue index 9bea6f9..833bfd5 100644 --- a/web/src/components/EditItem.vue +++ b/web/src/components/EditItem.vue @@ -12,13 +12,16 @@ field="description" :validation-fn="str => str && str.length > 0" /> - +
+ + +
diff --git a/web/src/components/Timeline.vue b/web/src/components/Timeline.vue index 88bfa94..41e1274 100644 --- a/web/src/components/Timeline.vue +++ b/web/src/components/Timeline.vue @@ -21,6 +21,9 @@ + + + @@ -30,40 +33,15 @@ + +

{{ item }}

  • - - - -
    -
    - - - - Save Comment - -
    -
    +
  • - - - -
    -
    - {{ newestMailSubject }} -
    -
    - - - - Send Mail - -
    -
    +
  • @@ -78,12 +56,20 @@ import TimelineAssignment from "@/components/TimelineAssignment.vue"; import TimelineRelatedItem from "@/components/TimelineRelatedItem.vue"; import TimelineShippingVoucher from "@/components/TimelineShippingVoucher.vue"; import AsyncButton from "@/components/inputs/AsyncButton.vue"; +import TimelinePlacement from "@/components/TimelinePlacement.vue"; +import TimelineRelatedTicket from "@/components/TimelineRelatedTicket.vue"; export default { name: 'Timeline', components: { - TimelineShippingVoucher, AsyncButton, - TimelineRelatedItem, TimelineAssignment, TimelineStateChange, TimelineComment, TimelineMail + TimelineRelatedTicket, + TimelinePlacement, + TimelineShippingVoucher, + TimelineRelatedItem, + TimelineAssignment, + TimelineStateChange, + TimelineComment, + TimelineMail }, props: { timeline: { @@ -91,33 +77,13 @@ export default { default: () => [] } }, - emits: ['sendMail', 'addComment'], - data: () => ({ - newMail: "", - newComment: "" - }), computed: { - ...mapGetters(['stateInfo']), - newestMailSubject() { - const mail = this.timeline.filter(item => item.type === 'mail').pop(); - return mail ? mail.subject : ""; - }, + ...mapGetters(['stateInfo']) }, - methods: { - ...mapActions(['sendMail', 'postComment']), - sendMailAndClear: async function () { - await this.sendMail(this.newMail); - this.newMail = ""; - }, - addCommentAndClear: async function () { - await this.postComment(this.newComment); - this.newComment = ""; - } - } }; - \ No newline at end of file diff --git a/web/src/components/TimelineRelatedItem.vue b/web/src/components/TimelineRelatedItem.vue index c17a3a8..b795853 100644 --- a/web/src/components/TimelineRelatedItem.vue +++ b/web/src/components/TimelineRelatedItem.vue @@ -5,8 +5,12 @@ - linked item #{{ item.item.uid }} on as {{ item.status }} + linked item #{{ + item.item.id + }} on as {{ + item.status + }}
    @@ -20,8 +24,10 @@
    -
    uid: {{ item.item.uid }} box: {{ item.item.box }}
    -
    {{ item.item.description }}
    +
    id: {{ item.item.id }} box: {{ item.item.box }}
    + +
    {{ item.item.description }}
    +
    @@ -33,7 +71,7 @@
    @@ -58,6 +96,30 @@
    +
    +
    +
    +
    Related
    +
    + +
    + +
    id: {{ item.id }} box: {{ + item.box + }}
    + +
    {{ item.description }}
    +
    +
    +
    +
    +
    +
    @@ -68,15 +130,19 @@ import {mapActions, mapGetters, mapState} from 'vuex'; import Timeline from "@/components/Timeline.vue"; import ClipboardButton from "@/components/inputs/ClipboardButton.vue"; import AsyncLoader from "@/components/AsyncLoader.vue"; +import AuthenticatedImage from "@/components/AuthenticatedImage.vue"; +import AsyncButton from "@/components/inputs/AsyncButton.vue"; export default { name: 'Ticket', - components: {AsyncLoader, ClipboardButton, Timeline}, + components: {AsyncButton, AuthenticatedImage, AsyncLoader, ClipboardButton, Timeline}, data() { return { selected_state: null, selected_assignee: null, shipping_voucher_type: null, + newMail: "", + newComment: "" } }, computed: { @@ -90,46 +156,51 @@ export default { shippingEmail() { const domain = document.location.hostname; return `ticket+${this.ticket.uuid}@${domain}`; - } + }, + newestMailSubject() { + const mail = this.ticket.timeline ? this.ticket.timeline.filter(item => item.type === 'mail').pop() : null; + return mail ? mail.subject : ""; + }, }, methods: { ...mapActions(['deleteItem', 'markItemReturned', 'sendMail', 'updateTicketPartial', 'postComment']), ...mapActions(['loadTickets', 'fetchTicketStates', 'loadUsers', 'scheduleAfterInit']), ...mapActions(['claimShippingVoucher', 'fetchShippingVouchers']), - handleMail(mail) { - this.sendMail({ - id: this.ticket.id, - message: mail - }) - }, - handleComment(comment) { - this.postComment({ - id: this.ticket.id, - message: comment - }) - }, - changeTicketStatus(ticket) { - ticket.state = this.selected_state; + changeTicketStatus() { + this.ticket.state = this.selected_state; this.updateTicketPartial({ - id: ticket.id, + id: this.ticket.id, state: this.selected_state, }) }, - assignTicket(ticket) { - ticket.assigned_to = this.selected_assignee; + assignTicket() { + this.ticket.assigned_to = this.selected_assignee; this.updateTicketPartial({ - id: ticket.id, + id: this.ticket.id, assigned_to: this.selected_assignee }) }, + sendMailAndClear: async function () { + await this.sendMail({ + id: this.ticket.id, + message: this.newMail, + }) + this.newMail = ""; + }, + addCommentAndClear: async function () { + await this.postComment({ + id: this.ticket.id, + message: this.newComment + }) + this.newComment = ""; + } }, mounted() { this.scheduleAfterInit(() => [Promise.all([this.fetchTicketStates(), this.loadTickets(), this.loadUsers(), this.fetchShippingVouchers()]).then(() => { - if (this.ticket.state == "pending_new") { + if (this.ticket.state === "pending_new") { this.selected_state = "pending_open"; - this.changeTicketStatus(this.ticket) + this.changeTicketStatus() } - ; this.selected_state = this.ticket.state; this.selected_assignee = this.ticket.assigned_to })]); diff --git a/web/src/views/Tickets.vue b/web/src/views/Tickets.vue index bc288f1..4a9144c 100644 --- a/web/src/views/Tickets.vue +++ b/web/src/views/Tickets.vue @@ -12,11 +12,11 @@ > @@ -39,11 +39,11 @@ {{ item.event }}