Skip to content

Commit

Permalink
Merge pull request #66 from bcgov/feature/bucket-check
Browse files Browse the repository at this point in the history
Check bucket exists before create/update
  • Loading branch information
jujaga authored Apr 5, 2023
2 parents 5af90de + 6bfdb08 commit 2b2f8da
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 30 deletions.
53 changes: 30 additions & 23 deletions frontend/src/components/bucket/BucketConfigForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,19 @@ import Password from '@/components/form/Password.vue';
import TextInput from '@/components/form/TextInput.vue';
import { Button, useToast } from '@/lib/primevue';
import { useAuthStore, useBucketStore } from '@/store';
import { differential } from '@/utils/utils';
import type { Bucket } from '@/types';
export type BucketForm = {
accessKeyId?: string;
bucket?: string;
bucketName?: string;
endpoint?: string;
key?: string;
secretAccessKey?: string;
};
// Props
type Props = {
bucket?: Bucket;
Expand All @@ -27,23 +37,23 @@ const bucketStore = useBucketStore();
const { getUserId } = storeToRefs(useAuthStore());
// Default form values
const initialValues = {
bucketName: props.bucket?.bucketName,
const initialValues: BucketForm = {
accessKeyId: props.bucket?.accessKeyId,
bucket: props.bucket?.bucket,
bucketName: props.bucket?.bucketName,
endpoint: props.bucket?.endpoint,
accessKeyId: props.bucket?.accessKeyId,
secretAccessKey: props.bucket?.secretAccessKey,
key: props.bucket?.key
key: props.bucket?.key,
secretAccessKey: props.bucket?.secretAccessKey
};
// Form validation schema
const schema = object({
bucketName: string().max(255).required().label('Bucket name'),
accessKeyId: string().max(255).required().label('Access Key ID'),
bucket: string().max(255).required().label('Bucket'),
bucketName: string().max(255).required().label('Bucket name'),
endpoint: string().max(255).required().label('Endpoint'),
accessKeyId: string().max(255).required().label('Access Key ID'),
secretAccessKey: string().max(255).required().label('Secret Access Key'),
key: string().max(255).label('Key')
key: string().max(255).label('Key'),
secretAccessKey: string().max(255).required().label('Secret Access Key')
});
// Actions
Expand All @@ -52,18 +62,16 @@ const toast = useToast();
const onSubmit = async (values: any) => {
try {
const formBucket = {
bucketName: values.bucketName,
accessKeyId: values.accessKeyId,
bucket: values.bucket,
bucketName: values.bucketName,
endpoint: values.endpoint,
accessKeyId: values.accessKeyId !== 'REDACTED' ? values.accessKeyId : undefined,
secretAccessKey:
values.secretAccessKey !== 'REDACTED' ? values.secretAccessKey : undefined,
key: values.key ? values.key : '/',
active: true
secretAccessKey: values.secretAccessKey,
} as Bucket;
props.bucket ?
await bucketStore.updateBucket(props.bucket?.bucketId, formBucket) :
await bucketStore.updateBucket(props.bucket?.bucketId, differential(formBucket, initialValues)) :
await bucketStore.createBucket(formBucket);
await bucketStore.fetchBuckets({ userId: getUserId.value, objectPerms: true });
Expand Down Expand Up @@ -106,37 +114,37 @@ const onCancel = () => {
name="bucketName"
label="Bucket name *"
placeholder="My Documents"
helptext="Your custom display name for the bucket."
help-text="Your custom display name for the bucket."
/>
<TextInput
name="bucket"
label="Bucket *"
placeholder="bucket0123456789"
helptext="Your storage provider's bucket identifier."
help-text="Your storage provider's bucket identifier."
/>
<TextInput
name="endpoint"
label="Endpoint *"
placeholder="https://example.com/"
helptext="The URL of the object storage server."
help-text="The URL of the object storage server."
/>
<Password
name="accessKeyId"
label="Access key identifier / Username *"
placeholder="username"
helptext="User/Account identifier or username."
help-text="User/Account identifier or username."
/>
<Password
name="secretAccessKey"
label="Secret access key *"
placeholder="password"
helptext="A password used to access the bucket."
help-text="A password used to access the bucket."
/>
<TextInput
name="key"
label="Key"
placeholder="directory"
helptext="An optional path prefix within a bucket. The path will be created if it doesn't already exist."
help-text="An optional path prefix within a bucket. The path will be created if it doesn't already exist."
/>
<Button
class="mt-2"
Expand All @@ -148,8 +156,7 @@ const onCancel = () => {
<Button
class="p-button-text mt-2"
label="Cancel"
icon="pi pi
-times"
icon="pi pi-times"
@click="onCancel"
/>
</Form>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/form/TextInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { InputText } from '@/lib/primevue';
// Props
type Props = {
helptext?: string;
helpText?: string;
label?: string;
name: string;
placeholder?: string;
};
const props = withDefaults(defineProps<Props>(), {
helptext: '',
helpText: '',
type: 'text',
label: '',
placeholder: ''
Expand All @@ -32,7 +32,7 @@ const { errorMessage, value } = useField<string>(toRef(props, 'name'));
:placeholder="placeholder"
:class="{ 'p-invalid': errorMessage }"
/>
<small id="`${name}-help`">{{ helptext }}</small>
<small id="`${name}-help`">{{ helpText }}</small>
<ErrorMessage
:name="name"
/>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/types/Bucket.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { IAudit } from '@/interfaces';

export type Bucket = {
bucketId: string;
bucketName: string;
active: boolean;
accessKeyId: string;
bucket: string;
bucketId: string;
bucketName: string;
endpoint: string;
key: string;
secretAccessKey: string;
region: string;
active: boolean;
secretAccessKey: string;
} & IAudit;
13 changes: 13 additions & 0 deletions frontend/src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/**
* @function differential
* Create a key/value differential from source against comparer
* @param {object} source Source object
* @param {object} comparer The object to be compared against
* @returns {object} Object containing the non-matching key/value pairs in the source object
*/
export function differential(source: any, comparer: any): any {
return Object.fromEntries(Object.entries(source)
.filter(([key, value]) => comparer[key] !== value)
);
}

/**
* @function isDebugMode
* Checks if the app is currently running in debug mode
Expand Down

0 comments on commit 2b2f8da

Please sign in to comment.