Browse Source

refactor/gui-v2-added-json

pull/2946/head
Muhammed Mustafa 2 years ago
parent
commit
ed64d28faf
  1. 101
      packages/nc-gui-v2/components/cell/Json.vue
  2. 119
      packages/nc-gui-v2/components/cell/JsonEditableCell.vue
  3. 60
      packages/nc-gui-v2/components/monaco/Editor.vue
  4. 1
      packages/nc-gui-v2/components/smartsheet/Cell.vue
  5. 1
      packages/nc-gui-v2/components/smartsheet/Grid.vue
  6. 19
      packages/nc-gui-v2/package-lock.json
  7. 1
      packages/nc-gui-v2/package.json

101
packages/nc-gui-v2/components/cell/Json.vue

@ -0,0 +1,101 @@
<script setup lang="ts">
import { Modal as AModal } from 'ant-design-vue'
import Editor from '~/components/monaco/Editor.vue'
import FullScreenIcon from '~icons/cil/fullscreen'
import FullScreenExitIcon from '~icons/cil/fullscreen-exit'
import { inject, onMounted } from '#imports'
import { EditModeInj } from '~/context'
interface Props {
modelValue: any
}
interface Emits {
(event: 'update:modelValue', model: any): void
}
const props = defineProps<Props>()
const emits = defineEmits<Emits>()
let editEnabled = $(inject(EditModeInj))
let vModel = $(useVModel(props, 'modelValue', emits))
let localValue = $ref({})
let error = $ref<string | undefined>(undefined)
let isExpanded = $ref(false)
const onError = (e: any) => {
error = e
}
const clear = () => {
error = undefined
isExpanded = false
editEnabled = false
localValue = JSON.parse(vModel)
}
const onSave = () => {
vModel = JSON.stringify(localValue)
isExpanded = false
}
const resetError = () => {
error = undefined
}
onMounted(() => {
localValue = JSON.parse(vModel)
})
watch(
() => editEnabled,
() => {
isExpanded = false
localValue = JSON.parse(vModel)
},
)
</script>
<template>
<component :is="isExpanded ? AModal : 'div'" v-model:visible="isExpanded" :closable="false" centered :footer="null">
<div v-if="editEnabled" class="flex flex-col w-full">
<div class="flex flex-row justify-between pt-1 pb-2">
<a-button type="text" size="small" @click="isExpanded = !isExpanded">
<FullScreenExitIcon v-if="isExpanded" class="h-2.5" />
<FullScreenIcon v-else class="h-2.5" />
</a-button>
<div class="flex flex-row">
<a-button type="text" size="small" :onclick="clear"><div class="text-xs">Cancel</div></a-button>
<a-button type="primary" size="small" :disabled="!!error"><div class="text-xs" :onclick="onSave">Save</div></a-button>
</div>
</div>
<Editor
:model-value="localValue"
class="min-w-full w-80"
:class="{ 'expanded-editor': isExpanded, 'editor': !isExpanded }"
:hide-minimap="true"
@validation-error="onError"
@update:model-value="localValue = $event"
@value-changed="resetError"
/>
<span v-if="error" class="text-xs w-full py-1 text-red-500">
{{ error?.toString() }}
</span>
</div>
<span v-else>{{ vModel }}</span>
</component>
</template>
<style scoped lang="scss">
.expanded-editor {
min-height: min(600px, 80vh);
}
.editor {
min-height: min(200px, 10vh);
}
</style>

119
packages/nc-gui-v2/components/cell/JsonEditableCell.vue

@ -1,119 +0,0 @@
<script lang="ts" setup>
import MonacoJsonObjectEditor from '@/components/monaco/Editor.vue'
import { computed, inject } from '#imports'
import { EditModeInj } from '~/context'
interface Props {
modelValue: string | Record<string, any> | null
isForm: boolean
}
const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue', 'cancel'])
const editEnabled = inject(EditModeInj)
let expand = $ref(false)
let isValid = $ref(true)
let error = $ref()
const vModel = computed({
get: () => (typeof props.modelValue === 'string' ? JSON.parse(props.modelValue) : props.modelValue),
set: (val) => {
if (props.isForm) {
emits('update:modelValue', JSON.stringify(val))
}
},
})
function save() {
expand = false
emits('update:modelValue', JSON.stringify(vModel.value))
}
function validate(n: boolean, e: any) {
isValid = n
error = e
}
</script>
<script lang="ts">
export default {
name: 'JsonEditableCell',
}
</script>
<template>
<v-dialog :is="expand ? 'v-dialog' : 'div'" v-model="expand" max-width="800px" class="cell-container" @keydown.stop.enter>
<div class="d-flex pa-1" :class="{ backgroundColor: expand }">
<v-spacer />
<v-icon small class="mr-2" @click="expand = !expand">
{{ expand ? 'mdi-arrow-collapse' : 'mdi-arrow-expand' }}
</v-icon>
<template v-if="!isForm">
<v-btn outlined x-small class="mr-1" @click="$emit('cancel')">
<!-- Cancel -->
{{ $t('general.cancel') }}
</v-btn>
<v-btn x-small color="primary" :disabled="!isValid" @click="save">
<!-- Save -->
{{ $t('general.save') }}
</v-btn>
</template>
<v-btn v-else-if="expand" x-small @click="expand = false">
<!-- Close -->
{{ $t('general.close') }}
</v-btn>
</div>
<MonacoJsonObjectEditor
v-if="expand"
v-model="vModel"
class="text-left caption"
style="width: 300px; min-height: min(600px, 80vh); min-width: 100%"
@validate="validate"
/>
<MonacoJsonObjectEditor
v-else
v-model="vModel"
class="text-left caption"
style="width: 300px; min-height: 200px; min-width: 100%"
@validate="validate"
/>
<div v-show="error" class="px-2 py-1 text-left caption error--text">
{{ error }}
</div>
</v-dialog>
</template>
<style scoped>
.cell-container {
width: 100%;
}
</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/>.
*
*/
-->

60
packages/nc-gui-v2/components/monaco/Editor.vue

@ -7,14 +7,22 @@ import { onMounted } from '#imports'
import { deepCompare } from '~/utils'
interface Props {
modelValue: string
lang?: string
validate?: boolean
modelValue: any
hideMinimap?: boolean
}
const { modelValue, lang = 'json', validate = true } = defineProps<Props>()
interface Emits {
(event: 'update:modelValue', model: any): void
(event: 'validationError', error: any): void
(event: 'valueChanged'): void
}
const props = defineProps<Props>()
const emits = defineEmits<Emits>()
const emit = defineEmits(['update:modelValue'])
const { hideMinimap } = props
let vModel = $(useVModel(props, 'modelValue', emits))
const isValid = ref(true)
@ -48,14 +56,13 @@ defineExpose({
})
onMounted(() => {
if (root.value && lang) {
const model = monaco.editor.createModel(JSON.stringify(modelValue, null, 2), lang)
if (lang === 'json') {
if (root.value) {
const model = monaco.editor.createModel(JSON.stringify(vModel, null, 2), 'json')
// configure the JSON language support with schemas and schema associations
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: validate as boolean,
validate: true,
})
}
editor = monaco.editor.create(root.value, {
model,
@ -68,22 +75,20 @@ onMounted(() => {
},
tabSize: 2,
automaticLayout: true,
minimap: {
enabled: !hideMinimap,
},
})
editor.onDidChangeModelContent(async (e) => {
try {
isValid.value = true
const value = editor?.getValue()
if (typeof modelValue === 'object') {
if (!value || !deepCompare(modelValue, JSON.parse(value))) {
emit('update:modelValue', JSON.stringify(modelValue, null, 2))
}
} else {
if (value !== modelValue) emit('update:modelValue', value)
}
const obj = JSON.parse(editor.getValue())
emits('valueChanged')
if (!deepCompare(vModel, obj)) vModel = obj
} catch (e) {
isValid.value = false
emits('validationError', e)
console.log(e)
}
})
@ -91,17 +96,18 @@ onMounted(() => {
})
watch(
() => modelValue,
() => vModel,
(v) => {
if (editor && v) {
const value = editor?.getValue()
if (typeof v === 'object') {
if (!value || !deepCompare(v, JSON.parse(value))) {
editor.setValue(JSON.stringify(v, null, 2))
if (!editor || !v) {
return
}
} else {
if (value !== v) editor.setValue(v)
try {
if (!deepCompare(v, JSON.parse(editor?.getValue() as string))) {
editor.setValue(JSON.stringify(v, null, 2))
}
} catch (e) {
editor.setValue(JSON.stringify(v, null, 2))
}
},
)

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

@ -130,6 +130,7 @@ const syncAndNavigate = (dir: NavigateDir) => {
<CellFloat v-else-if="isFloat" v-model="vModel" />
<CellText v-else-if="isString" v-model="vModel" />
<CellPercent v-else-if="isPercent" v-model="vModel" />
<CellJson v-else-if="isJSON" v-model="vModel" />
<CellText v-else v-model="vModel" />
</div>
</template>

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

@ -420,7 +420,6 @@ const onNavigate = (dir: NavigateDir) => {
td {
text-overflow: ellipsis;
white-space: nowrap;
}
td.active::after,

19
packages/nc-gui-v2/package-lock.json generated

@ -28,6 +28,7 @@
},
"devDependencies": {
"@antfu/eslint-config": "^0.25.2",
"@iconify-json/cil": "^1.1.2",
"@iconify-json/clarity": "^1.1.4",
"@iconify-json/eva": "^1.1.2",
"@iconify-json/ic": "^1.1.7",
@ -990,6 +991,15 @@
"dev": true,
"peer": true
},
"node_modules/@iconify-json/cil": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@iconify-json/cil/-/cil-1.1.2.tgz",
"integrity": "sha512-fu9x1f+A2H5qGWnApU1aw0EREAKqg5EP2Z6cWHV11XchlKgzY+jWQCalctkV+Jsef2M2m3C2DX/ukgyhMclIcw==",
"dev": true,
"dependencies": {
"@iconify/types": "*"
}
},
"node_modules/@iconify-json/clarity": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@iconify-json/clarity/-/clarity-1.1.4.tgz",
@ -15502,6 +15512,15 @@
"dev": true,
"peer": true
},
"@iconify-json/cil": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@iconify-json/cil/-/cil-1.1.2.tgz",
"integrity": "sha512-fu9x1f+A2H5qGWnApU1aw0EREAKqg5EP2Z6cWHV11XchlKgzY+jWQCalctkV+Jsef2M2m3C2DX/ukgyhMclIcw==",
"dev": true,
"requires": {
"@iconify/types": "*"
}
},
"@iconify-json/clarity": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@iconify-json/clarity/-/clarity-1.1.4.tgz",

1
packages/nc-gui-v2/package.json

@ -34,6 +34,7 @@
},
"devDependencies": {
"@antfu/eslint-config": "^0.25.2",
"@iconify-json/cil": "^1.1.2",
"@iconify-json/clarity": "^1.1.4",
"@iconify-json/eva": "^1.1.2",
"@iconify-json/ic": "^1.1.7",

Loading…
Cancel
Save