Skip to content

Commit

Permalink
pkp/pkp-lib#9890 Handle SideMenu state through useSideMenu api (#394)
Browse files Browse the repository at this point in the history
* pkp/pkp-lib#9890 Expose sideMenuProps from useSideMenu composable api and let the parent component to handle SideMenu state

* pkp/pkp-lib#9890 Add onUpdate:expandedKeys to bind with SideMenu component

* pkp/pkp-lib#9890 Add onUpdate:activeItemKey to bind with SideMenu component

* pkp/pkp-lib#9890 Add Workflow and Publication icons

* pkp/pkp-lib#9890 Use computed instead of reactive when defining items for SideMenu component

* pkp/pkp-lib#9890 Update SideMenu story - cleanup console.log
  • Loading branch information
blesildaramirez authored Aug 20, 2024
1 parent 83820ab commit 6acdbc9
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 78 deletions.
2 changes: 2 additions & 0 deletions src/components/Icon/Icon.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export const iconGallery = {
'Orcid',
'Overdue',
'Payment',
'Publication',
'ReadRecommendation',
'ReviewAssignments',
'ReviewSent',
Expand All @@ -116,6 +117,7 @@ export const iconGallery = {
'Url',
'UsefulTips',
'View',
'Workflow',
],
},
};
4 changes: 4 additions & 0 deletions src/components/Icon/Icon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import OpenReview from './icons/OpenReview.vue';
import Orcid from './icons/Orcid.vue';
import Overdue from './icons/Overdue.vue';
import Payment from './icons/Payment.vue';
import Publication from './icons/Publication.vue';
import ReadRecommendation from './icons/ReadRecommendation.vue';
import ReviewAssignments from './icons/ReviewAssignments.vue';
import ReviewRequestDeclined from './icons/ReviewRequestDeclined.vue';
Expand All @@ -95,6 +96,7 @@ import Underline from './icons/Underline.vue';
import Url from './icons/Url.vue';
import UsefulTips from './icons/UsefulTips.vue';
import View from './icons/View.vue';
import Workflow from './icons/Workflow.vue';
const svgIcons = {
Announcements,
Expand Down Expand Up @@ -143,6 +145,7 @@ const svgIcons = {
Orcid,
Overdue,
Payment,
Publication,
ReadRecommendation,
ReviewAssignments,
ReviewRequestDeclined,
Expand All @@ -156,6 +159,7 @@ const svgIcons = {
Url,
UsefulTips,
View,
Workflow,
};
const props = defineProps({
Expand Down
7 changes: 1 addition & 6 deletions src/components/Icon/icons/Dropup.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
<template>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 8L19 16H5L12 8Z"
fill="currentColor"
/>
<path d="M21 16L12 7L3 16L21 16Z" fill="currentColor" />
</svg>
</template>
39 changes: 39 additions & 0 deletions src/components/Icon/icons/Publication.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template>
<svg viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_385_53)">
<path
d="M18 5.20512H15.1796V3.99075H7.49661L6.58583 1.56201H0V16.438H15.1796V16.173L18 5.20512ZM17.2167 5.81231L15.1796 13.7349V5.81231H17.2167ZM0.607185 2.1692H6.16505L7.07583 4.59794H14.5724V5.20512V15.8309H0.607185V2.1692Z"
fill="currentColor"
/>
<path
d="M1.82155 14.6165H9.10777V10.0626H1.82155V14.6165ZM2.42873 10.6698H8.50058V14.0093H2.42873V10.6698Z"
fill="currentColor"
/>
<path
d="M6.07184 12.7949H3.33951C3.17163 12.7949 3.03592 12.9306 3.03592 13.0985C3.03592 13.2664 3.17163 13.4021 3.33951 13.4021H6.07184C6.23973 13.4021 6.37544 13.2664 6.37544 13.0985C6.37544 12.9306 6.23973 12.7949 6.07184 12.7949Z"
fill="currentColor"
/>
<path
d="M3.33951 11.8842H4.55388C4.72177 11.8842 4.85747 11.7485 4.85747 11.5806C4.85747 11.4127 4.72177 11.277 4.55388 11.277H3.33951C3.17163 11.277 3.03592 11.4127 3.03592 11.5806C3.03592 11.7485 3.17163 11.8842 3.33951 11.8842Z"
fill="currentColor"
/>
<path
d="M7.58981 11.277H6.98262C6.81474 11.277 6.67903 11.4127 6.67903 11.5806C6.67903 11.7485 6.81474 11.8842 6.98262 11.8842H7.58981C7.7577 11.8842 7.8934 11.7485 7.8934 11.5806C7.8934 11.4127 7.7577 11.277 7.58981 11.277Z"
fill="currentColor"
/>
<path
d="M7.07066 12.883C7.01571 12.9403 6.98262 13.0162 6.98262 13.0985C6.98262 13.1805 7.01571 13.2564 7.07066 13.311C7.12804 13.3684 7.20394 13.4021 7.28621 13.4021C7.36515 13.4021 7.44408 13.3687 7.50176 13.3141C7.55641 13.2564 7.58981 13.1774 7.58981 13.0985C7.58981 13.0196 7.55641 12.9403 7.50176 12.883C7.38943 12.7706 7.18299 12.7706 7.07066 12.883Z"
fill="currentColor"
/>
<path
d="M5.76825 11.8842C5.84719 11.8842 5.92612 11.8508 5.9838 11.7961C6.03845 11.7384 6.07185 11.6595 6.07185 11.5806C6.07185 11.4983 6.03845 11.4224 5.9838 11.365C5.87147 11.2527 5.66169 11.2527 5.5527 11.365C5.49775 11.4224 5.46466 11.5016 5.46466 11.5806C5.46466 11.6595 5.49775 11.7384 5.5527 11.7961C5.61008 11.8508 5.68932 11.8842 5.76825 11.8842Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_385_53">
<rect width="18" height="18" fill="white" />
</clipPath>
</defs>
</svg>
</template>
15 changes: 15 additions & 0 deletions src/components/Icon/icons/Workflow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<svg viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_385_54)">
<path
d="M5.625 11.625H1.875C1.67609 11.625 1.48532 11.704 1.34467 11.8447C1.20402 11.9853 1.125 12.1761 1.125 12.375V16.125C1.125 16.3239 1.20402 16.5147 1.34467 16.6553C1.48532 16.796 1.67609 16.875 1.875 16.875H5.625C5.82391 16.875 6.01468 16.796 6.15533 16.6553C6.29598 16.5147 6.375 16.3239 6.375 16.125V15H9C9.19891 15 9.38968 14.921 9.53033 14.7803C9.67098 14.6397 9.75 14.4489 9.75 14.25C9.75 14.0511 9.67098 13.8603 9.53033 13.7197C9.38968 13.579 9.19891 13.5 9 13.5H6.375V12.375C6.375 12.1761 6.29598 11.9853 6.15533 11.8447C6.01468 11.704 5.82391 11.625 5.625 11.625ZM4.875 15.375H2.625V13.125H4.875V15.375ZM3 6.64351V9.75001C3 9.94892 3.07902 10.1397 3.21967 10.2803C3.36032 10.421 3.55109 10.5 3.75 10.5C3.94891 10.5 4.13968 10.421 4.28033 10.2803C4.42098 10.1397 4.5 9.94892 4.5 9.75001V6.64351C5.20699 6.46096 5.82314 6.02684 6.23295 5.4225C6.64276 4.81817 6.81809 4.08512 6.72609 3.36076C6.63408 2.6364 6.28105 1.97046 5.73317 1.48777C5.18529 1.00507 4.48018 0.73877 3.75 0.73877C3.01982 0.73877 2.3147 1.00507 1.76683 1.48777C1.21895 1.97046 0.865916 2.6364 0.773911 3.36076C0.681905 4.08512 0.857239 4.81817 1.26705 5.4225C1.67686 6.02684 2.29301 6.46096 3 6.64351ZM3.75 2.25001C4.04667 2.25001 4.33668 2.33798 4.58335 2.5028C4.83003 2.66762 5.02229 2.90189 5.13582 3.17598C5.24935 3.45007 5.27906 3.75167 5.22118 4.04264C5.1633 4.33361 5.02044 4.60089 4.81066 4.81067C4.60088 5.02045 4.33361 5.16331 4.04263 5.22118C3.75166 5.27906 3.45006 5.24936 3.17597 5.13583C2.90189 5.02229 2.66762 4.83004 2.5028 4.58336C2.33797 4.33669 2.25 4.04668 2.25 3.75001C2.25 3.35218 2.40803 2.97065 2.68934 2.68935C2.97064 2.40804 3.35217 2.25001 3.75 2.25001ZM15 11.3565V9.00001C15 8.8011 14.921 8.61033 14.7803 8.46968C14.6397 8.32902 14.4489 8.25001 14.25 8.25001C14.0511 8.25001 13.8603 8.32902 13.7197 8.46968C13.579 8.61033 13.5 8.8011 13.5 9.00001V11.3565C12.793 11.5391 12.1769 11.9732 11.767 12.5775C11.3572 13.1818 11.1819 13.9149 11.2739 14.6393C11.3659 15.3636 11.7189 16.0296 12.2668 16.5122C12.8147 16.9949 13.5198 17.2612 14.25 17.2612C14.9802 17.2612 15.6853 16.9949 16.2332 16.5122C16.7811 16.0296 17.1341 15.3636 17.2261 14.6393C17.3181 13.9149 17.1428 13.1818 16.733 12.5775C16.3231 11.9732 15.707 11.5391 15 11.3565ZM14.25 15.75C13.9533 15.75 13.6633 15.662 13.4166 15.4972C13.17 15.3324 12.9777 15.0981 12.8642 14.824C12.7506 14.5499 12.7209 14.2483 12.7788 13.9574C12.8367 13.6664 12.9796 13.3991 13.1893 13.1893C13.3991 12.9796 13.6664 12.8367 13.9574 12.7788C14.2483 12.721 14.5499 12.7507 14.824 12.8642C15.0981 12.9777 15.3324 13.17 15.4972 13.4167C15.662 13.6633 15.75 13.9533 15.75 14.25C15.75 14.6478 15.592 15.0294 15.3107 15.3107C15.0294 15.592 14.6478 15.75 14.25 15.75ZM12.375 6.37501H16.125C16.3239 6.37501 16.5147 6.29599 16.6553 6.15534C16.796 6.01468 16.875 5.82392 16.875 5.62501V1.87501C16.875 1.67609 16.796 1.48533 16.6553 1.34468C16.5147 1.20402 16.3239 1.12501 16.125 1.12501H12.375C12.1761 1.12501 11.9853 1.20402 11.8447 1.34468C11.704 1.48533 11.625 1.67609 11.625 1.87501V3.00001H9C8.80109 3.00001 8.61032 3.07902 8.46967 3.21968C8.32902 3.36033 8.25 3.55109 8.25 3.75001C8.25 3.94892 8.32902 4.13968 8.46967 4.28034C8.61032 4.42099 8.80109 4.50001 9 4.50001H11.625V5.62501C11.625 5.82392 11.704 6.01468 11.8447 6.15534C11.9853 6.29599 12.1761 6.37501 12.375 6.37501ZM13.125 2.62501H15.375V4.87501H13.125V2.62501Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_385_54">
<rect width="18" height="18" fill="currentColor" />
</clipPath>
</defs>
</svg>
</template>
12 changes: 6 additions & 6 deletions src/components/Modal/SideModal.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,14 +427,14 @@ const SideModalWithSideMenu = {
},
];

const {activeItemKey, setExpandedKeys} = useSideMenu('review_round_1');
const expandedKeys = setExpandedKeys(['workflow', 'review', 'publication']);
const {sideMenuProps, setExpandedKeys} = useSideMenu('review_round_1');
setExpandedKeys(['workflow', 'review', 'publication']);

const items = [
{
label: 'Workflow',
key: 'workflow',
icon: 'Dashboard',
icon: 'Workflow',
items: [
{
label: 'Submission',
Expand Down Expand Up @@ -474,7 +474,7 @@ const SideModalWithSideMenu = {
{
label: 'Publication',
key: 'publication',
icon: 'MySubmissions',
icon: 'Publication',
isOpen: true,
items: [
{
Expand Down Expand Up @@ -515,7 +515,7 @@ const SideModalWithSideMenu = {
],
},
];
return {metadata, generalInformation, items, activeItemKey, expandedKeys};
return {metadata, generalInformation, items, sideMenuProps};
},
template: `
<SideModalBody>
Expand All @@ -528,7 +528,7 @@ const SideModalWithSideMenu = {
<SideModalLayout2Columns>
<template #left>
<div class="flex">
<SideMenu :items="items" v-model:activeItemKey="activeItemKey" :expanded-keys="expandedKeys"></SideMenu>
<SideMenu :items="items" v-bind="sideMenuProps"></SideMenu>
<p class="px-5">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
Expand Down
46 changes: 16 additions & 30 deletions src/components/SideMenu/SideMenu.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,28 @@ export default {
render: (args) => ({
components: {SideMenu},
setup() {
const {activeItemKey, setExpandedKeys} = useSideMenu('action_required');
const {sideMenuProps, setExpandedKeys, setActiveItemKey} =
useSideMenu('action_required');

args.expandedKeys = setExpandedKeys([
'action_required',
'editorial_dashboard',
]);
setExpandedKeys(['action_required', 'editorial_dashboard']);

function startNewSubmission(actionArgs) {
console.log('startNewSubmission clicked', actionArgs);
}

function otherAction(actionArgs) {
console.log('otherAction clicked', actionArgs);
setActiveItemKey(actionArgs.key);
}

function handleActions(action, actionArgs) {
switch (action) {
case 'startNewSubmission':
startNewSubmission(actionArgs);
break;
case 'otherAction':
otherAction(actionArgs);
break;
default:
console.error(`No handler for action: ${action}`);
}
}
return {args, activeItemKey, handleActions};
return {args, sideMenuProps, handleActions};
},
template:
'<SideMenu v-bind="args" @action="handleActions" v-model:activeItemKey="activeItemKey" />',
'<SideMenu v-bind="{...args, ...sideMenuProps}" @action="handleActions" />',
}),
};

Expand Down Expand Up @@ -174,7 +165,6 @@ export const Default = {
{
label: 'Start a New Submission',
key: 'start_a_new_submission',
link: '#',
action: 'startNewSubmission',
actionArgs: {
param1: 1,
Expand Down Expand Up @@ -229,14 +219,12 @@ export const WithColorStripe = {
setup() {
const activeItemKey = 'submission_stages';
const expandedKeys = ['submission_stages'];
const {setExpandedKeys} = useSideMenu(activeItemKey);
const {sideMenuProps, setExpandedKeys} = useSideMenu(activeItemKey);

args.activeItemKey = activeItemKey;
args.expandedKeys = setExpandedKeys(expandedKeys);
return {args};
setExpandedKeys(expandedKeys);
return {args, sideMenuProps};
},
template:
'<SideMenu v-bind="args" v-model:activeItemKey="args.activeItemKey" />',
template: '<SideMenu v-bind="{...args, ...sideMenuProps}" />',
}),
args: {
items: [
Expand Down Expand Up @@ -304,21 +292,19 @@ export const ExpandedMenu = {
setup() {
const activeItemKey = 'review_round_1';
const expandedKeys = ['workflow', 'review', 'publication'];
const {setExpandedKeys} = useSideMenu(activeItemKey);
const {sideMenuProps, setExpandedKeys} = useSideMenu(activeItemKey);

args.activeItemKey = activeItemKey;
args.expandedKeys = setExpandedKeys(expandedKeys);
return {args};
setExpandedKeys(expandedKeys);
return {args, sideMenuProps};
},
template:
'<SideMenu v-bind="args" v-model:activeItemKey="args.activeItemKey" />',
template: '<SideMenu v-bind="{...args, ...sideMenuProps}" />',
}),
args: {
items: [
{
label: 'Workflow',
key: 'workflow',
icon: 'Dashboard',
icon: 'Workflow',
items: [
{
label: 'Submission',
Expand Down Expand Up @@ -358,7 +344,7 @@ export const ExpandedMenu = {
{
label: 'Publication',
key: 'publication',
icon: 'MySubmissions',
icon: 'Publication',
isOpen: true,
items: [
{
Expand Down
38 changes: 14 additions & 24 deletions src/components/SideMenu/SideMenu.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<template>
<PanelMenu
v-model:expandedKeys="localExpandedKeys"
:expanded-keys="expandedKeys"
:model="items"
:pt="navigationStyling"
class="w-max min-w-60 overflow-y-auto border-e border-s border-light bg-secondary"
@update:expanded-keys="(...args) => emit('update:expandedKeys', ...args)"
>
<template #item="{item, active, hasSubmenu}">
<a
Expand Down Expand Up @@ -38,7 +39,7 @@
import PanelMenu from 'primevue/panelmenu';
import Icon from '../Icon/Icon.vue';
import Badge from '../Badge/Badge.vue';
import {ref, reactive, watch} from 'vue';
import {computed} from 'vue';
const props = defineProps({
/**
Expand Down Expand Up @@ -80,26 +81,12 @@ const props = defineProps({
const emit = defineEmits([
/** When a panel menu item's "action" is clicked */
'action',
/** When the localActiveItemKey value changes */
/** When the item with link is clicked */
'update:activeItemKey',
/** When the expandedKeys gets updated by the PanelMenu */
'update:expandedKeys',
]);
const localActiveItemKey = ref(props.activeItemKey);
watch(
() => props.activeItemKey,
(newActiveItemKey) => {
localActiveItemKey.value = newActiveItemKey;
},
);
const localExpandedKeys = ref({...props.expandedKeys});
watch(
() => props.expandedKeys,
(newExpandedKeys) => {
localExpandedKeys.value = {...newExpandedKeys};
},
);
// Maps the level attributes which are necessary to render the nested menu
function mapItems(_items, level = 1) {
const result = [];
Expand All @@ -120,7 +107,7 @@ function mapItems(_items, level = 1) {
return result;
}
const items = reactive(mapItems(props.items));
const items = computed(() => mapItems(props.items));
const navigationStyling = {
headerContent: () => {
Expand Down Expand Up @@ -148,16 +135,18 @@ const navigationStyling = {
};
function handleClick(item) {
localActiveItemKey.value = item.key;
emit('update:activeItemKey', localActiveItemKey.value);
if (item.action) {
emit('action', item.action, {...item.actionArgs, key: item.key});
}
if (item.link && !item.items) {
emit('update:activeItemKey', item.key);
}
}
function isActive(item) {
return localActiveItemKey.value && item?.key === localActiveItemKey.value;
const currentActiveKey = props.activeItemKey;
return currentActiveKey && currentActiveKey === item?.key;
}
function getButtonStyles(item) {
Expand Down Expand Up @@ -198,6 +187,7 @@ function getButtonStyles(item) {
<style lang="less" scoped>
@import '../../styles/_import';
/* Override legacy styles for: a:hover, a:focus, where the color is being set to #008acb */
a.text-on-dark:hover,
a.text-on-dark:focus,
a.text-on-dark:active {
Expand Down
11 changes: 2 additions & 9 deletions src/components/SideNav/SideNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
class="sticky top-12 flex h-[calc(100vh-3rem)] flex-none"
:aria-label="ariaLabel"
>
<SideMenu
v-model:activeItemKey="activeItemKey"
:items="items"
:expanded-keys="expandedKeys"
></SideMenu>
<SideMenu v-bind="sideMenuProps" :items="items"></SideMenu>
</nav>
</template>

Expand Down Expand Up @@ -95,8 +91,5 @@ function getExpandedKeys(items) {
return _expandedKeys;
}
const {expandedKeys, activeItemKey} = useSideMenu(
currentActiveKey,
getExpandedKeys(items),
);
const {sideMenuProps} = useSideMenu(currentActiveKey, getExpandedKeys(items));
</script>
Loading

0 comments on commit 6acdbc9

Please sign in to comment.