Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions packages/nc-gui/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ declare module '@vue/runtime-core' {
MdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
MdiChevronLeft: typeof import('~icons/mdi/chevron-left')['default']
MdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
MdiClipboard: typeof import('~icons/mdi/clipboard')['default']
MdiClose: typeof import('~icons/mdi/close')['default']
MdiCloseBox: typeof import('~icons/mdi/close-box')['default']
MdiCloseCircle: typeof import('~icons/mdi/close-circle')['default']
Expand All @@ -142,7 +141,6 @@ declare module '@vue/runtime-core' {
MdiCommentTextOutline: typeof import('~icons/mdi/comment-text-outline')['default']
MdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
MdiContentSave: typeof import('~icons/mdi/content-save')['default']
MdiCopy: typeof import('~icons/mdi/copy')['default']
MdiCurrencyUsd: typeof import('~icons/mdi/currency-usd')['default']
MdiDatabaseOutline: typeof import('~icons/mdi/database-outline')['default']
MdiDatabaseSync: typeof import('~icons/mdi/database-sync')['default']
Expand Down Expand Up @@ -180,7 +178,6 @@ declare module '@vue/runtime-core' {
MdiInformation: typeof import('~icons/mdi/information')['default']
MdiJson: typeof import('~icons/mdi/json')['default']
MdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
MdiKeyChainVariant: typeof import('~icons/mdi/key-chain-variant')['default']
MdiKeyChange: typeof import('~icons/mdi/key-change')['default']
MdiKeyStar: typeof import('~icons/mdi/key-star')['default']
MdiLink: typeof import('~icons/mdi/link')['default']
Expand All @@ -207,7 +204,6 @@ declare module '@vue/runtime-core' {
MdiRocketLaunchOutline: typeof import('~icons/mdi/rocket-launch-outline')['default']
MdiScriptTextKeyOutline: typeof import('~icons/mdi/script-text-key-outline')['default']
MdiScriptTextOutline: typeof import('~icons/mdi/script-text-outline')['default']
MdiShieldAccountOutline: typeof import('~icons/mdi/shield-account-outline')['default']
MdiShieldKeyOutline: typeof import('~icons/mdi/shield-key-outline')['default']
MdiSlack: typeof import('~icons/mdi/slack')['default']
MdiSort: typeof import('~icons/mdi/sort')['default']
Expand Down
26 changes: 15 additions & 11 deletions packages/nc-gui/components/smartsheet/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -524,19 +524,23 @@ provide(ReloadRowDataHookInj, reloadViewDataHook)
watch(
view,
async (next, old) => {
if (next && next.id !== old?.id) {
// whenever tab changes or view changes save any unsaved data
if (old?.id) {
const oldMeta = await getMeta(old.fk_model_id!)
if (oldMeta) {
await saveOrUpdateRecords({
viewMetaValue: old,
metaValue: oldMeta as TableType,
data: data.value,
})
try {
if (next && next.id !== old?.id) {
// whenever tab changes or view changes save any unsaved data
if (old?.id) {
const oldMeta = await getMeta(old.fk_model_id!)
if (oldMeta) {
await saveOrUpdateRecords({
viewMetaValue: old,
metaValue: oldMeta as TableType,
data: data.value,
})
}
}
await loadData()
}
await loadData()
} catch (e) {
console.log(e)
}
},
{ immediate: true },
Expand Down
134 changes: 74 additions & 60 deletions packages/nc-gui/components/tabs/auth/UserManagement.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { OrgUserRoles } from 'nocodb-sdk'
import type { RequestParams } from 'nocodb-sdk'
import {
extractSdkResponseErrorMsg,
Expand Down Expand Up @@ -160,6 +161,10 @@ onBeforeMount(async () => {
})

watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 })

const isSuperAdmin = (user: { main_roles?: string }) => {
return user.main_roles?.split(',').includes(OrgUserRoles.SUPER_ADMIN)
}
</script>

<template>
Expand Down Expand Up @@ -252,6 +257,13 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 })
</div>

<div class="flex w-1/6 justify-center flex-wrap ml-4">
<div
v-if="isSuperAdmin(user)"
class="rounded-full px-2 py-1 nc-user-role"
:style="{ backgroundColor: projectRoleTagColors[OrgUserRoles.SUPER_ADMIN] }"
>
Super Admin
</div>
<div
v-if="user.roles"
class="rounded-full px-2 py-1 nc-user-role"
Expand All @@ -261,71 +273,73 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 })
</div>
</div>
<div class="flex w-1/6 flex-wrap justify-end">
<a-tooltip v-if="user.project_id" placement="bottom">
<template #title>
<span>{{ $t('activity.editUser') }}</span>
</template>

<a-button type="text" class="!rounded-md nc-user-edit" @click="onEdit(user)">
<template #icon>
<IcRoundEdit class="flex mx-auto h-[1rem] text-gray-500" />
<template v-if="!isSuperAdmin(user)">
<a-tooltip v-if="user.project_id" placement="bottom">
<template #title>
<span>{{ $t('activity.editUser') }}</span>
</template>
</a-button>
</a-tooltip>

<!-- Add user to project -->
<a-tooltip v-if="!user.project_id" placement="bottom">
<template #title>
<span>{{ $t('activity.addUserToProject') }}</span>
</template>

<a-button type="text" class="!rounded-md nc-user-invite" @click="inviteUser(user)">
<template #icon>
<MdiPlus class="flex mx-auto h-[1.1rem] text-gray-500" />

<a-button type="text" class="!rounded-md nc-user-edit" @click="onEdit(user)">
<template #icon>
<IcRoundEdit class="flex mx-auto h-[1rem] text-gray-500" />
</template>
</a-button>
</a-tooltip>

<!-- Add user to project -->
<a-tooltip v-if="!user.project_id" placement="bottom">
<template #title>
<span>{{ $t('activity.addUserToProject') }}</span>
</template>
</a-button>
</a-tooltip>

<!-- Remove user from the project -->
<a-tooltip v-else placement="bottom">
<template #title>
<span>{{ $t('activity.deleteUser') }}</span>
</template>

<a-button v-e="['c:user:delete']" type="text" class="!rounded-md nc-user-delete" @click="onDelete(user)">
<template #icon>
<MdiDeleteOutline class="flex mx-auto h-[1.1rem] text-gray-500" />

<a-button type="text" class="!rounded-md nc-user-invite" @click="inviteUser(user)">
<template #icon>
<MdiPlus class="flex mx-auto h-[1.1rem] text-gray-500" />
</template>
</a-button>
</a-tooltip>

<!-- Remove user from the project -->
<a-tooltip v-else placement="bottom">
<template #title>
<span>{{ $t('activity.deleteUser') }}</span>
</template>
</a-button>
</a-tooltip>

<a-dropdown :trigger="['click']" class="flex" placement="bottomRight" overlay-class-name="nc-dropdown-user-mgmt">
<div class="flex flex-row items-center">
<a-button type="text" class="!px-0">
<div class="flex flex-row items-center h-[1.2rem]">
<IcBaselineMoreVert />
</div>

<a-button v-e="['c:user:delete']" type="text" class="!rounded-md nc-user-delete" @click="onDelete(user)">
<template #icon>
<MdiDeleteOutline class="flex mx-auto h-[1.1rem] text-gray-500" />
</template>
</a-button>
</div>

<template #overlay>
<a-menu>
<a-menu-item>
<!-- Resend invite Email -->
<div class="flex flex-row items-center py-3" @click="resendInvite(user)">
<MdiEmailArrowRightOutline class="flex h-[1rem] text-gray-500" />
<div class="text-xs pl-2">{{ $t('activity.resendInvite') }}</div>
</div>
</a-menu-item>
<a-menu-item>
<div class="flex flex-row items-center py-3" @click="copyInviteUrl(user)">
<MdiContentCopy class="flex h-[1rem] text-gray-500" />
<div class="text-xs pl-2">{{ $t('activity.copyInviteURL') }}</div>
</a-tooltip>

<a-dropdown :trigger="['click']" class="flex" placement="bottomRight" overlay-class-name="nc-dropdown-user-mgmt">
<div class="flex flex-row items-center">
<a-button type="text" class="!px-0">
<div class="flex flex-row items-center h-[1.2rem]">
<IcBaselineMoreVert />
</div>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-button>
</div>

<template #overlay>
<a-menu>
<a-menu-item>
<!-- Resend invite Email -->
<div class="flex flex-row items-center py-3" @click="resendInvite(user)">
<MdiEmailArrowRightOutline class="flex h-[1rem] text-gray-500" />
<div class="text-xs pl-2">{{ $t('activity.resendInvite') }}</div>
</div>
</a-menu-item>
<a-menu-item>
<div class="flex flex-row items-center py-3" @click="copyInviteUrl(user)">
<MdiContentCopy class="flex h-[1rem] text-gray-500" />
<div class="text-xs pl-2">{{ $t('activity.copyInviteURL') }}</div>
</div>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion packages/nc-gui/composables/useTabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const [setup, use] = useInjectionState(() => {

if (!tab) return

return navigateToTab(tab)
navigateToTab(tab)
}
},
})
Expand Down
2 changes: 1 addition & 1 deletion packages/nc-gui/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default {
<template>
<div class="w-full h-full">
<Teleport :to="hasSidebar ? '#nc-sidebar-left' : null" :disabled="!hasSidebar">
<slot :key="$route.name" name="sidebar" />
<slot name="sidebar" />
</Teleport>

<a-layout-content>
Expand Down
2 changes: 1 addition & 1 deletion packages/nc-gui/pages/[projectType]/[projectId]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ onBeforeUnmount(reset)
to="/account/users"
>
<MdiAt class="mt-1 group-hover:text-accent" />&nbsp;
<div class="prose group-hover:text-primary">
<div class="prose-sm group-hover:text-primary">
<div>Account</div>
<div class="text-xs text-gray-500">{{ email }}</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions packages/nc-gui/utils/userUtils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OrgUserRoles } from 'nocodb-sdk'
import { ProjectRole } from '~/lib/enums'

export const projectRoleTagColors = {
Expand All @@ -6,6 +7,7 @@ export const projectRoleTagColors = {
[ProjectRole.Editor]: '#c2f5e8',
[ProjectRole.Commenter]: '#ffdaf6',
[ProjectRole.Viewer]: '#ffdce5',
[OrgUserRoles.SUPER_ADMIN]: '#f5d7cb',
}

export const projectRoles = [ProjectRole.Creator, ProjectRole.Editor, ProjectRole.Commenter, ProjectRole.Viewer]
1 change: 1 addition & 0 deletions packages/nocodb-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './lib/Api';
export * from './lib/sqlUi';
export * from './lib/globals';
export * from './lib/helperFunctions';
export * from './lib/enums';
export * from './lib/formulaHelpers';
export { default as UITypes, isVirtualCol } from './lib/UITypes';
export { default as CustomAPI } from './lib/CustomAPI';
Expand Down
2 changes: 1 addition & 1 deletion packages/nocodb/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ COPY ./docker/start-litestream.sh /usr/src/appEntry/start.sh
# reduce node_module size with modclean & removing sqlite deps,
# package built code into app.tar.gz & add execute permission to start.sh
RUN npm ci --omit=dev --quiet \
&& npx modclean --patterns="default:*" --ignore="nc-lib-gui/**,dayjs/**,express-status-monitor/**" --run \
&& npx modclean --patterns="default:*" --ignore="nc-lib-gui/**,dayjs/**,express-status-monitor/**,@azure/msal-node/dist/**" --run \
&& rm -rf ./node_modules/sqlite3/deps \
&& tar -czf ../appEntry/app.tar.gz ./* \
&& chmod +x /usr/src/appEntry/start.sh
Expand Down
Loading