parent
befc6f03f6
commit
10ffcf9a5a
@ -0,0 +1,91 @@
|
||||
//= require rails-ujs
|
||||
//= require activestorage
|
||||
//= require turbolinks
|
||||
//= require jquery3
|
||||
//= require popper
|
||||
//= require bootstrap-sprockets
|
||||
//= require jquery.validate.min
|
||||
//= require additional-methods.min
|
||||
//= require bootstrap-notify
|
||||
//= require jquery.cookie.min
|
||||
//= require select2
|
||||
//= require jquery.cxselect
|
||||
//= require bootstrap-datepicker
|
||||
//= require bootstrap.viewer
|
||||
//= require jquery.mloading
|
||||
//= require jquery-confirm.min
|
||||
//= require common
|
||||
|
||||
//= require echarts
|
||||
//= require codemirror/lib/codemirror
|
||||
//= require codemirror/mode/shell/shell
|
||||
//= require editormd/editormd
|
||||
//= require editormd/languages/zh-tw
|
||||
//= require dragula/dragula
|
||||
|
||||
//= require_tree ./i18n
|
||||
//= require_tree ./cooperative
|
||||
|
||||
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr) {
|
||||
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
|
||||
}
|
||||
});
|
||||
|
||||
// ******** select2 global config ********
|
||||
$.fn.select2.defaults.set('theme', 'bootstrap4');
|
||||
$.fn.select2.defaults.set('language', 'zh-CN');
|
||||
|
||||
Turbolinks.setProgressBarDelay(200);
|
||||
|
||||
$.notifyDefaults({
|
||||
type: 'success',
|
||||
z_index: 9999,
|
||||
delay: 2000
|
||||
});
|
||||
|
||||
$(document).on('turbolinks:load', function(){
|
||||
$('[data-toggle="tooltip"]').tooltip({ trigger : 'hover' });
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
// 图片查看大图
|
||||
$('img.preview-image').bootstrapViewer();
|
||||
|
||||
// flash alert提示框自动关闭
|
||||
if($('.cooperative-alert-container .alert').length > 0){
|
||||
setTimeout(function(){
|
||||
$('.cooperative-alert-container .alert:not(.alert-danger)').alert('close');
|
||||
}, 2000);
|
||||
setTimeout(function(){
|
||||
$('.cooperative-alert-container .alert.alert-danger').alert('close');
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("turbolinks:before-cache", function () {
|
||||
$('[data-toggle="tooltip"]').tooltip('hide');
|
||||
$('[data-toggle="popover"]').popover('hide');
|
||||
});
|
||||
// var progressBar = new Turbolinks.ProgressBar();
|
||||
|
||||
// $(document).on('ajax:send', function(event){
|
||||
// console.log('ajax send', event);
|
||||
// progressBar.setValue(0)
|
||||
// progressBar.show()
|
||||
// });
|
||||
//
|
||||
// $(document).on('ajax:complete', function(event){
|
||||
// console.log('ajax complete', event);
|
||||
// progressBar.setValue(1)
|
||||
// progressBar.hide() // 分页时不触发,奇怪
|
||||
// });
|
||||
// $(document).on('ajax:success', function(event){
|
||||
// console.log('ajax success', event);
|
||||
// });
|
||||
// $(document).on('ajax:error', function(event){
|
||||
// console.log('ajax error', event);
|
||||
// });
|
||||
|
||||
$(function () {
|
||||
});
|
@ -0,0 +1,86 @@
|
||||
$(document).on('turbolinks:load', function() {
|
||||
if ($('body.cooperative-laboratory-settings-edit-page, body.cooperative-laboratory-settings-update-page').length > 0) {
|
||||
var $container = $('.edit-laboratory-setting-container');
|
||||
var $form = $container.find('.edit_laboratory');
|
||||
|
||||
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||
var $fileInput = $(this);
|
||||
var file = this.files[0];
|
||||
var imageType = /image.*/;
|
||||
if (file && file.type.match(imageType)) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
var $box = $fileInput.parent();
|
||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||
$box.addClass('has-img');
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
}
|
||||
});
|
||||
|
||||
createMDEditor('laboratory-footer-editor', { height: 200, placeholder: '请输入备案信息' });
|
||||
|
||||
$form.validate({
|
||||
errorElement: 'span',
|
||||
errorClass: 'danger text-danger',
|
||||
errorPlacement:function(error,element){
|
||||
if(element.parent().hasClass("input-group")){
|
||||
element.parent().after(error);
|
||||
}else{
|
||||
element.after(error)
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
identifier: {
|
||||
required: true,
|
||||
checkSite: true
|
||||
},
|
||||
name: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
});
|
||||
$.validator.addMethod("checkSite",function(value,element,params){
|
||||
var checkSite = /^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/;
|
||||
return this.optional(element)||(checkSite.test(value + '.educoder.com'));
|
||||
},"域名不合法!");
|
||||
|
||||
$form.on('click', '.submit-btn', function(){
|
||||
$form.find('.submit-btn').attr('disabled', 'disabled');
|
||||
$form.find('.error').html('');
|
||||
var valid = $form.valid();
|
||||
|
||||
$('input[name="navbar[][name]"]').each(function(_, e){
|
||||
var $ele = $(e);
|
||||
if($ele.val() === undefined || $ele.val().length === 0){
|
||||
$ele.addClass('danger text-danger');
|
||||
valid = false;
|
||||
} else {
|
||||
$ele.removeClass('danger text-danger');
|
||||
}
|
||||
});
|
||||
|
||||
if(!valid) return;
|
||||
$.ajax({
|
||||
method: 'PATCH',
|
||||
dataType: 'json',
|
||||
url: $form.attr('action'),
|
||||
data: new FormData($form[0]),
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(data){
|
||||
$.notify({ message: '保存成功' });
|
||||
window.location.reload();
|
||||
},
|
||||
error: function(res){
|
||||
var data = res.responseJSON;
|
||||
$form.find('.error').html(data.message);
|
||||
},
|
||||
complete: function(){
|
||||
$form.find('.submit-btn').attr('disabled', false);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
$(document).on('turbolinks:load', function(){
|
||||
$('#sidebarCollapse').on('click', function () {
|
||||
$(this).toggleClass('active');
|
||||
$('#sidebar').toggleClass('active');
|
||||
$.cookie('cooperative_sidebar_collapse', $(this).hasClass('active'), {path: '/cooperative'});
|
||||
});
|
||||
|
||||
var sidebarController = $('#sidebar').data('current-controller');
|
||||
if (sidebarController.length > 0) {
|
||||
$('#sidebar a.active').removeClass('active');
|
||||
$('#sidebar ul.collapse.show').removeClass('show');
|
||||
var activeLi = $('#sidebar a[data-controller="' + sidebarController + '"]');
|
||||
activeLi.addClass('active');
|
||||
activeLi.parent().parent('ul.collapse').addClass('show');
|
||||
}
|
||||
});
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||
* listed below.
|
||||
*
|
||||
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
|
||||
* vendor/assets/stylesheets directory can be referenced here using a relative path.
|
||||
*
|
||||
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
||||
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
||||
* files in this directory. Styles in this file should be added after the last require_* statement.
|
||||
* It is generally better to create a new file per style scope.
|
||||
*
|
||||
*= require_tree .
|
||||
*= require_self
|
||||
|
||||
*/
|
@ -0,0 +1,54 @@
|
||||
@import "bootstrap";
|
||||
@import "font-awesome-sprockets";
|
||||
@import "font-awesome";
|
||||
@import "select2.min";
|
||||
@import "select2-bootstrap4.min";
|
||||
@import "bootstrap-datepicker";
|
||||
@import "bootstrap-datepicker.standalone";
|
||||
@import "jquery.mloading";
|
||||
@import "jquery-confirm.min";
|
||||
|
||||
@import "codemirror/lib/codemirror";
|
||||
@import "editormd/css/editormd.min";
|
||||
@import "dragula/dragula";
|
||||
|
||||
@import "common";
|
||||
@import "cooperative/*";
|
||||
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
font-size: 14px;
|
||||
background: #efefef;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.simple_form {
|
||||
.form-group {
|
||||
.collection_radio_buttons {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.form-check-inline {
|
||||
height: calc(1.5em + 0.75rem + 2px)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input.form-control {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-default{
|
||||
color: #666;
|
||||
background: #e1e1e1!important;
|
||||
}
|
||||
.export-absolute{
|
||||
right:20px;
|
||||
position: absolute;
|
||||
}
|
||||
|
@ -0,0 +1,126 @@
|
||||
.cooperative-body-container {
|
||||
padding: 20px;
|
||||
flex: 1;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: scroll;
|
||||
|
||||
& > .content {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
|
||||
.box {
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* 面包屑 */
|
||||
.breadcrumb {
|
||||
padding-left: 5px;
|
||||
font-size: 20px;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
/* 内容表格 */
|
||||
table {
|
||||
table-layout: fixed;
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
tr {
|
||||
&.no-data {
|
||||
&:hover {
|
||||
color: darkgrey;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
& > td {
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-container {
|
||||
& > .action {
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
.more-action-dropdown {
|
||||
.dropdown-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分页 */
|
||||
.paginate-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.paginate-total {
|
||||
margin-bottom: 10px;
|
||||
color: darkgrey;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索表单 */
|
||||
.search-form-container {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.search-form {
|
||||
flex: 1;
|
||||
|
||||
* { font-size: 14px; }
|
||||
|
||||
select, input {
|
||||
margin-right: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.global-error {
|
||||
color: grey;
|
||||
min-height: 300px;
|
||||
|
||||
&-code {
|
||||
font-size: 80px;
|
||||
}
|
||||
|
||||
&-text {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
.nav-link {
|
||||
padding: 0.5rem 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
border: 1px solid #ced4da;
|
||||
}
|
||||
|
||||
.batch-action-container {
|
||||
margin-bottom: -15px;
|
||||
padding: 10px 20px 0;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
.cooperative-laboratory-settings-edit-page, .cooperative-laboratory-settings-update-page {
|
||||
.edit-laboratory-setting-container {
|
||||
.logo-item {
|
||||
display: flex;
|
||||
|
||||
&-img {
|
||||
display: block;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
&-upload {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: #F5F5F5;
|
||||
border: 1px solid #E5E5E5;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 27px;
|
||||
left: 39px;
|
||||
width: 2px;
|
||||
height: 26px;
|
||||
background: #E5E5E5;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 39px;
|
||||
left: 27px;
|
||||
width: 26px;
|
||||
height: 2px;
|
||||
background: #E5E5E5;
|
||||
}
|
||||
}
|
||||
|
||||
&-left {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
|
||||
&.has-img {
|
||||
.logo-item-upload {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.logo-item-upload {
|
||||
display: block;
|
||||
background: rgba(145, 145, 145, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
color: #777777;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: #23272B;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,235 @@
|
||||
#sidebar {
|
||||
min-width: 200px;
|
||||
max-width: 200px;
|
||||
background: #272822;
|
||||
color: #fff;
|
||||
transition: all 0.5s;
|
||||
overflow-y: scroll;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display:none
|
||||
}
|
||||
|
||||
&.active {
|
||||
min-width: 60px;
|
||||
max-width: 60px;
|
||||
text-align: center;
|
||||
|
||||
.sidebar-header {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-logo {
|
||||
overflow: hidden;
|
||||
margin-bottom: 10px;
|
||||
|
||||
& > .logo-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul li a {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-size: 0.85em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
span { display: none }
|
||||
|
||||
i {
|
||||
margin-right: 0;
|
||||
display: block;
|
||||
font-size: 1.8em;
|
||||
margin-bottom: 5px;
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-toggle::after {
|
||||
top: auto;
|
||||
bottom: 10px;
|
||||
right: 50%;
|
||||
-webkit-transform: translateX(50%);
|
||||
-ms-transform: translateX(50%);
|
||||
transform: translateX(50%);
|
||||
}
|
||||
|
||||
ul ul a {
|
||||
padding: 10px !important;
|
||||
|
||||
span { display: none }
|
||||
|
||||
i {
|
||||
margin-left: 0px;
|
||||
display: block;
|
||||
font-size: 0.8em;
|
||||
width: 30px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 20px;
|
||||
background: #272822;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
&-logo {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
& > img {
|
||||
width: 40px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
& > .logo-label {
|
||||
font-size: 18px;
|
||||
color: darkgrey;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#sidebarCollapse {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
|
||||
&.active {
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
background: #3f3f3f;
|
||||
border: 1px solid grey;
|
||||
border-radius: 3px;
|
||||
|
||||
i.fold { display: none; }
|
||||
i.unfold { display: block; }
|
||||
}
|
||||
|
||||
i.fold {
|
||||
display: block;
|
||||
}
|
||||
i.unfold { display: none; }
|
||||
}
|
||||
|
||||
a, a:hover, a:focus {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
& > ul > li > a > i {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
ul {
|
||||
&.components {
|
||||
padding: 20px 0;
|
||||
border-bottom: 1px solid #3f3f3f;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
li > a {
|
||||
padding: 10px;
|
||||
font-size: 1em;
|
||||
display: block;
|
||||
text-align: left;
|
||||
|
||||
i {
|
||||
margin-right: 10px;
|
||||
font-size: 1em;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
li a {
|
||||
&:hover, &.active {
|
||||
color: #fff;
|
||||
background: #276891;
|
||||
}
|
||||
}
|
||||
|
||||
li.active > a, a[aria-expanded="true"] {
|
||||
color: #fff;
|
||||
//background: #276891;
|
||||
}
|
||||
|
||||
ul a {
|
||||
font-size: 0.9em !important;
|
||||
padding-left: 30px !important;
|
||||
background: #3f3f3f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#sidebar {
|
||||
&.active {
|
||||
padding: 10px 5px;
|
||||
min-width: 40px;
|
||||
max-width: 40px;
|
||||
text-align: center;
|
||||
margin-left: 0;
|
||||
transform: none;
|
||||
|
||||
.sidebar-header {
|
||||
padding: 0px;
|
||||
|
||||
.sidebar-header-logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#sidebarCollapse {
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
ul li a {
|
||||
padding: 10px;
|
||||
font-size: 0.85em;
|
||||
|
||||
i {
|
||||
margin-right: 0;
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
& > ul > li > a > i {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
ul ul a {
|
||||
padding: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-toggle::after {
|
||||
top: auto;
|
||||
bottom: 10px;
|
||||
right: 50%;
|
||||
-webkit-transform: translateX(50%);
|
||||
-ms-transform: translateX(50%);
|
||||
transform: translateX(50%);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
module Admins::ErrorRescueHandler
|
||||
module Base::ErrorRescueHandler
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
@ -1,4 +1,4 @@
|
||||
module Admins::PaginateHelper
|
||||
module Base::PaginateHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def offset
|
@ -0,0 +1,37 @@
|
||||
module Base::RenderHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def render_by_format(hash)
|
||||
format = request.format.symbol
|
||||
hash.key?(format) ? hash[format].call : hash[:html].call
|
||||
end
|
||||
|
||||
def render_forbidden
|
||||
render_by_format(html: -> { current_user&.business? ? render('shared/403') : redirect_to('/403') },
|
||||
json: -> { render status: 403, json: { messages: I18n.t('error.forbidden') } } )
|
||||
end
|
||||
|
||||
def render_not_found
|
||||
render_by_format(html: -> { render 'shared/404' },
|
||||
js: -> { render_js_error('资源未找到') },
|
||||
json: -> { render status: 404, json: { message: '资源未找到' } })
|
||||
end
|
||||
|
||||
def render_unprocessable_entity(message, type: :alert)
|
||||
render_by_format(html: -> { render 'shared/422' },
|
||||
js: -> { render_js_error(message, type: type) },
|
||||
json: -> { render status: 422, json: { message: message } })
|
||||
end
|
||||
alias_method :render_error, :render_unprocessable_entity
|
||||
|
||||
def internal_server_error(message = '系统错误')
|
||||
@message = message
|
||||
render_by_format(html: -> { render 'shared/500' },
|
||||
js: -> { render_js_error(message) },
|
||||
json: -> { render status: 500, json: { message: message } })
|
||||
end
|
||||
|
||||
def render_js_template(template, **opts)
|
||||
render({ template: template, formats: :js }.merge(opts))
|
||||
end
|
||||
end
|
@ -0,0 +1,16 @@
|
||||
module Cooperative::RenderHelper
|
||||
include Base::RenderHelper
|
||||
|
||||
def render_delete_success
|
||||
render_js_template 'cooperative/shared/delete'
|
||||
end
|
||||
alias_method :render_success_js, :render_delete_success
|
||||
|
||||
def render_js_error(message, type: :alert)
|
||||
if type == :notify
|
||||
render js: "$.notify({ message: '#{message}' },{ type: 'danger', delay: 5000 });"
|
||||
else
|
||||
render_js_template 'cooperative/shared/error', locals: { message: message }
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
class Cooperative::DashboardsController < Cooperative::BaseController
|
||||
def show
|
||||
end
|
||||
end
|
@ -0,0 +1,14 @@
|
||||
class Cooperative::LaboratorySettingsController < Cooperative::BaseController
|
||||
def edit
|
||||
@laboratory = current_laboratory
|
||||
end
|
||||
|
||||
def update
|
||||
Admins::SaveLaboratorySettingService.call(current_laboratory, form_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def form_params
|
||||
params.permit(:identifier, :name, :nav_logo, :login_logo, :tab_logo, :footer, navbar: %i[name link hidden])
|
||||
end
|
||||
end
|
@ -1,110 +1,3 @@
|
||||
module Admins::BaseHelper
|
||||
def sidebar_item_group(url, text, **opts)
|
||||
link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false }
|
||||
content =
|
||||
link_to url, link_opts do
|
||||
content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
|
||||
content_tag(:span, text)
|
||||
end
|
||||
|
||||
content +=
|
||||
content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do
|
||||
yield
|
||||
end
|
||||
|
||||
raw content
|
||||
end
|
||||
|
||||
def sidebar_item(url, text, **opts)
|
||||
content =
|
||||
link_to url, 'data-controller': opts[:controller] do
|
||||
content_tag(:i, '', class: "fa fa-#{opts[:icon]} fa-fw", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
|
||||
content_tag(:span, text)
|
||||
end
|
||||
|
||||
raw content
|
||||
end
|
||||
|
||||
def admin_sidebar_controller
|
||||
key = params[:controller].to_s.gsub(/\//, '-')
|
||||
SidebarUtil.controller_name(key) || key
|
||||
end
|
||||
|
||||
def define_admin_breadcrumbs(&block)
|
||||
content_for(:setup_admin_breadcrumb, &block)
|
||||
end
|
||||
|
||||
def add_admin_breadcrumb(text, url = nil)
|
||||
@_admin_breadcrumbs ||= []
|
||||
@_admin_breadcrumbs << OpenStruct.new(text: text, url: url)
|
||||
end
|
||||
|
||||
def display_text(str, default = '--')
|
||||
str.presence || default
|
||||
end
|
||||
|
||||
def overflow_hidden_span(text, width: 300)
|
||||
opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" }
|
||||
opts.merge!('data-toggle': 'tooltip', title: text) if text != '--'
|
||||
|
||||
content_tag(:span, text, opts)
|
||||
end
|
||||
|
||||
def sort_tag(content = '', **opts)
|
||||
options = {}
|
||||
options[:sort_by] = opts.delete(:name)
|
||||
is_current_sort = params[:sort_by].to_s == options[:sort_by]
|
||||
options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
|
||||
|
||||
path = opts.delete(:path) + "?" + unsafe_params.merge(options).to_query
|
||||
arrow_class = case params[:sort_direction].to_s
|
||||
when 'desc' then 'fa-sort-amount-desc'
|
||||
when 'asc' then 'fa-sort-amount-asc'
|
||||
else ''
|
||||
end
|
||||
opts[:style] = "#{opts[:style]} ;position: relative;"
|
||||
|
||||
content_tag(:span, opts) do
|
||||
link_to path, remote: true do
|
||||
content = content_tag(:span) { yield } if block_given?
|
||||
|
||||
content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort
|
||||
raw content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def javascript_void_link(name, **opts)
|
||||
raw link_to(name, 'javascript:void(0)', opts)
|
||||
end
|
||||
|
||||
def agree_link(name, url, **opts)
|
||||
klass = ['action agree-action', opts.delete(:class)].compact.join(' ')
|
||||
|
||||
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
|
||||
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
|
||||
|
||||
raw link_to(name, url, { method: :post, remote: true, class: klass, 'data-confirm': '确认审核通过?'}.merge(opts))
|
||||
end
|
||||
|
||||
def delete_link(name, url, **opts, &block)
|
||||
klass = ['action delete-action', opts.delete(:class)].compact.join(' ')
|
||||
|
||||
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
|
||||
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
|
||||
|
||||
if block_given?
|
||||
raw link_to(url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts), &block)
|
||||
else
|
||||
raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts))
|
||||
end
|
||||
end
|
||||
|
||||
def unsafe_params
|
||||
params.except(:controller, :action).to_unsafe_h
|
||||
end
|
||||
|
||||
def list_index_no(page,index)
|
||||
(page - 1) * 20 + index + 1
|
||||
end
|
||||
include ManageBackHelper
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
module Cooperative::BaseHelper
|
||||
include ManageBackHelper
|
||||
end
|
@ -0,0 +1,115 @@
|
||||
module ManageBackHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def sidebar_item_group(url, text, **opts)
|
||||
link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false }
|
||||
content =
|
||||
link_to url, link_opts do
|
||||
content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
|
||||
content_tag(:span, text)
|
||||
end
|
||||
|
||||
content +=
|
||||
content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do
|
||||
yield
|
||||
end
|
||||
|
||||
raw content
|
||||
end
|
||||
|
||||
def sidebar_item(url, text, **opts)
|
||||
content =
|
||||
link_to url, 'data-controller': opts[:controller] do
|
||||
content_tag(:i, '', class: "fa fa-#{opts[:icon]} fa-fw", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
|
||||
content_tag(:span, text)
|
||||
end
|
||||
|
||||
raw content
|
||||
end
|
||||
|
||||
def admin_sidebar_controller
|
||||
key = params[:controller].to_s.gsub(/\//, '-')
|
||||
SidebarUtil.controller_name(key) || key
|
||||
end
|
||||
alias_method :sidebar_controller, :admin_sidebar_controller
|
||||
|
||||
def define_admin_breadcrumbs(&block)
|
||||
content_for(:setup_admin_breadcrumb, &block)
|
||||
end
|
||||
alias_method :define_breadcrumbs, :define_admin_breadcrumbs
|
||||
|
||||
def add_admin_breadcrumb(text, url = nil)
|
||||
@_breadcrumbs ||= []
|
||||
@_breadcrumbs << OpenStruct.new(text: text, url: url)
|
||||
end
|
||||
alias_method :add_breadcrumb, :add_admin_breadcrumb
|
||||
|
||||
def display_text(str, default = '--')
|
||||
str.presence || default
|
||||
end
|
||||
|
||||
def overflow_hidden_span(text, width: 300)
|
||||
opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" }
|
||||
opts.merge!('data-toggle': 'tooltip', title: text) if text != '--'
|
||||
|
||||
content_tag(:span, text, opts)
|
||||
end
|
||||
|
||||
def sort_tag(content = '', **opts)
|
||||
options = {}
|
||||
options[:sort_by] = opts.delete(:name)
|
||||
is_current_sort = params[:sort_by].to_s == options[:sort_by]
|
||||
options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
|
||||
|
||||
path = opts.delete(:path) + "?" + unsafe_params.merge(options).to_query
|
||||
arrow_class = case params[:sort_direction].to_s
|
||||
when 'desc' then 'fa-sort-amount-desc'
|
||||
when 'asc' then 'fa-sort-amount-asc'
|
||||
else ''
|
||||
end
|
||||
opts[:style] = "#{opts[:style]} ;position: relative;"
|
||||
|
||||
content_tag(:span, opts) do
|
||||
link_to path, remote: true do
|
||||
content = content_tag(:span) { yield } if block_given?
|
||||
|
||||
content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort
|
||||
raw content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def javascript_void_link(name, **opts)
|
||||
raw link_to(name, 'javascript:void(0)', opts)
|
||||
end
|
||||
|
||||
def agree_link(name, url, **opts)
|
||||
klass = ['action agree-action', opts.delete(:class)].compact.join(' ')
|
||||
|
||||
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
|
||||
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
|
||||
|
||||
raw link_to(name, url, { method: :post, remote: true, class: klass, 'data-confirm': '确认审核通过?'}.merge(opts))
|
||||
end
|
||||
|
||||
def delete_link(name, url, **opts, &block)
|
||||
klass = ['action delete-action', opts.delete(:class)].compact.join(' ')
|
||||
|
||||
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
|
||||
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
|
||||
|
||||
if block_given?
|
||||
raw link_to(url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts), &block)
|
||||
else
|
||||
raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts))
|
||||
end
|
||||
end
|
||||
|
||||
def unsafe_params
|
||||
params.except(:controller, :action).to_unsafe_h
|
||||
end
|
||||
|
||||
def list_index_no(page,index)
|
||||
(page - 1) * 20 + index + 1
|
||||
end
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
<% define_breadcrumbs do %>
|
||||
<% add_breadcrumb('概览') %>
|
||||
<% end %>
|
@ -0,0 +1,11 @@
|
||||
<%# Link to the "First" page
|
||||
- available local variables
|
||||
url: url to the first page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<li class="page-item first-page">
|
||||
<%= link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, remote: remote, class: 'page-link' %>
|
||||
</li>
|
@ -0,0 +1,13 @@
|
||||
<%# Non-link tag that stands for skipped pages...
|
||||
- available local variables
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<li class="page-item">
|
||||
<%= link_to 'javascript:void(0)', { class: 'page-link' } do %>
|
||||
<%= t('views.pagination.truncate').html_safe %>
|
||||
<span class="sr-only">(current)</span>
|
||||
<% end %>
|
||||
</li>
|
@ -0,0 +1,11 @@
|
||||
<%# Link to the "Last" page
|
||||
- available local variables
|
||||
url: url to the last page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<li class="page-item last-page">
|
||||
<%= link_to_unless(current_page.last?, t('views.pagination.last').html_safe, url, remote: remote, class: 'page-link') %>
|
||||
<li class="page-item last-page">
|
@ -0,0 +1,11 @@
|
||||
<%# Link to the "Next" page
|
||||
- available local variables
|
||||
url: url to the next page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<li class="page-item next">
|
||||
<%= link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, rel: 'next', remote: remote, class: 'page-link' %>
|
||||
</li>
|
@ -0,0 +1,19 @@
|
||||
<%# Link showing page number
|
||||
- available local variables
|
||||
page: a page object for "this" page
|
||||
url: url to this page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<li class="page-item page<%= ' current active' if page.current? %>">
|
||||
<% if page.current? %>
|
||||
<%= link_to url, {remote: remote, rel: page.rel, class: 'page-link'} do %>
|
||||
<%= page %>
|
||||
<span class="sr-only">(current)</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= link_to page, url, {remote: remote, rel: page.rel, class: 'page-link'} %>
|
||||
<% end %>
|
||||
</li>
|
@ -0,0 +1,27 @@
|
||||
<%# The container tag
|
||||
- available local variables
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
paginator: the paginator that renders the pagination tags inside
|
||||
-%>
|
||||
<%= paginator.render do -%>
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination justify-content-center">
|
||||
<%= first_page_tag unless current_page.first? %>
|
||||
<%= prev_page_tag unless current_page.first? %>
|
||||
<% each_page do |page| -%>
|
||||
<% if page.display_tag? -%>
|
||||
<%= page_tag page %>
|
||||
<% elsif !page.was_truncated? -%>
|
||||
<%= gap_tag %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% unless current_page.out_of_range? %>
|
||||
<%= next_page_tag unless current_page.last? %>
|
||||
<%= last_page_tag unless current_page.last? %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</nav>
|
||||
<% end -%>
|
@ -0,0 +1,11 @@
|
||||
<%# Link to the "Previous" page
|
||||
- available local variables
|
||||
url: url to the previous page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<li class="page-item prev">
|
||||
<%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, rel: 'prev', remote: remote, class: 'page-link' %>
|
||||
</li>
|
@ -0,0 +1 @@
|
||||
<tr class="no-data"><td colspan="100">暂无数据</td></tr>
|
@ -0,0 +1,6 @@
|
||||
<div class="paginate-container">
|
||||
<% if objects && objects.size.nonzero? %>
|
||||
<div class="paginate-total"><%= page_entries_info objects %></div>
|
||||
<% end %>
|
||||
<%= paginate objects, views_prefix: 'cooperative', remote: true %>
|
||||
</div>
|
@ -0,0 +1,20 @@
|
||||
<% sidebar_collapse = request.cookies['cooperative_sidebar_collapse'].to_s == 'true' %>
|
||||
<nav id="sidebar" class="<%= sidebar_collapse ? 'active' : '' %>" data-current-controller="<%= sidebar_controller %>">
|
||||
<div class="sidebar-header">
|
||||
<a href="/" class="sidebar-header-logo" data-toggle="tooltip" title="返回主页">
|
||||
<img src="<%= current_setting_or_default(:nav_logo_url) %>"/>
|
||||
<span class="logo-label">管理中心</span>
|
||||
</a>
|
||||
<div id="sidebarCollapse" class="navbar-btn <%= sidebar_collapse ? 'active' : '' %>">
|
||||
<i class="fa fa-chevron-left fold" data-toggle="tooltip" data-placement="right" data-boundary="window" title="收起"></i>
|
||||
<i class="fa fa-bars unfold" data-toggle="tooltip" data-placement="right" data-boundary="window" title="展开"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar Links -->
|
||||
<ul class="list-unstyled components">
|
||||
<li><%= sidebar_item(cooperative_path, '概览', icon: 'dashboard', controller: 'cooperative-dashboards') %></li>
|
||||
<li><%= sidebar_item(edit_cooperative_laboratory_setting_path, '网站设置', icon: 'cogs', controller: 'cooperative-laboratory_settings') %></li>
|
||||
<li><%= sidebar_item('/', '返回主页', icon: 'sign-out', controller: 'root') %></li>
|
||||
</ul>
|
||||
</nav>
|
@ -0,0 +1,4 @@
|
||||
;
|
||||
$('[data-toggle="tooltip"]').tooltip({ trigger : 'hover' });
|
||||
$('[data-toggle="popover"]').popover();
|
||||
$('img.preview-image').bootstrapViewer();
|
@ -0,0 +1,27 @@
|
||||
var deleteRow = $('<%= params[:element] %>');
|
||||
var refreshUrl = '<%= params[:refresh_url] %>';
|
||||
var notRefresh = <%= !!params[:not_refresh] %>;
|
||||
|
||||
$.notify({ message: '操作成功' },{ type: 'success' });
|
||||
|
||||
if (!notRefresh) {
|
||||
var refreshFunc = function(url) {
|
||||
$.ajax({
|
||||
url: url.length > 0 ? url : window.location.href,
|
||||
method: 'GET',
|
||||
dataType: "script"
|
||||
})
|
||||
}
|
||||
|
||||
if(deleteRow.length > 0){
|
||||
var needRefresh = deleteRow.siblings().length == 0;
|
||||
|
||||
deleteRow.remove();
|
||||
|
||||
if(needRefresh){ refreshFunc(refreshUrl); }
|
||||
} else {
|
||||
refreshFunc(refreshUrl);
|
||||
}
|
||||
} else {
|
||||
deleteRow.remove();
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
$('.cooperative-alert-container').html('<%= j( render partial: 'shared/alert', locals: { message: message } ) %>');
|
||||
|
||||
setTimeout(function() {
|
||||
if ($('.cooperative-alert-container button.close').length > 0) {
|
||||
$('.cooperative-alert-container button.close').trigger('click');
|
||||
}
|
||||
}, 5000)
|
||||
$(".cooperative-body-container").animate({
|
||||
scrollTop: 0
|
||||
}, 200);
|
@ -0,0 +1,18 @@
|
||||
<div class="modal fade cooperative-message-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">消息</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" style="max-height: 300px; overflow-y: scroll;">
|
||||
保存成功
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary submit-btn" data-dismiss="modal">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,32 @@
|
||||
<div class="modal fade admin-upload-file-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><%= title ||= '上传文件' %></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="admin-upload-file-form" enctype="multipart/form-data">
|
||||
<%= hidden_field_tag(:source_type, nil) %>
|
||||
<%= hidden_field_tag(:source_id, nil) %>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">文件</span>
|
||||
</div>
|
||||
<div class="custom-file">
|
||||
<input type="file" name="file" class="upload-file-input" id="upload-file-input">
|
||||
<label class="custom-file-label file-names" for="upload-file-input">选择文件</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="error text-danger"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
|
||||
<button type="button" class="btn btn-primary submit-btn" data-disable-with="上传中...">上传</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><%= current_laboratory.school&.name %>-后台管理</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel='shortcut icon' type='image/x-icon' href='<%= current_setting_or_default(:tab_logo_url) %>' />
|
||||
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
|
||||
<%= stylesheet_link_tag 'cooperative', media: 'all','data-turbolinks-track': 'reload' %>
|
||||
<%= javascript_include_tag 'cooperative', 'data-turbolinks-track': 'reload' %>
|
||||
</head>
|
||||
|
||||
<% body_class = [params[:controller].gsub(/\//, '-').gsub('_', '-'), params[:action], 'page'].join('-') %>
|
||||
<body class="<%= body_class %>">
|
||||
<!-- Sidebar -->
|
||||
<%= render partial: 'cooperative/shared/sidebar' %>
|
||||
|
||||
<!-- Page Content -->
|
||||
<div class="cooperative-body-container">
|
||||
<div class="cooperative-alert-container">
|
||||
<%= render 'shared/flash_notice' %>
|
||||
</div>
|
||||
|
||||
<div class="cooperative-breadcrumb-container">
|
||||
<%= yield :setup_breadcrumb %>
|
||||
<%= render(partial: 'shared/breadcrumb') %>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<%= yield %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cooperative-modal-container"></div>
|
||||
|
||||
<!-- message modal -->
|
||||
<%= render 'cooperative/shared/modal/message_modal' %>
|
||||
</body>
|
||||
</html>
|
@ -1,8 +1,8 @@
|
||||
<% if @_admin_breadcrumbs.present? %>
|
||||
<% if @_breadcrumbs.present? %>
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<% @_admin_breadcrumbs&.each_with_index do |item, index| %>
|
||||
<% if item.url.present? && index != @_admin_breadcrumbs.size - 1 %>
|
||||
<% @_breadcrumbs&.each_with_index do |item, index| %>
|
||||
<% if item.url.present? && index != @_breadcrumbs.size - 1 %>
|
||||
<li class="breadcrumb-item"><%= link_to item.text, item.url %></li>
|
||||
<% else %>
|
||||
<li class="breadcrumb-item active" aria-current="page"><%= item.text %></li>
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in new issue