fix: use dropdown for version controling

This commit is contained in:
Ramesh Mane
2026-01-27 11:47:14 +00:00
parent 86979b3188
commit 10635b7931
5 changed files with 312 additions and 2 deletions

View File

@@ -96,7 +96,7 @@ const { formState, isLoading, submit } = useProvideFormBuilderHelper({
model: 'visibility',
category: FORM_BUILDER_NON_CATEGORIZED,
options: [
{ label: 'Public', value: 'public', icon: 'eye' },
// { label: 'Public', value: 'public', icon: 'eye' },
{ label: 'Private', value: 'private', icon: 'lock' },
{ label: 'Unlisted', value: 'unlisted', icon: 'ncEyeOff' },
],

View File

@@ -0,0 +1,52 @@
<script lang="ts" setup>
interface Props {
label: string
subtext?: string
icon?: IconMapKey
iconWrapperClass?: string
clickable?: boolean
}
withDefaults(defineProps<Props>(), {})
</script>
<template>
<div :tabindex="clickable ? 0 : undefined" class="nc-managed-app-status-menu-item" :class="{ 'nc-clickable': clickable }">
<div class="nc-icon-wrapper" :class="iconWrapperClass">
<slot name="icon">
<GeneralIcon v-if="icon" :icon="icon" class="h-4 w-4 flex-none" />
</slot>
</div>
<div class="nc-content-wrapper flex-1">
<div v-if="$slots.label || label" class="nc-content-label">
<slot name="label">{{ label }}</slot>
</div>
<div v-if="$slots.subtext || subtext" class="nc-content-subtext">
<slot name="subtext">{{ subtext }}</slot>
</div>
</div>
<slot name="extraRight"> </slot>
</div>
</template>
<style lang="scss" scoped>
.nc-managed-app-status-menu-item {
@apply flex items-center gap-3 px-3 py-2.5 my-0.5 mx-2 rounded-lg transition-colors group;
&.nc-clickable {
@apply cursor-pointer select-none hover:bg-nc-bg-gray-extralight;
}
}
.nc-icon-wrapper {
@apply w-8 h-8 rounded-lg flex items-center justify-center children:flex-none;
}
.nc-content-label {
@apply text-caption font-600 text-nc-content-gray-subtle2;
}
.nc-content-subtext {
@apply text-captionSm text-nc-content-gray-muted;
}
</style>

View File

@@ -0,0 +1,240 @@
<script setup lang="ts">
const baseStore = useBase()
const { loadManagedApp, loadCurrentVersion } = baseStore
const { base, isManagedAppMaster, isManagedAppInstaller, managedApp, currentVersion, liveVersion } = storeToRefs(baseStore)
const isModalVisible = ref(false)
const initialTab = ref<'publish' | 'fork' | 'deployments' | undefined>(undefined)
const isOpenDropdown = ref<boolean>(false)
const isDraft = computed(() => currentVersion.value?.status === 'draft')
const openModal = (tab?: 'publish' | 'fork' | 'deployments') => {
initialTab.value = tab
isModalVisible.value = true
}
const loadManagedAppAndCurrentVersion = async () => {
await loadManagedApp()
await loadCurrentVersion()
}
const handlePublished = async () => {
await loadManagedAppAndCurrentVersion()
}
const handleForked = async () => {
await loadManagedAppAndCurrentVersion()
}
watch(
() => (base.value as any)?.managed_app_id,
async (managedAppId) => {
if (!managedAppId) return
await loadManagedAppAndCurrentVersion()
},
{ immediate: true },
)
watchEffect(() => {
console.log('managed App', managedApp.value)
console.log('currentVersion', currentVersion.value)
console.log('liveVersion', liveVersion.value)
})
</script>
<template>
<NcDropdown
v-if="isManagedAppMaster || isManagedAppInstaller"
v-model:visible="isOpenDropdown"
placement="bottomRight"
overlay-class-name="!rounded-xl"
>
<div class="flex items-center gap-2" @click="openModal()">
<!-- Version Badge (clickable to open modal) -->
<div
class="flex items-center gap-1.5 px-2.5 py-1 bg-nc-bg-gray-light rounded-md border-1 border-nc-border-gray-medium cursor-pointer hover:(bg-nc-bg-gray-medium border-nc-border-gray-dark) transition-colors"
>
<GeneralIcon icon="ncInfoSolid" class="w-3.5 h-3.5 text-nc-content-gray nc-managed-app-status-info-icon" />
<span class="text-xs font-mono font-semibold text-nc-content-gray-emphasis"
>v{{ currentVersion?.version || '1.0.0' }}</span
>
<div
v-if="currentVersion?.status === 'draft'"
class="ml-1 px-1.5 py-0.5 text-xs rounded bg-nc-bg-orange-light text-nc-content-orange-dark font-medium"
>
{{ $t('labels.draft') }}
</div>
<div
v-else-if="currentVersion?.status === 'published'"
class="ml-1 px-1.5 py-0.5 text-xs rounded bg-nc-bg-green-dark text-nc-content-green-dark font-medium"
>
{{ $t('labels.published') }}
</div>
</div>
</div>
<template #overlay>
<div class="nc-managed-app-status-menu flex flex-col">
<div class="nc-managed-app-status-menu-header">
<span class="uppercase">{{ isManagedAppInstaller ? 'Installed Version' : 'Current State' }}</span>
<span v-if="currentVersion?.status === 'draft' && liveVersion">Live: v{{ liveVersion.version }} </span>
</div>
<!-- Publisher application -->
<template v-if="isManagedAppMaster">
<!-- Live state -->
<template v-if="liveVersion && !isDraft">
<SmartsheetTopbarManagedAppStatusMenuItem
:label="`v${liveVersion.version || '1.0.0'}`"
icon-wrapper-class="bg-green-50 dark:bg-nc-green-20"
>
<template #icon>
<GeneralIcon icon="circleCheck3" class="text-green-600" />
</template>
<template #subtext>
<span class="text-green-600"> Live & Serving Users </span>
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
<NcDivider />
<SmartsheetTopbarManagedAppStatusMenuItem
clickable
label="Fork to Draft"
:subtext="`Create v${liveVersion.version || '1.0.0'} to make changes`"
icon-wrapper-class="bg-nc-bg-gray-light dakr:bg-nc-bg-gray-light/75"
>
<template #icon>
<GeneralIcon icon="ncCopy" class="text-nc-content-gray-muted" />
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
</template>
<!-- Draft state -->
<template v-if="isDraft">
<SmartsheetTopbarManagedAppStatusMenuItem
:label="`v${currentVersion.version || '1.0.0'}`"
icon-wrapper-class="bg-orange-50 dark:bg-nc-orange-20"
>
<template #icon>
<GeneralIcon icon="edit" class="text-orange-600" />
</template>
<template #subtext>
<span class="text-orange-600"> Editing Draft </span>
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
<NcDivider />
<SmartsheetTopbarManagedAppStatusMenuItem clickable icon-wrapper-class="bg-green-50 dark:bg-nc-green-20">
<template #icon>
<GeneralIcon icon="ncArrowUp" class="text-green-600" />
</template>
<template #label>
<span class="text-green-600"> Publish v{{ currentVersion.version || '1.0.0' }} </span>
</template>
<template #subtext>
{{ liveVersion ? `Replace v${liveVersion.version || '1.0.0'} and go live` : `Go live` }}
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
</template>
<!-- Initial draft state -->
<SmartsheetTopbarManagedAppStatusMenuItem
v-if="liveVersion && isDraft"
clickable
label="Discard Draft"
:subtext="`Return to v${liveVersion.version || '1.0.0'}`"
icon-wrapper-class="bg-nc-bg-gray-light"
>
<template #icon>
<GeneralIcon icon="delete" class="text-nc-content-gray-muted" />
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
<NcDivider />
<!-- Version history -->
<div class="flex items-center gap-2 px-5 py-2 text-captionSm text-nc-content-gray-muted cursor-pointer select-none">
<GeneralIcon icon="ncClock" />
View version history
</div>
</template>
<!-- Installer application -->
<template v-if="isManagedAppInstaller">
<SmartsheetTopbarManagedAppStatusMenuItem
:label="`v${liveVersion?.version || '1.0.0'}`"
icon-wrapper-class="bg-green-50 dark:bg-nc-green-20"
>
<template #icon>
<GeneralIcon icon="circleCheck3" class="text-green-600" />
</template>
<template #subtext>
<span class="text-green-600">
<!-- Todo: @rameshmane7218 - Update text -->
Installed Jan 10, 2025
</span>
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
<div class="bg-nc-brand-20 dark:bg-nc-brand-20/40 -mb-1.5">
<SmartsheetTopbarManagedAppStatusMenuItem
:label="`v${liveVersion?.version || '1.0.0'}`"
icon-wrapper-class="bg-brand-50 dark:bg-nc-brand-50"
>
<template #icon>
<GeneralIcon icon="ncDownload" class="text-brand-600" />
</template>
<template #subtext>
<span class="text-brand-600"> New version available </span>
</template>
<template #extraRight>
<NcButton size="small"> Update </NcButton>
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
</div>
<NcDivider />
<SmartsheetTopbarManagedAppStatusMenuItem
clickable
label="View Changelog"
subtext="See what's new in each version"
icon-wrapper-class="bg-nc-bg-gray-light"
>
<template #icon>
<GeneralIcon icon="file" class="text-nc-content-gray-muted" />
</template>
</SmartsheetTopbarManagedAppStatusMenuItem>
</template>
</div>
</template>
</NcDropdown>
<!-- Managed App Modal -->
<SmartsheetTopbarManagedAppModal
v-model:visible="isModalVisible"
:managed-app="managedApp"
:current-version="currentVersion"
:initial-tab="initialTab"
@published="handlePublished"
@forked="handleForked"
/>
</template>
<style lang="scss" scoped>
:deep(.nc-managed-app-status-info-icon path.nc-icon-inner) {
stroke: var(--nc-bg-gray-light) !important;
}
.nc-managed-app-status-menu {
@apply w-[318px] pb-2;
}
.nc-managed-app-status-menu-header {
@apply flex items-center justify-between gap-2 pt-3 px-5 mb-1 text-nc-content-gray-muted text-captionSm;
}
</style>

View File

@@ -168,7 +168,7 @@ const { formState, isLoading, submit } = useProvideFormBuilderHelper({
model: 'visibility',
category: FORM_BUILDER_NON_CATEGORIZED,
options: [
{ label: 'Public', value: 'public', icon: 'eye' },
// { label: 'Public', value: 'public', icon: 'eye' },
{ label: 'Private', value: 'private', icon: 'lock' },
{ label: 'Unlisted', value: 'unlisted', icon: 'ncEyeOff' },
],

View File

@@ -18,8 +18,16 @@ export const useBase = defineStore('baseStore', () => {
const basesStore = useBases()
const managedApp = ref<any>(null)
const currentVersion = ref<any>(null)
const liveVersion = ref<any>(null)
const isManagedAppMaster = ref(false)
const isManagedAppInstaller = ref(false)
const baseId = computed(() => {
// In shared base mode, use activeProjectId from basesStore which has the correct base ID
if (route.value.params.typeOrId === 'base') {
@@ -268,6 +276,10 @@ export const useBase = defineStore('baseStore', () => {
return `${basUrl}${projectPage ? `?page=${projectPage}` : ''}`
}
const loadManagedApp = async () => {}
const loadCurrentVersion = async () => {}
watch(
() => route.value.params.baseType,
(n) => {
@@ -343,6 +355,12 @@ export const useBase = defineStore('baseStore', () => {
isPrivateBase,
showBaseAccessRequestOverlay,
isManagedAppMaster,
isManagedAppInstaller,
managedApp,
loadManagedApp,
currentVersion,
liveVersion,
loadCurrentVersion,
}
})