refactor(frontend): split documents and review into workspace components
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
<script setup lang="ts">
|
||||
type ChangeItem = {
|
||||
id: string;
|
||||
title: string;
|
||||
entity: string;
|
||||
action: string;
|
||||
rolledBack?: boolean;
|
||||
};
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
activeChangeStepNumber: number;
|
||||
activeChangeItems: ChangeItem[];
|
||||
activeChangeItem: ChangeItem | null;
|
||||
activeChangeApproved: boolean;
|
||||
activeChangeIndex: number;
|
||||
selectedRollbackCount: number;
|
||||
changeActionBusy: boolean;
|
||||
describeChangeEntity: (entity: string) => string;
|
||||
describeChangeAction: (action: string) => string;
|
||||
isReviewItemApproved: (item: ChangeItem | null | undefined) => boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "close"): void;
|
||||
(e: "active-approval-change", event: Event): void;
|
||||
(e: "item-approval-change", payload: { itemId: string; event: Event }): void;
|
||||
(e: "open-item-target", item: ChangeItem): void;
|
||||
(e: "prev-step"): void;
|
||||
(e: "next-step"): void;
|
||||
(e: "approve-all"): void;
|
||||
(e: "mark-all-rollback"): void;
|
||||
(e: "rollback-selected"): void;
|
||||
(e: "done"): void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="props.visible"
|
||||
class="pointer-events-none fixed inset-x-2 bottom-2 z-40 md:inset-auto md:right-4 md:bottom-4 md:w-[390px]"
|
||||
>
|
||||
<section class="pointer-events-auto rounded-2xl border border-base-300 bg-base-100/95 p-3 shadow-2xl backdrop-blur">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="min-w-0">
|
||||
<p class="text-[11px] font-semibold uppercase tracking-wide text-base-content/60">
|
||||
Review {{ props.activeChangeStepNumber }}/{{ props.activeChangeItems.length }}
|
||||
</p>
|
||||
<p class="truncate text-sm font-semibold text-base-content">
|
||||
{{ props.activeChangeItem?.title || "Change step" }}
|
||||
</p>
|
||||
</div>
|
||||
<button class="btn btn-ghost btn-xs" @click="emit('close')">Close</button>
|
||||
</div>
|
||||
|
||||
<div v-if="props.activeChangeItem" class="mt-2 rounded-xl border border-base-300 bg-base-200/35 p-2">
|
||||
<p class="text-xs text-base-content/80">
|
||||
{{ props.describeChangeEntity(props.activeChangeItem.entity) }}
|
||||
{{ props.describeChangeAction(props.activeChangeItem.action) }}
|
||||
</p>
|
||||
<label class="mt-1 inline-flex items-center gap-2 text-xs">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-xs"
|
||||
:checked="props.activeChangeApproved"
|
||||
:disabled="props.activeChangeItem.rolledBack"
|
||||
@change="emit('active-approval-change', $event)"
|
||||
>
|
||||
<span>{{ props.activeChangeItem.rolledBack ? "Already rolled back" : "Approve this step" }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mt-2 max-h-40 space-y-1 overflow-y-auto pr-1">
|
||||
<div
|
||||
v-for="(item, index) in props.activeChangeItems"
|
||||
:key="`review-step-${item.id}`"
|
||||
class="flex items-center gap-2 rounded-lg border px-2 py-1"
|
||||
:class="index === props.activeChangeIndex ? 'border-primary/45 bg-primary/10' : 'border-base-300 bg-base-100'"
|
||||
>
|
||||
<button
|
||||
class="min-w-0 flex-1 text-left"
|
||||
@click="emit('open-item-target', item)"
|
||||
>
|
||||
<p class="truncate text-xs font-medium text-base-content">
|
||||
{{ index + 1 }}. {{ item.title }}
|
||||
</p>
|
||||
<p class="truncate text-[11px] text-base-content/65">
|
||||
{{ props.describeChangeEntity(item.entity) }}
|
||||
</p>
|
||||
</button>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-xs"
|
||||
:checked="props.isReviewItemApproved(item)"
|
||||
:disabled="item.rolledBack"
|
||||
@change="emit('item-approval-change', { itemId: item.id, event: $event })"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 flex items-center justify-between gap-2">
|
||||
<div class="join">
|
||||
<button
|
||||
class="btn btn-xs join-item"
|
||||
:disabled="props.activeChangeIndex <= 0"
|
||||
@click="emit('prev-step')"
|
||||
>
|
||||
Prev
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-xs join-item"
|
||||
:disabled="props.activeChangeIndex >= props.activeChangeItems.length - 1"
|
||||
@click="emit('next-step')"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-[11px] text-base-content/70">
|
||||
Rollback marked: {{ props.selectedRollbackCount }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
<button class="btn btn-xs btn-outline" @click="emit('approve-all')">Approve all</button>
|
||||
<button class="btn btn-xs btn-outline" @click="emit('mark-all-rollback')">Mark all rollback</button>
|
||||
<button
|
||||
class="btn btn-xs btn-warning"
|
||||
:disabled="props.changeActionBusy || props.selectedRollbackCount === 0"
|
||||
@click="emit('rollback-selected')"
|
||||
>
|
||||
{{ props.changeActionBusy ? "Applying..." : "Rollback selected" }}
|
||||
</button>
|
||||
<button class="btn btn-xs btn-primary ml-auto" @click="emit('done')">Done</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user