Skip to content

Commit 0c4cd27

Browse files
authored
enhancement: Shift + click to select multiples variables (#501)
1 parent ffa93ac commit 0c4cd27

File tree

4 files changed

+43
-18
lines changed

4 files changed

+43
-18
lines changed

apps/shelve/app/components/variable/Create.vue

-6
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ const { createLoading, createVariables } = useVariablesService()
99
1010
const route = useRoute()
1111
const projectId = route.params.projectId as string
12-
/*const project = useProject(projectId)
13-
14-
const { data: secrets, status, refresh, error } = await useFetch('/api/github/secrets', {
15-
method: 'GET',
16-
query: { repository: sanitizeGithubUrl(project.value?.repository) },
17-
})*/
1812
1913
const {
2014
variablesInput,

apps/shelve/app/components/variable/Item.vue

+6-2
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,19 @@ const variableToUpdate = computed(() => ({
3939
}))
4040
4141
const showEdit = ref(false)
42+
43+
const handleClick = (event: MouseEvent) => {
44+
emit('toggleSelected', event)
45+
}
4246
</script>
4347

4448
<template>
4549
<UCard variant="subtle" :ui="{ root: isSelected && !showEdit ? 'bg-(--ui-bg-accented)/60' : '' }">
46-
<div class="flex w-full items-start justify-between">
50+
<div class="flex w-full select-none items-start justify-between">
4751
<div
4852
class="flex w-full flex-col gap-1"
4953
:class="{ 'cursor-pointer': !showEdit }"
50-
@click="showEdit ? null : emit('toggleSelected')"
54+
@click="showEdit ? null : handleClick($event)"
5155
>
5256
<h3 class="flex items-center gap-1 text-sm font-semibold sm:text-base">
5357
<span class="lg:hidden">

apps/shelve/app/components/variable/Selector.vue

+14-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@
22
import type { Variable } from '@types'
33
import { ConfirmModal } from '#components'
44
5+
const props = defineProps<{
6+
variables: Variable[]
7+
}>()
8+
59
const selectedVariables = defineModel<Variable[]>({ required: true })
610
711
const { deleteVariables } = useVariablesService()
812
913
const loading = ref(false)
1014
const modal = useModal()
11-
const route = useRoute()
1215
const teamEnv = useEnvironments()
1316
17+
function selectAllVisible() {
18+
selectedVariables.value = [...props.variables]
19+
}
20+
1421
async function deleteSelectedVariables() {
1522
loading.value = true
1623
const ids = selectedVariables.value.map((v: Variable) => v.id)
@@ -57,12 +64,16 @@ function openDeleteModal() {
5764
</UCard>
5865
</template>
5966
</UPopover>
60-
<UTooltip text="Delete selected variables">
61-
<UButton color="error" variant="ghost" icon="heroicons:trash" :loading @click="openDeleteModal" />
67+
<UTooltip text="Select all visible variables">
68+
<UButton variant="ghost" icon="lucide:text-select" @click="selectAllVisible" />
6269
</UTooltip>
6370
<UTooltip text="Clear selection">
6471
<UButton variant="ghost" icon="lucide:x" @click="selectedVariables = []" />
6572
</UTooltip>
73+
<USeparator orientation="vertical" class="h-auto" />
74+
<UTooltip text="Delete selected variables">
75+
<UButton color="error" variant="ghost" icon="heroicons:trash" :loading @click="openDeleteModal" />
76+
</UTooltip>
6677
</div>
6778
</div>
6879
</div>

apps/shelve/app/pages/[teamSlug]/projects/[projectId]/index/variables.vue

+23-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { TeamRole, type Variable } from '@types'
2+
import type { Variable } from '@types'
33
44
const route = useRoute()
55
const projectId = route.params.projectId as string
@@ -10,6 +10,7 @@ const { loading, fetchVariables } = useVariablesService()
1010
if (!variables.value) fetchVariables()
1111
1212
const selectedVariables = ref<Variable[]>([])
13+
const lastSelectedIndex = ref<number | null>(null)
1314
const searchTerm = ref('')
1415
const selectedEnvironment = ref([])
1516
const order = ref('desc')
@@ -50,11 +51,25 @@ const filteredVariables = computed(() => {
5051
return filtered
5152
})
5253
53-
const toggleVariable = (variable: Variable) => {
54-
if (!isVariableSelected(variable)) {
55-
selectedVariables.value.push(variable)
54+
const toggleVariable = (variable: Variable, event?: MouseEvent) => {
55+
const filteredIndex = filteredVariables.value.findIndex(v => v.id === variable.id)
56+
57+
if (event?.shiftKey && lastSelectedIndex.value !== null) {
58+
const startIndex = Math.min(lastSelectedIndex.value, filteredIndex)
59+
const endIndex = Math.max(lastSelectedIndex.value, filteredIndex)
60+
const newSelection = filteredVariables.value.slice(startIndex, endIndex + 1)
61+
selectedVariables.value = Array.from(
62+
new Map(
63+
[...selectedVariables.value, ...newSelection].map(item => [item.id, item])
64+
).values()
65+
)
5666
} else {
57-
selectedVariables.value = selectedVariables.value.filter((v) => v.id !== variable.id)
67+
if (!isVariableSelected(variable)) {
68+
selectedVariables.value.push(variable)
69+
} else {
70+
selectedVariables.value = selectedVariables.value.filter((v) => v.id !== variable.id)
71+
}
72+
lastSelectedIndex.value = filteredIndex
5873
}
5974
}
6075
@@ -70,6 +85,7 @@ const isVariableSelected = (variable: Variable) => {
7085
<UInput
7186
v-model="searchTerm"
7287
placeholder="Search variables..."
88+
icon="lucide:search"
7389
class="w-1/3"
7490
/>
7591
<div class="flex gap-1">
@@ -84,14 +100,14 @@ const isVariableSelected = (variable: Variable) => {
84100
<USelectMenu v-model="selectedEnvironment" multiple :items class="w-full" placeholder="Select environment" />
85101
</div>
86102
</div>
87-
<LazyVariableSelector v-model="selectedVariables" />
103+
<LazyVariableSelector v-model="selectedVariables" :variables="filteredVariables" />
88104
<div v-if="!loading" class="flex flex-col gap-4">
89105
<div v-for="variable in filteredVariables" :key="variable.id">
90106
<VariableItem
91107
:variable
92108
:environments
93109
:is-selected="isVariableSelected(variable)"
94-
@toggle-selected="toggleVariable(variable)"
110+
@toggle-selected="(e) => toggleVariable(variable, e)"
95111
/>
96112
</div>
97113
</div>

0 commit comments

Comments
 (0)