Skip to content

Commit

Permalink
chore: added Dialog component and associated classes (for further use) (
Browse files Browse the repository at this point in the history
#911)

Signed-off-by: Eric Le Ponner <eric.leponner@icloud.com>
  • Loading branch information
ericleponner authored Mar 1, 2024
1 parent 15e380f commit 9d0ec39
Show file tree
Hide file tree
Showing 6 changed files with 487 additions and 0 deletions.
94 changes: 94 additions & 0 deletions src/components/dialog/CommitButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!--
-
- Hedera Mirror Node Explorer
-
- Copyright (C) 2021 - 2023 Hedera Hashgraph, LLC
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-->

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- TEMPLATE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<template>
<DialogButton :controller="controller" :auto-close="false" :enabled="enabled" @action="handleAction">
<div class="dialog-stack">
<div :class="{'is-invisible': isBusy}">
<slot/>
</div>
<div :class="{'is-invisible': !isBusy}">
<span class="loader is-inline-block"/>
</div>
</div>
</DialogButton>
</template>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- SCRIPT -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<script lang="ts">
import {computed, defineComponent, PropType} from "vue";
import Dialog from "@/components/dialog/Dialog.vue";
import DialogButton from "@/components/dialog/DialogButton.vue";
import {DialogController, DialogMode} from "@/components/dialog/DialogController";
export default defineComponent({
name: "CommitButton",
components: {DialogButton, Dialog },
props: {
controller: {
type: Object as PropType<DialogController>,
required: true
},
enabled: Boolean
},
emits: ["action"],
setup(props, ctx) {
const isBusy = computed(() => props.controller.mode.value == DialogMode.Busy)
const handleAction = () => {
ctx.emit("action")
}
return {
isBusy,
handleAction
}
}
})
</script>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- STYLE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<style scoped>
.dialog-stack {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
justify-items: center;
}
.dialog-stack div {
grid-column-start: 1;
grid-row-start: 1
}
</style>
137 changes: 137 additions & 0 deletions src/components/dialog/Dialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<!--
-
- Hedera Mirror Node Explorer
-
- Copyright (C) 2021 - 2024 Hedera Hashgraph, LLC
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-->

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- TEMPLATE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<template>
<template v-if="controller.visible.value">
<div class="is-active modal has-text-white">
<div class="modal-background"/>
<div class="modal-content" style="width: 768px; border-radius: 16px">
<div class="box">

<div class="is-flex h-is-primary-title is-justify-content-space-between is-align-items-baseline">
<slot name="dialogTitle"/>
</div>

<hr class="h-card-separator"/>

<div class="dialog-stack">
<div :class="{'is-invisible': !dialogInputVisible}">
<slot name="dialogInput"/>
</div>
<div :class="{'is-invisible': !dialogBusyVisible}" class="is-flex-direction-column is-align-content-center">
<slot name="dialogBusy">Task is on-going…</slot>
</div>
<div :class="{'is-invisible': !dialogSuccessVisible}" class="is-flex-direction-column is-align-content-center">
<slot name="dialogSuccess">Task did succeed</slot>
</div>
<div :class="{'is-invisible': !dialogErrorVisible}" class="is-flex-direction-column is-align-content-center">
<slot name="dialogError">Task did fail</slot>
</div>
</div>

<div class="is-flex is-justify-content-flex-end">
<template v-if="dialogInputVisible || dialogBusyVisible">
<slot name="dialogInputButtons">
<DialogButton :controller="controller">Close</DialogButton>
</slot>
</template>
<template v-else-if="dialogSuccessVisible">
<slot name="dialogSuccessButtons">
<DialogButton :controller="controller">Close</DialogButton>
</slot>
</template>
<template v-else-if="dialogErrorVisible">
<slot name="dialogErrorButtons">
<DialogButton :controller="controller">Close</DialogButton>
</slot>
</template>
</div>

</div>
</div>
</div>
</template>
</template>


<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- SCRIPT -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<script lang="ts">
import {computed, defineComponent, PropType, watch} from "vue";
import DialogButton from "@/components/dialog/DialogButton.vue";
import {DialogController, DialogMode} from "@/components/dialog/DialogController";
export default defineComponent({
name: "Dialog",
components: {DialogButton},
props: {
controller: {
type: Object as PropType<DialogController>,
required: true
},
},
setup(props) {
const dialogInputVisible = computed(() => props.controller.mode.value === DialogMode.Input)
const dialogBusyVisible = computed(() => props.controller.mode.value === DialogMode.Busy)
const dialogSuccessVisible = computed(() => props.controller.mode.value === DialogMode.Success)
const dialogErrorVisible = computed(() => props.controller.mode.value === DialogMode.Error)
watch(props.controller.visible, () => {
if (props.controller.visible.value) {
props.controller.mode.value = DialogMode.Input
}
})
return {
dialogInputVisible,
dialogBusyVisible,
dialogSuccessVisible,
dialogErrorVisible
}
}
});
</script>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- STYLE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<style scoped>
.dialog-stack {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
justify-items: start;
}
.dialog-stack div {
grid-column-start: 1;
grid-row-start: 1
}
</style>

84 changes: 84 additions & 0 deletions src/components/dialog/DialogButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!--
-
- Hedera Mirror Node Explorer
-
- Copyright (C) 2021 - 2023 Hedera Hashgraph, LLC
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-->

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- SCRIPT -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<template>
<button class="button is-white is-small is-uppercase ml-4"
@click="handleClick"
:disabled="!buttonEnabled"><slot/></button>
</template>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- TEMPLATE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<script lang="ts">
import {computed, defineComponent, PropType} from "vue";
import {DialogController, DialogMode} from "@/components/dialog/DialogController";
export default defineComponent({
name: "DialogButton",
components: {},
props: {
controller: {
type: Object as PropType<DialogController>,
required: true
},
autoClose: {
type: Boolean,
default: true
},
enabled: {
type: Boolean,
default: true
}
},
emits: ["action"],
setup(props, ctx) {
const handleClick = () => {
ctx.emit("action")
if (props.autoClose) {
props.controller.visible.value = false
}
}
const buttonEnabled = computed(
() => props.enabled && props.controller.mode.value !== DialogMode.Busy)
return {
handleClick,
buttonEnabled
}
}
})
</script>

<!-- --------------------------------------------------------------------------------------------------------------- -->
<!-- STYLE -->
<!-- --------------------------------------------------------------------------------------------------------------- -->

<style scoped/>
38 changes: 38 additions & 0 deletions src/components/dialog/DialogController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*-
*
* Hedera Mirror Node Explorer
*
* Copyright (C) 2021 - 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import {ref} from "vue";

export class DialogController {

public readonly visible = ref(false)
public readonly mode = ref<DialogMode>(DialogMode.Input)

public readonly handleClose = () => {
this.visible.value = false
}
}

export enum DialogMode {
Input,
Busy,
Error,
Success
}
Loading

0 comments on commit 9d0ec39

Please sign in to comment.