Skip to content

Commit 209cc43

Browse files
pkp/pkp-lib#9453 Provide file listing and layout for side modal (#318)
* pkp/pkp-lib#9453 Provide file listing and layout for side modal * pkp/pkp-lib#9453 Fix syntax error * pkp/pkp-lib@9453 Tweak SideModal story height for better snapshot * pkp/pkp-lib#9453 Refine spacing
1 parent 76cccda commit 209cc43

8 files changed

+216
-1
lines changed

src/components/File/File.stories.js

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ export default {
1515
}),
1616
};
1717

18+
export const WithLink = {
19+
args: {
20+
documentType: 'word',
21+
fileId: '35',
22+
name: 'ccorino-disclosure-statement.docx',
23+
url: 'https://www.google.com',
24+
},
25+
};
26+
1827
export const Word = {
1928
args: {
2029
documentType: 'word',

src/components/File/File.vue

+15-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
<span v-if="fileId" class="file__id">
55
{{ fileId }}
66
</span>
7-
{{ name }}
7+
<span class="ms-1">
8+
<a v-if="url" class="underline" href="url" target="_blank">{{ name }}</a>
9+
<template v-else>
10+
{{ name }}
11+
</template>
12+
</span>
813
</div>
914
</template>
1015

@@ -30,6 +35,15 @@ export default {
3035
type: String,
3136
required: true,
3237
},
38+
39+
/** Optional. If the file should be be url to download file */
40+
url: {
41+
type: String,
42+
required: false,
43+
default() {
44+
return '';
45+
},
46+
},
3347
},
3448
computed: {
3549
/**

src/components/ListPanel/ListPanel.vue

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<pkp-header>
66
<component :is="headingLevel">{{ title }}</component>
77
</pkp-header>
8+
<div v-if="description">{{ description }}</div>
89
</slot>
910
</div>
1011
<div class="listPanel__body">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {Primary, Controls, Stories, Meta, ArgTypes} from '@storybook/blocks';
2+
3+
import * as ListingFilesListPanelStories from './ListingFilesListPanel.stories.js';
4+
5+
<Meta of={ListingFilesListPanelStories} />
6+
7+
# ListingFileList
8+
9+
## Usage
10+
11+
Used for read-only file listing.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import ListingFilesListPanel from './ListingFilesListPanel.vue';
2+
import SubmissionFilesMock from '@/mocks/submissionFiles';
3+
4+
export default {
5+
title: 'ListPanel/ListingFilesListPanel',
6+
component: ListingFilesListPanel,
7+
};
8+
9+
export const Base = {
10+
render: (args) => ({
11+
components: {ListingFilesListPanel},
12+
setup() {
13+
return {args};
14+
},
15+
template: `
16+
<ListingFilesListPanel
17+
v-bind="args"
18+
/>
19+
`,
20+
}),
21+
22+
args: {
23+
title: 'Attachments',
24+
description: 'These files were sent to you for review',
25+
items: [...SubmissionFilesMock],
26+
},
27+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<ListPanel :title="title" :description="description" :items="files">
3+
<template #item="{item}">
4+
<div class="flex items-center">
5+
<div class="me-2 flex-grow truncate">
6+
<File
7+
:name="localize(item.name)"
8+
:document-type="item.documentType"
9+
:url="item.url"
10+
/>
11+
</div>
12+
<div class="flex-shrink-0">
13+
<Badge
14+
v-if="item.genreName"
15+
:is-primary="!item.genreIsDependent && !item.genreIsSupplementary"
16+
>
17+
{{ localize(item.genreName) }}
18+
</Badge>
19+
</div>
20+
</div>
21+
</template>
22+
</ListPanel>
23+
</template>
24+
25+
<script setup>
26+
import {defineProps} from 'vue';
27+
28+
defineProps({
29+
/** The title to display for this `ListPanel`. */
30+
title: {
31+
type: String,
32+
default() {
33+
return '';
34+
},
35+
},
36+
description: {
37+
type: String,
38+
default() {
39+
return '';
40+
},
41+
},
42+
files: {type: Array, required: false, default: () => []},
43+
});
44+
45+
import ListPanel from '@/components/ListPanel/ListPanel.vue';
46+
import File from '@/components/File/File.vue';
47+
import Badge from '@/components/Badge/Badge.vue';
48+
</script>

src/components/Modal/SideModal.stories.js

+88
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {within, userEvent} from '@storybook/testing-library';
22
import {ref} from 'vue';
33
import SideModal from './SideModal.vue';
44
import SideModalBody from './SideModalBody.vue';
5+
import SideModalLayout2Columns from './SideModalLayout2Columns.vue';
56
import PkpForm from '@/components/Form/Form.vue';
67
import cloneDeep from 'clone-deep';
78
import FormMock from '@/docs/components/Form/helpers/form-announcement';
@@ -71,6 +72,93 @@ export const Base = {
7172
},
7273
};
7374

75+
export const TwoColumnsLayout = {
76+
render: (args) => ({
77+
components: {SideModal, SideModalBody, SideModalLayout2Columns},
78+
setup() {
79+
const isModalOpened = ref(false);
80+
function closeModal() {
81+
isModalOpened.value = false;
82+
}
83+
const metadata = [
84+
{name: 'Type', value: 'Article'},
85+
{
86+
name: 'Abstract',
87+
value:
88+
'Nam id quam mollis, porta dui vel, accumsan sem. Sed commodo felis tristique justo pulvinar lacinia. Etiam pulvinar tortor et dui malesuada fringilla. Nullam leo risus, luctus ut sem ut, dignissim luctus quam. Nulla vel varius urna. Cras eget odio tellus. Proin eu nisi vehicula nulla laculis lobortis.',
89+
},
90+
];
91+
const generalInformation = [
92+
{name: 'Editors request', value: 'dd-mm-yyyy'},
93+
{
94+
name: 'Response due date',
95+
value: 'dd-mm-yyy',
96+
},
97+
];
98+
99+
return {isModalOpened, closeModal, metadata, generalInformation};
100+
},
101+
template: `
102+
<PkpButton @click="isModalOpened = true">
103+
Open Modal
104+
</PkpButton>
105+
<SideModal
106+
:open="isModalOpened"
107+
@close="closeModal"
108+
>
109+
<SideModalBody>
110+
<template #pre-title>970</template>
111+
<template #title><span class="underline">Round 1 Review submitted by you for</span></template>
112+
<template #description>
113+
Is blended e-learning as measured by an achievement test and self-assessment better than traditional classroom learning for vocational high school students?
114+
</template>
115+
116+
<SideModalLayout2Columns>
117+
<template #left>
118+
<p>
119+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
120+
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
121+
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
122+
aliquip ex ea commodo consequat.
123+
</p>
124+
</template>
125+
<template #right1>
126+
<div class="text-xl-bold">Article Metadata</div>
127+
<div v-for="item in metadata" class="mt-4">
128+
<div class="text-lg-bold">{{ item.name }}:</div>
129+
<div class="text-base-normal mt-1">{{item.value}}</div>
130+
</div>
131+
132+
</template>
133+
<template #right2>
134+
<div class="text-xl-bold">General Inforation</div>
135+
<div v-for="item in generalInformation" class="mt-4">
136+
<div class="text-lg-bold">{{ item.name }}:</div>
137+
<div class="text-base-normal mt-1">{{item.value}}</div>
138+
</div>
139+
</template>
140+
141+
142+
</SideModalLayout2Columns>
143+
</SideModalBody>
144+
</SideModal>
145+
`,
146+
}),
147+
decorators: [
148+
() => ({
149+
template: '<div style="height: 700px"><story/></div>',
150+
}),
151+
],
152+
153+
args: {},
154+
play: async ({canvasElement}) => {
155+
// Assigns canvas to the component root element
156+
const canvas = within(canvasElement);
157+
const user = userEvent.setup();
158+
159+
await user.click(canvas.getByText('Open Modal'));
160+
},
161+
};
74162
export const WithForm = {
75163
render: (args) => ({
76164
components: {SideModal, SideModalBody, PkpForm},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<template>
2+
<div class="border-ligh flex h-full w-full border-r border-t border-light">
3+
<div class="w-3/5 border-r border-light p-4">
4+
<div class="bg-lightest p-5">
5+
<slot name="left"></slot>
6+
</div>
7+
</div>
8+
<div class="w-2/5">
9+
<div class="border-b border-light p-4">
10+
<slot name="right1"></slot>
11+
</div>
12+
<div class="p-4">
13+
<slot name="right2"></slot>
14+
</div>
15+
</div>
16+
</div>
17+
</template>

0 commit comments

Comments
 (0)