Browse Source

feat(gui-v2): integrate locked view menu with api

- add smartsheet store

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/2860/head
Pranav C 2 years ago
parent
commit
f2cd6f7833
  1. 91
      packages/nc-gui-v2/components/smartsheet-toolbar/LockMenu.vue
  2. 7
      packages/nc-gui-v2/components/tabs/Smartsheet.vue
  3. 30
      packages/nc-gui-v2/composables/useSmartsheetStore.ts

91
packages/nc-gui-v2/components/smartsheet-toolbar/LockMenu.vue

@ -1,29 +1,21 @@
<script lang="ts" setup>
import { computed } from '@vue/reactivity'
import { useToast } from 'vue-toastification'
import { useSmartsheetStoreOrThrow } from '~/composables/useSmartsheetStore'
import { extractSdkResponseErrorMsg } from '~/utils/errorUtils'
import MdiLockOutlineIcon from '~icons/mdi/lock-outline'
import MdiAccountIcon from '~icons/mdi/account'
import MdiAccountGroupIcon from '~icons/mdi/account-group'
import MdiCheckIcon from '~icons/mdi/check-bold'
interface Props {
modelValue?: LockType
}
const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue'])
enum LockType {
Personal = 'personal',
Locked = 'locked',
Collaborative = 'collaborative',
}
const vModel = useVModel(props, 'modelValue', emits)
const { view, $api } = useSmartsheetStoreOrThrow()
const { $e } = useNuxtApp()
const toast = useToast()
function changeLockType(type: LockType) {
@ -32,14 +24,20 @@ function changeLockType(type: LockType) {
if (type === 'personal') {
return toast.info('Coming soon', { timeout: 3000 })
}
vModel.value = type
toast.success(`Successfully Switched to ${type} view`, { timeout: 3000 })
try {
view.value.lock_type = type
$api.dbView.update(view.value.id as string, {
lock_type: type,
})
toast.success(`Successfully Switched to ${type} view`, { timeout: 3000 })
} catch (e) {
toast.error(extractSdkResponseErrorMsg(e))
}
}
const Icon = computed(() => {
switch (vModel.value) {
switch (view?.value?.lock_type) {
case LockType.Personal:
return MdiAccountIcon
case LockType.Locked:
@ -49,15 +47,6 @@ const Icon = computed(() => {
return MdiAccountGroupIcon
}
})
const changeLockType = (type) => {
$e('a:grid:lockmenu', { lockType: type })
if (type === 'personal') {
return toast.info('Coming soon')
}
// $emit('input', type);
toast.success(`Successfully Switched to ${type} view`)
}
</script>
<template>
@ -68,32 +57,38 @@ const changeLockType = (type) => {
<template #overlay>
<div class="min-w-[350px] max-w-[500px] shadow bg-white">
<div>
<div class="nc-menu-item">
<MdiCheckIcon v-if="!vModel || vModel === LockType.Collaborative" />
<span v-else />
<div class="nc-menu-item" @click="changeLockType(LockType.Collaborative)">
<div>
<MdiAccountGroupIcon />
Collaborative view
<div class="nc-subtitle">Collaborators with edit permissions or higher can change the view configuration.</div>
<MdiCheckIcon v-if="!view?.lock_type || view?.lock_type === LockType.Collaborative" />
<span v-else />
<div>
<MdiAccountGroupIcon />
Collaborative view
<div class="nc-subtitle">Collaborators with edit permissions or higher can change the view configuration.</div>
</div>
</div>
</div>
<div class="nc-menu-item">
<MdiCheckIcon v-if="vModel === LockType.Locked" />
<span v-else />
<div class="nc-menu-item" @click="changeLockType(LockType.Locked)">
<div>
<MdiLockOutlineIcon />
Locked View
<div class="nc-subtitle">No one can edit the view configuration until it is unlocked.</div>
<MdiCheckIcon v-if="view.lock_type === LockType.Locked" />
<span v-else />
<div>
<MdiLockOutlineIcon />
Locked View
<div class="nc-subtitle">No one can edit the view configuration until it is unlocked.</div>
</div>
</div>
</div>
<div class="nc-menu-item">
<MdiCheckIcon v-if="vModel === LockType.Personal" />
<span v-else />
<div class="nc-menu-item" @click="changeLockType(LockType.Personal)">
<div>
<MdiAccountIcon />
Personal view
<div class="nc-subtitle">
Only you can edit the view configuration. Other collaborators personal views are hidden by default.
<MdiCheckIcon v-if="view.lock_type === LockType.Personal" />
<span v-else />
<div>
<MdiAccountIcon />
Personal view
<div class="nc-subtitle">
Only you can edit the view configuration. Other collaborators personal views are hidden by default.
</div>
</div>
</div>
</div>
@ -104,8 +99,12 @@ const changeLockType = (type) => {
</template>
<style scoped>
.nc-menu-item {
@apply grid grid-cols-[30px,auto] gap-2 p-4;
.nc-menu-item > div {
@apply grid grid-cols-[30px,auto] gap-2 p-2 align-center;
}
.nc-menu-item > div > svg {
align-self: center;
}
.nc-menu-option > :first-child {

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

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk'
import type { ColumnType, TableType, ViewType } from 'nocodb-sdk'
import { ViewTypes } from 'nocodb-sdk'
import SmartsheetGrid from '../smartsheet/Grid.vue'
import { computed, inject, provide, useMetas, watch, watchEffect } from '#imports'
@ -19,7 +19,7 @@ const tabMeta = inject(
computed(() => ({} as TabItem)),
)
const meta = computed(() => metas.value?.[tabMeta?.value?.id as string])
const meta = computed<TableType>(() => metas.value?.[tabMeta?.value?.id as string])
watchEffect(async () => {
await getMeta(tabMeta?.value?.id as string)
@ -27,6 +27,7 @@ watchEffect(async () => {
const reloadEventHook = createEventHook<void>()
// todo: move to store
provide(MetaInj, meta)
provide(TabMetaInj, tabMeta)
provide(ActiveViewInj, activeView)
@ -35,6 +36,8 @@ provide(ReloadViewDataHookInj, reloadEventHook)
provide(FieldsInj, fields)
provide(RightSidebarInj, ref(true))
useProvideSmartsheetStore(activeView as Ref<TableType>, meta)
watch(tabMeta, async (newTabMeta, oldTabMeta) => {
if (newTabMeta !== oldTabMeta && newTabMeta.id) await getMeta(newTabMeta.id)
})

30
packages/nc-gui-v2/composables/useSmartsheetStore.ts

@ -0,0 +1,30 @@
import { createInjectionState } from '@vueuse/core'
import type { TableType, ViewType } from 'nocodb-sdk'
import type { Ref } from 'vue'
import { useNuxtApp } from '#app'
const [useProvideSmartsheetStore, useSmartsheetStore] = createInjectionState((view: Ref<ViewType>, meta: Ref<TableType>) => {
const { $api } = useNuxtApp()
// state
// getters
const isLocked = computed(() => view?.value?.lock_type === 'locked')
// actions
return {
view,
meta,
isLocked,
$api,
}
})
export { useProvideSmartsheetStore }
export function useSmartsheetStoreOrThrow() {
const smartsheetStore = useSmartsheetStore()
if (smartsheetStore == null) throw new Error('Please call `useSmartsheetStore` on the appropriate parent component')
return smartsheetStore
}
Loading…
Cancel
Save