mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-26 09:42:46 +08:00
Add collapsable breadcrumbs component [SCI-11184]
This commit is contained in:
parent
8e0f0e27a7
commit
adcc401a79
7 changed files with 132 additions and 7 deletions
|
@ -8,7 +8,7 @@ class UserNotificationsController < ApplicationController
|
|||
notifications = load_notifications
|
||||
|
||||
case params[:tab]
|
||||
when 'all'
|
||||
when 'read'
|
||||
notifications = notifications.where.not(read_at: nil)
|
||||
when 'unread'
|
||||
notifications = notifications.where(read_at: nil)
|
||||
|
|
22
app/javascript/packs/vue/design_system/breadcrumbs.js
Normal file
22
app/javascript/packs/vue/design_system/breadcrumbs.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import Breadcrumbs from '../../../vue/shared/breadcrumbs.vue';
|
||||
import { mountWithTurbolinks } from '../helpers/turbolinks.js';
|
||||
|
||||
const app = createApp({
|
||||
computed: {
|
||||
breadcrumbs() {
|
||||
return [
|
||||
{ name: 'Home', url: '/' },
|
||||
{ name: 'Very very very long name ', url: '' },
|
||||
{ name: 'Data', url: '' },
|
||||
{ name: 'Very very very very very very very very very very long name ', url: '' },
|
||||
{ name: 'Very very very very very very very long name ', url: '' },
|
||||
{ name: 'Very very very very very long name ', url: '' },
|
||||
{ name: 'Very very very very long name ', url: '' }
|
||||
];
|
||||
}
|
||||
}
|
||||
});
|
||||
app.component('Breadcrumbs', Breadcrumbs);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#breadcrumbs');
|
|
@ -16,24 +16,23 @@
|
|||
<div v-html="notification.attributes.message" class="sci-navigation--notificaitons-flyout-notification-message"></div>
|
||||
</a>
|
||||
<div v-if="notification.attributes.breadcrumbs" class="flex items-center flex-wrap gap-0.5">
|
||||
<template v-for="(breadcrumb, index) in notification.attributes.breadcrumbs" :key="index">
|
||||
<div class="flex items-center gap-0.5">
|
||||
<i v-if="index > 0" class="sn-icon sn-icon-right"></i>
|
||||
<a :href="breadcrumb.url" :title="breadcrumb.name" class="truncate max-w-[20ch] inline-block">{{ breadcrumb.name }}</a>
|
||||
</div>
|
||||
</template>
|
||||
<Breadcrumbs :breadcrumbs="notification.attributes.breadcrumbs" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from '../../../packs/custom_axios.js';
|
||||
import Breadcrumbs from '../../shared/breadcrumbs.vue';
|
||||
|
||||
export default {
|
||||
name: 'NotificationItem',
|
||||
props: {
|
||||
notification: Object
|
||||
},
|
||||
components: {
|
||||
Breadcrumbs
|
||||
},
|
||||
computed: {
|
||||
lastBreadcrumbUrl() {
|
||||
if (!this.notification.attributes.breadcrumbs) {
|
||||
|
|
93
app/javascript/vue/shared/breadcrumbs.vue
Normal file
93
app/javascript/vue/shared/breadcrumbs.vue
Normal file
|
@ -0,0 +1,93 @@
|
|||
<template>
|
||||
<div ref="container" class="w-full flex items-center flex-wrap gap-0.5">
|
||||
<template v-if="!allVisible">
|
||||
<div class="flex items-center gap-0.5">
|
||||
<a :href="breadcrumbs[0].url" :title="breadcrumbs[0].name" class="max-w-[200px]">
|
||||
<StringWithEllipsis class="w-full" :text="breadcrumbs[0].name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<i class="sn-icon sn-icon-right text-sn-grey"></i>
|
||||
<GeneralDropdown>
|
||||
<template v-slot:field>
|
||||
<a>...</a>
|
||||
</template>
|
||||
<template v-slot:flyout>
|
||||
<div class="max-w-[600px]">
|
||||
<div v-for="(breadcrumb, index) in hiddenBreadcrumbs" :key="index" class="p-2 hover:bg-sn-super-light-grey cursor-pointer">
|
||||
<a :href="breadcrumb.url" :title="breadcrumb.name" class="max-w-[200px] hover:no-underline">
|
||||
<StringWithEllipsis class="w-full" :text="breadcrumb.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</GeneralDropdown>
|
||||
<i class="sn-icon sn-icon-right text-sn-grey"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div v-for="(breadcrumb, index) in visibleBreadcrumbs" :key="index" class="flex items-center gap-0.5">
|
||||
<i v-if="index > 0" class="sn-icon sn-icon-right text-sn-grey"></i>
|
||||
<a :href="breadcrumb.url" :title="breadcrumb.name" class="max-w-[200px]">
|
||||
<StringWithEllipsis class="w-full" :text="breadcrumb.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StringWithEllipsis from './string_with_ellipsis.vue';
|
||||
import GeneralDropdown from './general_dropdown.vue';
|
||||
|
||||
export default {
|
||||
name: 'Breadcrumbs',
|
||||
props: {
|
||||
breadcrumbs: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
StringWithEllipsis,
|
||||
GeneralDropdown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
containerSize: 0,
|
||||
breadcrumbSize: 200
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
breadcrumbsVisibleCount() {
|
||||
const size = Math.floor(this.containerSize / this.breadcrumbSize);
|
||||
if (size < 2) {
|
||||
return 2;
|
||||
}
|
||||
return size;
|
||||
},
|
||||
allVisible() {
|
||||
return this.breadcrumbs.length <= this.breadcrumbsVisibleCount;
|
||||
},
|
||||
hiddenBreadcrumbs() {
|
||||
return this.breadcrumbs.slice(1, this.breadcrumbs.length - this.breadcrumbsVisibleCount + 1);
|
||||
},
|
||||
visibleBreadcrumbs() {
|
||||
if (this.allVisible) {
|
||||
return this.breadcrumbs;
|
||||
}
|
||||
return this.breadcrumbs.slice(this.breadcrumbs.length - this.breadcrumbsVisibleCount + 1);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setContainerSize();
|
||||
window.addEventListener('resize', this.setContainerSize);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.setContainerSize);
|
||||
},
|
||||
methods: {
|
||||
setContainerSize() {
|
||||
this.containerSize = this.$refs.container.offsetWidth;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>;
|
8
app/views/design_elements/_breadcrumbs.html.erb
Normal file
8
app/views/design_elements/_breadcrumbs.html.erb
Normal file
|
@ -0,0 +1,8 @@
|
|||
<div>
|
||||
<h1>breadcrumbs</h1>
|
||||
<div id="breadcrumbs" class="flex items-center gap-4">
|
||||
<Breadcrumbs :breadcrumbs="breadcrumbs">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= javascript_include_tag 'vue_design_system_breadcrumbs' %>
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
<%= render partial: 'select' %>
|
||||
|
||||
<%= render partial: 'breadcrumbs' %>
|
||||
|
||||
<%= render partial: 'modals' %>
|
||||
|
||||
<%= render partial: 'icons', locals: {icons_list: icons_list} %>
|
||||
|
|
|
@ -54,6 +54,7 @@ const entryList = {
|
|||
vue_experiments_list: './app/javascript/packs/vue/experiments_list.js',
|
||||
vue_my_modules_list: './app/javascript/packs/vue/my_modules_list.js',
|
||||
vue_design_system_select: './app/javascript/packs/vue/design_system/select.js',
|
||||
vue_design_system_breadcrumbs: './app/javascript/packs/vue/design_system/breadcrumbs.js',
|
||||
vue_protocols_list: './app/javascript/packs/vue/protocols_list.js',
|
||||
vue_repositories_table: './app/javascript/packs/vue/repositories_table.js',
|
||||
vue_import_repository_modal: './app/javascript/packs/vue/import_repository_modal.js',
|
||||
|
|
Loading…
Reference in a new issue