mirror of
https://github.com/nocodb/nocodb.git
synced 2026-02-01 23:58:31 +00:00
Merge pull request #12971 from nocodb/nc-fix/update-managed-app-base-icon
This commit is contained in:
@@ -16,6 +16,8 @@ interface CmdAction {
|
|||||||
keywords?: string[]
|
keywords?: string[]
|
||||||
section?: string
|
section?: string
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
|
managed_app_master?: boolean
|
||||||
|
managed_app_id?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -90,6 +92,8 @@ const nestedScope = computed(() => {
|
|||||||
section: parentEl?.section,
|
section: parentEl?.section,
|
||||||
iconType: parentEl?.iconType,
|
iconType: parentEl?.iconType,
|
||||||
iconColor: parent.startsWith('ws-') ? parentEl?.iconColor : null,
|
iconColor: parent.startsWith('ws-') ? parentEl?.iconColor : null,
|
||||||
|
managed_app_master: !!parentEl?.managed_app_master,
|
||||||
|
managed_app_id: parentEl?.managed_app_id || '',
|
||||||
})
|
})
|
||||||
parent = parentEl?.parent || 'root'
|
parent = parentEl?.parent || 'root'
|
||||||
}
|
}
|
||||||
@@ -431,9 +435,13 @@ defineExpose({
|
|||||||
|
|
||||||
<template v-else-if="el.section === 'Bases' || el.icon === 'project'">
|
<template v-else-if="el.section === 'Bases' || el.icon === 'project'">
|
||||||
<GeneralBaseIconColorPicker
|
<GeneralBaseIconColorPicker
|
||||||
:key="el.iconColor"
|
:key="`${el.iconColor}-${el.managed_app_id}-${el.managed_app_master}`"
|
||||||
:model-value="el.iconColor"
|
:model-value="el.iconColor"
|
||||||
type="database"
|
type="database"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: el.managed_app_master,
|
||||||
|
managed_app_id: el.managed_app_id,
|
||||||
|
}"
|
||||||
readonly
|
readonly
|
||||||
class="cmdk-action-icon !w-5"
|
class="cmdk-action-icon !w-5"
|
||||||
>
|
>
|
||||||
@@ -544,10 +552,14 @@ defineExpose({
|
|||||||
/>
|
/>
|
||||||
<template v-else-if="item.data.section === 'Bases' || item.data.icon === 'project'">
|
<template v-else-if="item.data.section === 'Bases' || item.data.icon === 'project'">
|
||||||
<GeneralBaseIconColorPicker
|
<GeneralBaseIconColorPicker
|
||||||
:key="item.data.iconColor"
|
:key="`${item.data.iconColor}-${item.data.managed_app_id}-${item.data.managed_app_master}`"
|
||||||
:model-value="item.data.iconColor"
|
:model-value="item.data.iconColor"
|
||||||
type="database"
|
type="database"
|
||||||
readonly
|
readonly
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: item.data.managed_app_master,
|
||||||
|
managed_app_id: item.data.managed_app_id,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
</GeneralBaseIconColorPicker>
|
</GeneralBaseIconColorPicker>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -219,7 +219,14 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex w-1/2 justify-end text-nc-content-gray-subtle2">
|
<div class="flex w-1/2 justify-end text-nc-content-gray-subtle2">
|
||||||
<div class="flex gap-2 px-2 py-1 rounded-md items-center">
|
<div class="flex gap-2 px-2 py-1 rounded-md items-center">
|
||||||
<component :is="iconMap.project" class="w-4 h-4" />
|
<GeneralProjectIcon
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: cmdOption?.managed_app_master,
|
||||||
|
managed_app_id: cmdOption?.managed_app_id,
|
||||||
|
}"
|
||||||
|
:color="cmdOption?.iconColor"
|
||||||
|
class="!h-4 !w-4"
|
||||||
|
/>
|
||||||
<a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg" :tooltip-style="{ zIndex: 1100 }">
|
<a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg" :tooltip-style="{ zIndex: 1100 }">
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ cmdOption.baseName }}
|
{{ cmdOption.baseName }}
|
||||||
|
|||||||
@@ -52,7 +52,15 @@ const onDelete = async () => {
|
|||||||
v-if="base"
|
v-if="base"
|
||||||
class="flex flex-row items-center py-2 px-2.25 bg-nc-bg-gray-extralight rounded-lg text-nc-content-gray-subtle"
|
class="flex flex-row items-center py-2 px-2.25 bg-nc-bg-gray-extralight rounded-lg text-nc-content-gray-subtle"
|
||||||
>
|
>
|
||||||
<GeneralProjectIcon :color="parseProp(base.meta).iconColor" :type="base.type" class="nc-view-icon w-6 h-6 mx-1" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(base.meta).iconColor"
|
||||||
|
:type="base.type"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: base.managed_app_master,
|
||||||
|
managed_app_id: base.managed_app_id,
|
||||||
|
}"
|
||||||
|
class="nc-view-icon w-6 h-6 mx-1"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
class="capitalize text-ellipsis overflow-hidden select-none w-full pl-1.75"
|
class="capitalize text-ellipsis overflow-hidden select-none w-full pl-1.75"
|
||||||
:style="{ wordBreak: 'keep-all', whiteSpace: 'nowrap', display: 'inline' }"
|
:style="{ wordBreak: 'keep-all', whiteSpace: 'nowrap', display: 'inline' }"
|
||||||
|
|||||||
@@ -394,7 +394,14 @@ onMounted(() => {
|
|||||||
>
|
>
|
||||||
<template v-if="!!targetBase">
|
<template v-if="!!targetBase">
|
||||||
<div class="flex-1 capitalize truncate flex gap-1">
|
<div class="flex-1 capitalize truncate flex gap-1">
|
||||||
<GeneralProjectIcon :color="parseProp(targetBase?.meta ?? {}).iconColor" size="small" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(targetBase?.meta ?? {}).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: targetBase?.managed_app_master,
|
||||||
|
managed_app_id: targetBase?.managed_app_id,
|
||||||
|
}"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
{{ targetBase?.title }}
|
{{ targetBase?.title }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -439,7 +446,14 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #listItemExtraLeft="{ option: optionItem }">
|
<template #listItemExtraLeft="{ option: optionItem }">
|
||||||
<GeneralProjectIcon :color="parseProp(optionItem.meta).iconColor" size="small" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(optionItem.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: optionItem.managed_app_master,
|
||||||
|
managed_app_id: optionItem.managed_app_id,
|
||||||
|
}"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #listItemExtraRight="{ option: optionItem }">
|
<template #listItemExtraRight="{ option: optionItem }">
|
||||||
<div v-if="activeBase?.id === optionItem.id" class="text-nc-content-gray-muted leading-4.5 text-xs">
|
<div v-if="activeBase?.id === optionItem.id" class="text-nc-content-gray-muted leading-4.5 text-xs">
|
||||||
|
|||||||
@@ -143,7 +143,15 @@ watch(showShareModal, (val) => {
|
|||||||
|
|
||||||
<div class="share-base">
|
<div class="share-base">
|
||||||
<div class="flex flex-row items-center gap-x-2 px-4 pt-3 pb-3 select-none">
|
<div class="flex flex-row items-center gap-x-2 px-4 pt-3 pb-3 select-none">
|
||||||
<GeneralProjectIcon :color="parseProp(base.meta).iconColor" :type="base.type" class="nc-view-icon group-hover" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(base.meta).iconColor"
|
||||||
|
:type="base.type"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: base.managed_app_master,
|
||||||
|
managed_app_id: base.managed_app_id,
|
||||||
|
}"
|
||||||
|
class="nc-view-icon group-hover"
|
||||||
|
/>
|
||||||
|
|
||||||
<div>{{ $t('activity.shareBase.label') }}</div>
|
<div>{{ $t('activity.shareBase.label') }}</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ const props = withDefaults(
|
|||||||
size?: 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'
|
size?: 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
iconClass?: string
|
iconClass?: string
|
||||||
|
managedApp?: {
|
||||||
|
managed_app_master?: boolean
|
||||||
|
managed_app_id?: string
|
||||||
|
}
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
size: 'small',
|
size: 'small',
|
||||||
@@ -16,13 +20,17 @@ const props = withDefaults(
|
|||||||
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const { modelValue, readonly } = toRefs(props)
|
const { modelValue, readonly, managedApp } = toRefs(props)
|
||||||
const { size } = props
|
const { size } = props
|
||||||
|
|
||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
|
|
||||||
const colorRef = ref(tinycolor(modelValue.value).isValid() ? modelValue.value : baseIconColors[0])
|
const colorRef = ref(tinycolor(modelValue.value).isValid() ? modelValue.value : baseIconColors[0])
|
||||||
|
|
||||||
|
const isMasterManagedApp = computed(() => {
|
||||||
|
return isEeUI && !!managedApp.value?.managed_app_id && !!managedApp.value?.managed_app_master
|
||||||
|
})
|
||||||
|
|
||||||
const updateIconColor = (color: string) => {
|
const updateIconColor = (color: string) => {
|
||||||
const tcolor = tinycolor(color)
|
const tcolor = tinycolor(color)
|
||||||
if (tcolor.isValid()) {
|
if (tcolor.isValid()) {
|
||||||
@@ -31,7 +39,7 @@ const updateIconColor = (color: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onClick = (e: Event) => {
|
const onClick = (e: Event) => {
|
||||||
if (readonly.value) return
|
if (readonly.value || isMasterManagedApp.value) return
|
||||||
|
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
@@ -56,13 +64,13 @@ watch(
|
|||||||
<a-dropdown
|
<a-dropdown
|
||||||
v-model:visible="isOpen"
|
v-model:visible="isOpen"
|
||||||
:trigger="['click']"
|
:trigger="['click']"
|
||||||
:disabled="readonly"
|
:disabled="readonly || isMasterManagedApp"
|
||||||
overlay-class-name="nc-base-icon-color-picker-dropdown overflow-hidden max-w-[342px] relative"
|
overlay-class-name="nc-base-icon-color-picker-dropdown overflow-hidden max-w-[342px] relative"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-row justify-center items-center select-none rounded nc-base-icon-picker-trigger"
|
class="flex flex-row justify-center items-center select-none rounded nc-base-icon-picker-trigger"
|
||||||
:class="{
|
:class="{
|
||||||
'hover:bg-gray-500 dark:hover:bg-nc-bg-gray-dark hover:bg-opacity-15 cursor-pointer': !readonly,
|
'hover:bg-gray-500 dark:hover:bg-nc-bg-gray-dark hover:bg-opacity-15 cursor-pointer': !readonly && !isMasterManagedApp,
|
||||||
'bg-gray-500 dark:bg-nc-bg-gray-dark bg-opacity-15': isOpen,
|
'bg-gray-500 dark:bg-nc-bg-gray-dark bg-opacity-15': isOpen,
|
||||||
'h-5 w-5 text-base': size === 'xsmall',
|
'h-5 w-5 text-base': size === 'xsmall',
|
||||||
'h-6 w-6 text-lg': size === 'small',
|
'h-6 w-6 text-lg': size === 'small',
|
||||||
@@ -73,14 +81,17 @@ watch(
|
|||||||
@click="onClick"
|
@click="onClick"
|
||||||
>
|
>
|
||||||
<NcTooltip placement="topLeft" :disabled="readonly || isOpen">
|
<NcTooltip placement="topLeft" :disabled="readonly || isOpen">
|
||||||
<template #title> {{ $t('tooltip.changeIconColour') }} </template>
|
<template #title>
|
||||||
|
{{
|
||||||
|
isMasterManagedApp ? $t('tooltip.changeIconColorNotSupportedForManagedMasterApp') : $t('tooltip.changeIconColour')
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
|
||||||
<div>
|
<div class="flex items-center">
|
||||||
<GeneralProjectIcon :color="colorRef" :class="iconClass" />
|
<GeneralProjectIcon :color="colorRef" :class="iconClass" :managed-app="managedApp" />
|
||||||
</div>
|
</div>
|
||||||
</NcTooltip>
|
</NcTooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<div class="flex justify-start">
|
<div class="flex justify-start">
|
||||||
<GeneralColorPicker
|
<GeneralColorPicker
|
||||||
|
|||||||
@@ -5,28 +5,51 @@ const props = withDefaults(
|
|||||||
defineProps<{
|
defineProps<{
|
||||||
hoverable?: boolean
|
hoverable?: boolean
|
||||||
color?: string
|
color?: string
|
||||||
|
managedApp?: {
|
||||||
|
managed_app_master?: boolean
|
||||||
|
managed_app_id?: string
|
||||||
|
}
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
color: baseIconColors[0],
|
color: baseIconColors[0],
|
||||||
|
managedApp: () => ({}),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const { color } = toRefs(props)
|
const { color, managedApp } = toRefs(props)
|
||||||
|
|
||||||
|
const managedAppInfo = computed(() => {
|
||||||
|
return {
|
||||||
|
isManagedApp: isEeUI && !!managedApp.value?.managed_app_id,
|
||||||
|
isMaster: !!managedApp.value?.managed_app_master && !!managedApp.value?.managed_app_id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const iconColor = computed(() => {
|
const iconColor = computed(() => {
|
||||||
return color.value && tinycolor(color.value).isValid()
|
return color.value && tinycolor(color.value).isValid()
|
||||||
? {
|
? {
|
||||||
tint: baseIconColors.includes(color.value) ? color.value : tinycolor(color.value).lighten(10).toHexString(),
|
tint: baseIconColors.includes(color.value) ? color.value : tinycolor(color.value).lighten(10).toHexString(),
|
||||||
shade: tinycolor(color.value).darken(40).toHexString(),
|
shade: tinycolor(color.value)
|
||||||
|
.darken(managedAppInfo.value.isManagedApp ? 30 : 40)
|
||||||
|
.toHexString(),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
tint: baseIconColors[0],
|
tint: baseIconColors[0],
|
||||||
shade: tinycolor(baseIconColors[0]).darken(40).toHexString(),
|
shade: tinycolor(baseIconColors[0])
|
||||||
|
.darken(managedAppInfo.value.isManagedApp ? 30 : 40)
|
||||||
|
.toHexString(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Unique gradient ID based on app ID and color to avoid SVG gradient conflicts
|
||||||
|
const gradientId = computed(() => {
|
||||||
|
const colorHash = color.value?.replace('#', '') || 'default'
|
||||||
|
return `sphere-${managedApp.value?.managed_app_id || 'default'}-${colorHash}`
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg
|
<svg
|
||||||
|
v-if="!managedAppInfo.isManagedApp"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="20"
|
width="20"
|
||||||
height="20"
|
height="20"
|
||||||
@@ -46,11 +69,43 @@ const iconColor = computed(() => {
|
|||||||
:fill="iconColor.tint"
|
:fill="iconColor.tint"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
<!-- Master managed app - keep original icon -->
|
||||||
|
<GeneralIcon
|
||||||
|
v-else-if="managedAppInfo.isMaster"
|
||||||
|
icon="ncBox"
|
||||||
|
class="h-4.5 w-4.5 nc-base-icon text-nc-content-gray-subtle2"
|
||||||
|
:class="{
|
||||||
|
'nc-base-icon-hoverable': hoverable,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<!-- 3D Sphere icon for installed managed apps -->
|
||||||
|
<svg
|
||||||
|
v-else
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
class="nc-base-icon"
|
||||||
|
:class="{
|
||||||
|
'nc-base-icon-hoverable': hoverable,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<!-- Radial gradient for 3D sphere effect - light from top-left -->
|
||||||
|
<radialGradient :id="gradientId" cx="30%" cy="30%" r="70%" fx="25%" fy="25%">
|
||||||
|
<stop offset="0%" :stop-color="iconColor.tint" />
|
||||||
|
<stop offset="100%" :stop-color="iconColor.shade" />
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
<!-- Main sphere -->
|
||||||
|
<circle cx="10" cy="10" r="8" :fill="`url(#${gradientId})`" />
|
||||||
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.nc-base-icon {
|
.nc-base-icon {
|
||||||
@apply text-xl;
|
@apply flex-none text-xl;
|
||||||
}
|
}
|
||||||
.nc-base-icon-hoverable {
|
.nc-base-icon-hoverable {
|
||||||
@apply cursor-pointer !hover:bg-nc-bg-gray-medium !hover:bg-opacity-50;
|
@apply cursor-pointer !hover:bg-nc-bg-gray-medium !hover:bg-opacity-50;
|
||||||
|
|||||||
@@ -141,7 +141,14 @@ defineExpose({
|
|||||||
<NcListDropdown v-model:is-open="isOpenBaseSelectDropdown" :disabled="disabled" :has-error="!!selectedBase?.ncItemDisabled">
|
<NcListDropdown v-model:is-open="isOpenBaseSelectDropdown" :disabled="disabled" :has-error="!!selectedBase?.ncItemDisabled">
|
||||||
<div class="flex-1 flex items-center gap-2 min-w-0">
|
<div class="flex-1 flex items-center gap-2 min-w-0">
|
||||||
<div v-if="selectedBase" class="min-w-5 flex items-center justify-center">
|
<div v-if="selectedBase" class="min-w-5 flex items-center justify-center">
|
||||||
<GeneralProjectIcon :color="parseProp(selectedBase.meta).iconColor" size="small" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(selectedBase.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: selectedBase.managed_app_master,
|
||||||
|
managed_app_id: selectedBase.managed_app_id,
|
||||||
|
}"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<NcTooltip hide-on-click class="flex-1 truncate" show-on-truncate-only>
|
<NcTooltip hide-on-click class="flex-1 truncate" show-on-truncate-only>
|
||||||
<span
|
<span
|
||||||
@@ -178,7 +185,14 @@ defineExpose({
|
|||||||
>
|
>
|
||||||
<template #listItemExtraLeft="{ option }">
|
<template #listItemExtraLeft="{ option }">
|
||||||
<div class="min-w-5 flex items-center justify-center">
|
<div class="min-w-5 flex items-center justify-center">
|
||||||
<GeneralProjectIcon :color="parseProp(option.meta).iconColor" size="small" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(option.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: option.managed_app_master,
|
||||||
|
managed_app_id: option.managed_app_id,
|
||||||
|
}"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</NcList>
|
</NcList>
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ const baseOptions = computed(() => {
|
|||||||
label: base.title,
|
label: base.title,
|
||||||
value: base.id,
|
value: base.id,
|
||||||
meta: base.meta,
|
meta: base.meta,
|
||||||
|
managed_app_master: base.managed_app_master,
|
||||||
|
managed_app_id: base.managed_app_id,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@@ -41,7 +43,14 @@ const baseOptions = computed(() => {
|
|||||||
<a-select-option v-for="option of baseOptions" :key="option.value" :value="option.value" :data-label="option.label">
|
<a-select-option v-for="option of baseOptions" :key="option.value" :value="option.value" :data-label="option.label">
|
||||||
<div class="w-full flex gap-2 items-center" :data-testid="option.value">
|
<div class="w-full flex gap-2 items-center" :data-testid="option.value">
|
||||||
<div class="min-w-5 flex items-center justify-center">
|
<div class="min-w-5 flex items-center justify-center">
|
||||||
<GeneralProjectIcon :color="parseProp(option.meta).iconColor" size="small" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(option.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: option.managed_app_master,
|
||||||
|
managed_app_id: option.managed_app_id,
|
||||||
|
}"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<NcTooltip class="flex-1 truncate min-w-0" show-on-truncate-only>
|
<NcTooltip class="flex-1 truncate min-w-0" show-on-truncate-only>
|
||||||
<template #title>
|
<template #title>
|
||||||
|
|||||||
@@ -569,7 +569,13 @@ onBeforeUnmount(() => {
|
|||||||
<NcPageHeader>
|
<NcPageHeader>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<div class="nc-page-header-icon flex justify-center items-center h-5 w-5">
|
<div class="nc-page-header-icon flex justify-center items-center h-5 w-5">
|
||||||
<GeneralBaseIconColorPicker readonly />
|
<GeneralBaseIconColorPicker
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: currentBase?.managed_app_master,
|
||||||
|
managed_app_id: currentBase?.managed_app_id,
|
||||||
|
}"
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #title>
|
<template #title>
|
||||||
|
|||||||
@@ -208,6 +208,10 @@ onMounted(() => {
|
|||||||
<GeneralProjectIcon
|
<GeneralProjectIcon
|
||||||
:color="parseProp(currentBase?.meta).iconColor"
|
:color="parseProp(currentBase?.meta).iconColor"
|
||||||
:type="currentBase?.type"
|
:type="currentBase?.type"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: currentBase?.managed_app_master,
|
||||||
|
managed_app_id: currentBase?.managed_app_id,
|
||||||
|
}"
|
||||||
class="h-6 w-6 md:(h-4 w-4) flex-none"
|
class="h-6 w-6 md:(h-4 w-4) flex-none"
|
||||||
/>
|
/>
|
||||||
<NcTooltip
|
<NcTooltip
|
||||||
|
|||||||
@@ -224,10 +224,6 @@ const refViews = computed(() => {
|
|||||||
return (views || []).filter((v) => v.type !== ViewTypes.FORM)
|
return (views || []).filter((v) => v.type !== ViewTypes.FORM)
|
||||||
})
|
})
|
||||||
|
|
||||||
const filterOption = (value: string, option: { key: string }) => {
|
|
||||||
return option.key.toLowerCase().includes(value.toLowerCase())
|
|
||||||
}
|
|
||||||
|
|
||||||
const isLinks = computed(() => vModel.value.uidt === UITypes.Links && vModel.value.type !== RelationTypes.ONE_TO_ONE)
|
const isLinks = computed(() => vModel.value.uidt === UITypes.Links && vModel.value.type !== RelationTypes.ONE_TO_ONE)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -529,7 +525,7 @@ const handleScrollIntoView = () => {
|
|||||||
v-model:value="referenceBaseId"
|
v-model:value="referenceBaseId"
|
||||||
show-search
|
show-search
|
||||||
:disabled="isEdit"
|
:disabled="isEdit"
|
||||||
:filter-option="filterOption"
|
:filter-option="(input, option) => antSelectFilterOption(input, option, ['data-label'])"
|
||||||
placeholder="Select base"
|
placeholder="Select base"
|
||||||
dropdown-class-name="nc-dropdown-ltar-child-table"
|
dropdown-class-name="nc-dropdown-ltar-child-table"
|
||||||
@change="onBaseChange(referenceBaseId)"
|
@change="onBaseChange(referenceBaseId)"
|
||||||
@@ -539,7 +535,8 @@ const handleScrollIntoView = () => {
|
|||||||
</template>
|
</template>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="base of basesList"
|
v-for="base of basesList"
|
||||||
:key="base.title"
|
:key="base.id"
|
||||||
|
:data-label="base.title"
|
||||||
:disabled="!canCreateCrossBaseLink(base)"
|
:disabled="!canCreateCrossBaseLink(base)"
|
||||||
:value="base.id"
|
:value="base.id"
|
||||||
>
|
>
|
||||||
@@ -549,7 +546,15 @@ const handleScrollIntoView = () => {
|
|||||||
</template>
|
</template>
|
||||||
<div class="flex w-full items-center gap-2">
|
<div class="flex w-full items-center gap-2">
|
||||||
<div class="min-w-5 flex items-center justify-center">
|
<div class="min-w-5 flex items-center justify-center">
|
||||||
<GeneralProjectIcon :color="parseProp(base.meta).iconColor" :type="base.type" class="nc-project-icon" />
|
<GeneralProjectIcon
|
||||||
|
:color="parseProp(base.meta).iconColor"
|
||||||
|
:type="base.type"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: base.managed_app_master,
|
||||||
|
managed_app_id: base.managed_app_id,
|
||||||
|
}"
|
||||||
|
class="nc-project-icon"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||||
<template #title>{{ base.title }}</template>
|
<template #title>{{ base.title }}</template>
|
||||||
@@ -573,7 +578,7 @@ const handleScrollIntoView = () => {
|
|||||||
v-model:value="referenceTableChildId"
|
v-model:value="referenceTableChildId"
|
||||||
show-search
|
show-search
|
||||||
:disabled="isEdit || isLinkedTablePrivate"
|
:disabled="isEdit || isLinkedTablePrivate"
|
||||||
:filter-option="filterOption"
|
:filter-option="(input, option) => antSelectFilterOption(input, option, ['data-label'])"
|
||||||
placeholder="select table to link"
|
placeholder="select table to link"
|
||||||
dropdown-class-name="nc-dropdown-ltar-child-table"
|
dropdown-class-name="nc-dropdown-ltar-child-table"
|
||||||
@change="handleUpdateRefTable"
|
@change="handleUpdateRefTable"
|
||||||
@@ -583,7 +588,8 @@ const handleScrollIntoView = () => {
|
|||||||
</template>
|
</template>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="table of refTables"
|
v-for="table of refTables"
|
||||||
:key="table.title"
|
:key="table.id"
|
||||||
|
:data-label="table.title"
|
||||||
:value="table.id"
|
:value="table.id"
|
||||||
:disabled="(table as any).is_private"
|
:disabled="(table as any).is_private"
|
||||||
>
|
>
|
||||||
@@ -661,10 +667,16 @@ const handleScrollIntoView = () => {
|
|||||||
:placeholder="$t('labels.selectView')"
|
:placeholder="$t('labels.selectView')"
|
||||||
show-search
|
show-search
|
||||||
:disabled="isLinkedViewPrivate"
|
:disabled="isLinkedViewPrivate"
|
||||||
:filter-option="filterOption"
|
:filter-option="(input, option) => antSelectFilterOption(input, option, ['data-label'])"
|
||||||
dropdown-class-name="nc-dropdown-ltar-child-view"
|
dropdown-class-name="nc-dropdown-ltar-child-view"
|
||||||
>
|
>
|
||||||
<a-select-option v-for="view of refViews" :key="view.title" :value="view.id" :disabled="(view as any).is_private">
|
<a-select-option
|
||||||
|
v-for="view of refViews"
|
||||||
|
:key="view.id"
|
||||||
|
:value="view.id"
|
||||||
|
:data-label="view.title"
|
||||||
|
:disabled="(view as any).is_private"
|
||||||
|
>
|
||||||
<div class="flex w-full items-center gap-2">
|
<div class="flex w-full items-center gap-2">
|
||||||
<div class="min-w-5 flex items-center justify-center">
|
<div class="min-w-5 flex items-center justify-center">
|
||||||
<GeneralViewIcon
|
<GeneralViewIcon
|
||||||
|
|||||||
@@ -83,7 +83,15 @@ const viewModeInfo = computed(() => {
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<GeneralProjectIcon :type="base?.type" :color="parseProp(base.meta).iconColor" class="!grayscale min-w-4" />
|
<GeneralProjectIcon
|
||||||
|
:type="base?.type"
|
||||||
|
:color="parseProp(base.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: base?.managed_app_master,
|
||||||
|
managed_app_id: base?.managed_app_id,
|
||||||
|
}"
|
||||||
|
class="!grayscale min-w-4"
|
||||||
|
/>
|
||||||
</NcTooltip>
|
</NcTooltip>
|
||||||
<template v-if="isSharedBase">
|
<template v-if="isSharedBase">
|
||||||
<NcTooltip
|
<NcTooltip
|
||||||
|
|||||||
@@ -59,7 +59,16 @@ const handleNavigateToProject = async (base: NcProject) => {
|
|||||||
@change="handleNavigateToProject"
|
@change="handleNavigateToProject"
|
||||||
>
|
>
|
||||||
<template #listItem="{ option }">
|
<template #listItem="{ option }">
|
||||||
<GeneralBaseIconColorPicker :type="option?.type" :model-value="parseProp(option.meta).iconColor" size="xsmall" readonly>
|
<GeneralBaseIconColorPicker
|
||||||
|
:type="option?.type"
|
||||||
|
:model-value="parseProp(option.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: option?.managed_app_master,
|
||||||
|
managed_app_id: option?.managed_app_id,
|
||||||
|
}"
|
||||||
|
size="xsmall"
|
||||||
|
readonly
|
||||||
|
>
|
||||||
</GeneralBaseIconColorPicker>
|
</GeneralBaseIconColorPicker>
|
||||||
<NcTooltip class="truncate flex-1" show-on-truncate-only>
|
<NcTooltip class="truncate flex-1" show-on-truncate-only>
|
||||||
<template #title>
|
<template #title>
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ onMounted(() => {
|
|||||||
<GeneralBaseIconColorPicker
|
<GeneralBaseIconColorPicker
|
||||||
:type="option?.type"
|
:type="option?.type"
|
||||||
:model-value="parseProp(option.meta).iconColor"
|
:model-value="parseProp(option.meta).iconColor"
|
||||||
|
:managed-app="{
|
||||||
|
managed_app_master: option?.managed_app_master,
|
||||||
|
managed_app_id: option?.managed_app_id,
|
||||||
|
}"
|
||||||
size="xsmall"
|
size="xsmall"
|
||||||
readonly
|
readonly
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2128,6 +2128,7 @@
|
|||||||
"clientCert": "Select .cert file",
|
"clientCert": "Select .cert file",
|
||||||
"clientCA": "Select CA file",
|
"clientCA": "Select CA file",
|
||||||
"changeIconColour": "Change icon colour",
|
"changeIconColour": "Change icon colour",
|
||||||
|
"changeIconColorNotSupportedForManagedMasterApp": "Change icon color is not supported for managed master app",
|
||||||
"preFillFormInfo": "To get a prefilled link, make sure you’ve filled the necessary fields in the form view builder.",
|
"preFillFormInfo": "To get a prefilled link, make sure you’ve filled the necessary fields in the form view builder.",
|
||||||
"surveyFormInfo": "Form mode with one field per page",
|
"surveyFormInfo": "Form mode with one field per page",
|
||||||
"useFieldEditMenuToConfigFieldType": "Use field edit menu for type conversions after file is imported",
|
"useFieldEditMenuToConfigFieldType": "Use field edit menu for type conversions after file is imported",
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const color1 = ref('')
|
const color1 = ref('')
|
||||||
|
|
||||||
|
const managedApp = ref({
|
||||||
|
managed_app_master: false,
|
||||||
|
managed_app_id: 'prr1pr4xx9vqn5c',
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -8,8 +13,17 @@ const color1 = ref('')
|
|||||||
<h4>Simple</h4>
|
<h4>Simple</h4>
|
||||||
|
|
||||||
Selected color: {{ color1 }}
|
Selected color: {{ color1 }}
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<NcSwitch v-model:checked="managedApp.managed_app_master"> Toggle Managed App state </NcSwitch>
|
||||||
|
</div>
|
||||||
<div class="inline-block min-h-[24px] min-w-[24px] h-[24px] w-[24px] rounded-md" :class="[`bg-${color1}`]"></div>
|
<div class="inline-block min-h-[24px] min-w-[24px] h-[24px] w-[24px] rounded-md" :class="[`bg-${color1}`]"></div>
|
||||||
<GeneralBaseIconColorPicker :model-value="color1" type="database" @update:model-value="color1 = $event">
|
<GeneralBaseIconColorPicker
|
||||||
|
:model-value="color1"
|
||||||
|
type="database"
|
||||||
|
@update:model-value="color1 = $event"
|
||||||
|
:managed-app="managedApp"
|
||||||
|
>
|
||||||
</GeneralBaseIconColorPicker>
|
</GeneralBaseIconColorPicker>
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1264,7 +1264,7 @@ export const useViewsStore = defineStore('viewsStore', () => {
|
|||||||
|
|
||||||
const tableName = tablesStore.baseTables.get(view.base_id)?.find((t) => t.id === view.fk_model_id)?.title
|
const tableName = tablesStore.baseTables.get(view.base_id)?.find((t) => t.id === view.fk_model_id)?.title
|
||||||
|
|
||||||
const baseName = bases.basesList.find((p) => p.id === view.base_id)?.title
|
const base = bases.basesList.find((p) => p.id === view.base_id)
|
||||||
allRecentViews.value = [
|
allRecentViews.value = [
|
||||||
{
|
{
|
||||||
viewId: view.id,
|
viewId: view.id,
|
||||||
@@ -1274,7 +1274,10 @@ export const useViewsStore = defineStore('viewsStore', () => {
|
|||||||
viewType: view.type,
|
viewType: view.type,
|
||||||
workspaceId: activeWorkspaceId.value,
|
workspaceId: activeWorkspaceId.value,
|
||||||
tableName: tableName as string,
|
tableName: tableName as string,
|
||||||
baseName: baseName as string,
|
baseName: base?.title as string,
|
||||||
|
managed_app_master: base?.managed_app_master,
|
||||||
|
managed_app_id: base?.managed_app_id,
|
||||||
|
iconColor: parseProp(base?.meta).iconColor,
|
||||||
},
|
},
|
||||||
...allRecentViews.value.filter((f) => f.viewId !== view.id || f.tableID !== view.fk_model_id),
|
...allRecentViews.value.filter((f) => f.viewId !== view.id || f.tableID !== view.fk_model_id),
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user