Skip to content

Commit

Permalink
web/satellite: finalize logic for new setup app flow
Browse files Browse the repository at this point in the history
Added logic to combine all the flow steps.
Added logic to generate S3 credentials based on choosen caveats.

Issue:
#6829

Change-Id: I9321e4c0a54d59855f41cb75e497133cdd30bf5e
  • Loading branch information
VitaliiShpital authored and Storj Robot committed Mar 25, 2024
1 parent 8f7aac9 commit 2ebd0b4
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 120 deletions.
290 changes: 237 additions & 53 deletions web/satellite/src/components/dialogs/AppSetupDialog.vue

Large diffs are not rendered by default.

Expand Up @@ -14,33 +14,42 @@
flat
density="comfortable"
label="Access Key"
model-value="jx5n3ocoloor4ei2qh6jsqstjuqa"
read-only
:model-value="credentials.accessKeyId"
readonly
hide-details
append-inner-icon="mdi-content-copy"
/>
>
<template #append-inner>
<input-copy-button :value="credentials.accessKeyId" />
</template>
</v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
flat
density="comfortable"
label="Secret Key"
model-value="j3qlp56mr2oqnu57cx54er7lhfzxkdojmoayoeroqzvb56ihqh246"
read-only
:model-value="credentials.secretKey"
readonly
hide-details
append-inner-icon="mdi-content-copy"
/>
>
<template #append-inner>
<input-copy-button :value="credentials.secretKey" />
</template>
</v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
flat
density="comfortable"
label="Endpoint"
model-value="https://apps.storj.io"
read-only
:model-value="credentials.endpoint"
readonly
hide-details
append-inner-icon="mdi-content-copy"
/>
>
<template #append-inner>
<input-copy-button :value="credentials.endpoint" />
</template>
</v-text-field>
</v-col>

<v-col>
Expand All @@ -55,4 +64,12 @@

<script setup lang="ts">
import { VForm, VAlert, VCol, VRow, VTextField } from 'vuetify/components';
import { EdgeCredentials } from '@/types/accessGrants';
import InputCopyButton from '@/components/InputCopyButton.vue';
defineProps<{
credentials: EdgeCredentials
}>();
</script>
Expand Up @@ -2,7 +2,7 @@
// See LICENSE for copying information.

<template>
<v-form ref="form" class="pa-7" @submit.prevent>
<v-form class="pa-7" @submit.prevent>
<v-row>
<v-col>
<p>Setup access to third-party applications.</p>
Expand All @@ -13,7 +13,7 @@
color="primary"
mandatory
column
@update:model-value="val => emit('setFlowType', val)"
@update:modelValue="val => emit('setFlowType', val)"
>
<v-chip
:key="FlowType.Default"
Expand Down Expand Up @@ -62,13 +62,11 @@ const emit = defineEmits<{
'setFlowType': [flowType: FlowType]
}>();
const form = ref<VForm>();
const flowType = ref<FlowType>(FlowType.Default);
defineExpose<IDialogFlowStep>({
validate: () => {
form.value?.validate();
return !!form.value?.isValid;
onExit: () => {
emit('setFlowType', flowType.value);
},
});
</script>
Expand Up @@ -2,64 +2,66 @@
// See LICENSE for copying information.

<template>
<v-form class="pa-7">
<v-form class="pa-7" @submit.prevent>
<v-row>
<v-col cols="12">
<p class="font-weight-bold mb-2">
Choose Permissions
</p>
<p>Select which permissions to give this application.</p>
<v-btn
:color="permissions.length === 4 ? 'success' : 'default'"
density="comfortable"
variant="outlined"
size="default"
:prepend-icon="permissions.length === 4 ? mdiCheckCircle : undefined"
class="mt-2"
@click="onAllClick"
>
All
</v-btn>
<v-chip-group
v-model="permissions"
filter
multiple
selected-class="text-primary font-weight-bold"
class="mt-2 mb-3"
>
<v-chip
key="all"
variant="outlined"
filter
value="all"
color="default"
>
All
</v-chip>

<v-chip
key="read"
:key="Permission.Read"
variant="outlined"
filter
value="read"
:value="Permission.Read"
color="secondary"
>
Read
</v-chip>

<v-chip
key="write"
:key="Permission.Write"
variant="outlined"
filter
value="write"
:value="Permission.Write"
color="green"
>
Write
</v-chip>

<v-chip
key="list"
:key="Permission.List"
variant="outlined"
filter
value="list"
:value="Permission.List"
color="help"
>
List
</v-chip>

<v-chip
key="delete"
:key="Permission.Delete"
variant="outlined"
filter
value="delete"
:value="Permission.Delete"
color="warning"
>
Delete
Expand All @@ -79,5 +81,31 @@
</template>

<script setup lang="ts">
import { VForm, VAlert, VChip, VChipGroup, VCol, VRow } from 'vuetify/components';
import { ref, watch } from 'vue';
import { VAlert, VChip, VChipGroup, VCol, VForm, VRow, VBtn } from 'vuetify/components';
import { mdiCheckCircle } from '@mdi/js';
import { Permission } from '@/types/createAccessGrant';
const emit = defineEmits<{
'permissionsChanged': [perms: Permission[]];
}>();
const permissions = ref<Permission[]>([]);
/**
* Selects or deselects all the permissions.
*/
function onAllClick(): void {
permissions.value = permissions.value.length === 4 ?
[] :
[
Permission.Read,
Permission.Write,
Permission.List,
Permission.Delete,
];
}
watch(permissions, value => emit('permissionsChanged', value.slice()), { deep: true });
</script>
Expand Up @@ -2,21 +2,24 @@
// See LICENSE for copying information.

<template>
<v-form class="pa-7">
<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
value="all"
color="default"
:value="BucketsOption.All"
>
All Buckets
</v-chip>
Expand All @@ -25,42 +28,108 @@
variant="outlined"
filter
color="info"
value="select"
:value="BucketsOption.Select"
>
Select Buckets
</v-chip>

<v-chip
variant="outlined"
filter
color="success"
value="new"
>
New Bucket
</v-chip>
</v-chip-group>

<v-alert v-if="buckets === 'all'" variant="tonal" color="default">
<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-if="buckets === 'select'" variant="tonal" color="info">
<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-select label="Select Buckets" density="comfortable" class="mt-3" hide-details />
</v-alert>

<v-alert v-else variant="tonal" color="success">
<p class="text-subtitle-2 font-weight-bold">Create a new bucket</p>
<p class="text-subtitle-2">New bucket for this access only.</p>
<v-text-field label="Enter a bucket name" density="comfortable" class="mt-3" hide-details />
<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 { VForm, VAlert, VChip, VChipGroup, VCol, VRow, VSelect, VTextField } from 'vuetify/components';
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>
Expand Up @@ -63,9 +63,9 @@ const passphrase = ref<string>('');
const isPassphraseVisible = ref<boolean>(false);
const props = withDefaults(defineProps<{
title: string;
setOnNext: boolean;
ackRequired: boolean;
title?: string;
setOnNext?: boolean;
ackRequired?: boolean;
}>(), {
title: 'Enter New Passphrase',
setOnNext: false,
Expand Down
Expand Up @@ -40,7 +40,7 @@ import SaveButtons from '@/components/dialogs/commonPassphraseSteps/SaveButtons.
import Icon from '@/assets/createAccessGrantFlow/passphraseGenerated.svg';
const props = defineProps<{
defineProps<{
name: string;
}>();
Expand Down

0 comments on commit 2ebd0b4

Please sign in to comment.