WIP - Global UI (#785)

* update top bar and collections sidebar UI

* update collection entries UI

* improve global layout

* merge search page into collection page

* enable new entry button

* search fixup

* wip -initial editor update

* update editor scrolling and markdown toolbar position

* wip

* editor toolbar progress

* editor toolbar wip

* finished basic editor toolbar

* add standalone toggle component

* improve markdown toolbar spacing

* add user avatar placeholder

* finish markdown toggle styling

* refactor icon setup, add new icons

* add new icons to markdown editor toolbar

* remove extra app container

* add markdown active mark style

* relation and text widget styling

* widget design updates, basic list/object design update

* widget style updates, image widget improvements

* refactor widget directory, fix file removal

* widget focus styles

* finish editor widget focus styles

* migrate media library modal to react-modal

* wip - migrate editor component form to modal

* wip - move editor component form to modal

* wip - embed plugin forms in the editor

* inline shortcode forms working

* disable react hot loading, its breaking things

* improve shortcode form styles

* make shortcode form collapsible, improve styling

* add close functionality to shortcode blocks

* improve base media library styling

* fix shortcode label

* migrate unstyled workflow to new UI

* wip - reorganizing everything

* more work moving everything

* finish more moving and eliminating stuff

* restructure, remove react-toolbox

* wip - removing old stuff, more restructure

* finish restructure

* wip - css arch

* switch back to test repo

* update react-datetime to ^2.11.0

* remove leftover react-toolbox button

* more restructuring clean-up

* fix UI component directory case

* wip -css editor control style

* wip - consolidate widget styles

* wip - use a single control renderer

* fixed object values breaking

* wip - editor control active styles

* pass control wrapper to widgets

* ensure branch name is trimmed

* wip - improve widget authoring support

* import Map to Widget component

* refactor toolbar buttons

* wip - more widget active styles

* break out editor toggle component

* add local scroll sync back

* update editor toggle icons

* limit editor control pane content width

* fix editor control spacing

* migrate markdown toolbar stickiness to css

* fix markdown toolbar border radius

* temporarily use test backend

* stop markdown toolbar from going to bottom

* restore disabled markdown toolbar buttons for raw

* test markdown widget without focus styles

* more widget updates

* remove card visuals from editor

* disable dragging editor split off screen

* use editorControl component for shortcode fields

* make header site link configurable

* add configurable collection descriptions

* temporarily add example assets

* add basic list view

* remove outdated css mixins

* add and implement search icon

* activate quick add menu

* visualize usable space in editor view

* fix entry close, other improvements

* wip - editorial workflow updates

* some dropshadow and other CSS tweaks

* workflow ui updates

* add worfklow card buttons

* fix workflow card button handlers

* some dropshadow and other CSS tweaks

* make workflow board wider

* center workflow and collection views

* add basic responsiveness

* a bunch of fun UI fixes! a BUNCH! (#875)

* give `.nc-entryEditor-toolbar-mainSection` left and right child divs

* a bunch of fun UI fixes! a BUNCH!

* remove obscure --buttonShadow

* revert to test repo

* fix not found page styling

* allow workflow publishing from any column

* disallow publishing from all columns, with feedback

* fix new entry button

* fix markdown state persisting across entries

* enable simple workflow save and new from editor

* update slug in address bar when saving new entry

* wip - workflow updates, deletion working

* add status change functionality to editor

* wip - improving status change from editor

* editor toolbar back button improvements, loading improvements, cleanup

* progress on the media library UI cleanup

* remove font smothing css

* a quick fix for these buttons

* tweaks

* progress on media library modal— broken FYI

* fix media library functionality, finish migrating footer

* remove media library footer files

* remove leftover css import

* fix media library

* editor publishing functionality complete (unstyled)

* remove leftover loader var from media library

* wip - editor publishing styles

* add status dropdown styling

* editor toolbar style updates

* editor toolbar state improvements

* progress on the media library UI cleanup, style improvements

* finish editorial workflow editor styling

* finish media library styling

* fix config

* add what-input to optimize focus styling

* fix button

* fix navigation blocking for simple workflow

* improve simple workflow publishing

* add avatar dropdown to editor top bar

* style github and test-repo auth pages

* add git gateway auth page styles

* improve editor error styling
This commit is contained in:
Shawn Erquhart
2017-12-07 12:37:10 -05:00
committed by GitHub
parent 41af113d5b
commit cfbf31b130
344 changed files with 6964 additions and 7415 deletions

View File

@ -1,5 +1,5 @@
import Immutable from 'immutable';
import { authenticating, authenticate, authError, logout } from '../../actions/auth';
import { authenticating, authenticate, authError, logout } from 'Actions/auth';
import auth from '../auth';
describe('auth', () => {

View File

@ -1,5 +1,5 @@
import { OrderedMap, fromJS } from 'immutable';
import { configLoaded } from '../../actions/config';
import { configLoaded } from 'Actions/config';
import collections from '../collections';
describe('collections', () => {

View File

@ -1,5 +1,5 @@
import Immutable from 'immutable';
import { configLoaded, configLoading, configFailed } from '../../actions/config';
import { configLoaded, configLoading, configFailed } from 'Actions/config';
import config from '../config';
describe('config', () => {

View File

@ -1,5 +1,5 @@
import { Map, OrderedMap, fromJS } from 'immutable';
import * as actions from '../../actions/entries';
import * as actions from 'Actions/entries';
import reducer from '../entries';
const initialState = OrderedMap({

View File

@ -1,5 +1,5 @@
import { Map, List, fromJS } from 'immutable';
import * as actions from '../../actions/entries';
import * as actions from 'Actions/entries';
import reducer from '../entryDraft';
let initialState = Map({

View File

@ -1,5 +1,5 @@
import Immutable from 'immutable';
import { AUTH_REQUEST, AUTH_SUCCESS, AUTH_FAILURE, AUTH_REQUEST_DONE, LOGOUT } from '../actions/auth';
import { AUTH_REQUEST, AUTH_SUCCESS, AUTH_FAILURE, AUTH_REQUEST_DONE, LOGOUT } from 'Actions/auth';
const auth = (state = null, action) => {
switch (action.type) {

View File

@ -1,10 +1,10 @@
import { OrderedMap, fromJS } from 'immutable';
import { has, get } from 'lodash';
import consoleError from '../lib/consoleError';
import { CONFIG_SUCCESS } from '../actions/config';
import { FILES, FOLDER } from '../constants/collectionTypes';
import { INFERABLE_FIELDS } from '../constants/fieldInference';
import { formatByExtension, formatToExtension, supportedFormats } from '../formats/formats';
import consoleError from 'Lib/consoleError';
import { CONFIG_SUCCESS } from 'Actions/config';
import { FILES, FOLDER } from 'Constants/collectionTypes';
import { INFERABLE_FIELDS } from 'Constants/fieldInference';
import { formatByExtension, formatToExtension, supportedFormats } from 'Formats/formats';
const collections = (state = null, action) => {
const configCollections = action.payload && action.payload.collections;

View File

@ -1,5 +1,5 @@
import Immutable from 'immutable';
import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from '../actions/config';
import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from 'Actions/config';
const config = (state = null, action) => {
switch (action.type) {

View File

@ -1,13 +0,0 @@
import { Map } from 'immutable';
import { SWITCH_VISUAL_MODE } from '../actions/editor';
const editor = (state = Map({ useVisualMode: true }), action) => {
switch (action.type) {
case SWITCH_VISUAL_MODE:
return state.setIn(['useVisualMode'], action.payload);
default:
return state;
}
};
export default editor;

View File

@ -1,5 +1,5 @@
import { Map, List, fromJS } from 'immutable';
import { EDITORIAL_WORKFLOW } from '../constants/publishModes';
import { EDITORIAL_WORKFLOW } from 'Constants/publishModes';
import {
UNPUBLISHED_ENTRY_REQUEST,
UNPUBLISHED_ENTRY_REDIRECT,
@ -10,9 +10,15 @@ import {
UNPUBLISHED_ENTRY_PERSIST_SUCCESS,
UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST,
UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS,
UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE,
UNPUBLISHED_ENTRY_PUBLISH_REQUEST,
} from '../actions/editorialWorkflow';
import { CONFIG_SUCCESS } from '../actions/config';
UNPUBLISHED_ENTRY_PUBLISH_SUCCESS,
UNPUBLISHED_ENTRY_PUBLISH_FAILURE,
UNPUBLISHED_ENTRY_DELETE_REQUEST,
UNPUBLISHED_ENTRY_DELETE_SUCCESS,
UNPUBLISHED_ENTRY_DELETE_FAILURE,
} from 'Actions/editorialWorkflow';
import { CONFIG_SUCCESS } from 'Actions/config';
const unpublishedEntries = (state = null, action) => {
const publishMode = action.payload && action.payload.publish_mode;
@ -65,15 +71,23 @@ const unpublishedEntries = (state = null, action) => {
// Update Optimistically
return state.withMutations((map) => {
map.setIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'metaData', 'status'], action.payload.newStatus);
map.setIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'isPersisting'], true);
map.setIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'isUpdatingStatus'], true);
});
case UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS:
// Update Optimistically
return state.deleteIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'isPersisting']);
case UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE:
return state.setIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'isUpdatingStatus'], false);
case UNPUBLISHED_ENTRY_PUBLISH_REQUEST:
// Update Optimistically
return state.setIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'isPublishing'], true);
case UNPUBLISHED_ENTRY_PUBLISH_SUCCESS:
case UNPUBLISHED_ENTRY_PUBLISH_FAILURE:
return state.withMutations(map => {
map.deleteIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`]);
});
case UNPUBLISHED_ENTRY_DELETE_SUCCESS:
return state.deleteIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`]);
default:

View File

@ -7,9 +7,9 @@ import {
ENTRIES_SUCCESS,
ENTRIES_FAILURE,
ENTRY_DELETE_SUCCESS,
} from '../actions/entries';
} from 'Actions/entries';
import { SEARCH_ENTRIES_SUCCESS } from '../actions/search';
import { SEARCH_ENTRIES_SUCCESS } from 'Actions/search';
let collection;
let loadedEntries;

View File

@ -9,16 +9,16 @@ import {
ENTRY_PERSIST_SUCCESS,
ENTRY_PERSIST_FAILURE,
ENTRY_DELETE_SUCCESS,
} from '../actions/entries';
} from 'Actions/entries';
import {
UNPUBLISHED_ENTRY_PERSIST_REQUEST,
UNPUBLISHED_ENTRY_PERSIST_SUCCESS,
UNPUBLISHED_ENTRY_PERSIST_FAILURE,
} from '../actions/editorialWorkflow';
} from 'Actions/editorialWorkflow';
import {
ADD_ASSET,
REMOVE_ASSET,
} from '../actions/media';
} from 'Actions/media';
const initialState = Map({
entry: Map(),
@ -77,8 +77,16 @@ const entryDraftReducer = (state = Map(), action) => {
}
case ENTRY_PERSIST_SUCCESS:
case ENTRY_DELETE_SUCCESS:
case UNPUBLISHED_ENTRY_PERSIST_SUCCESS:
return state.withMutations((state) => {
state.deleteIn(['entry', 'isPersisting']);
state.set('hasChanged', false);
if (!state.getIn(['entry', 'slug'])) {
state.setIn(['entry', 'slug'], action.payload.slug);
}
});
case ENTRY_DELETE_SUCCESS:
return state.withMutations((state) => {
state.deleteIn(['entry', 'isPersisting']);
state.set('hasChanged', false);

View File

@ -1,9 +1,8 @@
import { Map } from 'immutable';
import { TOGGLE_SIDEBAR, OPEN_SIDEBAR } from '../actions/globalUI';
/*
* Reducer for some global UI state that we want to share between components
* */
const globalUI = (state = Map({ isFetching: false, sidebarIsOpen: true }), action) => {
const globalUI = (state = Map({ isFetching: false }), action) => {
// Generic, global loading indicator
if ((action.type.indexOf('REQUEST') > -1)) {
return state.set('isFetching', true);
@ -13,15 +12,7 @@ const globalUI = (state = Map({ isFetching: false, sidebarIsOpen: true }), actio
) {
return state.set('isFetching', false);
}
switch (action.type) {
case TOGGLE_SIDEBAR:
return state.set('sidebarIsOpen', !state.get('sidebarIsOpen'));
case OPEN_SIDEBAR:
return state.set('sidebarIsOpen', action.payload.open);
default:
return state;
}
return state;
};
export default globalUI;

View File

@ -1,6 +1,5 @@
import auth from './auth';
import config from './config';
import editor from './editor';
import integrations, * as fromIntegrations from './integrations';
import entries, * as fromEntries from './entries';
import editorialWorkflow, * as fromEditorialWorkflow from './editorialWorkflow';
@ -17,7 +16,6 @@ const reducers = {
collections,
search,
integrations,
editor,
entries,
editorialWorkflow,
entryDraft,

View File

@ -1,5 +1,5 @@
import { fromJS } from 'immutable';
import { CONFIG_SUCCESS } from '../actions/config';
import { CONFIG_SUCCESS } from 'Actions/config';
const integrations = (state = null, action) => {
switch (action.type) {

View File

@ -5,6 +5,7 @@ import {
MEDIA_LIBRARY_OPEN,
MEDIA_LIBRARY_CLOSE,
MEDIA_INSERT,
MEDIA_REMOVE_INSERTED,
MEDIA_LOAD_REQUEST,
MEDIA_LOAD_SUCCESS,
MEDIA_LOAD_FAILURE,
@ -14,7 +15,7 @@ import {
MEDIA_DELETE_REQUEST,
MEDIA_DELETE_SUCCESS,
MEDIA_DELETE_FAILURE,
} from '../actions/mediaLibrary';
} from 'Actions/mediaLibrary';
const mediaLibrary = (state = Map({ isVisible: false, controlMedia: Map() }), action) => {
const privateUploadChanged = state.get('privateUpload') !== get(action, ['payload', 'privateUpload']);
@ -46,6 +47,10 @@ const mediaLibrary = (state = Map({ isVisible: false, controlMedia: Map() }), ac
const mediaPath = get(action, ['payload', 'mediaPath']);
return state.setIn(['controlMedia', controlID], mediaPath);
}
case MEDIA_REMOVE_INSERTED: {
const controlID = get(action, ['payload', 'controlID']);
return state.setIn(['controlMedia', controlID], '');
}
case MEDIA_LOAD_REQUEST:
return state.withMutations(map => {
map.set('isLoading', true);

View File

@ -1,7 +1,7 @@
import { Map } from 'immutable';
import { resolvePath } from '../lib/pathHelper';
import { ADD_ASSET, REMOVE_ASSET } from '../actions/media';
import AssetProxy from '../valueObjects/AssetProxy';
import { resolvePath } from 'Lib/pathHelper';
import { ADD_ASSET, REMOVE_ASSET } from 'Actions/media';
import AssetProxy from 'ValueObjects/AssetProxy';
const medias = (state = Map(), action) => {
switch (action.type) {

View File

@ -6,7 +6,7 @@ import {
QUERY_REQUEST,
QUERY_SUCCESS,
SEARCH_CLEAR,
} from '../actions/search';
} from 'Actions/search';
let loadedEntries;
let response;