howly crap

howly crap

<template lang="html">

Proposal

        <app-tweet-fork-form v-if="proposing" :originalTweet="originalTweetToEdit"
          @editionProposed="newEdition($event)"></app-tweet-fork-form>

no-go

          <app-edition-card
            v-for="edition in noGoEditions" class="edition-card" :data-edition-id="edition.id"
            :key="edition.id" :edition="edition" @newEditionProposed="newEdition($event)"
            @dragging-me="draggingEditionStart($event)" @ed-drop="dropOnEdition($event)">
          </app-edition-card>

neutral

          <app-edition-card
            v-for="edition in neutralEditions" class="edition-card" :data-edition-id="edition.id"
            :key="edition.id" :edition="edition" @newEditionProposed="newEdition($event)"
            @dragging-me="draggingEditionStart($event)" @ed-drop="dropOnEdition($event)">
          </app-edition-card>
          <app-edition-card
            v-for="edition in nonRankedEditions" class="edition-card" :data-edition-id="edition.id"
            :key="edition.id" :edition="edition" @newEditionProposed="newEdition($event)"
            @dragging-me="draggingEditionStart($event)" @ed-drop="dropOnEdition($event)">
          </app-edition-card>

go

          <app-edition-card
            v-if="goEditions.length > 0" v-for="edition in goEditions" class="edition-card" :data-edition-id="edition.id"
            :key="edition.id" :edition="edition" @newEditionProposed="newEdition($event)"
            @dragging-me="draggingEditionStart($event)" @ed-drop="dropOnEdition($event)">
          </app-edition-card>

</template>


add 'prevent default' to order link; fix displayed entries

<template>

                <form class="form-inline" id="literature-search-form">

                            <input type="text" class="form-control" @input="debouncedSearch" placehoder="Search&ellipsis;">

                </form>

                <button type="button" class="btn btn-success" id="literature-add-button" @click="showNewItemModal" :disabled="!$can('add_remove_literature')">
                     {{ $t('main.bibliography.add') }}
                </button>

                <file-upload
                    accept="application/x-bibtex,text/x-bibtex,text/plain"
                    extensions="bib,bibtex"
                    ref="upload"
                    v-model="files"
                    post-action="/api/v1/bibliography/import"
                    :directory="false"
                    :disabled="!$can('add_remove_literature|edit_literature')"
                    :multiple="false"
                    :drop="true"
                    @input-file="inputFile">

                             {{ $t('main.bibliography.import') }}

                </file-upload>

                <button type="button" class="btn btn-outline-primary" @click="exportFile">
                     {{ $t('main.bibliography.export') }}
                </button>

                        {{ $t('main.bibliography.show-all-fields') }}

                        <input type="checkbox" id="apply-changes-toggle" v-model="showAllFields" />

                                {{ $t('global.type') }}

                                {{ $t('main.bibliography.column.cite-key') }}

                                {{ $t('main.bibliography.column.author') }}

                                {{ $t('main.bibliography.column.year') }}

                                {{ $t('main.bibliography.column.title') }}

                                {{ $t('main.bibliography.column.booktitle') }}

                                {{ $t('main.bibliography.column.publisher') }}

                            {{ $t('main.bibliography.column.pages') }}

                                {{ $t('main.bibliography.column.editor') }}

                                {{ $t('main.bibliography.column.journal') }}

                            {{ $t('main.bibliography.column.month') }}

                            {{ $t('main.bibliography.column.volume') }}

                            {{ $t('main.bibliography.column.number') }}

                            {{ $t('main.bibliography.column.chapter') }}

                            {{ $t('main.bibliography.column.edition') }}

                            {{ $t('main.bibliography.column.series') }}

                                {{ $t('main.bibliography.column.address') }}

                            {{ $t('main.bibliography.column.note') }}

                                {{ $t('main.bibliography.column.misc') }}

                                {{ $t('main.bibliography.column.howpublished') }}

                            {{ $t('main.bibliography.column.institution') }}

                            {{ $t('main.bibliography.column.organization') }}

                            {{ $t('main.bibliography.column.school') }}

                            {{ $t('global.created-at') }}

                            {{ $t('global.updated-at') }}

                            {{ $t('global.options') }}

                            {{ entry.type }}

                            {{ entry.citekey }}

                            {{ entry.author }}

                            {{ entry.year }}

                            {{ entry.title }}

                            {{ entry.booktitle }}

                            {{ entry.publisher }}

                            {{ entry.pages }}

                            {{ entry.editor }}

                            {{ entry.journal }}

                            {{ entry.month }}

                            {{ entry.volume }}

                            {{ entry.number }}

                            {{ entry.chapter }}

                            {{ entry.edition }}

                            {{ entry.series }}

                            {{ entry.address }}

                            {{ entry.note }}

                            {{ entry.misc }}

                            {{ entry.howpublished }}

                            {{ entry.institution }}

                            {{ entry.organization }}

                            {{ entry.school }}

                            {{ entry.created_at }}

                            {{ entry.updated_at }}

                                         {{ $t('global.edit') }}

                                         {{ $t('global.delete') }}

        <router-view
            v-can.one="'add_remove_literature|edit_literature'"
            :data="newItem"
            :available-types="availableTypes"
            :on-success="addBibliographyItem"
            :on-close="onModalClose">
        </router-view>

        <modal name="delete-bibliography-item-modal" height="auto" :scrollable="true" v-can="'add_remove_literature'">

{{ $t('main.bibliography.modal.delete.title') }}

                    <button type="button" class="close" aria-label="Close" @click="hideDeleteEntryModal">
                        ×
                    </button>

                        {{ $t('global.delete-name.desc', {name: deleteItem.title}) }}

                        {{
                            $tc('main.bibliography.modal.delete.alert', deleteItem.count, {
                                name: deleteItem.title,
                                cnt: deleteItem.count
                            })
                        }}

                    <button type="submit" class="btn btn-danger" @click="deleteEntry(deleteItem)">
                         {{ $t('global.delete') }}
                    </button>
                    <button type="button" class="btn btn-outline-secondary" @click="hideDeleteEntryModal">
                         {{ $t('global.cancel') }}
                    </button>

        </modal>

</template>


[#43] remove dev code

[#43] remove dev code

<template>

        <transition name="translate">

Beta

                    <el-progress type="circle" :percentage="progress"></el-progress>
                    <p v-if="progress < 100">Provide more information to Zeus to get a prediction on your case

See Latest Prediction

FEEDBACK

RESET CONVERSATION

        </transition>

        <transition name="el-zoom-in-center">

                <el-row>
                    <el-col :sm="{span: 24, offset: 0}">

                    </el-col>
                    <el-col :sm="{span: 1, offset: 23}">

                    </el-col>
                    <el-col :sm="{span: 24, offset: 0}">

Here is our prediction after analyzing {{ report.data_set }} Régie du logement"s precedents:

                    </el-col>
                    <el-col :sm="{span: 5, offset: 2}">

                            <el-progress type="circle" :percentage="report.accuracy" :stroke-width="30" :width="250"></el-progress>

Prediction Accuracy

                    </el-col>
                    <el-col :sm="{span: 8, offset: 2}">

                            <el-carousel indicator-position="outside">

                                    <el-carousel-item :key="key" :name="key">
                                        <vue-chart
                                            type="bar"
                                            :data="chartData"
                                            :options="{scales: {yAxes: [{ticks: {beginAtZero: true}}]}}"
                                            :update-config="{duration: 800, easing: 'easeOutBounce'}"
                                        ></vue-chart>
                                        properties
                                    </el-carousel-item>

                            </el-carousel>

                    </el-col>
                    <el-col :sm="{span: 4, offset: 2}">

Case Verdict

                                <el-col :sm="{span: 20, offset: 0}">

{{ key }}

                                </el-col>
                                <el-col :sm="{span: 2, offset: 2}">
                                    <icon name="check-square" class="outcome-check"></icon>
                                </el-col>

                    </el-col>
                    <el-col :sm="{span: 22, offset: 1}">

Here are {{ report.similar_case }} most similar precendents to your case

                                <el-table :data="report.similar_precedents_table" stripe>

                                        <el-table-column prop="name" label="Case Number" align="center" fixed="left"></el-table-column>

                                        <el-table-column :prop="fact" :label="fact" align="center"></el-table-column>

                                        <el-table-column :prop="outcome" :label="outcome" align="center"></el-table-column>

                                </el-table>

                    </el-col>
                    <el-col :sm="{span: 22, offset: 1}">

Need professional legal support? Contact us at 514-123-4567

FEEDBACK

RESET CONVERSATION

                    </el-col>
                </el-row>

        </transition>

        <el-dialog title="Feedback" :visible.sync="openFeedbackModal">
            <textarea id="feedback-input" v-model="feedback">
            </textarea>

                <el-button v-on:click="openFeedbackModal = false">Cancel</el-button>
                <el-button type="primary" v-on:click="submitFeedback()">Submit</el-button>

        </el-dialog>

</template>


removed extra cell field on corporation info

<template>

        File Upload In Progress...

        {{file_upload_error}}

        Successfully uploaded all files

{{ currentDriller.first_name }} {{ currentDriller.surname }}

            <api-error :error="error" resetter="SET_ERROR"></api-error>

Personal Information

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editPerson = !editPerson"
                  v-if="currentDriller.person_guid && userRoles.registry.edit"> Edit</button>

            <person-edit
                  section="person"
                  v-if="editPerson && userRoles.registry.edit"
                  :record="currentDriller.person_guid"
                  @updated="editPerson = false; updateRecord()"
                  @canceled="editPerson = false"></person-edit>

                  Surname:

                  {{ currentDriller.surname }}

                  First name:

                  {{ currentDriller.first_name }}

                  Well Driller ORCS:

                  {{ currentDriller.well_driller_orcs_no }}

                  Pump Installer ORCS:

                  {{ currentDriller.pump_installer_orcs_no }}

        <div class="card mb-3"
            v-for="(registration, index) in currentDriller.registrations"
            :key="`registration ${index}`">

{{ registration.activity_description }} Registration

Classifications

                    Classification
                    Register Status
                    Date Registered

                    <tr
                        v-if="item.activity === registration.registries_activity"
                        v-for="(item, index_c) in classifications" :key="`reg ${index} class ${index_c}`">
                      <router-link :to="{
                        name: 'ApplicationDetail',
                        params: { person_guid: currentDriller.person_guid, registration_guid: item.registration_guid, application_guid: item.application_guid } }">
                      {{ item.description }}</router-link>
                      {{ item.status }}
                      {{ item.date }}

                    <application-add
                        class="mb-3"
                        v-on:close="closeApplication(registration.registries_activity)"
                        :value="getApplication(registration.registries_activity)"
                        :activity="registration.registries_activity"
                        mode="edit">
                        <button type="submit" class="btn btn-primary" variant="primary">Save</button>
                        <button type="button" class="btn btn-light" @click="closeApplication(registration.registries_activity)">Cancel</button>
                    </application-add>

                   Add classification

{{ registration.activity_description }} Registration Details

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editRegistration = (editRegistration === (index + 1) ? 0 : (index + 1))"
                  v-if="userRoles.registry.edit">
                   Edit
                  </button>

            <person-edit
              class="mb-4"
              section="registration"
              :record="registration"
              v-if="editRegistration === (index + 1) && userRoles.registry.edit"
              @updated="editRegistration = 0; updateRecord()"
              @canceled="editRegistration = 0"></person-edit>

                  Registration number:

                  {{ registration.registration_no }}

{{ registration.activity_description }} Company Information

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editCompany = (editCompany === (index + 1) ? 0 : (index + 1))"
                  v-if="currentDriller.person_guid && userRoles.registry.edit">
                   Add company
                   Change company
                  </button>

            <person-edit
              section="company"
              :record="registration"
              v-if="editCompany === (index + 1) && userRoles.registry.edit"
              @updated="editCompany = 0; updateRecord()"
              @canceled="editCompany = 0"></person-edit>

                  Company name:

                  {{ registration.organization.name }}

                  Street address:

                  {{ registration.organization.street_address }}

                  City:

                  {{ registration.organization.city }}

                  Province:

                  {{ registration.organization.province_state }}

                  Postal Code:

                  {{ registration.organization.postal_code }}

                  Office number:

                  {{ registration.organization.main_tel }}

                  Email address:

                  {{ registration.organization.email }}

                  Fax number:

                  {{ registration.organization.fax_tel }}

                  Website:

                  {{ registration.organization.website_url }}

              No {{ registration.activity_description }} company.

            <div
                v-for="(item, index) in registrationOptions"
                :key="`unregistered activity ${index}`"
                v-if="!currentDriller.registrations.some(reg => reg.registries_activity === item.code)">
              <b-button variant="primary" class="my-1 registries-action-button" :ref="`registerButton${item.code}`" @click="confirmRegisterModal[item.code]=true">
                Register as a {{ item.desc }}

              <b-modal
                  v-model="confirmRegisterModal[item.code]"
                  centered
                  :title="`Confirm register as ${item.desc}`"
                  @shown="$refs[`confirmRegisterConfirmBtn${item.code}`][0].focus()"
                  :return-focus="$refs[`registerButton${item.code}`]">
                Are you sure you want to register {{ currentDriller.first_name }} {{ currentDriller.surname }} as a {{ item.desc }}?

                  <b-btn
                      variant="primary"
                      @click="confirmRegisterModal[item.code]=false;submitRegistration(item.code)"
                      :ref="`confirmRegisterConfirmBtn${item.code}`"
                      id="register-confirm">
                    Confirm

                    Cancel

Contact Information at Company

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editContact = !editContact"
                  v-if="currentDriller.person_guid && userRoles.registry.edit"> Edit</button>

            <person-edit
              section="contact"
              :record="currentDriller.person_guid"
              v-if="editContact && userRoles.registry.edit"
              @updated="editContact = false; updateRecord()"
              @canceled="editContact = false"></person-edit>

                  Email address: <a :href="`mailto:${currentDriller.contact_email}`">{{ currentDriller.contact_email }}

                  Telephone: {{ currentDriller.contact_tel }}

                  Cell: {{ currentDriller.contact_cell }}

        <person-notes @updated="updateRecord"></person-notes>

Attachments

 0">

                      {{f.name}}

                <person-documents :files="person_files"
                  v-on:fetchFiles="fetchFiles"
                  :guid="currentDriller.person_guid"></person-documents>

                Save

                Cancel

        <change-history
          ref="changeHistory"
          class="my-3"
          v-if="!!currentDriller"
          resource="person"
          :id="currentDriller.person_guid"></change-history>

</template>

<template>

        File Upload In Progress...

        {{file_upload_error}}

        Successfully uploaded all files

{{ currentDriller.first_name }} {{ currentDriller.surname }}

            <api-error :error="error" resetter="SET_ERROR"></api-error>

Personal Information

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editPerson = !editPerson"
                  v-if="currentDriller.person_guid && userRoles.registry.edit"> Edit</button>

            <person-edit
                  section="person"
                  v-if="editPerson && userRoles.registry.edit"
                  :record="currentDriller.person_guid"
                  @updated="editPerson = false; updateRecord()"
                  @canceled="editPerson = false"></person-edit>

                  Surname:

                  {{ currentDriller.surname }}

                  First name:

                  {{ currentDriller.first_name }}

                  Well Driller ORCS:

                  {{ currentDriller.well_driller_orcs_no }}

                  Pump Installer ORCS:

                  {{ currentDriller.pump_installer_orcs_no }}

        <div class="card mb-3"
            v-for="(registration, index) in currentDriller.registrations"
            :key="`registration ${index}`">

{{ registration.activity_description }} Registration

Classifications

                    Classification
                    Register Status
                    Date Registered

                    <tr
                        v-if="item.activity === registration.registries_activity"
                        v-for="(item, index_c) in classifications" :key="`reg ${index} class ${index_c}`">
                      <router-link :to="{
                        name: 'ApplicationDetail',
                        params: { person_guid: currentDriller.person_guid, registration_guid: item.registration_guid, application_guid: item.application_guid } }">
                      {{ item.description }}</router-link>
                      {{ item.status }}
                      {{ item.date }}

                    <application-add
                        class="mb-3"
                        v-on:close="closeApplication(registration.registries_activity)"
                        :value="getApplication(registration.registries_activity)"
                        :activity="registration.registries_activity"
                        mode="edit">
                        <button type="submit" class="btn btn-primary" variant="primary">Save</button>
                        <button type="button" class="btn btn-light" @click="closeApplication(registration.registries_activity)">Cancel</button>
                    </application-add>

                   Add classification

{{ registration.activity_description }} Registration Details

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editRegistration = (editRegistration === (index + 1) ? 0 : (index + 1))"
                  v-if="userRoles.registry.edit">
                   Edit
                  </button>

            <person-edit
              class="mb-4"
              section="registration"
              :record="registration"
              v-if="editRegistration === (index + 1) && userRoles.registry.edit"
              @updated="editRegistration = 0; updateRecord()"
              @canceled="editRegistration = 0"></person-edit>

                  Registration number:

                  {{ registration.registration_no }}

{{ registration.activity_description }} Company Information

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editCompany = (editCompany === (index + 1) ? 0 : (index + 1))"
                  v-if="currentDriller.person_guid && userRoles.registry.edit">
                   Add company
                   Change company
                  </button>

            <person-edit
              section="company"
              :record="registration"
              v-if="editCompany === (index + 1) && userRoles.registry.edit"
              @updated="editCompany = 0; updateRecord()"
              @canceled="editCompany = 0"></person-edit>

                  Company name:

                  {{ registration.organization.name }}

                  Street address:

                  {{ registration.organization.street_address }}

                  City:

                  {{ registration.organization.city }}

                  Province:

                  {{ registration.organization.province_state }}

                  Postal Code:

                  {{ registration.organization.postal_code }}

                  Office number:

                  {{ registration.organization.main_tel }}

                  Cell number:

                  {{ registration.surname }}

                  Fax number:

                  {{ registration.organization.fax_tel }}

                  Email address:

                  {{ registration.organization.email }}

                  Website:

                  {{ registration.organization.website_url }}

              No {{ registration.activity_description }} company.

            <div
                v-for="(item, index) in registrationOptions"
                :key="`unregistered activity ${index}`"
                v-if="!currentDriller.registrations.some(reg => reg.registries_activity === item.code)">
              <b-button variant="primary" class="my-1 registries-action-button" :ref="`registerButton${item.code}`" @click="confirmRegisterModal[item.code]=true">
                Register as a {{ item.desc }}

              <b-modal
                  v-model="confirmRegisterModal[item.code]"
                  centered
                  :title="`Confirm register as ${item.desc}`"
                  @shown="$refs[`confirmRegisterConfirmBtn${item.code}`][0].focus()"
                  :return-focus="$refs[`registerButton${item.code}`]">
                Are you sure you want to register {{ currentDriller.first_name }} {{ currentDriller.surname }} as a {{ item.desc }}?

                  <b-btn
                      variant="primary"
                      @click="confirmRegisterModal[item.code]=false;submitRegistration(item.code)"
                      :ref="`confirmRegisterConfirmBtn${item.code}`"
                      id="register-confirm">
                    Confirm

                    Cancel

Contact Information at Company

                <button
                  class="btn btn-light btn-sm registries-edit-btn"
                  type="button"
                  @click="editContact = !editContact"
                  v-if="currentDriller.person_guid && userRoles.registry.edit"> Edit</button>

            <person-edit
              section="contact"
              :record="currentDriller.person_guid"
              v-if="editContact && userRoles.registry.edit"
              @updated="editContact = false; updateRecord()"
              @canceled="editContact = false"></person-edit>

                  Email address: <a :href="`mailto:${currentDriller.contact_email}`">{{ currentDriller.contact_email }}

                  Telephone: {{ currentDriller.contact_tel }}

                  Cell: {{ currentDriller.contact_cell }}

        <person-notes @updated="updateRecord"></person-notes>

Attachments

 0">

                      {{f.name}}

                <person-documents :files="person_files"
                  v-on:fetchFiles="fetchFiles"
                  :guid="currentDriller.person_guid"></person-documents>

                Save

                Cancel

        <change-history
          ref="changeHistory"
          class="my-3"
          v-if="!!currentDriller"
          resource="person"
          :id="currentDriller.person_guid"></change-history>

</template>


chore(style): initial styling for editor

<script lang="coffee">
import tippy from 'tippy.js'
import 'tippy.js/dist/tippy.css'
import Records from 'shared/services/records'
import _concat from 'lodash/concat'
import _sortBy from 'lodash/sortBy'
import _isString from 'lodash/isString'
import _filter from 'lodash/filter'
import _uniq from 'lodash/uniq'
import _map from 'lodash/map'
import _forEach from 'lodash/forEach'
import FileUploader from 'shared/services/file_uploader'
import FilesList from './files_list.vue'

import { Editor, EditorContent, EditorMenuBar, EditorMenuBubble } from 'tiptap'

import { Blockquote, CodeBlock, HardBreak, Heading, HorizontalRule,
  OrderedList, BulletList, ListItem, TodoItem, TodoList, Bold, Code,
  Italic, Link, Strike, Underline, History, Mention, Placeholder } from 'tiptap-extensions'
import Image from 'shared/tiptap_extentions/image.js'

module.exports =
  props:
    model: Object
    field: String
    placeholder: Object
    helptext: Object
  components:
    EditorContent: EditorContent
    EditorMenuBar: EditorMenuBar
    FilesList: FilesList
    # EditorMenuBubble: EditorMenuBubble

  data: ->
    query: null
    suggestionRange: null
    files: []
    mentionableUserIds: []
    navigatedUserIndex: 0
    insertMention: () => {}
    editor: new Editor
      extensions: [
        new Mention(
          # is called when a suggestion starts
          onEnter: ({ query, range, command, virtualNode }) =>
            # console.log "suggestion started", items, query, range
            @query = query
            @suggestionRange = range
            @insertMention = command
            @renderPopup(virtualNode)
            @fetchMentionable()

          # is called when a suggestion has changed
          onChange: ({query, range, virtualNode}) =>
            # console.log "suggestion changed", items, query, range
            @query = query
            @suggestionRange = range
            @navigatedUserIndex = 0
            @renderPopup(virtualNode)
            @fetchMentionable()

          # is called when a suggestion is cancelled
          onExit: =>
            @query = null
            @suggestionRange = null
            @navigatedUserIndex = 0
            @destroyPopup()

          # is called on every keyDown event while a suggestion is active
          onKeyDown: ({ event }) =>
            # pressing up arrow
            if (event.keyCode == 38)
              @upHandler()
              return true

            # pressing down arrow
            if (event.keyCode == 40)
              @downHandler()
              return true

            # pressing enter
            if (event.keyCode == 13)
              @enterHandler()
              return true

            return false
        ),

        new Blockquote(),
        new BulletList(),
        new CodeBlock(),
        new HardBreak(),
        new Image({attachFile: @attachFile}),
        new Heading({ levels: [1, 2, 3] }),
        new HorizontalRule(),
        new ListItem(),
        new OrderedList(),
        new TodoItem(),
        new TodoList(),
        new Bold(),
        new Code(),
        new Italic(),
        new Link(),
        new Strike(),
        new Underline(),
        new History(),
        new Placeholder({
          emptyClass: 'is-empty',
          emptyNodeText: 'Write something …',
          showOnlyWhenEditable: true,
        })
      ]
      content: @model[@field]
      # onUpdate: ({ getJSON, getHTML }) =>
      #   @model[@field] = getHTML()
      #   @model["#{@field}Format"] = "html"

  computed:
    hasResults: -> @filteredUsers.length
    showSuggestions: -> @query || @hasResults
    filteredUsers: ->
      unsorted = _filter Records.users.collection.chain().find(@mentionableUserIds).data(), (u) =>
        _isString(u.username) &&
        (u.name.toLowerCase().startsWith(@query) or
        (u.username || "").toLowerCase().startsWith(@query) or
        u.name.toLowerCase().includes(" #{@query}"))
      _sortBy(unsorted, (u) -> (0 - Records.events.find(actorId: u.id).length))

  methods:
    removeFile: (name) ->
      @files = _filter @files, (wrapper) -> wrapper.file.name != name

    attachFile: (file) ->
      wrapper = {file: file, key: file.name+file.size, percentComplete: 0, blob: null, xhr: null}
      @files.push(wrapper)
      fileCallbacks = {
        progress: (e) ->
          if (e.lengthComputable)
            wrapper.percentComplete = parseInt(e.loaded / e.total * 100);
      }
      uploader = new FileUploader(fileCallbacks)
      uploader.upload(file).then (blob) => wrapper.blob = blob

    fileSelected: -> _forEach @$refs.filesField.files, @attachFile

    fetchMentionable: ->
      Records.users.fetchMentionable(@query, @model).then (response) =>
        @mentionableUserIds.concat(_.uniq @mentionableUserIds + _.map(response.users, 'id'))

    # navigate to the previous item
    # if it's the first item, navigate to the last one
    upHandler: ->
      @navigatedUserIndex = ((@navigatedUserIndex + @filteredUsers.length) - 1) % @filteredUsers.length

    # navigate to the next item
    # if it's the last item, navigate to the first one
    downHandler: ->
      @navigatedUserIndex = (@navigatedUserIndex + 1) % @filteredUsers.length

    enterHandler: ->
      user = @filteredUsers[@navigatedUserIndex]
      @selectUser(user) if user

    # we have to replace our suggestion text with a mention
    # so it's important to pass also the position of your suggestion text
    selectUser: (user) ->
      @insertMention
        range: @suggestionRange
        attrs:
          id: user.id,
          label: user.name
      @editor.focus()

     # renders a popup with suggestions
     # tiptap provides a virtualNode object for using popper.js (or tippy.js) for popups
     renderPopup: (node) ->
       return if @popup
       @popup = tippy(node, {
         content: @$refs.suggestions,
         trigger: 'mouseenter',
         interactive: true,
         theme: 'dark',
         placement: 'top-start',
         performance: true,
         inertia: true,
         duration: [400, 200],
         showOnInit: true,
         arrow: true,
         arrowType: 'round'
       })

     destroyPopup: ->
       if (@popup)
         @popup.destroyAll()
         @popup = null

  beforeDestroy: ->
    @editor.destroy()
</script>

<template lang="pug">
div
  .editor
    editor-menu-bar(:editor='editor')
      .menubar(slot-scope='{ commands, isActive }')
        v-btn-toggle
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.bold() }", @click='commands.bold')
            v-icon mdi-format-bold
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.italic() }", @click='commands.italic')
            v-icon mdi-format-italic
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.strike() }", @click='commands.strike')
            v-icon mdi-format-strikethrough
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.underline() }", @click='commands.underline')
            v-icon mdi-format-underline
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.underline() }", @click='$refs.filesField.click()')
            v-icon mdi-paperclip
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.code() }", @click='commands.code')
          //-   v-icon mdi-code-braces
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.paragraph() }", @click='commands.paragraph')
          //-   v-icon mdi-format-pilcrow
          //- v-btn.menubar__v-btn(icon @click='commands.todo_list')
          //-   v-icon mdi-format-list-checks
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.heading({ level: 1 }) }", @click='commands.heading({ level: 1 })')
          //-   v-icon mdi-format-header-1
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.heading({ level: 2 }) }", @click='commands.heading({ level: 2 })')
          //-   v-icon mdi-format-header-2
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.heading({ level: 3 }) }", @click='commands.heading({ level: 3 })')
          //-   v-icon mdi-format-header-3
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.bullet_list() }", @click='commands.bullet_list')
          //-   v-icon mdi-format-list-bulleted
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.ordered_list() }", @click='commands.ordered_list')
          //-   v-icon mdi-format-list-numbered
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.blockquote() }", @click='commands.blockquote')
          //-   v-icon mdi-format-quote-closed
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.code_block() }", @click='commands.code_block')
          //-   v-icon mdi-code-tags
          //- v-btn.menubar__v-btn(icon @click='commands.horizontal_rule')
          //-   v-icon mdi-format-page-break
          v-btn.menubar__v-btn(icon @click='commands.undo')
            v-icon mdi-undo
          v-btn.menubar__v-btn(icon @click='commands.redo')
            v-icon mdi-redo
    editor-content.editor__content(:editor='editor').lmo-markdown-wrapper

  .suggestion-list(v-show='showSuggestions', ref='suggestions')
    template(v-if='hasResults')
      .suggestion-list__item(v-for='(user, index) in filteredUsers', :key='user.id', :class="{ 'is-selected': navigatedUserIndex === index }", @click='selectUser(user)')
        | {{ user.name }}
    .suggestion-list__item.is-empty(v-else) No users found

  files-list(:files="files" v-on:removeFile="removeFile")

  form(style="display: block" @change="fileSelected")
    input(ref="filesField" type="file" name="files" multiple=true)
</template>

<style lang="scss">
@import 'variables.scss';

$color-black: #000;
$color-white: #fff;

progress {
  -webkit-appearance: none;
  appearance: none;
  background-color: $color-white;
  border: 1px solid $border-color;
}

progress::-webkit-progress-bar {
  background-color: $color-white;
  border: 1px solid $border-color;
}

progress::-webkit-progress-value {
  background-color: lightblue;
  border: 0;
  transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
}

progress::-moz-progress-bar {
  background-color: lightblue;
  border: 0;
  transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
}

.ProseMirror {
  border-bottom: 1px solid $grey-on-white;
  background-color: $background-color;
  outline: none;
}

.ProseMirror:focus {
  border-bottom: 2px solid yellow;
}

.ProseMirror img {
  display: block;
}

.editor p.is-empty:first-child::before {
  content: attr(data-empty-text);
  float: left;
  color: #aaa;
  pointer-events: none;
  height: 0;
  font-style: italic;
}

.mention {
  background: rgba($color-black, 0.1);
  color: rgba($color-black, 0.6);
  font-size: 0.8rem;
  font-weight: bold;
  border-radius: 5px;
  padding: 0.2rem 0.5rem;
  white-space: nowrap;
}

.mention-suggestion {
  color: rgba($color-black, 0.6);
}

.suggestion-list {
  padding: 0.2rem;
  border: 2px solid rgba($color-black, 0.1);
  font-size: 0.8rem;
  font-weight: bold;
  &__no-results {
    padding: 0.2rem 0.5rem;
  }
  &__item {
    border-radius: 5px;
    padding: 0.2rem 0.5rem;
    margin-bottom: 0.2rem;
    cursor: pointer;
    &:last-child {
      margin-bottom: 0;
    }
    &.is-selected,
    &:hover {
      background-color: rgba($color-white, 0.2);
    }
    &.is-empty {
      opacity: 0.5;
    }
  }
}

.tippy-tooltip.dark-theme {
  background-color: $color-black;
  padding: 0;
  font-size: 1rem;
  text-align: inherit;
  color: $color-white;
  border-radius: 5px;
  .tippy-backdrop {
    display: none;
  }
  .tippy-roundarrow {
    fill: $color-black;
  }
  .tippy-popper[x-placement^=top] & .tippy-arrow {
    border-top-color: $color-black;
  }
  .tippy-popper[x-placement^=bottom] & .tippy-arrow {
    border-bottom-color: $color-black;
  }
  .tippy-popper[x-placement^=left] & .tippy-arrow {
    border-left-color: $color-black;
  }
  .tippy-popper[x-placement^=right] & .tippy-arrow {
    border-right-color: $color-black;
  }
}

ul[data-type="todo_list"] {
  padding-left: 0;
}

li[data-type="todo_item"] {
  display: flex;
  flex-direction: row;
}

.todo-checkbox {
  border: 2px solid $color-black;
  height: 0.9em;
  width: 0.9em;
  box-sizing: border-box;
  margin-right: 10px;
  margin-top: 0.3rem;
  user-select: none;
  -webkit-user-select: none;
  cursor: pointer;
  border-radius: 0.2em;
  background-color: transparent;
  transition: 0.4s background;
}

.todo-content {
  flex: 1;
}

li[data-done="true"] {
  text-decoration: line-through;
}
li[data-done="true"] .todo-checkbox {
  background-color: $color-black;
}
li[data-done="false"] {
  text-decoration: none;
}
</style>

<script lang="coffee">
import tippy from 'tippy.js'
import 'tippy.js/dist/tippy.css'
import Records from 'shared/services/records'
import _concat from 'lodash/concat'
import _sortBy from 'lodash/sortBy'
import _isString from 'lodash/isString'
import _filter from 'lodash/filter'
import _uniq from 'lodash/uniq'
import _map from 'lodash/map'
import _forEach from 'lodash/forEach'
import FileUploader from 'shared/services/file_uploader'
import FilesList from './files_list.vue'

import { Editor, EditorContent, EditorMenuBar, EditorMenuBubble } from 'tiptap'

import { Blockquote, CodeBlock, HardBreak, Heading, HorizontalRule,
  OrderedList, BulletList, ListItem, TodoItem, TodoList, Bold, Code,
  Italic, Link, Strike, Underline, History, Mention } from 'tiptap-extensions'
import Image from 'shared/tiptap_extentions/image.js'

module.exports =
  props:
    model: Object
    field: String
    placeholder: Object
    helptext: Object
  components:
    EditorContent: EditorContent
    EditorMenuBar: EditorMenuBar
    FilesList: FilesList
    # EditorMenuBubble: EditorMenuBubble

  data: ->
    query: null
    suggestionRange: null
    files: []
    mentionableUserIds: []
    navigatedUserIndex: 0
    insertMention: () => {}
    editor: new Editor
      extensions: [
        new Mention(
          # is called when a suggestion starts
          onEnter: ({ query, range, command, virtualNode }) =>
            # console.log "suggestion started", items, query, range
            @query = query
            @suggestionRange = range
            @insertMention = command
            @renderPopup(virtualNode)
            @fetchMentionable()

          # is called when a suggestion has changed
          onChange: ({query, range, virtualNode}) =>
            # console.log "suggestion changed", items, query, range
            @query = query
            @suggestionRange = range
            @navigatedUserIndex = 0
            @renderPopup(virtualNode)
            @fetchMentionable()

          # is called when a suggestion is cancelled
          onExit: =>
            @query = null
            @suggestionRange = null
            @navigatedUserIndex = 0
            @destroyPopup()

          # is called on every keyDown event while a suggestion is active
          onKeyDown: ({ event }) =>
            # pressing up arrow
            if (event.keyCode == 38)
              @upHandler()
              return true

            # pressing down arrow
            if (event.keyCode == 40)
              @downHandler()
              return true

            # pressing enter
            if (event.keyCode == 13)
              @enterHandler()
              return true

            return false
        ),

        new Blockquote(),
        new BulletList(),
        new CodeBlock(),
        new HardBreak(),
        new Image({attachFile: @attachFile}),
        new Heading({ levels: [1, 2, 3] }),
        new HorizontalRule(),
        new ListItem(),
        new OrderedList(),
        new TodoItem(),
        new TodoList(),
        new Bold(),
        new Code(),
        new Italic(),
        new Link(),
        new Strike(),
        new Underline(),
        new History()]
      content: @model[@field]
      # onUpdate: ({ getJSON, getHTML }) =>
      #   @model[@field] = getHTML()
      #   @model["#{@field}Format"] = "html"

  computed:
    hasResults: -> @filteredUsers.length
    showSuggestions: -> @query || @hasResults
    filteredUsers: ->
      unsorted = _filter Records.users.collection.chain().find(@mentionableUserIds).data(), (u) =>
        _isString(u.username) &&
        (u.name.toLowerCase().startsWith(@query) or
        (u.username || "").toLowerCase().startsWith(@query) or
        u.name.toLowerCase().includes(" #{@query}"))
      _sortBy(unsorted, (u) -> (0 - Records.events.find(actorId: u.id).length))

  methods:
    removeFile: (name) ->
      @files = _filter @files, (wrapper) -> wrapper.file.name != name

    attachFile: (file) ->
      wrapper = {file: file, key: file.name+file.size, percentComplete: 0, blob: null, xhr: null}
      @files.push(wrapper)
      fileCallbacks = {
        progress: (e) ->
          if (e.lengthComputable)
            wrapper.percentComplete = parseInt(e.loaded / e.total * 100);
      }
      uploader = new FileUploader(fileCallbacks)
      uploader.upload(file).then (blob) => wrapper.blob = blob

    fileSelected: -> _forEach @$refs.filesField.files, @attachFile

    fetchMentionable: ->
      Records.users.fetchMentionable(@query, @model).then (response) =>
        @mentionableUserIds.concat(_.uniq @mentionableUserIds + _.map(response.users, 'id'))

    # navigate to the previous item
    # if it's the first item, navigate to the last one
    upHandler: ->
      @navigatedUserIndex = ((@navigatedUserIndex + @filteredUsers.length) - 1) % @filteredUsers.length

    # navigate to the next item
    # if it's the last item, navigate to the first one
    downHandler: ->
      @navigatedUserIndex = (@navigatedUserIndex + 1) % @filteredUsers.length

    enterHandler: ->
      user = @filteredUsers[@navigatedUserIndex]
      @selectUser(user) if user

    # we have to replace our suggestion text with a mention
    # so it's important to pass also the position of your suggestion text
    selectUser: (user) ->
      @insertMention
        range: @suggestionRange
        attrs:
          id: user.id,
          label: user.name
      @editor.focus()

     # renders a popup with suggestions
     # tiptap provides a virtualNode object for using popper.js (or tippy.js) for popups
     renderPopup: (node) ->
       return if @popup
       @popup = tippy(node, {
         content: @$refs.suggestions,
         trigger: 'mouseenter',
         interactive: true,
         theme: 'dark',
         placement: 'top-start',
         performance: true,
         inertia: true,
         duration: [400, 200],
         showOnInit: true,
         arrow: true,
         arrowType: 'round'
       })

     destroyPopup: ->
       if (@popup)
         @popup.destroyAll()
         @popup = null

  beforeDestroy: ->
    @editor.destroy()
</script>

<template lang="pug">
div
  .editor
    editor-menu-bar(:editor='editor')
      .menubar(slot-scope='{ commands, isActive }')
        v-btn-toggle
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.bold() }", @click='commands.bold')
            v-icon mdi-format-bold
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.italic() }", @click='commands.italic')
            v-icon mdi-format-italic
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.strike() }", @click='commands.strike')
            v-icon mdi-format-strikethrough
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.underline() }", @click='commands.underline')
            v-icon mdi-format-underline
          v-btn.menubar__button(icon :class="{ 'is-active': isActive.underline() }", @click='$refs.filesField.click()')
            v-icon mdi-paperclip
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.code() }", @click='commands.code')
          //-   v-icon mdi-code-braces
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.paragraph() }", @click='commands.paragraph')
          //-   v-icon mdi-format-pilcrow
          //- v-btn.menubar__v-btn(icon @click='commands.todo_list')
          //-   v-icon mdi-format-list-checks
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.heading({ level: 1 }) }", @click='commands.heading({ level: 1 })')
          //-   v-icon mdi-format-header-1
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.heading({ level: 2 }) }", @click='commands.heading({ level: 2 })')
          //-   v-icon mdi-format-header-2
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.heading({ level: 3 }) }", @click='commands.heading({ level: 3 })')
          //-   v-icon mdi-format-header-3
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.bullet_list() }", @click='commands.bullet_list')
          //-   v-icon mdi-format-list-bulleted
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.ordered_list() }", @click='commands.ordered_list')
          //-   v-icon mdi-format-list-numbered
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.blockquote() }", @click='commands.blockquote')
          //-   v-icon mdi-format-quote-closed
          //- v-btn.menubar__v-btn(icon :class="{ 'is-active': isActive.code_block() }", @click='commands.code_block')
          //-   v-icon mdi-code-tags
          //- v-btn.menubar__v-btn(icon @click='commands.horizontal_rule')
          //-   v-icon mdi-format-page-break
          v-btn.menubar__v-btn(icon @click='commands.undo')
            v-icon mdi-undo
          v-btn.menubar__v-btn(icon @click='commands.redo')
            v-icon mdi-redo
    editor-content.editor__content(:editor='editor').lmo-markdown-wrapper

  .suggestion-list(v-show='showSuggestions', ref='suggestions')
    template(v-if='hasResults')
      .suggestion-list__item(v-for='(user, index) in filteredUsers', :key='user.id', :class="{ 'is-selected': navigatedUserIndex === index }", @click='selectUser(user)')
        | {{ user.name }}
    .suggestion-list__item.is-empty(v-else) No users found

  files-list(:files="files" v-on:removeFile="removeFile")

  form(style="display: block" @change="fileSelected")
    input(ref="filesField" type="file" name="files" multiple=true)
</template>

<style lang="scss">
@import 'variables.scss';

$color-black: #000;
$color-white: #fff;

progress {
  -webkit-appearance: none;
  appearance: none;
  background-color: $color-white;
  border: 1px solid $border-color;
}

progress::-webkit-progress-bar {
  background-color: $color-white;
  border: 1px solid $border-color;
}

progress::-webkit-progress-value {
  background-color: lightblue;
  border: 0;
  transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
}

progress::-moz-progress-bar {
  background-color: lightblue;
  border: 0;
  transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
}

.ProseMirror img {
  display: block;
}

.mention {
  background: rgba($color-black, 0.1);
  color: rgba($color-black, 0.6);
  font-size: 0.8rem;
  font-weight: bold;
  border-radius: 5px;
  padding: 0.2rem 0.5rem;
  white-space: nowrap;
}

.mention-suggestion {
  color: rgba($color-black, 0.6);
}

.suggestion-list {
  padding: 0.2rem;
  border: 2px solid rgba($color-black, 0.1);
  font-size: 0.8rem;
  font-weight: bold;
  &__no-results {
    padding: 0.2rem 0.5rem;
  }
  &__item {
    border-radius: 5px;
    padding: 0.2rem 0.5rem;
    margin-bottom: 0.2rem;
    cursor: pointer;
    &:last-child {
      margin-bottom: 0;
    }
    &.is-selected,
    &:hover {
      background-color: rgba($color-white, 0.2);
    }
    &.is-empty {
      opacity: 0.5;
    }
  }
}

.tippy-tooltip.dark-theme {
  background-color: $color-black;
  padding: 0;
  font-size: 1rem;
  text-align: inherit;
  color: $color-white;
  border-radius: 5px;
  .tippy-backdrop {
    display: none;
  }
  .tippy-roundarrow {
    fill: $color-black;
  }
  .tippy-popper[x-placement^=top] & .tippy-arrow {
    border-top-color: $color-black;
  }
  .tippy-popper[x-placement^=bottom] & .tippy-arrow {
    border-bottom-color: $color-black;
  }
  .tippy-popper[x-placement^=left] & .tippy-arrow {
    border-left-color: $color-black;
  }
  .tippy-popper[x-placement^=right] & .tippy-arrow {
    border-right-color: $color-black;
  }
}

ul[data-type="todo_list"] {
  padding-left: 0;
}

li[data-type="todo_item"] {
  display: flex;
  flex-direction: row;
}

.todo-checkbox {
  border: 2px solid $color-black;
  height: 0.9em;
  width: 0.9em;
  box-sizing: border-box;
  margin-right: 10px;
  margin-top: 0.3rem;
  user-select: none;
  -webkit-user-select: none;
  cursor: pointer;
  border-radius: 0.2em;
  background-color: transparent;
  transition: 0.4s background;
}

.todo-content {
  flex: 1;
}

li[data-done="true"] {
  text-decoration: line-through;
}
li[data-done="true"] .todo-checkbox {
  background-color: $color-black;
}
li[data-done="false"] {
  text-decoration: none;
}
</style>


update donate page

update donate page

<template>

感谢捐赠，但是捐赠并不会让你在该项目上有任何特权。

    购买【世界和我】产品也是支持该项目发展。

    （天猫搜索 livingearth）

</template>


Reviews

Reviews

<template>

        {{ currentApp.appData.image | appName }}

                Stop Application

                Share (copy url to clipboard)

</template>

<template>

        {{ currentApp.appData.image | appName }}

Application settings

                Stop Application

                Share (copy url to clipboard)

</template>


router fix

router fix

<template>
  <f7-page>
    <f7-navbar title="Flexible Routing" back-link="Back" sliding></f7-navbar>
    <f7-block inner inset>

Use multiple ways to fit the routing perfectly to your application needs.

By default, routes for all pages will be created automatically!

    </f7-block>
    <f7-block inner>

Route: {{$route.route}}

Url: {{$route.url}}

Path: {{$route.path}}

Params:

{{key}}: {{value}}

Query:

{{key}}: {{value}}

Hash: {{$route.hash}}

    </f7-block>
    <f7-block inner>
      <f7-link @click="$router.back()">Go back via Router API</f7-link>
    </f7-block>

  </f7-page>
</template>

<template>
  <f7-page>
    <f7-navbar title="Flexible Routing" back-link="Back" sliding></f7-navbar>
    <f7-block inner inset>

Use multiple ways to fit the routing perfectly to your application needs.

By default, routes for all pages will be created automatically!

    </f7-block>
    <f7-block inner>

Route: {{$route.route.pagePath}}

Url: {{$route.url}}

Path: {{$route.path}}

Params:

{{key}}: {{value}}

Query:

{{key}}: {{value}}

Hash: {{$route.hash}}

    </f7-block>
    <f7-block inner>
      <f7-link @click="$router.back()">Go back via Router API</f7-link>
    </f7-block>

  </f7-page>
</template>


style(REC-47) : adjust css on article page

<template>

Pierre dans un pays trop stylé, n'est-ce pas ?

              <chapter-card :chapter="chapter"></chapter-card>

Voici la galerie photo de cet article !

              <photo-card :photo="photo"></photo-card>

</template>


Remove debug console.log

Remove debug console.log

<template>

Register

Login

      <template v-if="register">

      </template>

      Submit

</template>


Pass publicbody form to publicbody-chooser

<template>

    <request-form-breadcrumbs
      :i18n="i18n"
      :multi-request="multiRequest"
      :has-public-bodies="hasPublicBodies"
      :hide-publicbody-chooser="hidePublicbodyChooser"
    />

      <slot name="messages" />

          <fieldset
            v-if="stepSelectPublicBody"
            id="step-publicbody"
            class="mt-5"
          >

              <publicbody-multi-chooser
                name="publicbody"
                :defaultsearch="publicBodySearch"
                :scope="pbScope"
                :config="config"
              >
                <template slot="publicbody-missing">
                  <slot name="publicbody-missing" />
                </template>
              </publicbody-multi-chooser>

                  <slot name="publicbody-legend-title" />
                  <slot name="publicbody-help-text" />

                  <publicbody-chooser
                    name="publicbody"
                    :defaultsearch="publicBodySearch"
                    :scope="pbScope"
                    :form="publicbodyForm"
                    :config="config"
                    :list-view="publicBodyListView"
                  />

                  <slot name="publicbody-missing" />

          </fieldset>

          <fieldset
            v-if="stepReviewPublicBodies && !stepWriteRequest"
            id="step-review-publicbody"
            class="mt-5"
          >
            <pb-multi-review
              name="publicbody"
              :i18n="i18n"
              :scope="pbScope"
            />
          </fieldset>

          <fieldset
            v-if="stepWriteRequest"
            id="step-request"
            class="mt-3"
          >
            <request-form
              :config="config"
              :publicbodies="publicBodies"
              :user="user.id ? user : null"
              :request-form="requestForm"
              :user-form="userForm"
              :hide-publicbody-chooser="hidePublicbodyChooser"
              :hide-full-text="hideFullText"
              :hide-editing="hideEditing"
              :multi-request="multiRequest"
              :default-law="defaultLaw"
              :law-type="lawType"
              :initial-subject.sync="subject"
              :initial-body.sync="body"
              :initial-full-text.sync="fullText"
              :initial-first-name.sync="firstName"
              :initial-last-name.sync="lastName"
              :initial-private.sync="userPrivate"
              @setStepSelectPublicBody="setStepSelectPublicBody"
            >
              <template slot="request-hints">
                <slot name="request-hints" />
              </template>
              <template slot="request-legend-title">
                <slot name="request-legend-title" />
              </template>
            </request-form>

            <user-registration
              :form="userForm"
              :config="config"
              :user="user.id ? user : null"
              :default-law="defaultLaw"
              :initial-email.sync="email"
              :initial-address.sync="address"
              :address-help-text="userForm.fields.address.help_text"
            />

            <request-public
              :form="requestForm"
              :hide-public="hidePublic"
            />

            <user-terms
              v-if="!user.id"
              :form="userForm"
            />
          </fieldset>

          <similar-requests
            v-if="showSimilar && stepWriteRequest"
            :publicbodies="publicBodies"
            :subject="subject"
            :config="config"
          />

          <review-request
            v-if="stepWriteRequest && showReview"
            :i18n="i18n"
            :publicbodies="publicBodies"
            :user="user"
            :default-law="defaultLaw"
            :subject="subject"
            :body="body"
            :full-text="fullText"
            @close="showReview = false"
            @submit="submitting = true"
          />

          <button
            v-if="stepWriteRequest && shouldCheckRequest"
            id="review-button"
            type="button"
            class="btn btn-primary btn-lg mt-3"
            @click="showReview = true"
          >

            {{ i18n.reviewRequest }}
          </button>
          <button
            v-else-if="stepWriteRequest"
            id="send-request-button"
            type="submit"
            class="btn btn-primary btn-lg mt-3"
            @click="submitting = true"
          >

            {{ i18n.submitRequest }}
          </button>
          <button
            v-if="stepWriteRequest && user.id && showDraft"
            type="submit"
            class="btn btn-secondary mt-3"
            name="save_draft"
            value="true"
            @click="submitting = true"
          >

            {{ i18n.saveAsDraft }}
          </button>

</template>

<template>

    <request-form-breadcrumbs
      :i18n="i18n"
      :multi-request="multiRequest"
      :has-public-bodies="hasPublicBodies"
      :hide-publicbody-chooser="hidePublicbodyChooser"
    />

      <slot name="messages" />

          <fieldset
            v-if="stepSelectPublicBody"
            id="step-publicbody"
            class="mt-5"
          >

              <publicbody-multi-chooser
                name="publicbody"
                :defaultsearch="publicBodySearch"
                :scope="pbScope"
                :config="config"
              >
                <template slot="publicbody-missing">
                  <slot name="publicbody-missing" />
                </template>
              </publicbody-multi-chooser>

                  <slot name="publicbody-legend-title" />
                  <slot name="publicbody-help-text" />

                  <publicbody-chooser
                    name="publicbody"
                    :defaultsearch="publicBodySearch"
                    :scope="pbScope"
                    :config="config"
                    :list-view="publicBodyListView"
                  />

                  <slot name="publicbody-missing" />

          </fieldset>

          <fieldset
            v-if="stepReviewPublicBodies && !stepWriteRequest"
            id="step-review-publicbody"
            class="mt-5"
          >
            <pb-multi-review
              name="publicbody"
              :i18n="i18n"
              :scope="pbScope"
            />
          </fieldset>

          <fieldset
            v-if="stepWriteRequest"
            id="step-request"
            class="mt-3"
          >
            <request-form
              :config="config"
              :publicbodies="publicBodies"
              :user="user.id ? user : null"
              :request-form="requestForm"
              :user-form="userForm"
              :hide-publicbody-chooser="hidePublicbodyChooser"
              :hide-full-text="hideFullText"
              :hide-editing="hideEditing"
              :multi-request="multiRequest"
              :default-law="defaultLaw"
              :law-type="lawType"
              :initial-subject.sync="subject"
              :initial-body.sync="body"
              :initial-full-text.sync="fullText"
              :initial-first-name.sync="firstName"
              :initial-last-name.sync="lastName"
              :initial-private.sync="userPrivate"
              @setStepSelectPublicBody="setStepSelectPublicBody"
            >
              <template slot="request-hints">
                <slot name="request-hints" />
              </template>
              <template slot="request-legend-title">
                <slot name="request-legend-title" />
              </template>
            </request-form>

            <user-registration
              :form="userForm"
              :config="config"
              :user="user.id ? user : null"
              :default-law="defaultLaw"
              :initial-email.sync="email"
              :initial-address.sync="address"
              :address-help-text="userForm.fields.address.help_text"
            />

            <request-public
              :form="requestForm"
              :hide-public="hidePublic"
            />

            <user-terms
              v-if="!user.id"
              :form="userForm"
            />
          </fieldset>

          <similar-requests
            v-if="showSimilar && stepWriteRequest"
            :publicbodies="publicBodies"
            :subject="subject"
            :config="config"
          />

          <review-request
            v-if="stepWriteRequest && showReview"
            :i18n="i18n"
            :publicbodies="publicBodies"
            :user="user"
            :default-law="defaultLaw"
            :subject="subject"
            :body="body"
            :full-text="fullText"
            @close="showReview = false"
            @submit="submitting = true"
          />

          <button
            v-if="stepWriteRequest && shouldCheckRequest"
            id="review-button"
            type="button"
            class="btn btn-primary btn-lg mt-3"
            @click="showReview = true"
          >

            {{ i18n.reviewRequest }}
          </button>
          <button
            v-else-if="stepWriteRequest"
            id="send-request-button"
            type="submit"
            class="btn btn-primary btn-lg mt-3"
            @click="submitting = true"
          >

            {{ i18n.submitRequest }}
          </button>
          <button
            v-if="stepWriteRequest && user.id && showDraft"
            type="submit"
            class="btn btn-secondary mt-3"
            name="save_draft"
            value="true"
            @click="submitting = true"
          >

            {{ i18n.saveAsDraft }}
          </button>

</template>


Setting mobile breakpoint to 1 to match content-cards

<template>

  <div>

    <template v-if="popular.length">
      <content-card-group-header
        :header="$tr('popularSectionHeader')"
        :view-more-page-link="popularPageLink"
        :show-view-more="popular.length > trimmedPopular.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedPopular"/>
    </template>

    <template v-if="nextSteps.length">
      <content-card-group-header
        :header="$tr('suggestedNextStepsSectionHeader')"
        :view-more-page-link="nextStepsPageLink"
        :show-view-more="nextSteps.length > trimmedNextSteps.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedNextSteps"/>
    </template>

    <template v-if="resume.length">
      <content-card-group-header
        :header="$tr('resumeSectionHeader')"
        :view-more-page-link="resumePageLink"
        :show-view-more="resume.length > trimmedResume.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedResume"/>
    </template>

    <template v-if="overview.length">
      <content-card-group-header
        :header="$tr('overviewSectionHeader')"
        :view-more-page-link="overviewPageLink"
        :show-view-more="overview.length > trimmedOverview.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedOverview"/>
    </template>

  </div>

</template>

<script>

  import { PageNames } from '../../constants';
  import contentCardGroupCarousel from '../content-card-group-carousel';
  import contentCardGroupGrid from '../content-card-group-grid';
  import contentCardGroupHeader from '../content-card-group-header';
  import responsiveWindow from 'kolibri.coreVue.mixins.responsiveWindow';

  const mobileCarouselLimit = 3;
  const desktopCarouselLimit = 15;

  export default {
    name: 'recommendedPage',
    $trs: {
      popularSectionHeader: 'Most popular',
      suggestedNextStepsSectionHeader: 'Next steps',
      resumeSectionHeader: 'Resume',
      overviewSectionHeader: 'Overview',
    },
    mixins: [responsiveWindow],
    components: {
      contentCardGroupCarousel,
      contentCardGroupGrid,
      contentCardGroupHeader,
    },
    computed: {
      isMobile() {
        return this.windowSize.breakpoint <= 1;
      },
      recommendationDisplay() {
        if (this.isMobile) {
          return contentCardGroupGrid;
        }
        return contentCardGroupCarousel;
      },
      carouselLimit() {
        return this.isMobile ? mobileCarouselLimit : desktopCarouselLimit;
      },
      popularPageLink() {
        return {
          name: PageNames.RECOMMENDED_POPULAR,
          params: { channel_id: this.channelId },
        };
      },
      nextStepsPageLink() {
        return {
          name: PageNames.RECOMMENDED_NEXT_STEPS,
          params: { channel_id: this.channelId },
        };
      },
      resumePageLink() {
        return {
          name: PageNames.RECOMMENDED_RESUME,
          params: { channel_id: this.channelId },
        };
      },
      overviewPageLink() {
        return {
          name: PageNames.RECOMMENDED_OVERVIEW,
          params: { channel_id: this.channelId },
        };
      },
      trimmedPopular() {
        return this.popular.slice(0, this.carouselLimit);
      },
      trimmedNextSteps() {
        return this.nextSteps.slice(0, this.carouselLimit);
      },
      trimmedResume() {
        return this.resume.slice(0, this.carouselLimit);
      },
      trimmedOverview() {
        return this.overview.slice(0, this.carouselLimit);
      },
    },
    methods: {
      genContentLink(id, kind) {
        if (kind === 'topic') {
          return {
            name: PageNames.EXPLORE_TOPIC,
            params: { channel_id: this.channelId, id },
          };
        }
        return {
          name: PageNames.LEARN_CONTENT,
          params: { channel_id: this.channelId, id },
        };
      },
      subHeader(carouselItems, allItems) {
        if (this.needsTrim(allItems.length)) {
          const trArgs = {
            subset: carouselItems.length,
            total: allItems.length,
          };
          return this.$tr('subsetSectionSubHeader', trArgs);
        }
        return this.$tr('sectionSubHeader', { numOfItems: carouselItems.length });
      },
    },
    vuex: {
      getters: {
        channelId: state => state.pageState.channelId,
        nextSteps: state => state.pageState.nextSteps,
        popular: state => state.pageState.popular,
        resume: state => state.pageState.resume,
        overview: state => state.pageState.overview,
      },
    },
  };

</script>

<style lang="stylus" scoped></style>

<template>

  <div>

    <template v-if="popular.length">
      <content-card-group-header
        :header="$tr('popularSectionHeader')"
        :view-more-page-link="popularPageLink"
        :show-view-more="popular.length > trimmedPopular.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedPopular"/>
    </template>

    <template v-if="nextSteps.length">
      <content-card-group-header
        :header="$tr('suggestedNextStepsSectionHeader')"
        :view-more-page-link="nextStepsPageLink"
        :show-view-more="nextSteps.length > trimmedNextSteps.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedNextSteps"/>
    </template>

    <template v-if="resume.length">
      <content-card-group-header
        :header="$tr('resumeSectionHeader')"
        :view-more-page-link="resumePageLink"
        :show-view-more="resume.length > trimmedResume.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedResume"/>
    </template>

    <template v-if="overview.length">
      <content-card-group-header
        :header="$tr('overviewSectionHeader')"
        :view-more-page-link="overviewPageLink"
        :show-view-more="overview.length > trimmedOverview.length"/>
      <component
        :is="recommendationDisplay"
        :gen-content-link="genContentLink"
        :filter="false"
        :contents="trimmedOverview"/>
    </template>

  </div>

</template>

<script>

  import { PageNames } from '../../constants';
  import contentCardGroupCarousel from '../content-card-group-carousel';
  import contentCardGroupGrid from '../content-card-group-grid';
  import contentCardGroupHeader from '../content-card-group-header';
  import responsiveWindow from 'kolibri.coreVue.mixins.responsiveWindow';

  const mobileCarouselLimit = 3;
  const desktopCarouselLimit = 15;

  export default {
    name: 'recommendedPage',
    $trs: {
      popularSectionHeader: 'Most popular',
      suggestedNextStepsSectionHeader: 'Next steps',
      resumeSectionHeader: 'Resume',
      overviewSectionHeader: 'Overview',
    },
    mixins: [responsiveWindow],
    components: {
      contentCardGroupCarousel,
      contentCardGroupGrid,
      contentCardGroupHeader,
    },
    computed: {
      isMobile() {
        return this.windowSize.breakpoint <= 2;
      },
      recommendationDisplay() {
        if (this.isMobile) {
          return contentCardGroupGrid;
        }
        return contentCardGroupCarousel;
      },
      carouselLimit() {
        return this.isMobile ? mobileCarouselLimit : desktopCarouselLimit;
      },
      popularPageLink() {
        return {
          name: PageNames.RECOMMENDED_POPULAR,
          params: { channel_id: this.channelId },
        };
      },
      nextStepsPageLink() {
        return {
          name: PageNames.RECOMMENDED_NEXT_STEPS,
          params: { channel_id: this.channelId },
        };
      },
      resumePageLink() {
        return {
          name: PageNames.RECOMMENDED_RESUME,
          params: { channel_id: this.channelId },
        };
      },
      overviewPageLink() {
        return {
          name: PageNames.RECOMMENDED_OVERVIEW,
          params: { channel_id: this.channelId },
        };
      },
      trimmedPopular() {
        return this.popular.slice(0, this.carouselLimit);
      },
      trimmedNextSteps() {
        return this.nextSteps.slice(0, this.carouselLimit);
      },
      trimmedResume() {
        return this.resume.slice(0, this.carouselLimit);
      },
      trimmedOverview() {
        return this.overview.slice(0, this.carouselLimit);
      },
    },
    methods: {
      genContentLink(id, kind) {
        if (kind === 'topic') {
          return {
            name: PageNames.EXPLORE_TOPIC,
            params: { channel_id: this.channelId, id },
          };
        }
        return {
          name: PageNames.LEARN_CONTENT,
          params: { channel_id: this.channelId, id },
        };
      },
      subHeader(carouselItems, allItems) {
        if (this.needsTrim(allItems.length)) {
          const trArgs = {
            subset: carouselItems.length,
            total: allItems.length,
          };
          return this.$tr('subsetSectionSubHeader', trArgs);
        }
        return this.$tr('sectionSubHeader', { numOfItems: carouselItems.length });
      },
    },
    vuex: {
      getters: {
        channelId: state => state.pageState.channelId,
        nextSteps: state => state.pageState.nextSteps,
        popular: state => state.pageState.popular,
        resume: state => state.pageState.resume,
        overview: state => state.pageState.overview,
      },
    },
  };

</script>

<style lang="stylus" scoped></style>


add showNextBtn computed property

add showNextBtn computed property

<template>

    <page-header :title="title"></page-header>

    <content-render
      v-show="!searchOpen"
      class="content-renderer"
      :id="id"
      :kind="kind"
      :files="files"
      :content-id="contentId"
      :channel-id="channelId"
      :available="available"
      :extra-fields="extraFields">
    </content-render>

    <icon-button v-link="nextContent()" v-if="progress === 1 && showNextBtn" class="next-btn">{{ $tr("nextContent") }}<svg class="right-arrow" src="../icons/arrow_right.svg"></svg></icon-button>

{{ description }}

    <download-button v-if="canDownload" :files="files"></download-button>

    <expandable-content-grid
      class="recommendation-section"
      v-if="pageMode === $options.PageModes.LEARN"
      :title="recommendedText"
      :contents="recommended">
    </expandable-content-grid>

</template>

<template>

    <page-header :title="title"></page-header>

    <content-render
      v-show="!searchOpen"
      class="content-renderer"
      :id="id"
      :kind="kind"
      :files="files"
      :content-id="contentId"
      :channel-id="channelId"
      :available="available"
      :extra-fields="extraFields">
    </content-render>

    <icon-button v-link="nextContent()" v-if="progress === 1" class="next-btn">{{ $tr("nextContent") }}<svg class="right-arrow" src="../icons/arrow_right.svg"></svg></icon-button>

{{ description }}

    <download-button v-if="canDownload" :files="files"></download-button>

    <expandable-content-grid
      class="recommendation-section"
      v-if="pageMode === $options.PageModes.LEARN"
      :title="recommendedText"
      :contents="recommended">
    </expandable-content-grid>

</template>


Remove old file

Remove old file


fix paid cell in spa

fix paid cell in spa

<template lang="pug">
  td(v-if='!sum', :class="notPayedInDate ? 'table-danger' : ''") -
  td(v-else, :class="payedInDate ? 'table-warning' : ''")
    span(:id="popoverId") {{ Number(sum).toFixed() }}
      small.text-warning(v-if="count > 1")  ({{ count }})
    b-popover(
        :target="popoverId", triggers="focus click",
        placement="bottom", @show="getPayments()", @hide="clearPayments()")
      PromisedComponent(:state="promiseState")
        small: ol: li(v-for="payment in payments")
          strong {{ payment.transaction.date }}
          |   {{ payment.transaction.title }}
          |   {{ payment.cost }} zł

</template>
<script>
  import PaymentService from '@/services/payment';
  import linkVm from '@/helpers/linkVm';
  export default {
    props: ['year', 'month', 'member', 'paidmonth', 'dtNow', 'paymentTypeId'],
    data () {
      return {
        promiseState: null,
        payments: []
      }
    },
    changed () {
      let obj = this.paidmonth.months[this.getKey()] || {};
      let key = this.getKey();
      let dt = `${key}-01`;

      this.sum = obj.sum || '';
      this.count = obj.count || 0;
      this.popoverId = `id--${this.member.id}-${key}`;
      this.notPayedInDate = dt <= this.dtNow && this.member.join_date < dt;
      this.payedInDate = dt <= this.dtNow && this.member.join_date > dt;
    },
    methods: {
      getKey () {
        return `${this.year}-${this.month}`;
      },
      getPayments () {
        let promise = PaymentService.get({
          member_id: this.member.id,
          payment_type_id: this.paymentTypeId,
          month: this.key
        });
        linkVm(this, promise)
          .then(resp => { this.payments = resp.data; });
      },
      clearPayments () {
        this.payments = [];
      }
    }
  }
</script>
<style>
  .popover {max-width: none;}
</style>

<template lang="pug">
  td(v-if='!sum', :class="notPayedInDate ? 'table-danger' : ''") -
  td(v-else, :class="PayedInDate ? 'table-warning' : ''")
    span(:id="popoverId") {{ Number(sum).toFixed() }}
      small.text-warning(v-if="count > 1")  ({{ count }})
    b-popover(
        :target="popoverId", triggers="focus click",
        placement="bottom", @show="getPayments()", @hide="clearPayments()")
      PromisedComponent(:state="promiseState")
        small: ol: li(v-for="payment in payments")
          strong {{ payment.transaction.date }}
          |   {{ payment.transaction.title }}
          |   {{ payment.cost }} zł

</template>
<script>
  import PaymentService from '@/services/payment';
  import linkVm from '@/helpers/linkVm';
  export default {
    props: ['year', 'month', 'member', 'paidmonth', 'dtNow', 'paymentTypeId'],
    data () {
      return {
        promiseState: null,
        payments: []
      }
    },
    computed: {
      sum () {
        let obj = this.paidmonth.months[this.getKey()] || {};
        return obj.sum || '';
      },
      count () {
        let obj = this.paidmonth.months[this.getKey()] || {};
        return obj.count || 0;
      },
      popoverId () {
        let key = this.getKey();
        return `id--${this.member.id}-${key}`;
      },
      notPayedInDate () {
        let dt = `${this.getKey()}-01`;
        return dt <= this.dtNow && this.member.join_date < dt;
      },
      PayedInDate () {
        let dt = `${this.getKey()}-01`;
        return dt <= this.dtNow && this.member.join_date > dt;
      }

    },
    methods: {
      getKey () {
        return `${this.year}-${this.month}`;
      },
      getPayments () {
        let promise = PaymentService.get({
          member_id: this.member.id,
          payment_type_id: this.paymentTypeId,
          month: this.key
        });
        linkVm(this, promise)
          .then(resp => { this.payments = resp.data; });
      },
      clearPayments () {
        this.payments = [];
      }
    }
  }
</script>
<style>
  .popover {max-width: none;}
</style>


chore(dev): fix description on model-toggle test with accordeon

<template>

      <q-list bordered separator class="q-mt-lg">
        <q-item-label header>
          Expansion Item - no model
        </q-item-label>
        <q-separator />

        <q-expansion-item
          default-opened
          label="Expansion Item - defaultOpened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          label="Expansion Item"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          default-opened
          label="Expansion Item - defaultOpened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>
      </q-list>

      <q-list bordered separator class="q-mt-lg">
        <q-item-label header>
          Expansion Item - model
        </q-item-label>
        <q-separator />

        <q-expansion-item
          v-model="expModelOpen1"
          default-opened
          :label="`Expansion Item - model [${ expModelOpen1 }] (started as true) - defaultOpened`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          v-model="expModelClosed1"
          default-opened
          :label="`Expansion Item - model [${ expModelClosed1 }] (started as false) - defaultOpened`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          v-model="expModelOpen2"
          :label="`Expansion Item - model [${ expModelOpen2 }] (started as true)`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          v-model="expModelClosed2"
          :label="`Expansion Item - model [${ expModelClosed2 }] (started as false)`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>
      </q-list>

      <q-list bordered separator class="q-mt-lg">
        <q-item-label header>
          Expansion Item - Accordion - no model
        </q-item-label>
        <q-separator />

        <q-expansion-item
          group="group1"
          default-opened
          label="Expansion Item - Accordion (group1) - defaultOpened - should start open even if next defaultOpened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          group="group1"
          label="Expansion Item - Accordion (group1)"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          :group="changingGroup"
          default-opened
          :label="`Expansion Item - Accordion (${changingGroup}) - defaultOpened - should start opened`"
        >
          <q-card>
            <q-card-section>
              <q-radio v-model="changingGroup" val="group1" label="group1" />
              <q-radio v-model="changingGroup" val="group2" label="group2" />
            </q-card-section>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          group="group2"
          default-opened
          label="Expansion Item - Accordion (group2) - defaultOpened - should start opened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>
      </q-list>

      <q-card class="q-mt-lg">
        <q-card-section>
          <q-input v-model="showHideSequence" label="Sequence of show/hide/$nextTick (s/h/t)" />
        </q-card-section>
        <q-card-actions vertical>
          <q-btn :label="`Run on ExpansionItem - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refExpansionItem)" />
          <q-btn :label="`Run on ExpansionItem - model [${seqModelExpansionItem}] - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refExpansionItemModel)" />
          <q-btn :label="`Run on Dialog - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refDialog)" />
          <q-btn :label="`Run on Dialog - model [${seqModelDialog}] - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refDialogModel)" />
        </q-card-actions>

        <q-list separator>
          <q-expansion-item
            ref="refExpansionItem"
            :label="`Expansion Item - no model`"
          >
            <q-card>
              <q-card-section>{{ lorem }}</q-card-section>
            </q-card>
          </q-expansion-item>

          <q-expansion-item
            ref="refExpansionItemModel"
            v-model="seqModelExpansionItem"
            :label="`Expansion Item - model [${seqModelExpansionItem}]`"
          >
            <q-card>
              <q-card-section>{{ lorem }}</q-card-section>
            </q-card>
          </q-expansion-item>
        </q-list>

        <q-dialog ref="refDialog">

            Dialog

        </q-dialog>

        <q-dialog ref="refDialogModel" v-model="seqModelDialog">
          <q-card class="bg-white">
            <q-card-section>
              <q-input v-model="showHideSequence" label="Sequence of show/hide/$nextTick (s/h/t)" />
            </q-card-section>
            <q-card-actions vertical>
              <q-btn :label="`Run on Dialog - model [${seqModelDialog}] - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refDialogModel)" />
            </q-card-actions>
          </q-card>
        </q-dialog>
      </q-card>

</template>

<template>

      <q-list bordered separator class="q-mt-lg">
        <q-item-label header>
          Expansion Item - no model
        </q-item-label>
        <q-separator />

        <q-expansion-item
          default-opened
          label="Expansion Item - defaultOpened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          label="Expansion Item"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          default-opened
          label="Expansion Item - defaultOpened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>
      </q-list>

      <q-list bordered separator class="q-mt-lg">
        <q-item-label header>
          Expansion Item - model
        </q-item-label>
        <q-separator />

        <q-expansion-item
          v-model="expModelOpen1"
          default-opened
          :label="`Expansion Item - model [${ expModelOpen1 }] (started as true) - defaultOpened`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          v-model="expModelClosed1"
          default-opened
          :label="`Expansion Item - model [${ expModelClosed1 }] (started as false) - defaultOpened`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          v-model="expModelOpen2"
          :label="`Expansion Item - model [${ expModelOpen2 }] (started as true)`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          v-model="expModelClosed2"
          :label="`Expansion Item - model [${ expModelClosed2 }] (started as false)`"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>
      </q-list>

      <q-list bordered separator class="q-mt-lg">
        <q-item-label header>
          Expansion Item - Accordion - no model
        </q-item-label>
        <q-separator />

        <q-expansion-item
          group="group1"
          default-opened
          label="Expansion Item - Accordion (group1) - defaultOpened - should start closed because of the next defaultOpened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          group="group1"
          label="Expansion Item - Accordion (group1)"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          :group="changingGroup"
          default-opened
          :label="`Expansion Item - Accordion (${changingGroup}) - defaultOpened - should start opened`"
        >
          <q-card>
            <q-card-section>
              <q-radio v-model="changingGroup" val="group1" label="group1" />
              <q-radio v-model="changingGroup" val="group2" label="group2" />
            </q-card-section>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>

        <q-expansion-item
          group="group2"
          default-opened
          label="Expansion Item - Accordion (group2) - defaultOpened - should start opened"
        >
          <q-card>
            <q-card-section>{{ lorem }}</q-card-section>
          </q-card>
        </q-expansion-item>
      </q-list>

      <q-card class="q-mt-lg">
        <q-card-section>
          <q-input v-model="showHideSequence" label="Sequence of show/hide/$nextTick (s/h/t)" />
        </q-card-section>
        <q-card-actions vertical>
          <q-btn :label="`Run on ExpansionItem - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refExpansionItem)" />
          <q-btn :label="`Run on ExpansionItem - model [${seqModelExpansionItem}] - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refExpansionItemModel)" />
          <q-btn :label="`Run on Dialog - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refDialog)" />
          <q-btn :label="`Run on Dialog - model [${seqModelDialog}] - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refDialogModel)" />
        </q-card-actions>

        <q-list separator>
          <q-expansion-item
            ref="refExpansionItem"
            :label="`Expansion Item - no model`"
          >
            <q-card>
              <q-card-section>{{ lorem }}</q-card-section>
            </q-card>
          </q-expansion-item>

          <q-expansion-item
            ref="refExpansionItemModel"
            v-model="seqModelExpansionItem"
            :label="`Expansion Item - model [${seqModelExpansionItem}]`"
          >
            <q-card>
              <q-card-section>{{ lorem }}</q-card-section>
            </q-card>
          </q-expansion-item>
        </q-list>

        <q-dialog ref="refDialog">

            Dialog

        </q-dialog>

        <q-dialog ref="refDialogModel" v-model="seqModelDialog">
          <q-card class="bg-white">
            <q-card-section>
              <q-input v-model="showHideSequence" label="Sequence of show/hide/$nextTick (s/h/t)" />
            </q-card-section>
            <q-card-actions vertical>
              <q-btn :label="`Run on Dialog - model [${seqModelDialog}] - should end up ${showHideSequenceEndStatus}`" @click="runSequence($refs.refDialogModel)" />
            </q-card-actions>
          </q-card>
        </q-dialog>
      </q-card>

</template>


Update example layout

Update example layout

<template>

Draggable

      <draggable
        v-model="rows"
        tag="v-layout"
        class="row wrap fill-height align-center sortable-list"
        style="background: grey;"
      >
        <v-flex
          v-for="row in rows"
          :key="row.index"
          class="sortable"
          xs12
          my-2
          style="background: red"
        >
          <draggable
            :list="row.items"
            tag="v-layout"
            :group="{ name: 'row' }"
            class="row wrap justify-space-around"
          >
            <v-flex
              v-for="item in row.items"
              :key="item.title"
              xs4
              pa-3
              class="row-v"
            >
              <v-card style="height: 100px;">{{ item.title }}</v-card>
            </v-flex>
          </draggable>
        </v-flex>
      </draggable>

    <rawDisplayer
      class="col-3"
      :value="rows"
      title="List"
    />

</template>

<template>

Draggable

      <draggable
        v-model="rows"
        tag="v-layout"
        class="row wrap fill-height align-center sortable-list"
        style="background: grey;"
      >
        <v-flex
          v-for="row in rows"
          :key="row.index"
          class="sortable"
          xs12
          my-2
          style="background: red"
        >
          <draggable
            :list="row.items"
            tag="v-layout"
            :group="{ name: 'row' }"
            class="row wrap justify-space-around"
          >
            <v-flex
              v-for="item in row.items"
              :key="item.title"
              xs4
              pa-3
              class="row"
            >
              <v-card style="height: 100px;">{{ item.title }}</v-card>
            </v-flex>
          </draggable>
        </v-flex>
      </draggable>

    <rawDisplayer class="col-3" :value="rows" title="List" />

</template>