aboutsummaryrefslogblamecommitdiffhomepage
path: root/src/components/services/OctoPrint.vue
blob: c5da8d9e4ac76657c81745fde076ceff4bc534e4 (plain) (tree)











































































































                                                                                
<template>
  <Generic :item="item" :title="state">
    <template #content>
      <p class="title is-4">{{ item.name }}</p>
      <p class="subtitle is-6">
        <template v-if="item.subtitle && !state">
          {{ item.subtitle }}
        </template>
        <template v-if="!error && display == 'text'">
          <i class="fa-solid fa-gear mr-1"></i>
          <b v-if="completion">{{ completion.toFixed() }}%</b>
          <span class="separator mx-1"> | </span>
          <span v-if="printTime" :title="`${toTime(printTimeLeft)} left`">
            <i class="fa-solid fa-stopwatch mr-1"></i>
            {{ toTime(printTime) }}
          </span>
        </template>
        <template v-if="!error && display == 'bar'">
          <progress
            v-if="completion"
            class="progress is-primary"
            :value="completion"
            max="100"
            :title="`${state} - ${completion.toFixed()}%, ${toTime(
              printTimeLeft
            )} left`"
          >
            {{ completion }}%
          </progress>
        </template>
        <span v-if="error" :title="error">{{ error }}</span>
      </p>
    </template>
    <template #indicator>
      <i :class="['status', statusClass]" :title="state"></i>
    </template>
  </Generic>
</template>

<script>
import service from "@/mixins/service.js";
import Generic from "./Generic.vue";

export default {
  name: "OctoPrint",
  mixins: [service],
  props: {
    item: Object,
  },
  components: {
    Generic,
  },
  data: () => ({
    printTime: null,
    printTimeLeft: null,
    completion: null,
    state: null,
    error: null,
  }),
  computed: {
    statusClass: function () {
      switch (this.state) {
        case "Operational":
          return "ready";
        case "Offline":
          return "offline";
        case "Printing":
          return "in-progress";
        default:
          return "pending";
      }
    },
  },
  created() {
    this.display = this.item.display == "bar" ? this.item.display : "text";
    this.fetchStatus();
  },
  methods: {
    fetchStatus: async function () {
      try {
        const response = await this.fetch(`api/job?apikey=${this.item.apikey}`);
        this.printTime = response.progress.printTime;
        this.printTimeLeft = response.progress.printTimeLeft;
        this.completion = response.progress.completion;
        this.state = response.state;
        this.error = response.error;
      } catch (e) {
        this.error = `Fail to fetch octoprint data (${e.message})`;
        console.error(e);
      }
    },
    toTime: function (timastamp) {
      return new Date(timastamp * 1000).toTimeString().substring(0, 5);
    },
  },
};
</script>

<style scoped lang="scss">
.fa-triangle-exclamation::before {
  color: #d65c68;
}

.progress {
  height: 8px;
  width: 90%;
}
</style>