-
Notifications
You must be signed in to change notification settings - Fork 386
/
SelectBucketsStep.vue
135 lines (120 loc) · 4.36 KB
/
SelectBucketsStep.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (C) 2024 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<v-form class="pa-7" @submit.prevent>
<v-row>
<v-col>
<p class="font-weight-bold mb-2">Select Buckets</p>
<p>Choose buckets you want this application to access.</p>
<v-chip-group
v-model="option"
filter
mandatory
selected-class="text-primary font-weight-bold"
class="mt-2 mb-3"
@update:modelValue="onChangeOption"
>
<v-chip
variant="outlined"
filter
color="default"
:value="BucketsOption.All"
>
All Buckets
</v-chip>
<v-chip
variant="outlined"
filter
color="info"
:value="BucketsOption.Select"
>
Select Buckets
</v-chip>
</v-chip-group>
<v-alert v-if="option === BucketsOption.All" variant="tonal" color="default">
<p class="text-subtitle-2 font-weight-bold">All Buckets</p>
<p class="text-subtitle-2">The application can access all of the current and future buckets you create in this project.</p>
</v-alert>
<v-alert v-else variant="tonal" color="info">
<p class="text-subtitle-2 font-weight-bold">Select specific buckets</p>
<p class="text-subtitle-2">Please select which buckets do you want to share.</p>
<v-autocomplete
v-model="buckets"
v-model:search="bucketSearch"
:items="allBucketNames"
class="mt-3"
variant="outlined"
color="default"
label="Select Buckets"
no-data-text="No buckets found."
multiple
chips
closable-chips
:rules="bucketsRules"
:custom-filter="bucketFilter"
>
<template #item="{ props: slotProps }">
<v-list-item v-bind="slotProps" density="compact">
<template #prepend="{ isSelected }">
<v-checkbox-btn :model-value="isSelected" />
</template>
</v-list-item>
</template>
</v-autocomplete>
</v-alert>
</v-col>
</v-row>
</v-form>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import {
VAlert,
VAutocomplete,
VCheckboxBtn,
VChip,
VChipGroup,
VCol,
VForm,
VListItem,
VRow,
} from 'vuetify/components';
import { BucketsOption } from '@/types/createAccessGrant';
import { ValidationRule } from '@/types/common';
import { useBucketsStore } from '@/store/modules/bucketsStore';
const bucketsStore = useBucketsStore();
const emit = defineEmits<{
'bucketsChanged': [buckets: string[]];
}>();
const option = ref<BucketsOption>(BucketsOption.All);
const buckets = ref<string[]>([]);
const bucketSearch = ref<string>('');
const bucketsRules: ValidationRule<string[]>[] = [ v => !!v.length || 'Required' ];
/**
* Returns all bucket names from the store.
*/
const allBucketNames = computed<string[]>(() => bucketsStore.state.allBucketNames);
/**
* Returns whether the bucket name satisfies the query.
*/
function bucketFilter(bucketName: string, query: string): boolean {
query = query.trim();
if (!query) return true;
let lastIdx = 0;
for (const part of query.split(' ')) {
const idx = bucketName.indexOf(part, lastIdx);
if (idx === -1) return false;
lastIdx = idx + part.length;
}
return true;
}
/**
* Clears selected buckets.
*/
function onChangeOption(): void {
buckets.value = [];
}
watch(buckets, value => {
emit('bucketsChanged', value.slice());
}, { deep: true });
</script>