typos smh.

typos smh.

<template>

  <div>
    <div v-el:videowrapper class="videowrapper">
      <video v-el:video class="video-js vjs-default-skin" >
        <template v-for="video in videoSources">
          <source :src="video.storage_url" :type='"video/" + video.extension'>
        </template>
        <template v-for="track in trackSources">
          <track kind="captions" :src="track.storage_url" :srclang="track.lang" :label="getLangName(track.lang)">
        </template>
      </video>
    </div>
  </div>

</template>

<script>

  const videojs = require('video.js');
  const langcodes = require('./langcodes.json');
  require('./videojs-centerbtns');

  module.exports = {

    props: ['files'],

    computed: {
      posterSource() {
        const posterFileExtensions = ['png', 'jpg'];
        return this.files.filter(
          (file) => posterFileExtensions.some((ext) => ext === file.extension)
        )[0].storage_url;
      },

      videoSources() {
        const videoFileExtensions = ['mp4', 'webm', 'ogg'];
        return this.files.filter(
          (file) => videoFileExtensions.some((ext) => ext === file.extension)
        );
      },

      trackSources() {
        const trackFileExtensions = ['vtt'];
        return this.files.filter(
          (file) => trackFileExtensions.some((ext) => ext === file.extension)
        );
      },
    },

    methods: {
      getLangName(langCode) {
        return langcodes.filter(
            (lang) => lang.code === langCode
        )[0].lang;
      },

      setPlayState(state) {
        if (state === true) {
          this.videoPlayer.$('.videotoggle').classList.add('videopaused');
          this.videoPlayer.$('.videoreplay').classList.add('display');
          this.videoPlayer.$('.videoforward').classList.add('display');
        } else {
          this.videoPlayer.$('.videotoggle').classList.remove('videopaused');
          this.videoPlayer.$('.videoreplay').classList.remove('display');
          this.videoPlayer.$('.videoforward').classList.remove('display');
        }
      },
    },

    ready() {
      this.videoPlayer = videojs(this.$els.video, {
        controls: true,
        autoplay: false,
        fluid: true,
        preload: 'auto',
        poster: this.posterSource,
        playbackRates: [0.25, 0.5, 1.0, 1.25, 1.5, 2.0],
        textTrackDisplay: true,
        ReplayButton: true,
        ForwardButton: true,
        TogglePlayButton: true,
        bigPlayButton: false,
        controlBar: {
          children: [
            { name: 'currentTimeDisplay' },
            { name: 'timeDivider' },
            { name: 'progressControl' },
            { name: 'durationDisplay' },
            { name: 'remainingTimeDisplay' },
            { name: 'muteToggle' },
            { name: 'VolumeBar' },
            { name: 'playbackRateMenuButton' },
            { name: 'captionsButton' },
            { name: 'fullscreenToggle' },
          ],
        },
      },

      () => {
        const centerButtons = this.$els.videowrapper.childNodes[1];
        const toggleButton = centerButtons
          .getElementsByClassName('videotoggle')[0];
        const replayButton = centerButtons
          .getElementsByClassName('videoreplay')[0];
        const forwardButton = centerButtons
          .getElementsByClassName('videoforward')[0];

        videojs(this.$els.video).on('useractive', () => {
          toggleButton.classList.remove('userInactive');
          replayButton.classList.remove('userInactive');
          forwardButton.classList.remove('userInactive');
        });

        videojs(this.$els.video).on('userinactive', () => {
          toggleButton.classList.add('userInactive');
          replayButton.classList.add('userInactive');
          forwardButton.classList.add('userInactive');
        });

        videojs(this.$els.video).on('play', () => {
          this.setPlayState(true);
        });

        videojs(this.$els.video).on('pause', () => {
          this.setPlayState(false);
        });

        videojs(this.$els.video).on('ended', () => {
          this.setPlayState(false);
        });
      });
    },
  };

</script>

<style lang="stylus">

  // Default videojs stylesheet
  // Unable to reference the videojs using require since videojs doesn't have good webpack support
  @import '../../../../../../node_modules/video.js/dist/video-js.css'

  // Videojs skin customization
  .video-js
    font-size: 1em
    color: #fff
    .vjs-slider
      background-color: #545454
      background-color: rgba(84, 84, 84, 0.5)

    .vjs-load-progress
      background: ligthen(#545454, 25%)
      background: rgba(84, 84, 84, 0.5)

      div
        background: ligthen(#545454, 50%)
        background: rgba(84, 84, 84, 0.75)

  .video-js .vjs-control-bar,
  .video-js .vjs-big-play-button,
  .video-js .vjs-menu-button .vjs-menu-content
    background-color: #000
    background-color: rgba(0, 0, 0, 0.7)

   // Custom style
  .videowrapper
    position: relative

  .video-js .vjs-menu
    font-family: 'NotoSans', 'sans-serif'

  .video-js .vjs-current-time
    display: block

  .video-js .vjs-play-progress
    background-color: #996189

  .video-js .userInactive
    visibility: visible
    opacity: 0
    transition: visibility 1s, opacity 1s

  .video-js .videoreplay,
  .video-js .videoforward,
  .video-js .videotoggle
    background-repeat: no-repeat
    background-size: contain
    cursor: pointer
    position: absolute
    top: 50%
    transform: translate(-50%, -50%)

  .video-js .videoreplay,
  .video-js .videoforward
    display: none
    height: 10vw
    width: 10vw
    max-height: 133px
    max-width: 133px

  .video-js .videoreplay
    background: url('../icons/ic_replay_10_white.svg')
    background-repeat: no-repeat
    background-size: contain
    left: 35%

  .video-js .videoforward
    background: url('../icons/ic_forward_10_white.svg')
    background-repeat: no-repeat
    background-size: contain
    left: 65%

  .video-js .videotoggle
    background: url('../icons/ic_play_circle_outline_white.svg')
    background-repeat: no-repeat
    background-size: contain
    left: 50%
    height: 15vw
    width: 15vw
    max-height: 200px
    max-width: 200px

  .video-js .videopaused
    background: url('../icons/ic_pause_circle_outline_white.svg')
    background-repeat: no-repeat
    background-size: contain

  .video-js .display,
  .video-js .display
    display: block

</style>

<template>

  <div>
    <div v-el:videowrapper class="videowrapper">
      <video v-el:video class="video-js vjs-default-skin" >
        <template v-for="video in videoSources">
          <source :src="video.storage_url" :type='"video/" + video.extension'>
        </template>
        <template v-for="track in trackSources">
          <track kind="captions" :src="track.storage_url" :srclang="track.lang" :label="getLangName(track.lang)">
        </template>
      </video>
    </div>
  </div>

</template>

<script>

  const videojs = require('video.js');
  const langcodes = require('./langcodes.json');
  require('./videojs-centerbtns');

  module.exports = {

    props: ['files'],

    computed: {
      posterSource() {
        const posterFileExtensions = ['png', 'jpg'];
        return this.files.filter(
          (file) => posterFileExtensions.some((ext) => ext === file.extension)
        )[0].storage_url;
      },

      videoSources() {
        const videoFileExtensions = ['mp4', 'webm', 'ogg'];
        return this.files.filter(
          (file) => videoFileExtensions.some((ext) => ext === file.extension)
        );
      },

      trackSources() {
        const trackFileExtensions = ['vtt'];
        return this.files.filter(
          (file) => trackFileExtensions.some((ext) => ext === file.extension)
        );
      },
    },

    methods: {
      getLangName(langCode) {
        return langcodes.filter(
            (lang) => lang.code === langCode
        )[0].lang;
      },

      setPlayState(state) {
        if (state === true) {
          this.videoPlayer.$('.videotoggle').classList.add('videopaused');
          this.videoPlayer.$('.videoreplay').classList.add('display');
          this.videoPlayer.$('.videoforward').classList.add('display');
        } else {
          this.videoPlayer.$('.videotoggle').classList.remove('videopaused');
          this.videoPlayer.$('.videoreplay').classList.remove('display');
          this.videoPlayer.$('.videoforward').classList.remove('display');
        }
      },
    },

    ready() {
      this.videoPlayer = videojs(this.$els.video, {
        controls: true,
        autoplay: false,
        fluid: true,
        preload: 'auto',
        poster: this.posterSource,
        playbackRates: [0.25, 0.5, 1.0, 1.25, 1.5, 2.0],
        textTrackDisplay: true,
        ReplayButton: true,
        ForwardButton: true,
        TogglePlayButton: true,
        bigPlayButton: false,
        controlBar: {
          children: [
            { name: 'currentTimeDisplay' },
            { name: 'timeDivider' },
            { name: 'progressControl' },
            { name: 'durationDisplay' },
            { name: 'remainingTimeDisplay' },
            { name: 'muteToggle' },
            { name: 'VolumeBar' },
            { name: 'playbackRateMenuButton' },
            { name: 'captionsButton' },
            { name: 'fullscreenToggle' },
          ],
        },
      },

      () => {
        const centerButtons = this.$els.videowrapper.childNodes[1];
        const toggleButton = centerButtons
          .getElementsByClassName('videotoggle')[0];
        const replayButton = centerButtons
          .getElementsByClassName('videoreplay')[0];
        const forwardButton = centerButtons
          .getElementsByClassName('videoforward')[0];

        videojs(this.$els.video).on('useractive', () => {
          toggleButton.classList.remove('userInactive');
          replayButton.classList.remove('userInactive');
          forwardButton.classList.remove('userInactive');
        });

        videojs(this.$els.video).on('userinactive', () => {
          toggleButton.classList.add('userInactive');
          replayButton.classList.add('userInactive');
          forwardButton.classList.add('userInactive');
        });

        videojs(this.$els.video).on('play', () => {
          this.setPlayState(true);
        });

        videojs(this.$els.video).on('pause', () => {
          this.setPlayState(false);
        });

        videojs(this.$els.video).on('ended', () => {
          this.setPlayState(false);
        });
      });
    },
  };

</script>

<style lang="stylus">

  // Default videojs stylesheet
  // Unable to refrence the videojs using require since videojs dosen't have good webpack support
  @import '../../../../../../node_modules/video.js/dist/video-js.css'

  // Videojs skin customization
  .video-js
    font-size: 1em
    color: #fff
    .vjs-slider
      background-color: #545454
      background-color: rgba(84, 84, 84, 0.5)

    .vjs-load-progress
      background: ligthen(#545454, 25%)
      background: rgba(84, 84, 84, 0.5)

      div
        background: ligthen(#545454, 50%)
        background: rgba(84, 84, 84, 0.75)

  .video-js .vjs-control-bar,
  .video-js .vjs-big-play-button,
  .video-js .vjs-menu-button .vjs-menu-content
    background-color: #000
    background-color: rgba(0, 0, 0, 0.7)

   // Custom style
  .videowrapper
    position: relative

  .video-js .vjs-menu
    font-family: 'NotoSans', 'sans-serif'

  .video-js .vjs-current-time
    display: block

  .video-js .vjs-play-progress
    background-color: #996189

  .video-js .userInactive
    visibility: visible
    opacity: 0
    transition: visibility 1s, opacity 1s

  .video-js .videoreplay,
  .video-js .videoforward,
  .video-js .videotoggle
    background-repeat: no-repeat
    background-size: contain
    cursor: pointer
    position: absolute
    top: 50%
    transform: translate(-50%, -50%)

  .video-js .videoreplay,
  .video-js .videoforward
    display: none
    height: 10vw
    width: 10vw
    max-height: 133px
    max-width: 133px

  .video-js .videoreplay
    background: url('../icons/ic_replay_10_white.svg')
    background-repeat: no-repeat
    background-size: contain
    left: 35%

  .video-js .videoforward
    background: url('../icons/ic_forward_10_white.svg')
    background-repeat: no-repeat
    background-size: contain
    left: 65%

  .video-js .videotoggle
    background: url('../icons/ic_play_circle_outline_white.svg')
    background-repeat: no-repeat
    background-size: contain
    left: 50%
    height: 15vw
    width: 15vw
    max-height: 200px
    max-width: 200px

  .video-js .videopaused
    background: url('../icons/ic_pause_circle_outline_white.svg')
    background-repeat: no-repeat
    background-size: contain

  .video-js .display,
  .video-js .display
    display: block

</style>


[fixed] broken background image

[fixed] broken background image

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mtlong29/JBShop_Site.git/'


Playing with quagga config

Playing with quagga config

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NathanielDavid/Sumie.git/'


Loggin!

Loggin!


add style fix and content template in component Recycle

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/notadd/administration.git/'


add check-answer message

add check-answer message

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/christianmemije/kolibri-exercise-perseus-plugin.git/'


Make loading line slowler

Make loading line slowler

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stefanjudis/stefan-judis-website.git/'


Fix 'hide' event detection error

Fix 'hide' event detection error

<template>

        <slot></slot>

                    <slot name="content"></slot>

</template>


Work on tooltip

Work on tooltip

<template>

                <slot name="text">{{text}}</slot>

        <slot></slot>

</template>

<template>

    <slot></slot>

            <slot name="content" v-if="!text"></slot>

</template>


add file input code example

add file input code example

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/praneetloke/vue-material.git/'


Add panel layout component

Add panel layout component

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/PayBreak/basket.git/'


add http post handler in component Debug


re-title page login, and some styles fix


docs(codepen): load mdi fonts

docs(codepen): load mdi fonts

Fixes #6134

<template lang="pug">
  form(
    method="POST"
    action="https://codepen.io/pen/define/"
    target="_blank"
    ref="form"
  )
    input(
      type="hidden"
      name="data"
      :value="value"
    )
</template>

<script>
  import { version } from 'vuetify'
  const title = 'Vuetify Example Pen'

  const cssResources = [
    'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons',
    `https://cdn.jsdelivr.net/npm/vuetify@${version}/dist/vuetify.min.css`,
    'https://cdn.materialdesignicons.com/2.5.94/css/materialdesignicons.min.css'
  ]

  const jsResources = [
    'https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js',
    'https://cdn.jsdelivr.net/npm/vue/dist/vue.js',
    `https://cdn.jsdelivr.net/npm/vuetify@${version}/dist/vuetify.min.js`
  ]

  export default {
    name: 'Codepen',

    props: {
      pen: {
        type: Object,
        default: () => ({})
      },
      title: {
        type: String,
        default: title
      }
    },

    computed: {
      additionalScript () {
        const additional = this.pen.codepenAdditional || ''

        return additional
          .replace(/(<codepen-additional.*?>|<\/codepen-additional>$)/g, '')
          .replace(/\n {2}/g, '\n')
          .trim() + (additional ? '\n\n' : '')
      },
      additionalResources () {
        const resources = this.pen.codepenResources || '{}'

        return Object.assign(
          { css: [], js: [] },
          JSON.parse(
            resources.replace(/(<codepen-resources.*?>|<\/codepen-resources>$)/g, '')
          )
        )
      },
      script () {
        const imports = /(import*) ([^'\n]*) from ([^\n]*)/g
        let component = /export default {([\s\S]*)}/g.exec(this.pen.script || '')

        component = ((component && component[1]) || '')
          .replace(/\n {2}/g, '\n')
          .trim()

        let script = /<script>([\s\S]*)export default {/g.exec(this.pen.script || '')

        script = ((script && script[1]) || '')
          .replace(imports, '')
          .replace(/\n {2}/g, '\n')
          .trim()

        script += script ? '\n\n' : ''

        return this.additionalScript + script +
          `new Vue({
  el: '#app',
  ${component}
})`
      },
      style () {
        return {
          content: (this.pen.style || '').replace(/(<style.*?>|<\/style>)/g, '').replace(/\n {2}/g, '\n').trim(),
          language: /<style.*lang=["'](.*)["'].*>/.exec(this.pen.style || '')
        }
      },
      template () {
        const template = this.pen.template || ''

        return template
          .replace(/(<template>|<\/template>$)/g, '')
          .replace(/\n/g, '\n  ')
          .trim()
      },
      editors () {
        const html = this.template && 0b100
        const css = this.style.content && 0b010
        const js = this.script && 0b001

        return (html | css | js).toString(2)
      },
      value () {
        const data = {
          title: this.title,
          html:
            `<div id="app">
  <v-app id="inspire">
    ${this.template}
  </v-app>
</div>`,
          css: this.style.content,
          css_pre_processor: this.style.language ? this.style.language[1] : 'none',
          css_external: [...this.additionalResources.css, ...cssResources].join(';'),
          js: this.script,
          js_pre_processor: 'babel',
          js_external: [...this.additionalResources.js, ...jsResources].join(';'),
          editors: this.editors
        }

        return JSON.stringify(data)
      }
    },

    methods: {
      submit () {
        this.$el.submit()
      }
    }
  }
</script>

<template lang="pug">
  form(
    method="POST"
    action="https://codepen.io/pen/define/"
    target="_blank"
    ref="form"
  )
    input(
      type="hidden"
      name="data"
      :value="value"
    )
</template>

<script>
  import { version } from 'vuetify'
  const title = 'Vuetify Example Pen'

  const cssResources = [
    'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons',
    `https://cdn.jsdelivr.net/npm/vuetify@${version}/dist/vuetify.min.css`
  ]

  const jsResources = [
    'https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js',
    'https://cdn.jsdelivr.net/npm/vue/dist/vue.js',
    `https://cdn.jsdelivr.net/npm/vuetify@${version}/dist/vuetify.min.js`
  ]

  export default {
    name: 'Codepen',

    props: {
      pen: {
        type: Object,
        default: () => ({})
      },
      title: {
        type: String,
        default: title
      }
    },

    computed: {
      additionalScript () {
        const additional = this.pen.codepenAdditional || ''

        return additional
          .replace(/(<codepen-additional.*?>|<\/codepen-additional>$)/g, '')
          .replace(/\n {2}/g, '\n')
          .trim() + (additional ? '\n\n' : '')
      },
      additionalResources () {
        const resources = this.pen.codepenResources || '{}'

        return Object.assign(
          { css: [], js: [] },
          JSON.parse(
            resources.replace(/(<codepen-resources.*?>|<\/codepen-resources>$)/g, '')
          )
        )
      },
      script () {
        const imports = /(import*) ([^'\n]*) from ([^\n]*)/g
        let component = /export default {([\s\S]*)}/g.exec(this.pen.script || '')

        component = ((component && component[1]) || '')
          .replace(/\n {2}/g, '\n')
          .trim()

        let script = /<script>([\s\S]*)export default {/g.exec(this.pen.script || '')

        script = ((script && script[1]) || '')
          .replace(imports, '')
          .replace(/\n {2}/g, '\n')
          .trim()

        script += script ? '\n\n' : ''

        return this.additionalScript + script +
          `new Vue({
  el: '#app',
  ${component}
})`
      },
      style () {
        return {
          content: (this.pen.style || '').replace(/(<style.*?>|<\/style>)/g, '').replace(/\n {2}/g, '\n').trim(),
          language: /<style.*lang=["'](.*)["'].*>/.exec(this.pen.style || '')
        }
      },
      template () {
        const template = this.pen.template || ''

        return template
          .replace(/(<template>|<\/template>$)/g, '')
          .replace(/\n/g, '\n  ')
          .trim()
      },
      editors () {
        const html = this.template && 0b100
        const css = this.style.content && 0b010
        const js = this.script && 0b001

        return (html | css | js).toString(2)
      },
      value () {
        const data = {
          title: this.title,
          html:
            `<div id="app">
  <v-app id="inspire">
    ${this.template}
  </v-app>
</div>`,
          css: this.style.content,
          css_pre_processor: this.style.language ? this.style.language[1] : 'none',
          css_external: [...this.additionalResources.css, ...cssResources].join(';'),
          js: this.script,
          js_pre_processor: 'babel',
          js_external: [...this.additionalResources.js, ...jsResources].join(';'),
          editors: this.editors
        }

        return JSON.stringify(data)
      }
    },

    methods: {
      submit () {
        this.$el.submit()
      }
    }
  }
</script>


Make columns line up

Make columns line up

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cdubz/timestrap.git/'


Remove comma

Remove comma


Imports signin

Imports signin


[rating-bar] clean test code on about

[rating-bar] clean test code on about

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jaceks-iRonin/vue-material-test.git/'


Style on svg

Style on svg

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/JosefFriedrich-nodejs/baldr.git/'


fix: rebuilding List.vue for cssgram

fix: rebuilding List.vue for cssgram

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/amatelus/swipevideo.git/'


Cap the zoom and pan to within default domain.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/wuruoyun/vue-d3-example.git/'


[fixed] Vuejs warning about transition css usage

HTML attributes are case-insensitive and camelCased props need to use their kebab-case equivalents when using in-DOM templates.
You should probably use "leave-class" instead of "leaveClass".
You should probably use "enter-to-class" instead of "enterToClass"

<template>
    <transition enter-to-class="show" leave-class="show" @after-enter="afterEnter" mode="out-in">
        <div role="tabpanel" class="tab-pane"
             :class="[{fade, disabled, active: localActive}]"
             v-if="localActive || !lazy" v-show="localActive || lazy"
        ref="panel"
   >
       <slot></slot>
        </div>
    </transition>
</template>

<script>
    export default {
        methods: {
            afterEnter(el) {
                el.classList.add('show');
            }
        },
        data() {
            return {
                fade: false,
                localActive: false,
                lazy: true
            };
        },
        props: {
            id: {
                type: String,
                default: ''
            },
            title: {
                type: String,
                default: ''
            },
            disabled: {
                type: Boolean,
                default: false
            },
            active: {
                type: Boolean,
                default: false
            },
            href: {
                type: String,
                default: '#'
            }
        }
    };

</script>

<template>
    <transition enterToClass="show" leaveClass="show" @after-enter="afterEnter" mode="out-in">
        <div role="tabpanel" class="tab-pane"
             :class="[{fade, disabled, active: localActive}]"
             v-if="localActive || !lazy" v-show="localActive || lazy"
        ref="panel"
   >
       <slot></slot>
        </div>
    </transition>
</template>

<script>
    export default {
        methods: {
            afterEnter(el) {
                el.classList.add('show');
            }
        },
        data() {
            return {
                fade: false,
                localActive: false,
                lazy: true
            };
        },
        props: {
            id: {
                type: String,
                default: ''
            },
            title: {
                type: String,
                default: ''
            },
            disabled: {
                type: Boolean,
                default: false
            },
            active: {
                type: Boolean,
                default: false
            },
            href: {
                type: String,
                default: '#'
            }
        }
    };

</script>


Close #7

Close #7


add component SelectizeZone

add component SelectizeZone

<template lang="html">

 0">

          <icon :iname="itemIcon" /> {{ item }}

          <icon :title="$t('delete')" iname="minus" />

        {{ $t('user.search') }}
        <icon :iname="searchIcon" v-if="searchIcon" />

          {{ choice }}

</template>

error: pathspec 'app/src/components/SelectizeZone.vue' did not match any file(s) known to git


Tab Component

Tab Component

<script>
  export default {
    props: {
      tabActive: Boolean,
      id: String,
    },
    data() {
      return {
        tabContent: null,
      };
    },
    render(c) {
      const self = this;

      return c(
        'div', {
          staticClass: 'tab',
          attrs: {
            id: self.id,
          },
          class: {
            active: self.tabActive,
          },
          on: {
            'tab:show': self.onTabShow,
            'tab:hide': self.onTabHide,
          },
        },
        [self.tabContent ? c(self.tabContent.component, { tag: 'component', props: self.tabContent.params, key: self.tabContent.id }) : self.$slots.default]
      );
    },
    methods: {
      show(animated) {
        if (!this.$f7) return;
        this.$f7.tab.show(this.$el, animated);
      },
      onTabShow(e) {
        this.$emit('tab:show', e);
      },
      onTabHide(e) {
        this.$emit('tab:hide', e);
      },
    },
  };
</script>

error: pathspec 'src/components/tab.vue' did not match any file(s) known to git


Avoid raising a JS error on doughnut tooltip

<template>
    <div class="chart" v-style="height: height" v-el="container">
        <canvas v-el="canvas" height="100%"></canvas>
    </div>
</template>

<script>
import Chart from 'chart.js';

export default {
    name: 'chartjs-doughnut',
    props: ['score'],
    watch: {
        'score': function() {
            this.build_chart();
        }
    },
    ready: function() {
        this.build_chart()
    },
    methods: {
        build_chart: function() {
            if (!this.score) {
                return;
            }
            let data = [
                {
                    value: this.score,
                    color:"#3C8DBC",
                },
                {
                    value: 10 - this.score,
                    color: "#F5F5F5",
                }
            ];
            let ctx = this.$$.canvas.getContext('2d');
            new Chart(ctx).Doughnut(data, {
                segmentShowStroke : false,
                showTooltips: false,
            });
        },
    }
};
</script>

<template>
    <div class="chart" v-style="height: height" v-el="container">
        <canvas v-el="canvas" height="100%"></canvas>
    </div>
</template>

<script>
import Chart from 'chart.js';

export default {
    name: 'chartjs-doughnut',
    props: ['score'],
    watch: {
        'score': function() {
            this.build_chart();
        }
    },
    ready: function() {
        this.build_chart()
    },
    methods: {
        build_chart: function() {
            if (!this.score) {
                return;
            }
            let data = [
                {
                    value: this.score,
                    color:"#3C8DBC",
                },
                {
                    value: 10 - this.score,
                    color: "#F5F5F5",
                }
            ];
            let ctx = this.$$.canvas.getContext('2d');
            new Chart(ctx).Doughnut(data, {
                segmentShowStroke : false,
                tooltipTemplate: "",
            });
        },
    }
};
</script>


Show count behind tags and disable tags with 0 count on Startpage (close #22)

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tum-rt/web-quiz.git/'


remove watcher

remove watcher

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/E-Bo/vueZoomer.git/'


pass text as prop

pass text as prop


添加Page6.vue

<template>
	<section>page6...
	</section>
</template>

error: pathspec 'src/components/nav3/Page6.vue' did not match any file(s) known to git


Simplify Tweet component

Simplify Tweet component

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mplusmuseum/mplusmuseum-stories.git/'


Fix on desktop

Fix on desktop

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/barprive/barprive.com.git/'


center podium images on mobile

center podium images on mobile


add validation forms

add validation forms

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lucaslimax/curriculo_gratis.git/'


feature | comboxtree.vue | 下拉树组件

feature | comboxtree.vue | 下拉树组件

功能同easyui>comboxtree，多了搜索功能

<template>

    <input type="text" v-model="nodelabel" @click='toggleShowTree'>

 <tree v-show=showTree ref='tree' :treeData='treeData' :options="options" @node-click='nodeclick' @handlecheckedChange='handlecheckedChange'></tree>

</template>

error: pathspec 'src/components/tree/combotree.vue' did not match any file(s) known to git


Removed test code

Removed test code

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/LokeCarlsson/lokecarlsson.git/'


Add red around input description if too long or too short

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Winbee/Cashcash.git/'


Fixed SVG positions

Fixed SVG positions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/moso/moso-vue.git/'


Added classes and pin action

Added classes and pin action

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/codeweavers/Consign.git/'


Rearranged sections

Rearranged sections

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NathanielDavid/Sumie.git/'


Version bump

Version bump


Rework results style

Rework results style


Default notifications remved froma rray

Default notifications remved froma rray

<template>
  <div class="notification">
  </div>
</template>

<script>
import EventBus from 'src/event-bus/event-bus'

export default {
  name: 'notification',
  data () {
    return {
      notifications: []
    }
  },
  created () {
    EventBus.$on('notification', data => {
      this.notifications.push(data)
    })
  },
  methods: {
    action (action, id) {
      switch (action) {
        case 'close':
          this.notifications.splice(id, 1)
      }
    }
  }
}
</script>

<template>
  <div class="notification">
  </div>
</template>

<script>
import EventBus from 'src/event-bus/event-bus'

export default {
  name: 'notification',
  data () {
    return {
      notifications: [
        {
          type: 'info',
          message: 'Product has been added to the cart!',
          action1: { label: 'OK', action: 'close' }
        },
        {
          type: 'info',
          message: 'Product has been added to the cart!',
          action1: { label: 'OK', action: 'close' }
        }
      ]
    }
  },
  created () {
    EventBus.$on('notification', data => {
      this.notifications.push(data)
    })
  },
  methods: {
    action (action, id) {
      switch (action) {
        case 'close':
          this.notifications.splice(id, 1)
      }
    }
  }
}
</script>


Adding raster layer component

Adding raster layer component

<template></template>

<script>
import bus from '../../messageBus';
import layerEvents from '../../lib/layerEvents';
import mixin from './layerMixin';

export default {
  mixins: [mixin],
  props: {
    url: {
      type: String,
      default: undefined
    },
    tiles: {
      type: Array,
      default: () => []
    },
    tilesMinZoom: {
      type: Number,
      default: undefined
    },
    tilesMaxZoom: {
      type: Number,
      default: undefined
    },
    tileSize: {
      type: Number,
      defaul: undefined
    }
  },

  mounted() {
    bus.$once('mgl-load', map => {
      this.map = map;
      let source = {
        type: 'raster',
        tilesMinZoom: this.tilesMinZoom,
        tilesMaxZoom: this.tilesMaxZoom,
        tileSize: this.tileSize,
        url: this.url,
        tiles: this.tiles
      }

      this.map.on('dataloading', this._watchSourceLoading);
      try {
        this.map.addSource(this.sourceId, source)
      } catch (err) {
        if (this.replaceSource) {
          this.map.removeSource(this.sourceId);
          this.map.addSource(this.sourceId, source)
        } else {
          this._emitMapEvent('mgl-layer-source-error', { sourceId: this.sourceId, error: err });
        }
      }
      this._addLayer();
      if (this.listenUserEvents) {
        this._bindEvents(layerEvents);
      }
      this.map.off('dataloading', this._watchSourceLoading);
      this.initial = false;
    });
  },

  methods: {
    _addLayer() {
      let existed = this.map.getLayer(this.layerId);
      if (existed) {
        if (this.replace) {
          this.map.removeLayer(this.layerId);
        } else {
          this._emitMapEvent('mgl-layer-exists', { layerId: this.layerId });
          return existed;
        }
      }
      let layer = {
        id: this.layerId,
        source: this.sourceId
      }
      if (this.refLayer) {
        layer.ref = this.refLayer;
      } else {
        layer.type = 'raster'
        layer.source = this.sourceId;
        layer['source-layer'] = this['source-layer']
        if (this.minzoom) layer.minzoom = this.minzoom
        if (this.maxzoom) layer.maxzoom = this.maxzoom
        if (this.layout) {
          layer.layout = this.layout;
        }
      }
      layer.paint = layer.paint = this.paint ? this.paint : { 'raster-opacity': 1 };
      layer.metadata = this.metadata

      this.map.addLayer(layer, this.before);
      this._emitMapEvent('mgl-layer-added', { layerId: this.layerId });
    }
  }
}
</script>

error: pathspec 'src/components/layer/RasterLayer.vue' did not match any file(s) known to git


scroll selected option into view

scroll selected option into view

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jaceks-iRonin/vue-material-test.git/'


Как мог бы выглядеть компонент на vue.js

<template>

А еще лучше слетать повидать новый город.

</template>

error: pathspec 'resources/assets/js/components/Aviasales.vue' did not match any file(s) known to git


Added hyperlink to new version update tag

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/04n0/goldfish.git/'


Small text change

Small text change

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/egoconf/egoconf.git/'


add lecture component

add lecture component

<template>

{{ lecture.title }}

{{ lecture.speaker }}

                {{ lecture.outline }}

{{ lecture.detail }}

</template>

error: pathspec 'src/components/Lecture.vue' did not match any file(s) known to git


correct form field binding using computed method for state's getter and setter in Setting, add http post handler

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/notadd/administration.git/'


update

update

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/iview/iview-doc.git/'


Use new filter option mixin

Use new filter option mixin

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/PayBreak/basket.git/'


add(notFound): 404组件

add(notFound): 404组件

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/maple5233/LetsChat.git/'


tags were enlarging the line unnecessarily

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/chrisamow/url-ingstad.git/'


TimePicker: fix picker-options

TimePicker: fix picker-options

<template>
  <span
    class="el-date-editor"
    v-clickoutside="handleClose"
    :class="{
      'is-have-trigger': haveTrigger,
      'is-active': pickerVisible,
      'is-filled': !!this.value
    }">

    <input
      class="el-date-editor__editor"
      :readonly="readonly"
      :type="editorType"
      :placeholder="placeholder"
      @focus="handleFocus"
      @blur="handleBlur"
      @keydown="handleKeydown"
      @keyup="handleKeyup"
      ref="reference"
      v-model.lazy="visualValue" />

    <span
      @click="togglePicker()"
      class="el-date-editor__trigger el-icon"
      :class="[triggerClass]"
      v-if="haveTrigger">
    </span>
  </span>
</template>

<script>
import Vue from 'vue';
import Clickoutside from 'main/utils/clickoutside';
import { merge, formatDate, parseDate, getWeekNumber } from './util';
import Popper from 'main/utils/popper';
import emitter from 'main/mixins/emitter';

const FUNCTION_KEYS = [13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40];
const RANGE_SEPARATOR = ' - ';
const DEFAULT_FORMATS = {
  date: 'yyyy-MM-dd',
  month: 'yyyy-MM',
  datetime: 'yyyy-MM-dd HH:mm:ss',
  time: 'HH:mm:ss',
  timerange: 'HH:mm:ss',
  daterange: 'yyyy-MM-dd',
  datetimerange: 'yyyy-MM-dd HH:mm:ss'
};
const HAVE_TRIGGER_TYPES = [
  'date',
  'datetime',
  'time',
  'time-select',
  'week',
  'month',
  'year',
  'daterange',
  'timerange',
  'datetimerange'
];
const DATE_FORMATTER = function(value, format) {
  return formatDate(value, format);
};
const DATE_PARSER = function(text, format) {
  text = text.split(':');
  if (text.length > 1) text = text.map(item => item.slice(-2));
  text = text.join(':');

  return parseDate(text, format);
};
const RANGE_FORMATTER = function(value, format) {
  if (Array.isArray(value) && value.length === 2) {
    const start = value[0];
    const end = value[1];

    if (start && end) {
      return formatDate(start, format) + RANGE_SEPARATOR + formatDate(end, format);
    }
  }
  return '';
};
const RANGE_PARSER = function(text, format) {
  const array = text.split(RANGE_SEPARATOR);
  if (array.length === 2) {
    const range1 = array[0].split(':').map(item => item.slice(-2)).join(':');
    const range2 = array[1].split(':').map(item => item.slice(-2)).join(':');
    return [parseDate(range1, format), parseDate(range2, format)];
  }
  return [];
};
const TYPE_VALUE_RESOLVER_MAP = {
  default: {
    formatter(value) {
      if (!value) return '';
      return '' + value;
    },
    parser(text) {
      if (text === undefined || text === '') return null;
      return text;
    }
  },
  week: {
    formatter(value) {
      if (value instanceof Date) {
        const weekNumber = getWeekNumber(value);
        return value.getFullYear() + 'w' + (weekNumber > 9 ? weekNumber : '0' + weekNumber);
      }
      return value;
    },
    parser(text) {
      const array = (text || '').split('w');
      if (array.length === 2) {
        const year = Number(array[0]);
        const month = Number(array[1]);

        if (!isNaN(year) && !isNaN(month) && month < 54) {
          return text;
        }
      }
      return null;
    }
  },
  date: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  datetime: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  daterange: {
    formatter: RANGE_FORMATTER,
    parser: RANGE_PARSER
  },
  datetimerange: {
    formatter: RANGE_FORMATTER,
    parser: RANGE_PARSER
  },
  timerange: {
    formatter: RANGE_FORMATTER,
    parser: RANGE_PARSER
  },
  time: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  month: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  year: {
    formatter(value) {
      if (!value) return '';
      return '' + value;
    },
    parser(text) {
      const year = Number(text);
      if (!isNaN(year)) return year;

      return null;
    }
  },
  number: {
    formatter(value) {
      if (!value) return '';
      return '' + value;
    },
    parser(text) {
      let result = Number(text);

      if (!isNaN(text)) {
        return result;
      } else {
        return null;
      }
    }
  }
};

export default {
  mixins: [emitter],

  props: {
    format: String,
    readonly: Boolean,
    placeholder: String,
    value: {},
    haveTrigger: {},
    pickerOptions: {}
  },

  directives: {
    Clickoutside
  },

  data() {
    return {
      pickerVisible: false
    };
  },

  watch: {
    pickerVisible(val) {
      val === true ? this.showPicker() : this.hidePicker();
    },
    value(val) {
      this.dispatch('form-item', 'el.form.change');
    }
  },

  computed: {
    triggerClass() {
      return this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date';
    },

    editable() {
      return this.type.indexOf('range') === -1;
    },

    selectionMode() {
      if (this.type === 'week') {
        return 'week';
      } else if (this.type === 'month') {
        return 'month';
      } else if (this.type === 'year') {
        return 'year';
      }

      return 'day';
    },

    haveTrigger() {
      if (typeof this.showTrigger !== 'undefined') {
        return this.showTrigger;
      }
      return HAVE_TRIGGER_TYPES.indexOf(this.type) !== -1;
    },

    visualValue: {
      get() {
        const value = this.value;
        const formatter = (
          TYPE_VALUE_RESOLVER_MAP[this.type] ||
          TYPE_VALUE_RESOLVER_MAP['default']
        ).formatter;
        const format = DEFAULT_FORMATS[this.type];

        return formatter(value, this.format || format);
      },

      set(value) {
        if (value) {
          const type = this.type;
          const parser = (
            TYPE_VALUE_RESOLVER_MAP[type] ||
            TYPE_VALUE_RESOLVER_MAP['default']
          ).parser;
          const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);

          if (parsedValue) {
            this.$emit('input', parsedValue);
          }
          return;
        }
        this.$emit('input', value);
      }
    },

    editorType() {
      return 'text';
    }
  },

  methods: {
    handleClose() {
      this.pickerVisible = false;
    },

    handleFocus() {
      const type = this.type;

      if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1) {
        if (!this.pickerVisible) {
          this.showPicker();
        }
      }
      this.$emit('focus', this);
    },

    handleBlur() {
      this.$emit('blur', this);
      this.dispatch('form-item', 'el.form.blur');
    },

    handleKeydown(event) {
      const keyCode = event.keyCode;
      let selectionStart = event.target.selectionStart;
      let selectionEnd = event.target.selectionEnd;
      let length = event.target.value.length;

      if (keyCode === 27) {
        this.pickerVisible = this.picker.visible = false;
      // left
      } else if (keyCode === 37) {
        event.preventDefault();

        if (selectionEnd === length && selectionStart === length) {
          event.target.selectionStart = length - 2;
        } else if (selectionStart >= 3) {
          event.target.selectionStart -= 3;
        } else {
          event.target.selectionStart = 0;
        }
        event.target.selectionEnd = event.target.selectionStart + 2;
      // right
      } else if (keyCode === 39) {
        event.preventDefault();
        if (selectionEnd === 0 && selectionStart === 0) {
          event.target.selectionEnd = 2;
        } else if (selectionEnd <= length - 3) {
          event.target.selectionEnd += 3;
        } else {
          event.target.selectionEnd = length;
        }
        event.target.selectionStart = event.target.selectionEnd - 2;
      }
    },

    handleKeyup(event) {
      const keyCode = event.keyCode;
      if (FUNCTION_KEYS.indexOf(keyCode) > -1) return;
      if (!(this.picker && this.pickerVisible)) return;
      const selectionStart = event.target.selectionStart;
      const value = event.target.value;
      const type = this.type;
      const parser = (
        TYPE_VALUE_RESOLVER_MAP[type] ||
        TYPE_VALUE_RESOLVER_MAP['default']
      ).parser;
      const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);

      if (!parsedValue) return;
      this.picker.value = parsedValue;
      this.$emit('input', parsedValue);

      if (this.type.indexOf('date') > -1) return;

      setTimeout(_ => {
        let start = selectionStart;
        let end = selectionStart;
        const offset = 2;

        if (selectionStart === 9) {
          start += offset;
        }
        if (selectionStart >= 12) {
          if (selectionStart % 3 === 0) {
            start += 1;
            end = start;
          } else if (selectionStart % 3 === 2) {
            end = start + offset;
          }
        } else {
          if (selectionStart % 3 === 1) {
            start += 1;
            end = start;
          } else if (selectionStart % 3 === 0) {
            end = start + offset;
          }
        }

        event.target.selectionStart = start;
        event.target.selectionEnd = end;
      }, 0);
    },

    togglePicker() {
      !this.pickerVisible ? this.showPicker() : this.hidePicker();
    },

    destroyPopper() {
      if (this.popper) {
        this.resetTransformOrigin(this.popper);
        setTimeout(() => {
          this.popper && this.popper.destroy();
          this.popper = null;
        }, 300);
      }
    },

    hidePicker() {
      if (this.picker) {
        this.picker.resetView && this.picker.resetView();
        this.pickerVisible = this.picker.visible = false;
        this.destroyPopper();
      }
    },

    showPicker() {
      if (!this.picker) {
        this.picker = new Vue(merge({
          el: document.createElement('div')
        }, this.panel));
        this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange';
        this.picker.selectionMode = this.selectionMode;
        if (this.format) {
          this.picker.format = this.format;
        }

        const options = this.pickerOptions;

        if (options && options.selectableRange) {
          let ranges = options.selectableRange;
          const parser = TYPE_VALUE_RESOLVER_MAP.datetimerange.parser;
          const format = DEFAULT_FORMATS.timerange;

          ranges = Array.isArray(ranges) ? ranges : [ranges];
          this.picker.selectableRange = ranges.map(range => parser(range, format));
        }

        if (this.type === 'time-select' && options) {
          this.$watch('pickerOptions.minTime', val => {
            this.picker.minTime = val;
          });
        }

        for (const option in options) {
          if (options.hasOwnProperty(option) &&
              // 忽略 time-picker 的该配置项
              option !== 'selectableRange') {
            this.picker[option] = options[option];
          }
        }

        this.$el.appendChild(this.picker.$el);
        this.pickerVisible = this.picker.visible = true;
        this.picker.resetView && this.picker.resetView();

        this.picker.$on('pick', (date, visible = false) => {
          this.$emit('input', date);

          if (!visible) {
            this.pickerVisible = this.picker.visible = false;
          }
          this.picker.resetView && this.picker.resetView();
        });

        this.picker.$on('select-range', (start, end) => {
          setTimeout(() => {
            this.$refs.reference.setSelectionRange(start, end);
            this.$refs.reference.focus();
          }, 0);
        });
      } else {
        this.pickerVisible = this.picker.visible = true;
      }

      this.$nextTick(() => {
        if (this.popper) {
          this.popper.update();
          return;
        }

        this.popper = new Popper(this.$refs.reference, this.picker.$el, {
          gpuAcceleration: false,
          placement: 'bottom-start',
          boundariesPadding: 0,
          forceAbsolute: true
        });

        this.popper.onCreate(popper => {
          this.resetTransformOrigin(popper);
        });
      });

      if (this.value instanceof Date) {
        this.picker.date = new Date(this.value.getTime());
        this.picker.resetView && this.picker.resetView();
      } else {
        this.picker.value = this.value;
      }

      this.$nextTick(() => {
        if (this.type.indexOf('time') !== -1) {
          this.picker.focusEditor && this.picker.focusEditor('hours');
        }
        this.picker.ajustScrollTop && this.picker.ajustScrollTop();
      });
    },

    resetTransformOrigin(popper) {
      let placementMap = { top: 'bottom', bottom: 'top' };
      let placement = popper._popper.getAttribute('x-placement').split('-')[0];
      let origin = placementMap[placement];
      popper._popper.style.transformOrigin = `center ${ origin }`;
    }
  },

  beforeDestroy() {
    this.popper && this.popper.destroy();
  }
};
</script>

<template>
  <span
    class="el-date-editor"
    v-clickoutside="handleClose"
    :class="{
      'is-have-trigger': haveTrigger,
      'is-active': pickerVisible,
      'is-filled': !!this.value
    }">

    <input
      class="el-date-editor__editor"
      :readonly="readonly"
      :type="editorType"
      :placeholder="placeholder"
      @focus="handleFocus"
      @blur="handleBlur"
      @keydown="handleKeydown"
      @keyup="handleKeyup"
      ref="reference"
      v-model.lazy="visualValue" />

    <span
      @click="togglePicker()"
      class="el-date-editor__trigger el-icon"
      :class="[triggerClass]"
      v-if="haveTrigger">
    </span>
  </span>
</template>

<script>
import Vue from 'vue';
import Clickoutside from 'main/utils/clickoutside';
import { merge, formatDate, parseDate, getWeekNumber } from './util';
import Popper from 'main/utils/popper';
import emitter from 'main/mixins/emitter';

const FUNCTION_KEYS = [13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40];
const RANGE_SEPARATOR = ' - ';
const DEFAULT_FORMATS = {
  date: 'yyyy-MM-dd',
  month: 'yyyy-MM',
  datetime: 'yyyy-MM-dd HH:mm:ss',
  time: 'HH:mm:ss',
  timerange: 'HH:mm:ss',
  daterange: 'yyyy-MM-dd',
  datetimerange: 'yyyy-MM-dd HH:mm:ss'
};
const HAVE_TRIGGER_TYPES = [
  'date',
  'datetime',
  'time',
  'time-select',
  'week',
  'month',
  'year',
  'daterange',
  'timerange',
  'datetimerange'
];
const DATE_FORMATTER = function(value, format) {
  return formatDate(value, format);
};
const DATE_PARSER = function(text, format) {
  text = text.split(':');
  if (text.length > 1) text = text.map(item => item.slice(-2));
  text = text.join(':');

  return parseDate(text, format);
};
const RANGE_FORMATTER = function(value, format) {
  if (Array.isArray(value) && value.length === 2) {
    const start = value[0];
    const end = value[1];

    if (start && end) {
      return formatDate(start, format) + RANGE_SEPARATOR + formatDate(end, format);
    }
  }
  return '';
};
const RANGE_PARSER = function(text, format) {
  const array = text.split(RANGE_SEPARATOR);
  if (array.length === 2) {
    const range1 = array[0].split(':').map(item => item.slice(-2)).join(':');
    const range2 = array[1].split(':').map(item => item.slice(-2)).join(':');
    return [parseDate(range1, format), parseDate(range2, format)];
  }
  return [];
};
const TYPE_VALUE_RESOLVER_MAP = {
  default: {
    formatter(value) {
      if (!value) return '';
      return '' + value;
    },
    parser(text) {
      if (text === undefined || text === '') return null;
      return text;
    }
  },
  week: {
    formatter(value) {
      if (value instanceof Date) {
        const weekNumber = getWeekNumber(value);
        return value.getFullYear() + 'w' + (weekNumber > 9 ? weekNumber : '0' + weekNumber);
      }
      return value;
    },
    parser(text) {
      const array = (text || '').split('w');
      if (array.length === 2) {
        const year = Number(array[0]);
        const month = Number(array[1]);

        if (!isNaN(year) && !isNaN(month) && month < 54) {
          return text;
        }
      }
      return null;
    }
  },
  date: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  datetime: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  daterange: {
    formatter: RANGE_FORMATTER,
    parser: RANGE_PARSER
  },
  datetimerange: {
    formatter: RANGE_FORMATTER,
    parser: RANGE_PARSER
  },
  timerange: {
    formatter: RANGE_FORMATTER,
    parser: RANGE_PARSER
  },
  time: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  month: {
    formatter: DATE_FORMATTER,
    parser: DATE_PARSER
  },
  year: {
    formatter(value) {
      if (!value) return '';
      return '' + value;
    },
    parser(text) {
      const year = Number(text);
      if (!isNaN(year)) return year;

      return null;
    }
  },
  number: {
    formatter(value) {
      if (!value) return '';
      return '' + value;
    },
    parser(text) {
      let result = Number(text);

      if (!isNaN(text)) {
        return result;
      } else {
        return null;
      }
    }
  }
};

export default {
  mixins: [emitter],

  props: {
    format: String,
    readonly: Boolean,
    placeholder: String,
    value: {},
    haveTrigger: {},
    pickerOptions: {}
  },

  directives: {
    Clickoutside
  },

  data() {
    return {
      pickerVisible: false
    };
  },

  watch: {
    pickerVisible(val) {
      val === true ? this.showPicker() : this.hidePicker();
    },
    value(val) {
      this.dispatch('form-item', 'el.form.change');
    }
  },

  computed: {
    triggerClass() {
      return this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date';
    },

    editable() {
      return this.type.indexOf('range') === -1;
    },

    selectionMode() {
      if (this.type === 'week') {
        return 'week';
      } else if (this.type === 'month') {
        return 'month';
      } else if (this.type === 'year') {
        return 'year';
      }

      return 'day';
    },

    haveTrigger() {
      if (typeof this.showTrigger !== 'undefined') {
        return this.showTrigger;
      }
      return HAVE_TRIGGER_TYPES.indexOf(this.type) !== -1;
    },

    visualValue: {
      get() {
        const value = this.value;
        const formatter = (
          TYPE_VALUE_RESOLVER_MAP[this.type] ||
          TYPE_VALUE_RESOLVER_MAP['default']
        ).formatter;
        const format = DEFAULT_FORMATS[this.type];

        return formatter(value, this.format || format);
      },

      set(value) {
        if (value) {
          const type = this.type;
          const parser = (
            TYPE_VALUE_RESOLVER_MAP[type] ||
            TYPE_VALUE_RESOLVER_MAP['default']
          ).parser;
          const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);

          if (parsedValue) {
            this.$emit('input', parsedValue);
          }
          return;
        }
        this.$emit('input', value);
      }
    },

    editorType() {
      return 'text';
    }
  },

  methods: {
    handleClose() {
      this.pickerVisible = false;
    },

    handleFocus() {
      const type = this.type;

      if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1) {
        if (!this.pickerVisible) {
          this.showPicker();
        }
      }
      this.$emit('focus', this);
    },

    handleBlur() {
      this.$emit('blur', this);
      this.dispatch('form-item', 'el.form.blur');
    },

    handleKeydown(event) {
      const keyCode = event.keyCode;
      let selectionStart = event.target.selectionStart;
      let selectionEnd = event.target.selectionEnd;
      let length = event.target.value.length;

      if (keyCode === 27) {
        this.pickerVisible = this.picker.visible = false;
      // left
      } else if (keyCode === 37) {
        event.preventDefault();

        if (selectionEnd === length && selectionStart === length) {
          event.target.selectionStart = length - 2;
        } else if (selectionStart >= 3) {
          event.target.selectionStart -= 3;
        } else {
          event.target.selectionStart = 0;
        }
        event.target.selectionEnd = event.target.selectionStart + 2;
      // right
      } else if (keyCode === 39) {
        event.preventDefault();
        if (selectionEnd === 0 && selectionStart === 0) {
          event.target.selectionEnd = 2;
        } else if (selectionEnd <= length - 3) {
          event.target.selectionEnd += 3;
        } else {
          event.target.selectionEnd = length;
        }
        event.target.selectionStart = event.target.selectionEnd - 2;
      }
    },

    handleKeyup(event) {
      const keyCode = event.keyCode;
      if (FUNCTION_KEYS.indexOf(keyCode) > -1) return;
      if (!(this.picker && this.pickerVisible)) return;
      const selectionStart = event.target.selectionStart;
      const value = event.target.value;
      const type = this.type;
      const parser = (
        TYPE_VALUE_RESOLVER_MAP[type] ||
        TYPE_VALUE_RESOLVER_MAP['default']
      ).parser;
      const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);

      if (!parsedValue) return;
      this.picker.value = parsedValue;
      this.$emit('input', parsedValue);

      if (this.type.indexOf('date') > -1) return;

      setTimeout(_ => {
        let start = selectionStart;
        let end = selectionStart;
        const offset = 2;

        if (selectionStart === 9) {
          start += offset;
        }
        if (selectionStart >= 12) {
          if (selectionStart % 3 === 0) {
            start += 1;
            end = start;
          } else if (selectionStart % 3 === 2) {
            end = start + offset;
          }
        } else {
          if (selectionStart % 3 === 1) {
            start += 1;
            end = start;
          } else if (selectionStart % 3 === 0) {
            end = start + offset;
          }
        }

        event.target.selectionStart = start;
        event.target.selectionEnd = end;
      }, 0);
    },

    togglePicker() {
      !this.pickerVisible ? this.showPicker() : this.hidePicker();
    },

    destroyPopper() {
      if (this.popper) {
        this.resetTransformOrigin(this.popper);
        setTimeout(() => {
          this.popper && this.popper.destroy();
          this.popper = null;
        }, 300);
      }
    },

    hidePicker() {
      if (this.picker) {
        this.picker.resetView && this.picker.resetView();
        this.pickerVisible = this.picker.visible = false;
        this.destroyPopper();
      }
    },

    showPicker() {
      if (!this.picker) {
        this.picker = new Vue(merge({
          el: document.createElement('div')
        }, this.panel));
        this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange';
        this.picker.selectionMode = this.selectionMode;
        if (this.format) {
          this.picker.format = this.format;
        }

        const options = this.pickerOptions;

        if (options && options.selectableRange) {
          let ranges = options.selectableRange;
          const parser = TYPE_VALUE_RESOLVER_MAP.datetimerange.parser;
          const format = DEFAULT_FORMATS.timerange;

          ranges = Array.isArray(ranges) ? ranges : [ranges];
          this.picker.selectableRange = ranges.map(range => parser(range, format));
          delete this.pickerOptions.selectableRange;
        }

        if (this.type === 'time-select' && options) {
          this.$watch('pickerOptions.minTime', val => {
            this.picker.minTime = val;
          });
        }

        for (const option in options) {
          if (options.hasOwnProperty(option)) {
            this.picker[option] = options[option];
          }
        }

        this.$el.appendChild(this.picker.$el);
        this.pickerVisible = this.picker.visible = true;
        this.picker.resetView && this.picker.resetView();

        this.picker.$on('pick', (date, visible = false) => {
          this.$emit('input', date);

          if (!visible) {
            this.pickerVisible = this.picker.visible = false;
          }
          this.picker.resetView && this.picker.resetView();
        });

        this.picker.$on('select-range', (start, end) => {
          setTimeout(() => {
            this.$refs.reference.setSelectionRange(start, end);
            this.$refs.reference.focus();
          }, 0);
        });
      } else {
        this.pickerVisible = this.picker.visible = true;
      }

      this.$nextTick(() => {
        if (this.popper) {
          this.popper.update();
          return;
        }

        this.popper = new Popper(this.$refs.reference, this.picker.$el, {
          gpuAcceleration: false,
          placement: 'bottom-start',
          boundariesPadding: 0,
          forceAbsolute: true
        });

        this.popper.onCreate(popper => {
          this.resetTransformOrigin(popper);
        });
      });

      if (this.value instanceof Date) {
        this.picker.date = new Date(this.value.getTime());
        this.picker.resetView && this.picker.resetView();
      } else {
        this.picker.value = this.value;
      }

      this.$nextTick(() => {
        if (this.type.indexOf('time') !== -1) {
          this.picker.focusEditor && this.picker.focusEditor('hours');
        }
        this.picker.ajustScrollTop && this.picker.ajustScrollTop();
      });
    },

    resetTransformOrigin(popper) {
      let placementMap = { top: 'bottom', bottom: 'top' };
      let placement = popper._popper.getAttribute('x-placement').split('-')[0];
      let origin = placementMap[placement];
      popper._popper.style.transformOrigin = `center ${ origin }`;
    }
  },

  beforeDestroy() {
    this.popper && this.popper.destroy();
  }
};
</script>


try touch

try touch

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Chan-Chun/Introduction.git/'


menu demo add matchMethod

menu demo add matchMethod

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/g-bbfe/components-assembly.git/'


keep sticky height

keep sticky height

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/frontools/magnolia-megaton.git/'


修正v-validate字段错误的问题

修正v-validate字段错误的问题


Last comments fix

Last comments fix

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stefanjudis/stefan-judis-website.git/'


update basic layout

update basic layout

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sy264115809/goblin.git/'


Add ‘recent activity’ header to channel list

<template>

{{ $tr('recentTitle') }}

      {{ $tr('recentSubHeading') }}

    <report-table :caption="$tr('channelList')">

        <template v-for="channel in channelList">

            <name-cell :kind="CHANNEL" :title="channel.title" :link="reportLink(channel.id)"/>
            <activity-cell :date="lastActive[channel.id]"/>

        </template>

    </report-table>

</template>

<template>

  <report-table :caption="$tr('channelList')">

      <template v-for="row in channelList">

          <name-cell :kind="CHANNEL" :title="row.title" :link="reportLink(row.id)"/>
          <activity-cell :date="lastActive[row.id]"/>

      </template>

  </report-table>

</template>


Removed test code

Removed test code

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/LokeCarlsson/lokecarlsson.git/'


Icon component

Icon component

<template>
  <i class="icon" :style="{'font-size':sizeComputed}" :class="classes">{{iconTextComputed}}<slot></slot></i>
</template>
<script>
  export default {
    props: {
      color: String,
      material: String, // Material Icons
      f7: String, // Framework7 Icons
      ion: String, // Ionicons
      fa: String, // Font Awesome
      icon: String, // Custom
      ifMd: String,
      ifIos: String,
      size: [String, Number],
    },
    computed: {
      sizeComputed() {
        const self = this;
        let size = self.size;
        if (typeof size === 'number' || parseFloat(size) === size * 1) {
          size = `${size}px`;
        }
        return size;
      },
      iconTextComputed() {
        const self = this;
        let text = self.material || self.f7;
        if (self.ifMd && self.$theme.md && (self.ifMd.indexOf('material:') >= 0 || self.ifMd.indexOf('f7:') >= 0)) {
          text = self.ifMd.split(':')[1];
        } else if (self.ifIos && self.$theme.ios && (self.ifIos.indexOf('material:') >= 0 || self.ifIos.indexOf('f7:') >= 0)) {
          text = self.ifIos.split(':')[1];
        }
        return text;
      },
      classes() {
        let classes = {};
        const self = this;
        if (self.ifMd || self.ifIos) {
          const parts = self[self.$theme.md ? 'ifMd' : 'ifIos'].split(':');
          const prop = parts[0];
          const value = parts[1];
          if (prop === 'material' || prop === 'fa' || prop === 'f7') {
            classes.fa = prop === 'fa';
            classes['material-icons'] = prop === 'material';
            classes['f7-icons'] = prop === 'f7';
          }
          if (prop === 'fa' || prop === 'ion') {
            classes[`${prop}-${value}`] = true;
          }
          if (prop === 'icon') {
            classes[value] = true;
          }
        } else {
          classes = {
            'material-icons': this.material,
            'f7-icons': this.f7,
            fa: this.fa,
          };
          if (this.ion) classes[`ion-${this.ion}`] = true;
          if (this.fa) classes[`fa-${this.fa}`] = true;
          if (this.icon) classes[this.icon] = true;
        }
        if (this.color) classes[`color-${this.color}`] = true;
        return classes;
      },
    },
  };
</script>

error: pathspec 'src/components/icon.vue' did not match any file(s) known to git


Fix comments

Fix comments


Version bump

Version bump

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NathanielDavid/Sumie.git/'


add scoped

add scoped

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/firery/mirs-web-vue.git/'


Adding Folder chooser for main roleplay folder

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/CodeOfCinders/roleplaymanager.git/'


Display event data on the Events view

Display event data on the Events view

The Sun, Moon and event highlights are displayed within the Events view,
using the date methods found in the `utils` module.

The formatting is not yet complete.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/astronote/astronote-docker.git/'


Use the coordinates in the store for API requests

When grabbing the events for a given day, the latitude and longitude are
referenced from the store as parameters. The store has to be imported as
the API request function lives outside of the Vue component definition.


show no resources message

show no resources message

<template>

          {{ currentLesson.name }}
          <progress-icon v-if="lessonHasResources" :progress="lessonProgress" />

{{ $tr('teacherNote') }}

 {{ currentLesson.description }}

      <content-card
        v-for="c in contentNodes"
        :key="c.pk"
        class="content-card"
        :isMobile="true"
        :kind="c.kind"
        :link="lessonContentNodeLink(c)"
        :progress="c.progress_fraction"
        :thumbnail="getContentNodeThumbnail(c)"
        :title="c.title"
      />

        {{ $tr('noResourcesInLesson') }}

</template>

<template>

          {{ currentLesson.name }}
          <progress-icon v-if="lessonHasResources" :progress="lessonProgress" />

{{ $tr('teacherNote') }}

 {{ currentLesson.description }}

      <content-card
        v-for="c in contentNodes"
        :key="c.pk"
        class="content-card"
        :isMobile="true"
        :kind="c.kind"
        :link="lessonContentNodeLink(c)"
        :progress="c.progress_fraction"
        :thumbnail="getContentNodeThumbnail(c)"
        :title="c.title"
      />

</template>


Adding more pagination functionality.

Adding more pagination functionality.

<template>

      <router-link :to="editClassLink">
        <icon-button
          :text="$tr('backToClassDetails')"
          :primary="false"
        >
          <mat-svg category="navigation" name="arrow_back"/>
        </icon-button>
      </router-link>
      <icon-button
        :text="$tr('reviewAndSave')"
        :primary="true"
      />

{{ $tr('selectUsers') }}

{{ $tr('showingAllUnassigned') }}

      <textbox
        :placeholder="$tr('searchByName')"
        :aria-label="$tr('searchByName')"
        v-model="filterInput"
        type="search"
      />

{{ $tr('showing') }} {{ startRange }} - {{ endRange }} {{ $tr('of') }} {{ $tr('numLearners',
        {count: totalItems}) }}

          {{$tr('name')}}
          {{$tr('username')}}

            <input type="checkbox" :id="learner.id" :value="learner.id" v-model="selectedLearners">

          {{learner.full_name}}
          {{learner.username}}

        <ui-icon-button
          type="secondary"
          color="default"
          icon="chevron_left"
          ariaLabel="Previous results"
          :disabled="pageNum === 1"
        />
        <icon-button
          v-for="page in totalPages"
          :text="String(page)"
          :primary="false"
          :disabled="pageNum === page"
          @click="goTo(page)"
        />
        <ui-icon-button
          type="secondary"
          color="default"
          icon="chevron_right"
          ariaLabel="Next results"
          :disabled="pageNum === totalPages"
        />

{{ $tr('createAndEnroll') }}

{{ $tr('enrollSomeone') }}

      <icon-button
        :text="$tr('createNewUser')"
        :primary="false"
        @click="openCreateUserModal"
      >
        <mat-svg category="content" name="add"/>
      </icon-button>

      <user-create-modal
        v-if="createUserModalOpen"
        @close="closeCreateUserModal"/>

</template>

<template>

      <router-link :to="editClassPage">
        <icon-button
          :text="$tr('backToClassDetails')"
          :primary="false"
        >
          <mat-svg category="navigation" name="arrow_back"/>
        </icon-button>
      </router-link>
      <icon-button
        :text="$tr('reviewAndSave')"
        :primary="true"
      />

{{ $tr('selectUsers') }}

{{ $tr('showingAllUnassigned') }}

      <textbox
        :placeholder="$tr('searchByName')"
        :aria-label="$tr('searchByName')"
        v-model="filterInput"
        type="search"
      />

{{ $tr('showing') }} {{ startRange }} - {{ endRange }} {{ $tr('of') }} {{ $tr('numLearners',
        {count: totalLearners}) }}

          {{$tr('name')}}
          {{$tr('username')}}

            <input type="checkbox" :id="learner.id" :value="learner.id" v-model="selectedLearners">

          {{learner.full_name}}
          {{learner.username}}

pagination

{{ $tr('createAndEnroll') }}

{{ $tr('enrollSomeone') }}

      <icon-button
        :text="$tr('createNewUser')"
        :primary="false"
        @click="openCreateUserModal"
      >
        <mat-svg category="content" name="add"/>
      </icon-button>

      <user-create-modal
        v-if="createUserModalOpen"
        @close="closeCreateUserModal"/>

</template>


Begin transition of Clients tag to Vue.

Begin transition of Clients tag to Vue.

<template>

            Client

            Total Time

            # Related

    <form name="client-add"
          class="row mb-4 py-2 bg-faded rounded-bottom"
          v-on:submit.prevent="onSubmit"
          v-on:submit="submitClient">

            <input name="client-name"
                   type="text"
                   class="form-control form-control-sm"
                   v-model="name"
                   placeholder="New Client Name"
                   required>

            <button
                    name="client-add-submit"
                    type="submit"
                    class="btn btn-success btn-sm w-100"
                    v-on:click="submitClient">
                Add
            </button>

    </form>

</template>


properly mark task as done

properly mark task as done

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aligerum/clockwork.git/'


Add icon to the start page

Add icon to the start page

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/JosefFriedrich-nodejs/baldr.git/'


Use ltr for pdfs to avoid distortion

Use ltr for pdfs to avoid distortion

<template>

     {{ $formatNumber(pageNum) }}
    <canvas
      v-show="active"
      class="canvas"
      ref="canvas"
      dir="ltr"
      :height="pageHeight"
      :width="pageWidth">
    </canvas>

</template>

<template>

     {{ $formatNumber(pageNum) }}
    <canvas
      v-show="active"
      class="canvas"
      ref="canvas"
      :height="pageHeight"
      :width="pageWidth">
    </canvas>

</template>


Add documentation for UiTooltip

Add documentation for UiTooltip

<template>

UiTooltip

UiTooltip allows you to show a tooltip on an element. You can customize the position and the event the causes the tooltip to open.

UiTooltip is used internally by UiIconButton and UiFab.

Examples

                <image-pane inline-template
                    :image="simpson.image" :name="simpson.name" :position="simpson.position"
                    v-for="simpson in theSimpsons"
                >

                        <ui-tooltip
                            :trigger="$els.portrait" :content="name" :position="position"
                        ></ui-tooltip>

                </image-pane>

API

        <ui-tabs raised>

            <ui-tab header="Props">

                            Name
                            Type
                            Default
                            Description

                                trigger *
                                HTMLElement
                                (required)
                                An Element to attach the tooltip to. By default, when this element is hovered or focused, the tooltip is shown.

                                content
                                String

                                The tooltip content (text only).

                                position
                                String
                                "bottom center"
                                The position of the tooltip relative to the trigger. One of top left, left top, left middle, left bottom, bottom left, bottom center, bottom right, right bottom, right middle, right top, top right, or top center.

                                openOn
                                String
                                "hover focus"
                                The type of event(s) that will cause the tooltip to open. One or more of click, hover, or focus. Separate multiple events with a space.

                * Required prop
            </ui-tab>

        </ui-tabs>

</template>

error: pathspec 'src-docs/components/UiTooltipDocs.vue' did not match any file(s) known to git


Removed one do that felt out of place

Removed one do that felt out of place


Fix state animations

Fix state animations

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/wappulehti-apy/diilikone-front-2017.git/'


- Update to Laravel commit: d1ba0c3d0d8fce35cb03c0b0593cb7e3c35c70d1

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/linzhengen/lala.git/'


Fix session store name issue

Fix session store name issue

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/PayBreak/basket.git/'


create and show tasks on different days

create and show tasks on different days


Disable backbag in 25 magazine deals

Disable backbag in 25 magazine deals


add unique-opened

add unique-opened

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/CHCP/toolmaker-web.git/'


Make breadcrumbs' list prop required.

Make breadcrumbs' list prop required.

<template>

      {{ ancestor.name }} >
       {{ ancestor.name }}

</template>


Display list in three columns

Display list in three columns


[added] new form

[added] new form

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mtlong29/JBShop_Site.git/'


Prevent join to a private exam

Prevent join to a private exam

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/JimmehCai/VTIC.git/'


Add tooltip component

Add tooltip component

<template>
    <b-tooltip>
        <slot />
    </b-tooltip>
</template>

<script>
    import { BTooltip } from 'bootstrap-vue';

    export default {
        components: {
            BTooltip,
        },
        props: {

        },
    }
</script>

error: pathspec 'packages/ui/src/components/Tooltip.vue' did not match any file(s) known to git


hotfix social medias

hotfix social medias

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/chypriote/france-v2.git/'


show that a filter is active in the reports

<template>

        <icon :icon="['fas', 'book']" class="fa-sm mr-2"/>
        Reports

      <template v-if="is_staff">
        <select
          v-model="exportFormat"
          class="export-select custom-select form-control-sm w-25 flex-fill mr-2">
          <option value="csv">csv</option>
          <option value="xls">xls</option>
          <option value="tsv">tsv</option>
          <option value="ods">ods</option>
          <option value="json">json</option>
          <option value="yaml">yaml</option>
          <option value="html">html</option>
        </select>
        <button
          id="export-report"
          class="btn btn-light flex-fill text-nowrap mr-2"
          @click="exportReport">
          <icon :icon="['fas', 'download']" class="mr-1"/>
          Export
        </button>
      </template>

      <popover class="flex-fill mr-2">
        <template slot="popover-button">

            <icon :icon="['fas', 'filter']" class="mr-1"/>
            Filter

        </template>
        <template slot="popover-content">
          Filter by column, multiple filters are okay

                User
                <selector
                  id="report-filter-user"
                  v-model="user"
                  :options="users"
                  :selected="user"
                  placeholder="User"
                  allowclear/>

                Client
                <selector
                  id="report-filter-client"
                  v-model="client"
                  :options="clients"
                  :selected="client"
                  placeholder="Client"
                  allowclear/>

                Project
                <selector
                  id="report-filter-project"
                  v-model="project"
                  :options="projects"
                  :selected="project"
                  placeholder="Project"
                  allowclear/>

                Task
                <selector
                  id="report-filter-task"
                  v-model="task"
                  :options="tasks"
                  :selected="task"
                  placeholder="Task"
                  allowclear/>

                Min. Date
                <datepicker
                  id="report-filter-min-date"
                  v-model="minDate"
                  type="text"
                  class="form-control date-input"
                  placeholder="Min. date"
                  allowclear/>

                Max. Date
                <datepicker
                  id="report-filter-max-date"
                  v-model="maxDate"
                  type="text"
                  class="form-control date-input"
                  placeholder="Max. date"
                  allowclear/>

              <button
                class="btn btn-info w-100 clear"
                @click.prevent.exact="clear">
                clear
              </button>

        </template>
      </popover>

      <popover class="flex-fill">
        <template slot="popover-button">
          <icon :icon="['fas', 'sort']" class="mr-1"/>
          Sort
        </template>
        <template slot="popover-content">
          Sort by column and direction

              <selector
                id="report-sort-by"
                v-model="orderBy"
                :options="orderByOptions"
                selected="date"
                placeholder="Order by"/>

              <selector
                id="report-order-dir"
                v-model="orderDir"
                :options="orderDirOptions"
                selected="desc"
                placeholder="Order direction"/>

        </template>
      </popover>

  <template v-if="entries.length">

              <icon :icon="['fas', 'address-book']" class="mr-1"/>
              Client

              <icon :icon="['fas', 'briefcase']" class="mr-1"/>
              Project

              <icon :icon="['fas', 'tasks']" class="mr-1"/>
              Task

              <icon :icon="['fas', 'user-circle']" class="mr-1"/>
              User

              <icon :icon="['fas', 'calendar']" class="mr-1"/>
              Date

              <icon :icon="['fas', 'clock']" class="mr-1"/>
              Duration

              <icon :icon="['fas', 'comment']" class="mr-1"/>
              Note

            {{ entry.project ? getClient(getProject(entry.project).client).name : '' }}
            {{ entry.project ? getProject(entry.project).name : '' }}
            {{ entry.task ? getTask(entry.task).name : '' }}
            {{ entry.user ? getUser(entry.user).username : '' }}
            {{ $moment(entry.date).format('LL') }}
            {{ $moment.duration(entry.duration, 'hours').format('h[h] mm[m]') }}
            {{ entry.note }}

              Count
              {{ entries.length }}

              Sum
              {{ $moment.duration(total, 'hours').format('d[d] h[h] m[m]') }}

  </template>

          Loading...

</template>


Fix Presentation overview

Fix Presentation overview


Update Services.vue

Update Services.vue

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mubaidr/gh-pages.git/'


修复遗漏的 iview-theme 文档更新

修复遗漏的 iview-theme 文档更新

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/iview/iview-doc.git/'


Adds new component

Adds new component

<template>

</template>

<script>

</script>

<style scoped>
</style>

error: pathspec 'src/components/hack.vue' did not match any file(s) known to git


Disabled Show Invisibles

Disabled Show Invisibles

as it was annoying but useful for debugging

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/codeweavers/Consign.git/'


add error texts in component Mail

add error texts in component Mail

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/notadd/administration.git/'


Add Last updated column

Add Last updated column


more UI changes

more UI changes

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/joshStillerman/NDM.git/'


use external icon component for exhibition listings

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mplusmuseum/mplusmuseum-stories.git/'


use vuejs-datepicker components, finsh the ajax interaction

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/joriscai/myblog-vue.git/'