11<script setup lang="ts">
2+ import _ from ' lodash'
3+ import type { Ref } from ' vue'
24import StdTable from ' @/components/StdDesign/StdDataDisplay/StdTable.vue'
35import type Curd from ' @/api/curd'
46import type { Column } from ' @/components/StdDesign/types'
57
68const props = defineProps <{
7- selectedKey: string | number
8- value? : string | number
9- recordValueIndex: string
9+ label? : string
10+ selectedKey: number | number [] | undefined | null
1011 selectionType: ' radio' | ' checkbox'
12+ recordValueIndex: string // to index the value of the record
1113 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1214 api: Curd <any >
1315 columns: Column []
1416 disableSearch? : boolean
1517 // eslint-disable-next-line @typescript-eslint/no-explicit-any
16- getParams: any
18+ getParams? : any
1719 description? : string
20+ errorMessages? : string
21+ itemKey? : string // default: id
22+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23+ value? : any | any []
24+ disabled? : boolean
25+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26+ valueApi? : Curd <any >
1827}>()
1928
20- const emit = defineEmits ([' update:selectedKey' , ' changeSelect' ])
29+ const emit = defineEmits ([' update:selectedKey' ])
30+
31+ const getParams = computed (() => {
32+ return props .getParams
33+ })
2134
2235const visible = ref (false )
23- const M_value = ref (' ' )
36+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37+ const M_values = ref ([]) as any
38+
39+ const init = _ .debounce (_init , 500 , {
40+ leading: true ,
41+ trailing: false ,
42+ })
2443
2544onMounted (() => {
2645 init ()
2746})
2847
29- const selected = ref ([])
3048// eslint-disable-next-line @typescript-eslint/no-explicit-any
31- const record: any = reactive ({})
32-
33- function init() {
34- if (props .selectedKey && ! props .value && props .selectionType === ' radio' ) {
35- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36- props .api .get (props .selectedKey ).then ((r : any ) => {
37- Object .assign (record , r )
38- M_value .value = r [props .recordValueIndex ]
39- })
49+ const records = ref ([]) as Ref <any []>
50+
51+ async function _init() {
52+ // valueApi is used to fetch items that are using itemKey as index value
53+ const api = props .valueApi || props .api
54+
55+ M_values .value = []
56+
57+ if (props .selectionType === ' radio' ) {
58+ // M_values.value = [props.value] // not init value, we need to fetch them from api
59+ if (! props .value && props .selectedKey ) {
60+ api .get (props .selectedKey , props .getParams ).then (r => {
61+ M_values .value = [r ]
62+ records .value = [r ]
63+ })
64+ }
65+ }
66+ else if (typeof props .selectedKey === ' object' ) {
67+ M_values .value = props .value || []
68+
69+ // not init value, we need to fetch them from api
70+ if (! props .value && (props .selectedKey ?.length || 0 ) > 0 ) {
71+ api .get_list ({
72+ ... props .getParams ,
73+ id: props .selectedKey ,
74+ }).then (r => {
75+ M_values .value = r .data
76+ records .value = r .data
77+ })
78+ }
4079 }
4180}
4281
4382function show() {
44- visible .value = true
45- }
46- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47- function onSelect(_selected : any ) {
48- selected .value = _selected
49- }
50- // eslint-disable-next-line @typescript-eslint/no-explicit-any
51- function onSelectedRecord(r : any ) {
52- Object .assign (record , r )
83+ if (! props .disabled )
84+ visible .value = true
5385}
5486
55- function ok() {
56- visible .value = false
57- if (props .selectionType === ' radio' )
58- emit (' update:selectedKey' , selected .value [0 ])
59- else
60- emit (' update:selectedKey' , selected .value )
87+ const selectedKeyBuffer = ref ()
6188
62- M_value .value = record [props .recordValueIndex ]
63- emit (' changeSelect' , record )
64- }
89+ if (props .selectionType === ' radio' )
90+ selectedKeyBuffer .value = [props .selectedKey ]
91+ else
92+ selectedKeyBuffer .value = props .selectedKey
6593
66- watch (props , () => {
67- if (! props ?.selectedKey )
68- M_value .value = ' '
69- else if (props .value )
70- M_value .value = props .value as string
71- else
72- init ()
73- })
74-
75- const _selectedKey = computed ({
94+ const computedSelectedKeys = computed ({
7695 get() {
77- return props .selectedKey
96+ if (props .selectionType === ' radio' )
97+ return [selectedKeyBuffer .value ]
98+ else
99+ return selectedKeyBuffer .value
78100 },
79101 set(v ) {
80- emit ( ' update:selectedKey ' , v )
102+ selectedKeyBuffer . value = v
81103 },
82104})
105+
106+ onMounted (() => {
107+ if (props .selectedKey === undefined || props .selectedKey === null ) {
108+ if (props .selectionType === ' radio' )
109+ emit (' update:selectedKey' , ' ' )
110+ else
111+ emit (' update:selectedKey' , [])
112+ }
113+ })
114+
115+ async function ok() {
116+ visible .value = false
117+ emit (' update:selectedKey' , selectedKeyBuffer .value )
118+
119+ M_values .value = _ .clone (records .value )
120+ }
121+
122+ watchEffect (() => {
123+ init ()
124+ })
125+
126+ // function clear() {
127+ // M_values.value = []
128+ // emit('update:selectedKey', '')
129+ // }
83130 </script >
84131
85132<template >
@@ -88,19 +135,23 @@ const _selectedKey = computed({
88135 class =" std-selector"
89136 @click =" show"
90137 >
91- <AInput
92- v-model =" _selectedKey"
93- disabled
94- hidden
95- />
96- <div class =" value" >
97- {{ M_value }}
138+ <div class =" chips-container" >
139+ <ATag
140+ v-for =" (chipText, index) in M_values"
141+ :key =" index"
142+ class =" mr-1"
143+ color =" orange"
144+ :bordered =" false"
145+ @click =" show"
146+ >
147+ {{ chipText?.[recordValueIndex] }}
148+ </ATag >
98149 </div >
99150 <AModal
100151 :mask =" false"
101152 :open =" visible"
102153 :cancel-text =" $gettext('Cancel')"
103- :ok-text =" $gettext('OK ')"
154+ :ok-text =" $gettext('Ok ')"
104155 :title =" $gettext('Selector')"
105156 :width =" 800"
106157 destroy-on-close
@@ -109,15 +160,16 @@ const _selectedKey = computed({
109160 >
110161 {{ description }}
111162 <StdTable
163+ v-model:selected-row-keys =" computedSelectedKeys"
164+ v-model:selected-rows =" records"
112165 :api =" api"
113166 :columns =" columns"
114167 :disable-search =" disableSearch"
115168 pithy
169+ :row-key =" itemKey"
116170 :get-params =" getParams"
117171 :selection-type =" selectionType"
118172 disable-query-params
119- @on-selected =" onSelect"
120- @on-selected-record =" onSelectedRecord"
121173 />
122174 </AModal >
123175 </div >
@@ -126,26 +178,34 @@ const _selectedKey = computed({
126178
127179<style lang="less" scoped>
128180.std-selector-container {
129- height : 39.9px ;
181+ min- height : 39.9px ;
130182 display : flex ;
131183 align-items : flex-start ;
132184
133185 .std-selector {
186+ overflow-y : auto ;
134187 box-sizing : border-box ;
135188 font-variant : tabular-nums ;
136189 list-style : none ;
137190 font-feature-settings : ' tnum' ;
138- height : 32px ;
191+ min-height : 32px ;
192+ max-height : 100px ;
139193 padding : 4px 11px ;
140194 font-size : 14px ;
141195 line-height : 1.5 ;
142196 background-image : none ;
143197 border : 1px solid #d9d9d9 ;
144198 border-radius : 4px ;
145199 transition : all 0.3s ;
146- margin : 0 10px 0 0 ;
200+ // margin: 0 10px 0 0;
147201 cursor : pointer ;
148202 min-width : 180px ;
149203 }
150204}
205+
206+ .chips-container {
207+ span {
208+ margin : 2px ;
209+ }
210+ }
151211 </style >
0 commit comments