Browse Source

feat(gui-v2): add single/multi select

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/2716/head
Pranav C 2 years ago
parent
commit
1d52a65efd
  1. 101
      packages/nc-gui-v2/components/editable-cell/EnumRadioEditableCell.vue
  2. 37
      packages/nc-gui-v2/components/editable-cell/Float.vue
  3. 69
      packages/nc-gui-v2/components/editable-cell/FloatCell.vue
  4. 37
      packages/nc-gui-v2/components/editable-cell/Integer.vue
  5. 69
      packages/nc-gui-v2/components/editable-cell/IntegerCell.vue
  6. 54
      packages/nc-gui-v2/components/editable-cell/MultiSelect.vue
  7. 73
      packages/nc-gui-v2/components/editable-cell/SingleSelect.vue
  8. 5
      packages/nc-gui-v2/components/smartsheet/EditableCell.vue
  9. 2
      packages/nc-gui-v2/components/tabs/Smartsheet.vue
  10. 4
      packages/nc-gui-v2/composables/useColumn.ts

101
packages/nc-gui-v2/components/editable-cell/EnumRadioEditableCell.vue

@ -1,101 +0,0 @@
<script>
import { enumColor as colors } from '@/components/project/spreadsheet/helpers/colors'
export default {
name: 'EnumRadioEditableCell',
props: {
value: String,
column: Object,
},
computed: {
colors() {
return this.$store.state.settings.darkTheme ? colors.dark : colors.light
},
localState: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
this.$emit('update')
},
},
enumValues() {
if (this.column && this.column.dtxp) {
return this.column.dtxp.split(',').map((v) => v.replace(/^'|'$/g, ''))
}
return []
},
parentListeners() {
const $listeners = {}
if (this.$listeners.blur) {
$listeners.blur = this.$listeners.blur
}
if (this.$listeners.focus) {
$listeners.focus = this.$listeners.focus
}
return $listeners
},
},
mounted() {
// this.$el.focus();
// let event;
// event = document.createEvent('MouseEvents');
// event.initMouseEvent('mousedown', true, true, window);
// this.$el.dispatchEvent(event);
},
}
</script>
<template>
<div class="d-flex align-center">
<div>
<div v-for="(val, i) of enumValues" :key="val" class="item">
<input :id="`key-radio-${val}`" v-model="localState" type="radio" class="orange--text" :value="val" />
<label
class="py-1 px-3 d-inline-block my-1 label"
:for="`key-radio-${val}`"
:style="{
background: colors[i % colors.length],
}"
>{{ val }}</label
>
</div>
</div>
</div>
</template>
<style scoped>
.label {
border-radius: 25px;
}
.item {
white-space: nowrap;
}
</style>
<!--
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-->

37
packages/nc-gui-v2/components/editable-cell/Float.vue

@ -0,0 +1,37 @@
<script lang="ts" setup>
import { computed } from "@vue/reactivity";
import { onMounted } from "vue";
const { modelValue: value } = defineProps<{ modelValue: any }>()
const emit = defineEmits(['update:modelValue'])
const root = ref<HTMLInputElement>()
const localState = computed({
get() {
return value
},
set(val) {
emit('update:modelValue', val)
},
})
onMounted(() => {
root.value?.focus()
})
</script>
<template>
<input ref="root" v-model="localState" type="number" />
</template>
<style scoped>
input {
outline: none;
width: 100%;
height: 100%;
color: var(--v-textColor-base);
}
</style>

69
packages/nc-gui-v2/components/editable-cell/FloatCell.vue

@ -1,69 +0,0 @@
<script>
export default {
name: 'FloatCell',
props: {
value: [String, Number],
},
computed: {
localState: {
get() {
return this.value
},
set(val) {
this.$emit('input', +val)
},
},
parentListeners() {
const $listeners = {}
if (this.$listeners.blur) {
$listeners.blur = this.$listeners.blur
}
if (this.$listeners.focus) {
$listeners.focus = this.$listeners.focus
}
return $listeners
},
},
mounted() {
this.$el.focus()
},
}
</script>
<template>
<input v-model="localState" type="number" v-on="parentListeners" />
</template>
<style scoped>
input {
width: 100%;
height: 100%;
color: var(--v-textColor-base);
}
</style>
<!--
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-->

37
packages/nc-gui-v2/components/editable-cell/Integer.vue

@ -0,0 +1,37 @@
<script setup lang="ts">
import { computed } from "@vue/reactivity";
import { onMounted } from "vue";
const { modelValue: value } = defineProps<{ modelValue: any }>()
const emit = defineEmits(['update:modelValue'])
const root = ref<HTMLInputElement>()
const localState = computed({
get() {
return value
},
set(val) {
emit('update:modelValue', val)
},
})
onMounted(() => {
root.value?.focus()
})
</script>
<template>
<input ref="root" v-model="localState" type="number" />
</template>
<style scoped>
input {
outline: none;
width: 100%;
height: 100%;
color: var(--v-textColor-base);
}
</style>

69
packages/nc-gui-v2/components/editable-cell/IntegerCell.vue

@ -1,69 +0,0 @@
<script>
export default {
name: 'IntegerCell',
props: {
value: [String, Number],
},
computed: {
localState: {
get() {
return this.value
},
set(val) {
this.$emit('input', parseInt(val, 10))
},
},
parentListeners() {
const $listeners = {}
if (this.$listeners.blur) {
$listeners.blur = this.$listeners.blur
}
if (this.$listeners.focus) {
$listeners.focus = this.$listeners.focus
}
return $listeners
},
},
mounted() {
this.$el.focus()
},
}
</script>
<template>
<input v-model="localState" type="number" v-on="parentListeners" />
</template>
<style scoped>
input {
width: 100%;
height: 100%;
color: var(--v-textColor-base);
}
</style>
<!--
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-->

54
packages/nc-gui-v2/components/editable-cell/SetListCheckboxCell.vue → packages/nc-gui-v2/components/editable-cell/MultiSelect.vue

@ -1,5 +1,31 @@
<script>
import colors from '@/components/project/spreadsheet/helpers/colors'
import { computed } from "@vue/reactivity";
import { ColumnType } from "nocodb-sdk";
import { inject, Ref } from "vue";
import {enumColor}from "~/utils/colorsUtils";
const column = inject<ColumnType>("column");
const isForm = inject<boolean>("isForm");
const { modelValue } = defineProps<{ modelValue: any }>();
const emit = defineEmits(["update:modelValue"]);
const localState = computed({
get() {
return modelValue?.replace(/\\'/g, "'").replace(/^'|'$/g, "");
},
set(val) {
emit("update:modelValue", val);
}
});
const options = computed<string[]>(() => {
return column?.dtxp?.split(",").map((v) => v.replace(/\\'/g, "'").replace(/^'|'$/g, "")) || [];
});
/*import colors from '@/components/project/spreadsheet/helpers/colors'
export default {
name: 'SetListCheckboxCell',
@ -47,7 +73,7 @@ export default {
event.initMouseEvent('mousedown', true, true, window)
this.$el.dispatchEvent(event)
},
}
}*/
</script>
<template>
@ -73,27 +99,3 @@ export default {
border-radius: 25px;
}
</style>
<!--
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-->

73
packages/nc-gui-v2/components/editable-cell/EnumListEditableCell.vue → packages/nc-gui-v2/components/editable-cell/SingleSelect.vue

@ -1,5 +1,31 @@
<script>
import colors from '@/mixins/colors'
<script lang="ts" setup>
import { computed } from "@vue/reactivity";
import { ColumnType } from "nocodb-sdk";
import { inject, Ref } from "vue";
import {enumColor}from "~/utils/colorsUtils";
const column = inject<ColumnType>("column");
const isForm = inject<boolean>("isForm");
const { modelValue } = defineProps<{ modelValue: any }>();
const emit = defineEmits(["update:modelValue"]);
const localState = computed({
get() {
return modelValue?.replace(/\\'/g, "'").replace(/^'|'$/g, "");
},
set(val) {
emit("update:modelValue", val);
}
});
const options = computed<string[]>(() => {
return column?.dtxp?.split(",").map((v) => v.replace(/\\'/g, "'").replace(/^'|'$/g, "")) || [];
});
/*import colors from '@/mixins/colors'
export default {
name: 'EnumListEditableCell',
@ -11,20 +37,6 @@ export default {
isForm: Boolean,
},
computed: {
localState: {
get() {
return this.value && this.value.replace(/\\'/g, "'").replace(/^'|'$/g, '')
},
set(val) {
this.$emit('input', val)
},
},
enumValues() {
if (this.column && this.column.dtxp) {
return this.column.dtxp.split(',').map((v) => v.replace(/\\'/g, "'").replace(/^'|'$/g, ''))
}
return []
},
parentListeners() {
const $listeners = {}
@ -38,28 +50,23 @@ export default {
return $listeners
},
},
mounted() {
// this.$el.focus();
// let event;
// event = document.createEvent('MouseEvents');
// event.initMouseEvent('mousedown', true, true, window);
// this.$el.dispatchEvent(event);
},
}
}*/
</script>
<template>
{{options}}
<v-select
v-model="localState"
solo
dense
flat
:items="enumValues"
:items="options"
hide-details
class="mt-0"
:clearable="!column.rqd"
v-on="parentListeners"
>
<!-- v-on="parentListeners"
<template #selection="{ item }">
<div
class="d-100"
@ -67,31 +74,33 @@ export default {
'text-center': !isForm,
}"
>
<v-chip small :color="colors[enumValues.indexOf(item) % colors.length]" class="ma-1">
{{ item }}
<v-chip small :color="enumColor.light[options.indexOf(item) % enumColor.light.length]" class="ma-1">
{{ item.text }}
</v-chip>
</div>
</template>
<template #item="{ item }">
<v-chip small :color="colors[enumValues.indexOf(item) % colors.length]">
<v-chip small :color="enumColor.light[options.indexOf(item) % enumColor.light.length]">
{{ item }}
</v-chip>
</template>
<template #append>
<v-icon small class="mt-1"> mdi-menu-down </v-icon>
</template>
<v-icon small class="mt-1"> mdi-menu-down</v-icon>
</template>-->
</v-select>
</template>
<style scoped lang="scss">
::v-deep {
:deep {
.v-select {
min-width: 150px;
}
.v-input__slot {
padding-right: 0 !important;
padding-left: 35px !important;
}
.v-input__icon.v-input__icon--clear {
width: 15px !important;
min-width: 13px !important;

5
packages/nc-gui-v2/components/smartsheet/EditableCell.vue

@ -19,8 +19,6 @@ const localState = computed({
})
const {
isSet,
isEnum,
isURL,
isEmail,
isJSON,
@ -34,6 +32,8 @@ const {
isAttachment,
isTextArea,
isString,
isSingleSelect,
isMultiSelect
} = useColumn(column)
</script>
@ -164,6 +164,7 @@ const {
<!-- />&ndash;&gt; -->
<EditableCellAttachment v-if="isAttachment" v-model="localState" />
<EditableCellSingleSelect v-if="isSingleSelect" v-model="localState" />
<!-- v-model="localState"
:active="active"
:db-alias="dbAlias"

2
packages/nc-gui-v2/components/tabs/Smartsheet.vue

@ -29,7 +29,7 @@ watch(
<template>
<div class="overflow-auto">
<v-toolbar height="32" dense class="nc-table-toolbar elevation-0 xc-toolbar xc-border-bottom mx-1" style="z-index: 7" />
<!-- <v-toolbar height="32" dense class="nc-table-toolbar elevation-0 xc-toolbar xc-border-bottom mx-1" style="z-index: 7" />-->
<template v-if="meta && tabMeta">
<SmartsheetGrid />
</template>

4
packages/nc-gui-v2/composables/useColumn.ts

@ -21,7 +21,9 @@ export default (column: ColumnType) => {
const isDateTime = abstractType === 'datetime' || uiDatatype === 'DateTime'
const isJSON = uiDatatype === 'JSON'
const isEnum = uiDatatype === 'SingleSelect'
const isSingleSelect = uiDatatype === 'SingleSelect'
const isSet = uiDatatype === 'MultiSelect'
const isMultiSelect = uiDatatype === 'MultiSelect'
const isURL = uiDatatype === 'URL'
const isEmail = uiDatatype === UITypes.Email
const isAttachment = uiDatatype === 'Attachment'
@ -66,5 +68,7 @@ export default (column: ColumnType) => {
isDuration,
isAutoSaved,
isManualSaved,
isSingleSelect,
isMultiSelect
}
}

Loading…
Cancel
Save