Skip to content

Commit

Permalink
Initial Galleys implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jardakotesovec committed Sep 10, 2024
1 parent 7040ec0 commit 32e6455
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 33 deletions.
2 changes: 2 additions & 0 deletions src/components/Icon/Icon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import MoreOptions from './icons/MoreOptions.vue';
import MySubmissions from './icons/MySubmissions.vue';
import NavDoi from './icons/NavDoi.vue';
import NavAdmin from './icons/NavAdmin.vue';
import New from './icons/New.vue';
import Notifications from './icons/Notifications.vue';
import OpenReview from './icons/OpenReview.vue';
import Orcid from './icons/Orcid.vue';
Expand Down Expand Up @@ -142,6 +143,7 @@ const svgIcons = {
MySubmissions,
NavDoi,
NavAdmin,
New,
Notifications,
OpenReview,
Orcid,
Expand Down
8 changes: 8 additions & 0 deletions src/components/Icon/icons/New.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M20.5477 4.79141V14.8916C20.5471 15.0505 20.4836 15.2028 20.3713 15.3151C20.2589 15.4275 20.1067 15.491 19.9477 15.4916H16.9717V18.6141C16.9714 18.7732 16.9081 18.9256 16.7956 19.038C16.6832 19.1505 16.5308 19.2138 16.3717 19.2141H4.05215C3.89312 19.2138 3.7407 19.1505 3.62825 19.038C3.5158 18.9256 3.45248 18.7732 3.45215 18.6141V8.51393C3.45248 8.3549 3.5158 8.20249 3.62825 8.09004C3.7407 7.97759 3.89312 7.91427 4.05215 7.91393H7.02815V4.79141C7.02848 4.63238 7.0918 4.47996 7.20425 4.36751C7.3167 4.25506 7.46912 4.19174 7.62815 4.19141H19.9477C20.1068 4.19174 20.2592 4.25506 20.3716 4.36751C20.4841 4.47996 20.5474 4.63238 20.5477 4.79141ZM15.5709 15.4916H7.62941C7.47049 15.491 7.31826 15.4275 7.20588 15.3151C7.0935 15.2028 7.03008 15.0505 7.02941 14.8916V10.8962H4.85046V17.8133H15.5709V15.4916ZM19.1481 7.17372H8.42773V14.0908H19.1481V7.17372Z"
fill="currentColor"
/>
</svg>
</template>
8 changes: 7 additions & 1 deletion src/components/Modal/AjaxModalWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const contentDiv = ref(null);
// eslint-disable-next-line no-unused-vars
const pkp = window.pkp;
// to collect data change events, which are passed on close
// used in galleys when the new galley id is needed to open upload modal
const dataChangedEvents = [];
// Fetches html content from legacy endpoints
const {data: modalData, fetch: fetchModalData} = useFetch(legacyOptions.url);
Expand Down Expand Up @@ -74,6 +78,8 @@ function passToHandlerElement(...args) {
const eventType = args?.[0]?.type;
if (eventType === 'dataChanged') {
dataChangedEvents.push(args?.[1]);
// Naive implementation to check for notifications for the actions in modals that are now opened from Vue.js, instead of the grid.
// Logic to trigger these notifications is LinkActionHandler.dataChangedHandler_
$('body').trigger('notifyUser');
Expand All @@ -88,7 +94,7 @@ function passToHandlerElement(...args) {
'wizardCancel',
].includes(eventType)
) {
closeModal();
closeModal({dataChanged: dataChangedEvents});
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/components/Modal/ModalManager.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<SideModal
:key="sideModal1?.modalId"
close-label="Close"
:open="sideModal1?.opened || false"
:modal-level="1"
Expand All @@ -19,7 +20,11 @@
:open="sideModal2?.opened || false"
@close="(returnData) => close(sideModal2?.modalId, returnData)"
>
<component :is="component2" v-bind="sideModal2?.props" />
<component
:is="component2"
:key="sideModal2?.modalId"
v-bind="sideModal2?.props"
/>
<PkpDialog
:key="JSON.stringify(dialogProps)"
:opened="dialogOpened && dialogLevel === 2"
Expand All @@ -32,7 +37,11 @@
:open="sideModal3?.opened || false"
@close="(returnData) => close(sideModal3?.modalId, returnData)"
>
<component :is="component3" v-bind="sideModal3?.props" />
<component
:is="component3"
:key="sideModal3?.modalId"
v-bind="sideModal3?.props"
/>
</SideModal>
</SideModal>
</SideModal>
Expand Down
57 changes: 33 additions & 24 deletions src/components/TableNext/Table.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
<template>
<div
v-if="slots.label || slots.description || slots['top-controls']"
class="flex justify-between bg-default p-4"
>
<div v-if="slots.label || slots.description">
<span v-if="slots.label" :id="labelId" class="text-xl-bold">
<slot name="label" />
</span>
<div v-if="slots.description" :id="descriptionId">
<slot name="description" />
<div>
<div
v-if="slots.label || slots.description || slots['top-controls']"
class="flex justify-between border-x border-t border-light bg-secondary p-4"
>
<div v-if="slots.label || slots.description">
<span
v-if="slots.label"
:id="labelId"
class="text-lg-bold text-heading"
>
<slot name="label" />
</span>
<div v-if="slots.description" :id="descriptionId">
<slot name="description" />
</div>
</div>
<div v-if="slots['top-controls']">
<slot name="top-controls" />
</div>
</div>
<div v-if="slots['top-controls']">
<slot name="top-controls" />
<table
class="pkpTable w-full max-w-full border-separate border-spacing-0"
:aria-labelledby="labelledBy ?? (slots.label ? labelId : null)"
:aria-describedby="
describedBy ?? (slots.description ? descriptionId : null)
"
>
<slot />
</table>
<div
v-if="slots['bottom-controls']"
class="flex justify-between border-x border-b border-light px-3 py-2"
>
<slot name="bottom-controls" />
</div>
</div>
<table
class="pkpTable w-full max-w-full border-separate border-spacing-0"
:aria-labelledby="labelledBy ?? (slots.label ? labelId : null)"
:aria-describedby="
describedBy ?? (slots.description ? descriptionId : null)
"
>
<slot />
</table>
<div v-if="slots['bottom-controls']" class="flex justify-between py-4">
<slot name="bottom-controls" />
</div>
</template>

<script setup>
Expand Down
5 changes: 2 additions & 3 deletions src/composables/useLegacyGridUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ export function useLegacyGridUrl({
},
},
{
onClose: async () => {
console.log('openLegacyModel OnClose');
finishedCallback();
onClose: async (closeData) => {
finishedCallback(closeData);
},
},
);
Expand Down
55 changes: 55 additions & 0 deletions src/managers/GalleyManager/GalleyManager.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<PkpTable>
<template #label>{{ t('submission.layout.galleys') }}</template>
<template #bottom-controls>
<div class="space-x-y flex">
<PkpButton
v-for="action in galleyManagerStore.bottomActions"
:key="action.name"
class="-ms-3"
is-link
@click="galleyManagerStore.handleAction(action.name)"
>
{{ action.label }}
</PkpButton>
</div>
</template>
<TableHeader>
<TableColumn>{{ t('common.name') }}</TableColumn>
<TableColumn>{{ t('common.language') }}</TableColumn>
<TableColumn>
<span class="sr-only">{{ t('common.moreActions') }}</span>
</TableColumn>
</TableHeader>
<TableBody>
<GalleyManagerTableRow
v-for="galley in galleyManagerStore.galleys"
:key="galley.id"
:galley="galley"
:metadata-locales="submission.metadataLocales"
:item-actions="galleyManagerStore.itemActions"
@action="galleyManagerStore.handleAction"
></GalleyManagerTableRow>
</TableBody>
</PkpTable>
</template>

<script setup>
import {useLocalize} from '@/composables/useLocalize';
import {useGalleyManagerStore} from './galleyManagerStore';
import PkpTable from '@/components/TableNext/Table.vue';
import TableColumn from '@/components/TableNext/TableColumn.vue';
import TableHeader from '@/components/TableNext/TableHeader.vue';
import TableBody from '@/components/TableNext/TableBody.vue';
import GalleyManagerTableRow from './GalleyManagerTableRow.vue';
import PkpButton from '@/components/Button/Button.vue';
const props = defineProps({
publication: {type: Object, required: true},
submission: {type: Object, required: true},
});
const {t} = useLocalize();
const galleyManagerStore = useGalleyManagerStore(props);
</script>
60 changes: 60 additions & 0 deletions src/managers/GalleyManager/GalleyManagerTableRow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<template>
<TableRow>
<TableCell>
<div class="flex items-center">
<Icon :icon="fileIcon" class="h-6 w-6 flex-none text-heading" />

<span class="ms-2 text-base-normal">
<a
v-if="galley?.file?.url"
class="hover:underline"
target="_blank"
:href="galley.file.url"
>
{{ galley.label }}
</a>
<template v-else>{{ galley.label }}</template>
</span>
</div>
</TableCell>
<TableCell>
<span class="text-base-normal">
{{ language }}
</span>
</TableCell>
<TableCell>
<DropdownActions
:label="t('common.moreActions')"
:display-as-ellipsis="true"
:actions="itemActions"
@action="(actionName) => emit('action', actionName, {galley})"
></DropdownActions>
</TableCell>
</TableRow>
</template>
<script setup>
import {computed} from 'vue';
import Icon from '@/components/Icon/Icon.vue';
import TableRow from '@/components/TableNext/TableRow.vue';
import TableCell from '@/components/TableNext/TableCell.vue';
import DropdownActions from '@/components/DropdownActions/DropdownActions.vue';
const props = defineProps({
galley: {type: Object, required: true},
metadataLocales: {type: Object, required: true},
itemActions: {type: Array, required: true},
});
const emit = defineEmits(['action']);
const language = computed(() => {
return props.metadataLocales[props.galley.locale];
});
const fileIcon = computed(() =>
!!pkp.documentTypeIcons &&
!!pkp.documentTypeIcons[props.galley?.file?.documentType]
? pkp.documentTypeIcons[props.galley?.file?.documentType]
: 'DocumentDefault',
);
</script>
46 changes: 46 additions & 0 deletions src/managers/GalleyManager/galleyManagerStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {defineComponentStore} from '@/utils/defineComponentStore';
import {computed} from 'vue';
import {useGalleyManagerActions} from './useGalleyManagerActions';
import {useDataChanged} from '@/composables/useDataChanged';

export const useGalleyManagerStore = defineComponentStore(
'galleyManager',
(props) => {
const galleys = computed(() => {
return props?.publication?.galleys || [];
});

/** Reload files when data on screen changes */

/**
* Actions
*/
const _galleyActionsFns = useGalleyManagerActions();

const itemActions = computed(() => _galleyActionsFns.getItemActions());
const bottomActions = computed(() => _galleyActionsFns.getBottomActions());

const {triggerDataChange} = useDataChanged();

function handleAction(actionName, _args = {}) {
_galleyActionsFns.handleAction(
actionName,
{
..._args,
submission: props.submission,
publication: props.publication,
},
() => {
triggerDataChange();
},
);
}
return {
galleys,
itemActions,
bottomActions,
_galleyActionsFns,
handleAction,
};
},
);
Loading

0 comments on commit 32e6455

Please sign in to comment.