mirror of
https://github.com/nocodb/nocodb.git
synced 2026-02-02 02:37:33 +00:00
fix: some ui changes
This commit is contained in:
@@ -127,7 +127,7 @@ watch(visible, (isVisible) => {
|
||||
size="sm"
|
||||
height="auto"
|
||||
centered
|
||||
wrap-class-name="nc-modal-convert-to-managed-app "
|
||||
wrap-class-name="nc-modal-convert-to-managed-app"
|
||||
nc-modal-class-name="!p-0"
|
||||
>
|
||||
<div class="p-4 w-full flex items-center gap-3 border-b border-nc-border-gray-medium">
|
||||
|
||||
@@ -149,7 +149,7 @@ if (stopEventPropogation.value) {
|
||||
<div
|
||||
ref="ncModalRef"
|
||||
class="flex flex-col nc-modal p-6 h-full"
|
||||
:class="[`${ncModalClassName}`]"
|
||||
:class="[`nc-modal-size-${size} ${ncModalClassName}`]"
|
||||
:style="{
|
||||
maxHeight: height,
|
||||
...(modalSizes[size] ? { height } : {}),
|
||||
|
||||
@@ -152,24 +152,6 @@ const formatDate = (dateString: string) => {
|
||||
}).format(date)
|
||||
}
|
||||
|
||||
const suggestNextVersion = () => {
|
||||
if (!props.currentVersion?.version) {
|
||||
forkForm.version = '1.0.0'
|
||||
return
|
||||
}
|
||||
|
||||
const currentVersion = props.currentVersion.version
|
||||
const versionParts = currentVersion.split('.')
|
||||
if (versionParts.length === 3) {
|
||||
// Increment minor version for new draft
|
||||
versionParts[1] = String(Number(versionParts[1]) + 1)
|
||||
versionParts[2] = '0'
|
||||
forkForm.version = versionParts.join('.')
|
||||
} else {
|
||||
forkForm.version = ''
|
||||
}
|
||||
}
|
||||
|
||||
const openVersionDeploymentsModal = (version: any) => {
|
||||
selectedVersion.value = version
|
||||
showVersionDeploymentsModal.value = true
|
||||
@@ -193,20 +175,28 @@ watch(
|
||||
|
||||
await loadVersions()
|
||||
await loadDeployments()
|
||||
if (!isDraft.value && !props.initialTab) {
|
||||
suggestNextVersion()
|
||||
if (!isDraft.value) {
|
||||
forkForm.version = suggestManagedAppNextVersion(props.currentVersion?.version)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const modalSize = computed(() => {
|
||||
if (props.initialTab === 'fork' || props.initialTab === 'publish') {
|
||||
return 'sm'
|
||||
}
|
||||
|
||||
return 'sm'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NcModal
|
||||
:visible="visible"
|
||||
size="lg"
|
||||
:size="modalSize"
|
||||
:height="modalSize === 'sm' ? 'auto' : undefined"
|
||||
nc-modal-class-name="nc-modal-managed-app-management"
|
||||
centered
|
||||
@update:visible="emit('update:visible', $event)"
|
||||
>
|
||||
<div class="flex flex-col h-full">
|
||||
@@ -256,7 +246,7 @@ watch(
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<div class="flex-1 nc-scrollbar-thin">
|
||||
<!-- Publish Tab -->
|
||||
<div v-if="activeTab === 'publish'" class="p-6">
|
||||
<NcAlert
|
||||
@@ -346,46 +336,26 @@ watch(
|
||||
<div class="nc-deployment-stats">
|
||||
<!-- Total Deployments -->
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-icon-wrapper bg-nc-bg-blue-light">
|
||||
<GeneralIcon icon="ncServer" class="w-5 h-5 text-nc-content-blue-dark" />
|
||||
</div>
|
||||
<div class="nc-stat-content">
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.totalDeployments || 0 }}</div>
|
||||
<div class="nc-stat-label">Total Installs</div>
|
||||
</div>
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.totalDeployments || 0 }}</div>
|
||||
<div class="nc-stat-label">Total Installs</div>
|
||||
</div>
|
||||
|
||||
<!-- Active -->
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-icon-wrapper bg-nc-bg-green-light">
|
||||
<GeneralIcon icon="check" class="w-5 h-5 text-nc-content-green-dark" />
|
||||
</div>
|
||||
<div class="nc-stat-content">
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.activeDeployments || 0 }}</div>
|
||||
<div class="nc-stat-label">Active</div>
|
||||
</div>
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.activeDeployments || 0 }}</div>
|
||||
<div class="nc-stat-label">Active</div>
|
||||
</div>
|
||||
|
||||
<!-- Failed -->
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-icon-wrapper bg-nc-bg-red-light">
|
||||
<GeneralIcon icon="alertTriangle" class="w-5 h-5 text-nc-content-red-dark" />
|
||||
</div>
|
||||
<div class="nc-stat-content">
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.failedDeployments || 0 }}</div>
|
||||
<div class="nc-stat-label">Failed</div>
|
||||
</div>
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.failedDeployments || 0 }}</div>
|
||||
<div class="nc-stat-label">Failed</div>
|
||||
</div>
|
||||
|
||||
<!-- Versions -->
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-icon-wrapper bg-nc-bg-purple-light">
|
||||
<GeneralIcon icon="ncGitBranch" class="w-5 h-5 text-nc-content-purple-dark" />
|
||||
</div>
|
||||
<div class="nc-stat-content">
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.totalVersions || 0 }}</div>
|
||||
<div class="nc-stat-label">Versions</div>
|
||||
</div>
|
||||
<div class="nc-stat-value">{{ deploymentStats.statistics?.totalVersions || 0 }}</div>
|
||||
<div class="nc-stat-label">Versions</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -545,7 +515,7 @@ watch(
|
||||
|
||||
// Deployments Tab Styles
|
||||
.nc-deployments-content {
|
||||
@apply p-6;
|
||||
@apply px-6 pb-6;
|
||||
}
|
||||
|
||||
.nc-deployments-loading {
|
||||
@@ -553,11 +523,11 @@ watch(
|
||||
}
|
||||
|
||||
.nc-deployment-stats {
|
||||
@apply grid grid-cols-4 gap-4 mb-6;
|
||||
@apply grid grid-cols-4 mb-6;
|
||||
}
|
||||
|
||||
.nc-stat-card {
|
||||
@apply bg-nc-bg-gray-extralight border-1 border-nc-border-gray-light rounded-xl p-4 transition-all duration-200 hover:(border-nc-border-gray-medium shadow-hover);
|
||||
@apply flex flex-col gap-1 items-center justify-center border-r-1 border-nc-border-gray-light last:border-r-0 p-4;
|
||||
}
|
||||
|
||||
.nc-stat-icon-wrapper {
|
||||
@@ -569,11 +539,11 @@ watch(
|
||||
}
|
||||
|
||||
.nc-stat-value {
|
||||
@apply text-3xl font-bold text-nc-content-gray-emphasis leading-none;
|
||||
@apply text-subHeading1 font-normal;
|
||||
}
|
||||
|
||||
.nc-stat-label {
|
||||
@apply text-xs font-medium text-nc-content-gray-subtle2 uppercase tracking-wide;
|
||||
@apply text-captionSm text-nc-content-gray-muted uppercase;
|
||||
}
|
||||
|
||||
.nc-version-list-wrapper {
|
||||
@@ -713,5 +683,10 @@ watch(
|
||||
<style lang="scss">
|
||||
.nc-modal-managed-app-management {
|
||||
@apply !p-0;
|
||||
|
||||
&.nc-modal-size-sm {
|
||||
max-height: min(90vh, 540px) !important;
|
||||
height: min(90vh, 540px) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
interface Props {
|
||||
label: string
|
||||
label?: string
|
||||
subtext?: string
|
||||
icon?: IconMapKey
|
||||
iconWrapperClass?: string
|
||||
|
||||
@@ -3,16 +3,19 @@ const baseStore = useBase()
|
||||
|
||||
const { loadManagedApp, loadCurrentVersion } = baseStore
|
||||
|
||||
const { base, isManagedAppMaster, isManagedAppInstaller, managedApp, currentVersion, liveVersion } = storeToRefs(baseStore)
|
||||
const { base, isManagedAppMaster, isManagedAppInstaller, managedApp, currentVersion, liveVersion, managedAppVersionsInfo } =
|
||||
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 isDraft = computed(() => managedAppVersionsInfo.value.current?.status === 'draft')
|
||||
|
||||
const openModal = (tab?: 'publish' | 'fork' | 'deployments') => {
|
||||
isOpenDropdown.value = false
|
||||
|
||||
initialTab.value = tab
|
||||
isModalVisible.value = true
|
||||
}
|
||||
@@ -54,23 +57,23 @@ watchEffect(() => {
|
||||
placement="bottomRight"
|
||||
overlay-class-name="!rounded-xl"
|
||||
>
|
||||
<div class="flex items-center gap-2" @click="openModal()">
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- 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
|
||||
>v{{ managedAppVersionsInfo.current?.version || '1.0.0' }}</span
|
||||
>
|
||||
<div
|
||||
v-if="currentVersion?.status === 'draft'"
|
||||
v-if="managedAppVersionsInfo.current?.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'"
|
||||
v-else-if="managedAppVersionsInfo.current?.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') }}
|
||||
@@ -81,15 +84,17 @@ watchEffect(() => {
|
||||
<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>
|
||||
<span v-if="managedAppVersionsInfo.current?.status === 'draft' && managedAppVersionsInfo.published"
|
||||
>Live: v{{ managedAppVersionsInfo.published.version }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Publisher application -->
|
||||
<template v-if="isManagedAppMaster">
|
||||
<!-- Live state -->
|
||||
<template v-if="liveVersion && !isDraft">
|
||||
<template v-if="managedAppVersionsInfo.published && !isDraft">
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
:label="`v${liveVersion.version || '1.0.0'}`"
|
||||
:label="`v${managedAppVersionsInfo.published.version || '1.0.0'}`"
|
||||
icon-wrapper-class="bg-green-50 dark:bg-nc-green-20"
|
||||
>
|
||||
<template #icon>
|
||||
@@ -104,8 +109,11 @@ watchEffect(() => {
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
clickable
|
||||
label="Fork to Draft"
|
||||
:subtext="`Create v${liveVersion.version || '1.0.0'} to make changes`"
|
||||
:subtext="`Create v${suggestManagedAppNextVersion(
|
||||
managedAppVersionsInfo.published.version || '1.0.0',
|
||||
)} to make changes`"
|
||||
icon-wrapper-class="bg-nc-bg-gray-light dakr:bg-nc-bg-gray-light/75"
|
||||
@click="openModal('fork')"
|
||||
>
|
||||
<template #icon>
|
||||
<GeneralIcon icon="ncCopy" class="text-nc-content-gray-muted" />
|
||||
@@ -116,7 +124,7 @@ watchEffect(() => {
|
||||
<!-- Draft state -->
|
||||
<template v-if="isDraft">
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
:label="`v${currentVersion.version || '1.0.0'}`"
|
||||
:label="`v${managedAppVersionsInfo.current.version || '1.0.0'}`"
|
||||
icon-wrapper-class="bg-orange-50 dark:bg-nc-orange-20"
|
||||
>
|
||||
<template #icon>
|
||||
@@ -128,25 +136,33 @@ watchEffect(() => {
|
||||
</SmartsheetTopbarManagedAppStatusMenuItem>
|
||||
<NcDivider />
|
||||
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem clickable icon-wrapper-class="bg-green-50 dark:bg-nc-green-20">
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
clickable
|
||||
icon-wrapper-class="bg-green-50 dark:bg-nc-green-20"
|
||||
@click="openModal('publish')"
|
||||
>
|
||||
<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>
|
||||
<span class="text-green-600"> Publish v{{ managedAppVersionsInfo.current.version || '1.0.0' }} </span>
|
||||
</template>
|
||||
<template #subtext>
|
||||
{{ liveVersion ? `Replace v${liveVersion.version || '1.0.0'} and go live` : `Go live` }}
|
||||
{{
|
||||
managedAppVersionsInfo.published
|
||||
? `Replace v${managedAppVersionsInfo.published.version || '1.0.0'} and go live`
|
||||
: `Go live`
|
||||
}}
|
||||
</template>
|
||||
</SmartsheetTopbarManagedAppStatusMenuItem>
|
||||
</template>
|
||||
|
||||
<!-- Initial draft state -->
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
v-if="liveVersion && isDraft"
|
||||
v-if="managedAppVersionsInfo.published && isDraft"
|
||||
clickable
|
||||
label="Discard Draft"
|
||||
:subtext="`Return to v${liveVersion.version || '1.0.0'}`"
|
||||
:subtext="`Return to v${managedAppVersionsInfo.published.version || '1.0.0'}`"
|
||||
icon-wrapper-class="bg-nc-bg-gray-light"
|
||||
>
|
||||
<template #icon>
|
||||
@@ -156,7 +172,10 @@ watchEffect(() => {
|
||||
<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">
|
||||
<div
|
||||
class="flex items-center gap-2 px-5 py-2 text-captionSm text-nc-content-gray-muted cursor-pointer select-none"
|
||||
@click="openModal('deployments')"
|
||||
>
|
||||
<GeneralIcon icon="ncClock" />
|
||||
View version history
|
||||
</div>
|
||||
@@ -165,24 +184,26 @@ watchEffect(() => {
|
||||
<!-- Installer application -->
|
||||
<template v-if="isManagedAppInstaller">
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
:label="`v${liveVersion?.version || '1.0.0'}`"
|
||||
:label="`v${managedAppVersionsInfo.current?.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>
|
||||
<template v-if="managedAppVersionsInfo.current?.published_at" #subtext>
|
||||
<span class="text-green-600">
|
||||
<!-- Todo: @rameshmane7218 - Update text -->
|
||||
Installed Jan 10, 2025
|
||||
Published {{ parseStringDateTime(managedAppVersionsInfo.current?.published_at, undefined, true, 'MMM DD, YYYY') }}
|
||||
</span>
|
||||
</template>
|
||||
</SmartsheetTopbarManagedAppStatusMenuItem>
|
||||
|
||||
<div class="bg-nc-brand-20 dark:bg-nc-brand-20/40 -mb-1.5">
|
||||
<div
|
||||
v-if="!base.auto_update && managedAppVersionsInfo.updateAvailable"
|
||||
class="bg-nc-brand-20 dark:bg-nc-brand-20/40 -mb-1.5"
|
||||
>
|
||||
<SmartsheetTopbarManagedAppStatusMenuItem
|
||||
:label="`v${liveVersion?.version || '1.0.0'}`"
|
||||
:label="`v${managedAppVersionsInfo.published?.version || '1.0.0'}`"
|
||||
icon-wrapper-class="bg-brand-50 dark:bg-nc-brand-50"
|
||||
>
|
||||
<template #icon>
|
||||
@@ -218,7 +239,7 @@ watchEffect(() => {
|
||||
<SmartsheetTopbarManagedAppModal
|
||||
v-model:visible="isModalVisible"
|
||||
:managed-app="managedApp"
|
||||
:current-version="currentVersion"
|
||||
:current-version="managedAppVersionsInfo.current"
|
||||
:initial-tab="initialTab"
|
||||
@published="handlePublished"
|
||||
@forked="handleForked"
|
||||
|
||||
@@ -143,7 +143,7 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<GeneralModal :visible="visible" size="large" centered @update:visible="emit('update:visible', $event)">
|
||||
<NcModal :visible="visible" size="lg" nc-modal-class-name="!p-0" @update:visible="emit('update:visible', $event)">
|
||||
<div class="nc-deployments-modal">
|
||||
<!-- Header -->
|
||||
<div class="nc-deployments-header">
|
||||
@@ -246,7 +246,7 @@ watch(
|
||||
</div>
|
||||
<span class="nc-log-divider">•</span>
|
||||
<div class="nc-log-time">
|
||||
<GeneralIcon icon="clock" class="w-3.5 h-3.5 opacity-60" />
|
||||
<GeneralIcon icon="ncClock" class="w-3.5 h-3.5 opacity-60" />
|
||||
<span>{{ formatDate(log.createdAt) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -305,7 +305,7 @@ watch(
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GeneralModal>
|
||||
</NcModal>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -24,6 +24,10 @@ export const useBase = defineStore('baseStore', () => {
|
||||
|
||||
const liveVersion = ref<any>(null)
|
||||
|
||||
const managedAppVersions = ref<any[]>([])
|
||||
|
||||
const managedAppVersionsInfo = computed(() => {})
|
||||
|
||||
const isManagedAppMaster = ref(false)
|
||||
|
||||
const isManagedAppInstaller = ref(false)
|
||||
@@ -361,6 +365,8 @@ export const useBase = defineStore('baseStore', () => {
|
||||
currentVersion,
|
||||
liveVersion,
|
||||
loadCurrentVersion,
|
||||
managedAppVersions,
|
||||
managedAppVersionsInfo,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -104,3 +104,20 @@ export const extractAiBaseCreateQueryParams = (query: any) => {
|
||||
|
||||
return searchQuery
|
||||
}
|
||||
|
||||
export const suggestManagedAppNextVersion = (currentVersion?: string) => {
|
||||
if (!currentVersion) {
|
||||
return '1.0.0'
|
||||
}
|
||||
|
||||
const versionParts = currentVersion.split('.')
|
||||
|
||||
if (versionParts.length === 3) {
|
||||
// Increment minor version for new draft
|
||||
versionParts[1] = String(Number(versionParts[1]) + 1)
|
||||
versionParts[2] = '0'
|
||||
return versionParts.join('.')
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,16 +90,19 @@ export function parseStringDate(v: string, dateFormat: string) {
|
||||
export function parseStringDateTime(
|
||||
v: string,
|
||||
dateTimeFormat: string = `${dateFormats[0]} ${timeFormats[0]}`,
|
||||
toLocal: boolean = true
|
||||
toLocal: boolean = true,
|
||||
newDateTimeFormat?: string
|
||||
) {
|
||||
const dayjsObj = toLocal ? dayjs(v).local() : dayjs(v);
|
||||
|
||||
if (dayjsObj.isValid()) {
|
||||
v = dayjsObj.format(dateTimeFormat);
|
||||
v = dayjsObj.format(newDateTimeFormat || dateTimeFormat);
|
||||
} else {
|
||||
v = toLocal
|
||||
? dayjs(v, dateTimeFormat).local().format(dateTimeFormat)
|
||||
: dayjs(v, dateTimeFormat).format(dateTimeFormat);
|
||||
? dayjs(v, dateTimeFormat)
|
||||
.local()
|
||||
.format(newDateTimeFormat || dateTimeFormat)
|
||||
: dayjs(v, dateTimeFormat).format(newDateTimeFormat || dateTimeFormat);
|
||||
}
|
||||
|
||||
return v;
|
||||
|
||||
Reference in New Issue
Block a user