refactor(frontend) : redesign TaskGitSection with tabs and collapsible commits, add scrollable modal
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,147 +1,231 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mt-5 rounded-lg border border-neutral-200 bg-neutral-50 p-4">
|
<div class="mt-5 rounded-lg border border-neutral-200 bg-neutral-50">
|
||||||
<h3 class="text-sm font-bold text-neutral-900">{{ $t('gitea.branch.title') }}</h3>
|
<!-- Header with tabs -->
|
||||||
|
<div class="flex items-center justify-between border-b border-neutral-200 bg-neutral-100/60 px-4 py-2">
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="rounded-md px-3 py-1.5 text-xs font-semibold transition-colors"
|
||||||
|
:class="activeTab === 'branches'
|
||||||
|
? 'bg-white text-neutral-900 shadow-sm ring-1 ring-neutral-200'
|
||||||
|
: 'text-neutral-500 hover:text-neutral-700'"
|
||||||
|
@click="activeTab = 'branches'"
|
||||||
|
>
|
||||||
|
<Icon name="mdi:source-branch" size="14" class="mr-1 inline-block align-[-2px]" />
|
||||||
|
{{ $t('gitea.branch.title') }}
|
||||||
|
<span
|
||||||
|
v-if="branches.length"
|
||||||
|
class="ml-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-neutral-200 px-1 text-[10px] font-bold text-neutral-600"
|
||||||
|
>{{ branches.length }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="rounded-md px-3 py-1.5 text-xs font-semibold transition-colors"
|
||||||
|
:class="activeTab === 'prs'
|
||||||
|
? 'bg-white text-neutral-900 shadow-sm ring-1 ring-neutral-200'
|
||||||
|
: 'text-neutral-500 hover:text-neutral-700'"
|
||||||
|
@click="activeTab = 'prs'"
|
||||||
|
>
|
||||||
|
<Icon name="mdi:source-pull" size="14" class="mr-1 inline-block align-[-2px]" />
|
||||||
|
{{ $t('gitea.pr.title') }}
|
||||||
|
<span
|
||||||
|
v-if="pullRequests.length"
|
||||||
|
class="ml-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-bold"
|
||||||
|
:class="hasOpenPr ? 'bg-green-100 text-green-700' : 'bg-neutral-200 text-neutral-600'"
|
||||||
|
>{{ pullRequests.length }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Error state -->
|
<!-- Actions -->
|
||||||
<p v-if="error" class="mt-2 text-sm text-red-500">{{ $t('gitea.error') }}</p>
|
<div class="flex gap-1">
|
||||||
|
<button
|
||||||
<!-- Create branch form -->
|
v-if="activeTab === 'branches'"
|
||||||
<div v-if="!showCreateForm" class="mt-3 flex gap-2">
|
type="button"
|
||||||
<button
|
class="rounded-md px-2.5 py-1.5 text-xs font-medium text-neutral-500 transition-colors hover:bg-neutral-200/60 hover:text-neutral-700"
|
||||||
type="button"
|
:title="$t('gitea.branch.copy')"
|
||||||
class="rounded-md bg-primary-500 px-3 py-1.5 text-xs font-semibold text-white hover:bg-secondary-500"
|
@click="handleCopy"
|
||||||
@click="showCreateForm = true"
|
>
|
||||||
>
|
<Icon name="mdi:content-copy" size="14" />
|
||||||
{{ $t('gitea.branch.create') }}
|
</button>
|
||||||
</button>
|
<button
|
||||||
<button
|
v-if="activeTab === 'branches'"
|
||||||
type="button"
|
type="button"
|
||||||
class="rounded-md border border-neutral-300 px-3 py-1.5 text-xs font-semibold text-neutral-600 hover:bg-neutral-100"
|
class="rounded-md bg-primary-500 px-2.5 py-1.5 text-xs font-semibold text-white transition-colors hover:bg-secondary-500"
|
||||||
@click="handleCopy"
|
@click="showCreateForm = !showCreateForm"
|
||||||
>
|
>
|
||||||
{{ $t('gitea.branch.copy') }}
|
<Icon name="mdi:plus" size="14" class="mr-0.5 inline-block align-[-2px]" />
|
||||||
</button>
|
{{ $t('gitea.branch.create') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="showCreateForm" class="mt-3 space-y-3 rounded-md border border-neutral-200 bg-white p-3">
|
<!-- Error state -->
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div v-if="error" class="px-4 py-3">
|
||||||
<MalioSelect
|
<p class="text-xs text-red-500">{{ $t('gitea.error') }}</p>
|
||||||
v-model="branchForm.type"
|
</div>
|
||||||
:options="typeOptions"
|
|
||||||
:label="$t('gitea.branch.type')"
|
<!-- Create branch form (inline) -->
|
||||||
min-width="w-full"
|
<Transition name="slide-down">
|
||||||
/>
|
<div v-if="showCreateForm && activeTab === 'branches'" class="relative z-20 border-b border-neutral-200 bg-white px-4 py-3">
|
||||||
<MalioInputText
|
<div class="grid grid-cols-[1fr_1fr_auto] items-end gap-3">
|
||||||
v-model="branchForm.baseBranch"
|
<MalioSelect
|
||||||
:label="$t('gitea.branch.baseBranch')"
|
v-model="branchForm.type"
|
||||||
input-class="w-full"
|
:options="typeOptions"
|
||||||
/>
|
:label="$t('gitea.branch.type')"
|
||||||
</div>
|
min-width="w-full"
|
||||||
<div>
|
/>
|
||||||
<p class="text-xs text-neutral-500">{{ $t('gitea.branch.preview') }}</p>
|
<MalioInputText
|
||||||
<code class="mt-1 block rounded bg-neutral-100 px-2 py-1 text-xs text-neutral-800">
|
v-model="branchForm.baseBranch"
|
||||||
|
:label="$t('gitea.branch.baseBranch')"
|
||||||
|
input-class="w-full"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="mb-[2px] rounded-md bg-primary-500 px-4 py-2 text-xs font-semibold text-white transition-colors hover:bg-secondary-500 disabled:opacity-50"
|
||||||
|
:disabled="isCreating"
|
||||||
|
@click="handleCreate"
|
||||||
|
>
|
||||||
|
{{ isCreating ? '...' : $t('gitea.branch.create') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<code class="mt-2 block rounded bg-neutral-50 px-2 py-1 text-[11px] text-neutral-500">
|
||||||
{{ branchPreview }}
|
{{ branchPreview }}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
</Transition>
|
||||||
<button
|
|
||||||
type="button"
|
<!-- Content area with scroll -->
|
||||||
class="rounded-md bg-primary-500 px-3 py-1.5 text-xs font-semibold text-white hover:bg-secondary-500 disabled:opacity-50"
|
<div class="max-h-64 overflow-y-auto overscroll-contain">
|
||||||
:disabled="isCreating"
|
<!-- Loading -->
|
||||||
@click="handleCreate"
|
<div v-if="(activeTab === 'branches' && isLoading) || (activeTab === 'prs' && isLoadingPrs)" class="flex items-center justify-center py-8">
|
||||||
>
|
<Icon name="mdi:loading" size="20" class="animate-spin text-neutral-300" />
|
||||||
{{ $t('gitea.branch.create') }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="rounded-md border border-neutral-300 px-3 py-1.5 text-xs font-semibold text-neutral-600 hover:bg-neutral-100"
|
|
||||||
@click="showCreateForm = false"
|
|
||||||
>
|
|
||||||
{{ $t('common.cancel') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Loading -->
|
<!-- BRANCHES TAB -->
|
||||||
<div v-if="isLoading" class="mt-3 text-xs text-neutral-400">{{ $t('common.loading') }}</div>
|
<template v-if="activeTab === 'branches' && !isLoading">
|
||||||
|
<div v-if="branches.length" class="divide-y divide-neutral-100">
|
||||||
<!-- Branches list -->
|
|
||||||
<div v-if="!isLoading && branches.length" class="mt-4 space-y-3">
|
|
||||||
<div v-for="branch in branches" :key="branch.name" class="rounded-md border border-neutral-200 bg-white p-3">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<Icon name="mdi:source-branch" size="16" class="text-primary-500" />
|
|
||||||
<a
|
|
||||||
:href="branchUrl(branch.name)"
|
|
||||||
target="_blank"
|
|
||||||
class="text-sm font-medium text-primary-500 hover:underline"
|
|
||||||
>
|
|
||||||
{{ branch.name }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Commits -->
|
|
||||||
<div v-if="branch.commits.length" class="ml-6 mt-2 space-y-1">
|
|
||||||
<p class="text-xs font-semibold text-neutral-500">{{ $t('gitea.branch.commits') }}</p>
|
|
||||||
<div
|
<div
|
||||||
v-for="commit in branch.commits.slice(0, 5)"
|
v-for="branch in branches"
|
||||||
:key="commit.sha"
|
:key="branch.name"
|
||||||
class="flex items-baseline gap-2 text-xs"
|
class="group"
|
||||||
>
|
>
|
||||||
<code class="text-primary-500">{{ commit.sha }}</code>
|
<!-- Branch header (clickable to expand) -->
|
||||||
<span class="truncate text-neutral-700">{{ commitFirstLine(commit.message) }}</span>
|
<button
|
||||||
<span class="whitespace-nowrap text-neutral-400">{{ commit.author }}</span>
|
type="button"
|
||||||
|
class="flex w-full items-center gap-2 px-4 py-2.5 text-left transition-colors hover:bg-white"
|
||||||
|
@click="toggleBranch(branch.name)"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name="mdi:chevron-right"
|
||||||
|
size="14"
|
||||||
|
class="shrink-0 text-neutral-400 transition-transform"
|
||||||
|
:class="{ 'rotate-90': expandedBranches.has(branch.name) }"
|
||||||
|
/>
|
||||||
|
<Icon name="mdi:source-branch" size="14" class="shrink-0 text-primary-500" />
|
||||||
|
<span class="min-w-0 truncate text-xs font-medium text-primary-600">
|
||||||
|
{{ branch.name }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-if="branch.commits.length"
|
||||||
|
class="ml-auto shrink-0 rounded bg-neutral-200/60 px-1.5 py-0.5 text-[10px] font-medium text-neutral-500"
|
||||||
|
>
|
||||||
|
{{ branch.commits.length }} commit{{ branch.commits.length > 1 ? 's' : '' }}
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
:href="branchUrl(branch.name)"
|
||||||
|
target="_blank"
|
||||||
|
class="shrink-0 text-neutral-400 opacity-0 transition-opacity hover:text-primary-500 group-hover:opacity-100"
|
||||||
|
@click.stop
|
||||||
|
>
|
||||||
|
<Icon name="mdi:open-in-new" size="12" />
|
||||||
|
</a>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Commits (collapsible) -->
|
||||||
|
<Transition name="expand">
|
||||||
|
<div v-if="expandedBranches.has(branch.name) && branch.commits.length" class="border-t border-neutral-100 bg-white">
|
||||||
|
<div
|
||||||
|
v-for="(commit, idx) in branch.commits.slice(0, 10)"
|
||||||
|
:key="commit.sha"
|
||||||
|
class="flex items-center gap-2 px-4 py-1.5"
|
||||||
|
:class="idx !== Math.min(branch.commits.length, 10) - 1 ? 'border-b border-neutral-50' : ''"
|
||||||
|
>
|
||||||
|
<span class="shrink-0 pl-5 font-mono text-[10px] text-primary-400">{{ commit.sha.slice(0, 7) }}</span>
|
||||||
|
<span class="min-w-0 truncate text-[11px] text-neutral-700">{{ commitFirstLine(commit.message) }}</span>
|
||||||
|
<span class="ml-auto shrink-0 text-[10px] text-neutral-400">{{ commit.author }}</span>
|
||||||
|
<span class="shrink-0 text-[10px] text-neutral-300">{{ formatDate(commit.date) }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="branch.commits.length > 10"
|
||||||
|
class="border-t border-neutral-50 px-4 py-1.5 text-center text-[10px] text-neutral-400"
|
||||||
|
>
|
||||||
|
+{{ branch.commits.length - 10 }} commits
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p v-if="!isLoading && !branches.length && !error" class="mt-3 text-xs text-neutral-400">
|
<p v-else-if="!error" class="py-6 text-center text-xs text-neutral-400">
|
||||||
{{ $t('gitea.branch.noBranches') }}
|
{{ $t('gitea.branch.noBranches') }}
|
||||||
</p>
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Pull Requests -->
|
<!-- PULL REQUESTS TAB -->
|
||||||
<div v-if="!isLoadingPrs && pullRequests.length" class="mt-4">
|
<template v-if="activeTab === 'prs' && !isLoadingPrs">
|
||||||
<h4 class="text-xs font-bold text-neutral-700">{{ $t('gitea.pr.title') }}</h4>
|
<div v-if="pullRequests.length" class="divide-y divide-neutral-100">
|
||||||
<div class="mt-2 space-y-2">
|
<div
|
||||||
<div v-for="pr in pullRequests" :key="pr.number" class="rounded-md border border-neutral-200 bg-white p-3">
|
v-for="pr in pullRequests"
|
||||||
<div class="flex items-center gap-2">
|
:key="pr.number"
|
||||||
|
class="group flex items-start gap-3 px-4 py-3 transition-colors hover:bg-white"
|
||||||
|
>
|
||||||
|
<!-- Status pill -->
|
||||||
<span
|
<span
|
||||||
class="rounded-full px-2 py-0.5 text-xs font-semibold text-white"
|
class="mt-0.5 shrink-0 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-white"
|
||||||
:class="prStatusClass(pr)"
|
:class="prStatusClass(pr)"
|
||||||
>
|
>
|
||||||
{{ prStatusLabel(pr) }}
|
{{ prStatusLabel(pr) }}
|
||||||
</span>
|
</span>
|
||||||
<a
|
|
||||||
:href="pr.url"
|
|
||||||
target="_blank"
|
|
||||||
class="text-sm font-medium text-primary-500 hover:underline"
|
|
||||||
>
|
|
||||||
#{{ pr.number }} {{ pr.title }}
|
|
||||||
</a>
|
|
||||||
<span class="text-xs text-neutral-400">{{ pr.author }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- CI statuses -->
|
<!-- PR content -->
|
||||||
<div v-if="pr.ciStatuses.length" class="ml-6 mt-2 flex flex-wrap gap-2">
|
<div class="min-w-0 flex-1">
|
||||||
<a
|
<a
|
||||||
v-for="ci in pr.ciStatuses"
|
:href="pr.url"
|
||||||
:key="ci.context"
|
target="_blank"
|
||||||
:href="ci.target_url"
|
class="text-xs font-medium text-neutral-800 hover:text-primary-500 hover:underline"
|
||||||
target="_blank"
|
>
|
||||||
class="flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium"
|
<span class="text-neutral-400">#{{ pr.number }}</span>
|
||||||
:class="ciStatusClass(ci.status)"
|
{{ pr.title }}
|
||||||
>
|
</a>
|
||||||
<Icon :name="ciStatusIcon(ci.status)" size="12" />
|
<div class="mt-1 flex items-center gap-2">
|
||||||
{{ ci.context }}
|
<span class="text-[10px] text-neutral-400">{{ pr.author }}</span>
|
||||||
</a>
|
<span v-if="pr.headBranch" class="rounded bg-neutral-100 px-1.5 py-0.5 font-mono text-[10px] text-neutral-500">
|
||||||
|
{{ pr.headBranch }}
|
||||||
|
</span>
|
||||||
|
<!-- CI statuses -->
|
||||||
|
<template v-if="pr.ciStatuses.length">
|
||||||
|
<a
|
||||||
|
v-for="ci in pr.ciStatuses"
|
||||||
|
:key="ci.context"
|
||||||
|
:href="ci.target_url"
|
||||||
|
target="_blank"
|
||||||
|
class="inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-[10px] font-medium transition-opacity hover:opacity-80"
|
||||||
|
:class="ciStatusClass(ci.status)"
|
||||||
|
>
|
||||||
|
<Icon :name="ciStatusIcon(ci.status)" size="10" />
|
||||||
|
{{ ci.context }}
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p v-if="!isLoadingPrs && !pullRequests.length && branches.length && !error" class="mt-3 text-xs text-neutral-400">
|
<p v-else-if="branches.length && !error" class="py-6 text-center text-xs text-neutral-400">
|
||||||
{{ $t('gitea.pr.noPrs') }}
|
{{ $t('gitea.pr.noPrs') }}
|
||||||
</p>
|
</p>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -158,6 +242,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const { listBranches, createBranch, listPullRequests, getBranchName } = useGiteaService()
|
const { listBranches, createBranch, listPullRequests, getBranchName } = useGiteaService()
|
||||||
|
|
||||||
|
const activeTab = ref<'branches' | 'prs'>('branches')
|
||||||
const branches = ref<GiteaBranch[]>([])
|
const branches = ref<GiteaBranch[]>([])
|
||||||
const pullRequests = ref<GiteaPullRequest[]>([])
|
const pullRequests = ref<GiteaPullRequest[]>([])
|
||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
@@ -165,6 +250,7 @@ const isLoadingPrs = ref(true)
|
|||||||
const isCreating = ref(false)
|
const isCreating = ref(false)
|
||||||
const error = ref(false)
|
const error = ref(false)
|
||||||
const showCreateForm = ref(false)
|
const showCreateForm = ref(false)
|
||||||
|
const expandedBranches = ref(new Set<string>())
|
||||||
|
|
||||||
const branchForm = reactive({
|
const branchForm = reactive({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
@@ -179,6 +265,8 @@ const typeOptions = [
|
|||||||
{ label: t('gitea.branch.types.chore'), value: 'chore' },
|
{ label: t('gitea.branch.types.chore'), value: 'chore' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const hasOpenPr = computed(() => pullRequests.value.some(pr => pr.state === 'open' && !pr.merged))
|
||||||
|
|
||||||
const branchPreview = computed(() => {
|
const branchPreview = computed(() => {
|
||||||
if (!props.task.project?.code || !props.task.number) return ''
|
if (!props.task.project?.code || !props.task.number) return ''
|
||||||
const slug = props.task.title
|
const slug = props.task.title
|
||||||
@@ -191,6 +279,14 @@ const branchPreview = computed(() => {
|
|||||||
return `${branchForm.type}/${props.task.project.code}-${props.task.number}-${slug}`
|
return `${branchForm.type}/${props.task.project.code}-${props.task.number}-${slug}`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function toggleBranch(name: string) {
|
||||||
|
if (expandedBranches.value.has(name)) {
|
||||||
|
expandedBranches.value.delete(name)
|
||||||
|
} else {
|
||||||
|
expandedBranches.value.add(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function branchUrl(name: string): string {
|
function branchUrl(name: string): string {
|
||||||
const project = props.task.project
|
const project = props.task.project
|
||||||
if (!project?.giteaOwner || !project?.giteaRepo) return '#'
|
if (!project?.giteaOwner || !project?.giteaRepo) return '#'
|
||||||
@@ -201,6 +297,18 @@ function commitFirstLine(message: string): string {
|
|||||||
return message.split('\n')[0]
|
return message.split('\n')[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatDate(dateStr: string): string {
|
||||||
|
const d = new Date(dateStr)
|
||||||
|
const now = new Date()
|
||||||
|
const diffMs = now.getTime() - d.getTime()
|
||||||
|
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))
|
||||||
|
|
||||||
|
if (diffDays === 0) return "aujourd'hui"
|
||||||
|
if (diffDays === 1) return 'hier'
|
||||||
|
if (diffDays < 7) return `il y a ${diffDays}j`
|
||||||
|
return d.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' })
|
||||||
|
}
|
||||||
|
|
||||||
function prStatusClass(pr: GiteaPullRequest): string {
|
function prStatusClass(pr: GiteaPullRequest): string {
|
||||||
if (pr.merged) return 'bg-purple-500'
|
if (pr.merged) return 'bg-purple-500'
|
||||||
if (pr.state === 'open') return 'bg-green-500'
|
if (pr.state === 'open') return 'bg-green-500'
|
||||||
@@ -234,6 +342,10 @@ async function loadData() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
branches.value = await listBranches(props.task.id)
|
branches.value = await listBranches(props.task.id)
|
||||||
|
// Auto-expand first branch
|
||||||
|
if (branches.value.length === 1) {
|
||||||
|
expandedBranches.value.add(branches.value[0].name)
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
error.value = true
|
error.value = true
|
||||||
} finally {
|
} finally {
|
||||||
@@ -278,3 +390,36 @@ onMounted(() => {
|
|||||||
loadData()
|
loadData()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.slide-down-enter-active {
|
||||||
|
transition: opacity 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-down-leave-active {
|
||||||
|
transition: opacity 0.1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-down-enter-from,
|
||||||
|
.slide-down-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-enter-active,
|
||||||
|
.expand-leave-active {
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-enter-from,
|
||||||
|
.expand-leave-to {
|
||||||
|
max-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-enter-to,
|
||||||
|
.expand-leave-from {
|
||||||
|
max-height: 500px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
<!-- Modal -->
|
<!-- Modal -->
|
||||||
<div
|
<div
|
||||||
class="relative z-10 w-full max-w-2xl overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-black/5"
|
class="relative z-10 flex w-full max-w-2xl flex-col overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-black/5"
|
||||||
|
style="max-height: min(90vh, 900px)"
|
||||||
>
|
>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="border-b border-neutral-100 bg-neutral-50/80 px-8 py-5">
|
<div class="border-b border-neutral-100 bg-neutral-50/80 px-8 py-5">
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<form @submit.prevent="handleSubmit" class="px-8 py-6">
|
<form @submit.prevent="handleSubmit" class="overflow-y-auto px-8 py-6">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<MalioInputText
|
<MalioInputText
|
||||||
v-model="form.title"
|
v-model="form.title"
|
||||||
|
|||||||
Reference in New Issue
Block a user