Skip to content

Commit

Permalink
# This is a combination of 3 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

Fix 4305 builder changes

# This is the commit message #2:

add delete confirm modal to builder

# This is the commit message #3:

implement some points added to the issue

* Rename Column title, to Immersive Content
* change tooltip text and icons (chevron-left, down) of collapse/expand button to  "Expand All"/"Compress All"
* When empty view:
* all buttons in builder toolbar are disabled
* add a gray background on the right
* add No Contents Available string in the left panel
* add a gray line under the toolbar
* Change icon drag and drop, (small burger menu)
* Each title must be customizable, also add onBlur events for state updates and use internal state
  • Loading branch information
MV88 committed Oct 11, 2019
1 parent 054f893 commit f39a220
Show file tree
Hide file tree
Showing 29 changed files with 538 additions and 132 deletions.
39 changes: 38 additions & 1 deletion web/client/actions/__tests__/geostory-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
LOAD_GEOSTORY_ERROR, loadGeostoryError,
editResource, EDIT_RESOURCE,
remove, REMOVE,
toggleCardPreview, TOGGLE_CARD_PREVIEW, SAVE, saveStory
selectCard, SELECT_CARD,
toggleCardPreview, TOGGLE_CARD_PREVIEW,
SAVE, saveStory,
moved, MOVED,
move, MOVE
} from '../geostory';

describe('test geostory action creators', () => {
Expand Down Expand Up @@ -115,4 +119,37 @@ describe('test geostory action creators', () => {
expect(retVal.type).toBe(SAVE);
expect(retVal.resource).toBe(SAMPLE_RESOURCE);
});
it('selectCard', () => {
const card = "id-card";
const retVal = selectCard(card);
expect(retVal).toExist();
expect(retVal.type).toBe(SELECT_CARD);
expect(retVal.card).toBe(card);
});
it('move', () => {
const source = "source";
const target = "target";
const position = 0;
const newId = "newId";
const updatePath = "updatePath";
const retVal = move(source, target, position, newId, updatePath);
expect(retVal).toExist();
expect(retVal.type).toBe(MOVE);
expect(retVal.source).toBe(source);
expect(retVal.target).toBe(target);
expect(retVal.position).toBe(position);
expect(retVal.newId).toBe(newId);
expect(retVal.updatePath).toBe(updatePath);
});
it('moved', () => {
const source = "source";
const target = "target";
const position = 0;
const retVal = moved(source, target, position);
expect(retVal).toExist();
expect(retVal.type).toBe(MOVED);
expect(retVal.source).toBe(source);
expect(retVal.target).toBe(target);
expect(retVal.position).toBe(position);
});
});
54 changes: 29 additions & 25 deletions web/client/actions/geostory.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
*/
import isString from 'lodash/isString';
import uuid from "uuid";
import { Modes, getDefaultSectionTemplate, isSection } from '../utils/GeoStoryUtils';
import { createPathSelector } from '../selectors/geostory';
import { Modes, getDefaultSectionTemplate } from '../utils/GeoStoryUtils';

export const ADD = "GEOSTORY:ADD";
export const ADD_RESOURCE = "GEOSTORY:ADD_RESOURCE";
Expand All @@ -30,6 +29,7 @@ export const TOGGLE_CARD_PREVIEW = "GEOSTORY:TOGGLE_CARD_PREVIEW";
export const UPDATE = "GEOSTORY:UPDATE";
export const UPDATE_CURRENT_PAGE = "GEOSTORY:UPDATE_CURRENT_PAGE";
export const MOVED = "GEOSTORY:MOVED";
export const MOVE = "GEOSTORY:MOVE";

/**
* Adds an entry to current story. The entry can be a section, a content or anything to append in an array (even sub-content)
Expand Down Expand Up @@ -153,29 +153,33 @@ export const updateCurrentPage = ({sectionId}) => ({
type: UPDATE_CURRENT_PAGE,
sectionId
});

/**
* sort cards in builder content list after drag & drop events
* @param {string} source source path that is being dragged
* @param {string} target target path in the story, where to place dragged item
* @param {string|number} position new position of the target drop
* @param {string} newId id of the new card that is created, it is temporary
* @param {string} updatePath path to the new item where old id will be restored
*/
export const move = (source, target, position, newId, updatePath) => ({
type: MOVE,
source,
target,
position,
newId,
updatePath
});

/**
* clean up states after sort operation
* @param {string} source source path that is being dragged
* @param {string} target target path in the story, where to place dragged item
* @param {string|number} position new position of the target drop
*/
export const move = (source, target, position, newId, updatePath) => {
return (dispatch, getState) => {
const state = getState();
const current = createPathSelector(source)(state);
/* const newId = uuid();
let updatePath;
if (isSection(current.type)) {
updatePath = `sections[{"id": "${newId}"}]`;
} else {
updatePath = `sections[{"id": "${newId}"}]`;
}*/
dispatch(remove(source));
dispatch(add(target, position > 0 ? position - 1 : 0, { ...current, id: newId }));
dispatch(update(updatePath, {id: current.id}, "merge" ));
dispatch({
type: MOVED,
source,
target,
position
});
};
};
export const moved = (source, target, position) => ({
type: MOVED,
source,
target,
position
});
30 changes: 19 additions & 11 deletions web/client/components/geostory/builder/Builder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class Builder extends React.Component {
story: PropTypes.object,
mode: PropTypes.oneOf(lists.Modes),
onToggleCardPreview: PropTypes.func,
cardPreviewEnabled: PropTypes.bool,
isCollapsed: PropTypes.bool,
isToolbarEnabled: PropTypes.bool,
scrollTo: PropTypes.func,
setEditing: PropTypes.func,
currentPage: PropTypes.object,
Expand All @@ -47,7 +48,8 @@ class Builder extends React.Component {
setEditing: () => {},
onToggleCardPreview: () => {},
story: {},
cardPreviewEnabled: true,
isCollapsed: true,
isToolbarEnabled: true,
onSort: () => {}
};

Expand All @@ -57,7 +59,8 @@ class Builder extends React.Component {
scrollTo,
setEditing,
mode,
cardPreviewEnabled,
isCollapsed,
isToolbarEnabled,
onToggleCardPreview,
currentPage,
selected,
Expand Down Expand Up @@ -86,7 +89,7 @@ class Builder extends React.Component {
className="square-button-md no-border"
tooltipId="geostory.builder.delete"
confirmTitle={<Message msgId="geostory.contentToolbar.removeConfirmTitle" />}
disabled= {!selected}
disabled= {!isToolbarEnabled || !selected }
confirmContent={<Message msgId="geostory.contentToolbar.removeConfirmContent" />}
onClick={ () => {
onRemove(selected && `sections[{ "id": "${selected}" }]` || "");
Expand All @@ -95,7 +98,7 @@ class Builder extends React.Component {
{
tooltipId: "geostory.builder.preview",
glyph: "eye-open",
disabled: story.sections && story.sections.length === 0,
disabled: !isToolbarEnabled,
onClick: () => setEditing(mode === Modes.VIEW)
},
{
Expand All @@ -104,24 +107,29 @@ class Builder extends React.Component {
disabled: true // TODO: restore when implemented
},
{
tooltipId: `geostory.builder.${cardPreviewEnabled ? "hide" : "show"}`,
glyph: "list-alt",
bsStyle: cardPreviewEnabled ? "success" : "primary",
tooltipId: `geostory.builder.${isCollapsed ? "expandAll" : "collapseAll"}`,
glyph: isCollapsed ? "chevron-left" : "chevron-down",
bsStyle: "primary",
disabled: !isToolbarEnabled,
onClick: () => onToggleCardPreview()
}
]}/>
</div>
}>
<SectionsPreview
{isToolbarEnabled ? <SectionsPreview
currentPage={currentPage}
scrollTo={scrollTo}
onSelect={onSelect}
selected={selected}
onUpdate={onUpdate}
cardPreviewEnabled={cardPreviewEnabled}
isCollapsed={isCollapsed}
sections={story && story.sections}
onSort={onSort}
/>
/> : <div className="ms-story-empty-content-parent">
<div className="ms-story-empty-content-child">
<Message msgId="geostory.builder.noContents" />
</div>
</div>}
</BorderLayout>
);
}
Expand Down
49 changes: 30 additions & 19 deletions web/client/components/geostory/builder/SectionsPreview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import React from 'react';
import capitalize from "lodash/capitalize";
import get from 'lodash/get';
import find from 'lodash/find';
import ContentEditable from 'react-contenteditable';
import {Glyphicon} from 'react-bootstrap';
import compose from 'recompose/compose';
import withProps from 'recompose/withProps';
import { connect } from "react-redux";
import { createSelector } from 'reselect';
import uuid from "uuid";

import TitleEditable from './TitleEditable';

import { resourcesSelector } from '../../../selectors/geostory';
import Toolbar from '../../misc/toolbar/Toolbar';
import SideGrid from '../../misc/cardgrids/SideGrid';
Expand All @@ -25,7 +26,7 @@ import draggableContainer from '../../misc/enhancers/draggableContainer';
import draggableComponent from '../../misc/enhancers/draggableComponent';

const DraggableSideGrid = draggableContainer(SideGrid);
const DraggableSideCard = draggableComponent(SideCard);
const DraggableSideCard = draggableComponent((props) => <SideCard {...props} dragSymbol={<Glyphicon glyph="menu-hamburger"/>} />);

/**
* avoid triggering other events like card selection
Expand All @@ -37,6 +38,7 @@ const scrollToHandler = (id, scrollTo) => (evt) => {
scrollTo(id);
};


/**
* Renders icon for the Section or content provided
* @prop {object} props passed to this icon
Expand Down Expand Up @@ -72,7 +74,7 @@ const ConnectedIcon = compose(

const previewContents = {
title: () => null,
paragraph: ({ id, contents, cardPreviewEnabled, scrollTo, onSort }) => (
paragraph: ({ id, contents, isCollapsed, scrollTo, onSort, sectionId, onUpdate }) => (
<div style={{ position: 'relative' }}>
<DraggableSideGrid
containerId={id}
Expand Down Expand Up @@ -106,20 +108,22 @@ const previewContents = {
onClick: scrollToHandler(content.id, scrollTo)
}
]} />,
title: capitalize(content.type),
title: <TitleEditable
title={content.title || capitalize(content.type)}
onUpdate={(text) => onUpdate(`sections[{"id": "${sectionId}"}].contents[{"id": "${contents[0].id}"}].contents[{"id": "${content.id}"}]`, {title: text}, "merge")}/>,
description: `type: ${content.type}`,
body: PreviewContents
&& <PreviewContents
id={id}
onSort={onSort}
scrollTo={scrollTo}
cardPreviewEnabled={cardPreviewEnabled}
isCollapsed={isCollapsed}
contents={content.contents}/>
};
})} />
</div>
),
column: ({ sectionId, id, contents, cardPreviewEnabled, scrollTo, onSort }) => (
column: ({ sectionId, id, contents, isCollapsed, scrollTo, onSort, onUpdate }) => (
<div style={{ position: 'relative' }}>
<DraggableSideGrid
containerId={id}
Expand Down Expand Up @@ -153,15 +157,17 @@ const previewContents = {
onClick: scrollToHandler(content.id, scrollTo)
}
]} />,
title: capitalize(content.type),
title: <TitleEditable
title={content.title || capitalize(content.type)}
onUpdate={(text) => onUpdate(`sections[{"id": "${sectionId}"}].contents[{"id": "${id}"}].contents[{"id": "${content.id}"}]`, {title: text}, "merge")}/>,
description: `type: ${content.type}`,
body: cardPreviewEnabled && PreviewContents
body: !isCollapsed && PreviewContents
&& <PreviewContents id={id} onSort={onSort}/>
};
})} />
</div>
),
immersive: ({ id, contents, cardPreviewEnabled, scrollTo, onSort }) => (
immersive: ({ id, contents, isCollapsed, scrollTo, onUpdate, onSort }) => (
<div style={{ position: 'relative' }}>
<DraggableSideGrid
containerId={id}
Expand Down Expand Up @@ -195,15 +201,18 @@ const previewContents = {
onClick: scrollToHandler(content.id, scrollTo)
}
]} />,
title: capitalize(content.type),
title: <TitleEditable
title={content.title || capitalize(content.type)}
onUpdate={(text) => onUpdate(`sections[{"id": "${id}"}].contents[{"id":"${content.id}"}]`, {title: text}, "merge")}/>,
description: `type: ${content.type}`,
body: PreviewContents
&& <PreviewContents
id={content.id}
sectionId={id}
onSort={onSort}
onUpdate={onUpdate}
scrollTo={scrollTo}
cardPreviewEnabled={cardPreviewEnabled}
isCollapsed={isCollapsed}
contents={content.contents}/>
};
})} />
Expand All @@ -217,7 +226,7 @@ const previewContents = {
*/
const sectionToItem = ({
scrollTo,
cardPreviewEnabled = false,
isCollapsed = false,
currentPage,
onSort,
onSelect,
Expand Down Expand Up @@ -250,17 +259,19 @@ const sectionToItem = ({
tooltipId: "geostory.zoomToContent"
}
]} />,
title: <ContentEditable html={title} onChange={evt => {
onUpdate(`sections[{"id": "${id}"}]`, {title: evt.target.value}, "merge");
}}/>,
title: <TitleEditable title={title} onUpdate={(text) => onUpdate(`sections[{"id": "${id}"}]`, {title: text}, "merge")}/>,
description: `type: ${type}`,
body: !cardPreviewEnabled ?
body: !isCollapsed ?
PreviewContents &&
<PreviewContents
id={id}
sectionId={id}
onSort={onSort}
onUpdate={onUpdate}
onSelect={onSelect}
selected={selected}
scrollTo={scrollTo}
cardPreviewEnabled={cardPreviewEnabled}
isCollapsed={isCollapsed}
contents={contents}/>
: null
};
Expand All @@ -272,7 +283,7 @@ const sectionToItem = ({
* @SectionsPreview
* @param {object[]} [sections=[]] Array of sections to display
*/
export default ({ sections = [], scrollTo, onSelect = () => {}, cardPreviewEnabled, currentPage, selected, onSort, onUpdate }) => (<DraggableSideGrid
export default ({ sections = [], scrollTo, onSelect = () => {}, isCollapsed, currentPage, selected, onSort, onUpdate }) => (<DraggableSideGrid
isDraggable
onSort={(sortIdTo, sortIdFrom, itemDataTo, itemDataFrom) => {
if (itemDataTo.containerId === 'story-sections'
Expand All @@ -290,5 +301,5 @@ export default ({ sections = [], scrollTo, onSelect = () => {}, cardPreviewEnabl
cardComponent={DraggableSideCard}
size="sm"
items={
sections.map(sectionToItem({ currentPage, onSelect, cardPreviewEnabled, scrollTo, selected, onUpdate, onSort }))
sections.map(sectionToItem({ currentPage, onSelect, isCollapsed, scrollTo, selected, onUpdate, onSort }))
} />);
Loading

0 comments on commit f39a220

Please sign in to comment.