feat: Click outside modal closes modal

Also made visual modifications to existing PreferencesContainerConnectionRendering
component.

Signed-off-by: Doehyun Baek <doehyunbaek@gmail.com>
This commit is contained in:
Doehyun Baek 2022-06-03 20:31:51 +09:00 committed by Florent BENOIT
parent 7be524acf7
commit 29c6ff1043
7 changed files with 186 additions and 179 deletions

View file

@ -9,6 +9,7 @@ import ContainerDetails from './ContainerDetails.svelte';
import type { ContainerInfoUI } from './container/ContainerInfoUI';
import ContainerActions from './container/ContainerActions.svelte';
import ContainerEmptyScreen from './container/ContainerEmptyScreen.svelte';
import Modal from './dialogs/Modal.svelte';
let openChoiceModal = false;
@ -317,39 +318,40 @@ function getEngineName(containerInfo: ContainerInfo): string {
</div>
{#if openChoiceModal}
<div class="pf-c-backdrop">
<div class="pf-l-bullseye">
<div
class="pf-c-modal-box pf-m-sm modal z-50 "
tabindex="{0}"
autofocus
aria-modal="true"
on:keydown="{keydownChoice}"
aria-labelledby="modal-title-modal-basic-example-modal"
aria-describedby="modal-description-modal-basic-example-modal">
<button
class="pf-c-button pf-m-plain"
type="button"
aria-label="Close dialog"
on:click="{() => toggleCreateContainer()}">
<i class="fas fa-times" aria-hidden="true"></i>
</button>
<header class="pf-c-modal-box__header" on:keydown="{keydownChoice}">
<h1 class="pf-c-modal-box__title">Create a new container</h1>
</header>
<div class="pf-c-modal-box__body">
<ul class="list-disc">
<li>Create a container from a Containerfile description. Browse a local content description.</li>
<li>Or create a container from an existing image stored in the local registry.</li>
</ul>
</div>
<footer class="pf-c-modal-box__footer">
<button class="pf-c-button pf-m-primary" type="button" on:click="{() => fromDockerfile()}"
>From Containerfile/Dockerfile</button>
<button class="pf-c-button pf-m-secondary" type="button" on:click="{() => fromExistingImage()}"
>From existing image</button>
</footer>
<Modal
on:close="{() => {
openChoiceModal = false;
}}">
<div
class="pf-c-modal-box pf-m-sm modal z-50 "
tabindex="{0}"
autofocus
aria-modal="true"
on:keydown="{keydownChoice}"
aria-labelledby="modal-title-modal-basic-example-modal"
aria-describedby="modal-description-modal-basic-example-modal">
<button
class="pf-c-button pf-m-plain"
type="button"
aria-label="Close dialog"
on:click="{() => toggleCreateContainer()}">
<i class="fas fa-times" aria-hidden="true"></i>
</button>
<header class="pf-c-modal-box__header" on:keydown="{keydownChoice}">
<h1 class="pf-c-modal-box__title">Create a new container</h1>
</header>
<div class="pf-c-modal-box__body">
<ul class="list-disc">
<li>Create a container from a Containerfile description. Browse a local content description.</li>
<li>Or create a container from an existing image stored in the local registry.</li>
</ul>
</div>
<footer class="pf-c-modal-box__footer">
<button class="pf-c-button pf-m-primary" type="button" on:click="{() => fromDockerfile()}"
>From Containerfile/Dockerfile</button>
<button class="pf-c-button pf-m-secondary" type="button" on:click="{() => fromExistingImage()}"
>From existing image</button>
</footer>
</div>
</div>
</Modal>
{/if}

View file

@ -69,12 +69,6 @@ if (previously_focused) {
<div class="modal-background" on:click="{close}"></div>
<div class="modal bg-gray-700" role="dialog" aria-modal="true" bind:this="{modal}">
<slot name="header" />
<hr />
<div class="modal" role="dialog" aria-modal="true" bind:this="{modal}">
<slot />
<hr style="margin-bottom: 9px;" />
<!-- svelte-ignore a11y-autofocus -->
<button autofocus on:click="{close}" class="pf-c-button pf-m-primary pf-m-block"> Close </button>
</div>

View file

@ -7,6 +7,7 @@ import RunContainerModal from './RunContainerModal.svelte';
import { onMount } from 'svelte';
import PushImage from './PushImageModal.svelte';
import PushImageModal from './PushImageModal.svelte';
import Modal from '../dialogs/Modal.svelte';
export let hasModalCallback: (flag: boolean) => void;
export let image: ImageInfoUI;
@ -54,18 +55,28 @@ async function pushImage(imageInfo: ImageInfoUI): Promise<void> {
<Fa class="{iconStyle}" icon="{faTrash}" /></button>
{#if pushImageModal}
<PushImageModal
imageInfoToPush="{imageInfoToPush}"
closeCallback="{() => {
(pushImageModal = false), hasModalCallback(false);
}}" />
<Modal
on:close="{() => {
pushImageModal = false;
}}">
<PushImageModal
imageInfoToPush="{imageInfoToPush}"
closeCallback="{() => {
(pushImageModal = false), hasModalCallback(false);
}}" />
</Modal>
{/if}
{#if runContainerFromImageModal}
<RunContainerModal
image="{modalImageInfo}"
closeCallback="{() => {
<Modal
on:close="{() => {
runContainerFromImageModal = false;
}}" />
}}">
<RunContainerModal
image="{modalImageInfo}"
closeCallback="{() => {
runContainerFromImageModal = false;
}}" />
</Modal>
{/if}
{#if errorMessage}

View file

@ -110,7 +110,7 @@ let pushLogsXtermDiv: HTMLDivElement;
</script>
<div
class="modal z-50 fixed w-full h-full top-0 left-0 flex items-center justify-center p-8 lg:p-0"
class="modal z-50 w-full h-full top-0 left-0 flex items-center justify-center p-8 lg:p-0"
tabindex="{0}"
autofocus
on:keydown="{keydownDockerfileChoice}">

View file

@ -86,7 +86,7 @@ async function startContainer() {
{#if dataReady}
<div
class="modal z-50 fixed w-full h-full top-0 left-0 flex items-center justify-center p-8 lg:p-0"
class="modal z-50 w-full h-full top-0 left-0 flex items-center justify-center p-8 lg:p-0"
tabindex="{0}"
autofocus
on:keydown="{keydownDockerfileChoice}">

View file

@ -69,136 +69,130 @@ async function addRegistry() {
}
</script>
<div class="pf-c-backdrop">
<div class="pf-l-bullseye">
<div
class="pf-c-modal-box pf-m-sm modal z-50 "
tabindex="{0}"
autofocus
aria-modal="true"
on:keydown="{keydownChoice}"
aria-labelledby="modal-title-modal-basic-example-modal"
aria-describedby="modal-description-modal-basic-example-modal">
<button
class="pf-c-button pf-m-plain"
type="button"
aria-label="Close dialog"
on:click="{() => toggleCallback()}">
<i class="fas fa-times" aria-hidden="true"></i>
</button>
<header class="pf-c-modal-box__header" on:keydown="{keydownChoice}">
<h1 class="pf-c-modal-box__title">Add a new registry</h1>
</header>
<div class="pf-c-modal-box__body">
<form novalidate class="pf-c-form pf-m-horizontal-on-sm">
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">Server URL:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<input
class="pf-c-form-control"
type="text"
name="serverUrl"
on:input="{event => checkServerValue(event)}"
bind:value="{registryToCreate.serverUrl}"
aria-invalid="{!!isServerUrlInvalid}"
required />
{#if isServerUrlInvalid}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{isServerUrlInvalid}
</p>
{/if}
</div>
<div class="pf-l-bullseye">
<div
class="pf-c-modal-box pf-m-sm modal z-50 "
tabindex="{0}"
autofocus
aria-modal="true"
on:keydown="{keydownChoice}"
aria-labelledby="modal-title-modal-basic-example-modal"
aria-describedby="modal-description-modal-basic-example-modal">
<button class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog" on:click="{() => toggleCallback()}">
<i class="fas fa-times" aria-hidden="true"></i>
</button>
<header class="pf-c-modal-box__header" on:keydown="{keydownChoice}">
<h1 class="pf-c-modal-box__title">Add a new registry</h1>
</header>
<div class="pf-c-modal-box__body">
<form novalidate class="pf-c-form pf-m-horizontal-on-sm">
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">Server URL:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">username:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<input
class="pf-c-form-control"
type="text"
bind:value="{registryToCreate.username}"
on:input="{event => checkUsernameValue(event)}"
aria-invalid="{!!isUsernameInvalid}"
name="username"
required />
{#if isUsernameInvalid}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{isUsernameInvalid}
</p>
{/if}
</div>
<div class="pf-c-form__group-control">
<input
class="pf-c-form-control"
type="text"
name="serverUrl"
on:input="{event => checkServerValue(event)}"
bind:value="{registryToCreate.serverUrl}"
aria-invalid="{!!isServerUrlInvalid}"
required />
{#if isServerUrlInvalid}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{isServerUrlInvalid}
</p>
{/if}
</div>
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">password:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<input
class="pf-c-form-control"
type="password"
bind:value="{registryToCreate.secret}"
on:input="{event => checkPasswordValue(event)}"
aria-invalid="{!!isPasswordInvalid}"
name="password"
required />
{#if isPasswordInvalid}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{isPasswordInvalid}
</p>
{/if}
</div>
</div>
{#if providerSourceNames.length > 1}
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">Provider:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<select
class="border text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 bg-gray-600 border-gray-500 placeholder-gray-400 text-white"
name="providerChoice"
bind:value="{registryToCreate.source}">
{#each providerSourceNames as providerSourceName}
<option value="{providerSourceName}">{providerSourceName}</option>
{/each}
</select>
</div>
</div>
{/if}
{#if providerSourceNames.length == 1}
<input type="hidden" name="source" readonly bind:value="{registryToCreate.source}" />
{/if}
</form>
</div>
<footer class="pf-c-modal-box__footer">
<div class="w-full flex flex-col justify-end">
<button
class="pf-c-button pf-m-primary"
disabled="{!!isServerUrlInvalid || !!isUsernameInvalid || !!isPasswordInvalid}"
type="button"
on:click="{() => addRegistry()}">Add registry</button>
{#if creationError}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{creationError}
</p>
{/if}
</div>
</footer>
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">username:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<input
class="pf-c-form-control"
type="text"
bind:value="{registryToCreate.username}"
on:input="{event => checkUsernameValue(event)}"
aria-invalid="{!!isUsernameInvalid}"
name="username"
required />
{#if isUsernameInvalid}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{isUsernameInvalid}
</p>
{/if}
</div>
</div>
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">password:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<input
class="pf-c-form-control"
type="password"
bind:value="{registryToCreate.secret}"
on:input="{event => checkPasswordValue(event)}"
aria-invalid="{!!isPasswordInvalid}"
name="password"
required />
{#if isPasswordInvalid}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{isPasswordInvalid}
</p>
{/if}
</div>
</div>
{#if providerSourceNames.length > 1}
<div class="pf-c-form__group">
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="form-horizontal-custom-breakpoint-name">
<span class="pf-c-form__label-text">Provider:</span>
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
</label>
</div>
<div class="pf-c-form__group-control">
<select
class="border text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 bg-gray-600 border-gray-500 placeholder-gray-400 text-white"
name="providerChoice"
bind:value="{registryToCreate.source}">
{#each providerSourceNames as providerSourceName}
<option value="{providerSourceName}">{providerSourceName}</option>
{/each}
</select>
</div>
</div>
{/if}
{#if providerSourceNames.length == 1}
<input type="hidden" name="source" readonly bind:value="{registryToCreate.source}" />
{/if}
</form>
</div>
<footer class="pf-c-modal-box__footer">
<div class="w-full flex flex-col justify-end">
<button
class="pf-c-button pf-m-primary"
disabled="{!!isServerUrlInvalid || !!isUsernameInvalid || !!isPasswordInvalid}"
type="button"
on:click="{() => addRegistry()}">Add registry</button>
{#if creationError}
<p class="pf-c-form__helper-text pf-m-error" id="form-help-text-address-helper" aria-live="polite">
{creationError}
</p>
{/if}
</div>
</footer>
</div>
</div>

View file

@ -3,6 +3,7 @@ import { onMount } from 'svelte';
import type { Registry } from '@tmpwip/extension-api';
import { registriesInfos } from '../../stores/registries';
import PreferencesRegistriesCreateRegistryModal from './PreferencesRegistriesCreateRegistryModal.svelte';
import Modal from '../dialogs/Modal.svelte';
let registries: readonly Registry[] = [];
onMount(() => {
@ -62,5 +63,10 @@ function toggleRegistryModal(): void {
</div>
{#if showRegistryModal}
<PreferencesRegistriesCreateRegistryModal toggleCallback="{toggleRegistryModal}" />
<Modal
on:close="{() => {
showRegistryModal = false;
}}">
<PreferencesRegistriesCreateRegistryModal toggleCallback="{toggleRegistryModal}" />
</Modal>
{/if}