Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/frontend/vue/components/UtilityPanel/Scratchpad.vue
3375 views
<template>
  <div class="scratchpad">
    <p class="scratchpad__description">
      {{ $translate('This is your Python Scratchpad. Use this however you like while you work or copy the code over from the chapter.') }}
    </p>
    <p class="scratchpad__description">
      <strong>{{ $translate('Note') }}: </strong>{{ $translate('Code in the scratchpad will not be saved.') }}
    </p>
    <div class="code-exercise">
      <div class="scratchpad__editor-block">
        <CodeEditor
          class="scratchpad__editor-block__editor"
          :code="code"
          :initial-code="initialCode"
          :scratchpad-enabled="false"
          @codeChanged="codeChanged"
          @resetOutput="resetOutput"
          @keyboardRun="keyboardRun"
        />
        <ExerciseActionsBar
          class="scratchpad__editor-block__actions-bar"
          :is-running="isKernelBusy"
          :run-enabled="isKernelReady"
          :grade-enabled="isKernelReady && isGradingExercise"
          :is-api-token-needed="isApiTokenNeeded"
          @run="run"
        />
      </div>
      <div v-if="isApiTokenNeeded" class="scratchpad__api-token-info">
        <WarningIcon />
        <div>
          This code is executed on real hardware using an IBM Quantum provider. Setup your API-token in
          <BasicLink url="/account/admin">
            your account
          </BasicLink>
          to execute this code cell.
        </div>
      </div>
      <CodeOutput
        ref="output"
        @running="kernelRunning"
        @finished="kernelFinished"
        @kernelReady="kernelReady"
      />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue, Options } from 'vue-class-component'
import WarningIcon from '@carbon/icons-vue/lib/warning--alt/32'
import BasicLink from '../common/BasicLink.vue'
import CodeEditor from '../CodeExercise/CodeEditor.vue'
import ExerciseActionsBar from '../CodeExercise/ExerciseActionsBar.vue'
import CodeOutput from '../CodeExercise/CodeOutput.vue'

const INITIAL_CODE = `




`
const pageRoute = window.location.pathname

type scratchpadCopyRequestEvent = Event & { detail: { code: string } }

@Options({
  components: {
    CodeEditor,
    ExerciseActionsBar,
    CodeOutput,
    BasicLink,
    WarningIcon
  }
})
export default class Scratchpad extends Vue {
  code = INITIAL_CODE
  isKernelBusy = false
  isKernelReady = false
  isGradingExercise = false
  isApiTokenNeeded = false

  get initialCode () {
    return INITIAL_CODE
  }

  mounted () {
    window.addEventListener(
      'scratchpadCopyRequest',
      (ev: Event) => {
        const { detail } = ev as scratchpadCopyRequestEvent
        const newCode = this.code === INITIAL_CODE ? `${detail.code}\n` : `${this.code}\n${detail.code}\n`
        this.codeChanged(newCode)
      }
    )
  }

  codeChanged (code: string) {
    this.code = code
    const codeOutput: any = this.$refs.output
    codeOutput.needsApiToken(this.code).then((isNeeded: boolean) => {
      this.isApiTokenNeeded = isNeeded
    })
  }

  resetOutput () {
    const codeOutput: any = this.$refs.output
    codeOutput.clearOutput()
  }

  run () {
    const codeOutput: any = this.$refs.output
    codeOutput.requestExecute(this.code)
    window.textbook.trackClickEvent('Run', `Scratchpad code cell, ${pageRoute}`)
  }

  keyboardRun () {
    this.run()
  }

  kernelRunning () {
    this.isKernelBusy = true
  }

  kernelFinished () {
    this.isKernelBusy = false
  }

  kernelReady () {
    this.isKernelReady = true
  }
}
</script>

<style scoped lang="scss">
@import 'carbon-components/scss/globals/scss/typography';

.scratchpad {
  &__description {
    @include type-style('body-short-01');
    margin-bottom: $spacing-05;
  }

  &__editor-block {
    position: relative;
    &__actions-bar {
      position: absolute;
      right: 0;
      bottom: 0;
      z-index: 3;
    }
  }

  &__api-token-info {
    @include type-style('body-short-01');
    display: flex;
    flex-flow: row;
    padding: $spacing-05;
    gap: $spacing-05;
  }
}
</style>