feat: loading state on urql actions

This commit is contained in:
liyasthomas
2022-02-04 17:41:21 +05:30
parent 5aa6bf0d53
commit 6fb8bcfe25
5 changed files with 66 additions and 13 deletions

View File

@@ -80,6 +80,7 @@
:save-request="saveRequest" :save-request="saveRequest"
:collections-type="collectionsType" :collections-type="collectionsType"
:picked="picked" :picked="picked"
:loading-collection-i-ds="loadingCollectionIDs"
@edit-collection="editCollection(collection, index)" @edit-collection="editCollection(collection, index)"
@add-folder="addFolder($event)" @add-folder="addFolder($event)"
@edit-folder="editFolder($event)" @edit-folder="editFolder($event)"
@@ -95,7 +96,14 @@
/> />
</div> </div>
<div <div
v-if="filteredCollections.length === 0 && filterText.length === 0" v-if="loadingCollectionIDs.includes('root')"
class="flex flex-col items-center justify-center p-4"
>
<SmartSpinner class="my-4" />
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
</div>
<div
v-else-if="filteredCollections.length === 0 && filterText.length === 0"
class="flex flex-col items-center justify-center p-4 text-secondaryLight" class="flex flex-col items-center justify-center p-4 text-secondaryLight"
> >
<img <img
@@ -258,6 +266,7 @@ export default defineComponent({
}, },
teamCollectionAdapter: new TeamCollectionAdapter(null), teamCollectionAdapter: new TeamCollectionAdapter(null),
teamCollectionsNew: [], teamCollectionsNew: [],
loadingCollectionIDs: [],
} }
}, },
computed: { computed: {
@@ -332,6 +341,13 @@ export default defineComponent({
this.subscribeTo(this.teamCollectionAdapter.collections$, (colls) => { this.subscribeTo(this.teamCollectionAdapter.collections$, (colls) => {
this.teamCollectionsNew = cloneDeep(colls) this.teamCollectionsNew = cloneDeep(colls)
}) })
this.subscribeTo(
this.teamCollectionAdapter.loadingCollections$,
(collectionsIDs) => {
console.log("loading collections", collectionsIDs)
this.loadingCollectionIDs = collectionsIDs
}
)
}, },
methods: { methods: {
updateTeamCollections() { updateTeamCollections() {

View File

@@ -146,6 +146,7 @@
:collections-type="collectionsType" :collections-type="collectionsType"
:is-filtered="isFiltered" :is-filtered="isFiltered"
:picked="picked" :picked="picked"
:loading-collection-i-ds="loadingCollectionIDs"
@add-folder="$emit('add-folder', $event)" @add-folder="$emit('add-folder', $event)"
@edit-folder="$emit('edit-folder', $event)" @edit-folder="$emit('edit-folder', $event)"
@edit-request="$emit('edit-request', $event)" @edit-request="$emit('edit-request', $event)"
@@ -173,7 +174,14 @@
@duplicate-request="$emit('duplicate-request', $event)" @duplicate-request="$emit('duplicate-request', $event)"
/> />
<div <div
v-if=" v-if="loadingCollectionIDs.includes(collection.id)"
class="flex flex-col items-center justify-center p-4"
>
<SmartSpinner class="my-4" />
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
</div>
<div
v-else-if="
(collection.children == undefined || (collection.children == undefined ||
collection.children.length === 0) && collection.children.length === 0) &&
(collection.requests == undefined || (collection.requests == undefined ||
@@ -218,6 +226,7 @@ export default defineComponent({
saveRequest: Boolean, saveRequest: Boolean,
collectionsType: { type: Object, default: () => {} }, collectionsType: { type: Object, default: () => {} },
picked: { type: Object, default: () => {} }, picked: { type: Object, default: () => {} },
loadingCollectionIDs: { type: Array, default: () => [] },
}, },
setup() { setup() {
const t = useI18n() const t = useI18n()

View File

@@ -126,6 +126,7 @@
:collections-type="collectionsType" :collections-type="collectionsType"
:folder-path="`${folderPath}/${subFolderIndex}`" :folder-path="`${folderPath}/${subFolderIndex}`"
:picked="picked" :picked="picked"
:loading-collection-i-ds="loadingCollectionIDs"
@add-folder="$emit('add-folder', $event)" @add-folder="$emit('add-folder', $event)"
@edit-folder="$emit('edit-folder', $event)" @edit-folder="$emit('edit-folder', $event)"
@edit-request="$emit('edit-request', $event)" @edit-request="$emit('edit-request', $event)"
@@ -154,7 +155,14 @@
@duplicate-request="$emit('duplicate-request', $event)" @duplicate-request="$emit('duplicate-request', $event)"
/> />
<div <div
v-if=" v-if="loadingCollectionIDs.includes(folder.id)"
class="flex flex-col items-center justify-center p-4"
>
<SmartSpinner class="my-4" />
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
</div>
<div
v-else-if="
(folder.children == undefined || folder.children.length === 0) && (folder.children == undefined || folder.children.length === 0) &&
(folder.requests == undefined || folder.requests.length === 0) (folder.requests == undefined || folder.requests.length === 0)
" "
@@ -200,6 +208,7 @@ export default defineComponent({
isFiltered: Boolean, isFiltered: Boolean,
collectionsType: { type: Object, default: () => {} }, collectionsType: { type: Object, default: () => {} },
picked: { type: Object, default: () => {} }, picked: { type: Object, default: () => {} },
loadingCollectionIDs: { type: Array, default: () => [] },
}, },
setup() { setup() {
return { return {

View File

@@ -19,7 +19,11 @@
</template> </template>
<template #footer> <template #footer>
<span> <span>
<ButtonPrimary :label="t('action.save')" @click.native="addNewTeam" /> <ButtonPrimary
:label="t('action.save')"
:loading="isLoading"
@click.native="addNewTeam"
/>
<ButtonSecondary <ButtonSecondary
:label="t('action.cancel')" :label="t('action.cancel')"
@click.native="hideModal" @click.native="hideModal"
@@ -51,12 +55,15 @@ const emit = defineEmits<{
const name = ref<string | null>(null) const name = ref<string | null>(null)
const addNewTeam = () => const isLoading = ref(false)
pipe(
TeamNameCodec.decode(name.value), // Perform decode (returns either) const addNewTeam = async () => {
TE.fromEither, // Convert either to a task either isLoading.value = true
TE.mapLeft(() => "invalid_name" as const), // Failure above is an invalid_name, give it an identifiable value await pipe(
TE.chainW(createTeam), // Create the team TeamNameCodec.decode(name.value),
TE.fromEither,
TE.mapLeft(() => "invalid_name" as const),
TE.chainW(createTeam),
TE.match( TE.match(
(err) => { (err) => {
// err is of type "invalid_name" | GQLError<Err> // err is of type "invalid_name" | GQLError<Err>
@@ -72,6 +79,8 @@ const addNewTeam = () =>
} }
) )
)() )()
isLoading.value = false
}
const hideModal = () => { const hideModal = () => {
name.value = null name.value = null

View File

@@ -175,7 +175,11 @@
</template> </template>
<template #footer> <template #footer>
<span> <span>
<ButtonPrimary :label="t('action.save')" @click.native="saveTeam" /> <ButtonPrimary
:label="t('action.save')"
:loading="isLoading"
@click.native="saveTeam"
/>
<ButtonSecondary <ButtonSecondary
:label="t('action.cancel')" :label="t('action.cancel')"
@click.native="hideModal" @click.native="hideModal"
@@ -343,7 +347,10 @@ const membersList = computed(() => {
return [] return []
}) })
const isLoading = ref(false)
const removeExistingTeamMember = async (userID: string) => { const removeExistingTeamMember = async (userID: string) => {
isLoading.value = true
const removeTeamMemberResult = await removeTeamMember( const removeTeamMemberResult = await removeTeamMember(
userID, userID,
props.editingTeamID props.editingTeamID
@@ -353,9 +360,11 @@ const removeExistingTeamMember = async (userID: string) => {
} else { } else {
toast.success(`${t("team.member_removed")}`) toast.success(`${t("team.member_removed")}`)
} }
isLoading.value = false
} }
const saveTeam = async () => { const saveTeam = async () => {
isLoading.value = true
if (name.value !== "") { if (name.value !== "") {
if (TeamNameCodec.is(name.value)) { if (TeamNameCodec.is(name.value)) {
const updateTeamNameResult = await renameTeam( const updateTeamNameResult = await renameTeam(
@@ -380,11 +389,12 @@ const saveTeam = async () => {
hideModal() hideModal()
toast.success(`${t("team.saved")}`) toast.success(`${t("team.saved")}`)
} else { } else {
return toast.error(`${t("team.name_length_insufficient")}`) toast.error(`${t("team.name_length_insufficient")}`)
} }
} else { } else {
return toast.error(`${t("empty.team_name")}`) toast.error(`${t("empty.team_name")}`)
} }
isLoading.value = false
} }
const hideModal = () => { const hideModal = () => {