feat: more flexible and responsive tables (#2546)

* Refactors summer-school data table and fixes width issue

* Refactors india-week-of-women-in-quantum data table

* Makes component in TableRowElement optional

* Refactors physics-of-computation data table

* Refactors seminar-series data tables

* Cleans code
This commit is contained in:
Yaiza 2022-04-29 18:05:56 +02:00 committed by GitHub
parent b1736689cd
commit d995e515e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 48 deletions

View File

@ -5,19 +5,7 @@
:sortable="false" :sortable="false"
> >
<template slot="data"> <template slot="data">
<cv-data-table-row v-for="(row, rowIndex) in elements" :key="`${rowIndex}`"> <slot />
<cv-data-table-cell v-for="({ component, styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<AppCta v-if="isAppCtaComponent(component)" kind="ghost" v-bind="data" :style="styles" />
<!-- eslint-disable vue/no-v-html -->
<component
:is="component"
v-else
:style="styles"
v-html="data"
/>
<!-- eslint-enable -->
</cv-data-table-cell>
</cv-data-table-row>
</template> </template>
</cv-data-table> </cv-data-table>
</template> </template>
@ -28,25 +16,21 @@ import { Component, Prop } from 'vue-property-decorator'
import { GeneralLink } from '~/constants/appLinks' import { GeneralLink } from '~/constants/appLinks'
export interface TableRowElement { export interface TableRowElement {
component: string, component?: string,
styles: string, styles: string,
data: string | GeneralLink, data: string | GeneralLink,
} }
@Component @Component
export default class AppDataTable extends Vue { export default class AppDataTable extends Vue {
@Prop({ type: Array, default: () => [] }) elements!: TableRowElement[]
@Prop({ type: Array, default: () => [] }) columns!: string[] @Prop({ type: Array, default: () => [] }) columns!: string[]
isAppCtaComponent (component: string) : boolean {
return component === 'AppCta'
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.app-data-table { .app-data-table {
overflow-x: scroll; overflow-x: scroll;
max-width: 100%;
} }
</style> </style>

View File

@ -1,7 +1,9 @@
<template> <template>
<section> <section>
<h2 v-text="sectionTitle" /> <h2 v-text="sectionTitle" />
<AppDataTable :columns="dataTableColumns" :elements="dataTableElements" /> <AppDataTable :columns="dataTableColumns">
<slot name="data-table-elements" />
</AppDataTable>
<slot /> <slot />
</section> </section>
</template> </template>

View File

@ -328,22 +328,18 @@ const week2Schedule: dailyAgenda[] = [
const scheduleToTableData = (slot: dailyAgenda) => ([ const scheduleToTableData = (slot: dailyAgenda) => ([
{ {
component: 'span',
styles: 'min-width: 10rem; display: inline-block; font-weight: bold;', styles: 'min-width: 10rem; display: inline-block; font-weight: bold;',
data: slot.day data: slot.day
}, },
{ {
component: 'span',
styles: 'min-width: 10rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 10rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.topic data: slot.topic
}, },
{ {
component: 'span',
styles: 'min-width: 10rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 10rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.speaker data: slot.speaker
}, },
{ {
component: 'span',
styles: 'min-width: 10rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 10rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.format data: slot.format
} }

View File

@ -43,8 +43,18 @@
<AppDataTable <AppDataTable
class="india-week-of-women-in-quantum-page__section" class="india-week-of-women-in-quantum-page__section"
:columns="agendaColumnsDataTable" :columns="agendaColumnsDataTable"
:elements="day.tableData" >
/> <cv-data-table-row v-for="(row, rowIndex) in day.tableData" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<!-- eslint-disable vue/no-v-html -->
<span
:style="styles"
v-html="data"
/>
<!-- eslint-enable -->
</cv-data-table-cell>
</cv-data-table-row>
</AppDataTable>
</cv-tab> </cv-tab>
</cv-tabs> </cv-tabs>
</section> </section>
@ -199,22 +209,18 @@ export default class IndiaWeekOfWomenInQuantumPage extends QiskitPage {
scheduleToTableData = (slot: dailyAgenda) => ([ scheduleToTableData = (slot: dailyAgenda) => ([
{ {
component: 'span',
styles: 'min-width: 10rem; display: inline-block; font-weight: bold;', styles: 'min-width: 10rem; display: inline-block; font-weight: bold;',
data: slot.time data: slot.time
}, },
{ {
component: 'span',
styles: 'min-width: 15rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 15rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.event data: slot.event
}, },
{ {
component: 'span',
styles: 'min-width: 15rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 15rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.speaker data: slot.speaker
}, },
{ {
component: 'span',
styles: 'min-width: 15rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 15rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.affiliation data: slot.affiliation
} }

View File

@ -32,23 +32,51 @@
class="physics-of-computation-page__section" class="physics-of-computation-page__section"
:section-title="morningAgendaSectionTitle" :section-title="morningAgendaSectionTitle"
:data-table-columns="agendaColumnsDataTable" :data-table-columns="agendaColumnsDataTable"
:data-table-elements="morningSessionElementsDataTable"
> >
<template #data-table-elements>
<cv-data-table-row v-for="(row, rowIndex) in morningSessionElementsDataTable" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<!-- eslint-disable vue/no-v-html -->
<span
:style="styles"
v-html="data"
/>
<!-- eslint-enable -->
</cv-data-table-cell>
</cv-data-table-row>
</template>
<AppCta kind="ghost" v-bind="morningSessionAgendaCTA" is-wider /> <AppCta kind="ghost" v-bind="morningSessionAgendaCTA" is-wider />
</AppDataTableSection> </AppDataTableSection>
<AppDataTableSection <AppDataTableSection
class="physics-of-computation-page__section" class="physics-of-computation-page__section"
:section-title="afternoonAgendaSectionTitle" :section-title="afternoonAgendaSectionTitle"
:data-table-columns="agendaColumnsDataTable" :data-table-columns="agendaColumnsDataTable"
:data-table-elements="afternoonSessionElementsDataTable"
> >
<template #data-table-elements>
<cv-data-table-row v-for="(row, rowIndex) in afternoonSessionElementsDataTable" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<span :style="styles">{{ data }}</span>
</cv-data-table-cell>
</cv-data-table-row>
</template>
<AppCta kind="ghost" v-bind="afternoonSessionAgendaCTA" is-wider /> <AppCta kind="ghost" v-bind="afternoonSessionAgendaCTA" is-wider />
</AppDataTableSection> </AppDataTableSection>
<section class="physics-of-computation-page__section"> <section class="physics-of-computation-page__section">
<h3 class="copy__subtitle"> <h3 class="copy__subtitle">
* Parallel tracks (times listed are approximate and subject to change) * Parallel tracks (times listed are approximate and subject to change)
</h3> </h3>
<AppDataTable :columns="agendaTracksColumnsDataTable" :elements="afternoonSessionByTrackElementsDataTable" /> <AppDataTable :columns="agendaTracksColumnsDataTable">
<cv-data-table-row v-for="(row, rowIndex) in afternoonSessionByTrackElementsDataTable" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<!-- eslint-disable vue/no-v-html -->
<span
:style="styles"
v-html="data"
/>
<!-- eslint-enable -->
</cv-data-table-cell>
</cv-data-table-row>
</AppDataTable>
</section> </section>
<AppHelpfulResourcesSection <AppHelpfulResourcesSection
class="physics-of-computation-page__section" class="physics-of-computation-page__section"
@ -361,12 +389,10 @@ export default class PhysicsOfComputationPage extends QiskitPage {
getDataTableElements (agenda: AgendaSlot[]) : TableRowElement[][] { getDataTableElements (agenda: AgendaSlot[]) : TableRowElement[][] {
return agenda.map(slot => ([ return agenda.map(slot => ([
{ {
component: 'span',
styles: 'min-width: 5rem; display: inline-block; font-weight: bold;', styles: 'min-width: 5rem; display: inline-block; font-weight: bold;',
data: slot.time data: slot.time
}, },
{ {
component: 'span',
styles: 'min-width: 20rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'min-width: 20rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.event data: slot.event
} }
@ -376,17 +402,14 @@ export default class PhysicsOfComputationPage extends QiskitPage {
getDataTableElementsByTrack (agenda: AgendaSlotByTrack[]) : TableRowElement[][] { getDataTableElementsByTrack (agenda: AgendaSlotByTrack[]) : TableRowElement[][] {
return agenda.map(slot => ([ return agenda.map(slot => ([
{ {
component: 'span',
styles: 'min-width: 5rem; display: inline-block; font-weight: bold;', styles: 'min-width: 5rem; display: inline-block; font-weight: bold;',
data: slot.time data: slot.time
}, },
{ {
component: 'span',
styles: 'width: 25rem; min-width: 20rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'width: 25rem; min-width: 20rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.track1 data: slot.track1
}, },
{ {
component: 'span',
styles: 'width: 25rem; min-width: 20rem; display: inline-block; padding-top: 8px; padding-bottom: 8px', styles: 'width: 25rem; min-width: 20rem; display: inline-block; padding-top: 8px; padding-bottom: 8px',
data: slot.track2 data: slot.track2
} }

View File

@ -31,14 +31,29 @@
class="seminar-series-page__section" class="seminar-series-page__section"
:section-title="upcomingEventsSectionTitle" :section-title="upcomingEventsSectionTitle"
:data-table-columns="seminarSeriesDataTableColumns" :data-table-columns="seminarSeriesDataTableColumns"
:data-table-elements="upcomingEventsDataTable" >
/> <template #data-table-elements>
<cv-data-table-row v-for="(row, rowIndex) in upcomingEventsDataTable" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({component, styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<AppCta v-if="isAppCtaComponent(component)" kind="ghost" v-bind="data" :style="styles" />
<span v-else :style="styles">{{ data }}</span>
</cv-data-table-cell>
</cv-data-table-row>
</template>
</AppDataTableSection>
<AppDataTableSection <AppDataTableSection
class="seminar-series-page__section" class="seminar-series-page__section"
:section-title="pastEventsSectionTitle" :section-title="pastEventsSectionTitle"
:data-table-columns="seminarSeriesDataTableColumns" :data-table-columns="seminarSeriesDataTableColumns"
:data-table-elements="pastEventsDataTable"
> >
<template #data-table-elements>
<cv-data-table-row v-for="(row, rowIndex) in pastEventsDataTable" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({component, styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<AppCta v-if="isAppCtaComponent(component)" kind="ghost" v-bind="data" :style="styles" />
<span v-else :style="styles">{{ data }}</span>
</cv-data-table-cell>
</cv-data-table-row>
</template>
<AppCta <AppCta
class="seminar-series-page__past-events-cta" class="seminar-series-page__past-events-cta"
kind="ghost" kind="ghost"
@ -204,25 +219,25 @@ export default class SeminarSeriesPage extends QiskitPage {
} }
] ]
isAppCtaComponent (component: string) : boolean {
return component === 'AppCta'
}
dataPerRow (events: SeminarSeriesEvent[], eventsSection: string) : TableRowElement[][] { dataPerRow (events: SeminarSeriesEvent[], eventsSection: string) : TableRowElement[][] {
return events.map(event => ([ return events.map(event => ([
{ {
component: 'span',
styles: 'min-width: 9rem; display: inline-block;', styles: 'min-width: 9rem; display: inline-block;',
data: event.speaker data: event.speaker
}, },
{ {
component: 'span',
styles: 'min-width: 9rem; display: inline-block;', styles: 'min-width: 9rem; display: inline-block;',
data: event.institution data: event.institution
}, },
{ {
component: 'span',
styles: 'min-width: 19rem; display: inline-block;', styles: 'min-width: 19rem; display: inline-block;',
data: event.title data: event.title
}, },
{ {
component: 'span',
styles: 'min-width: 8rem; display: inline-block;', styles: 'min-width: 8rem; display: inline-block;',
data: event.date data: event.date
}, },

View File

@ -30,7 +30,8 @@
</EventCard> </EventCard>
</template> </template>
</AppPageHeaderWithCard> </AppPageHeaderWithCard>
<div class="bx--grid">
<div class="bx--grid summer-school-page__container">
<AppMosaicSection <AppMosaicSection
class="summer-school-page__section" class="summer-school-page__section"
:title="mosaicData.title" :title="mosaicData.title"
@ -49,8 +50,13 @@
<AppDataTable <AppDataTable
class="summer-school-page__section" class="summer-school-page__section"
:columns="agendaColumnsDataTable" :columns="agendaColumnsDataTable"
:elements="week.tableData" >
/> <cv-data-table-row v-for="(row, rowIndex) in week.tableData" :key="`${rowIndex}`">
<cv-data-table-cell v-for="({styles, data}, elementIndex) in row" :key="`${elementIndex}`">
<span :style="styles">{{ data }}</span>
</cv-data-table-cell>
</cv-data-table-row>
</AppDataTable>
</cv-tab> </cv-tab>
</cv-tabs> </cv-tabs>
</section> </section>
@ -152,6 +158,10 @@ export default class SummerSchoolPage extends QiskitPage {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
&__container {
max-width: 100%;
}
&__section { &__section {
margin-top: $spacing-10; margin-top: $spacing-10;
margin-bottom: $spacing-07; margin-bottom: $spacing-07;