ProfileEdit

ProfileEdit

<template>
  <div>
    <el-form ref="PostForm" :model="PostForm" label-width="80px">
      <el-form-item label="姓名">
        <el-input v-model="PostForm.Name"></el-input>
      </el-form-item>
      <el-form-item prop="PostForm.Grade" label="年级" :required="true">
        <el-select v-model="PostForm.Grade" value="">
          <elm-option label="高一" value="1"></elm-option>
          <el-option label="高二" value="2"></el-option>
          <el-option label="高三" value="3"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="PostForm.Class" label="班级" :required="true">
        <el-select v-model="PostForm.Class" value="">
          <el-option label="1" value="1"></el-option>
          <el-option label="2" value="2"></el-option>
          <el-option label="3" value="3"></el-option>
          <el-option label="4" value="4"></el-option>
          <el-option label="5" value="5"></el-option>
          <el-option label="6" value="6"></el-option>
          <el-option label="7" value="7"></el-option>
          <el-option label="8" value="8"></el-option>
          <el-option label="9" value="9"></el-option>
          <el-option label="10" value="10"></el-option>
          <el-option label="11" value="11"></el-option>
          <el-option label="12" value="12"></el-option>
          <el-option label="13" value="13"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="QQ" prop="QQ">
        <el-input v-model="PostForm.QQ"></el-input>
      </el-form-item>
      <el-form-item label="Email" prop="Email">
        <el-input v-model="PostForm.Email"></el-input>
      </el-form-item>
      <el-form-item label="Phone" prop="Phone">
        <el-input v-model="PostForm.Phone"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">立即创建</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
  import axios from 'axios'
  export default {
    data () {
      return {
        PostForm: {
          Name: '',
          Grade: '',
          Class: '',
          QQ: '',
          Email: '',
          Phone: ''
        }
      }
    },
    computed: {
      Authenticate () {
        return this.$store.state.Authenticated
      },
      GetToken () {
        return this.$store.state.Token
      },
      GetUserName () {
        return this.$store.state.UserName
      }
    },
    mounted: function () {
      axios({
        method: 'GET',
        url: 'http://127.0.0.1:8000/api/cd/post/list'
      })
        .then(function (response) {
          if (response.data.message === 'success') {
            this.PostListTable = JSON.parse(response.data.data)
            console.log(this.PostListTable)
            console.log('success')
          } else {
            console.log('error')
          }
        }.bind(this))
    }
  }
</script>
<style scoped>
  @import url("//unpkg.com/element-ui@1.3.2/lib/theme-default/index.css");
</style>

<template>
  <div>
    <el-form ref="PostForm" :model="PostForm" label-width="80px">
      <el-form-item label="姓名">
        <el-input v-model="PostForm.Name"></el-input>
      </el-form-item>
      <el-form-item prop="PostForm.Grade" label="年级" :required="true">
        <el-select v-model="PostForm.Grade" value="">
          <elm-option label="高一" value="1"></elm-option>
          <el-option label="高二" value="2"></el-option>
          <el-option label="高三" value="3"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="PostForm.Class" label="班级" :required="true">
        <el-select v-model="PostForm.Class" value="">
          <el-option label="1" value="1"></el-option>
          <el-option label="2" value="2"></el-option>
          <el-option label="3" value="3"></el-option>
          <el-option label="4" value="4"></el-option>
          <el-option label="5" value="5"></el-option>
          <el-option label="6" value="6"></el-option>
          <el-option label="7" value="7"></el-option>
          <el-option label="8" value="8"></el-option>
          <el-option label="9" value="9"></el-option>
          <el-option label="10" value="10"></el-option>
          <el-option label="11" value="11"></el-option>
          <el-option label="12" value="12"></el-option>
          <el-option label="13" value="13"></el-option>
        </el-select>
        <el-form-item prop="PostForm.QQ" label="QQ" :required="true">
          <el-form-item label="QQ" prop="QQ">
            <el-input v-model.number="PostForm.QQ"></el-input>
          </el-form-item>
          <el-form-item label="Email" prop="Email">
            <el-input v-model.number="PostForm.Email"></el-input>
          </el-form-item>
          <el-form-item label="Phone" prop="Phone">
            <el-input v-model.number="PostForm.Phone"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmit">立即创建</el-button>
            <el-button>取消</el-button>
          </el-form-item>
    </el-form>
  </div>
</template>
<script>
  import axios from 'axios'
  export default {
    data () {
      return {
        PostForm: {
          Grade: '',
          Class: '',
          QQ: '',
          Email: '',
          Phone: ''
        }
      }
    },
    computed: {
      Authenticate () {
        return this.$store.state.Authenticated
      },
      GetToken () {
        return this.$store.state.Token
      },
      GetUserName () {
        return this.$store.state.UserName
      }
    },
    mounted: function () {
      axios({
        method: 'GET',
        url: 'http://127.0.0.1:8000/api/cd/post/list'
      })
        .then(function (response) {
          if (response.data.message === 'success') {
            this.PostListTable = JSON.parse(response.data.data)
            console.log(this.PostListTable)
            console.log('success')
          } else {
            console.log('error')
          }
        }.bind(this))
    }
  }
</script>
<style scoped>
  @import url("//unpkg.com/element-ui@1.3.2/lib/theme-default/index.css");
</style>


解决供应商对账页面的单据点击不弹出的bug

解决供应商对账页面的单据点击不弹出的bug

<template>

                      {{ item.supplier }}

                  查询

                  {{firstTotal}} {{lastTotal}} {{pleaseSelect}}

            {{record.number}}

        <bill-detail ref="modalBillDetail"></bill-detail>
        <financial-detail ref="modalFinancialDetail"></financial-detail>

</template>

<template>

                      {{ item.supplier }}

                  查询

                  {{firstTotal}} {{lastTotal}} {{pleaseSelect}}

            {{record.number}}

        <bill-detail ref="modalDetail"></bill-detail>

</template>


debug panel fix

debug panel fix

<template>

    <CoreBase
      :immersivePage="currentPageIsImmersive"
      :appBarTitle="appBarTitle"
      :immersivePageIcon="immersivePageIcon"
      :immersivePageRoute="toolbarRoute"
      :immersivePagePrimary="immersivePagePrimary"
      :authorized="userCanAccessPage"
      authorizedRole="adminOrCoach"
      :showSubNav="Boolean(classId) && showCoachNav && !currentPageIsImmersive"
    >

      <NewCoachTopNav v-if="isNewPage" slot="sub-nav" />
      <CoachTopNav v-else slot="sub-nav" />

          MOCKUP FOR TRANSLATION:

          not the final design or functionality

{{ $route.params.page }}

      <template v-if="showCoachNav && !isNewPage">
        <NavTitle
          class="nav-title"
          :className="className"
          :classCoaches="classCoaches"
        />
      </template>
      <LessonContentPreviewPage
        v-if="isPreviewPage"
        :currentContentNode="currentContentNode"
        :isSelected="isSelected"
        :questions="questions"
        :displaySelectOptions="displaySelectOptions"
        :completionData="completionData"
        @addResource="handleAddResource"
        @removeResource="handleRemoveResource"
      />
      <component
        :is="currentPage"
        v-else
      />
      <router-view />

    </CoreBase>

</template>


Улучшение таблицы

Улучшение таблицы

<template>

Течение анестезии

          <button class="btn btn-blue-nb sidebar-btn close-btn"
                  @click="show_anesthesia_sidebar">

          </button>

          <input type="datetime-local" class="form-control nbr" v-model="timeValue" :max="maxTimeValue"/>
          <button class="btn btn-blue-nb nbr" @click="setCurrentTime" title="Текущие дата и время" v-tippy>

          </button>

Показатели человека

            <colgroup>
              <col/>
              <col width='80'/>
            </colgroup>

              {{k}}

                <input class="no-outline anastesia" type="text" v-model="patient_params_used[k]" :key="k"
                       @focus="focus_input"
                       @blur="blur_input"
                       @keyup.enter="move_focus_next"
                       @keyup.enter.shift="move_focus_prev"
                       placeholder="значение"/>

            <button class="btn btn-blue-nb nbr" @click="minus_temperature_once" tabindex="-1">
              -1
            </button>
            <button class="btn btn-blue-nb nbr" @mousedown="minus_temperature_start"
                    @mouseleave="temperature_stop" @mouseup="temperature_stop" tabindex="-1">
              -0.1
            </button>
            <input type="text" v-model.number="temperature" class="anastesia"
                   @keyup.enter="move_focus_next"
                   @keyup.enter.shift="move_focus_prev"
                   placeholder="Температура"/>
            <button class="btn btn-blue-nb nbr" @mousedown="plus_temperature_start"
                    @mouseleave="temperature_stop" @mouseup="temperature_stop" tabindex="-1">
              +0.1
            </button>
            <button class="btn btn-blue-nb nbr" @click="plus_temperature_once" tabindex="-1">
              +1
            </button>

Сильнодействующие

            <colgroup>
              <col/>
              <col width='80'/>
            </colgroup>

              {{k}}

                <input class="no-outline anastesia" type="text" v-model="potent_drugs_used[k]"
                       @focus="focus_input"
                       @blur="blur_input"
                       @keyup.enter="move_focus_next"
                       @keyup.enter.shift="move_focus_prev"
                       :key="k" placeholder="значение"/>

Наркотические

            <colgroup>
              <col/>
              <col width='80'/>
            </colgroup>

              {{k}}

                <input class="no-outline anastesia" type="text" v-model="narcotic_drugs_used[k]" :key="k"
                       @focus="focus_input"
                       @blur="blur_input"
                       @keyup.enter="move_focus_next"
                       @keyup.enter.shift="move_focus_prev"
                       placeholder="значение"/>

          <button class="btn btn-blue-nb nbr" @click="save_data">
            Добавить
          </button>
          <button class="btn btn-blue-nb nbr" @click="load_data">
            Обновить
          </button>

    <button class="btn btn-blue-nb tb-add-btn" title="Добавить значения в наркозную карту" v-tippy
            @click="show_anesthesia_sidebar">

      Добавить
    </button>

 0">

                  {{row[0]}}

             0">

 0">
                <DisplayDateTime :value="item"/>

                {{ item }}

            нет данных

</template>


Use method in keyup, down

Use method in keyup, down

<template>

貨物列車 種別計算

2〜4ケタの列番から列車種別を計算。現在は貨物列車の列番のみの対応です。旅客列車の種別計算は少々お待ち下さい。

              {{ error }}

          {{ freightType }}

      <form>

          列車番号 (2〜4ケタの数字)
          <input
            v-model.number="freightNumber"
            v-on:keyup="changeInput"
            v-on:keydown="changeInput"
            type="number"
            class="form-control"
            id="freightNumber"
            placeholder="列車番号"
          >

      </form>

</template>

<template>

貨物列車 種別計算

2〜4ケタの列番から列車種別を計算。現在は貨物列車の列番のみの対応です。旅客列車の種別計算は少々お待ち下さい。

              {{ error }}

          {{ freightType }}

      <form>

          列車番号 (2〜4ケタの数字)
          <input
            v-model.number="freightNumber"
            v-on:keyup="calcNumber(freightNumber)"
            v-on:keydown="calcNumber(freightNumber)"
            type="number"
            class="form-control"
            id="freightNumber"
            placeholder="列車番号"
          >

      </form>

</template>


Reassigning role and label to a proper modal div

<template>

      <button aria-label="Close dialog window" @click="closeModal" class="btn-close">
        <svg src="../icons/close.svg" role="presentation"></svg>
      </button>

          Error in:

        {{title}}

      <slot name="body" class="modal-content" id="modal-holder" role="document">

          To populate, add slot="body" to the HTML element you want to fill here.

      </slot>

</template>

<template>

      <button aria-label="close" @click="closeModal" class="btn-close">
        <svg src="../icons/close.svg"></svg>
      </button>

          Error in:

        {{title}}

      <slot name="body" class="modal-content" id="modal-holder" role="document">

          To populate, add slot="body" to the HTML element you want to fill here.

      </slot>

</template>


fixed #98 ui-pagination bug

fixed #98 ui-pagination bug

<template>
    <mor-pagination
        :_uiid="uiid"
        :class="[sizeClass, colorClass]"

        :total="total"
        :list="list"
        :page-size="pageSize"
        :page="page"
        :max-show="maxShow"
        :jump-page="jumpPage"
    >

        <slot
            :page="data.currentPage"
            :items="data.currentItems"
        ></slot>

        <template v-for="index in data.total">

            <template v-if="(data.hideEnd - 1) === index && data.hideEnd !== 1">
                
                ...
            </template>

            <template v-if="index >= data.hideEnd && index <= data.hideStart">

                    {{index}}

                    {{index}}

            </template>

            <template v-if="(data.hideStart + 1) === index && data.hideStart !== data.total">
                ...
                
            </template>

        </template>

 conf.maxShow"
        >
            <morning-textinput :ref="'ui-select-input-' + uiid" class="page-num" form-name="页码"></morning-textinput>
            

    </mor-pagination>
</template>


chore(): clear should be capital

chore(): clear should be capital

<template>

    <ScoreHeader></ScoreHeader>

Extras

Add that special something to supercharge your PWA. Consider connecting your website with these API's to enable magical cross-platform experiences.

            <button @click="clearSelected()" id="clearButton">Clear</button>
            <nuxt-link id="doneButton" to="/reportCard">Done</nuxt-link>

      <FeatureCard
        v-if="samples.length > 0 && !selectedSamples.includes(sample)"
        v-for="sample in samples"
        :sample="sample"
        :key="sample.id"
        v-on:selected="onSelected"
        v-on:removed="onRemoved"
        :showRemoveButton="false"
      ></FeatureCard>

      <FeatureCard
        v-if="selectedSamples.length > 0"
        v-for="sample in selectedSamples"
        :sample="sample"
        :key="sample.id"
        :showRemoveButton="true"
      ></FeatureCard>

        <Loading active></Loading>

        <Loading active></Loading>

        <Loading active></Loading>

    <Modal
      v-on:modalOpened="modalOpened()"
      v-on:modalClosed="modalClosed()"
      v-on:modalSubmit="modalSelected()"
      :showSubmitButton="false"
      title="Add Feature"
      ref="addFeatureModal"
    >

Usage Example

            <CodeViewer
              code-type="javascript"
              :size="viewerSize"
              :code="loadCode()"
              v-on:editorValue="updateCode($event)"
              v-if="sample"
              :showToolbar="true"
              :title="$t('windows.codeTitle')"
            ></CodeViewer>

Snippit

            <CodeViewer
              code-type="javascript"
              :size="viewerSize"
              :code="sample.source"
              v-if="sample"
              :showToolbar="true"
              :title="$t('windows.sourceTitle')"
            />

      <button
        slot="extraButton"
        id="addBundleButton"
        v-on:click="addBundle()"
      >{{ $t("windows.add") }}</button>

{{sample.description}}

Required Properties

{{prop.name}}

{{prop.description}}

    </Modal>

</template>

<template>

    <ScoreHeader></ScoreHeader>

Extras

Add that special something to supercharge your PWA. Consider connecting your website with these API's to enable magical cross-platform experiences.

            <button @click="clearSelected()" id="clearButton">clear</button>
            <nuxt-link id="doneButton" to="/reportCard">Done</nuxt-link>

      <FeatureCard
        v-if="samples.length > 0 && !selectedSamples.includes(sample)"
        v-for="sample in samples"
        :sample="sample"
        :key="sample.id"
        v-on:selected="onSelected"
        v-on:removed="onRemoved"
        :showRemoveButton="false"
      ></FeatureCard>

      <FeatureCard
        v-if="selectedSamples.length > 0"
        v-for="sample in selectedSamples"
        :sample="sample"
        :key="sample.id"
        :showRemoveButton="true"
      ></FeatureCard>

        <Loading active></Loading>

        <Loading active></Loading>

        <Loading active></Loading>

    <Modal
      v-on:modalOpened="modalOpened()"
      v-on:modalClosed="modalClosed()"
      v-on:modalSubmit="modalSelected()"
      :showSubmitButton="false"
      title="Add Feature"
      ref="addFeatureModal"
    >

Usage Example

            <CodeViewer
              code-type="javascript"
              :size="viewerSize"
              :code="loadCode()"
              v-on:editorValue="updateCode($event)"
              v-if="sample"
              :showToolbar="true"
              :title="$t('windows.codeTitle')"
            ></CodeViewer>

Snippit

            <CodeViewer
              code-type="javascript"
              :size="viewerSize"
              :code="sample.source"
              v-if="sample"
              :showToolbar="true"
              :title="$t('windows.sourceTitle')"
            />

      <button
        slot="extraButton"
        id="addBundleButton"
        v-on:click="addBundle()"
      >{{ $t("windows.add") }}</button>

{{sample.description}}

Required Properties

{{prop.name}}

{{prop.description}}

    </Modal>

</template>


improve product tile image margins

improve product tile image margins

<template>
  <div
    class="product align-center w-100 pb20"
    v-observe-visibility="visibilityChanged"
  >
    <router-link
      class="block no-underline product-link"
      :to="localizedRoute({
        name: product.type_id + '-product',
        params: {
          parentSku: product.parentSku ? product.parentSku : product.sku,
          slug: product.slug,
          childSku: product.sku
        }
      })"
      data-testid="productLink"
    >
      <div
        class="product-image relative bg-cl-secondary"
        :class="[{ sale: labelsActive && isOnSale }, { new: labelsActive && isNew }, {'product-image--loaded': imageLoaded}]">
        <img
          class="product-image__content"
          :alt="product.name"
          :src="thumbnailObj.src"
          height="300"
          width="310"
          data-testid="productImage"
          @load="imageLoaded = true"
        >
      </div>

      <p class="mb0 cl-accent mt10" v-if="!onlyImage">
        {{ product.name | htmlDecode }}
      </p>

      <span
        class="price-original mr5 lh30 cl-secondary"
        v-if="product.special_price && parseFloat(product.originalPriceInclTax) > 0 && !onlyImage"
      >
        {{ product.originalPriceInclTax | price }}
      </span>

      <span
        class="price-special lh30 cl-accent weight-700"
        v-if="product.special_price && parseFloat(product.special_price) > 0 && !onlyImage"
      >
        {{ product.priceInclTax | price }}
      </span>

      <span
        class="lh30 cl-secondary"
        v-if="!product.special_price && parseFloat(product.priceInclTax) > 0 && !onlyImage"
      >
        {{ product.priceInclTax | price }}
      </span>
    </router-link>
  </div>
</template>

<script>
import rootStore from '@vue-storefront/core/store'
import { ProductTile } from '@vue-storefront/core/modules/catalog/components/ProductTile.ts'

export default {
  mixins: [ProductTile],
  data () {
    return {
      imageLoaded: false
    }
  },
  props: {
    labelsActive: {
      type: Boolean,
      requred: false,
      default: true
    },
    onlyImage: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  methods: {
    onProductPriceUpdate (product) {
      if (product.sku === this.product.sku) {
        Object.assign(this.product, product)
      }
    },
    visibilityChanged (isVisible, entry) {
      if (isVisible) {
        if (rootStore.state.config.products.configurableChildrenStockPrefetchDynamic && rootStore.products.filterUnavailableVariants) {
          const skus = [this.product.sku]
          if (this.product.type_id === 'configurable' && this.product.configurable_children && this.product.configurable_children.length > 0) {
            for (const confChild of this.product.configurable_children) {
              const cachedItem = rootStore.state.stock.cache[confChild.id]
              if (typeof cachedItem === 'undefined' || cachedItem === null) {
                skus.push(confChild.sku)
              }
            }
            if (skus.length > 0) {
              rootStore.dispatch('stock/list', { skus: skus }) // store it in the cache
            }
          }
        }
      }
    }
  },
  beforeMount () {
    this.$bus.$on('product-after-priceupdate', this.onProductPriceUpdate)
  },
  beforeDestroy () {
    this.$bus.$off('product-after-priceupdate', this.onProductPriceUpdate)
  }
}
</script>

<style lang="scss" scoped>
@import '~theme/css/animations/transitions';
@import '~theme/css/variables/colors';
@import '~theme/css/helpers/functions/color';

$bg-secondary: color(secondary, $colors-background);
$border-secondary: color(secondary, $colors-border);
$color-white: color(white);

.product {
  @media (max-width: 767px) {
    padding-bottom: 10px;
  }
}

.price-original {
  text-decoration: line-through;
}

%label {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 40px;
  height: 40px;
  background-color: $border-secondary;
  text-transform: uppercase;
  color: $color-white;
  font-size: 12px;
}

.product-image {
  width: 100%;
  overflow: hidden;
  max-height: 300px;
  height: 100%;
  min-height: 155px;
  display: flex;
  align-items: flex-end;
  background-image: url('/assets/placeholder.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 60% auto;

  @media (min-width: 768px) {
    min-height: 190px;
  }
  @media (min-width: 1200px) {
    min-height: 300px;
  }

  &__content {
    display: none;
  }

  &--loaded {
    background-image: none;

    .product-image__content {
      display: block;
    }
  }

  &:hover {
    img {
      opacity: 1;
      transform: scale(1.1);
    }

    &.sale::after,
    &.new::after {
      opacity: 0.8;
    }
  }

  img {
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: auto;
    margin: auto;
    mix-blend-mode: darken;
    opacity: 0.8;
    transform: scale(1);
    transition: 0.3s opacity $motion-main, 0.3s transform $motion-main;

    &[lazy="loaded"] {
      animation: products-loaded;
      animation-duration: 0.3s;
    }

    @keyframes products-loaded {
      from {
        opacity: 0;
      }
      to {
        opacity: 0.8;
      }
    }
  }

  &.sale {
    &::after {
      @extend %label;
      content: 'Sale';
    }
  }

  &.new {
    &::after {
      @extend %label;
      content: 'New';
    }
  }
}
</style>

<template>
  <div
    class="product align-center w-100 pb20"
    v-observe-visibility="visibilityChanged"
  >
    <router-link
      class="block no-underline product-link"
      :to="localizedRoute({
        name: product.type_id + '-product',
        params: {
          parentSku: product.parentSku ? product.parentSku : product.sku,
          slug: product.slug,
          childSku: product.sku
        }
      })"
      data-testid="productLink"
    >
      <div
        class="product-image relative bg-cl-secondary"
        :class="[{ sale: labelsActive && isOnSale }, { new: labelsActive && isNew }, {'product-image--loaded': imageLoaded}]">
        <img
          class="product-image__content"
          :alt="product.name"
          :src="thumbnailObj.src"
          height="300"
          width="310"
          data-testid="productImage"
          @load="imageLoaded = true"
        >
      </div>

      <p class="mb0 cl-accent mt10" v-if="!onlyImage">
        {{ product.name | htmlDecode }}
      </p>

      <span
        class="price-original mr5 lh30 cl-secondary"
        v-if="product.special_price && parseFloat(product.originalPriceInclTax) > 0 && !onlyImage"
      >
        {{ product.originalPriceInclTax | price }}
      </span>

      <span
        class="price-special lh30 cl-accent weight-700"
        v-if="product.special_price && parseFloat(product.special_price) > 0 && !onlyImage"
      >
        {{ product.priceInclTax | price }}
      </span>

      <span
        class="lh30 cl-secondary"
        v-if="!product.special_price && parseFloat(product.priceInclTax) > 0 && !onlyImage"
      >
        {{ product.priceInclTax | price }}
      </span>
    </router-link>
  </div>
</template>

<script>
import rootStore from '@vue-storefront/core/store'
import { ProductTile } from '@vue-storefront/core/modules/catalog/components/ProductTile.ts'

export default {
  mixins: [ProductTile],
  data () {
    return {
      imageLoaded: false
    }
  },
  props: {
    labelsActive: {
      type: Boolean,
      requred: false,
      default: true
    },
    onlyImage: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  methods: {
    onProductPriceUpdate (product) {
      if (product.sku === this.product.sku) {
        Object.assign(this.product, product)
      }
    },
    visibilityChanged (isVisible, entry) {
      if (isVisible) {
        if (rootStore.state.config.products.configurableChildrenStockPrefetchDynamic && rootStore.products.filterUnavailableVariants) {
          const skus = [this.product.sku]
          if (this.product.type_id === 'configurable' && this.product.configurable_children && this.product.configurable_children.length > 0) {
            for (const confChild of this.product.configurable_children) {
              const cachedItem = rootStore.state.stock.cache[confChild.id]
              if (typeof cachedItem === 'undefined' || cachedItem === null) {
                skus.push(confChild.sku)
              }
            }
            if (skus.length > 0) {
              rootStore.dispatch('stock/list', { skus: skus }) // store it in the cache
            }
          }
        }
      }
    }
  },
  beforeMount () {
    this.$bus.$on('product-after-priceupdate', this.onProductPriceUpdate)
  },
  beforeDestroy () {
    this.$bus.$off('product-after-priceupdate', this.onProductPriceUpdate)
  }
}
</script>

<style lang="scss" scoped>
@import '~theme/css/animations/transitions';
@import '~theme/css/variables/colors';
@import '~theme/css/helpers/functions/color';

$bg-secondary: color(secondary, $colors-background);
$border-secondary: color(secondary, $colors-border);
$color-white: color(white);

.product {
  @media (max-width: 767px) {
    padding-bottom: 10px;
  }
}

.price-original {
  text-decoration: line-through;
}

%label {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 40px;
  height: 40px;
  background-color: $border-secondary;
  text-transform: uppercase;
  color: $color-white;
  font-size: 12px;
}

.product-image {
  width: 100%;
  overflow: hidden;
  max-height: 300px;
  height: 270px;
  display: flex;
  align-items: flex-end;
  background-image: url('/assets/placeholder.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 60% auto;

  &__content {
    display: none;
  }

  &--loaded {
    background-image: none;

    .product-image__content {
      display: block;
    }
  }

  &:hover {
    img {
      opacity: 1;
      transform: scale(1.1);
    }

    &.sale::after,
    &.new::after {
      opacity: 0.8;
    }
  }

  img {
    max-height: 100%;
    max-width: 100%;
    width: auto;
    height: auto;
    margin: auto;
    mix-blend-mode: darken;
    opacity: 0.8;
    transform: scale(1);
    transition: 0.3s opacity $motion-main, 0.3s transform $motion-main;

    &[lazy="loaded"] {
      animation: products-loaded;
      animation-duration: 0.3s;
    }

    @keyframes products-loaded {
      from {
        opacity: 0;
      }
      to {
        opacity: 0.8;
      }
    }
  }

  &.sale {
    &::after {
      @extend %label;
      content: 'Sale';
    }
  }

  &.new {
    &::after {
      @extend %label;
      content: 'New';
    }
  }
}
</style>


Organized code

Organized code

<template>

    <v-calendar
      v-model="value"
      class="ec-picasso"
      :events="events"
      :event-name="getActivityName | loading('Lädt…', ({ input }) => isActivityLoading(input))"
      :event-color="getActivityColor | loading('grey lighten-2', (entry) => isActivityLoading(entry))"
      :interval-height="intervalHeight"
      interval-width="46"
      :interval-format="intervalFormat"
      first-interval="5"
      interval-count="19"
      :start="start"
      :end="end"
      :locale="$i18n.locale"
      :day-format="dayFormat"
      :type="type"
      :weekday-format="weekdayFormat"
      :weekdays="[1, 2, 3, 4, 5, 6, 0]"
      color="primary"
      :event-ripple="false"
      @mousedown:event="entryMouseDown"
      @mouseup:event="entryMouseUp"
      @mousedown:time="timeMouseDown"
      @mousemove:time="timeMouseMove"
      @mouseup:time="timeMouseUp"
      @mouseleave.native="nativeMouseUp">
      <template #event="{event, eventParsed, timed}">
        <v-btn v-if="!event.tmpEvent" absolute
               top
               right x-small
               dark text
               class="ec-event--btn rounded-sm"
               @click.stop="showEntryInfoPopup(event)">
          <v-icon x-small>mdi-pencil</v-icon>
        </v-btn>

{{ getActivityName(event) }}

      </template>
    </v-calendar>
    <v-menu
      v-model="showEntryInfo"
      :activator="selectedElement"
      :open-on-click="false"
      :close-on-click="false"
      :close-on-content-click="false"
      offset-x>
      <v-card v-if="tempScheduleEntry">
        <v-card-text>
          <e-text-field v-model="tempScheduleEntry.name" no-label
                        class="font-weight-bold" placeholder="Aktivitätsname"
                        hide-details="auto" />
          <e-select v-model="tempScheduleEntry.type" label="Aktivitätstyp"
                    :items="activityCategories.items" item-value="id"
                    :return-object="true"
                    item-text="name">
            <template #item="{item, on, attrs}">
              <v-list-item :key="item.id" v-bind="attrs" v-on="on">
                <v-list-item-avatar>
                  <v-chip :color="item.color">{{ item.short }}</v-chip>
                </v-list-item-avatar>
                <v-list-item-content>
                  {{ item.name }}
                </v-list-item-content>
              </v-list-item>
            </template>
            <template #selection="{item}">

                  {{ item.name }}

                <v-chip x-small :color="item.color">{{ item.short }}</v-chip>

            </template>
          </e-select>
          <v-row no-gutters class="my-4">
            <e-time-picker label="Start"
                           :icon="null" class="flex-full"
                           :value="toTimeString(tempScheduleEntry.start)" />
            <e-time-picker width="100" label="Ende"
                           :icon="null" class="flex-full mt-0"
                           :value="toTimeString(tempScheduleEntry.end)" />
          </v-row>
          <e-select label="Verantwortliche Leitende" multiple
                    chips deletable-chips
                    :items="[{text:'Leitende1'},{text:'Leitende2'}]" />
        </v-card-text>
        <v-card-actions class="px-4 pb-4">
          <v-btn v-if="!tempScheduleEntry.tmpEvent"
                 color="primary" :to="scheduleEntryRoute(camp(), tempScheduleEntry)">
            Öffnen
          </v-btn>
          <v-btn text color="secondary"
                 class="ml-auto"
                 @click="cancelEntryInfoPopup()">
            Abbrechen
          </v-btn>
          <v-btn v-if="tempScheduleEntry.tmpEvent" color="success" @click="createActivity">Erstellen</v-btn>
          <v-btn v-else color="success" @click="saveScheduleEntry">Speichern</v-btn>
        </v-card-actions>
      </v-card>
    </v-menu>

</template>

<template>

    <v-calendar
      v-model="value"
      class="ec-picasso"
      :events="events"
      :event-name="getActivityName | loading('Lädt…', ({ input }) => isActivityLoading(input))"
      :event-color="getActivityColor | loading('grey lighten-2', (entry) => isActivityLoading(entry))"
      :interval-height="intervalHeight"
      interval-width="46"
      :interval-format="intervalFormat"
      first-interval="5"
      interval-count="19"
      :start="start"
      :end="end"
      :locale="$i18n.locale"
      :day-format="dayFormat"
      :type="type"
      :weekday-format="weekdayFormat"
      :weekdays="[1, 2, 3, 4, 5, 6, 0]"
      color="primary"
      :event-ripple="false"
      @change="getEvents"
      @mousedown:event="entryMouseDown"
      @mouseup:event="entryMouseUp"
      @mousedown:time="timeMouseDown"
      @mousemove:time="timeMouseMove"
      @mouseup:time="timeMouseUp"
      @mouseleave.native="nativeMouseUp">
      <template #event="{event, eventParsed, timed}">
        <v-btn v-if="!event.tmpEvent" absolute
               top
               right x-small
               dark text
               class="ec-event--btn rounded-sm"
               @click.stop="showEntryInfoPopup(event)">
          <v-icon x-small>mdi-pencil</v-icon>
        </v-btn>

{{ getActivityName(event) }}

      </template>
    </v-calendar>
    <v-menu
      v-model="showEntryInfo"
      :activator="selectedElement"
      :open-on-click="false"
      :close-on-click="false"
      :close-on-content-click="false"
      offset-x>
      <v-card v-if="tempScheduleEntry">
        <v-card-text>
          <e-text-field v-model="tempScheduleEntry.name" no-label
                        class="font-weight-bold" placeholder="Aktivitätsname"
                        hide-details="auto" />
          <e-select v-model="tempScheduleEntry.type" label="Aktivitätstyp"
                    :items="activityCategories.items" item-value="id"
                    :return-object="true"
                    item-text="name">
            <template #item="{item, on, attrs}">
              <v-list-item :key="item.id" v-bind="attrs" v-on="on">
                <v-list-item-avatar>
                  <v-chip :color="item.color">{{ item.short }}</v-chip>
                </v-list-item-avatar>
                <v-list-item-content>
                  {{ item.name }}
                </v-list-item-content>
              </v-list-item>
            </template>
            <template #selection="{item}">

                  {{ item.name }}

                <v-chip x-small :color="item.color">{{ item.short }}</v-chip>

            </template>
          </e-select>
          <v-row no-gutters class="my-4">
            <e-time-picker label="Start"
                           :icon="null" class="flex-full"
                           :value="toTimeString(tempScheduleEntry.start)" />
            <e-time-picker width="100" label="Ende"
                           :icon="null" class="flex-full mt-0"
                           :value="toTimeString(tempScheduleEntry.end)" />
          </v-row>
          <e-select label="Verantwortliche Leitende" multiple
                    chips deletable-chips
                    :items="[{text:'Leitende1'},{text:'Leitende2'}]" />
        </v-card-text>
        <v-card-actions class="px-4 pb-4">
          <v-btn v-if="!tempScheduleEntry.tmpEvent"
                 color="primary" :to="scheduleEntryRoute(camp(), tempScheduleEntry)">
            Öffnen
          </v-btn>
          <v-btn text color="secondary"
                 class="ml-auto"
                 @click="cancelEntryInfoPopup()">
            Abbrechen
          </v-btn>
          <v-btn v-if="tempScheduleEntry.tmpEvent" color="success" @click="createActivity">Erstellen</v-btn>
          <v-btn v-else color="success" @click="saveScheduleEntry">Speichern</v-btn>
        </v-card-actions>
      </v-card>
    </v-menu>

</template>


Display which team buzzed in text form.

Display which team buzzed in text form.

<template>

{{ openQuestion.clue }}

            <button type="button" id="buzzer" @click="buzz" @keyup="buzz">Buzzer</button>

(or press the any key)

Team {{ buzzedTeamId }} buzzed in!

{{ answer }}

</template>

<template>

{{ openQuestion.clue }}

            <button type="button" id="buzzer" @click="buzz" @keyup="buzz">Buzzer</button>

(or press the any key)

{{ answer }}

</template>


discard changes should reset undo/redo. (You could never undo discard changes which is why it has a confirm prompt. Previously we just had buggy behavior where it looked like you could undo it, and then more stuff broke.)

<template>

        <AposLogoPadless class="apos-admin-bar__logo" />

            <AposButton
              type="subtle" label="Page Tree"
              icon="file-tree-icon" class="apos-admin-bar__btn"
              :modifiers="['no-motion']"
              @click="emitEvent('@apostrophecms/page:manager')"
            />

            <AposButton
              v-if="item.options" type="subtle"
              @click="emitEvent(item.action)"
              :label="item.label"
              :modifiers="['no-motion']"
              class="apos-admin-bar__btn"
            />
            <AposContextMenu
              v-else-if="item.items" class="apos-admin-bar__sub"
              :menu="item.items" :button="{
                label: item.label,
                modifiers: ['no-motion'],
                class: 'apos-admin-bar__btn',
                type: 'subtle'
              }"
              @item-clicked="emitEvent"
            />

 0">
            <AposContextMenu
              class="apos-admin-bar__create"
              :menu="createMenu"
              :button="{
                label: 'New item',
                iconOnly: true,
                icon: 'plus-icon',
                type: 'primary',
                modifiers: ['round', 'no-motion']
              }"
              @item-clicked="emitEvent"
            />

        <TheAposAdminBarUser class="apos-admin-bar__user" />

        <transition-group
          tag="div"
          class="apos-admin-bar__control-set apos-admin-bar__control-set--context-controls"
          name="flip"
        >

            <AposButton
              :disabled="patchesSinceLoaded.length === 0"
              type="subtle" :modifiers="['small', 'no-motion']"
              label="Undo" class="apos-admin-bar__context-button"
              icon="undo-icon" :icon-only="true"
              @click="undo"
            />

            <AposButton
              :disabled="undone.length === 0"
              type="subtle" :modifiers="['small', 'no-motion']"
              label="Redo" class="apos-admin-bar__context-button"
              icon="redo-icon" :icon-only="true"
              @click="redo"
            />

              <component
                :is="savingIndicator.el"
                v-bind="savingIndicator.options"
                class="apos-admin-bar__status__icon"
              />

                {{ savingLabel }}

        </transition-group>
        <transition-group
          tag="div"
          class="apos-admin-bar__control-set apos-admin-bar__control-set--title"
          name="flip"
        >

            <AposIndicator
              icon="information-outline-icon"
              fill-color="var(--a-primary)"
              :tooltip="docTooltip"
              class="apos-admin-bar__title__indicator"
            />

              {{ context.title }}

              —

            <AposContextMenu
              class="apos-admin-bar__title__document"
              :button="draftButton"
              :menu="draftMenu"
              :disabled="contextStack.length > 0"
              @item-clicked="switchDraftMode"
              menu-offset="13, 10"
              menu-placement="bottom-end"
            />

        </transition-group>
        <transition-group
          tag="div"
          class="apos-admin-bar__control-set apos-admin-bar__control-set--mode-and-settings"
          name="flip"
        >

            <AposButton
              class="apos-admin-bar__context-button"
              label="Edit" type="subtle"
              :modifiers="['small', 'no-motion']"
              :tooltip="{
                content: 'Toggle Edit Mode',
                placement: 'bottom'
              }"
              @click="switchEditMode(true)"
              :disabled="contextStack.length > 0"
            />

            <AposButton
              v-for="item in trayItems"
              :key="item.name"
              type="subtle" :modifiers="['small', 'no-motion']"
              :tooltip="trayItemTooltip(item)" class="apos-admin-bar__context-button"
              :icon="item.options.icon" :icon-only="true"
              :label="item.label"
              :state="trayItemState[item.name] ? [ 'active' ] : []"
              @click="emitEvent(item.action)"
            />
            <AposButton
              v-if="context._id"
              class="apos-admin-bar__context-button"
              label="Page Settings" :tooltip="{
                content: 'Page Settings',
                placement: 'bottom'
              }"
              type="subtle" :modifiers="['small', 'no-motion']"
              icon="cog-icon" :icon-only="true"
              @click="emitEvent({
                itemName: contextEditorName,
                props: {
                  docId: context._id
                }
              })"
              :disabled="contextStack.length > 0"
            />

            <AposDocMoreMenu
              :doc-id="context._id"
              :disabled="!context.modified"
              :is-modified="context.modified"
              :can-discard-draft="context.modified"
              :is-modified-from-published="context.modified"
              :is-published="!!context.lastPublishedAt"
              :options="{ saveDraft: false }"
              @discardDraft="onDiscardDraft"
            />
            <AposButton
              class="apos-admin-bar__context-button"
              label="Preview" :tooltip="{
                content: 'Toggle Preview Mode',
                placement: 'bottom'
              }"
              type="subtle" :modifiers="['small', 'no-motion']"
              @click="switchEditMode(false)"
              :disabled="contextStack.length > 0"
            />
            <AposButton
              v-if="editMode"
              type="primary" :label="publishLabel"
              :disabled="!readyToPublish"
              class="apos-admin-bar__btn apos-admin-bar__context-button"
              @click="onPublish"
              :modifiers="['no-motion']"
            />

        </transition-group>

</template>


#322 增加域导出功能

#322 增加域导出功能

<template>

            <FilterPageList :data="namespaceList" :total="total" :order-by="orderBy" :filters="filters">
                <template slot-scope="scope">
                    <el-form :inline="true" class="table-filter">
                        <el-form-item label="">
                            <el-select v-model="filters.zkClusterKey" @change="scope.search">
                                <el-option label="全部ZK集群" value=""></el-option>
                                <el-option v-for="item in zkClusterKeys" :label="item.zkAlias" :value="item.zkClusterKey" :key="item.zkClusterKey"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="">
                            <el-input placeholder="搜索" v-model="filters.namespace" @keyup.enter.native="scope.search"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" icon="el-icon-search" @click="scope.search">查询</el-button>
                            <el-button type="primary" icon="el-icon-plus" @click="handleAdd()">添加域</el-button>

                        </el-form-item>
                    </el-form>

域信息
                                <el-button type="text" @click="getAllNamespace"></el-button>

                                <el-button @click="batchMigrate()">批量迁移</el-button>
                                <el-button @click="handleExport()">导出</el-button>

                        <el-table stripe border ref="multipleTable" @selection-change="handleSelectionChange" @sort-change="scope.onSortChange" :data="scope.pageData" style="width: 100%">
                            <el-table-column type="selection" width="55"></el-table-column>
                            <el-table-column prop="namespace" label="域名" min-width="110px" sortable>
                                <template slot-scope="scope">
                                    <router-link tag="a" :to="{ name: 'job_overview', params: { domain: scope.row.namespace } }">
                                        <el-button type="text">
                                            {{scope.row.namespace}}
                                        </el-button>
                                    </router-link>
                                </template>
                            </el-table-column>
                            <el-table-column prop="name" label="描述"></el-table-column>
                            <el-table-column prop="degree" label="重要等级" sortable>
                                <template slot-scope="scope">
                                    {{$map.degreeMap[scope.row.degree]}}
                                </template>
                            </el-table-column>
                            <el-table-column prop="version" label="Executor版本" sortable></el-table-column>
                            <el-table-column prop="zkAlias" label="ZK集群名称" sortable>
                                <template slot-scope="scope">
                                    <el-tooltip placement="top">

{{scope.row.zkAddressList}}

                                        {{scope.row.zkAlias}}
                                    </el-tooltip>
                                </template>
                            </el-table-column>
                        </el-table>

                </template>
            </FilterPageList>

                <namespace-info-dialog :namespace-info="namespaceInfo" :zk-cluster-keys="zkClusterKeys" @close-dialog="closeInfoDialog" @namespace-info-success="namespaceInfoSuccess"></namespace-info-dialog>

                <batch-migrate-dialog :batch-migrate-info="batchMigrateInfo" :zk-cluster-keys="zkClusterKeys" @batch-migrate-complete="batchMigrateComplete" @close-dialog="closeMigrateDialog"></batch-migrate-dialog>

                <migrate-status-dialog :migrate-status-title="migrateStatusTitle" @close-dialog="closeMigrateStatusDialog"></migrate-status-dialog>

</template>

<template>

            <FilterPageList :data="namespaceList" :total="total" :order-by="orderBy" :filters="filters">
                <template slot-scope="scope">
                    <el-form :inline="true" class="table-filter">
                        <el-form-item label="">
                            <el-select v-model="filters.zkClusterKey" @change="scope.search">
                                <el-option label="全部ZK集群" value=""></el-option>
                                <el-option v-for="item in zkClusterKeys" :label="item.zkAlias" :value="item.zkClusterKey" :key="item.zkClusterKey"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="">
                            <el-input placeholder="搜索" v-model="filters.namespace" @keyup.enter.native="scope.search"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" icon="el-icon-search" @click="scope.search">查询</el-button>
                            <el-button type="primary" icon="el-icon-plus" @click="handleAdd()">添加域</el-button>

                        </el-form-item>
                    </el-form>

域信息
                                <el-button type="text" @click="getAllNamespace"></el-button>

                                <el-button @click="batchMigrate()">批量迁移</el-button>

                        <el-table stripe border ref="multipleTable" @selection-change="handleSelectionChange" @sort-change="scope.onSortChange" :data="scope.pageData" style="width: 100%">
                            <el-table-column type="selection" width="55"></el-table-column>
                            <el-table-column prop="namespace" label="域名" min-width="110px" sortable>
                                <template slot-scope="scope">
                                    <router-link tag="a" :to="{ name: 'job_overview', params: { domain: scope.row.namespace } }">
                                        <el-button type="text">
                                            {{scope.row.namespace}}
                                        </el-button>
                                    </router-link>
                                </template>
                            </el-table-column>
                            <el-table-column prop="name" label="描述"></el-table-column>
                            <el-table-column prop="degree" label="重要等级" sortable>
                                <template slot-scope="scope">
                                    {{$map.degreeMap[scope.row.degree]}}
                                </template>
                            </el-table-column>
                            <el-table-column prop="version" label="Executor版本" sortable></el-table-column>
                            <el-table-column prop="zkAlias" label="ZK集群名称" sortable>
                                <template slot-scope="scope">
                                    <el-tooltip placement="top">

{{scope.row.zkAddressList}}

                                        {{scope.row.zkAlias}}
                                    </el-tooltip>
                                </template>
                            </el-table-column>
                        </el-table>

                </template>
            </FilterPageList>

                <namespace-info-dialog :namespace-info="namespaceInfo" :zk-cluster-keys="zkClusterKeys" @close-dialog="closeInfoDialog" @namespace-info-success="namespaceInfoSuccess"></namespace-info-dialog>

                <batch-migrate-dialog :batch-migrate-info="batchMigrateInfo" :zk-cluster-keys="zkClusterKeys" @batch-migrate-complete="batchMigrateComplete" @close-dialog="closeMigrateDialog"></batch-migrate-dialog>

                <migrate-status-dialog :migrate-status-title="migrateStatusTitle" @close-dialog="closeMigrateStatusDialog"></migrate-status-dialog>

</template>


feat(docs): TOC add scroll into iview support

<template>
     0" aria-label="Page table of contents">

          <template v-for="h2 in toc">
             0" vertical class="mb-1">

          </template>

</template>


remove back button

remove back button

<template>

    <Card>

{{ article.title }}

        <time>{{ article.date }}</time>

    </Card>

</template>

<template>

    <Card>

        <AppButton @click="back()" icon="back" :light="false">Back</AppButton>

{{ article.title }}

        <time>{{ article.date }}</time>

    </Card>

</template>


Fix marker

Fix marker

<template>

{{ place.city }}

{{ place.longitude }}, {{ place.latitude }}

            <v-map :zoom="zoom"
                :minZoom="minZoom"
                :maxZoom="maxZoom"
                :center="[place.longitude, place.latitude]">
                <v-tilelayer :url="url"
                    :attribution="attribution"></v-tilelayer>
                <v-marker :lat-lng="[place.longitude, place.latitude]"></v-marker>
            </v-map>

</template>

<template>

{{ place.city }}

{{ place.longitude }}, {{ place.latitude }}

            <v-map :zoom="zoom"
                :minZoom="minZoom"
                :maxZoom="maxZoom"
                :center="[place.longitude, place.latitude]">
                <v-tilelayer :url="url"
                    :attribution="attribution"></v-tilelayer>
                <v-marker :lat-lng="{ lng: place.longitude, lat: place.latitude }"></v-marker>
            </v-map>

</template>


CA-289

<template>

            Username

            Role title

            Organization Name

            <router-link to="/">

                back
            </router-link>

            Competencies & Frameworks

                <router-link to="/">
                    Frameworks
                </router-link>

                 New Framework

                <router-link to="/crosswalk">
                    Crosswalk Frameworks
                </router-link>

                <router-link to="/import">
                    Import
                </router-link>

            Activity

            Configuration

                <router-link to="/config">
                    Configurations
                </router-link>

                <router-link to="/usergroup">
                    Users/Groups
                </router-link>

                Import Options

                Supported File Type

                        PDF

                    HTML

                    DOCX

                Supported Framework Formats

                        Competency Model Clearinghouse

                        Kentucky Community and Technical College System

                        ACT.org

                        National Commission for the Certification of Crane Operators

                        Department of Labor: Employment and Training Administration

                        CBOF

</template>

<template>

            Username

            Role title

            Organization Name

            Competencies & Frameworks

                <router-link to="/">
                    Frameworks
                </router-link>

                 New Framework

                <router-link to="/crosswalk">
                    Crosswalk Frameworks
                </router-link>

                <router-link to="/import">
                    Import
                </router-link>

            Activity

            Configuration

                <router-link to="/config">
                    Configurations
                </router-link>

                <router-link to="/usergroup">
                    Users/Groups
                </router-link>

</template>


Remove stylus style

Remove stylus style

<template>
  <transition>
    <svg class="spinner" :class="{ show: show }" v-show="show" width="44px" height="44px" viewBox="0 0 44 44">
      <circle class="path" fill="none" stroke-width="4" stroke-linecap="round" cx="22" cy="22" r="20"></circle>
    </svg>
  </transition>
</template>

<script>
export default {
  name: 'spinner',
  props: ['show'],
  serverCacheKey: props => props.show
}
</script>

<style lang="stylus">
$offset = 126
$duration = 1.4s

.spinner
  transition opacity .15s ease
  animation rotator $duration linear infinite
  animation-play-state paused
  &.show
    animation-play-state running
  &.v-enter, &.v-leave-active
    opacity 0
  &.v-enter-active, &.v-leave
    opacity 1

@keyframes rotator
  0%
    transform scale(0.5) rotate(0deg)
  100%
    transform scale(0.5) rotate(270deg)

.spinner .path
  stroke #ff6600
  stroke-dasharray $offset
  stroke-dashoffset 0
  transform-origin center
  animation dash $duration ease-in-out infinite

@keyframes dash
  0%
    stroke-dashoffset $offset
  50%
    stroke-dashoffset ($offset/2)
    transform rotate(135deg)
  100%
    stroke-dashoffset $offset
    transform rotate(450deg)
</style>


docs(DefaultSystemBar): update link.

docs(DefaultSystemBar): update link.


dynamic add - work in progress

dynamic add - work in progress

<template>

select

        The select option is used to identify the select element that will be used to
        create slim select. You can any value you normally would in a querySelector
        or pass the element directly.

      new SlimSelect({
        select: '.element .you #want',
        // or
        select: document.querySelector('.element .you #want')
      })

placeholder

        Placeholders consists of setting the placeholder option value.
        The only difference is single selects require an empty option with data-placeholder set to true.
        Default value is "Select Value".

        <select id="placeholderSingle">
          <option data-placeholder="true"></option>
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>
        <select id="placeholderMultiple" multiple>
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '#placeholder',
        placeholder: 'Placeholder Text Here'
      })

      <!-- Single Selects require emtpy data-placeholder option -->
      <select id="placeholderSingle">
        <option data-placeholder="true"></option>
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

        Slim select has the ability to dynamically add options

        <select id="select-dynamic-add">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '.element .you #want',
      })

css / class

        Slim select will inherit any styles and classes that were added to the original select element.

        <select id="select-class" class="select-class">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      <select id="select-class" class="classItems">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

innerHTML

        Slim select has the ability to set custom html in content in the select option.

        Due to html spec we cant do this directly on the select dropdown, but we can pass them as data values to slim select

        <select id="select-innerHTML"></select>

      <select id="select-innerHTML"></select>

      var select = new SlimSelect({
        select: '#select-innerHTML',
        data: [
          {innerHTML: '<img height="30" width="30" src="http://lorempixel.com/30/30" /> Image', text: 'Image', value: 'image'},
          {innerHTML: '<i>Bold Text</i>', text: 'Bold Text', value: 'bold text'},
          {innerHTML: '<div style="border: solid 1px #666666;">Border</div>', text: 'Border', value: 'border'},
          {innerHTML: '<i>Slim Select you are awesome</i>', text: 'Slim Select awesome'}
        ]
      })

showSearch / searchText

        showSearch is a boolean value that will decide whether or not to show the search.
        Default is true.

        searchText is a string value that will show in the event there are no results.
        Default is 'No Results'.

        <select id="showSearch">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>
        <select id="searchText">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '#search',
        showSearch: false,
        searchText: 'Sorry nothing to see here'
      })

closeOnSelect

        closeOnSelect is a boolean value in which determines whether or not to
        close the content area upon selecting a value.

        <select id="closeOnSelectSingle">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>
        <select id="closeOnSelectMultiple" multiple>
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '#search',
        closeOnSelect: false
      })

showContent

        showContent is a string value that will decide where to show your content when it comes out.
        By default slim select will try to put the content where it can without going off screen.
        But you may want to always show it in one direction.

        Possible Options: 'auto', 'up' or 'down'. Default is 'auto'

        <select id="showContentUp">
          <option value="up1">Up 1</option>
          <option value="up2">Up 2</option>
          <option value="up3">Up 3</option>
        </select>
        <select id="showContentDown">
          <option value="down1">Down 1</option>
          <option value="down2">Down 2</option>
          <option value="down3">Down 3</option>
        </select>

      new SlimSelect({
        select: '#showContent',
        showContent: 'auto' // 'auto', 'up' or 'down'
      })

beforeOnChange

        beforeOnChange will trigger a callback on an option click and will allow
        you the ability to halt if the value it produces isnt to your liking.
        In order to stop propagation just return false on the callback.
        Returning nothing or true will allow it to continue as normal.

Before on change: {{beforeOnChangeSingle}}

      <select id="beforeOnChangeSingle">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

Before on change: {{beforeOnChangeMultiple}}

      <select id="beforeOnChangeMultiple" multiple>
        <option value="value1" selected>Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

      new SlimSelect({
        select: '#beforeOnChange',
        beforeOnChange: (info) => {
          console.log(info)
          return false // this will stop propagation
        }
      })

onChange

        onChange will trigger a callback after the value of the select dropdown has changed.

On change: {{onChangeSingle}}

      <select id="onChangeSingle">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

On change: {{onChangeMultiple}}

      <select id="onChangeMultiple" multiple>
        <option value="value1" selected>Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

      new SlimSelect({
        select: '#onChange',
        onChange: (info) => {
          console.log(info)
        }
      })

</template>

<template>

select

        The select option is used to identify the select element that will be used to
        create slim select. You can any value you normally would in a querySelector
        or pass the element directly.

      new SlimSelect({
        select: '.element .you #want',
        // or
        select: document.querySelector('.element .you #want')
      })

placeholder

        Placeholders consists of setting the placeholder option value.
        The only difference is single selects require an empty option with data-placeholder set to true.
        Default value is "Select Value".

        <select id="placeholderSingle">
          <option data-placeholder="true"></option>
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>
        <select id="placeholderMultiple" multiple>
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '#placeholder',
        placeholder: 'Placeholder Text Here'
      })

      <!-- Single Selects require emtpy data-placeholder option -->
      <select id="placeholderSingle">
        <option data-placeholder="true"></option>
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

css / class

        Slim select will inherit any styles and classes that were added to the original select element.

        <select id="select-class" class="select-class">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      <select id="select-class" class="classItems">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

innerHTML

        Slim select has the ability to set custom html in content in the select option.

        Due to html spec we cant do this directly on the select dropdown, but we can pass them as data values to slim select

        <select id="select-innerHTML"></select>

      <select id="select-innerHTML"></select>

      var select = new SlimSelect({
        select: '#select-innerHTML',
        data: [
          {innerHTML: '<img height="30" width="30" src="http://lorempixel.com/30/30" /> Image', text: 'Image', value: 'image'},
          {innerHTML: '<i>Bold Text</i>', text: 'Bold Text', value: 'bold text'},
          {innerHTML: '<div style="border: solid 1px #666666;">Border</div>', text: 'Border', value: 'border'},
          {innerHTML: '<i>Slim Select you are awesome</i>', text: 'Slim Select awesome'}
        ]
      })

showSearch / searchText

        showSearch is a boolean value that will decide whether or not to show the search.
        Default is true.

        searchText is a string value that will show in the event there are no results.
        Default is 'No Results'.

        <select id="showSearch">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>
        <select id="searchText">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '#search',
        showSearch: false,
        searchText: 'Sorry nothing to see here'
      })

closeOnSelect

        closeOnSelect is a boolean value in which determines whether or not to
        close the content area upon selecting a value.

        <select id="closeOnSelectSingle">
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>
        <select id="closeOnSelectMultiple" multiple>
          <option value="value1">Value 1</option>
          <option value="value2">Value 2</option>
          <option value="value3">Value 3</option>
        </select>

      new SlimSelect({
        select: '#search',
        closeOnSelect: false
      })

showContent

        showContent is a string value that will decide where to show your content when it comes out.
        By default slim select will try to put the content where it can without going off screen.
        But you may want to always show it in one direction.

        Possible Options: 'auto', 'up' or 'down'. Default is 'auto'

        <select id="showContentUp">
          <option value="up1">Up 1</option>
          <option value="up2">Up 2</option>
          <option value="up3">Up 3</option>
        </select>
        <select id="showContentDown">
          <option value="down1">Down 1</option>
          <option value="down2">Down 2</option>
          <option value="down3">Down 3</option>
        </select>

      new SlimSelect({
        select: '#showContent',
        showContent: 'auto' // 'auto', 'up' or 'down'
      })

beforeOnChange

        beforeOnChange will trigger a callback on an option click and will allow
        you the ability to halt if the value it produces isnt to your liking.
        In order to stop propagation just return false on the callback.
        Returning nothing or true will allow it to continue as normal.

Before on change: {{beforeOnChangeSingle}}

      <select id="beforeOnChangeSingle">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

Before on change: {{beforeOnChangeMultiple}}

      <select id="beforeOnChangeMultiple" multiple>
        <option value="value1" selected>Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

      new SlimSelect({
        select: '#beforeOnChange',
        beforeOnChange: (info) => {
          console.log(info)
          return false // this will stop propagation
        }
      })

onChange

        onChange will trigger a callback after the value of the select dropdown has changed.

On change: {{onChangeSingle}}

      <select id="onChangeSingle">
        <option value="value1">Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

On change: {{onChangeMultiple}}

      <select id="onChangeMultiple" multiple>
        <option value="value1" selected>Value 1</option>
        <option value="value2">Value 2</option>
        <option value="value3">Value 3</option>
      </select>

      new SlimSelect({
        select: '#onChange',
        onChange: (info) => {
          console.log(info)
        }
      })

</template>


truncate avatar initials in vue component. refs #464

<template>

          <span v-if="entity.initials.length <= 4">
            {{ entity.initials }}

            {{ entity.initials.substr(0, 1) }}...

</template>

<template>

            {{ entity.initials }}

</template>


Update App.desktop.vue

Update App.desktop.vue

<template>

    <help-index
      v-if="isHelpVisible"
      :io="io"
      @helpMounted="setIo">
    </help-index>

        Product paradise

          {{ t('app.mixin.home') }}
          {{ t('app.mixin.register') }}
          {{ t('app.mixin.login') }}
          {{ t('app.mixin.shop') }}
          Logout

          {{ t('app.mixin.help') }}

            {{ t('app.mixin.basket') }} ({{ basket.products.length }})

          {{ t('app.mixin.products') }}

            English
            Deutsch

      <router-view class="mt-4"></router-view>

        This shop is not real and only for demonstration purposes

</template>


Added search reset functionality (task #8668)

<template>

                <form class="search-form" novalidate="novalidate" v-on:submit.prevent="search">

                                <select v-model="filter" class="form-control input-sm" v-on:change="criteriaCreate()">
                                    <option value="">-- Add filter --</option>
                                    <template v-for="(group_filters, group) in filtersGroup">
                                        <optgroup :label="group">
                                            <option v-for="filter in group_filters" :value="filter.field">{{ filter.label }}</option>
                                        </optgroup>
                                    </template>
                                </select>

                                <select v-model="aggregator" class="form-control input-sm">
                                    <option v-for="aggregator in aggregators" :value="aggregator.value">{{ aggregator.text }}</option>
                                </select>

                            <fieldset>
                                <template v-for="(fields, field_name) in criteria">

{{ filtersFlat[field_name].label }}

                                                <select v-model="operator[guid]" class="form-control input-sm" v-on:change="operatorUpdated(field_name, guid, operator[guid])">
                                                    <option v-for="option in $store.state.search.operators.types[$store.state.search.operators.map[filtersFlat[field_name].type]]" v-bind:value="option.value">
                                                        {{ option.text }}
                                                    </option>
                                                </select>

                                                <component :is="field.type + 'Input'" :guid="guid" :field="field_name" :key="guid + field.value" :value="field.value" :options="filtersFlat[field_name].options" :source="filtersFlat[field_name].source" :display-field="filtersFlat[field_name].display_field" :multiple="true" @input-value-updated="criteriaUpdated" />

                                                    <button type="button" @click="criteriaRemove(guid)" class="btn btn-default btn-xs"></button>

                                </template>
                            </fieldset>

                                        Available Columns
                                        <select v-model="selectedColumns.available" class="form-control input-sm" multiple size="8">
                                            <option v-for="filter in filtersList" v-if="-1 === displayColumns.indexOf(filter.field)" :value="filter.field">
                                                {{ filter.label }}
                                                <template v-if="filter.group !== modelName">({{ filter.group }})</template>
                                            </option>
                                        </select>

                                        <button type="button" @click="displayColumnsUpdated('add')" class="btn btn-block btn-xs">

                                        </button>
                                        <button type="button" @click="displayColumnsUpdated('remove')" class="btn btn-block btn-xs">

                                        </button>

                                        Display Columns
                                        <select v-model="selectedColumns.display" class="form-control input-sm" multiple size="8">
                                            <option v-for="column in displayColumns" :value="filtersFlat[column].field">
                                                {{ filtersFlat[column].label }}
                                                <template v-if="filtersFlat[column].group !== modelName">({{ filtersFlat[column].group }})</template>
                                            </option>
                                        </select>

                                                <button type="button" @click="displayColumnsSorted('up')" :disabled="0 === displayColumns.length" class="btn btn-block btn-xs">

                                                </button>

                                                <button type="button" @click="displayColumnsSorted('down')" :disabled="0 === displayColumns.length" class="btn btn-block btn-xs">

                                                </button>

                                                Group By
                                                <select v-model="groupBy" class="form-control input-sm">
                                                    <option value="">-- Please choose --</option>
                                                    <option v-for="filter in filtersList" :value="filter.field" v-if="filter.group === modelName">{{ filter.label }}</option>
                                                </select>

                            <button class="btn btn-primary btn-sm" type="submit"> Search</button>
                            <button type="button" @click="searchReset()" class="btn btn-default btn-sm"> Reset</button>

                                Saved Searches

                                    <select v-model="savedSearchSelected" class="form-control input-sm">
                                        <option value="">-- Please choose --</option>
                                        <option v-for="savedSearch in savedSearches" :value="savedSearch.id">{{ savedSearch.name }}</option>
                                    </select>

                                        <button type="button" @click="savedSearchGet()" :disabled="'' === savedSearchSelected" class="btn btn-default btn-sm">

                                        </button>
                                        <button type="button" @click="savedSearchCopy()" :disabled="'' === savedSearchSelected" class="btn btn-default btn-sm">

                                        </button>
                                        <button type="button" @click="savedSearchDelete()" :disabled="'' === savedSearchSelected || savedSearchSelected === $store.state.search.savedSearch.id" class="btn btn-danger btn-sm">

                                        </button>

                                Save Search

                                        <input type="text" v-model="name" class="form-control input-sm" placeholder="Saved search name" required="required">

                                        <button type="button" @click="savedSearchCreate()" class="btn btn-sm btn-primary"></button>

                </form>

{{ modelName }}

</template>

<template>

                <form class="search-form" novalidate="novalidate" v-on:submit.prevent="search">

                                <select v-model="filter" class="form-control input-sm" v-on:change="criteriaCreate()">
                                    <option value="">-- Add filter --</option>
                                    <template v-for="(group_filters, group) in filtersGroup">
                                        <optgroup :label="group">
                                            <option v-for="filter in group_filters" :value="filter.field">{{ filter.label }}</option>
                                        </optgroup>
                                    </template>
                                </select>

                                <select v-model="aggregator" class="form-control input-sm">
                                    <option v-for="aggregator in aggregators" :value="aggregator.value">{{ aggregator.text }}</option>
                                </select>

                            <fieldset>
                                <template v-for="(fields, field_name) in criteria">

{{ filtersFlat[field_name].label }}

                                                <select v-model="operator[guid]" class="form-control input-sm" v-on:change="operatorUpdated(field_name, guid, operator[guid])">
                                                    <option v-for="option in $store.state.search.operators.types[$store.state.search.operators.map[filtersFlat[field_name].type]]" v-bind:value="option.value">
                                                        {{ option.text }}
                                                    </option>
                                                </select>

                                                <component :is="field.type + 'Input'" :guid="guid" :field="field_name" :key="guid + field.value" :value="field.value" :options="filtersFlat[field_name].options" :source="filtersFlat[field_name].source" :display-field="filtersFlat[field_name].display_field" :multiple="true" @input-value-updated="criteriaUpdated" />

                                                    <button type="button" @click="criteriaRemove(guid)" class="btn btn-default btn-xs"></button>

                                </template>
                            </fieldset>

                                        Available Columns
                                        <select v-model="selectedColumns.available" class="form-control input-sm" multiple size="8">
                                            <option v-for="filter in filtersList" v-if="-1 === displayColumns.indexOf(filter.field)" :value="filter.field">
                                                {{ filter.label }}
                                                <template v-if="filter.group !== modelName">({{ filter.group }})</template>
                                            </option>
                                        </select>

                                        <button type="button" @click="displayColumnsUpdated('add')" class="btn btn-block btn-xs">

                                        </button>
                                        <button type="button" @click="displayColumnsUpdated('remove')" class="btn btn-block btn-xs">

                                        </button>

                                        Display Columns
                                        <select v-model="selectedColumns.display" class="form-control input-sm" multiple size="8">
                                            <option v-for="column in displayColumns" :value="filtersFlat[column].field">
                                                {{ filtersFlat[column].label }}
                                                <template v-if="filtersFlat[column].group !== modelName">({{ filtersFlat[column].group }})</template>
                                            </option>
                                        </select>

                                                <button type="button" @click="displayColumnsSorted('up')" :disabled="0 === displayColumns.length" class="btn btn-block btn-xs">

                                                </button>

                                                <button type="button" @click="displayColumnsSorted('down')" :disabled="0 === displayColumns.length" class="btn btn-block btn-xs">

                                                </button>

                                                Group By
                                                <select v-model="groupBy" class="form-control input-sm">
                                                    <option value="">-- Please choose --</option>
                                                    <option v-for="filter in filtersList" :value="filter.field" v-if="filter.group === modelName">{{ filter.label }}</option>
                                                </select>

                            <button class="btn btn-primary btn-sm" type="submit"> Search</button>

                                Saved Searches

                                    <select v-model="savedSearchSelected" class="form-control input-sm">
                                        <option value="">-- Please choose --</option>
                                        <option v-for="savedSearch in savedSearches" :value="savedSearch.id">{{ savedSearch.name }}</option>
                                    </select>

                                        <button type="button" @click="savedSearchGet()" :disabled="'' === savedSearchSelected" class="btn btn-default btn-sm">

                                        </button>
                                        <button type="button" @click="savedSearchCopy()" :disabled="'' === savedSearchSelected" class="btn btn-default btn-sm">

                                        </button>
                                        <button type="button" @click="savedSearchDelete()" :disabled="'' === savedSearchSelected || savedSearchSelected === $store.state.search.savedSearch.id" class="btn btn-danger btn-sm">

                                        </button>

                                Save Search

                                        <input type="text" v-model="name" class="form-control input-sm" placeholder="Saved search name" required="required">

                                        <button type="button" @click="savedSearchCreate()" class="btn btn-sm btn-primary"></button>

                </form>

{{ modelName }}

</template>


Remove additional class dark-mode

Remove additional class dark-mode

<template>

    <league-signup-modal
        v-if="leagueSignupModalOpen"
        @close="leagueSignupModalOpen = false"
        @submit="submitRegistration"
        :first-name="firstName"
        :last-name="lastName"
        :name="name"
        :email="email"
        :birthday="birthday"
        :emails="emails"
        :unsubscribed-from-marketing-emails="unsubscribedFromMarketingEmails"
    >
    </league-signup-modal>

    <clan-creation-modal
        v-if="clanCreationModal"
        :clan="myCreatedClan"
        @close="clanCreationModal = false"
    >
    </clan-creation-modal>

        <clan-selector v-if="!isLoading && Array.isArray(myClans) && myClans.length > 0" :clans="myClans" @change="e => changeClanSelected(e)" :selected="clanIdSelected || clanIdOrSlug" style="margin-bottom: 40px;"/>

Competitive coding has never been so epic

The CodeCombat AI League is uniquely both a competitive AI battle simulator and game engine for learning real Python and JavaScript code.

      Join Now

{{ currentSelectedClanName }}

{{ currentSelectedClanDescription }}

Invite players to this clan by sending them this link:

        <input readonly :value="clanInviteLink()" />

        Join Now
        Edit Clan
        Leave Clan
        Join Clan

{{ currentSelectedClanName }} stats

Global stats

Use your coding skills and battle strategies to rise up the ranks!

      <leaderboard v-if="currentSelectedClan" :rankings="selectedClanRankings" :key="`${clanIdSelected}-score`" style="color: black;" />
      <leaderboard v-else :rankings="globalRankings" style="color: black;" />
      <leaderboard :rankings="selectedClanCodePointsRankings" :key="`${clanIdSelected}-codepoints`" scoreType="codePoints" style="color: black;" />

      Play Blazing Battle Multiplayer Arena

Free to get started

Access competitive multiplayer arenas, leaderboard, and global coding championships

Earn points for completing practice levels and competing in head-to-head matches

Join competitive coding clans with friends, family, or classmates

Showcase your coding skills and take home great prizes

        Join Now

Global final arena

          Put all the skills you’ve learned to the test! Compete against students and players from across the world in this exciting culmination to the season.

        Join Now

How it works

Join a clan

Complete the training levels and compete in the Season Arena

Compete in the culminating Global Final Arena and push your coding skills to the test

Season arenas

Infinite Inferno Cup

Jan - April 2021

Sorcerer's Blitz

May - Aug 2021

Colossus Clash

Sep - Dec 2021

          For both Season and Championship arenas, each player programs their team of “AI Heroes” with code written in Python, JavaScript, C++, Lua, or CoffeeScript.

          Their code informs the strategies their AI Heroes will execute in a head-to-head battle against other competitors.

      Join Now

Are you an educator or esports coach?

The CodeCombat AI League combines our project-based standards-aligned curriculum, engaging adventure-based coding game, and our annual AI coding global tournament into an organized academic competition unlike any other.

                Unlike other eSports platforms serving schools, we own the structure top to bottom, which means we’re not tied to any game developer or have issues with licensing. That also means we can make custom modifications in-game for your school or organization.

                The game platform fits into a regular Computer Science curriculum, so as students play through the game levels, they’re completing course work. Students learn coding and computer science while they play, then use these skills in arena battles as they practice and play on the same platform.

                Our tournament structure is adaptable to any environment or use case. Students can participate at a designated time during regular learning, play at home asynchronously, or participate on their own schedule.

      Edit Clan
      Start a Clan
      Join Now

Features

Built-in Competitive Infrastructure

Our platform hosts every element of the competitive process, from leaderboards to the game platform, assets, and tournament awards.

Custom Development

Customization elements for your school or organization are included, plus options like branded landing pages and in-game characters.

Comprehensive Curriculum

CodeCombat is a standards-aligned CS solution that helps educators teach real coding in JavaScript and Python, no matter their experience.

Roster Management Tools

Track student performance within the curriculum and within the game, and easily add or remove students.

Bring competitive coding to your school

Share our AI League flyer with educators, administrators, parents, eSports coaches or others that may be interested.

        Download Flyer

</template>


:cyclone: v-for key

:cyclone: v-for key

<template lang="pug">
.screen
  .entries
    .entry(v-for="e in catalog" :key="e.eid")
      entry(:obj="e")
</template>

<script>
import { mapGetters } from 'vuex';
import Entry from '@/components/Entry';

export default {
  components: {
    Entry,
  },
  computed: {
    ...mapGetters({
      catalog: 'catalog',
    }),
  },
};
</script>

<template lang="pug">
.screen
  .entries
    .entry(v-for="e in catalog")
      entry(:obj="e")
</template>

<script>
import { mapGetters } from 'vuex';
import Entry from '@/components/Entry';

export default {
  components: {
    Entry,
  },
  computed: {
    ...mapGetters({
      catalog: 'catalog',
    }),
  },
};
</script>


Table: Change debounce invoke atBegin.

Table: Change debounce invoke atBegin.


Update Customization.vue (#2903)

Update Customization.vue (#2903)

There's been changes in bulma. If you change variable ($primary in this case) you have to provide its light and dark variants. Also, there's new option to add custom colours via $custom-colors variable that is passed as argument to mergeColorMaps function. More info in this: https://bulma.io/2019/10/15/light-dark-colors/#4-value-color-map

<template>

1

Install Buefy via npm

                <CodeView code="npm install buefy" lang="bash" expanded/>

Or clone the repository: https://github.com/buefy/buefy

2

Set your variables with Sass

Tip: You can see all of Bulma's variables.

There's also two other variables created by Buefy:

$speed-slow: 150ms !default

$speed-slower: 250ms !default

                    <CodeView :code="sass | pre" lang="sass" expanded/>

3

Import and use Buefy

                    Please note that import 'buefy/dist/buefy.css' from the <router-link to="/documentation/start">start section</router-link> has been omitted.

                <CodeView :code="importing | pre" lang="javascript" expanded/>

</template>


Fix NaN

Fix NaN


Removed unused console log.

Removed unused console log.

<template>

{{$t('pages:settings.security.changePasswordTitle')}}

        <v-form v-model="valid" ref="formChangePassword" class="new-password-container">
            <v-text-field type="password" v-model="oldPassword"
                          :label="$t('pages:settings.security.oldPassword')"
                          :rules="[ruleFieldRequired($t('validation:fieldRequired'))]"
                          :counter="55">
            </v-text-field>
            <v-text-field type="password" v-model="newPassword"
                          :label="$t('common:password')"
                          :rules="[ruleMinLength($t('validation:minLength', {length: 8}), 8),
                               rulePasswordChars($t('validation:noPasswordChars')),
                               ruleToManyChars($t('validation:toManyChars'), 55)]"
                          :counter="55">
            </v-text-field>
            <v-text-field type="password" v-model="newPasswordConfirm"
                          :label="$t('common:passwordConfirm')"
                          :rules="[ruleFieldRequired($t('validation:fieldRequired')),
                               rulePasswordEquals($t('validation:passwordNoEqual'), newPassword),
                               ruleToManyChars($t('validation:toManyChars'), 55)]"
                          :counter="55">
            </v-text-field>

                {{$t('pages:settings.security.changedPasswordSuccessfully')}}

            <v-btn color="primary" class="change-password-button" :disabled="!valid || loading" :loading="loading"
                   @click="changePassword()">
                {{$t('pages:settings.security.changePasswordButton')}}
            </v-btn>
        </v-form>

</template>


fixed period for offer component 👽

fixed period for offer component 👽

<template>

{{plan.name}}

{{plan.time}}

{{plan.description[0]}}

{{plan.description[1]}}

{{plan.description[2]}}

          {{ plan.price }}€ / {{plan.period}}

</template>

<template>

{{plan.name}}

{{plan.time}}

{{plan.description[0]}}

{{plan.description[1]}}

{{plan.description[2]}}

          {{ plan.price }}€ / week

</template>


feat(design): make small buttons a bit bigger


Update multiple-languages.vue

Update multiple-languages.vue

<template>
  <f7-page>

    <f7-navbar :title="text.title" :back-link="text.backlink" sliding></f7-navbar>

    <f7-list inset>
      <f7-list-item smart-select smart-select-back-on-select
        :title="text.selectLang"
        :media="''">
        <select @change="updateLanguageText" v-model="$root.language">
          <option value="en" :data-option-image="images.flag_en">{{text.en}}</option>
          <option value="de" :data-option-image="images.flag_de">{{text.de}}</option>
        </select>
      </f7-list-item>
    </f7-list>

    <f7-block inner inset>
{{text.text}}
</f7-block>

    <f7-block inset>
      <f7-button :text="text.openPage" href="simple-page"></f7-button>
    </f7-block>

    <f7-block inset>
      <f7-button @click="modal()">Modal</f7-button></f7-col>
    </f7-block>

    <f7-block inner inset style="text-align: center">

Standard text patterns will change their language as well - currently English and German are supported - Please request other in our <f7-link href="https://github.com/scriptPilot/app-framework/issues" external>GitHub Issue List</f7-link>.

    </f7-block>

  </f7-page>
</template>


Update _footer.vue

Update _footer.vue

<template>

Navigasi

Home

Masuk

Daftar

Tim PKM Mikroskil 2015

Dennis Daslim – 131112641

Adeline Rosabella – 131110381

Javentira Lienata – 131110950

Michael – 131111718

Nipe Setiawan Harefa – 131110011

PencariLoker.com

PencariLoker.com adalah sebuah website dirancang untuk membantu masyarakat menemukan lowongan pekerjaan yang sesuai dengan kemampuannya dan juga membantu perusahaan dalam mensortir calon karyawan.

Copyright © 2015 PencariLoker.com

</template>


Allowed banner in side-nav to be empty

Allowed banner in side-nav to be empty


Exclude current directory from copy/move options


fix the images from doing a houdini on imagelist


Fixed leaderboard stats link to get around mixing error

<template>

LEADERBOARD STATISTICS

{{metric.players}}

Players

{{metric.organizations}}

Organizations

{{metric.countries}}

Countries

{{classes.professional}}

Professional

{{classes.university}}

University Students

{{classes.high_school}}

High School Students

                More Stats

    <Leaderboard v-if="leaderboard" :lbFromContainer="leaderboard" :hackathonId="hackathonId" :baseUrl="baseUrl"></Leaderboard>

</template>


Change ImportKeystore.vue Add keystore check.

<template>

Import Keystore Wallet App

        <message v-bind:message="msg" v-bind:error="error" v-on:update:msg="val => msg = val"></message>

            Password

              <input id="pass" class="input" type="text" v-model="password" placeholder="Password" v-on:change.prevent.self="checkPassword" v-if="type === 'text'" v-bind:class="{'is-danger': ((score < 3 && password) || error), 'is-success': (score >= 3 && password)}">
              <input id="pass" class="input" type="password" v-model="password" placeholder="Password" v-on:change.prevent.self="checkPassword" v-if="type === 'password'" v-bind:class="{'is-danger': ((score < 3 && password) || error), 'is-success': (score >= 3 && password)}">
              <p class="help is-danger password-help" v-if="score < 3 && password">Weak Password

= 3 && password">Strong Password

            <button class="button is-info password-button" v-on:click.prevent.self="switchType">{{ buttonText }}</button>

            Keystore JSON(Choose file)

              <input id="file-seed" class="input" type="file" v-on:change="readKeystoreJsonFile" placeholder="Keystore JSON" v-bind:class="{'is-danger': (!isKeystoreJsonValid && keystoreJson), 'is-success': isKeystoreJsonValid}">

Keystore JSON isn't valid

Keystore JSON is valid

        <button class="button is-primary file-button" v-on:click.prevent.self="importWallet">Import Wallet</button>

Address

{{ address }}

</template>


Stripped out v-bind, using data binding shortcuts

<template>

      {{index.name}} ({{collectionCount(index)}})

           {{collection}}

          {{collection}}

</template>


Fix reference value

Fix reference value

<template>

=> {{value['@id']}}

</template>