import { Vue , Component , Prop , Watch } from 'vue-property-decorator' ; import FormSelect from '@/components/form-select/form-select' ; import _ from 'lodash' ; import $ from 'jquery' ; import ns from '@/store/namespaces' ; import { MessageModalOptions } from '@/store/modals/types' ; import { ColumnSelectOption } from '@/components/column-select/column-select' ; const NUM_CLUTTER_COLUMNS = 20 ; export const getColumnListInputType = ( columns , prevColumns ) : string => { const columnsSorted = columns . concat ( ) . sort ( ) ; if ( columnsSorted . length && _ . isEqual ( columnsSorted , prevColumns . concat ( ) . sort ( ) ) ) { return 'order columns' ; } else if ( columns . length - prevColumns . length === 1 ) { return 'add column' ; } else if ( columns . length - prevColumns . length === - 1 ) { return 'remove column' ; } else if ( columns . length && ! prevColumns . length ) { return 'all columns' ; } else if ( ! columns . length && prevColumns . length ) { return 'clear columns' ; } else { return 'select columns' ; } } ; @ Component ( { components : { FormSelect } } ) export default class ColumnList extends Vue { @ ns . modals . Mutation ( 'openMessageModal' ) private openMessageModal ! : ( options : MessageModalOptions ) => void ; @ Prop ( ) private columns ! : ColumnSelectOption [ ] ; @ Prop ( { type : Array } ) private value ! : number [ ] ; private selected : number [ ] = [ ] ; private prevSelected : number [ ] = [ ] ; private beforeOrderSelected : number [ ] = [ ] ; private isSorting = false ; private created ( ) { this . selected = this . value . concat ( ) . filter ( index => index < this . columns . length ) ; this . prevSelected = this . selected . concat ( ) ; } @ Watch ( 'value' ) private onValueChange ( ) { if ( this . isSorting ) { return ; } this . prevSelected = this . selected = this . value ; } private mounted ( ) { const $el = $ ( this . $el ) ; const getNewOrder = ( evt , ui ) : number [ ] => { const tags = $el . find ( '.selected-tag' ) . not ( '.ui-sortable-helper' ) ; const values = [ ] ; for ( const tag of tags ) { const $tag = $ ( tag ) ; if ( $tag . hasClass ( 'ui-sortable-placeholder' ) ) { values . push ( + ( ui . item . attr ( 'id' ) as string ) ) ; } else { values . push ( + ( $ ( tag ) . attr ( 'id' ) as string ) ) ; } } const newSelected = values ; return newSelected ; } ; $el . find ( '.dropdown-toggle' ) . sortable ( { items : '> .selected-tag' , start : ( ) => { this . beforeOrderSelected = this . selected . concat ( ) ; const tags = $el . find ( '.selected-tag' ) . not ( '.ui-sortable-placeholder' ) ; _ . each ( tags , ( tag , index ) => { $ ( tag ) . attr ( 'id' , this . selected [ index ] . toString ( ) ) ; } ) ; this . isSorting = true ; } , change : ( evt , ui ) => { this . $emit ( 'input' , getNewOrder ( evt , ui ) , this . prevSelected ) ; } , stop : ( evt , ui ) => { this . isSorting = false ; this . selected = getNewOrder ( evt , ui ) ; this . prevSelected = this . beforeOrderSelected ; this . onSelect ( ) ; return false ; } } ) ; } private clear ( ) { this . selected = [ ] ; this . onSelect ( ) ; } private all ( ) { const select = ( ) => { const selected = this . columns . map ( column => column . disabled ? null : column . value ) . filter ( column => column !== null ) as number [ ] ; this . selected = selected ; this . onSelect ( ) ; } ; if ( this . columns . length > NUM_CLUTTER_COLUMNS ) { this . openMessageModal ( { title : 'Too Many Columns' , message : `You have selected ${ this . columns . length } columns that may cause clutter. Do you want to proceed?` , onConfirm : select } ) ; return ; } select ( ) ; } private sort ( ) { this . selected = this . selected . concat ( ) . sort ( ( a , b ) => a - b ) ; this . onSelect ( ) ; } private onChildSelect ( selected ) { this . selected = selected ; this . onSelect ( ) ; } private onSelect ( ) { if ( ! _ . isEqual ( this . selected , this . prevSelected ) ) { this . $emit ( 'input' , this . selected , this . prevSelected ) ; this . $emit ( 'change' , this . selected , this . prevSelected ) ; this . prevSelected = this . selected . concat ( ) ; } } }