-
Notifications
You must be signed in to change notification settings - Fork 256
[Remove Vuetify from Studio] Side panel (container only) in Content Library #5555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Changes from all commits
c468d0a
0b61a60
f408184
16d13da
ee03f49
fca8fb0
e12e747
c1401a2
d22f575
9d496a1
ed400e7
d5e760a
33fb8b4
905c9d0
349e963
783275b
472ed4c
046ee25
95ffa9c
8c0c628
049383c
623e582
68369af
1e37e8e
d3edaa5
470b5c4
17d0758
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,233 +1,89 @@ | ||
| <template> | ||
|
|
||
| <div> | ||
| <div class="catalog-filters-wrapper"> | ||
| <!-- Mobile: Filter button that opens SidePanelModal --> | ||
| <KButton | ||
| v-if="$vuetify.breakpoint.xsOnly" | ||
| class="drawer-btn" | ||
| :text="$tr('searchText')" | ||
| :primary="true" | ||
| appearance="flat-button" | ||
| @click.stop="drawer = true" | ||
| v-if="isMobile" | ||
| class="filter-button-mobile" | ||
| :text="$tr('filterText')" | ||
| appearance="raised-button" | ||
| icon="filter" | ||
| @click="openSidePanel" | ||
| /> | ||
| <CatalogFilterBar /> | ||
| <VNavigationDrawer | ||
| v-model="drawer" | ||
| :permanent="$vuetify.breakpoint.smAndUp" | ||
| app | ||
| disable-route-watcher | ||
| :clipped="$vuetify.breakpoint.smAndUp" | ||
| :right="isRTL" | ||
| > | ||
| <VContainer class="filters pa-3"> | ||
| <VToolbar | ||
| v-if="$vuetify.breakpoint.xsOnly" | ||
| color="transparent" | ||
| flat | ||
| dense | ||
| > | ||
| <VSpacer /> | ||
| <VBtn | ||
| icon | ||
| flat | ||
| style="text-align: right" | ||
| @click="drawer = false" | ||
| > | ||
| <Icon icon="clear" /> | ||
| </VBtn> | ||
| </VToolbar> | ||
|
|
||
| <!-- Keyword search --> | ||
| <VTextField | ||
| v-model="keywordInput" | ||
| color="primary" | ||
| :label="$tr('searchLabel')" | ||
| box | ||
| clearable | ||
| data-test="keywords" | ||
| autofocus | ||
| @input="setKeywords" | ||
| /> | ||
|
|
||
| <!-- Language --> | ||
| <LanguageFilter | ||
| v-model="languages" | ||
| :menu-props="menuProps" | ||
| /> | ||
|
|
||
| <!-- License (attach to self to keep in notranslate class) --> | ||
| <MultiSelect | ||
| v-if="!libraryMode" | ||
| v-model="licenses" | ||
| :items="licenseOptions" | ||
| :label="$tr('licenseLabel')" | ||
| /> | ||
|
|
||
| <!-- Formats (attach to self to keep in notranslate class) --> | ||
| <MultiSelect | ||
| v-model="kinds" | ||
| :items="kindOptions" | ||
| :label="$tr('formatLabel')" | ||
| /> | ||
|
|
||
| <!-- Starred --> | ||
| <Checkbox | ||
| v-if="loggedIn" | ||
| v-model="bookmark" | ||
| :label="$tr('starredLabel')" | ||
| /> | ||
|
|
||
| <!-- Includes --> | ||
| <div class="subheading"> | ||
| {{ $tr('includesLabel') }} | ||
| </div> | ||
|
|
||
| <div :style="{ display: 'flex', alignItems: 'center' }"> | ||
| <Checkbox | ||
| v-model="coach" | ||
| aria-describedby="tooltip-coach" | ||
| :label="$tr('coachLabel')" | ||
| /> | ||
| <HelpTooltip | ||
| :text="$tr('coachDescription')" | ||
| maxWidth="250px" | ||
| tooltipId="tooltip-coach" | ||
| /> | ||
| </div> | ||
| <!-- Desktop/Tablet: Permanent side panel as page section --> | ||
| <aside | ||
| v-if="!isMobile" | ||
| class="filter-panel-desktop" | ||
| :class="{ 'filter-panel-rtl': isRTL }" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like there isn't a css class called |
||
| > | ||
| <CatalogFilterPanelContent /> | ||
| </aside> | ||
|
|
||
| <Checkbox | ||
| v-model="subtitles" | ||
| :label="$tr('subtitlesLabel')" | ||
| /> | ||
| <KRouterLink | ||
| class="qa-link" | ||
| :to="faqLink" | ||
| :text="$tr('frequentlyAskedQuestionsLink')" | ||
| appearance="basic-link" | ||
| iconAfter="openNewTab" | ||
| target="_blank" | ||
| /> | ||
| </VContainer> | ||
| <VFooter | ||
| class="pb-3 pt-2 px-4" | ||
| color="transparent" | ||
| height="100" | ||
| > | ||
| <div> | ||
| <VImg | ||
| height="60" | ||
| width="90" | ||
| class="mb-1 mr-2" | ||
| contain | ||
| :src="require('shared/images/le-logo.svg')" | ||
| /> | ||
| <KExternalLink | ||
| href="https://learningequality.org/" | ||
| :text="$tr('copyright', { year: new Date().getFullYear() })" | ||
| openInNewTab | ||
| /> | ||
| </div> | ||
| </VFooter> | ||
| </VNavigationDrawer> | ||
| <!-- Main content area that includes CatalogFilterBar and the list --> | ||
| <div | ||
| class="main-content-area" | ||
| :class="{ 'with-sidebar': !isMobile }" | ||
| > | ||
| <CatalogFilterBar /> | ||
| <slot></slot> | ||
| </div> | ||
|
Comment on lines
+23
to
+30
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can avoid using To make this layout more flexible, we can use a parent component for the side panel and the main content with |
||
|
|
||
| <!-- Mobile: SidePanelModal for filters (full width) --> | ||
| <SidePanelModal | ||
| v-if="isMobile && showMobilePanel" | ||
| alignment="left" | ||
| fullscreen | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like the |
||
| @closePanel="closeSidePanel" | ||
| > | ||
| <CatalogFilterPanelContent /> | ||
| </SidePanelModal> | ||
| </div> | ||
|
|
||
| </template> | ||
|
|
||
|
|
||
| <script> | ||
| import { mapGetters } from 'vuex'; | ||
| import debounce from 'lodash/debounce'; | ||
| import { RouteNames } from '../../constants'; | ||
| import useKResponsiveWindow from 'kolibri-design-system/lib/composables/useKResponsiveWindow'; | ||
| import CatalogFilterBar from './CatalogFilterBar'; | ||
| import { catalogFilterMixin } from './mixins'; | ||
| import LanguageFilter from './components/LanguageFilter'; | ||
| import MultiSelect from 'shared/views/form/MultiSelect'; | ||
| import { constantsTranslationMixin } from 'shared/mixins'; | ||
| import Checkbox from 'shared/views/form/Checkbox'; | ||
| import HelpTooltip from 'shared/views/HelpTooltip'; | ||
| import { ContentKindsNames } from 'shared/leUtils/ContentKinds'; | ||
| const excludedKinds = new Set([ContentKindsNames.TOPIC, ContentKindsNames.H5P]); | ||
| import CatalogFilterPanelContent from './components/CatalogFilterPanelContent.vue'; | ||
| import SidePanelModal from 'shared/views/SidePanelModal'; | ||
| export default { | ||
| name: 'CatalogFilters', | ||
| components: { | ||
| LanguageFilter, | ||
| Checkbox, | ||
| HelpTooltip, | ||
| MultiSelect, | ||
| CatalogFilterBar, | ||
| CatalogFilterPanelContent, | ||
| SidePanelModal, | ||
| }, | ||
| setup() { | ||
| const { windowIsSmall } = useKResponsiveWindow(); | ||
| return { | ||
| isMobile: windowIsSmall, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. idem, let's just return the |
||
| }; | ||
| }, | ||
| mixins: [constantsTranslationMixin, catalogFilterMixin], | ||
| data() { | ||
| return { | ||
| drawer: false, | ||
| keywordInput: '', | ||
| showMobilePanel: false, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Idem, this shouldn't be necessarily related to a "mobile" device. |
||
| }; | ||
| }, | ||
| computed: { | ||
| ...mapGetters(['loggedIn']), | ||
| isRTL() { | ||
| return window.isRTL; | ||
| }, | ||
| libraryMode() { | ||
| return window.libraryMode; | ||
| }, | ||
| faqLink() { | ||
| return { name: RouteNames.CATALOG_FAQ }; | ||
| }, | ||
| menuProps() { | ||
| return { offsetY: true, maxHeight: 270 }; | ||
| }, | ||
| kindOptions() { | ||
| return (window.publicKinds || []) | ||
| .map(kind => { | ||
| if (!excludedKinds.has(kind)) { | ||
| return { | ||
| value: kind, | ||
| text: this.translateConstant(kind), | ||
| }; | ||
| } | ||
| }) | ||
| .filter(Boolean); | ||
| }, | ||
| licenseOptions() { | ||
| return (window.publicLicenses || []).map(id => { | ||
| return { | ||
| value: Number(id), | ||
| text: this.translateLicense(Number(id)), | ||
| }; | ||
| }); | ||
| }, | ||
| setKeywords() { | ||
| return debounce(this.updateKeywords, 500); | ||
| }, | ||
| }, | ||
| watch: { | ||
| keywords() { | ||
| this.keywordInput = this.keywords; | ||
| }, | ||
| }, | ||
| beforeMount() { | ||
| this.keywordInput = this.$route.query.keywords; | ||
| }, | ||
| methods: { | ||
| updateKeywords() { | ||
| this.keywords = this.keywordInput; | ||
| openSidePanel() { | ||
| this.showMobilePanel = true; | ||
| }, | ||
| closeSidePanel() { | ||
| this.showMobilePanel = false; | ||
| }, | ||
| }, | ||
| $trs: { | ||
| searchLabel: 'Keywords', | ||
| coachLabel: 'Resources for coaches', | ||
| subtitlesLabel: 'Captions or subtitles', | ||
| starredLabel: 'Starred', | ||
| licenseLabel: 'Licenses', | ||
| formatLabel: 'Formats', | ||
| includesLabel: 'Display only channels with', | ||
| searchText: 'Search', | ||
| coachDescription: 'Resources for coaches are only visible to coaches in Kolibri', | ||
| frequentlyAskedQuestionsLink: 'Frequently asked questions', | ||
| copyright: '© {year} Learning Equality', | ||
| filterText: 'Filter', | ||
| }, | ||
| }; | ||
|
|
@@ -236,33 +92,34 @@ | |
|
|
||
| <style lang="scss" scoped> | ||
| .v-input--checkbox { | ||
| margin: 0; | ||
| } | ||
| ::v-deep .v-messages { | ||
| display: none; | ||
| .catalog-filters-wrapper { | ||
| display: flex; | ||
| flex-direction: column; | ||
| width: 100%; | ||
| overflow-x: hidden; | ||
| } | ||
| .subheading { | ||
| margin-top: 20px; | ||
| margin-bottom: 5px; | ||
| font-weight: bold; | ||
| color: gray; | ||
| .filter-button-mobile { | ||
| align-self: flex-start; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is setting the |
||
| margin: 16px; | ||
| } | ||
| .filters { | ||
| width: 100%; | ||
| height: calc(100% - 100px); | ||
| overflow: auto; | ||
| .filter-panel-desktop { | ||
| position: fixed; | ||
| top: 100px; | ||
| left: 0; | ||
| width: 335px; | ||
| overflow-y: auto; | ||
|
Comment on lines
+107
to
+112
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We usually try to avoid Also, the original width of the side panel is |
||
| } | ||
| .qa-link { | ||
| margin-top: 24px; | ||
| } | ||
| .main-content-area { | ||
| flex: 1; | ||
| min-height: 100vh; | ||
| .drawer-btn { | ||
| margin-top: 10px; | ||
| &.with-sidebar { | ||
| width: calc(100% - 335px); | ||
| margin-left: 335px; | ||
| } | ||
| } | ||
| </style> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, We don't usually make differentiations between "mobile vs desktop", and use instead wording like "windowIsSmall" because a Mobile device could render a "windowIsLarge" layout if we rotate it and see the content in landscape mode, and a desktop device could render a "windowIsSmall" layout if the window is shrinked or the user display is splitted displaying two or more apps.
So, it'd be great if we could call all these properties in terms of windowIsSmall/windowIsMedium/windowIsLarge naming that are the ones exposed by the
useKResponsiveWindowcomposable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this
asidenode, we should also set these styles: