Skip to content
Snippets Groups Projects
Commit 8ac695a1 authored by Daniel Göbel's avatar Daniel Göbel
Browse files

Merge branch 'feature/67-ui-improvements' into 'development'

Resolve "UI improvements"

Closes #67

See merge request !62
parents 7cc7544f 1d1178ae
No related branches found
No related tags found
2 merge requests!84Remove development branch,!62Resolve "UI improvements"
Showing
with 11146 additions and 5672 deletions
......@@ -13,12 +13,17 @@ default:
- docker
before_script:
- npm --version # For debugging
- npm install
- npm install --no-fund
- npm update --no-fund
lint:
stage: test
script:
- npm run lint
type-check:
stage: test
script:
- npm run type-check
build:
......
# build stage
FROM node:18 as build-stage
WORKDIR /app
# RUN apk add yarn
COPY package.json ./
COPY package-lock.json ./
RUN npm install
RUN npm install --no-fund
COPY . .
RUN npm run build-only
......
......@@ -8,7 +8,7 @@
<script src="/env.js"></script>
</head>
<body>
<div id="app"></div>
<div id="app" class="d-flex flex-column justify-content-between" style="min-height: 100vh"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
This diff is collapsed.
......@@ -2,12 +2,13 @@
import NavbarTop from "@/components/NavbarTop.vue";
import { onBeforeMount } from "vue";
import { useCookies } from "vue3-cookies";
import { useAuthStore } from "@/stores/auth";
import { useAuthStore } from "@/stores/users";
import { useRouter } from "vue-router";
import { OpenAPI as S3ProxyOpenAPI } from "@/client/s3proxy";
import { OpenAPI as AuthOpenAPI } from "@/client/auth";
import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow";
import { environment } from "@/environment";
import FooterBottom from "@/components/FooterBottom.vue";
const { cookies } = useCookies();
const store = useAuthStore();
......@@ -44,9 +45,10 @@ onBeforeMount(() => {
<template>
<NavbarTop />
<div class="container-xxl mt-4">
<div class="container-xxl mt-4 flex-grow-1">
<router-view></router-view>
</div>
<FooterBottom />
</template>
<style scoped></style>
src/assets/images/bibi.png

10.6 KiB

This diff is collapsed.
src/assets/images/dfg.png

133 KiB

This diff is collapsed.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 713.24 170.14"><title>Element 4</title><path d="M262.07,72.19c0,7.85-4.85,13.13-12.08,13.13S237.82,80,237.82,72.19V36.51H227.33V72.8a22.5,22.5,0,0,0,5.84,15.58C237.27,92.73,243.09,95,250,95c15.6,0,22.58-11.16,22.58-22.23V36.51h-10.5Z" fill="#1d1d1b"/><polygon points="327.15 94.95 329.56 94.95 329.56 36.51 319.16 36.51 319.16 71.65 287.39 35.51 287.27 35.37 284.85 35.37 284.85 93.9 295.43 93.9 295.43 58.93 327.03 94.81 327.15 94.95" fill="#1d1d1b"/><rect x="342.48" y="36.51" width="10.49" height="57.39" fill="#1d1d1b"/><polygon points="399.47 36.51 386.48 71.82 373.23 36.51 361.97 36.51 384.72 94.77 387.54 94.77 410.47 36.51 399.47 36.51" fill="#1d1d1b"/><polygon points="454.31 84.63 429.96 84.63 429.96 69.19 452.92 69.19 452.92 60.26 429.96 60.26 429.96 45.95 454.31 45.95 454.31 36.51 419.46 36.51 419.46 93.9 454.31 93.9 454.31 84.63" fill="#1d1d1b"/><path d="M494.47,93.9h12.45L488.34,70c9.58-1.43,15.28-7.64,15.28-16.72,0-10.48-7.36-16.73-19.69-16.73H466.07V93.9h10.49V70.67l17.79,23.07ZM482.79,62.36h-6.23v-17h6.93c6.05,0,9.81,3.25,9.81,8.5C493.3,59.26,489.47,62.36,482.79,62.36Z" fill="#1d1d1b"/><path d="M533.75,85.59c-5.61,0-10.79-3.61-15.55-7.51l-.34-.28-5.25,7.64.27.24c6.9,6.15,13.74,9.27,20.34,9.27C544.48,95,552,88.22,552,78.21c0-8.91-7.1-13.49-12.44-16.16L533,58.73c-5.58-2.84-7.38-4.77-7.38-7.94,0-4,3.84-6.14,7.63-6.14s7.84,1.73,12.15,5.15l.34.27,5-7.3-.27-.23c-4.16-3.5-9.43-7.08-17.11-7.08-11.17,0-18.39,6.26-18.39,15.94s7.76,14.22,13.59,16.87L534.17,71c4.5,2.29,7.29,4.43,7.29,8C541.46,83.12,538.58,85.59,533.75,85.59Z" fill="#1d1d1b"/><rect x="561.68" y="36.51" width="10.49" height="57.39" fill="#1d1d1b"/><polygon points="599.38 93.9 609.78 93.9 609.78 45.95 625.93 45.95 625.93 36.51 583.14 36.51 583.14 45.95 599.38 45.95 599.38 93.9" fill="#1d1d1b"/><path d="M638.54,30.94a6.69,6.69,0,1,0-6.69-6.69A6.55,6.55,0,0,0,638.54,30.94Z" fill="#1d1d1b"/><path d="M657.57,30.94a6.62,6.62,0,0,0,6.69-6.69,6.7,6.7,0,0,0-6.69-6.69,6.61,6.61,0,0,0-6.69,6.69A6.55,6.55,0,0,0,657.57,30.94Z" fill="#1d1d1b"/><path d="M649.46,35.63h-2.9L622.66,93.9h10.83l4-10.31H658.7l4.19,10.31h10.82l-24.15-58Zm5.77,39.21H640.88L648,56.77Z" fill="#1d1d1b"/><polygon points="670.44 36.35 670.44 45.8 686.68 45.8 686.68 93.74 697.09 93.74 697.09 45.8 713.24 45.8 713.24 36.35 670.44 36.35" fill="#1d1d1b"/><path d="M257.28,140.57a14.44,14.44,0,0,0,7.34-12.45c0-9.64-7.64-15.39-20.43-15.39H227.33V170h18.34c13.18,0,21-6.3,21-16.86C266.71,147.36,263.21,142.72,257.28,140.57ZM237.8,137V121.46h6.74c5.62,0,9.7,3.13,9.7,7.44,0,3.93-2.55,8.14-9.7,8.14Zm8.39,24.47H237.8V145.25H247c5.73,0,9.43,3.05,9.43,7.78C256.41,158.42,252.69,161.51,246.19,161.51Z" fill="#1d1d1b"/><rect x="275.86" y="112.73" width="10.47" height="57.25" fill="#1d1d1b"/><polygon points="298.26 169.99 333.02 169.99 333.02 160.73 308.73 160.73 308.73 145.33 331.63 145.33 331.63 136.43 308.73 136.43 308.73 122.16 333.02 122.16 333.02 112.73 298.26 112.73 298.26 169.99" fill="#1d1d1b"/><polygon points="353.26 112.73 342.79 112.73 342.79 169.99 377.64 169.99 377.64 160.29 353.26 160.29 353.26 112.73" fill="#1d1d1b"/><polygon points="388.03 169.99 422.8 169.99 422.8 160.73 398.5 160.73 398.5 145.33 421.4 145.33 421.4 136.43 398.5 136.43 398.5 122.16 422.8 122.16 422.8 112.73 388.03 112.73 388.03 169.99" fill="#1d1d1b"/><polygon points="434.68 169.99 445.15 169.99 445.15 146.9 466.22 146.9 466.22 138.25 445.15 138.25 445.15 122.34 467.79 122.34 467.79 112.73 434.68 112.73 434.68 169.99" fill="#1d1d1b"/><polygon points="478.72 169.99 513.49 169.99 513.49 160.73 489.19 160.73 489.19 145.33 512.1 145.33 512.1 136.43 489.19 136.43 489.19 122.16 513.49 122.16 513.49 112.73 478.72 112.73 478.72 169.99" fill="#1d1d1b"/><polygon points="535.32 112.73 524.85 112.73 524.85 169.99 559.7 169.99 559.7 160.29 535.32 160.29 535.32 112.73" fill="#1d1d1b"/><path d="M589.67,112.73H571.33V170h17.91c23.17,0,31.4-15.6,31.4-29C620.64,124.36,607.9,112.73,589.67,112.73ZM609.73,141c0,12.7-7.31,20-20.06,20H581.8V121.9h8.13C599.79,121.9,609.73,127.81,609.73,141Z" fill="#1d1d1b"/><polygon points="133.58 36.46 133.58 0 0 0 0 170.14 170.08 170.14 170.08 36.46 133.58 36.46" fill="#1d1d1b"/></svg>
\ No newline at end of file
<script setup lang="ts"></script>
<template>
<footer
class="navbar navbar-expand-lg bd-navbar w-100 border-top border-secondary mt-auto p-2"
>
<nav
class="container-xxl bd-gutter flex-wrap flex-lg-nowrap text-light"
></nav>
</footer>
</template>
<style scoped>
footer {
background: rgb(255, 177, 45);
}
</style>
<script setup lang="ts">
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { useAuthStore } from "@/stores/auth";
import { useAuthStore } from "@/stores/users";
import { useRoute } from "vue-router";
import { useCookies } from "vue3-cookies";
import { watch, ref, computed } from "vue";
......@@ -78,7 +78,7 @@ watch(
aria-expanded="false"
data-bs-auto-close="true"
>
Object Storage
Files
</a>
<ul
class="dropdown-menu shadow m-0"
......@@ -86,12 +86,12 @@ watch(
>
<li>
<router-link class="dropdown-item" :to="{ name: 'buckets' }"
>Buckets</router-link
>My Data Buckets</router-link
>
</li>
<li>
<router-link class="dropdown-item" :to="{ name: 's3_keys' }"
>S3 Keys</router-link
>S3 Bucket Keys</router-link
>
</li>
</ul>
......@@ -115,14 +115,14 @@ watch(
>
<li>
<router-link class="dropdown-item" :to="{ name: 'workflows' }"
>Workflows</router-link
>Available Workflows</router-link
>
</li>
<li>
<router-link
class="dropdown-item"
:to="{ name: 'workflow-executions' }"
>My Executions</router-link
>My Workflow Executions</router-link
>
</li>
<li
......
......@@ -4,7 +4,7 @@ import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { UserService } from "@/client/auth";
import type { User } from "@/client/auth";
import { useAuthStore } from "@/stores/auth";
import { useAuthStore } from "@/stores/users";
const props = defineProps<{
modalID: string;
......
......@@ -13,6 +13,7 @@ import { computed, onMounted } from "vue";
import { Tooltip } from "bootstrap";
import { useBucketStore } from "@/stores/buckets";
import { useRouter } from "vue-router";
import { useAuthStore } from "@/stores/users";
const props = defineProps<{
active: boolean;
......@@ -23,10 +24,11 @@ const props = defineProps<{
const randomIDSuffix = Math.random().toString(16).substring(2, 8);
const permissionRepository = useBucketStore();
const userRepository = useAuthStore();
const router = useRouter();
const permission = computed<BucketPermissionOut | undefined>(() =>
permissionRepository.getBucketPermission(props.bucket.name),
const permission = computed<BucketPermissionOut | undefined>(
() => permissionRepository.ownPermissions[props.bucket.name],
);
const emit = defineEmits<{
......@@ -41,13 +43,15 @@ function permissionDeleted(perm: BucketPermissionIn) {
onMounted(() => {
if (!props.loading) {
new Tooltip("#tooltip-" + randomIDSuffix);
new Tooltip("#ownBucketIcon-" + randomIDSuffix);
new Tooltip("#sharedBucketIcon-" + randomIDSuffix);
}
});
</script>
<template>
<permission-modal
v-if="permission != null && props.active"
v-if="permission != undefined && props.active"
:modalID="'view-permission-modal' + randomIDSuffix"
:bucket-name="props.bucket.name"
:sub-folders="{ subFolders: {}, files: [] }"
......@@ -86,8 +90,44 @@ onMounted(() => {
params: { bucketName: bucket.name, subFolders: [] },
}"
>
<span class="text-truncate" style="width: 80%">{{ bucket.name }}</span>
<div>
<span class="text-truncate flex-grow-3">
<template v-if="bucket.owner_constraint === 'READ'"
>Upload Bucket</template
>
<template v-else-if="bucket.owner_constraint === 'WRITE'"
>Download Bucket</template
>
<template v-else>{{ bucket.name }}</template>
</span>
<div class="text-nowrap">
<font-awesome-icon
:hidden="bucket.owner !== userRepository.currentUID"
:id="'ownBucketIcon-' + randomIDSuffix"
icon="fa-solid fa-user"
:class="{
'me-2':
props.active ||
permission ||
(
permissionRepository.bucketPermissionsMapping[bucket.name] ??
[]
).length > 0,
}"
data-bs-toogle="tooltip"
data-bs-title="Own Bucket"
/>
<font-awesome-icon
:hidden="
!permission &&
(permissionRepository.bucketPermissionsMapping[bucket.name] ?? [])
.length === 0
"
:id="'sharedBucketIcon-' + randomIDSuffix"
icon="fa-solid fa-users"
:class="{ 'me-2': props.active }"
data-bs-toogle="tooltip"
data-bs-title="Shared Bucket"
/>
<font-awesome-icon
v-if="props.active && !permission && props.deletable"
icon="fa-solid fa-trash"
......@@ -111,7 +151,7 @@ onMounted(() => {
<table class="table table-sm table-borderless mb-0">
<tbody>
<tr v-if="permission">
<th scope="row" class="fw-bold">Permission</th>
<th scope="row" class="fw-bold">Permission:</th>
<td>
<a
href="#"
......@@ -121,6 +161,30 @@ onMounted(() => {
>
</td>
</tr>
<tr v-if="permission">
<th scope="row" class="fw-bold">Owner:</th>
<td class="text-truncate">
{{ userRepository.userMapping[bucket.owner] }}
</td>
</tr>
<tr
v-if="
(
permissionRepository.bucketPermissionsMapping[bucket.name] ??
[]
).length > 0
"
>
<th scope="row" class="fw-bold">Permissions:</th>
<td>
<a
href="#"
data-bs-toggle="modal"
data-bs-target="#permission-list-modal"
>View</a
>
</td>
</tr>
<tr>
<th scope="row" class="fw-bold">Created:</th>
<td>
......@@ -156,12 +220,15 @@ onMounted(() => {
.delete-icon {
color: white;
}
.delete-icon:hover {
color: var(--bs-danger) !important;
}
.info-icon {
color: white;
}
.info-icon:hover {
color: var(--bs-info) !important;
}
......
......@@ -27,8 +27,8 @@ const props = defineProps<{
<table class="table table-hover table-sm table-borderless">
<tbody>
<tr>
<th scope="row" class="col-2">Name</th>
<td class="col-10">{{ props.bucket.name }}</td>
<th scope="row" class="col-3">Name</th>
<td class="col-9">{{ props.bucket.name }}</td>
</tr>
<tr>
<th scope="row">Creation date</th>
......
......@@ -38,9 +38,9 @@ function createBucket() {
bucket.name = bucket.name.trim();
if (bucketCreateForm.value?.checkValidity()) {
formState.loading = true;
bucketRepository.createBucket(
bucket,
(createdBucket) => {
bucketRepository
.createBucket(bucket)
.then((createdBucket) => {
createBucketModal?.hide();
bucket.name = "";
bucket.description = "";
......@@ -50,19 +50,18 @@ function createBucket() {
name: "bucket",
params: { bucketName: createdBucket.name, subFolders: [] },
});
},
(error) => {
})
.catch((error) => {
if (
error.status === 400 &&
error.body["detail"] === "Bucket name is already taken"
) {
formState.bucketNameTaken = true;
}
},
() => {
})
.finally(() => {
formState.loading = false;
},
);
});
}
}
......@@ -79,7 +78,7 @@ function modalClosed() {
modal-label="Create Bucket Modal"
v-on="{ 'hidden.bs.modal': modalClosed }"
>
<template v-slot:header> Create new Bucket </template>
<template v-slot:header> Create new S3 Bucket</template>
<template v-slot:body>
<form
id="bucketCreateForm"
......@@ -113,15 +112,15 @@ function modalClosed() {
</div>
<div class="mb-3">
<label for="bucketDescriptionInput" class="form-label">
Description {{ bucket.description.length }} / 126
Description
</label>
<div class="input-group">
<textarea
class="form-control"
id="bucketDescriptionInput"
required
rows="5"
minlength="126"
rows="3"
minlength="32"
maxlength="65536"
v-model="bucket.description"
placeholder="Describe the purpose of the bucket"
......@@ -129,7 +128,7 @@ function modalClosed() {
<div class="invalid-feedback">
Requirements
<ul>
<li>At least 126 Characters long</li>
<li>At least 32 Characters long</li>
</ul>
</div>
</div>
......
......@@ -17,7 +17,7 @@ const props = defineProps<{
modal-label="Object Detail Modal"
>
<template v-slot:header>
<h4>Object Details</h4>
<h4>File Details</h4>
</template>
<template v-slot:body>
<div class="container-fluid">
......@@ -32,8 +32,12 @@ const props = defineProps<{
<td>{{ props.s3Object.key }}</td>
</tr>
<tr>
<th scope="row">Content Type</th>
<td>{{ props.s3Object.content_type }}</td>
<th scope="row">Size</th>
<td>
{{
filesize(props.s3Object.size, { base: 2, standard: "jedec" })
}}
</td>
</tr>
<tr>
<th scope="row">Timestamp</th>
......@@ -46,12 +50,8 @@ const props = defineProps<{
</td>
</tr>
<tr>
<th scope="row">Size</th>
<td>
{{
filesize(props.s3Object.size, { base: 2, standard: "jedec" })
}}
</td>
<th scope="row">Content Type</th>
<td>{{ props.s3Object.content_type }}</td>
</tr>
</tbody>
</table>
......
<script setup lang="ts">
import type { BucketPermissionIn, BucketPermissionOut } from "@/client/s3proxy";
import type { BucketPermissionOut } from "@/client/s3proxy";
import type { FolderTree } from "@/types/PseudoFolder";
import { reactive } from "vue";
import { BucketPermissionService } from "@/client/s3proxy";
import { onBeforeMount, watch } from "vue";
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import PermissionModal from "@/components/object-storage/modals/PermissionModal.vue";
import { useBucketStore } from "@/stores/buckets";
const bucketRepository = useBucketStore();
// Props
// -----------------------------------------------------------------------------
const props = defineProps<{
bucketName: string;
subFolders: FolderTree;
modalID: string;
addPermission: undefined | BucketPermissionOut;
}>();
// Reactive State
// -----------------------------------------------------------------------------
const state = reactive<{
permissions: BucketPermissionOut[];
loading: boolean;
currentPermission: BucketPermissionOut;
}>({
permissions: [],
loading: true,
currentPermission: {
bucket_name: "bucketname",
uid: "uid",
......@@ -47,46 +43,10 @@ watch(
},
);
watch(
() => props.addPermission,
(newBucketPermission) => {
if (newBucketPermission !== undefined) {
state.permissions.push(newBucketPermission);
}
},
);
// Function
// -----------------------------------------------------------------------------
function updateBucketPermissions(bucketName: string) {
state.loading = true;
BucketPermissionService.bucketPermissionListPermissionsPerBucket(bucketName)
.then((permissions) => {
state.permissions = permissions;
})
.catch((err) => {
console.error(err);
})
.finally(() => {
state.loading = false;
});
}
function permissionDeleted(bucketPermission: BucketPermissionIn) {
state.permissions = state.permissions.filter(
(perm) => perm.uid != bucketPermission.uid,
);
}
function permissionCreated(bucketPermission: BucketPermissionOut) {
state.permissions.push(bucketPermission);
}
function permissionEdited(bucketPermission: BucketPermissionOut) {
const index = state.permissions.findIndex(
(perm) => perm.uid == bucketPermission.uid,
);
state.permissions[index] = bucketPermission;
bucketRepository.fetchBucketPermissions(bucketName);
}
// Lifecycle Hooks
......@@ -106,33 +66,29 @@ onBeforeMount(() => {
:sub-folders="props.subFolders"
:back-modal-id="props.modalID"
:modalID="'permission-list-edit-modal' + randomIDSuffix"
@permission-deleted="permissionDeleted"
@permission-created="permissionCreated"
@permission-edited="permissionEdited"
/>
<bootstrap-modal
:modalID="props.modalID"
:static-backdrop="true"
modal-label="Permission List Modal"
>
<template v-slot:header> Bucket Permissions </template>
<template v-slot:header>
Bucket Permissions for Bucket <i>{{ props.bucketName }}</i>
</template>
<template v-slot:body>
<ul v-if="state.loading" class="list-group">
<li
class="list-group-item list-group-item-action placeholder-wave"
v-for="n in 5"
:key="n"
<div>
<div
class="list-group"
v-if="
bucketRepository.getBucketPermissions(props.bucketName).length > 0
"
>
<span class="placeholder col-2 bg-info"></span>
<span class="placeholder col-8 offset-1"></span>
</li>
</ul>
<div v-else>
<div class="list-group" v-if="state.permissions.length > 0">
<button
type="button"
class="list-group-item list-group-item-action text-truncate"
v-for="permission in state.permissions"
v-for="permission in bucketRepository.getBucketPermissions(
props.bucketName,
)"
:key="permission.uid"
@click="state.currentPermission = permission"
data-bs-toggle="modal"
......
......@@ -12,9 +12,10 @@ import type {
} from "@/client/s3proxy";
import type { User } from "@/client/auth";
import type { FolderTree } from "@/types/PseudoFolder";
import { Permission, BucketPermissionService } from "@/client/s3proxy";
import { Permission } from "@/client/s3proxy";
import { Toast } from "bootstrap";
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { useBucketStore } from "@/stores/buckets";
// Props
// -----------------------------------------------------------------------------
......@@ -29,6 +30,7 @@ const props = defineProps<{
backModalId?: string;
}>();
const bucketRepository = useBucketStore();
// Variables
// -----------------------------------------------------------------------------
const randomIDSuffix = Math.random().toString(16).substring(2, 8);
......@@ -82,24 +84,16 @@ const permissionUserReadonly = computed<boolean>(() => {
watch(
() => props.bucketName,
(newBucketName) => {
updatePermission();
updateLocalPermission();
permission.bucket_name = newBucketName;
},
);
watch(
() => props.editUserPermission,
() => updatePermission(),
() => updateLocalPermission(),
);
// Events
// -----------------------------------------------------------------------------
const emit = defineEmits<{
(e: "permission-deleted", permission: BucketPermissionIn): void;
(e: "permission-created", permission: BucketPermissionOut): void;
(e: "permission-edited", permission: BucketPermissionOut): void;
}>();
// Functions
// -----------------------------------------------------------------------------
/**
......@@ -109,7 +103,7 @@ function modalClosed() {
formState.readonly = props.readonly;
formState.error = false;
if (editPermission.value) {
updatePermission();
updateLocalPermission();
}
}
......@@ -131,7 +125,7 @@ function inputVisible(input?: number | string | null): boolean {
/**
* Update the form content
*/
function updatePermission() {
function updateLocalPermission() {
if (props.editUserPermission != undefined) {
permission.bucket_name = props.editUserPermission.bucket_name;
permission.file_prefix = props.editUserPermission.file_prefix;
......@@ -184,9 +178,9 @@ function formSubmit() {
if (permissionForm.value?.checkValidity()) {
formState.loading = true;
const serverAnswerPromise = editPermission.value
? BucketPermissionService.bucketPermissionUpdatePermission(
permission.uid,
? bucketRepository.updateBucketPermission(
permission.bucket_name,
permission.uid,
{
to_timestamp: permission.to_timestamp,
from_timestamp: permission.from_timestamp,
......@@ -194,17 +188,12 @@ function formSubmit() {
file_prefix: permission.file_prefix,
} as BucketPermissionParameters,
)
: BucketPermissionService.bucketPermissionCreatePermission(permission);
: bucketRepository.createBucketPermission(permission);
serverAnswerPromise
.then((permission: BucketPermissionOut) => {
if (editPermission.value) {
emit("permission-edited", permission);
} else {
emit("permission-created", permission);
}
.then(() => {
permissionModal?.hide();
successToast?.show();
updatePermission();
updateLocalPermission();
})
.catch(() => {
formState.error = true;
......@@ -223,15 +212,12 @@ function formSubmit() {
function confirmedDeletePermission(bucketName: string, uid: string) {
if (!formState.loading) {
formState.loading = true;
BucketPermissionService.bucketPermissionDeletePermissionForBucket(
bucketName,
uid,
)
bucketRepository
.deleteBucketPermission(bucketName, uid)
.then(() => {
permissionDeleted.value = true;
permissionModal?.hide();
successToast?.show();
emit("permission-deleted", permission);
})
.catch(() => {
formState.error = true;
......@@ -252,7 +238,7 @@ function updateUser(user: User) {
onMounted(() => {
permissionModal = new Modal("#" + props.modalID);
successToast = new Toast("#" + "toast-" + randomIDSuffix);
updatePermission();
updateLocalPermission();
});
function fromTimestampChanged(target?: HTMLInputElement | null) {
......@@ -321,7 +307,7 @@ function toTimestampChanged(target?: HTMLInputElement | null) {
<template v-slot:header v-else-if="props.editUserPermission !== undefined"
>Edit Permission
</template>
<template v-slot:header v-else> Create new Permission</template>
<template v-slot:header v-else> Create new Bucket Permission</template>
<template v-slot:extra-button>
<font-awesome-icon
v-if="props.deletable"
......@@ -391,10 +377,10 @@ function toTimestampChanged(target?: HTMLInputElement | null) {
</div>
</div>
<div class="mb-3 row">
<label for="permissionTypeInput" class="col-2 col-form-label">
Type<span v-if="!formState.readonly">*</span>
<label for="permissionTypeInput" class="col-3 col-form-label">
Permission Type<span v-if="!formState.readonly">*</span>
</label>
<div class="col-10">
<div class="col-9">
<select
class="form-select text-lowercase"
id="permissionTypeInput"
......
......@@ -136,6 +136,7 @@ function updateKeysInBucket(bucketName?: string) {
onMounted(() => {
bucketRepository.fetchBuckets();
bucketRepository.fetchOwnPermissions();
if (format.value) {
s3Path.key = defaultValue.value;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment