@ -0,0 +1,31 @@
|
||||
.nc-dashboard-layouts-propspanel-value-input { |
||||
@apply flex-grow py-1 px-3 border-grey-light border border-solid rounded-lg text-sm w-full my-2; |
||||
} |
||||
|
||||
.nc-dashboard-layouts-propspanel-description-input { |
||||
@apply flex-grow py-1 px-3 !border-gray-200 border border-solid rounded-lg text-sm w-full my-2; |
||||
} |
||||
|
||||
.nc-dashboard-layouts-propspanel-selectable-config-section { |
||||
@apply bg-gray-100 rouwded-lg p-2; |
||||
h3 { |
||||
@apply text-black; |
||||
} |
||||
h4 { |
||||
@apply text-gray-500 |
||||
} |
||||
} |
||||
|
||||
.nc-dashboard-layouts-propspanel-collapse { |
||||
background-color: transparent; |
||||
.nc-dashboard-layouts-propspanel-collapse-panel { |
||||
@apply border-1 border-grey-light rounded-lg my-2 min-w-full; |
||||
.ant-collapse-header { |
||||
@apply font-semibold; |
||||
@apply !text-sm !2xl:text-base; |
||||
} |
||||
h3 { |
||||
@apply text-gray-500; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,529 @@
|
||||
.nc-docs-page { |
||||
overflow-y: overlay; |
||||
height: calc(100vh - var(--topbar-height)); |
||||
|
||||
&::-webkit-scrollbar { |
||||
width: 6px; |
||||
} |
||||
&::-webkit-scrollbar-track { |
||||
background: #f6f6f600 !important; |
||||
} |
||||
&::-webkit-scrollbar-thumb { |
||||
background: #f6f6f600; |
||||
} |
||||
&::-webkit-scrollbar-thumb:hover { |
||||
background: #f6f6f600; |
||||
} |
||||
} |
||||
.nc-docs-page:hover { |
||||
&::-webkit-scrollbar { |
||||
width: 6px; |
||||
} |
||||
&::-webkit-scrollbar-track { |
||||
background: #f6f6f600 !important; |
||||
} |
||||
&::-webkit-scrollbar-thumb { |
||||
background: rgb(215, 215, 215); |
||||
} |
||||
&::-webkit-scrollbar-thumb:hover { |
||||
background: rgb(203, 203, 203); |
||||
} |
||||
} |
||||
|
||||
.nc-docs-page-title { |
||||
font-weight: 600; |
||||
font-size: 3rem; |
||||
line-height: 1.25; |
||||
word-break: break-all; |
||||
outline: none; |
||||
padding: 0; |
||||
color: black; |
||||
} |
||||
|
||||
.nc-docs-page-content { |
||||
@apply min-h-full; |
||||
.ProseMirror { |
||||
@apply min-h-full; |
||||
} |
||||
.ProseMirror-focused { |
||||
// remove all border |
||||
outline: none; |
||||
} |
||||
|
||||
[data-diff-node='ins'] { |
||||
@apply !bg-green-200 rounded-sm p-0.5 m-0.5; |
||||
} |
||||
|
||||
[data-diff-node='del'] { |
||||
@apply !bg-red-200 rounded-sm p-0.5 m-0.5; |
||||
} |
||||
|
||||
del { |
||||
@apply !bg-red-200 rounded-sm my-0.5; |
||||
text-decoration: none; |
||||
} |
||||
ins { |
||||
@apply !bg-green-200 rounded-sm my-0.5 mx-0.5; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
ins[isempty='true'] { |
||||
display: block; |
||||
color: transparent; |
||||
user-select: none; |
||||
@apply !w-full; |
||||
} |
||||
del[isempty='true'] { |
||||
display: block; |
||||
color: transparent; |
||||
user-select: none; |
||||
@apply !w-full; |
||||
} |
||||
|
||||
td { |
||||
ins { |
||||
@apply !p-0 !m-0; |
||||
} |
||||
} |
||||
|
||||
.draggable-block-wrapper{ |
||||
overflow: visible; |
||||
} |
||||
.draggable-block-wrapper.focused { |
||||
.attachment-wrapper .attachment { |
||||
@apply !bg-primary-selected; |
||||
} |
||||
} |
||||
|
||||
.draggable-block-wrapper.selected { |
||||
table { |
||||
@apply !bg-primary-selected; |
||||
tr:first-child td { |
||||
@apply !bg-primary-selected; |
||||
} |
||||
} |
||||
.attachment-wrapper .attachment { |
||||
@apply !bg-primary-selected; |
||||
} |
||||
p, |
||||
h1, |
||||
h2, |
||||
h3, |
||||
h4, |
||||
h5, |
||||
h6, |
||||
li, |
||||
blockquote, |
||||
pre, |
||||
code, |
||||
img, |
||||
.link-to-page-wrapper { |
||||
@apply !bg-primary-selected; |
||||
} |
||||
|
||||
.node-view-drag-content > ul { |
||||
@apply !bg-primary-selected; |
||||
} |
||||
} |
||||
|
||||
div[contenteditable='false'].ProseMirror { |
||||
user-select: text !important; |
||||
} |
||||
|
||||
p.is-empty::after, |
||||
h1.is-empty::after, |
||||
h2.is-empty::after, |
||||
h3.is-empty::after { |
||||
content: attr(data-placeholder); |
||||
float: left; |
||||
color: #afafaf; |
||||
pointer-events: none; |
||||
margin-top: -1.55rem; |
||||
margin-left: 0.01rem; |
||||
} |
||||
|
||||
[data-one-content='true'] [data-type='collapsable_content'] { |
||||
p.is-empty::after { |
||||
content: 'Empty collapsable. Press / to open the command menu or start writing'; |
||||
} |
||||
} |
||||
|
||||
p.is-empty::after { |
||||
margin-top: -1.55rem; |
||||
} |
||||
h1.is-empty::after { |
||||
margin-top: -2.85rem; |
||||
} |
||||
h2.is-empty::after { |
||||
margin-top: -2.25rem; |
||||
} |
||||
h3.is-empty::after { |
||||
margin-top: -1.8rem; |
||||
} |
||||
.collapsable-wrapper { |
||||
h1, |
||||
h2, |
||||
h3 { |
||||
margin-top: 0; |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
.editable { |
||||
.focused { |
||||
div[data-is-empty='true'] { |
||||
p::after { |
||||
content: 'Press / to open the command menu or start writing' !important; |
||||
float: left; |
||||
color: #afafaf; |
||||
pointer-events: none; |
||||
margin-top: -1.55rem; |
||||
margin-left: 0.01rem; |
||||
} |
||||
} |
||||
} |
||||
div.is-empty.focused { |
||||
p::after { |
||||
content: 'Press / to open the command menu or start writing' !important; |
||||
float: left; |
||||
color: #afafaf; |
||||
pointer-events: none; |
||||
margin-top: -1.55rem; |
||||
margin-left: 0.01rem; |
||||
} |
||||
} |
||||
} |
||||
|
||||
h1.is-empty::before, |
||||
h2.is-empty::before, |
||||
h3.is-empty::before { |
||||
color: #d6d6d6; |
||||
} |
||||
|
||||
.nc-docs-list-item > p { |
||||
margin-top: 0.25rem !important; |
||||
margin-bottom: 0.25rem !important; |
||||
} |
||||
|
||||
p { |
||||
font-weight: 400; |
||||
color: #000000; |
||||
font-size: 1rem; |
||||
margin-top: 0.25rem; |
||||
margin-bottom: 0.25rem; |
||||
} |
||||
|
||||
h1 { |
||||
font-weight: 600; |
||||
font-size: 1.85rem; |
||||
margin-bottom: 0.6em; |
||||
} |
||||
|
||||
h2 { |
||||
font-weight: 600; |
||||
font-size: 1.45rem; |
||||
margin-bottom: 0.5em; |
||||
} |
||||
|
||||
h3 { |
||||
font-weight: 600; |
||||
font-size: 1.15rem; |
||||
margin-bottom: 0.3em; |
||||
} |
||||
|
||||
h4 { |
||||
font-size: 1.2rem; |
||||
} |
||||
|
||||
h5 { |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
h6 { |
||||
font-size: 1rem; |
||||
} |
||||
|
||||
// Pre tag is the parent wrapper for Code block |
||||
pre { |
||||
background: #f2f4f7; |
||||
border-color: #d0d5dd; |
||||
border: 1px; |
||||
color: black; |
||||
font-family: 'JetBrainsMono', monospace; |
||||
padding: 1rem; |
||||
border-radius: 0.5rem; |
||||
@apply overflow-auto mt-3; |
||||
|
||||
code { |
||||
@apply !px-0; |
||||
} |
||||
} |
||||
|
||||
code { |
||||
background: #f2f4f7; |
||||
@apply rounded-md px-2 py-1; |
||||
color: inherit; |
||||
font-size: 0.8rem; |
||||
} |
||||
|
||||
|
||||
[data-group-type='list-item'] { |
||||
@apply flex items-start; |
||||
.tiptap-list-item-start { |
||||
@apply flex mt-1.125 pr-2 !select-none; |
||||
|
||||
input { |
||||
@apply mt-0.75 flex rounded-sm; |
||||
} |
||||
// Unchecked |
||||
input:not(:checked) { |
||||
// Add border to checkbox |
||||
border-width: 1.5px; |
||||
@apply border-gray-700; |
||||
} |
||||
} |
||||
|
||||
} |
||||
table { |
||||
[data-group-type='list-item'] { |
||||
.tiptap-list-item-start { |
||||
@apply mt-0.125; |
||||
} |
||||
} |
||||
} |
||||
|
||||
[data-type='ordered'] { |
||||
@apply flex flex-row items-start gap-x-1; |
||||
.tiptap-list-item-start > span::before { |
||||
margin-top: 6px; |
||||
content: attr(data-number) '. '; |
||||
display: inline-block; |
||||
white-space: nowrap; |
||||
} |
||||
.tiptap-list-item-content { |
||||
@apply flex flex-grow; |
||||
} |
||||
} |
||||
|
||||
[data-type='image'] { |
||||
@apply mb-3 |
||||
} |
||||
|
||||
hr { |
||||
border: 0; |
||||
border-top: 1px solid #ccc; |
||||
margin: 1.5em 0; |
||||
} |
||||
|
||||
hr.ProseMirror-selectednode { |
||||
// outline with rounded corners |
||||
outline: 4px solid #e8eafd; |
||||
border-radius: 4px; |
||||
} |
||||
.focused { |
||||
hr { |
||||
// outline with rounded corners |
||||
outline: 4px solid #e8eafd; |
||||
border-radius: 4px; |
||||
} |
||||
} |
||||
.selected { |
||||
hr { |
||||
// outline with rounded corners |
||||
outline: 4px solid #e8eafd; |
||||
border-radius: 4px; |
||||
} |
||||
} |
||||
|
||||
.selected { |
||||
.external-content-wrapper { |
||||
// outline with rounded corners |
||||
outline: 2px solid #e8eafd; |
||||
border-radius: 1px; |
||||
} |
||||
} |
||||
|
||||
.external-content-wrapper.ProseMirror-selectednode { |
||||
// outline with rounded corners |
||||
outline: 2px solid #e8eafd; |
||||
border-radius: 1px; |
||||
} |
||||
|
||||
blockquote { |
||||
border-left: 3px solid #d0d5dd; |
||||
padding: 0 1em; |
||||
color: #666; |
||||
margin: 1em 0; |
||||
font-style: italic; |
||||
} |
||||
|
||||
.column-resize-handle { |
||||
background-color: #e3e5ff !important; |
||||
width: 6px; |
||||
cursor: col-resize; |
||||
z-index: 1; |
||||
} |
||||
|
||||
.resize-cursor { |
||||
cursor: ew-resize; |
||||
cursor: col-resize; |
||||
} |
||||
|
||||
.external-content-wrapper { |
||||
@apply bg-gray-100 my-2; |
||||
} |
||||
|
||||
div[data-type='column'] { |
||||
@apply flex flex-row gap-x-12 justify-between; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Table styles |
||||
*/ |
||||
|
||||
.tiptap-table-wrapper { |
||||
@apply !pb-4 !pt-4; |
||||
} |
||||
|
||||
table { |
||||
border-collapse: collapse; |
||||
table-layout: fixed; |
||||
width: 100%; |
||||
padding-top: 2rem; |
||||
padding-bottom: 2rem; |
||||
overflow: visible; |
||||
tbody { |
||||
overflow: visible; |
||||
} |
||||
td { |
||||
.tiptap-list-item-start { |
||||
@apply -mt-1; |
||||
} |
||||
position: relative; |
||||
min-width: 1em; |
||||
border: 1px solid #e5e5e5; |
||||
overflow: visible !important; |
||||
height: 20px; |
||||
border-top: 0; |
||||
padding-left: 1rem; |
||||
padding-right: 1rem; |
||||
padding-top: 0.5rem; |
||||
padding-bottom: 0.5rem; |
||||
} |
||||
|
||||
// First row's td |
||||
tr:first-child { |
||||
td { |
||||
border-top: 1px solid #e5e5e5 !important; |
||||
background-color: #fafbfb; |
||||
p { |
||||
font-weight: 500; |
||||
} |
||||
} |
||||
} |
||||
|
||||
th { |
||||
@apply font-semibold; |
||||
background-color: #fafbfb; |
||||
} |
||||
|
||||
.column-resize-handle { |
||||
position: absolute; |
||||
right: -2px; |
||||
top: 0; |
||||
bottom: 0px; |
||||
margin-top: 1px; |
||||
margin-bottom: 1px; |
||||
width: 8px; |
||||
outline: 1px solid #e3e5ff; |
||||
} |
||||
|
||||
p { |
||||
margin: 0; |
||||
} |
||||
|
||||
.column-resize-handle { |
||||
background-color: #e3e5ff !important; |
||||
width: 3px; |
||||
cursor: col-resize; |
||||
z-index: 1; |
||||
} |
||||
} |
||||
|
||||
// First cell |
||||
tr:hover > td:first-child .row-drag-handle { |
||||
display: block; |
||||
} |
||||
|
||||
tr:first-child > td:hover .tiptap-column-options { |
||||
display: flex; |
||||
} |
||||
|
||||
tr:first-child > td:only-child:hover .tiptap-column-options { |
||||
display: none; |
||||
} |
||||
|
||||
|
||||
.selectedCell { |
||||
@apply !bg-primary-selected; |
||||
|
||||
// transition for white to blue background with delay as row/column creation causes cell selection for a moment which causes flicker |
||||
transition: background-color 1ms ease-out 1ms; |
||||
|
||||
.tiptap-column-options { |
||||
display: none !important; |
||||
} |
||||
.row-drag-handle { |
||||
display: none !important; |
||||
} |
||||
} |
||||
|
||||
.tiptap-table-cell { |
||||
@apply w-full; |
||||
} |
||||
|
||||
.selected { |
||||
.callout { |
||||
@apply bg-primary-selected; |
||||
} |
||||
} |
||||
.callout { |
||||
@apply my-2.5 px-2 py-2 rounded-md; |
||||
[data-type='bullet'] { |
||||
margin-left: 0.7rem; |
||||
} |
||||
.nc-callout-emoji { |
||||
@apply text-base; |
||||
} |
||||
} |
||||
|
||||
|
||||
[data-bg-color='gray'] { |
||||
@apply bg-gray-100 bg-opacity-30; |
||||
} |
||||
[data-bg-color='brown'] { |
||||
@apply bg-amber-600 bg-opacity-20; |
||||
} |
||||
[data-bg-color='orange'] { |
||||
@apply bg-orange-100 bg-opacity-50; |
||||
} |
||||
[data-bg-color='yellow'] { |
||||
@apply bg-yellow-100 bg-opacity-50; |
||||
} |
||||
[data-bg-color='green'] { |
||||
@apply bg-green-100 bg-opacity-50; |
||||
} |
||||
[data-bg-color='blue'] { |
||||
@apply bg-blue-100 bg-opacity-50; |
||||
} |
||||
[data-bg-color='purple'] { |
||||
@apply bg-purple-100 bg-opacity-50; |
||||
} |
||||
[data-bg-color='pink'] { |
||||
@apply bg-pink-100 bg-opacity-50; |
||||
} |
||||
[data-bg-color='red'] { |
||||
@apply bg-red-100 bg-opacity-50; |
||||
} |
||||
} |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 647 B |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 722 B |
After Width: | Height: | Size: 557 B |
After Width: | Height: | Size: 845 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 300 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 712 B |
After Width: | Height: | Size: 602 B |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 518 B |
After Width: | Height: | Size: 486 B |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
<template> |
||||
<div /> |
||||
</template> |
@ -0,0 +1,153 @@
|
||||
<script lang="ts" setup> |
||||
import { storeToRefs } from 'pinia' |
||||
import { useGlobal } from '#imports' |
||||
|
||||
const router = useRouter() |
||||
|
||||
const route = router.currentRoute |
||||
|
||||
const workspaceStore = useWorkspace() |
||||
|
||||
const { activeWorkspace, isWorkspaceOwnerOrCreator } = storeToRefs(workspaceStore) |
||||
|
||||
const projectStore = useProject() |
||||
|
||||
const { isSharedBase } = storeToRefs(projectStore) |
||||
|
||||
const { navigateToWorkspaceSettings } = useWorkspace() |
||||
|
||||
const { isUIAllowed } = useUIPermission() |
||||
|
||||
const dialogOpen = ref(false) |
||||
|
||||
const openDialogKey = ref<string>('') |
||||
|
||||
const dataSourcesState = ref<string>('') |
||||
|
||||
const projectId = ref<string>() |
||||
|
||||
const isCreateProjectOpen = ref(false) |
||||
|
||||
function toggleDialog(value?: boolean, key?: string, dsState?: string, pId?: string) { |
||||
dialogOpen.value = value ?? !dialogOpen.value |
||||
openDialogKey.value = key || '' |
||||
dataSourcesState.value = dsState || '' |
||||
projectId.value = pId || '' |
||||
} |
||||
|
||||
// todo: |
||||
const currentVersion = ref('') |
||||
|
||||
const isTreeViewOnScrollTop = ref(true) |
||||
const onTreeViewScrollTop = (onScrollTop: boolean) => { |
||||
isTreeViewOnScrollTop.value = !onScrollTop |
||||
} |
||||
|
||||
const { appInfo } = useGlobal() |
||||
|
||||
const navigateToSettings = () => { |
||||
navigateToWorkspaceSettings() |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div |
||||
class="nc-sidebar flex flex-col bg-gray-50 outline-r-1 outline-gray-100 select-none" |
||||
:style="{ |
||||
outlineWidth: '1px', |
||||
height: isSharedBase ? '100%' : null, |
||||
}" |
||||
> |
||||
<div class="flex flex-col"> |
||||
<div style="border-bottom-width: 1px" class="flex items-center px-1 nc-sidebar-header !border-0 py-1.25 pl-2"> |
||||
<div class="flex flex-row flex-grow hover:bg-gray-100 pl-2 pr-1 py-0.5 rounded-md max-w-full"> |
||||
<a |
||||
v-if="isSharedBase" |
||||
class="w-[40px] min-w-[40px] transition-all duration-200 p-1 cursor-pointer transform hover:scale-105" |
||||
href="https://github.com/nocodb/nocodb" |
||||
target="_blank" |
||||
> |
||||
<img width="25" alt="NocoDB" src="~/assets/img/icons/512x512.png" /> |
||||
</a> |
||||
|
||||
<WorkspaceMenu :workspace="activeWorkspace" :is-open="true"> |
||||
<template #brandIcon> |
||||
<div |
||||
v-if="!isSharedBase" |
||||
v-e="['c:navbar:home']" |
||||
data-testid="nc-noco-brand-icon" |
||||
class="w-[29px] min-w-[29px] nc-noco-brand-icon" |
||||
> |
||||
<img width="25" class="mr-0" alt="NocoDB" src="~/assets/img/icons/512x512.png" /> |
||||
</div> |
||||
</template> |
||||
</WorkspaceMenu> |
||||
</div> |
||||
</div> |
||||
|
||||
<template v-if="!isSharedBase"> |
||||
<div class="h-auto"> |
||||
<div |
||||
v-if="isWorkspaceOwnerOrCreator" |
||||
role="button" |
||||
class="nc-sidebar-top-button" |
||||
data-testid="nc-sidebar-team-settings-btn" |
||||
@click="navigateToSettings" |
||||
> |
||||
<GeneralIcon icon="settings" class="!h-3.9" /> |
||||
<div>Team & Settings</div> |
||||
</div> |
||||
<WorkspaceCreateProjectBtn |
||||
v-if="isUIAllowed('projectCreate', false)" |
||||
v-model:is-open="isCreateProjectOpen" |
||||
modal |
||||
type="text" |
||||
class="!p-0 mx-1" |
||||
data-testid="nc-sidebar-create-project-btn" |
||||
:active-workspace-id="route.params.typeOrId" |
||||
> |
||||
<div |
||||
class="gap-x-2 flex flex-row w-full items-center nc-sidebar-top-button !my-0 !mx-0" |
||||
:class="{ |
||||
'bg-gray-100': isCreateProjectOpen, |
||||
}" |
||||
> |
||||
<MdiPlus class="!h-4" /> |
||||
|
||||
<div class="flex">{{ $t('title.newProj') }}</div> |
||||
</div> |
||||
</WorkspaceCreateProjectBtn> |
||||
</div> |
||||
|
||||
<div class="w-full mt-2"></div> |
||||
|
||||
<div class="text-gray-500 mx-5 font-medium mb-1.5">{{ $t('objects.projects') }}</div> |
||||
<div |
||||
class="w-full border-b-1" |
||||
:class="{ |
||||
'border-gray-200': !isTreeViewOnScrollTop, |
||||
'border-transparent': isTreeViewOnScrollTop, |
||||
}" |
||||
></div> |
||||
</template> |
||||
</div> |
||||
<LazyDashboardTreeViewNew |
||||
class="flex-1" |
||||
:class="{ |
||||
'nc-shared-base': isSharedBase, |
||||
}" |
||||
@create-base-dlg="toggleDialog(true, 'dataSources', undefined, projectId)" |
||||
@on-scroll-top="onTreeViewScrollTop" |
||||
/> |
||||
</div> |
||||
</template> |
||||
|
||||
<style lang="scss" scoped> |
||||
.nc-sidebar-top-button { |
||||
@apply flex flex-row mx-1 px-3.5 rounded-md items-center py-0.75 my-0.5 gap-x-2 hover:bg-gray-200 cursor-pointer; |
||||
} |
||||
|
||||
:deep(.nc-shared-base.nc-treeview-container) { |
||||
@apply !h-full; |
||||
} |
||||
</style> |
@ -0,0 +1,262 @@
|
||||
<script lang="ts" setup> |
||||
import type { ProjectType } from 'nocodb-sdk' |
||||
import { storeToRefs } from 'pinia' |
||||
import { toRef } from '@vue/reactivity' |
||||
import { resolveComponent } from '@vue/runtime-core' |
||||
import { ref } from 'vue' |
||||
import { ProjectRoleInj, useDialog, useUIPermission } from '#imports' |
||||
|
||||
const props = withDefaults( |
||||
defineProps<{ |
||||
project: ProjectType |
||||
baseIndex?: number |
||||
}>(), |
||||
{ |
||||
baseIndex: 0, |
||||
}, |
||||
) |
||||
|
||||
const emit = defineEmits<{ |
||||
openTableCreateDialog: () => void |
||||
}>() |
||||
|
||||
const { isUIAllowed } = useUIPermission() |
||||
|
||||
const project = toRef(props, 'project') |
||||
|
||||
const { $e } = useNuxtApp() |
||||
|
||||
const projectStore = useProject() |
||||
|
||||
const { isSharedBase } = storeToRefs(projectStore) |
||||
|
||||
const projectRole = inject(ProjectRoleInj) |
||||
|
||||
function openSchemaMagicDialog(baseId?: string) { |
||||
if (!baseId) return |
||||
|
||||
$e('c:table:create:navdraw') |
||||
|
||||
const isOpen = ref(true) |
||||
|
||||
const { close } = useDialog(resolveComponent('DlgSchemaMagic'), { |
||||
'modelValue': isOpen, |
||||
'baseId': baseId, |
||||
'onUpdate:modelValue': closeDialog, |
||||
}) |
||||
|
||||
function closeDialog() { |
||||
isOpen.value = false |
||||
|
||||
close(1000) |
||||
} |
||||
} |
||||
|
||||
function openQuickImportDialog(type: string, baseId?: string) { |
||||
if (!baseId) return |
||||
|
||||
$e(`a:actions:import-${type}`) |
||||
|
||||
const isOpen = ref(true) |
||||
|
||||
const { close } = useDialog(resolveComponent('DlgQuickImport'), { |
||||
'modelValue': isOpen, |
||||
'importType': type, |
||||
'baseId': baseId, |
||||
'onUpdate:modelValue': closeDialog, |
||||
}) |
||||
|
||||
function closeDialog() { |
||||
isOpen.value = false |
||||
|
||||
close(1000) |
||||
} |
||||
} |
||||
|
||||
function openAirtableImportDialog(baseId?: string) { |
||||
if (!baseId) return |
||||
|
||||
$e('a:actions:import-airtable') |
||||
|
||||
const isOpen = ref(true) |
||||
|
||||
const { close } = useDialog(resolveComponent('DlgAirtableImport'), { |
||||
'modelValue': isOpen, |
||||
'baseId': baseId, |
||||
'onUpdate:modelValue': closeDialog, |
||||
}) |
||||
|
||||
function closeDialog() { |
||||
isOpen.value = false |
||||
|
||||
close(1000) |
||||
} |
||||
} |
||||
|
||||
function openTableCreateMagicDialog(baseId?: string) { |
||||
if (!baseId) return |
||||
|
||||
$e('c:table:create:navdraw') |
||||
|
||||
const isOpen = ref(true) |
||||
|
||||
const { close } = useDialog(resolveComponent('DlgTableMagic'), { |
||||
'modelValue': isOpen, |
||||
'baseId': baseId, |
||||
'onUpdate:modelValue': closeDialog, |
||||
}) |
||||
|
||||
function closeDialog() { |
||||
isOpen.value = false |
||||
|
||||
close(1000) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<div |
||||
v-if="isUIAllowed('table-create', false, projectRole)" |
||||
class="group flex items-center gap-2 pl-2 pr-4.75 py-1 text-primary/70 hover:(text-primary/100) cursor-pointer select-none" |
||||
@click="emit('openTableCreateDialog')" |
||||
> |
||||
<PhPlusThin class="w-5 ml-2" /> |
||||
|
||||
<span class="text-gray-500 group-hover:(text-primary/100) flex-1 nc-add-new-table">{{ $t('tooltip.addTable') }}</span> |
||||
|
||||
<a-dropdown v-if="!isSharedBase" :trigger="['click']" overlay-class-name="nc-dropdown-import-menu" @click.stop> |
||||
<GeneralIcon |
||||
icon="threeDotVertical" |
||||
class="transition-opacity opacity-0 group-hover:opacity-100 nc-import-menu outline-0" |
||||
/> |
||||
|
||||
<template #overlay> |
||||
<a-menu class="!py-0 rounded text-sm"> |
||||
<a-menu-item-group class="!px-0 !mx-0"> |
||||
<template #title> |
||||
<div class="flex items-center"> |
||||
Noco |
||||
<GeneralIcon icon="magic" class="ml-1 text-orange-400" /> |
||||
</div> |
||||
</template> |
||||
<a-menu-item key="table-magic" @click="openTableCreateMagicDialog(project.bases[baseIndex].id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="magic1" class="group-hover:text-accent" /> |
||||
Create table |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="schema-magic" @click="openSchemaMagicDialog(project.bases[baseIndex].id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="magic1" class="group-hover:text-accent" /> |
||||
Create schema |
||||
</div> |
||||
</a-menu-item> |
||||
</a-menu-item-group> |
||||
|
||||
<a-menu-divider class="my-0" /> |
||||
|
||||
<!-- Quick Import From --> |
||||
<a-menu-item-group :title="$t('title.quickImportFrom')" class="!px-0 !mx-0"> |
||||
<a-menu-item |
||||
v-if="isUIAllowed('airtableImport', false, projectRole)" |
||||
key="quick-import-airtable" |
||||
@click="openAirtableImportDialog(project.bases[baseIndex].id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="airtable" class="group-hover:text-accent" /> |
||||
Airtable |
||||
</div> |
||||
</a-menu-item> |
||||
|
||||
<a-menu-item |
||||
v-if="isUIAllowed('csvImport', false, projectRole)" |
||||
key="quick-import-csv" |
||||
@click="openQuickImportDialog('csv', project.bases[baseIndex].id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="csv" class="group-hover:text-accent" /> |
||||
CSV file |
||||
</div> |
||||
</a-menu-item> |
||||
|
||||
<a-menu-item |
||||
v-if="isUIAllowed('jsonImport', false, projectRole)" |
||||
key="quick-import-json" |
||||
@click="openQuickImportDialog('json', project.bases[baseIndex].id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="json" class="group-hover:text-accent" /> |
||||
JSON file |
||||
</div> |
||||
</a-menu-item> |
||||
|
||||
<a-menu-item |
||||
v-if="isUIAllowed('excelImport', false, projectRole)" |
||||
key="quick-import-excel" |
||||
@click="openQuickImportDialog('excel', project.bases[baseIndex].id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="excel" class="group-hover:text-accent" /> |
||||
Microsoft Excel |
||||
</div> |
||||
</a-menu-item> |
||||
</a-menu-item-group> |
||||
|
||||
<a-menu-divider class="my-0" /> |
||||
|
||||
<!-- <a-menu-item-group title="Connect to new datasource" class="!px-0 !mx-0"> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.MYSQL, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<LogosMysqlIcon class="group-hover:text-accent" /> |
||||
MySQL |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.PG, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<LogosPostgresql class="group-hover:text-accent" /> |
||||
Postgres |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.SQLITE, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<VscodeIconsFileTypeSqlite class="group-hover:text-accent" /> |
||||
SQLite |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.MSSQL, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<SimpleIconsMicrosoftsqlserver class="group-hover:text-accent" /> |
||||
MSSQL |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item |
||||
v-if="appInfo.ee" |
||||
key="connect-new-source" |
||||
@click="toggleDialog(true, 'dataSources', ClientType.SNOWFLAKE, project.id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<LogosSnowflakeIcon class="group-hover:text-accent" /> |
||||
Snowflake |
||||
</div> |
||||
</a-menu-item> |
||||
</a-menu-item-group> |
||||
|
||||
<a-menu-divider class="my-0" /> --> |
||||
|
||||
<a-menu-item v-if="isUIAllowed('importRequest', false, projectRole)" key="add-new-table" class="py-1 rounded-b"> |
||||
<a |
||||
v-e="['e:datasource:import-request']" |
||||
href="https://github.com/nocodb/nocodb/issues/2052" |
||||
target="_blank" |
||||
class="prose-sm hover:(!text-primary !opacity-100) color-transition nc-project-menu-item group after:(!rounded-b)" |
||||
> |
||||
<GeneralIcon icon="openInNew" class="group-hover:text-accent" /> |
||||
<!-- Request a data source you need? --> |
||||
{{ $t('labels.requestDataSource') }} |
||||
</a> |
||||
</a-menu-item> |
||||
</a-menu> |
||||
</template> |
||||
</a-dropdown> |
||||
</div> |
||||
</template> |
@ -0,0 +1,179 @@
|
||||
<script lang="ts" setup> |
||||
import type { BaseType, ProjectType } from 'nocodb-sdk' |
||||
|
||||
const props = defineProps<{ |
||||
base: BaseType |
||||
project: ProjectType |
||||
}>() |
||||
|
||||
const base = toRef(props, 'base') |
||||
|
||||
const { isUIAllowed } = useUIPermission() |
||||
|
||||
const projectRole = inject(ProjectRoleInj) |
||||
|
||||
const { $e } = useNuxtApp() |
||||
|
||||
function openAirtableImportDialog(baseId?: string) { |
||||
if (!baseId) return |
||||
|
||||
$e('a:actions:import-airtable') |
||||
|
||||
const isOpen = ref(true) |
||||
|
||||
const { close } = useDialog(resolveComponent('DlgAirtableImport'), { |
||||
'modelValue': isOpen, |
||||
'baseId': baseId, |
||||
'onUpdate:modelValue': closeDialog, |
||||
}) |
||||
|
||||
function closeDialog() { |
||||
isOpen.value = false |
||||
|
||||
close(1000) |
||||
} |
||||
} |
||||
|
||||
function openQuickImportDialog(type: string) { |
||||
if (!base.value?.id) return |
||||
|
||||
$e(`a:actions:import-${type}`) |
||||
|
||||
const isOpen = ref(true) |
||||
|
||||
const { close } = useDialog(resolveComponent('DlgQuickImport'), { |
||||
'modelValue': isOpen, |
||||
'importType': type, |
||||
'baseId': base.value.id, |
||||
'onUpdate:modelValue': closeDialog, |
||||
}) |
||||
|
||||
function closeDialog() { |
||||
isOpen.value = false |
||||
|
||||
close(1000) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<a-menu-divider class="my-0" /> |
||||
|
||||
<!-- Quick Import From --> |
||||
<a-sub-menu class="py-0"> |
||||
<template #title> |
||||
<div class="nc-project-menu-item group"> |
||||
<GeneralIcon icon="download" class="-ml-0.25" /> |
||||
<div class="-ml-0.5"> |
||||
{{ $t('title.quickImportFrom') }} |
||||
</div> |
||||
|
||||
<MaterialSymbolsChevronRightRounded class="transform group-hover:(scale-115 text-accent) text-xl text-gray-400" /> |
||||
</div> |
||||
</template> |
||||
|
||||
<template #expandIcon></template> |
||||
|
||||
<a-menu-item |
||||
v-if="isUIAllowed('airtableImport', false, projectRole)" |
||||
key="quick-import-airtable" |
||||
@click="openAirtableImportDialog(base.id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="airtable" class="group-hover:text-black" /> |
||||
Airtable |
||||
</div> |
||||
</a-menu-item> |
||||
|
||||
<a-menu-item v-if="isUIAllowed('csvImport', false, projectRole)" key="quick-import-csv" @click="openQuickImportDialog('csv')"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="csv" class="group-hover:text-black" /> |
||||
CSV file |
||||
</div> |
||||
</a-menu-item> |
||||
|
||||
<a-menu-item |
||||
v-if="isUIAllowed('jsonImport', false, projectRole)" |
||||
key="quick-import-json" |
||||
@click="openQuickImportDialog('json')" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="code" class="group-hover:text-black" /> |
||||
JSON file |
||||
</div> |
||||
</a-menu-item> |
||||
|
||||
<a-menu-item |
||||
v-if="isUIAllowed('excelImport', false, projectRole)" |
||||
key="quick-import-excel" |
||||
@click="openQuickImportDialog('excel')" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<GeneralIcon icon="excel" class="group-hover:text-black" /> |
||||
Microsoft Excel |
||||
</div> |
||||
</a-menu-item> |
||||
</a-sub-menu> |
||||
|
||||
<a-menu-divider v-if="false" class="my-0" /> |
||||
|
||||
<!-- Connect to new datasource --> |
||||
<!-- <a-sub-menu> |
||||
<template #title> |
||||
<div class="nc-project-menu-item group"> |
||||
<GeneralIcon icon="datasource" class="group-hover:text-black" /> |
||||
Connect to new datasource |
||||
<div class="flex-1" /> |
||||
|
||||
<MaterialSymbolsChevronRightRounded class="transform group-hover:(scale-115 text-accent) text-xl text-gray-400" /> |
||||
</div> |
||||
</template> |
||||
|
||||
<template #expandIcon></template> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.MYSQL, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<LogosMysqlIcon class="group-hover:text-black" /> |
||||
MySQL |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.PG, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<LogosPostgresql class="group-hover:text-black" /> |
||||
Postgres |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.SQLITE, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<VscodeIconsFileTypeSqlite class="group-hover:text-black" /> |
||||
SQLite |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item key="connect-new-source" @click="toggleDialog(true, 'dataSources', ClientType.MSSQL, project.id)"> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<SimpleIconsMicrosoftsqlserver class="group-hover:text-black" /> |
||||
MSSQL |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item |
||||
v-if="appInfo.ee" |
||||
key="connect-new-source" |
||||
@click="toggleDialog(true, 'dataSources', ClientType.SNOWFLAKE, project.id)" |
||||
> |
||||
<div class="color-transition nc-project-menu-item group"> |
||||
<LogosSnowflakeIcon class="group-hover:text-black" /> |
||||
Snowflake |
||||
</div> |
||||
</a-menu-item> |
||||
<a-menu-item v-if="isUIAllowed('importRequest', false, projectRole)" key="add-new-table" class="py-1 rounded-b"> |
||||
<a |
||||
v-e="['e:datasource:import-request']" |
||||
href="https://github.com/nocodb/nocodb/issues/2052" |
||||
target="_blank" |
||||
class="prose-sm hover:(!text-primary !opacity-100) color-transition nc-project-menu-item group after:(!rounded-b)" |
||||
> |
||||
<GeneralIcon icon="openInNew" class="group-hover:text-black" /> |
||||
{{ $t('labels.requestDataSource') }} |
||||
</a> |
||||
</a-menu-item> |
||||
</a-sub-menu> --> |
||||
</template> |