Browse Source

feat: migrate textcell and textarea cell

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/2716/head
Pranav C 2 years ago
parent
commit
489b7377fa
  1. 30
      packages/nc-gui-v2/components/editable-cell/Text.vue
  2. 78
      packages/nc-gui-v2/components/editable-cell/TextArea.vue
  3. 81
      packages/nc-gui-v2/components/editable-cell/TextAreaCell.vue
  4. 2
      packages/nc-gui-v2/components/smartsheet/Cell.vue
  5. 124
      packages/nc-gui-v2/components/smartsheet/EditableCell.vue
  6. 281
      packages/nc-gui-v2/components/smartsheet/Grid.vue
  7. 5
      packages/nc-gui-v2/pages/projects/create-external.vue
  8. 100
      packages/nc-gui-v2/utils/projectCreateUtils.ts

30
packages/nc-gui-v2/components/editable-cell/TextCell.vue → packages/nc-gui-v2/components/editable-cell/Text.vue

@ -1,5 +1,25 @@
<script>
export default {
<script setup lang="ts">
import { computed } from "@vue/reactivity";
import { onMounted } from "vue";
const root = ref<HTMLInputElement>();
const { modelValue:value } = defineProps<{ modelValue: any }>()
const emit = defineEmits(["update:modelValue"]);
const localState = computed({
get() {
return value;
}, set(val) {
emit("update:modelValue", val);
}
});
onMounted(() => {
root.value?.focus()
});
/*export default {
name: 'TextCell',
props: {
value: [String, Object, Number, Boolean, Array],
@ -33,11 +53,12 @@ export default {
mounted() {
this.$el.focus()
},
}
}*/
</script>
<template>
<input v-model="localState" v-on="parentListeners" />
<input v-model="localState" ref="root"/>
<!-- v-on="parentListeners" />-->
</template>
<style scoped>
@ -46,6 +67,7 @@ textarea {
width: 100%;
height: 100%;
color: var(--v-textColor-base);
outline: none;
}
</style>
<!--

78
packages/nc-gui-v2/components/editable-cell/TextArea.vue

@ -0,0 +1,78 @@
<script setup lang="ts">
import { computed } from "@vue/reactivity";
import { onMounted } from "vue";
const root = ref<HTMLInputElement>();
const { modelValue:value } = defineProps<{ modelValue: any }>()
const emit = defineEmits(["update:modelValue"]);
const localState = computed({
get() {
return value;
}, set(val) {
emit("update:modelValue", val);
}
});
onMounted(() => {
root.value?.focus()
});
/*export default {
name: 'TextAreaCell',
props: {
value: String,
},
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
},
},
created() {
this.localState = this.value
},
mounted() {
this.$refs.textarea && this.$refs.textarea.focus()
},
}*/
</script>
<template>
<textarea
v-model="localState" ref="root"
rows="4"
v-on="parentListeners"
@keydown.alt.enter.stop
@keydown.shift.enter.stop
/>
</template>
<style scoped>
input,
textarea {
width: 100%;
min-height: 60px;
height: 100%;
color: var(--v-textColor-base);
}
</style>

81
packages/nc-gui-v2/components/editable-cell/TextAreaCell.vue

@ -1,81 +0,0 @@
<script>
export default {
name: 'TextAreaCell',
props: {
value: String,
},
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
},
},
created() {
this.localState = this.value
},
mounted() {
this.$refs.textarea && this.$refs.textarea.focus()
},
}
</script>
<template>
<textarea
ref="textarea"
v-model="localState"
rows="4"
v-on="parentListeners"
@keydown.alt.enter.stop
@keydown.shift.enter.stop
/>
</template>
<style scoped>
input,
textarea {
width: 100%;
min-height: 60px;
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/>.
*
*/
-->

2
packages/nc-gui-v2/components/smartsheet/Cell.vue

@ -38,7 +38,7 @@ const {
<!-- <CellDuration v-else-if="isDuration" /> -->
<!-- <CellRating v-else-if="isRating" /> -->
<!-- <CellCurrency v-else-if="isCurrency" /> -->
<span v-else :title="title">{{ value }}</span>
<span v-else :title="value">{{ value }}</span>
</template>
<style scoped></style>

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

@ -1,10 +1,22 @@
<script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk'
import useColumn from '~/composables/useColumn'
import { computed } from "@vue/reactivity";
import type { ColumnType } from "nocodb-sdk";
import useColumn from "~/composables/useColumn";
const { column, value } = defineProps<{ column: ColumnType; value: any }>()
provide('column', column)
provide('value', value)
const { column, modelValue: value } = defineProps<{ column: ColumnType; modelValue: any }>();
const emit = defineEmits(["update:modelValue"]);
provide("column", column);
const localState = computed({
get() {
return value;
},
set(val) {
emit("update:modelValue", val);
}
});
const {
isSet,
@ -21,25 +33,27 @@ const {
isCurrency,
isAttachment,
isTextArea,
} = useColumn(column)
isString
} = useColumn(column);
</script>
<template>
<div class="nc-cell" @keydown.stop.left @keydown.stop.right @keydown.stop.up @keydown.stop.down>
<EditableAttachmentCell
v-if="isAttachment"
v-model="localState"
:active="active"
:db-alias="dbAlias"
:meta="meta"
:is-form="isForm"
:column="column"
:is-public-grid="isPublic && !isForm"
:is-public-form="isPublic && isForm"
:view-id="viewId"
:is-locked="isLocked"
v-on="$listeners"
/>
<!-- <EditableAttachmentCell -->
<!-- v-if="isAttachment" -->
<!-- /> -->
<!-- v-model="localState"
:active="active"
:db-alias="dbAlias"
:meta="meta"
:is-form="isForm"
:column="column"
:is-public-grid="isPublic && !isForm"
:is-public-form="isPublic && isForm"
:view-id="viewId"
:is-locked="isLocked"
v-on="$listeners"
/> -->
<RatingCell
v-else-if="isRating"
@ -63,17 +77,45 @@ const {
v-on="parentListeners"
/>
<BooleanCell v-else-if="isBoolean" v-model="localState" :column="column" :is-form="isForm" v-on="parentListeners" />
<BooleanCell
v-else-if="isBoolean"
v-model="localState"
:column="column"
:is-form="isForm"
v-on="parentListeners"
/>
<IntegerCell v-else-if="isInt" v-model="localState" v-on="parentListeners" />
<IntegerCell
v-else-if="isInt"
v-model="localState"
v-on="parentListeners"
/>
<FloatCell v-else-if="isFloat" v-model="localState" v-on="parentListeners" />
<FloatCell
v-else-if="isFloat"
v-model="localState"
v-on="parentListeners"
/>
<DatePickerCell v-else-if="isDate" v-model="localState" v-on="parentListeners" />
<DatePickerCell
v-else-if="isDate"
v-model="localState"
v-on="parentListeners"
/>
<TimePickerCell v-else-if="isTime" v-model="localState" v-on="parentListeners" @save="$emit('save')" />
<TimePickerCell
v-else-if="isTime"
v-model="localState"
v-on="parentListeners"
@save="$emit('save')"
/>
<DateTimePickerCell v-else-if="isDateTime" v-model="localState" ignore-focus v-on="parentListeners" />
<DateTimePickerCell
v-else-if="isDateTime"
v-model="localState"
ignore-focus
v-on="parentListeners"
/>
<EnumCell
v-else-if="isEnum && ((!isForm && !active) || isLocked || (isPublic && !isForm))"
@ -81,9 +123,21 @@ const {
:column="column"
v-on="parentListeners"
/>
<EnumListCell v-else-if="isEnum" v-model="localState" :is-form="isForm" :column="column" v-on="parentListeners" />
<EnumListCell
v-else-if="isEnum"
v-model="localState"
:is-form="isForm"
:column="column"
v-on="parentListeners"
/>
<JsonEditableCell v-else-if="isJSON" v-model="localState" :is-form="isForm" v-on="parentListeners" @input="$emit('save')" />
<JsonEditableCell
v-else-if="isJSON"
v-model="localState"
:is-form="isForm"
v-on="parentListeners"
@input="$emit('save')"
/>
<SetListEditableCell
v-else-if="isSet && (active || isForm) && !isLocked && !(isPublic && !isForm)"
@ -91,13 +145,23 @@ const {
:column="column"
v-on="parentListeners"
/>
<SetListCell v-else-if="isSet" v-model="localState" :column="column" v-on="parentListeners" />
<SetListCell
v-else-if="isSet"
v-model="localState"
:column="column"
v-on="parentListeners"
/>
<EditableUrlCell v-else-if="isURL" v-model="localState" v-on="parentListeners" />
<TextCell v-else-if="isString" v-model="localState" v-on="parentListeners" />
<TextAreaCell v-else-if="isTextArea" v-model="localState" :is-form="isForm" v-on="parentListeners" />
<TextAreaCell
v-else-if="isTextArea"
v-model="localState"
:is-form="isForm"
v-on="parentListeners"
/>
<TextCell v-else v-model="localState" v-on="$listeners" />
<span v-if="hint" class="nc-hint">{{ hint }}</span>

281
packages/nc-gui-v2/components/smartsheet/Grid.vue

@ -1,138 +1,155 @@
<script lang="ts" setup>
import type { ComputedRef } from 'vue'
import { inject, onMounted } from 'vue'
import { isVirtualCol } from 'nocodb-sdk'
import type { TableType } from 'nocodb-sdk'
import useViewData from '~/composables/useViewData'
import type { ComputedRef } from "vue";
import { inject, onMounted } from "vue";
import { isVirtualCol } from "nocodb-sdk";
import type { TableType } from "nocodb-sdk";
import useViewData from "~/composables/useViewData";
const meta = inject<ComputedRef<TableType>>('meta')
const meta = inject<ComputedRef<TableType>>("meta");
const { loadData, paginationData, formattedData: data } = useViewData(meta)
// todo: get from parent ( inject or use prop )
const isPublicView = false;
onMounted(() => loadData({}))
const selected = reactive<{ row?: number | null; col?: number | null }>({});
const editEnabled = ref(false);
const { loadData, paginationData, formattedData: data } = useViewData(meta);
onMounted(() => loadData({}));
const selectCell = (row: number, col: number) => {
selected.row = row;
selected.col = col;
};
onKeyStroke(["Enter"], (e) => {
if (selected.row !== null && selected.col !== null) {
editEnabled.value = true;
}
});
</script>
<template>
<table class="xc-row-table nc-grid backgroundColorDefault">
<thead>
<tr>
<th>#</th>
<th v-for="col in meta.columns" :key="col.title">
{{ col.title }}
</th>
</tr>
<tr>
<th>#</th>
<th v-for="col in meta.columns" :key="col.title">
{{ col.title }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="({ row }, rowIndex) in data" :key="rowIndex" class="nc-grid-row">
<td key="row-index" style="width: 65px" class="caption nc-grid-cell">
<div class="d-flex align-center">
{{ rowIndex + 1 }}
</div>
</td>
<td
v-for="columnObj in meta.columns"
:key="rowIndex + columnObj.title"
class="cell pointer nc-grid-cell"
:class="{
// 'active':
// !isPublicView
// && selected.col === col
// && selected.row === row
// && isEditable,
<tr v-for="({ row }, rowIndex) in data" :key="rowIndex" class="nc-grid-row">
<td key="row-index" style="width: 65px" class="caption nc-grid-cell">
<div class="d-flex align-center">
{{ rowIndex + 1 }}
</div>
</td>
<td
v-for="(columnObj, colIndex) in meta.columns"
:key="rowIndex + columnObj.title"
class="cell pointer nc-grid-cell"
:class="{
active: !isPublicView && selected.col === colIndex && selected.row === rowIndex,
// 'primary-column': primaryValueColumn === columnObj.title,
// 'text-center': isCentrallyAligned(columnObj),
// 'required': isRequired(columnObj, rowObj),
}"
:data-col="columnObj.title"
>
<!-- @dblclick="makeEditable(col, row, columnObj.ai, rowMeta)" -->
<!-- @click="makeSelected(col, row)" -->
<!-- @contextmenu=" -->
<!-- showRowContextMenu($event, rowObj, rowMeta, row, col, columnObj) -->
<!-- " -->
<!-- > -->
<!-- <virtual-cell -->
<!-- v-if="isVirtualCol(columnObj)" -->
<!-- :password="password" -->
<!-- :is-public="isPublicView" -->
<!-- :metas="metas" -->
<!-- :is-locked="isLocked" -->
<!-- :column="columnObj" -->
<!-- :row="rowObj" -->
<!-- :nodes="nodes" -->
<!-- :meta="meta" -->
<!-- :api="api" -->
<!-- :active="selected.col === col && selected.row === row" -->
<!-- :sql-ui="sqlUi" -->
<!-- :is-new="rowMeta.new" -->
<!-- v-on="$listeners" -->
<!-- @updateCol=" -->
<!-- (...args) => -->
<!-- updateCol( -->
<!-- ...args, -->
<!-- columnObj.bt -->
<!-- && meta.columns.find( -->
<!-- (c) => c.column_name === columnObj.bt.column_name, -->
<!-- ), -->
<!-- col, -->
<!-- row, -->
<!-- ) -->
<!-- " -->
<!-- @saveRow="onCellValueChange(col, row, columnObj, true)" -->
<!-- /> -->
<!-- <editable-cell -->
<!-- v-else-if=" -->
<!-- ((isPkAvail || rowMeta.new) -->
<!-- && !isView -->
<!-- && !isLocked -->
<!-- && !isPublicView -->
<!-- && editEnabled.col === col -->
<!-- && editEnabled.row === row) -->
<!-- || enableEditable(columnObj) -->
<!-- " -->
<!-- v-model="rowObj[columnObj.title]" -->
<!-- :column="columnObj" -->
<!-- :meta="meta" -->
<!-- :active="selected.col === col && selected.row === row" -->
<!-- :sql-ui="sqlUi" -->
<!-- :db-alias="nodes.dbAlias" -->
<!-- :is-locked="isLocked" -->
<!-- :is-public="isPublicView" -->
<!-- :view-id="viewId" -->
<!-- @save="editEnabled = {}; onCellValueChange(col, row, columnObj, true);" -->
<!-- @cancel="editEnabled = {}" -->
<!-- @update="onCellValueChange(col, row, columnObj, false)" -->
<!-- @blur="onCellValueChange(col, row, columnObj, true)" -->
<!-- @input="unsaved = true" -->
<!-- @navigateToNext="navigateToNext" -->
<!-- @navigateToPrev="navigateToPrev" -->
<!-- /> -->
<span v-if="isVirtualCol(columnObj)" />
<SmartsheetCell
v-else
:class="{
// 'primary--text': primaryValueColumn === columnObj.title,
}"
:column="columnObj"
:value="row[columnObj.title]"
/>
<!-- :selected="selected.col === col && selected.row === row" -->
<!-- :is-locked="isLocked" -->
<!-- :column="columnObj" -->
<!-- :meta="meta" -->
<!-- :db-alias="nodes.dbAlias" -->
<!-- :value="rowObj[columnObj.title]" -->
<!-- :sql-ui="sqlUi" -->
<!-- @enableedit=" -->
<!-- makeSelected(col, row); -->
<!-- makeEditable(col, row, columnObj.ai, rowMeta); -->
<!-- " -->
<!-- /> -->
</td>
</tr>
:data-col="columnObj.title"
@click="selectCell(rowIndex, colIndex)"
@dblclick="editEnabled = true"
>
<!-- @contextmenu=" -->
<!-- showRowContextMenu($event, rowObj, rowMeta, row, col, columnObj) -->
<!-- " -->
<!-- > -->
<!-- <virtual-cell -->
<!-- v-if="isVirtualCol(columnObj)" -->
<!-- :password="password" -->
<!-- :is-public="isPublicView" -->
<!-- :metas="metas" -->
<!-- :is-locked="isLocked" -->
<!-- :column="columnObj" -->
<!-- :row="rowObj" -->
<!-- :nodes="nodes" -->
<!-- :meta="meta" -->
<!-- :api="api" -->
<!-- :active="selected.col === col && selected.row === row" -->
<!-- :sql-ui="sqlUi" -->
<!-- :is-new="rowMeta.new" -->
<!-- v-on="$listeners" -->
<!-- @updateCol=" -->
<!-- (...args) => -->
<!-- updateCol( -->
<!-- ...args, -->
<!-- columnObj.bt -->
<!-- && meta.columns.find( -->
<!-- (c) => c.column_name === columnObj.bt.column_name, -->
<!-- ), -->
<!-- col, -->
<!-- row, -->
<!-- ) -->
<!-- " -->
<!-- @saveRow="onCellValueChange(col, row, columnObj, true)" -->
<!-- /> -->
<!-- <editable-cell -->
<!-- v-else-if=" -->
<!-- ((isPkAvail || rowMeta.new) -->
<!-- && !isView -->
<!-- && !isLocked -->
<!-- && !isPublicView -->
<!-- && editEnabled.col === col -->
<!-- && editEnabled.row === row) -->
<!-- || enableEditable(columnObj) -->
<!-- " -->
<!-- v-model="rowObj[columnObj.title]" -->
<!-- :column="columnObj" -->
<!-- :meta="meta" -->
<!-- :active="selected.col === col && selected.row === row" -->
<!-- :sql-ui="sqlUi" -->
<!-- :db-alias="nodes.dbAlias" -->
<!-- :is-locked="isLocked" -->
<!-- :is-public="isPublicView" -->
<!-- :view-id="viewId" -->
<!-- @save="editEnabled = {}; onCellValueChange(col, row, columnObj, true);" -->
<!-- @cancel="editEnabled = {}" -->
<!-- @update="onCellValueChange(col, row, columnObj, false)" -->
<!-- @blur="onCellValueChange(col, row, columnObj, true)" -->
<!-- @input="unsaved = true" -->
<!-- @navigateToNext="navigateToNext" -->
<!-- @navigateToPrev="navigateToPrev" -->
<!-- /> -->
<span v-if="isVirtualCol(columnObj)" />
<SmartsheetEditableCell
v-else-if="editEnabled && selected.col === colIndex && selected.row === rowIndex"
:column="columnObj"
v-model="row[columnObj.title]"
/>
<SmartsheetCell
v-else
:column="columnObj"
:value="row[columnObj.title]"
/>
<!-- :selected="selected.col === col && selected.row === row" -->
<!-- :is-locked="isLocked" -->
<!-- :column="columnObj" -->
<!-- :meta="meta" -->
<!-- :db-alias="nodes.dbAlias" -->
<!-- :value="rowObj[columnObj.title]" -->
<!-- :sql-ui="sqlUi" -->
<!-- @enableedit=" -->
<!-- makeSelected(col, row); -->
<!-- makeEditable(col, row, columnObj.ai, rowMeta); -->
<!-- " -->
<!-- /> -->
</td>
</tr>
</tbody>
</table>
</template>
@ -162,4 +179,28 @@ td {
text-overflow: ellipsis;
white-space: nowrap;
}
td.active::after,
td.active::before {
content: '';
position: absolute;
z-index: 3;
height: calc(100% + 2px);
width: calc(100% + 2px);
left: -1px;
top: -1px;
pointer-events: none;
}
// todo: replace with css variable
td.active::after {
border: 2px solid #0040bc; /*var(--v-primary-lighten1);*/
}
td.active::before {
background: #0040bc /*var(--v-primary-base)*/
;
opacity: 0.1;
}
</style>

5
packages/nc-gui-v2/pages/projects/create-external.vue

@ -166,8 +166,11 @@ const testConnection = async () => {
</v-btn>
<v-btn small class="px-2">
<!-- todo:implement test connection -->
<!-- <v-btn size="sm" class="text-sm text-capitalize">
&lt;!&ndash; Test Database Connection &ndash;&gt;
{{ $t('activity.testDbConn') }}
</v-btn>
</v-btn>-->
</div>
</v-container>
</v-card>

100
packages/nc-gui-v2/utils/projectCreateUtils.ts

@ -41,11 +41,11 @@ const sampleConnectionData = {
user: 'postgres',
password: 'password',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
mysql2: {
host: 'localhost',
@ -53,11 +53,11 @@ const sampleConnectionData = {
user: 'root',
password: 'password',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
vitess: {
host: 'localhost',
@ -65,11 +65,11 @@ const sampleConnectionData = {
user: 'root',
password: 'password',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
tidb: {
host: 'localhost',
@ -77,11 +77,11 @@ const sampleConnectionData = {
user: 'root',
password: '',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
yugabyte: {
host: 'localhost',
@ -89,11 +89,11 @@ const sampleConnectionData = {
user: 'postgres',
password: '',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
citusdb: {
host: 'localhost',
@ -101,11 +101,11 @@ const sampleConnectionData = {
user: 'postgres',
password: '',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
cockroachdb: {
host: 'localhost',
@ -113,11 +113,11 @@ const sampleConnectionData = {
user: 'postgres',
password: '',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
greenplum: {
host: 'localhost',
@ -125,11 +125,11 @@ const sampleConnectionData = {
user: 'postgres',
password: '',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
mssql: {
host: 'localhost',
@ -137,11 +137,11 @@ const sampleConnectionData = {
user: 'sa',
password: 'Password123.',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
oracledb: {
host: 'localhost',
@ -149,11 +149,11 @@ const sampleConnectionData = {
user: 'system',
password: 'Oracle18',
database: '_test',
ssl: {
ca: '',
key: '',
cert: '',
},
// ssl: {
// ca: '',
// key: '',
// cert: '',
// },
},
sqlite3: {
client: 'sqlite3',

Loading…
Cancel
Save