refactor all modals to use same dialog component

This commit is contained in:
undergroundwires
2021-03-20 16:07:26 +01:00
parent 5f527a00cf
commit 6f46cdb4ed
4 changed files with 83 additions and 50 deletions

View File

@@ -36,3 +36,16 @@
- Do not forget to subscribe from events when component is destroyed or if needed [collection](./collection-files.md) is changed. - Do not forget to subscribe from events when component is destroyed or if needed [collection](./collection-files.md) is changed.
- 💡 `events` in base class [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts) makes lifecycling easier - 💡 `events` in base class [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts) makes lifecycling easier
- 📖 See [Application state | Application layer](./presentation.md#application-state) where the state is implemented using using state pattern. - 📖 See [Application state | Application layer](./presentation.md#application-state) where the state is implemented using using state pattern.
## Modals
- [Dialog.vue](./../src/presentation/components/Shared/Dialog.vue) is a shared component that can be used to show modal windows
- Simply wrap the content inside of its slot and call `.show()` method on its reference.
- Example:
```html
<Dialog ref="testDialog">
<div>Hello world</div>
</Dialog>
<div @click="$refs.testDialog.show()">Show dialog</div>
```

View File

@@ -17,17 +17,9 @@
v-on:click="copyCodeAsync" v-on:click="copyCodeAsync"
icon-prefix="fas" icon-name="copy"> icon-prefix="fas" icon-name="copy">
</IconButton> </IconButton>
<modal :name="macOsModalName" height="auto" :scrollable="true" :adaptive="true" <Dialog v-if="this.isMacOsCollection" ref="instructionsDialog">
v-if="this.isMacOsCollection">
<div class="modal">
<div class="modal__content">
<MacOsInstructions :fileName="this.fileName" /> <MacOsInstructions :fileName="this.fileName" />
</div> </Dialog>
<div class="modal__close-button">
<font-awesome-icon :icon="['fas', 'times']" @click="$modal.hide(macOsModalName)"/>
</div>
</div>
</modal>
</div> </div>
</template> </template>
@@ -36,6 +28,7 @@ import { Component } from 'vue-property-decorator';
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue'; import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
import { SaveFileDialog, FileType } from '@/infrastructure/SaveFileDialog'; import { SaveFileDialog, FileType } from '@/infrastructure/SaveFileDialog';
import { Clipboard } from '@/infrastructure/Clipboard'; import { Clipboard } from '@/infrastructure/Clipboard';
import Dialog from '@/presentation/components/Shared/Dialog.vue';
import IconButton from './IconButton.vue'; import IconButton from './IconButton.vue';
import MacOsInstructions from './MacOsInstructions.vue'; import MacOsInstructions from './MacOsInstructions.vue';
import { Environment } from '@/application/Environment/Environment'; import { Environment } from '@/application/Environment/Environment';
@@ -51,11 +44,10 @@ import { IApplicationContext } from '@/application/Context/IApplicationContext';
components: { components: {
IconButton, IconButton,
MacOsInstructions, MacOsInstructions,
Dialog,
}, },
}) })
export default class TheCodeButtons extends StatefulVue { export default class TheCodeButtons extends StatefulVue {
public readonly macOsModalName = 'macos-instructions';
public readonly isDesktopVersion = Environment.CurrentEnvironment.isDesktop; public readonly isDesktopVersion = Environment.CurrentEnvironment.isDesktop;
public canRun = false; public canRun = false;
public hasCode = false; public hasCode = false;
@@ -70,7 +62,7 @@ export default class TheCodeButtons extends StatefulVue {
const context = await this.getCurrentContextAsync(); const context = await this.getCurrentContextAsync();
saveCode(this.fileName, context.state); saveCode(this.fileName, context.state);
if (this.isMacOsCollection) { if (this.isMacOsCollection) {
this.$modal.show(this.macOsModalName); (this.$refs.instructionsDialog as any).show();
} }
} }
public async executeCodeAsync() { public async executeCodeAsync() {
@@ -134,9 +126,6 @@ async function executeCodeAsync(context: IApplicationContext) {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/presentation/styles/colors.scss";
@import "@/presentation/styles/fonts.scss";
.container { .container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -145,26 +134,4 @@ async function executeCodeAsync(context: IApplicationContext) {
.container > * + * { .container > * + * {
margin-left: 30px; margin-left: 30px;
} }
.modal {
font-family: $normal-font;
margin-bottom: 10px;
display: flex;
flex-direction: row;
&__content {
width: 100%;
margin: 5%;
}
&__close-button {
width: auto;
font-size: 1.5em;
margin-right:0.25em;
align-self: flex-start;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
}
</style> </style>

View File

@@ -0,0 +1,58 @@
<template>
<modal
:name="name"
:scrollable="true"
:adaptive="true"
height="auto">
<div class="dialog">
<div class="dialog__content">
<slot></slot>
</div>
<div class="dialog__close-button">
<font-awesome-icon :icon="['fas', 'times']" @click="$modal.hide(name)"/>
</div>
</div>
</modal>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class Dialog extends Vue {
private static idCounter = 0;
public name = (++Dialog.idCounter).toString();
public show(): void {
this.$modal.show(this.name);
}
}
</script>
<style scoped lang="scss">
@import "@/presentation/styles/fonts.scss";
.dialog {
font-family: $normal-font;
margin-bottom: 10px;
display: flex;
flex-direction: row;
&__content {
width: 100%;
margin: 5%;
}
&__close-button {
width: auto;
font-size: 1.5em;
margin-right: 0.25em;
align-self: flex-start;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
}
</style>

View File

@@ -31,18 +31,13 @@
</div> </div>
<div class="footer__section__item"> <div class="footer__section__item">
<font-awesome-icon class="icon" :icon="['fas', 'user-secret']" /> <font-awesome-icon class="icon" :icon="['fas', 'user-secret']" />
<a @click="$modal.show(modalName)">Privacy</a> <a @click="$refs.privacyDialog.show()">Privacy</a>
</div> </div>
</div> </div>
</div> </div>
<modal :name="modalName" height="auto" :scrollable="true" :adaptive="true"> <Dialog ref="privacyDialog">
<div class="modal"> <PrivacyPolicy />
<PrivacyPolicy class="modal__content"/> </Dialog>
<div class="modal__close-button">
<font-awesome-icon :icon="['fas', 'times']" @click="$modal.hide(modalName)"/>
</div>
</div>
</modal>
</div> </div>
</template> </template>
@@ -50,17 +45,17 @@
import { Component, Vue } from 'vue-property-decorator'; import { Component, Vue } from 'vue-property-decorator';
import { Environment } from '@/application/Environment/Environment'; import { Environment } from '@/application/Environment/Environment';
import PrivacyPolicy from './PrivacyPolicy.vue'; import PrivacyPolicy from './PrivacyPolicy.vue';
import Dialog from '@/presentation/components/Shared/Dialog.vue';
import DownloadUrlList from './DownloadUrlList.vue'; import DownloadUrlList from './DownloadUrlList.vue';
import { IApplication } from '@/domain/IApplication'; import { IApplication } from '@/domain/IApplication';
import { ApplicationFactory } from '@/application/ApplicationFactory'; import { ApplicationFactory } from '@/application/ApplicationFactory';
@Component({ @Component({
components: { components: {
PrivacyPolicy, DownloadUrlList, Dialog, PrivacyPolicy, DownloadUrlList,
}, },
}) })
export default class TheFooter extends Vue { export default class TheFooter extends Vue {
public readonly modalName = 'privacy-policy';
public readonly isDesktop = Environment.CurrentEnvironment.isDesktop; public readonly isDesktop = Environment.CurrentEnvironment.isDesktop;
public version: string = ''; public version: string = '';