Skip to content

Commit

Permalink
feat(spaces): add loaders on create/update/delete
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasRichel committed Jan 20, 2021
1 parent 4d70eed commit 16d7588
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 31 deletions.
13 changes: 13 additions & 0 deletions src/components/space-action-menu/SpaceActionMenu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
background-color: $color-white;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.1);

.action-loader {
display: flex;
justify-content: center;
align-items: center;
:deep() .bimdata-loading {
background: transparent;
color: $color-primary;
&--square {
border-color: $color-primary;
}
}
}

.action-menu {
display: flex;
flex-direction: column;
Expand Down
15 changes: 14 additions & 1 deletion src/components/space-action-menu/SpaceActionMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@
<div class="space-action-menu__container" v-show="showMenu">
<transition name="fade" mode="out-in">

<SpaceUpdateForm v-if="showUpdateForm"
<div class="action-loader" v-if="loading">
<BIMDataLoading />
</div>

<SpaceUpdateForm v-else-if="showUpdateForm"
:space="space"
@close="closeUpdateForm"
@success="closeMenu"
/>

<SpaceDeleteGuard v-else-if="showDeleteGuard"
Expand Down Expand Up @@ -46,10 +51,12 @@

<script>
import { ref } from 'vue';
import { createLoadingContext } from '@/state/loadingState'
import { useSpacesState } from '@/state/spacesState';
// Components
import BIMDataButton from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js';
import BIMDataIcon from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataIcon.js';
import BIMDataLoading from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataLoading.js";
import SpaceDeleteGuard from '@/components/space-delete-guard/SpaceDeleteGuard';
import SpaceImageInput from '@/components/space-image-input/SpaceImageInput';
import SpaceUpdateForm from '@/components/space-update-form/SpaceUpdateForm';
Expand All @@ -58,6 +65,7 @@ export default {
components: {
BIMDataButton,
BIMDataIcon,
BIMDataLoading,
SpaceDeleteGuard,
SpaceImageInput,
SpaceUpdateForm,
Expand All @@ -71,15 +79,19 @@ export default {
setup(props) {
const { removeSpaceImage } = useSpacesState();
const loading = createLoadingContext(`space-action-${props.space.id}`);
const showMenu = ref(false);
const closeMenu = () => {
closeUpdateForm();
closeDeleteGuard();
loading.value = false;
showMenu.value = false;
};
const toggleMenu = () => {
closeUpdateForm();
closeDeleteGuard();
loading.value = false;
showMenu.value = !showMenu.value;
};
Expand All @@ -105,6 +117,7 @@ export default {
return {
// References
loading,
showDeleteGuard,
showMenu,
showUpdateForm,
Expand Down
30 changes: 26 additions & 4 deletions src/components/space-creation-card/SpaceCreationCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,33 @@
}

.bimdata-card__content {
display: flex;
flex-direction: column;
justify-content: space-evenly;
height: calc(100% - #{$spacing-unit*4});
padding: $spacing-unit;

.action-loader {
display: flex;
justify-content: center;
align-items: center;
.bimdata-loading {
background: transparent;
color: $color-primary;
&--square {
border-color: $color-primary;
}
}
}

.creation-form {
display: flex;
flex-direction: column;
justify-content: space-evenly;
height: 100%;
padding: $spacing-unit;
}
}
}
}

// Transition classes
.fade-enter-from, .fade-leave-to { opacity: 0; }
.fade-enter-active { transition: opacity 0.1s ease-out; }
.fade-leave-active { transition: opacity 0.1s ease-in; }
53 changes: 40 additions & 13 deletions src/components/space-creation-card/SpaceCreationCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@
<BIMDataCard class="space-creation-card"
:submenuText="$t('Spaces.SpaceCreationCard.title')">
<template #right>
<BIMDataButton ghost rounded icon
<BIMDataButton ghost rounded icon v-show="!loading"
@click="close">
<BIMDataIcon name="close" size="xxxs" />
</BIMDataButton>
</template>
<template #content>
<BIMDataInput ref="nameInput"
:placeholder="$t('Spaces.SpaceCreationCard.inputName')"
v-model="newSpace.name"
/>
<BIMDataButton fill radius color="primary"
@click="createSpace">
{{ $t('Spaces.SpaceCreationCard.buttonCreate') }}
</BIMDataButton>
<transition name="fade" mode="out-in">

<div class="action-loader" v-if="loading">
<BIMDataLoading />
</div>

<div class="creation-form" v-else>
<BIMDataInput ref="nameInput"
:placeholder="$t('Spaces.SpaceCreationCard.inputName')"
v-model="newSpace.name"
/>
<BIMDataButton fill radius color="primary"
@click="createSpace">
{{ $t('Spaces.SpaceCreationCard.buttonCreate') }}
</BIMDataButton>
</div>

</transition>
</template>
</BIMDataCard>
</template>
Expand All @@ -28,31 +38,48 @@ import BIMDataCard from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/B
import BIMDataButton from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js';
import BIMDataIcon from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataIcon.js';
import BIMDataInput from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataInput.js';
import BIMDataLoading from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataLoading.js";
export default {
components: {
BIMDataCard,
BIMDataButton,
BIMDataIcon,
BIMDataInput
BIMDataInput,
BIMDataLoading,
},
emits: [
'close'
],
setup(props, { emit }) {
const { createSpace: create } = useSpacesState();
const loading = ref(false);
const nameInput = ref(null);
const newSpace = reactive({ name: '' });
const close = () => emit('close');
const createSpace = () => create(newSpace).then(close);
const createSpace = () => {
loading.value = true;
create(newSpace).then(() => {
loading.value = false;
close();
});
};
const close = () => {
emit('close');
};
onMounted(() => nameInput.value.focus());
onMounted(
() => setTimeout(() => nameInput.value.focus(), 400)
);
return {
// References
loading,
nameInput,
newSpace,
// Methods
close,
createSpace
};
Expand Down
12 changes: 10 additions & 2 deletions src/components/space-delete-guard/SpaceDeleteGuard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
</div>
<BIMDataButton fill radius color="high"
class="space-delete-guard__submit-btn"
@click="deleteSpace(space)">
@click="removeSpace">
{{ $t('Spaces.SpaceDeleteGuard.buttonDelete') }}
</BIMDataButton>
</div>
</template>

<script>
import { useLoadingContext } from '@/state/loadingState';
import { useSpacesState } from '@/state/spacesState';
// Components
import BIMDataButton from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js';
Expand All @@ -42,14 +43,21 @@ export default {
setup(props, { emit }) {
const { deleteSpace } = useSpacesState();
const loading = useLoadingContext(`space-action-${props.space.id}`);
const removeSpace = () => {
loading.value = true;
deleteSpace({ ...props.space });
};
const close = () => {
emit('close');
};
return {
// Methods
close,
deleteSpace
removeSpace
};
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/components/space-image-input/SpaceImageInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Uppy from '@uppy/core';
import XHRUpload from '@uppy/xhr-upload';
import { ref } from 'vue';
import { useGlobalState } from '@/state/globalState';
import { useLoadingContext } from '@/state/loadingState';
import { useSpacesState } from '@/state/spacesState';
// Components
import BIMDataButton from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js';
Expand All @@ -36,6 +37,8 @@ export default {
const { user } = useGlobalState();
const { softUpdateSpace } = useSpacesState();
const loading = useLoadingContext(`space-action-${props.space.id}`);
const fileInput = ref(null);
const uppy = new Uppy({
Expand All @@ -58,14 +61,14 @@ export default {
'Authorization': `Bearer ${user.value.access_token}`
}
});
uppy.on('file-added', () => {
loading.value = true;
});
uppy.on('upload-error', (file, error) => {
// TODO: properly handle error
console.log('An error occurred while uploading file: ' + file.name);
console.error(error);
emit('error', error);
});
uppy.on('complete', ({ successful:[{ response:{ body:{ image }}}] }) => {
softUpdateSpace({ ...props.space, image });
fileInput.value.value = ""; // reset file input
uppy.reset(); // reset Uppy instance
emit('success');
});
Expand Down
12 changes: 10 additions & 2 deletions src/components/space-update-form/SpaceUpdateForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

<script>
import { onMounted, ref } from 'vue';
import { useLoadingContext } from '@/state/loadingState';
import { useSpacesState } from '@/state/spacesState';
// Components
import BIMDataButton from '@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js';
Expand All @@ -42,15 +43,22 @@ export default {
}
},
emits: [
'close'
'close',
'success',
'error',
],
setup(props, { emit }) {
const { updateSpace } = useSpacesState();
const loading = useLoadingContext(`space-action-${props.space.id}`);
const nameInput = ref(null);
const spaceName = ref(props.space.name);
const renameSpace = () => {
updateSpace({ ...props.space, name: spaceName.value }).then(close);
loading.value = true;
updateSpace({ ...props.space, name: spaceName.value })
.then(() => emit('success'))
.catch((error) => emit('error', error));
};
const close = () => {
Expand Down
20 changes: 20 additions & 0 deletions src/state/loadingState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ref } from 'vue';

const state = {};

const createLoadingContext = (contextID) => {
state[contextID] = { loading: ref(false) };
return state[contextID].loading;
};

const removeLoadingContext = (contextID) => {
delete state[contextID];
};

const useLoadingContext = (contextID) => state[contextID].loading;

export {
createLoadingContext,
removeLoadingContext,
useLoadingContext
};
2 changes: 1 addition & 1 deletion src/views/oidc-callback/OidcCallback.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="oidc-callback-view">
<BIMDataBigSpinner style="transform: translateX(130px);"></BIMDataBigSpinner>
<BIMDataBigSpinner style="transform: translateX(130px);" />
</div>
</template>

Expand Down
10 changes: 6 additions & 4 deletions src/views/spaces/Spaces.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</div>
<div class="space-list">
<transition name="pop-in">
<SpaceCreationCard v-if="onCreate" @close="onCreate = false" />
<SpaceCreationCard v-if="showCreationCard" @close="showCreationCard = false" />
</transition>
<transition-group name="space-list">
<SpaceCard v-for="space in spaces" :key="space.id" :space="space" />
Expand Down Expand Up @@ -55,7 +55,7 @@ export default {
const displayedSpaces = ref([]);
const searchText = ref('');
const onCreate = ref(false);
const showCreationCard = ref(false);
let sortOrder = 'none';
const filterSpaces = (value) => {
Expand All @@ -76,7 +76,7 @@ export default {
);
};
const createSpace = () => {
onCreate.value = true;
showCreationCard.value = true;
};
watch(
Expand All @@ -91,9 +91,11 @@ export default {
onMounted(() => fetchSpaces());
return {
// References
spaces: displayedSpaces,
onCreate,
searchText,
showCreationCard,
// Methods
filterSpaces,
sortSpaces,
createSpace
Expand Down

0 comments on commit 16d7588

Please sign in to comment.