Skip to content

Commit

Permalink
pkp/pkp-lib#9527 refine modals
Browse files Browse the repository at this point in the history
  • Loading branch information
jardakotesovec committed Jan 8, 2024
1 parent ef5be51 commit b2f2b54
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 154 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook": "^7.6.5",
"tailwindcss": "^3.3.3",
"tailwindcss": "3.4",
"vite": "^4.4.9",
"vitest": "^1.0.4"
},
Expand Down
3 changes: 3 additions & 0 deletions src/components/Container/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import {mapStores} from 'pinia';
import Container from '@/components/Container/Container.vue';
import PkpDialog from '@/components/Modal/Dialog.vue';
import LegacyModalManager from '@/components/Modal/LegacyModalManager.vue';
import PkpAnnouncer from '@/components/Announcer/Announcer.vue';
// store
import {useDialogStore} from '@/stores/dialogStore.js';
Expand All @@ -11,6 +13,7 @@ export default {
components: {
PkpDialog,
PkpAnnouncer,
LegacyModalManager,
},
extends: Container,
setup() {
Expand Down
37 changes: 30 additions & 7 deletions src/components/Modal/AjaxModalWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@
import {ref, onMounted, inject, defineProps} from 'vue';
import {useFetch} from '@/composables/useFetch';
const props = defineProps({
contentUrl: {
type: String,
const {options} = defineProps({
options: {
type: Object,
default: () => {},
},
});
const contentDiv = ref(null);
// eslint-disable-next-line no-unused-vars
const pkp = window.pkp;
const {data: assignParticipantPageData, fetch: fetchAssignParticipantPage} =
useFetch(props.contentUrl);
const {data: modalData, fetch: fetchAssignParticipantPage} = useFetch(
options.url,
);
const closeModal = inject('closeModal');
const registerCloseCallback = inject('registerCloseCallback');
Expand Down Expand Up @@ -48,14 +50,35 @@ function catchInsideClick(e) {
}
}
function passToBridge(jQueryEvent) {
// If we have an event bridge configured then re-trigger
// the event on the target object.
if (options.eventBridge) {
$('[id^="' + options.eventBridge + '"]').trigger(
jQueryEvent.type,
jQueryEvent.data,
);
}
}
onMounted(async () => {
await fetchAssignParticipantPage();
if (assignParticipantPageData.value) {
$(contentDiv.value).html(assignParticipantPageData.value.content);
if (modalData.value) {
// TODO CONSIDER REMOVE BINDS ON UNMOUNT
$(contentDiv.value).html(modalData.value.content);
$(contentDiv.value).bind('formSubmitted', closeModal);
$(contentDiv.value).bind('formCanceled', closeModal);
$(contentDiv.value).bind('ajaxHtmlError', closeModal);
$(contentDiv.value).bind('modalFinished', closeModal);
// Publish some otherwise private events triggered
// by nested widgets so that they can be handled by
// the element that opened the modal.
$(contentDiv.value).bind('redirectRequested', passToBridge);
$(contentDiv.value).bind('dataChanged', passToBridge);
$(contentDiv.value).bind('updateHeader', passToBridge);
$(contentDiv.value).bind('gridRefreshRequested', passToBridge);
}
});
</script>
96 changes: 48 additions & 48 deletions src/components/Modal/Dialog.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<TransitionRoot as="template" :show="open">
<HLDialog class="modal" :class="'modal--' + type" @close="onClose">
<TransitionRoot as="template" :show="opened">
<HLDialog class="modal" :class="'modal--popup'" @close="onClose">
<TransitionChild
as="template"
enter="ease-out duration-300"
Expand Down Expand Up @@ -31,29 +31,29 @@
class="modal__panel modal__panel--dialog rounded-lg shadow-xl relative mx-3 w-10/12 max-w-3xl transform overflow-hidden bg-lightest text-left transition-all sm:my-8"
>
<div class="modal__header">
<DialogTitle v-if="title" class="modal__title">
{{ title }}
<DialogTitle v-if="dialogProps.title" class="modal__title">
{{ dialogProps.title }}
</DialogTitle>
<button class="modal__closeButton" @click="onClose">
<span :aria-hidden="true">×</span>
<span class="-screenReader">
{{ closeLabel || t('common.close') }}
{{ dialogProps.closeLabel || t('common.close') }}
</span>
</button>
</div>
<div class="modal__content">
<div v-html="message" />
<div v-html="dialogProps.message" />
</div>
<div class="modal__footer">
<spinner v-if="isLoading" />
<spinner v-if="dialogProps.isLoading" />
<pkp-button
v-for="action in actions"
v-for="action in dialogProps.actions"
:key="action.label"
:element="action.element || 'button'"
:href="action.href || null"
:is-primary="action.isPrimary || null"
:is-warnable="action.isWarnable || null"
:is-disabled="isLoading"
:is-disabled="dialogProps.isLoading"
@click="
action.callback ? fireCallback(action.callback) : null
"
Expand All @@ -69,7 +69,10 @@
</TransitionRoot>
</template>

<script>
<script setup>
import {ref, computed, onMounted, onUnmounted} from 'vue';
import {storeToRefs} from 'pinia';
import {
Dialog as HLDialog,
DialogTitle,
Expand All @@ -78,17 +81,41 @@ import {
TransitionChild,
} from '@headlessui/vue';
import Modal from './Modal.vue';
import {useDialogStore} from '@/stores/dialogStore';
const modalLevel = ref(0);
const dialogStore = useDialogStore();
const {dialogProps, dialogOpened, currentLevel} = storeToRefs(dialogStore);
const {closeDialog} = dialogStore;
const opened = computed(
() => dialogOpened.value && modalLevel.value === currentLevel.value,
);
const isLoading = ref(false);
function onClose() {
isLoading.value = false;
closeDialog();
}
export default {
components: {
HLDialog,
DialogTitle,
DialogPanel,
TransitionRoot,
TransitionChild,
},
extends: Modal,
function fireCallback(callback) {
isLoading.value = true;
if (typeof callback === 'function') {
callback(() => {
onClose();
});
}
}
onMounted(() => {
currentLevel.value = currentLevel.value + 1;
modalLevel.value = currentLevel.value;
});
onUnmounted(() => {
currentLevel.value = currentLevel.value - 1;
});
/*export default {
props: {
actions: {
type: Array,
Expand Down Expand Up @@ -117,32 +144,5 @@ export default {
return '';
},
},
},
data() {
return {
isLoading: false,
};
},
mounted() {},
unmounted() {
if (typeof this.close === 'function') {
this.close();
}
},
methods: {
fireCallback(callback) {
this.isLoading = true;
if (typeof callback === 'function') {
callback(() => {
this.onClose();
});
}
},
onClose() {
// reset state;
this.isLoading = false;
this.$emit('close');
},
},
};
},*/
</script>
43 changes: 43 additions & 0 deletions src/components/Modal/LegacyModalManager.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<SideModal close-label="Close" :open="isOpened" @close="close">
<SideModalBodyAjax :options="options" />
<SideModal close-label="Close" :open="isOpened2" @close="close2">
<SideModalBodyAjax :options="options2" />
</SideModal>
</SideModal>
</template>

<script setup>
import {ref} from 'vue';
import SideModal from '@/components/Modal/SideModal.vue';
import SideModalBodyAjax from '@/components/Modal/SideModalBodyAjax.vue';
const isOpened = ref(false);
const isOpened2 = ref(false);
const options = ref(null);
const options2 = ref(null);
function close() {
isOpened.value = false;
options.value = null;
}
function close2() {
isOpened2.value = false;
options2.value = null;
}
// pkp.eventBus.$emit('open-tab', tab);
pkp.eventBus.$on('open-modal-vue', (_options) => {
console.log('open modal vue:', _options);
if (options.value) {
options2.value = _options;
isOpened2.value = true;
return;
}
options.value = _options;
isOpened.value = true;
});
</script>
43 changes: 28 additions & 15 deletions src/components/Modal/SideModalBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,43 @@
</button>
</div>
<div class="ml-8 mr-8 flex-grow">
<slot name="header" :close-modal="closeModal" />
<!--<DialogTitle
class="text-gray-900 font-semibold leading-6 text-base"
>
Panel title
</DialogTitle>-->
<div class="flex">
<div class="flex-grow">
<div class="text-xl-medium"><slot name="pre-title"></slot></div>
<DialogTitle as="h1" class="mt-1 text-4xl-bold">
<slot name="title"></slot>
</DialogTitle>
<DialogDescription class="mt-1 text-3xl-normal">
<slot name="description"></slot>
</DialogDescription>
<div class="mt-1">
<slot name="post-description"></slot>
</div>
</div>
<div class="flex items-center">
<slot name="actions" />
</div>
</div>
</div>
</div>
</div>
<div class="relative mt-6 flex-1 overflow-y-scroll">
<slot :close-modal="closeModal" />
</div>
</div>
<PkpDialog></PkpDialog>
</DialogPanel>
</template>

<script>
import {DialogPanel /*DialogTitle*/} from '@headlessui/vue';
<script setup>
import {inject} from 'vue';
import {DialogPanel, DialogTitle, DialogDescription} from '@headlessui/vue';
import Icon from '@/components/Icon/Icon.vue';
export default {
components: {Icon, DialogPanel /*DialogTitle*/},
inject: ['closeModal'],
props: {
secondary: Boolean,
},
};
import PkpDialog from '@/components/Modal/Dialog.vue';
const {secondary} = defineProps({
secondary: {type: Boolean, default: () => false},
});
const closeModal = inject('closeModal');
</script>
19 changes: 19 additions & 0 deletions src/components/Modal/SideModalBodyAjax.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<SideModalBody :secondary="true">
<template #header><h1 class="text-4xl-bold">Assign editors</h1></template>
<div class="p-4">
<div class="bg-lightest p-4">
<AjaxModalWrapper :options="options" />
</div>
</div>
</SideModalBody>
</template>

<script setup>
import {defineProps} from 'vue';
import SideModalBody from '@/components/Modal/SideModalBody.vue';
import AjaxModalWrapper from '@/components/Modal/AjaxModalWrapper.vue';
const {options} = defineProps({options: {type: Object, default: null}});
console.log('side modal body ajax:', options);
</script>
Loading

0 comments on commit b2f2b54

Please sign in to comment.