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:
Will Rossiter 2016-12-01 10:07:07 +13:00 committed by Christopher Joe
parent 87fbd5f781
commit cb6ec11f1b
30 changed files with 311 additions and 215 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -22,6 +22,7 @@
position: absolute;
z-index: 2;
margin-right: 0;
font-size: 24px;
height: 32px;
span {

View File

@ -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) {

View File

@ -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,11 +405,8 @@ $.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');
}
addbutton.removeAttr('disabled');
}
});
}

View File

@ -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.

View File

@ -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.

View File

@ -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, {}));

View File

@ -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),

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)
);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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()
);

View File

@ -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 %>

View File

@ -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 %>

View File

@ -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
);

View File

@ -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>',

View 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 [];
}
}

View File

@ -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>',

View File

@ -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>');

View File

@ -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;

View File

@ -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 {

View File

@ -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>

View File

@ -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>