mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Enhancement Implement import CSV icon and tidy up import forms
Enhancement Tidy up permission icons to new icon library WIP The modal is a short term workaround until the UI is all react based but we wanted to do some cleanup prior to 4 release API Remove ssui.button Enhancement Update buttons to new flat bootstrap style
This commit is contained in:
parent
87fbd5f781
commit
cb6ec11f1b
106
admin/client/dist/styles/bundle.css
vendored
106
admin/client/dist/styles/bundle.css
vendored
@ -9292,9 +9292,12 @@ div.switch-states .switch a.active span{
|
||||
max-height:180px;
|
||||
}
|
||||
|
||||
.cms-content-filters .importSpec{
|
||||
margin-bottom:8px;
|
||||
padding-left:16px;
|
||||
.cms-content-filters .form-group{
|
||||
padding-bottom:0;
|
||||
}
|
||||
|
||||
.cms-content-filters .form-group:after{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.ss-uploadfield .form__field-holder .ss-uploadfield-item{
|
||||
@ -9709,6 +9712,8 @@ body.cms{
|
||||
.ui-tabs .ui-tabs-panel .toolbar--content{
|
||||
margin-left:-20px;
|
||||
margin-right:-20px;
|
||||
padding-left:20px;
|
||||
padding-right:20px;
|
||||
}
|
||||
|
||||
.ui-tabs .ui-tabs-panel>.grid-field:first-child>.toolbar--content{
|
||||
@ -9872,6 +9877,10 @@ body.cms{
|
||||
margin-bottom:13px;
|
||||
}
|
||||
|
||||
.cms-content-header-tabs .btn{
|
||||
vertical-align:top;
|
||||
}
|
||||
|
||||
.panel{
|
||||
overflow:hidden;
|
||||
}
|
||||
@ -10167,6 +10176,10 @@ body.cms{
|
||||
color:#0071c4;
|
||||
}
|
||||
|
||||
.ui-widget-content a.btn-primary{
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.cms-content-tools{
|
||||
background:#f6f7f8;
|
||||
width:300px;
|
||||
@ -10297,17 +10310,6 @@ body.cms{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.cms-content-batchactions-button{
|
||||
display:inline-block;
|
||||
padding:4px 6px;
|
||||
vertical-align:middle;
|
||||
background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#d9d9d9));
|
||||
background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);
|
||||
background-image:linear-gradient(180deg,#fff,#d9d9d9);
|
||||
border:1px solid #aaa;
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.cms-content-batchactions{
|
||||
float:left;
|
||||
position:relative;
|
||||
@ -12045,7 +12047,7 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
padding-right:18px;
|
||||
}
|
||||
|
||||
.cms-menu.collapsed .ss-ui-button.sticky-toggle{
|
||||
.cms-menu.collapsed .sticky-toggle{
|
||||
background-position:12px;
|
||||
width:40px;
|
||||
}
|
||||
@ -12064,7 +12066,7 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
padding-bottom:14px;
|
||||
}
|
||||
|
||||
.cms-menu .ss-ui-button.sticky-toggle{
|
||||
.cms-menu .sticky-toggle{
|
||||
float:left;
|
||||
width:52px;
|
||||
height:52px;
|
||||
@ -12083,19 +12085,19 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
z-index:2;
|
||||
}
|
||||
|
||||
.cms-menu .ss-ui-button.sticky-toggle:hover{
|
||||
.cms-menu .sticky-toggle:hover{
|
||||
box-shadow:0 0 0;
|
||||
}
|
||||
|
||||
.cms-menu .ss-ui-button.sticky-toggle.active{
|
||||
.cms-menu .sticky-toggle.active{
|
||||
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPRJREFUeNq8VNsNgjAULcZ/GIERGKEj8OWnlQ0coSPoBIKffjkCIzBCR8AJ4NQckqb2mhCJNzlpch+H23tPyaZpUlvYTm1kmxHtU87DsSlxWKAGcrpfwNP7H/ebi2uyeEYgqXD0wEiypWghLwANskG8Gjvp+eWKbk0o+nysZ654NctOzsAFMFFcM6aZe5KGXQezMYnxmSjn82poteBgHechmWZO/uv63VcdYQsjV1xKyQFRyVyxo0UnLc4uQdIxZpkrEr11gnm1KPAbaYArSRvv8zFqya4V5BBoSBRklnr9wRMJJbDuiQikKlW8iujvv5FZgAEAPlxgpNhINwUAAAAASUVORK5CYII=);
|
||||
}
|
||||
|
||||
.cms-menu .ss-ui-button.sticky-toggle .ui-button-text{
|
||||
.cms-menu .sticky-toggle .ui-button-text{
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.cms-menu .ss-ui-button.sticky-toggle:hover+.sticky-status-indicator{
|
||||
.cms-menu .sticky-toggle:hover+.sticky-status-indicator{
|
||||
display:block;
|
||||
}
|
||||
|
||||
@ -12857,6 +12859,10 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
border-right:none;
|
||||
}
|
||||
|
||||
.cms .ss-ui-action-tabset.multi ul.ui-tabs-nav li input{
|
||||
margin-left:5px;
|
||||
}
|
||||
|
||||
.cms .ss-ui-action-tabset.multi ul.ui-tabs-nav li a.tab-nav-link{
|
||||
color:#66727d;
|
||||
display:inline-block;
|
||||
@ -13417,14 +13423,10 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.cms .ss-ui-action-tabset.action-menus.ss-tabset .ui-tabs-panel button.ss-ui-button{
|
||||
.cms .ss-ui-action-tabset.action-menus.ss-tabset .ui-tabs-panel .btn,.cms .ss-ui-action-tabset.action-menus.ss-tabset .ui-tabs-panel button.ss-ui-button{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.cms .ss-ui-action-tabset.action-menus.ss-tabset .ui-tabs-panel button.ss-ui-button:active,.cms .ss-ui-action-tabset.action-menus.ss-tabset .ui-tabs-panel button.ss-ui-button:focus,.cms .ss-ui-action-tabset.action-menus.ss-tabset .ui-tabs-panel button.ss-ui-button:hover{
|
||||
box-shadow:none;
|
||||
background-color:#ebedef;
|
||||
outline:none;
|
||||
text-align:left;
|
||||
margin:0 5px;
|
||||
}
|
||||
|
||||
.cms .ss-ui-action-tabset.action-menus.ss-tabset .last .ui-tabs-panel.ss-ui-action-tab{
|
||||
@ -13444,6 +13446,10 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
margin-top:1.2308rem;
|
||||
}
|
||||
|
||||
.permissioncheckboxsetfield_readonly label,.permissioncheckboxset label{
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.cms-content.cms-edit-form .permissioncheckboxset.form-group--no-label>.form__field-holder--no-label,.cms-content.cms-edit-form .permissioncheckboxsetfield_readonly.form-group--no-label>.form__field-holder--no-label{
|
||||
margin-left:0;
|
||||
-webkit-box-flex:0;
|
||||
@ -13456,6 +13462,20 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
list-style-type:none;
|
||||
}
|
||||
|
||||
.permissioncheckboxset .font-icon-cancel-circled,.permissioncheckboxset .font-icon-check-mark-circle,.permissioncheckboxsetfield_readonly .font-icon-cancel-circled,.permissioncheckboxsetfield_readonly .font-icon-check-mark-circle{
|
||||
font-size:18px;
|
||||
position:relative;
|
||||
top:2px;
|
||||
}
|
||||
|
||||
.permissioncheckboxset .font-icon-check-mark-circle,.permissioncheckboxsetfield_readonly .font-icon-check-mark-circle{
|
||||
color:#3fa142;
|
||||
}
|
||||
|
||||
.permissioncheckboxset .font-icon-cancel-circled,.permissioncheckboxsetfield_readonly .font-icon-cancel-circled{
|
||||
color:#d40404;
|
||||
}
|
||||
|
||||
.permissioncheckboxsetfield_readonly li,.permissioncheckboxset li{
|
||||
margin-bottom:4px;
|
||||
}
|
||||
@ -13480,7 +13500,6 @@ li.class-ErrorPage>a .jstree-pageicon{
|
||||
|
||||
.permissioncheckboxsetfield_readonly .optionset li label span{
|
||||
display:inline-block;
|
||||
left:-16px;
|
||||
margin-bottom:-2px;
|
||||
margin-right:6px;
|
||||
}
|
||||
@ -15468,7 +15487,19 @@ div.grid-field__sort-field+.form__fieldgroup-item{
|
||||
}
|
||||
}
|
||||
|
||||
.field.hidden{
|
||||
.grid-field-import.in{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.grid-field-import.in .modal-content{
|
||||
overflow-y:scroll;
|
||||
}
|
||||
|
||||
.grid-field-import.in .modal-dialog{
|
||||
max-height:600px;
|
||||
}
|
||||
|
||||
.field.hidden,.grid-field-import.in .modal-dialog .advanced,.import-form .advanced{
|
||||
display:none;
|
||||
}
|
||||
|
||||
@ -15552,8 +15583,11 @@ div.grid-field__sort-field+.form__fieldgroup-item{
|
||||
}
|
||||
|
||||
.toolbar--content .btn-toolbar,.toolbar--north .btn-toolbar,.toolbar--south .btn-toolbar,.toolbar .btn-toolbar{
|
||||
margin-top:0;
|
||||
margin-bottom:0;
|
||||
margin:0 -5px;
|
||||
}
|
||||
|
||||
.toolbar--content .btn-toolbar .pull-xs-left .btn-primary,.toolbar--north .btn-toolbar .pull-xs-left .btn-primary,.toolbar--south .btn-toolbar .pull-xs-left .btn-primary,.toolbar .btn-toolbar .pull-xs-left .btn-primary{
|
||||
margin-left:5px;
|
||||
}
|
||||
|
||||
.toolbar--north{
|
||||
@ -15569,6 +15603,10 @@ div.grid-field__sort-field+.form__fieldgroup-item{
|
||||
color:#66727d;
|
||||
}
|
||||
|
||||
.toolbar a.btn-primary{
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.toolbar .btn{
|
||||
margin-bottom:0;
|
||||
}
|
||||
@ -15581,6 +15619,11 @@ div.grid-field__sort-field+.form__fieldgroup-item{
|
||||
min-height:auto;
|
||||
}
|
||||
|
||||
.toolbar--content.ss-gridfield-buttonrow{
|
||||
padding-top:0;
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
@media (max-width:991px){
|
||||
.toolbar--content.toolbar--space-save .btn__text{
|
||||
position:absolute;
|
||||
@ -15988,6 +16031,7 @@ input.checkbox,input.radio,input[type=checkbox],input[type=radio]{
|
||||
position:absolute;
|
||||
z-index:2;
|
||||
margin-right:0;
|
||||
font-size:24px;
|
||||
height:32px;
|
||||
}
|
||||
|
||||
|
@ -257,3 +257,23 @@ div.grid-field__sort-field + .form__fieldgroup-item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-field-import.in {
|
||||
display: block;
|
||||
|
||||
.modal-content {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
max-height: 600px;
|
||||
|
||||
.advanced {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.import-form .advanced {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import SilverStripeComponent from 'lib/SilverStripeComponent';
|
||||
import { Modal } from 'react-bootstrap-ss';
|
||||
|
||||
class GridFieldAction extends SilverStripeComponent {
|
||||
constructor(props) {
|
||||
@ -17,6 +18,9 @@ class GridFieldAction extends SilverStripeComponent {
|
||||
}
|
||||
|
||||
handleClick(event) {
|
||||
console.log('handle click');
|
||||
|
||||
return false;
|
||||
this.props.handleClick(event, this.props.record.ID);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
margin-right: 0;
|
||||
font-size: 24px;
|
||||
height: 32px;
|
||||
|
||||
span {
|
||||
|
@ -6,9 +6,14 @@
|
||||
min-height: $toolbar-total-height;
|
||||
|
||||
.btn-toolbar {
|
||||
// TODO Remove '.cms .btn-toolbar' override
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
|
||||
.pull-xs-left .btn-primary {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +35,10 @@
|
||||
color: $body-color-light;
|
||||
}
|
||||
|
||||
a.btn-primary {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@ -43,6 +52,10 @@
|
||||
padding: $spacer-xs;
|
||||
min-height: auto;
|
||||
|
||||
&.ss-gridfield-buttonrow {
|
||||
padding-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
|
||||
|
@ -54,7 +54,7 @@ $.entwine('ss', function($) {
|
||||
content = '<span class="non-sortable"></span>';
|
||||
self.addClass('show-filter').find('.filter-header').show();
|
||||
} else {
|
||||
content = '<button type="button" name="showFilter" class="btn font-icon-search btn--no-text btn--icon-large grid-field__filter-open ss-gridfield-button-filter trigger"></button>';
|
||||
content = '<button type="button" name="showFilter" class="btn btn-secondary font-icon-search btn--no-text btn--icon-large grid-field__filter-open ss-gridfield-button-filter trigger"></button>';
|
||||
self.removeClass('show-filter').find('.filter-header').hide();
|
||||
}
|
||||
|
||||
@ -133,6 +133,34 @@ $.entwine('ss', function($) {
|
||||
}
|
||||
});
|
||||
|
||||
$('.grid-field .action.action_import:button').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var backdrop = $('.modal-backdrop');
|
||||
|
||||
if(backdrop.length < 1) {
|
||||
backdrop = $('<div class="modal-backdrop fade in"></div>');
|
||||
$('body').append(backdrop);
|
||||
} else {
|
||||
backdrop.addClass('fade in').fadeIn();
|
||||
}
|
||||
|
||||
$(this.data('target')).addClass('in');
|
||||
|
||||
// workaround until GridField rewritten into react.
|
||||
var self = this;
|
||||
|
||||
$(this.data('target')).find('[data-dismiss]').on('click', function() {
|
||||
backdrop.fadeOut(function() {
|
||||
$(this).removeClass('in');
|
||||
});
|
||||
|
||||
$(self.data('target')).removeClass('in');
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
$('.grid-field .action:button').entwine({
|
||||
onclick: function(e){
|
||||
var filterState='show'; //filterstate should equal current state.
|
||||
@ -377,12 +405,9 @@ $.entwine('ss', function($) {
|
||||
.find(".action_gridfield_relationfind")
|
||||
.replaceWith(hiddenField);
|
||||
var addbutton = $(this).closest(".grid-field").find(".action_gridfield_relationadd");
|
||||
if(addbutton.data('button')){
|
||||
addbutton.button('enable');
|
||||
} else {
|
||||
|
||||
addbutton.removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1029,19 +1029,6 @@ $.entwine('ss', function($) {
|
||||
}
|
||||
});
|
||||
|
||||
/** Make all buttons "hoverable" with jQuery theming. */
|
||||
$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({
|
||||
onadd: function() {
|
||||
this.addClass('ss-ui-button');
|
||||
if(!this.data('button')) this.button();
|
||||
this._super();
|
||||
},
|
||||
onremove: function() {
|
||||
if(this.data('button')) this.button('destroy');
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Loads the link's 'href' attribute into a panel via ajax,
|
||||
* as opposed to triggering a full page reload.
|
||||
|
@ -2,118 +2,6 @@ import $ from 'jQuery';
|
||||
|
||||
require('../../../thirdparty/jquery-ui/jquery-ui.js');
|
||||
|
||||
/**
|
||||
* Allows icon definition via HTML5 data attrs for easier handling in PHP.
|
||||
*
|
||||
* Adds an alternative appearance so we can toggle back and forth between them
|
||||
* and register event handlers to add custom styling and behaviour. Example use
|
||||
* is in the CMS with the saving buttons - depending on the page's state one of
|
||||
* them will either say "Save draft" or "Saved", and will have different colour.
|
||||
*/
|
||||
$.widget('ssui.button', $.ui.button, {
|
||||
options: {
|
||||
alternate: {
|
||||
icon: null,
|
||||
text: null
|
||||
},
|
||||
showingAlternate: false
|
||||
},
|
||||
|
||||
/**
|
||||
* Switch between the alternate appearances.
|
||||
*/
|
||||
toggleAlternate: function() {
|
||||
if (this._trigger('ontogglealternate')===false) return;
|
||||
|
||||
// Only switch to alternate if it has been enabled through options.
|
||||
if (!this.options.alternate.icon && !this.options.alternate.text) return;
|
||||
|
||||
this.options.showingAlternate = !this.options.showingAlternate;
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust the appearance to fit with the current settings.
|
||||
*/
|
||||
_refreshAlternate: function() {
|
||||
this._trigger('beforerefreshalternate');
|
||||
|
||||
// Only switch to alternate if it has been enabled through options.
|
||||
if (!this.options.alternate.icon && !this.options.alternate.text) return;
|
||||
|
||||
if (this.options.showingAlternate) {
|
||||
this.element.find('.ui-button-icon-primary').hide();
|
||||
this.element.find('.ui-button-text').hide();
|
||||
this.element.find('.ui-button-icon-alternate').show();
|
||||
this.element.find('.ui-button-text-alternate').show();
|
||||
}
|
||||
else {
|
||||
this.element.find('.ui-button-icon-primary').show();
|
||||
this.element.find('.ui-button-text').show();
|
||||
this.element.find('.ui-button-icon-alternate').hide();
|
||||
this.element.find('.ui-button-text-alternate').hide();
|
||||
}
|
||||
|
||||
this._trigger('afterrefreshalternate');
|
||||
},
|
||||
|
||||
/**
|
||||
* Construct button - pulls in options from data attributes.
|
||||
* Injects new elements for alternate appearance (if requested via options).
|
||||
*/
|
||||
_resetButton: function() {
|
||||
var iconPrimary = this.element.data('icon-primary'),
|
||||
iconSecondary = this.element.data('icon-secondary');
|
||||
|
||||
if (!iconPrimary) iconPrimary = this.element.data('icon');
|
||||
|
||||
// TODO Move prefix out of this method, without requriing it for every icon definition in a data attr
|
||||
if(iconPrimary) this.options.icons.primary = 'btn-icon-' + iconPrimary;
|
||||
if(iconSecondary) this.options.icons.secondary = 'btn-icon-' + iconSecondary;
|
||||
|
||||
$.ui.button.prototype._resetButton.call(this);
|
||||
|
||||
// Pull options from data attributes. Overriden by explicit options given on widget creation.
|
||||
if (!this.options.alternate.text) {
|
||||
this.options.alternate.text = this.element.data('text-alternate');
|
||||
}
|
||||
if (!this.options.alternate.icon) {
|
||||
this.options.alternate.icon = this.element.data('icon-alternate');
|
||||
}
|
||||
if (!this.options.showingAlternate) {
|
||||
this.options.showingAlternate = this.element.hasClass('ss-ui-alternate');
|
||||
}
|
||||
|
||||
// Create missing elements.
|
||||
if (this.options.alternate.icon) {
|
||||
this.buttonElement.append(
|
||||
"<span class='ui-button-icon-alternate ui-button-icon-primary ui-icon btn-icon-"
|
||||
+ this.options.alternate.icon + "'></span>"
|
||||
);
|
||||
}
|
||||
if (this.options.alternate.text) {
|
||||
this.buttonElement.append(
|
||||
"<span class='ui-button-text-alternate ui-button-text'>" + this.options.alternate.text + "</span>"
|
||||
);
|
||||
}
|
||||
|
||||
this._refreshAlternate();
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
$.ui.button.prototype.refresh.call(this);
|
||||
|
||||
this._refreshAlternate();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.element.find('.ui-button-text-alternate').remove();
|
||||
this.element.find('.ui-button-icon-alternate').remove();
|
||||
|
||||
$.ui.button.prototype.destroy.call( this );
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Extends jQueryUI dialog with iframe abilities (and related resizing logic),
|
||||
* and sets some CMS-wide defaults.
|
||||
|
@ -7,8 +7,12 @@ function recordsReducer(state = initialState, action) {
|
||||
let records = null;
|
||||
let recordType = null;
|
||||
let record = null;
|
||||
let apolloRecordRelation = {};
|
||||
|
||||
switch (action.type) {
|
||||
case 'APOLLO_QUERY_RESULT':
|
||||
|
||||
return state;
|
||||
|
||||
case ACTION_TYPES.CREATE_RECORD:
|
||||
return deepFreeze(Object.assign({}, state, {}));
|
||||
|
@ -5,7 +5,6 @@ const initialState = deepFreeze({});
|
||||
|
||||
export default function schemaReducer(state = initialState, action = null) {
|
||||
switch (action.type) {
|
||||
|
||||
case ACTION_TYPES.SET_SCHEMA: {
|
||||
return deepFreeze(Object.assign({}, state, {
|
||||
[action.payload.id]: Object.assign({}, state[action.payload.id], action.payload),
|
||||
|
@ -5,6 +5,10 @@
|
||||
margin-top: $spacer-y;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cms-content.cms-edit-form & {
|
||||
&.form-group--no-label > .form__field-holder--no-label {
|
||||
@include make-col-offset(0);
|
||||
@ -17,6 +21,21 @@
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.font-icon-check-mark-circle,
|
||||
.font-icon-cancel-circled {
|
||||
font-size: 18px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.font-icon-check-mark-circle {
|
||||
color: $brand-success;
|
||||
}
|
||||
|
||||
.font-icon-cancel-circled {
|
||||
color: $brand-danger;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 4px;
|
||||
|
||||
@ -36,12 +55,13 @@ green tick icon as a background this is created using gulp-sprity generated clas
|
||||
input {
|
||||
display:none;
|
||||
}
|
||||
|
||||
|
||||
label {
|
||||
cursor: default;
|
||||
position:relative; // needs to be set to position the span element correctly
|
||||
span { // background set using gulp-sprity generated classes (background is green tick icon)
|
||||
display: inline-block;
|
||||
left:$grid-x*-2;
|
||||
margin-bottom: -2px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
@ -75,6 +75,9 @@ $border: 1px solid darken(#D9D9D9, 15%);
|
||||
border-bottom-right-radius: 3px;
|
||||
border-right:none;
|
||||
}
|
||||
input {
|
||||
margin-left: 5px;
|
||||
}
|
||||
a.tab-nav-link{
|
||||
color:$color-text;
|
||||
display:inline-block;
|
||||
@ -312,13 +315,11 @@ $border: 1px solid darken(#D9D9D9, 15%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
button.ss-ui-button{
|
||||
button.ss-ui-button,
|
||||
.btn {
|
||||
width: 100%;
|
||||
&:hover, &:focus, &:active{
|
||||
box-shadow: none;
|
||||
background-color: darken($tab-panel-texture-color,4%);
|
||||
outline:none;
|
||||
}
|
||||
text-align: left;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
/* Re-align last tab */
|
||||
|
@ -800,9 +800,12 @@ div.switch-states{
|
||||
max-height: 180px;
|
||||
}
|
||||
|
||||
.importSpec {
|
||||
margin-bottom: 8px;
|
||||
padding-left: 16px;
|
||||
.form-group {
|
||||
padding-bottom: 0;
|
||||
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.ss-ui-button.sticky-toggle {
|
||||
.sticky-toggle {
|
||||
background-position: 12px center;
|
||||
width: 40px;
|
||||
}
|
||||
@ -175,7 +175,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.ss-ui-button.sticky-toggle {
|
||||
.sticky-toggle {
|
||||
float: left;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
|
@ -490,6 +490,8 @@ body.cms {
|
||||
.toolbar--content {
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
> .grid-field:first-child > .toolbar--content {
|
||||
@ -675,6 +677,10 @@ body.cms {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
@ -1041,6 +1047,10 @@ body.cms {
|
||||
|
||||
.ui-widget-content a {
|
||||
color: $link-color;
|
||||
|
||||
&.btn-primary {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1188,14 +1198,6 @@ body.cms {
|
||||
/**
|
||||
* CMS Batch actions
|
||||
*/
|
||||
.cms-content-batchactions-button {
|
||||
display: inline-block;
|
||||
padding: 4px 6px;
|
||||
vertical-align: middle;
|
||||
background-image: linear-gradient(to bottom, #fff, #D9D9D9);
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.cms-content-batchactions {
|
||||
float: left;
|
||||
@ -1314,6 +1316,7 @@ form.member-profile-form {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
|
||||
.advanced h4 {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
@ -34,8 +34,7 @@ class CMSProfileController extends LeftAndMain
|
||||
$form->Fields()->push(new HiddenField('ID', null, Member::currentUserID()));
|
||||
$form->Actions()->push(
|
||||
FormAction::create('save', _t('CMSMain.SAVE', 'Save'))
|
||||
->addExtraClass('ss-ui-button ss-ui-action-constructive')
|
||||
->setAttribute('data-icon', 'accept')
|
||||
->addExtraClass('btn-primary font-icon-save')
|
||||
->setUseButtonTag(true)
|
||||
);
|
||||
|
||||
|
@ -66,7 +66,7 @@ class GroupImportForm extends Form
|
||||
|
||||
if (!$actions) {
|
||||
$action = new FormAction('doImport', _t('SecurityAdmin_MemberImportForm.BtnImport', 'Import from CSV'));
|
||||
$action->addExtraClass('ss-ui-button');
|
||||
$action->addExtraClass('btn btn-secondary-outline font-icon-upload');
|
||||
$actions = new FieldList($action);
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ class MemberImportForm extends Form
|
||||
|
||||
if (!$actions) {
|
||||
$action = new FormAction('doImport', _t('SecurityAdmin_MemberImportForm.BtnImport', 'Import from CSV'));
|
||||
$action->addExtraClass('btn btn-secondary-outline ss-ui-button');
|
||||
$action->addExtraClass('btn btn-secondary-outline font-icon-upload');
|
||||
$actions = new FieldList($action);
|
||||
}
|
||||
|
||||
|
@ -246,9 +246,9 @@ abstract class ModelAdmin extends LeftAndMain
|
||||
$context->getSearchFields(),
|
||||
new FieldList(
|
||||
FormAction::create('search', _t('MemberTableField.APPLY_FILTER', 'Apply Filter'))
|
||||
->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive'),
|
||||
->setUseButtonTag(true)->addExtraClass('btn-primary'),
|
||||
ResetFormAction::create('clearsearch', _t('ModelAdmin.RESET', 'Reset'))
|
||||
->setUseButtonTag(true)
|
||||
->setUseButtonTag(true)->addExtraClass('btn-secondary'),
|
||||
),
|
||||
new RequiredFields()
|
||||
);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
<div class="cms-content-header-tabs cms-tabset-nav-primary ss-ui-tabs-nav">
|
||||
<% if $SearchForm || $ImportForm %>
|
||||
<button id="filters-button" class="icon-button font-icon-search no-text" title="<%t CMSPagesController_Tools_ss.FILTER 'Filter' %>"></button>
|
||||
<button id="filters-button" class="btn btn-secondary font-icon-search no-text" title="<%t CMSPagesController_Tools_ss.FILTER 'Filter' %>"></button>
|
||||
<% end_if %>
|
||||
<ul class="cms-tabset-nav-primary">
|
||||
<% loop $ManagedModelTabs %>
|
||||
|
@ -4,10 +4,5 @@
|
||||
<h3 class="cms-panel-header"><%t ModelAdmin_Tools_ss.FILTER 'Filter' %></h3>
|
||||
$SearchForm
|
||||
<% end_if %>
|
||||
|
||||
<% if $ImportForm %>
|
||||
<h3 class="cms-panel-header"><%t ModelAdmin_Tools_ss.IMPORT 'Import' %></h3>
|
||||
$ImportForm
|
||||
<% end_if %>
|
||||
</div>
|
||||
<% end_if %>
|
||||
|
@ -288,21 +288,19 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
||||
if ($canEdit) {
|
||||
$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
|
||||
->setUseButtonTag(true)
|
||||
->addExtraClass('ss-ui-action-constructive')
|
||||
->setAttribute('data-icon', 'accept'));
|
||||
->addExtraClass('btn-primary font-icon-save'));
|
||||
}
|
||||
|
||||
if ($canDelete) {
|
||||
$actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))
|
||||
->setUseButtonTag(true)
|
||||
->addExtraClass('ss-ui-action-destructive action-delete'));
|
||||
->addExtraClass('btn-secondary action-delete'));
|
||||
}
|
||||
} else { // adding new record
|
||||
//Change the Save label to 'Create'
|
||||
$actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))
|
||||
->setUseButtonTag(true)
|
||||
->addExtraClass('ss-ui-action-constructive')
|
||||
->setAttribute('data-icon', 'add'));
|
||||
->addExtraClass('btn-primary font-icon-plus'));
|
||||
|
||||
// Add a Cancel link which is a button-like link and link back to one level up.
|
||||
$crumbs = $this->Breadcrumbs();
|
||||
@ -310,7 +308,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
||||
$oneLevelUp = $crumbs->offsetGet($crumbs->count() - 2);
|
||||
$text = sprintf(
|
||||
"<a class=\"%s\" href=\"%s\">%s</a>",
|
||||
"crumb ss-ui-button ss-ui-action-destructive cms-panel-link ui-corner-all", // CSS classes
|
||||
"crumb btn btn-secondary font-icon-trash cms-panel-link", // CSS classes
|
||||
$oneLevelUp->Link, // url
|
||||
_t('GridFieldDetailForm.CancelBtn', 'Cancel') // label
|
||||
);
|
||||
|
@ -63,8 +63,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
||||
'export',
|
||||
null
|
||||
);
|
||||
$button->setAttribute('data-icon', 'download-csv');
|
||||
$button->addExtraClass('no-ajax font-icon-down-circled action_export');
|
||||
$button->addExtraClass('btn btn-secondary no-ajax font-icon-down-circled action_export');
|
||||
$button->setForm($gridField->getForm());
|
||||
return array(
|
||||
$this->targetFragment => '<p class="grid-csv-button">' . $button->Field() . '</p>',
|
||||
|
77
src/Forms/GridField/GridFieldImportButton.php
Normal file
77
src/Forms/GridField/GridFieldImportButton.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms\GridField;
|
||||
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\Forms\Form;
|
||||
use SilverStripe\Forms\CompositeField;
|
||||
|
||||
|
||||
class GridFieldImportButton implements GridField_HTMLProvider
|
||||
{
|
||||
/**
|
||||
* Fragment to write the button to
|
||||
*/
|
||||
protected $targetFragment;
|
||||
|
||||
/**
|
||||
* @var CompositeField
|
||||
*/
|
||||
protected $importFormField;
|
||||
|
||||
/**
|
||||
* @param string $targetFragment The HTML fragment to write the button into
|
||||
*/
|
||||
public function __construct($targetFragment = "after", $importFormField = null)
|
||||
{
|
||||
$this->targetFragment = $targetFragment;
|
||||
$this->importFormField = $importFormField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Place the export button in a <p> tag below the field
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getHTMLFragments($gridField)
|
||||
{
|
||||
$button = new GridField_FormAction(
|
||||
$gridField,
|
||||
'import',
|
||||
_t('TableListField.CSVIMPORT', 'Import CSV'),
|
||||
'import',
|
||||
null
|
||||
);
|
||||
$button->addExtraClass('btn btn-secondary no-ajax font-icon-upload action_import');
|
||||
$button
|
||||
->setAttribute('data-toggle', "modal")
|
||||
->setAttribute('data-target', "#". $gridField->ID() . ' .grid-field-import');
|
||||
|
||||
$button->setForm($gridField->getForm());
|
||||
$extra = null;
|
||||
|
||||
if($this->importFormField) {
|
||||
$extra = ($this->importFormField instanceof Form)
|
||||
? $this->importFormField->forTemplate()
|
||||
: $this->importFormField->Field();
|
||||
}
|
||||
|
||||
return array(
|
||||
$this->targetFragment => ($extra) ? '<p class="grid-csv-button">' . $button->Field() . '</p>'.$extra : '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* export is an action button
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getActions($gridField)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -65,9 +65,7 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
|
||||
null
|
||||
);
|
||||
|
||||
$button->setAttribute('data-icon', 'grid_print');
|
||||
$button->addExtraClass('gridfield-button-print');
|
||||
$button->addExtraClass('font-icon-print');
|
||||
$button->addExtraClass('font-icon-print btn btn-secondary');
|
||||
|
||||
return array(
|
||||
$this->targetFragment => '<p class="grid-print-button">' . $button->Field() . '</p>',
|
||||
|
@ -191,7 +191,7 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
|
||||
&& $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldFilterHeader')) {
|
||||
$field = new LiteralField(
|
||||
$fieldName,
|
||||
'<button type="button" name="showFilter" class="btn font-icon-search btn--no-text btn--icon-large grid-field__filter-open"></button>'
|
||||
'<button type="button" name="showFilter" class="btn btn-secondary font-icon-search btn--no-text btn--icon-large grid-field__filter-open"></button>'
|
||||
);
|
||||
} else {
|
||||
$field = new LiteralField($fieldName, '<span class="non-sortable">' . $title . '</span>');
|
||||
|
@ -37,8 +37,7 @@ class VersionedGridFieldItemRequest extends GridFieldDetailForm_ItemRequest
|
||||
_t('VersionedGridFieldItemRequest.BUTTONPUBLISH', 'Publish')
|
||||
)
|
||||
->setUseButtonTag(true)
|
||||
->addExtraClass('ss-ui-action-constructive')
|
||||
->setAttribute('data-icon', 'accept');
|
||||
->addExtraClass('btn btn-primary font-icon-rocket');
|
||||
|
||||
// Insert after save
|
||||
if ($actions->fieldByName('action_doSave')) {
|
||||
@ -61,7 +60,7 @@ class VersionedGridFieldItemRequest extends GridFieldDetailForm_ItemRequest
|
||||
'VersionedGridFieldItemRequest.BUTTONUNPUBLISHDESC',
|
||||
'Remove this record from the published site'
|
||||
))
|
||||
->addExtraClass('ss-ui-action-destructive')
|
||||
->addExtraClass('btn-secondary')
|
||||
);
|
||||
}
|
||||
|
||||
@ -77,7 +76,7 @@ class VersionedGridFieldItemRequest extends GridFieldDetailForm_ItemRequest
|
||||
'VersionedGridFieldItemRequest.BUTTONARCHIVEDESC',
|
||||
'Unpublish and send to archive'
|
||||
))
|
||||
->addExtraClass('delete ss-ui-action-destructive')
|
||||
->addExtraClass('delete btn-secondary')
|
||||
);
|
||||
}
|
||||
return $actions;
|
||||
|
@ -236,7 +236,7 @@ class PermissionCheckboxSetField extends FormField
|
||||
}
|
||||
|
||||
$inheritMessage = '<small>' . $inheritMessage . '</small>';
|
||||
$icon = ($checked) ? 'accept' : 'decline';
|
||||
$icon = ($checked) ? 'check-mark-circle' : 'cancel-circled';
|
||||
|
||||
// If the field is readonly, add a span that will replace the disabled checkbox input
|
||||
if ($this->readonly) {
|
||||
@ -244,7 +244,7 @@ class PermissionCheckboxSetField extends FormField
|
||||
. "<input id=\"$itemID\"$disabled name=\"$this->name[$code]\" type=\"checkbox\""
|
||||
. " value=\"$code\"$checked class=\"checkbox\" />"
|
||||
. "<label {$title}for=\"$itemID\">"
|
||||
. "<span class=\"ui-button-icon-primary ui-icon btn-icon-$icon\"></span>"
|
||||
. "<span class=\"font-icon-$icon\"></span>"
|
||||
. "$value$inheritMessage</label>"
|
||||
. "</li>\n";
|
||||
} else {
|
||||
|
@ -1,3 +1,3 @@
|
||||
<a href="$NewLink" class="action action-detail ss-ui-action-constructive ss-ui-button ui-button ui-widget ui-state-default ui-corner-all new new-link" data-icon="add">
|
||||
<a href="$NewLink" class="action action-detail btn btn-primary font-icon-plus-circled new new-link">
|
||||
$ButtonName
|
||||
</a>
|
||||
|
@ -0,0 +1,19 @@
|
||||
<div class="modal fade grid-field-import" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content"><div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<% if $URL %>
|
||||
<iframe src="$URL" id="MemberImportFormIframe" width="100%%" height="400px" frameBorder="0"></iframe>
|
||||
<% else %>
|
||||
$ImportForm
|
||||
<% end_if %>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary-outline font-icon-check-mark" data-dismiss="modal"><%t GridField.DONE 'Done' %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user