Browse Source

chore(gui-v2): lint

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/3057/head
Pranav C 2 years ago
parent
commit
947e9ec02e
  1. 4
      packages/nc-gui-v2/components/cell/MultiSelect.vue
  2. 2
      packages/nc-gui-v2/components/cell/attachment/Carousel.vue
  3. 10
      packages/nc-gui-v2/components/dashboard/TreeView.vue
  4. 6
      packages/nc-gui-v2/components/dlg/AirtableImport.vue
  5. 2
      packages/nc-gui-v2/components/dlg/QuickImport.vue
  6. 23
      packages/nc-gui-v2/components/dlg/TableCreate.vue
  7. 6
      packages/nc-gui-v2/components/dlg/TableRename.vue
  8. 8
      packages/nc-gui-v2/components/general/MiniSidebar.vue
  9. 2
      packages/nc-gui-v2/components/smartsheet-column/CurrencyOptions.vue
  10. 2
      packages/nc-gui-v2/components/smartsheet-column/DurationOptions.vue
  11. 13
      packages/nc-gui-v2/components/smartsheet-column/EditOrAdd.vue
  12. 2
      packages/nc-gui-v2/components/smartsheet-column/RatingOptions.vue
  13. 2
      packages/nc-gui-v2/components/smartsheet-header/VirtualCell.vue
  14. 3
      packages/nc-gui-v2/components/smartsheet-toolbar/ColumnFilter.vue
  15. 2
      packages/nc-gui-v2/components/smartsheet-toolbar/ColumnFilterMenu.vue
  16. 8
      packages/nc-gui-v2/components/smartsheet-toolbar/MoreActions.vue
  17. 1
      packages/nc-gui-v2/components/smartsheet-toolbar/ShareView.vue
  18. 10
      packages/nc-gui-v2/components/smartsheet-toolbar/SharedViewList.vue
  19. 6
      packages/nc-gui-v2/components/smartsheet/Cell.vue
  20. 5
      packages/nc-gui-v2/components/smartsheet/Gallery.vue
  21. 9
      packages/nc-gui-v2/components/smartsheet/Grid.vue
  22. 4
      packages/nc-gui-v2/components/smartsheet/sidebar/index.vue
  23. 3
      packages/nc-gui-v2/components/tabs/Smartsheet.vue
  24. 4
      packages/nc-gui-v2/components/webhook/Test.vue
  25. 8
      packages/nc-gui-v2/layouts/base.vue
  26. 10
      packages/nc-gui-v2/pages/index/user/index.vue
  27. 4
      packages/nc-gui-v2/pages/index/user/index/index.vue
  28. 6
      packages/nc-gui-v2/pages/nc/[projectId]/index/index.vue
  29. 4
      packages/nc-gui-v2/pages/project/index/[id].vue
  30. 6
      packages/nc-gui-v2/pages/project/index/create.vue
  31. 2
      packages/nc-gui-v2/pages/projects/index.vue

4
packages/nc-gui-v2/components/cell/MultiSelect.vue

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { computed, inject } from '#imports'
import { ColumnInj, EditModeInj } from '~/context'
import { ColumnInj } from '~/context'
interface Props {
modelValue: string | null
@ -11,8 +11,6 @@ const { modelValue } = defineProps<Props>()
const emit = defineEmits(['update:modelValue'])
const column = inject(ColumnInj)
const isForm = inject<boolean>('isForm', false)
const editEnabled = inject(EditModeInj, ref(false))
const options = computed(() => column?.value?.dtxp?.split(',').map((v) => v.replace(/\\'/g, "'").replace(/^'|'$/g, '')) || [])

2
packages/nc-gui-v2/components/cell/attachment/Carousel.vue

@ -2,7 +2,7 @@
import { onKeyDown } from '@vueuse/core'
import { useAttachmentCell } from './utils'
import { isImage } from '~/utils'
import { computed, onClickOutside, ref, watch } from '#imports'
import { computed, onClickOutside, ref } from '#imports'
import MaterialSymbolsArrowCircleRightRounded from '~icons/material-symbols/arrow-circle-right-rounded'
import MaterialSymbolsArrowCircleLeftRounded from '~icons/material-symbols/arrow-circle-left-rounded'
import MdiCloseCircle from '~icons/mdi/close-circle'

10
packages/nc-gui-v2/components/dashboard/TreeView.vue

@ -1,7 +1,6 @@
<script setup lang="ts">
import type { TableType } from 'nocodb-sdk'
import Sortable from 'sortablejs'
import { useToast } from 'vue-toastification'
import { useNuxtApp, useRoute } from '#app'
import { computed, useProject, useTable, useTabs, watchEffect } from '#imports'
import { TabType } from '~/composables'
@ -292,23 +291,22 @@ const activeTable = computed(() => {
}
}
.nc-tree-item{
.nc-tree-item {
@apply relative cursor-pointer after:(content-[''] absolute top-0 left-0 w-full h-full right-0 !bg-current transition transition-opactity duration-100 opacity-0);
}
.nc-tree-item svg{
@apply text-gray-500
.nc-tree-item svg {
@apply text-gray-500;
}
.nc-tree-item.active {
@apply !text-primary after:(!opacity-5);
svg {
@apply !text-primary
@apply !text-primary;
}
}
.nc-tree-item:hover {
@apply !text-grey after:(!opacity-2);
}
</style>

6
packages/nc-gui-v2/components/dlg/AirtableImport.vue

@ -25,9 +25,7 @@ const { $state } = useNuxtApp()
const toast = useToast()
const { sqlUi, project, loadTables } = useProject()
const loading = ref(false)
const { project, loadTables } = useProject()
const showGoToDashboardButton = ref(false)
@ -78,7 +76,7 @@ const dialogShow = computed({
const useForm = Form.useForm
const { resetFields, validate, validateInfos } = useForm(syncSource, validators)
const { validateInfos } = useForm(syncSource, validators)
const disableImportButton = computed(() => {
return !syncSource.value.details.apiKey || !syncSource.value.details.syncSourceUrlOrId

2
packages/nc-gui-v2/components/dlg/QuickImport.vue

@ -68,7 +68,7 @@ const validators = computed(() => {
}
})
const { resetFields, validate, validateInfos } = useForm(importState, validators)
const { validate, validateInfos } = useForm(importState, validators)
const importMeta = computed(() => {
if (IsImportTypeExcel.value) {

23
packages/nc-gui-v2/components/dlg/TableCreate.vue

@ -1,6 +1,5 @@
<script setup lang="ts">
import { Form } from 'ant-design-vue'
import { useToast } from 'vue-toastification'
import { onMounted, useProject, useTable, useTabs } from '#imports'
import { validateTableName } from '~/utils/validation'
import { TabType } from '~/composables'
@ -15,12 +14,6 @@ const emit = defineEmits(['update:modelValue'])
const dialogShow = useVModel(props, 'modelValue', emit)
const toast = useToast()
const valid = ref(false)
const isIdToggleAllowed = ref(false)
const isAdvanceOptVisible = ref(false)
const { addTab } = useTabs()
@ -38,17 +31,17 @@ const { table, createTable, generateUniqueTitle, tables, project } = useTable(as
dialogShow.value = false
})
const prefix = computed(() => project?.value?.prefix || '')
// const prefix = computed(() => project?.value?.prefix || '')
const validateDuplicateAlias = (v: string) => {
return (tables?.value || []).every((t) => t.title !== (v || '')) || 'Duplicate table alias'
}
const validateLeadingOrTrailingWhiteSpace = (v: string) => {
return !/^\s+|\s+$/.test(v) || 'Leading or trailing whitespace not allowed in table name'
}
const validateDuplicate = (v: string) => {
return (tables?.value || []).every((t) => t.table_name.toLowerCase() !== (v || '').toLowerCase()) || 'Duplicate table name'
}
// const validateLeadingOrTrailingWhiteSpace = (v: string) => {
// return !/^\s+|\s+$/.test(v) || 'Leading or trailing whitespace not allowed in table name'
// }
// const validateDuplicate = (v: string) => {
// return (tables?.value || []).every((t) => t.table_name.toLowerCase() !== (v || '').toLowerCase()) || 'Duplicate table name'
// }
const inputEl = ref<HTMLInputElement>()
@ -60,7 +53,7 @@ const validators = computed(() => {
table_name: [validateTableName],
}
})
const { resetFields, validate, validateInfos } = useForm(table, validators)
const { validateInfos } = useForm(table, validators)
onMounted(() => {
generateUniqueTitle()

6
packages/nc-gui-v2/components/dlg/TableRename.vue

@ -28,9 +28,9 @@ const dialogShow = computed({
const { updateTab } = useTabs()
const { loadTables } = useProject()
const { project, tables } = useProject()
const { tables } = useProject()
const prefix = computed(() => project?.value?.prefix || '')
// const prefix = computed(() => project?.value?.prefix || '')
const inputEl = $ref<any>()
let loading = $ref(false)
@ -60,7 +60,7 @@ const validators = computed(() => {
],
}
})
const { resetFields, validate, validateInfos } = useForm(formState, validators)
const { validateInfos } = useForm(formState, validators)
watchEffect(() => {
if (tableMeta?.title) formState.title = tableMeta?.title

8
packages/nc-gui-v2/components/general/MiniSidebar.vue

@ -1,12 +1,12 @@
<script lang="ts" setup>
import { breakpointsTailwind } from '@vueuse/core'
// import { breakpointsTailwind } from '@vueuse/core'
import { navigateTo } from '#app'
import { computed, useBreakpoints, useGlobal, useProject, useRoute, useSidebar } from '#imports'
import { computed, useGlobal, useProject, useRoute, useSidebar } from '#imports'
/** get current breakpoints (for enabling sidebar) */
const breakpoints = useBreakpoints(breakpointsTailwind)
// const breakpoints = useBreakpoints(breakpointsTailwind)
const { signOut, signedIn, isLoading, user } = useGlobal()
const { signOut, signedIn, user } = useGlobal()
const { isOpen } = useSidebar({ isOpen: true })

2
packages/nc-gui-v2/components/smartsheet-column/CurrencyOptions.vue

@ -7,7 +7,7 @@ interface Option {
value: string
}
const { formState, validateInfos, setAdditionalValidations, sqlUi, onDataTypeChange, onAlter } = useColumnCreateStoreOrThrow()
const { formState, validateInfos, setAdditionalValidations } = useColumnCreateStoreOrThrow()
const validators = {
'meta.currency_locale': [

2
packages/nc-gui-v2/components/smartsheet-column/DurationOptions.vue

@ -2,7 +2,7 @@
import { useColumnCreateStoreOrThrow } from '#imports'
import { durationOptions } from '@/utils'
const { formState, validateInfos, setAdditionalValidations, sqlUi, onDataTypeChange, onAlter } = useColumnCreateStoreOrThrow()
const { formState } = useColumnCreateStoreOrThrow()
const durationOptionList =
durationOptions.map((o) => ({

13
packages/nc-gui-v2/components/smartsheet-column/EditOrAdd.vue

@ -21,17 +21,8 @@ const { getMeta } = useMetas()
const formulaOptionsRef = ref()
const {
formState,
resetFields,
validate,
validateInfos,
onUidtOrIdTypeChange,
onAlter,
addOrUpdate,
generateNewColumnMeta,
isEdit,
} = useColumnCreateStoreOrThrow()
const { formState, validateInfos, onUidtOrIdTypeChange, onAlter, addOrUpdate, generateNewColumnMeta, isEdit } =
useColumnCreateStoreOrThrow()
const columnToValidate = [UITypes.Email, UITypes.URL, UITypes.PhoneNumber]

2
packages/nc-gui-v2/components/smartsheet-column/RatingOptions.vue

@ -3,7 +3,7 @@ import { Sketch } from '@ckpack/vue-color'
import { useColumnCreateStoreOrThrow } from '#imports'
import { enumColor, getMdiIcon } from '@/utils'
const { formState, validateInfos, setAdditionalValidations, sqlUi, onDataTypeChange, onAlter } = useColumnCreateStoreOrThrow()
const { formState } = useColumnCreateStoreOrThrow()
// cater existing v1 cases
const iconList = [

2
packages/nc-gui-v2/components/smartsheet-header/VirtualCell.vue

@ -16,7 +16,7 @@ provide(ColumnInj, column)
const { metas } = useMetas()
const meta = inject(MetaInj)
const { isLookup, isBt, isRollup, isMm, isHm, isFormula, isCount } = useVirtualCell(column)
const { isLookup, isBt, isRollup, isMm, isHm, isFormula } = useVirtualCell(column)
const colOptions = $computed(() => column.value?.colOptions)
const tableTile = $computed(() => meta?.value?.title)

3
packages/nc-gui-v2/components/smartsheet-toolbar/ColumnFilter.vue

@ -5,7 +5,7 @@ import FieldListAutoCompleteDropdown from './FieldListAutoCompleteDropdown.vue'
import { useNuxtApp } from '#app'
import { inject, useViewFilters } from '#imports'
import { comparisonOpList } from '~/utils/filterUtils'
import { ActiveViewInj, IsLockedInj, MetaInj, ReloadViewDataHookInj } from '~/context'
import { ActiveViewInj, MetaInj, ReloadViewDataHookInj } from '~/context'
import MdiDeleteIcon from '~icons/mdi/close-box'
import MdiAddIcon from '~icons/mdi/plus'
@ -16,7 +16,6 @@ const emit = defineEmits(['update:filtersLength'])
const meta = inject(MetaInj)
const activeView = inject(ActiveViewInj)
const reloadDataHook = inject(ReloadViewDataHookInj)
const isLocked = inject(IsLockedInj)
// todo: replace with inject or get from state
const shared = ref(false)

2
packages/nc-gui-v2/components/smartsheet-toolbar/ColumnFilterMenu.vue

@ -1,12 +1,10 @@
<script setup lang="ts">
import { watchEffect } from '@vue/runtime-core'
import type ColumnFilter from './ColumnFilter.vue'
import { useState } from '#app'
import { ActiveViewInj, IsLockedInj } from '~/context'
import MdiFilterIcon from '~icons/mdi/filter-outline'
import MdiMenuDownIcon from '~icons/mdi/menu-down'
const autoApplyFilter = useState('autoApplyFilter', () => false)
const isLocked = inject(IsLockedInj)
const activeView = inject(ActiveViewInj)

8
packages/nc-gui-v2/components/smartsheet-toolbar/MoreActions.vue

@ -18,10 +18,10 @@ const sharedViewListDlg = ref(false)
// todo : replace with inject
const publicViewId = null
// TODO:: identify based on meta
const isView = ref(false)
const { isUIAllowed } = useUIPermission()
// // TODO:: identify based on meta
// const isView = ref(false)
//
// const { isUIAllowed } = useUIPermission()
const { project } = useProject()

1
packages/nc-gui-v2/components/smartsheet-toolbar/ShareView.vue

@ -10,7 +10,6 @@ import { extractSdkResponseErrorMsg } from '~/utils/errorUtils'
import MdiOpenInNewIcon from '~icons/mdi/open-in-new'
import MdiCopyIcon from '~icons/mdi/content-copy'
const { isUIAllowed } = useUIPermission()
const { view, $api } = useSmartsheetStoreOrThrow()
const { copy } = useClipboard()

10
packages/nc-gui-v2/components/smartsheet-toolbar/SharedViewList.vue

@ -3,7 +3,6 @@ import { useClipboard } from '@vueuse/core'
import { ViewTypes } from 'nocodb-sdk'
import { useToast } from 'vue-toastification'
import { message } from 'ant-design-vue'
import { useRoute } from '#app'
import { onMounted, useSmartsheetStoreOrThrow } from '#imports'
import { extractSdkResponseErrorMsg } from '~/utils/errorUtils'
import MdiVisibilityOnIcon from '~icons/mdi/visibility'
@ -20,18 +19,17 @@ interface SharedViewType {
showPassword?: boolean
}
const { view, $api, meta } = useSmartsheetStoreOrThrow()
const { $api, meta } = useSmartsheetStoreOrThrow()
const { copy } = useClipboard()
const toast = useToast()
const route = useRoute()
const { dashboardUrl } = useDashboard()
let isLoading = $ref(false)
// let isLoading = $ref(false)
// let activeSharedView = $ref(null)
const sharedViewList = ref<SharedViewType[]>()
const loadSharedViewsList = async () => {
isLoading = true
// isLoading = true
const list = await $api.dbViewShare.list(meta.value?.id as string)
console.log(unref(sharedViewList))
@ -50,7 +48,7 @@ const loadSharedViewsList = async () => {
// activeSharedView = null
// }
isLoading = false
// isLoading = false
}
onMounted(loadSharedViewsList)

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

@ -12,9 +12,9 @@ interface Props {
editEnabled: boolean
}
interface Emits {
(event: 'update:modelValue', value: any): void
}
// interface Emits {
// (event: 'update:modelValue', value: any): void
// }
const props = defineProps<Props>()
const emit = defineEmits(['update:modelValue', 'save', 'navigate', 'update:editEnabled'])

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

@ -12,10 +12,7 @@ const meta = inject(MetaInj)
const view = inject(ActiveViewInj)
// todo: get from parent ( inject or use prop )
const isPublicView = false
const selected = reactive<{ row?: number | null; col?: number | null }>({})
const editEnabled = ref(false)
// const isPublicView = false
const { loadData, paginationData, formattedData: data, loadGalleryData, galleryData, changePage } = useViewData(meta, view as any)

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

@ -126,7 +126,7 @@ const makeEditable = (row: Row, col: ColumnType) => {
return
}
if (!isPkAvail.value && !row.rowMeta.new) {
message.info('Update not allowed for table which doesn\'t have primary Key')
message.info("Update not allowed for table which doesn't have primary Key")
return
}
if (col.ai) {
@ -259,8 +259,7 @@ const onNavigate = (dir: NavigateDir) => {
<div class="flex flex-col h-100 min-h-0 w-100">
<div class="nc-grid-wrapper min-h-0 flex-1 scrollbar-thin-dull">
<a-dropdown v-model:visible="contextMenu" :trigger="['contextmenu']">
<table ref="smartTable" class="xc-row-table nc-grid backgroundColorDefault"
@contextmenu.prevent="contextMenu = true">
<table ref="smartTable" class="xc-row-table nc-grid backgroundColorDefault" @contextmenu.prevent="contextMenu = true">
<thead>
<tr class="group">
<th>
@ -323,8 +322,8 @@ const onNavigate = (dir: NavigateDir) => {
:key="rowIndex + columnObj.title"
class="cell pointer nc-grid-cell"
:class="{
active: !isPublicView && selected.col === colIndex && selected.row === rowIndex,
}"
active: !isPublicView && selected.col === colIndex && selected.row === rowIndex,
}"
:data-col="columnObj.id"
:data-title="columnObj.title"
@click="selectCell(rowIndex, colIndex)"

4
packages/nc-gui-v2/components/smartsheet/sidebar/index.vue

@ -3,7 +3,7 @@ import type { FormType, GalleryType, GridType, KanbanType, ViewTypes } from 'noc
import MenuTop from './MenuTop.vue'
import MenuBottom from './MenuBottom.vue'
import Toolbar from './toolbar/index.vue'
import { computed, inject, provide, ref, useApi, useRoute, useViews, watch } from '#imports'
import { computed, inject, provide, ref, useRoute, useViews, watch } from '#imports'
import { ActiveViewInj, MetaInj, RightSidebarInj, ViewListInj } from '~/context'
const meta = inject(MetaInj, ref())
@ -12,8 +12,6 @@ const activeView = inject(ActiveViewInj, ref())
const { views, loadViews } = useViews(meta)
const { api } = useApi()
const route = useRoute()
provide(ViewListInj, views)

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

@ -1,6 +1,5 @@
<script setup lang="ts">
import type { ColumnType, TableType, ViewType } from 'nocodb-sdk'
import { ViewTypes } from 'nocodb-sdk'
import type { ColumnType, TableType } from 'nocodb-sdk'
import type { Ref } from 'vue'
import SmartsheetGrid from '../smartsheet/Grid.vue'
import { computed, inject, provide, useMetas, useProvideSmartsheetStore, watch, watchEffect } from '#imports'

4
packages/nc-gui-v2/components/webhook/Test.vue

@ -10,7 +10,7 @@ interface Props {
const { hook } = defineProps<Props>()
const { $state, $api, $e } = useNuxtApp()
const { $api } = useNuxtApp()
const toast = useToast()
@ -23,7 +23,7 @@ const activeKey = ref(0)
watch(
() => hook?.operation,
async (v) => {
async (_v) => {
await loadSampleData()
},
)

8
packages/nc-gui-v2/layouts/base.vue

@ -1,15 +1,13 @@
<script lang="ts" setup>
import { breakpointsTailwind } from '@vueuse/core'
// import { breakpointsTailwind } from '@vueuse/core'
import { navigateTo } from '#app'
import { computed, useBreakpoints, useGlobal, useProject, useRoute } from '#imports'
import { computed, useGlobal, useRoute } from '#imports'
/** get current breakpoints (for enabling sidebar) */
const breakpoints = useBreakpoints(breakpointsTailwind)
// const breakpoints = useBreakpoints(breakpointsTailwind)
const { signOut, signedIn, isLoading, user } = useGlobal()
const { project } = useProject()
const route = useRoute()
const email = computed(() => user.value?.email ?? '---')

10
packages/nc-gui-v2/pages/index/user/index.vue

@ -1,13 +1,3 @@
<script setup lang="ts">
import { navigateTo, useNuxtApp, useRoute } from '#app'
import MdiAccountCog from '~icons/mdi/account-cog'
import MdiFolderOutline from '~icons/mdi/folder-outline'
const { $api } = useNuxtApp()
const route = useRoute()
</script>
<template>
<NuxtLayout>
<NuxtPage />

4
packages/nc-gui-v2/pages/index/user/index/index.vue

@ -6,7 +6,7 @@ import { reactive, ref, useApi } from '#imports'
import MaterialSymbolsWarning from '~icons/material-symbols/warning'
import MdiKeyChange from '~icons/mdi/key-change'
const { api, isLoading } = useApi()
const { api } = useApi()
const { t } = useI18n()
@ -34,7 +34,7 @@ const formRules = {
{ required: true, message: t('msg.error.signUpRules.passwdRequired') },
// Passwords match
{
validator: (_: unknown, v: string) => {
validator: (_: unknown, _v: string) => {
return new Promise((resolve, reject) => {
if (form.password === form.passwordRepeat) return resolve(true)
reject(new Error(t('msg.error.signUpRules.passwdMismatch')))

6
packages/nc-gui-v2/pages/nc/[projectId]/index/index.vue

@ -21,12 +21,6 @@ const currentMenu = ref<string[]>(['addORImport'])
provide(TabMetaInj, activeTab)
function onEdit(targetKey: number, action: string) {
if (action !== 'add') {
closeTab(targetKey)
}
}
function openQuickImportDialog(type: string) {
quickImportDialog.value = true
importType.value = type

4
packages/nc-gui-v2/pages/project/index/[id].vue

@ -4,13 +4,13 @@ import type { Form } from 'ant-design-vue'
import type { ProjectType } from 'nocodb-sdk'
import { ref } from 'vue'
import { useToast } from 'vue-toastification'
import { navigateTo, useNuxtApp, useRoute } from '#app'
import { navigateTo, useRoute } from '#app'
import { extractSdkResponseErrorMsg } from '~/utils/errorUtils'
import { projectTitleValidator } from '~/utils/validation'
import MaterialSymbolsRocketLaunchOutline from '~icons/material-symbols/rocket-launch-outline'
import { nextTick, reactive, useSidebar } from '#imports'
const { api, isLoading } = useApi()
const { api } = useApi()
useSidebar({ hasSidebar: false })

6
packages/nc-gui-v2/pages/project/index/create.vue

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { onMounted, onUpdated } from '@vue/runtime-core'
import { onMounted } from '@vue/runtime-core'
import type { Form } from 'ant-design-vue'
import { useToast } from 'vue-toastification'
import { nextTick, reactive, ref, useApi, useSidebar } from '#imports'
@ -8,10 +8,6 @@ import { extractSdkResponseErrorMsg } from '~/utils/errorUtils'
import { projectTitleValidator } from '~/utils/validation'
import MaterialSymbolsRocketLaunchOutline from '~icons/material-symbols/rocket-launch-outline'
const name = ref('')
const valid = ref(false)
const { $e } = useNuxtApp()
const { api, isLoading } = useApi()

2
packages/nc-gui-v2/pages/projects/index.vue

@ -56,8 +56,6 @@ const deleteProject = (project: ProjectType) => {
},
})
}
const visible = ref(true)
</script>
<template>

Loading…
Cancel
Save