mirror of https://github.com/halo-dev/halo
				
				
				
			
		
			
				
	
	
		
			139 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Vue
		
	
	
| <script setup lang="ts">
 | |
| import type { ListedSnapshotDto, Post } from "@halo-dev/api-client";
 | |
| import { consoleApiClient } from "@halo-dev/api-client";
 | |
| import { Dialog, Toast, VButton, VStatusDot, VTag } from "@halo-dev/components";
 | |
| import { useQueryClient } from "@tanstack/vue-query";
 | |
| import { computed } from "vue";
 | |
| import { relativeTimeTo } from "@/utils/date";
 | |
| import { useI18n } from "vue-i18n";
 | |
| 
 | |
| const { t } = useI18n();
 | |
| const queryClient = useQueryClient();
 | |
| 
 | |
| const props = withDefaults(
 | |
|   defineProps<{
 | |
|     post?: Post;
 | |
|     snapshot: ListedSnapshotDto;
 | |
|     selectedSnapshotName?: string;
 | |
|   }>(),
 | |
|   {
 | |
|     post: undefined,
 | |
|     selectedSnapshotName: undefined,
 | |
|   }
 | |
| );
 | |
| 
 | |
| async function handleRestore() {
 | |
|   Dialog.warning({
 | |
|     title: t("core.post_snapshots.operations.revert.title"),
 | |
|     description: t("core.post_snapshots.operations.revert.description"),
 | |
|     confirmText: t("core.common.buttons.confirm"),
 | |
|     cancelText: t("core.common.buttons.cancel"),
 | |
|     async onConfirm() {
 | |
|       await consoleApiClient.content.post.revertToSpecifiedSnapshotForPost({
 | |
|         name: props.post?.metadata.name as string,
 | |
|         revertSnapshotForPostParam: {
 | |
|           snapshotName: props.snapshot.metadata.name,
 | |
|         },
 | |
|       });
 | |
|       await queryClient.invalidateQueries({
 | |
|         queryKey: ["post-snapshots-by-post-name"],
 | |
|       });
 | |
|       Toast.success(t("core.post_snapshots.operations.revert.toast_success"));
 | |
|     },
 | |
|   });
 | |
| }
 | |
| 
 | |
| function handleDelete() {
 | |
|   Dialog.warning({
 | |
|     title: t("core.post_snapshots.operations.delete.title"),
 | |
|     description: t("core.post_snapshots.operations.delete.description"),
 | |
|     confirmText: t("core.common.buttons.confirm"),
 | |
|     cancelText: t("core.common.buttons.cancel"),
 | |
|     async onConfirm() {
 | |
|       await consoleApiClient.content.post.deletePostContent({
 | |
|         name: props.post?.metadata.name as string,
 | |
|         snapshotName: props.snapshot.metadata.name,
 | |
|       });
 | |
|       await queryClient.invalidateQueries({
 | |
|         queryKey: ["post-snapshots-by-post-name"],
 | |
|       });
 | |
|       Toast.success(t("core.common.toast.delete_success"));
 | |
|     },
 | |
|   });
 | |
| }
 | |
| 
 | |
| const isSelected = computed(() => {
 | |
|   return props.selectedSnapshotName === props.snapshot.metadata.name;
 | |
| });
 | |
| 
 | |
| const isReleased = computed(() => {
 | |
|   return props.post?.spec.releaseSnapshot === props.snapshot.metadata.name;
 | |
| });
 | |
| 
 | |
| const isHead = computed(() => {
 | |
|   const { headSnapshot, releaseSnapshot } = props.post?.spec || {};
 | |
|   return (
 | |
|     headSnapshot !== releaseSnapshot &&
 | |
|     headSnapshot === props.snapshot.metadata.name
 | |
|   );
 | |
| });
 | |
| 
 | |
| const isBase = computed(() => {
 | |
|   return props.post?.spec.baseSnapshot === props.snapshot.metadata.name;
 | |
| });
 | |
| </script>
 | |
| <template>
 | |
|   <div
 | |
|     class="group relative flex cursor-pointer flex-col gap-5 p-4"
 | |
|     :class="{ 'bg-gray-50': isSelected }"
 | |
|   >
 | |
|     <div
 | |
|       v-if="isSelected"
 | |
|       class="absolute inset-y-0 left-0 w-0.5 bg-primary"
 | |
|     ></div>
 | |
|     <div class="flex items-center justify-between">
 | |
|       <div
 | |
|         class="truncate text-sm"
 | |
|         :class="{
 | |
|           'font-semibold': isSelected,
 | |
|         }"
 | |
|       >
 | |
|         {{ relativeTimeTo(snapshot.metadata.creationTimestamp) }}
 | |
|       </div>
 | |
|       <div class="inline-flex flex-none items-center space-x-3">
 | |
|         <VTag v-if="isReleased" theme="primary">
 | |
|           {{ $t("core.post_snapshots.status.released") }}
 | |
|         </VTag>
 | |
|         <VTag v-if="isHead">
 | |
|           {{ $t("core.post_snapshots.status.draft") }}
 | |
|         </VTag>
 | |
|         <VTag v-if="isBase">
 | |
|           {{ $t("core.post_snapshots.status.base") }}
 | |
|         </VTag>
 | |
|         <VStatusDot
 | |
|           v-if="snapshot.metadata.deletionTimestamp"
 | |
|           v-tooltip="$t('core.common.status.deleting')"
 | |
|           state="warning"
 | |
|           animate
 | |
|         />
 | |
|       </div>
 | |
|     </div>
 | |
|     <div class="flex h-6 items-end justify-between gap-2">
 | |
|       <div class="flex-1 truncate text-xs text-gray-600">
 | |
|         {{ snapshot.spec.owner }}
 | |
|       </div>
 | |
|       <div
 | |
|         v-if="!isReleased"
 | |
|         class="hidden flex-none space-x-2 group-hover:block"
 | |
|       >
 | |
|         <VButton v-if="!isHead" size="xs" @click="handleRestore()">
 | |
|           {{ $t("core.post_snapshots.operations.revert.button") }}
 | |
|         </VButton>
 | |
|         <VButton v-if="!isBase" size="xs" type="danger" @click="handleDelete">
 | |
|           {{ $t("core.common.buttons.delete") }}
 | |
|         </VButton>
 | |
|       </div>
 | |
|     </div>
 | |
|   </div>
 | |
| </template>
 |