Replace some select components with CInputSelect
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
"v-photoswipe": "^1.0.3-1",
|
||||
"vue-color": "^2.8.1",
|
||||
"vue-echarts": "^6.2.3",
|
||||
"vue-select": "^3.4.0",
|
||||
"vue-select": "3.20.2",
|
||||
"vue-swatches": "^1.0.4",
|
||||
"vue2-ace-editor": "^0.0.15",
|
||||
"vue2-leaflet": "^2.7.1",
|
||||
|
||||
@@ -20,6 +20,7 @@ export {
|
||||
CInputColorPicker,
|
||||
CAceEditor,
|
||||
CButtonSubmit,
|
||||
CInputSelect,
|
||||
} from './input'
|
||||
|
||||
export {
|
||||
|
||||
@@ -30,22 +30,13 @@
|
||||
class="align-middle"
|
||||
style="min-width: 250px;"
|
||||
>
|
||||
<b-form-select
|
||||
<c-input-select
|
||||
v-model="column.field"
|
||||
:options="availableFields"
|
||||
text-field="label"
|
||||
value-field="name"
|
||||
:reduce="o => o.name"
|
||||
:placeholder="labels.none"
|
||||
class="rounded"
|
||||
>
|
||||
<template #first>
|
||||
<b-form-select-option
|
||||
:value="undefined"
|
||||
disabled
|
||||
>
|
||||
{{ labels.none }}
|
||||
</b-form-select-option>
|
||||
</template>
|
||||
</b-form-select>
|
||||
/>
|
||||
</td>
|
||||
|
||||
<td
|
||||
@@ -117,10 +108,12 @@
|
||||
|
||||
<script>
|
||||
import Draggable from 'vuedraggable'
|
||||
import CInputSelect from './CInputSelect.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Draggable,
|
||||
CInputSelect,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<vue-select
|
||||
v-model="_value"
|
||||
v-bind="$attrs"
|
||||
:clearable="clearable"
|
||||
:options="options"
|
||||
:searchable="searchable"
|
||||
:calculate-position="calculateDropdownPosition"
|
||||
:append-to-body="appendToBody"
|
||||
class="bg-white rounded"
|
||||
:class="sizeClass"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<template
|
||||
v-for="(_, name) in $scopedSlots"
|
||||
v-slot:[name]="data"
|
||||
>
|
||||
<slot
|
||||
:name="name"
|
||||
v-bind="data"
|
||||
/>
|
||||
</template>
|
||||
</vue-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { VueSelect } from 'vue-select'
|
||||
import { createPopper } from '@popperjs/core'
|
||||
import 'vue-select/dist/vue-select.css';
|
||||
|
||||
export default {
|
||||
name: 'CInputSelect',
|
||||
|
||||
components: {
|
||||
VueSelect,
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array],
|
||||
default: () => '',
|
||||
},
|
||||
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
},
|
||||
},
|
||||
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
||||
appendToBody: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
|
||||
defaultValue: {
|
||||
type: [String, Array],
|
||||
default: () => '',
|
||||
},
|
||||
|
||||
size: {
|
||||
type: String,
|
||||
default: 'md',
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
_value: {
|
||||
get () {
|
||||
const fallbackValue = this.$attrs.multiple ? [] : ''
|
||||
return !!this.defaultValue && (this.value === this.defaultValue) ? fallbackValue : this.value
|
||||
},
|
||||
|
||||
set (v) {
|
||||
this.$emit('input', !v ? this.defaultValue : v)
|
||||
}
|
||||
},
|
||||
|
||||
sizeClass () {
|
||||
return this.size === 'sm' ? 'c-input-sm' : this.size === 'lg' ? 'c-input-lg' : ''
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
calculateDropdownPosition (dropdownList, component, { width }) {
|
||||
/**
|
||||
* We need to explicitly define the dropdown width since
|
||||
* it is usually inherited from the parent with CSS.
|
||||
*/
|
||||
dropdownList.style.width = width
|
||||
|
||||
/**
|
||||
* Here we position the dropdownList relative to the $refs.toggle Element.
|
||||
*
|
||||
* The 'offset' modifier aligns the dropdown so that the $refs.toggle and
|
||||
* the dropdownList overlap by 1 pixel.
|
||||
*
|
||||
* The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
|
||||
* wrapper so that we can set some styles for when the dropdown is placed
|
||||
* above.
|
||||
*/
|
||||
const popper = createPopper(component.$refs.toggle, dropdownList, {
|
||||
placement: 'bottom',
|
||||
modifiers: [
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, -1],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'toggleClass',
|
||||
enabled: true,
|
||||
phase: 'write',
|
||||
fn ({ state }) {
|
||||
component.$el.classList.toggle('drop-up', state.placement === 'top')
|
||||
},
|
||||
}],
|
||||
})
|
||||
|
||||
/**
|
||||
* To prevent memory leaks Popper needs to be destroyed.
|
||||
* If you return function, it will be called just before dropdown is removed from DOM.
|
||||
*/
|
||||
return () => popper.destroy()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.v-select {
|
||||
min-width: auto;
|
||||
position: relative;
|
||||
-ms-flex: 1 1 auto;
|
||||
flex: 1 1 auto;
|
||||
margin-bottom: 0;
|
||||
font-size: .9rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
.vs__selected-options {
|
||||
// do not allow growing
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.vs__selected {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vs__search {
|
||||
margin-top: 0.375rem;
|
||||
}
|
||||
|
||||
&:not(.vs--open) .vs__selected + .vs__search {
|
||||
// force this to not use any space
|
||||
// we still need it to be rendered for the focus
|
||||
width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.vs__dropdown-toggle {
|
||||
padding: 0.375rem;
|
||||
padding-top: 0;
|
||||
border-width: 2px;
|
||||
border-color: var(--light);
|
||||
|
||||
.vs__selected {
|
||||
margin-top: 0.375rem;
|
||||
}
|
||||
|
||||
.vs__actions {
|
||||
padding-top: 0.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
.vs__clear,
|
||||
.vs__open-indicator {
|
||||
fill: var(--gray-900);
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.vs__clear {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
margin-right: 8px
|
||||
}
|
||||
}
|
||||
|
||||
.vs__dropdown-menu {
|
||||
z-index: 1090;
|
||||
}
|
||||
|
||||
.c-input-sm {
|
||||
height: calc(1.5em + .5rem + 2px);
|
||||
padding-top: .25rem;
|
||||
padding-bottom: .25rem;
|
||||
padding-left: .5rem;
|
||||
font-size: .875rem;
|
||||
}
|
||||
.c-input-lg {
|
||||
height: calc(1.5em + 1rem + 2px);
|
||||
padding-top: .5rem;
|
||||
padding-bottom: .5rem;
|
||||
padding-left: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -10,4 +10,5 @@ export { default as CInputColorPicker } from './CInputColorPicker.vue'
|
||||
export { default as CAceEditor } from './CAceEditor.vue'
|
||||
export {
|
||||
CButtonSubmit
|
||||
} from './button'
|
||||
} from './button'
|
||||
export { default as CInputSelect } from './CInputSelect.vue'
|
||||
|
||||
@@ -43,17 +43,16 @@
|
||||
:label="labels.edit.label"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<vue-select
|
||||
v-model="currentRole"
|
||||
<c-input-select
|
||||
v-model="currentRoleID"
|
||||
data-test-id="select-user-list-roles"
|
||||
key="roleID"
|
||||
label="name"
|
||||
:clearable="false"
|
||||
:options="roles"
|
||||
:get-option-key="getOptionRoleKey"
|
||||
:reduce="o => o.roleID"
|
||||
append-to-body
|
||||
:calculate-position="calculateDropdownPosition"
|
||||
class="h-100 bg-white rounded"
|
||||
@input="onRoleChange"
|
||||
/>
|
||||
</b-form-group>
|
||||
@@ -75,6 +74,7 @@
|
||||
>
|
||||
{{ n }}
|
||||
</label>
|
||||
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'plus']"
|
||||
class="text-secondary rotate mt-1"
|
||||
@@ -105,6 +105,7 @@
|
||||
style="min-height: 50vh;"
|
||||
>
|
||||
<b-spinner />
|
||||
|
||||
<div>
|
||||
{{ labels.loading }}
|
||||
</div>
|
||||
@@ -122,6 +123,7 @@
|
||||
:rules.sync="rules"
|
||||
/>
|
||||
</b-col>
|
||||
|
||||
<b-col
|
||||
v-for="(e, i) in evaluate"
|
||||
:key="i"
|
||||
@@ -142,11 +144,13 @@
|
||||
:icon="['fas', 'question']"
|
||||
class="text-secondary"
|
||||
/>
|
||||
|
||||
<font-awesome-icon
|
||||
v-else-if="r.access === 'allow'"
|
||||
:icon="['fas', 'check']"
|
||||
class="text-success"
|
||||
/>
|
||||
|
||||
<font-awesome-icon
|
||||
v-else
|
||||
:icon="['fas', 'times']"
|
||||
@@ -191,7 +195,7 @@
|
||||
label-class="text-primary"
|
||||
class="mb-0"
|
||||
>
|
||||
<vue-select
|
||||
<c-input-select
|
||||
data-test-id="select-role"
|
||||
key="roleID"
|
||||
v-model="add.roleID"
|
||||
@@ -202,8 +206,6 @@
|
||||
clearable
|
||||
:disabled="!!add.userID"
|
||||
:placeholder="labels.add.role.placeholder"
|
||||
:calculate-position="calculateDropdownPosition"
|
||||
class="bg-white rounded"
|
||||
/>
|
||||
</b-form-group>
|
||||
|
||||
@@ -212,7 +214,7 @@
|
||||
label-class="text-primary"
|
||||
class="mt-3 mb-0"
|
||||
>
|
||||
<vue-select
|
||||
<c-input-select
|
||||
data-test-id="select-user"
|
||||
key="userID"
|
||||
v-model="add.userID"
|
||||
@@ -220,11 +222,10 @@
|
||||
:options="userOptions"
|
||||
:get-option-label="getUserLabel"
|
||||
:get-option-key="getOptionUserKey"
|
||||
:reduce="o => o.userID"
|
||||
label="name"
|
||||
clearable
|
||||
:placeholder="labels.add.user.placeholder"
|
||||
:calculate-position="calculateDropdownPosition"
|
||||
class="bg-white rounded"
|
||||
@search="searchUsers"
|
||||
/>
|
||||
</b-form-group>
|
||||
@@ -243,9 +244,8 @@
|
||||
</template>
|
||||
<script lang="js">
|
||||
import { modalOpenEventName, split } from './def.ts'
|
||||
import { VueSelect } from 'vue-select'
|
||||
import CInputSelect from '../input/CInputSelect.vue'
|
||||
import Rules from './form/Rules.vue'
|
||||
import calculateDropdownPosition from '../../mixins/vue-select-position'
|
||||
|
||||
export default {
|
||||
i18nOptions: {
|
||||
@@ -254,13 +254,9 @@ export default {
|
||||
|
||||
components: {
|
||||
Rules,
|
||||
VueSelect,
|
||||
CInputSelect,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
calculateDropdownPosition
|
||||
],
|
||||
|
||||
props: {
|
||||
labels: {
|
||||
required: false,
|
||||
@@ -291,8 +287,7 @@ export default {
|
||||
// List of all available roles
|
||||
roles: [],
|
||||
|
||||
// Current role object
|
||||
currentRole: undefined,
|
||||
currentRoleID: undefined,
|
||||
|
||||
evaluate: [],
|
||||
|
||||
@@ -370,8 +365,8 @@ export default {
|
||||
this.fetchPermissions().then(() => {
|
||||
if (!this.roles.length) {
|
||||
return this.fetchRoles()
|
||||
} else if (this.currentRole) {
|
||||
const { roleID } = this.currentRole
|
||||
} else if (this.currentRoleID) {
|
||||
const roleID = this.currentRoleID
|
||||
this.processing = true
|
||||
|
||||
return this.fetchRules(roleID).then(() => {
|
||||
@@ -404,7 +399,7 @@ export default {
|
||||
this.target = undefined
|
||||
},
|
||||
|
||||
onRoleChange ({ roleID }) {
|
||||
onRoleChange (roleID) {
|
||||
this.fetchRules(roleID)
|
||||
},
|
||||
|
||||
@@ -412,7 +407,7 @@ export default {
|
||||
this.processing = true
|
||||
|
||||
const rules = this.collectChangedRules()
|
||||
const { roleID } = this.currentRole
|
||||
const roleID = this.currentRoleID
|
||||
|
||||
this.api.permissionsUpdate({ roleID, rules }).then(() => {
|
||||
this.fetchRules(roleID)
|
||||
@@ -455,8 +450,8 @@ export default {
|
||||
.sort((a, b) => a.roleID.localeCompare(b.roleID))
|
||||
|
||||
if (this.roles.length > 0) {
|
||||
this.currentRole = this.roles[0]
|
||||
this.onRoleChange(this.currentRole)
|
||||
this.currentRoleID = this.roles[0].roleID
|
||||
this.onRoleChange(this.currentRoleID)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.processing = false
|
||||
@@ -490,7 +485,7 @@ export default {
|
||||
},
|
||||
|
||||
onAddEval () {
|
||||
const { userID } = this.add.userID || {}
|
||||
const userID = this.add.userID || {}
|
||||
let { roleID = [] } = this.add
|
||||
roleID = roleID.map(({ roleID }) => roleID)
|
||||
|
||||
@@ -513,9 +508,9 @@ export default {
|
||||
this.evaluate.splice(i, 1)
|
||||
},
|
||||
|
||||
getEvalName ({ roleID, userID }) {
|
||||
getEvalName ({ userID, roleID }) {
|
||||
if (userID) {
|
||||
const { name, username, email, handle } = userID
|
||||
const { name, username, email, handle } = this.userOptions.find(({ userID: id }) => id === userID) || {}
|
||||
return [name || username || email || handle || userID || '']
|
||||
} else {
|
||||
return roleID.map(({ name }) => name)
|
||||
@@ -615,7 +610,7 @@ export default {
|
||||
this.permissions = []
|
||||
this.rules = []
|
||||
this.roles = []
|
||||
this.currentRole = undefined
|
||||
this.currentRoleID = undefined
|
||||
this.evaluate = []
|
||||
this.add = {}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<vue-select
|
||||
<c-input-select
|
||||
data-test-id="select-sens-lvl"
|
||||
key="type"
|
||||
:value="_value"
|
||||
@@ -10,26 +10,19 @@
|
||||
:placeholder="placeholder"
|
||||
:reduce="l => l.sensitivityLevelID"
|
||||
append-to-body
|
||||
:calculate-position="calculateDropdownPosition"
|
||||
class="bg-white rounded"
|
||||
@input="onInput"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NoID } from '@cortezaproject/corteza-js'
|
||||
import { VueSelect } from 'vue-select'
|
||||
import calculateDropdownPosition from '../../mixins/vue-select-position'
|
||||
import CInputSelect from '../input/CInputSelect.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VueSelect,
|
||||
CInputSelect,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
calculateDropdownPosition
|
||||
],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div
|
||||
class="text-center m-2"
|
||||
>
|
||||
<vue-select
|
||||
<c-input-select
|
||||
v-model="value"
|
||||
:options="options"
|
||||
:get-option-key="getOptionKey"
|
||||
@@ -17,7 +17,7 @@
|
||||
option-text="label"
|
||||
placeholder="Select record"
|
||||
:filterable="false"
|
||||
class="bg-white w-100 mb-3 rounded"
|
||||
class="w-100 mb-3"
|
||||
@search="search"
|
||||
>
|
||||
<c-pagination
|
||||
@@ -28,7 +28,7 @@
|
||||
@prev="goToPage(false)"
|
||||
@next="goToPage(true)"
|
||||
/>
|
||||
</vue-select>
|
||||
</c-input-select>
|
||||
|
||||
<b-button
|
||||
@click="$emit('submit', { value: encodeValue() })"
|
||||
@@ -43,7 +43,7 @@
|
||||
import base from './base.vue'
|
||||
import CPagination from '../common/CPagination.vue'
|
||||
import { pVal } from '../utils.ts'
|
||||
import { VueSelect } from 'vue-select'
|
||||
import CInputSelect from '../../input/CInputSelect.vue'
|
||||
import { compose, NoID } from '@cortezaproject/corteza-js'
|
||||
import { createPopper } from '@popperjs/core'
|
||||
import { debounce } from 'lodash'
|
||||
@@ -53,7 +53,7 @@ export default {
|
||||
name: 'c-prompt-compose-record-picker',
|
||||
|
||||
components: {
|
||||
VueSelect,
|
||||
CInputSelect,
|
||||
CPagination,
|
||||
},
|
||||
|
||||
|
||||
+4
-4
@@ -11346,10 +11346,10 @@ vue-runtime-helpers@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/vue-runtime-helpers/-/vue-runtime-helpers-1.1.2.tgz#446b7b820888ab0c5264d2c3a32468e72e4100f3"
|
||||
integrity sha512-pZfGp+PW/IXEOyETE09xQHR1CKkR9HfHZdnMD/FVLUNI+HxYTa82evx5WrF6Kz4s82qtqHvMZ8MZpbk2zT2E1Q==
|
||||
|
||||
vue-select@^3.4.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vue-select/-/vue-select-3.16.0.tgz#db2ee2ddf80bd8876ce57738107b8a1a741862f4"
|
||||
integrity sha512-F0x7HXTUc5eq7YSjR0uX77RGA+Yk2+I8aMW+NePyPqRX9OPSiDtKpezFIFhnhxqrOvMh4uVR0jHkXIDmzs6nYQ==
|
||||
vue-select@3.20.2:
|
||||
version "3.20.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-select/-/vue-select-3.20.2.tgz#eaa15012b032c154d4fb51ac82ebeda2beeae54b"
|
||||
integrity sha512-ZSzIDzyYsWZULGUxVp1h6u3yi9IZQBWX8r6kSudUI/I5J1HQKpBjRntvkrg6pr87xmm16kdChvHCDN+W84vTKw==
|
||||
|
||||
vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
|
||||
version "4.1.3"
|
||||
|
||||
Reference in New Issue
Block a user