Skip to content

Commit

Permalink
Feature Add: Bulk destroy snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
JordanKeo45 committed May 17, 2024
1 parent f5eb0ec commit 616affd
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 42 deletions.
2 changes: 1 addition & 1 deletion zfs/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "zfs",
"name": "cockpit-zfs",
"private": true,
"version": "0.0.0",
"description": "Redesigned ZFS Manager for Cockpit",
Expand Down
26 changes: 16 additions & 10 deletions zfs/src/components/common/UniversalConfirmation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
</template>
<template v-slot:content>
<div class="grid grid-flow-row mt-3 text-center">
<p v-if="!operation2" class="text-default row-start-1" :class="truncateText" :title="props[props.item].name">Are you sure you wish to {{props.operation}} <b :class="truncateText" :title="props[props.item].name">{{ props[props.item].name }}</b>?</p>
<p v-if="operation2" class="text-default row-start-1" :class="truncateText" :title="props[props.item].name">Are you sure you wish to {{props.operation}} {{props.operation2!}} on <b :class="truncateText" :title="props[props.item].name">{{ props[props.item].name }}</b>?</p>

<p v-if="!operation2 && props.item !== 'snapshots'" class="text-default row-start-1" :class="truncateText" :title="props[props.item].name">Are you sure you wish to {{props.operation}} <b :class="truncateText" :title="props[props.item].name">{{ props[props.item].name }}</b>?</p>
<p v-if="operation2 && props.item !== 'snapshots'" class="text-default row-start-1" :class="truncateText" :title="props[props.item].name">Are you sure you wish to {{props.operation}} {{props.operation2!}} on <b :class="truncateText" :title="props[props.item].name">{{ props[props.item].name }}</b>?</p>

<p v-if="props.item == 'snapshots'" class="text-default row-start-1">Are you sure you wish to destroy these snapshots?</p>
<div v-if="props.item == 'snapshots'" class="text-default text-left items-center divide-y divide-default row-start-2 p-2 bg-accent">
<p v-for="snapshot, idx in props.snapshots" :key="idx">{{ snapshot }}</p>
</div>
<div v-if="props.operation == 'destroy' && props.hasChildren!">
<div v-if="props.item == 'filesystem'" class="w-full">
<div class="font-medium text-sm grid grid-flow-row justify-items-center justify-center">
Expand Down Expand Up @@ -123,7 +127,7 @@
<div class="button-group-row justify-between">
<button @click="closeModal" :id="getIdKey('confirm-no')" name="button-no" class="mt-1 btn btn-secondary object-left justify-start h-fit">Cancel</button>

<!-- computed property to determine which buttons to render? -->
<!-- add a computed property to determine which buttons to render? -->
<button v-if="props.item == 'filesystem' && !operationRunning && !hasChildren" @click="confirmOperation" :id="getIdKey('confirm-yes-A1')" name="button-yes-A" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item == 'filesystem' && !operationRunning && hasChildren && !hasChildrenButtonRender" disabled @click="confirmOperation" :id="getIdKey('confirm-yes-C1')" name="button-yes-C" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item == 'filesystem' && !operationRunning && hasChildren && hasChildrenButtonRender" @click="confirmOperation" :id="getIdKey('confirm-yes-B1')" name="button-yes-B" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
Expand All @@ -132,10 +136,12 @@
<button v-if="props.item == 'snapshot' && !operationRunning && hasChildren && option2Toggle" @click="confirmOperation" :id="getIdKey('confirm-yes-B2')" name="button-yes-B" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item == 'snapshot' && !operationRunning && !hasChildren" @click="confirmOperation" :id="getIdKey('confirm-yes-B2')" name="button-yes-B" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>

<button v-if="props.item != 'snapshot' && props.item != 'filesystem' && !operationRunning && !hasChildren && !option1" @click="confirmOperation" :id="getIdKey('confirm-yes-A3')" name="button-yes-A" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item != 'snapshot' && props.item != 'filesystem' && !operationRunning && hasChildren && !option1" disabled @click="confirmOperation" :id="getIdKey('confirm-yes-C3')" name="button-yes-C" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item != 'snapshot' && props.item != 'filesystem' && !operationRunning && option1" @click="confirmOperation" :id="getIdKey('confirm-yes-B3')" name="button-yes-B" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>

<button v-if="props.item != 'snapshot' && props.item != 'snapshots' && props.item != 'filesystem' && !operationRunning && !hasChildren && !option1" @click="confirmOperation" :id="getIdKey('confirm-yes-A3')" name="button-yes-A" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item != 'snapshot' && props.item != 'snapshots' && props.item != 'filesystem' && !operationRunning && hasChildren && !option1" disabled @click="confirmOperation" :id="getIdKey('confirm-yes-C3')" name="button-yes-C" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>
<button v-if="props.item != 'snapshot' && props.item != 'snapshots' && props.item != 'filesystem' && !operationRunning && option1" @click="confirmOperation" :id="getIdKey('confirm-yes-B3')" name="button-yes-B" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>

<button v-if="props.item == 'snapshots' && !operationRunning" @click="confirmOperation" :id="getIdKey('confirm-yes-B3')" name="button-yes-B3" class="mt-1 btn btn-danger object-right justify-end h-fit">{{upperCaseWord(props.operation)}}</button>

<button disabled v-if="operationRunning" :id="getIdKey('confirm-spinner')" type="button" class="btn btn-danger object-right justify-end h-fit">
<svg aria-hidden="true" role="status" class="inline w-4 h-4 mr-3 text-gray-200 animate-spin text-default" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
Expand All @@ -155,6 +161,7 @@ import { upperCaseWord } from '../../composables/helpers';
import Modal from './Modal.vue';

interface UniversalConfirmationProps {
showFlag: boolean;
idKey: string;
item: string;
operation: string;
Expand All @@ -165,11 +172,10 @@ interface UniversalConfirmationProps {
disk?: DiskData;
filesystem?: FileSystemData;
snapshot?: Snapshot;
snapshots?: string[];
firstOption?: string;
secondOption?: string;
hasChildren: boolean;

showFlag: boolean;
}

const props = defineProps<UniversalConfirmationProps>();
Expand Down
25 changes: 21 additions & 4 deletions zfs/src/components/file-systems/FileSystemList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<div class="relative py-1 mt-1 p-3 text-right font-medium sm:pr-6 lg:pr-8">
<Menu as="div" class="relative inline-block text-right -mt-1">
<div>
<MenuButton class="flex items-center rounded-full bg-default p-2 text-default hover:text-default focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 focus:ring-offset-gray-100">
<MenuButton @click.stop class="flex items-center rounded-full bg-default p-2 text-default hover:text-default focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 focus:ring-offset-gray-100">
<span class="sr-only">Open options</span>
<EllipsisVerticalIcon class="w-5" aria-hidden="true" />
</MenuButton>
Expand Down Expand Up @@ -122,18 +122,25 @@
</MenuItem>
<MenuItem as="div" v-if="!findPoolDataset(allDatasets[datasetIdx])" v-slot="{ active }">
<a href="#" @click="deleteFileSystem(allDatasets[datasetIdx])" :class="[active ? 'bg-danger text-default' : 'text-muted', 'block px-4 py-2 text-sm']">Destroy File System</a>
</MenuItem>
</MenuItem>

<MenuItem as="div" v-slot="{ active }">
<a href="#" @click="enterBulkSnapDestroyMode(allDatasets[datasetIdx])" :class="[active ? 'bg-danger text-default' : 'text-muted', 'block px-4 py-2 text-sm']">Destroy Multiple Snapshots</a>
</MenuItem>

</div>
</MenuItems>
</transition>
</Menu>
</div>
</DisclosureButton>

<DisclosurePanel>
<div>
<SnapshotsList :filesystem="allDatasets[datasetIdx]" :item="'filesystem'"/>
<SnapshotsList :filesystem="allDatasets[datasetIdx]" :item="'filesystem'" :bulkSnapDestroyMode="bulkSnapDestroyMode.get(allDatasets[datasetIdx].name)"/>
</div>
</DisclosurePanel>

</Disclosure>
</div>
<div v-if="dataset.type == 'SNAPSHOT'" class="border border-default">
Expand Down Expand Up @@ -241,7 +248,7 @@
</template>

<script setup lang="ts">
import { ref, inject, Ref, provide, watch, onMounted, computed } from "vue";
import { ref, inject, Ref, provide, watch, onMounted, computed, reactive } from "vue";
import { EllipsisVerticalIcon, ArrowPathIcon, ChevronUpIcon, LockClosedIcon, LockOpenIcon, NoSymbolIcon, CheckIcon, } from '@heroicons/vue/24/outline';
import { CameraIcon } from '@heroicons/vue/24/solid'
import { Menu, MenuButton, MenuItem, MenuItems, Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue';
Expand Down Expand Up @@ -807,6 +814,16 @@ watch(confirmCloneSnap, async (newVal, oldVal) => {
}
});
///////////// Destroy Snaps in Bulk /////////////////
/////////////////////////////////////////////////////
const bulkSnapDestroyMode = reactive(new Map<string, boolean>());
function enterBulkSnapDestroyMode(dataset) {
bulkSnapDestroyMode.set(dataset.name, true);
console.log('Bulk Snap Destroy Mode Enabled for:', dataset.name);
}
provide('bulk-destroy-snaps', bulkSnapDestroyMode);
provide('confirm-clone-snap', confirmCloneSnap);
provide('confirm-send-snap', confirmSendSnap);
provide('all-datasets', allDatasets);
Expand Down
2 changes: 1 addition & 1 deletion zfs/src/components/pools/PoolListElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<div class="relative py-1 mt-1 p-3 text-right font-medium sm:pr-6 lg:pr-8">
<Menu as="div" class="relative inline-block text-right -mt-1">
<div>
<MenuButton class="flex items-center rounded-full bg-default p-2 hover:text-default focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 focus:ring-offset-gray-100">
<MenuButton @click.stop class="flex items-center rounded-full bg-default p-2 hover:text-default focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 focus:ring-offset-gray-100">
<span class="sr-only">Open options</span>
<EllipsisVerticalIcon class="w-5" aria-hidden="true" />
</MenuButton>
Expand Down
2 changes: 1 addition & 1 deletion zfs/src/components/pools/VDevElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<div class="col-span-1 relative p-1 pl-3 pr-4 text-right font-medium sm:pr-6 lg:pr-8 justify-self-end justify-items-end">
<Menu as="div" class="relative inline-block text-right">
<div>
<MenuButton class="flex items-center rounded-full bg-primary p-2 hover:text-white focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 focus:ring-offset-gray-100">
<MenuButton @click.stop class="flex items-center rounded-full bg-primary p-2 hover:text-white focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 focus:ring-offset-gray-100">
<span class="sr-only">Open options</span>
<EllipsisVerticalIcon class="w-5" aria-hidden="true" />
</MenuButton>
Expand Down
Loading

0 comments on commit 616affd

Please sign in to comment.