Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/base/src/commands/BaseCommandIDs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ export const showIdentifyPanelTab = 'jupytergis:showIdentifyPanelTab';

// Story maps
export const addStorySegment = 'jupytergis:addStorySegment';
export const toggleStoryPresentationMode =
'jupytergis:toggleStoryPresentationMode';
47 changes: 47 additions & 0 deletions packages/base/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ export function addCommands(
Private.removeSelectedItems(model, 'layer', selection => {
model?.removeLayer(selection);
});

commands.notifyCommandChanged(CommandIDs.toggleStoryPresentationMode);
},
});

Expand Down Expand Up @@ -1072,10 +1074,55 @@ export function addCommands(
return;
}
current.model.addStorySegment();
commands.notifyCommandChanged(CommandIDs.toggleStoryPresentationMode);
},
...icons.get(CommandIDs.addStorySegment),
});

commands.addCommand(CommandIDs.toggleStoryPresentationMode, {
label: trans.__('Toggle Story Presentation Mode'),
isToggled: () => {
const current = tracker.currentWidget;
if (!current) {
return false;
}

const { storyMapPresentationMode } = current.model.getOptions();

return storyMapPresentationMode ?? false;
},
isEnabled: () => {
const storySegments =
tracker.currentWidget?.model.getSelectedStory().story?.storySegments;

if (
tracker.currentWidget?.model.jgisSettings.storyMapsDisabled ||
!storySegments ||
storySegments.length < 1
) {
return false;
}

return true;
},
execute: args => {
const current = tracker.currentWidget;
if (!current) {
return;
}

const currentOptions = current.model.getOptions();

current.model.setOptions({
...currentOptions,
storyMapPresentationMode: !currentOptions.storyMapPresentationMode,
});

commands.notifyCommandChanged(CommandIDs.toggleStoryPresentationMode);
},
...icons.get(CommandIDs.toggleStoryPresentationMode),
});

loadKeybindings(commands, keybindings);
}

Expand Down
3 changes: 3 additions & 0 deletions packages/base/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ const iconObject = {
[CommandIDs.temporalController]: { icon: clockIcon },
[CommandIDs.addMarker]: { icon: markerIcon },
[CommandIDs.addStorySegment]: { iconClass: 'fa fa-link' },
[CommandIDs.toggleStoryPresentationMode]: {
iconClass: 'fa fa-book jgis-icon-adjust',
},
};

/**
Expand Down
1 change: 1 addition & 0 deletions packages/base/src/mainview/mainView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,7 @@ export class MainView extends React.Component<IProps, IStates> {
{this._formSchemaRegistry && this._annotationModel && (
<RightPanel
model={this._model}
commands={this._mainViewModel.commands}
formSchemaRegistry={this._formSchemaRegistry}
annotationModel={this._annotationModel}
></RightPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,29 @@ import { faLink } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IJGISStoryMap, IJupyterGISModel } from '@jupytergis/schema';
import jgisSchema from '@jupytergis/schema/lib/schema/project/jgis.json';
import { CommandRegistry } from '@lumino/commands';
import React, { useMemo } from 'react';

import { CommandIDs } from '@/src/constants';
import { StoryEditorPropertiesForm } from '@/src/formbuilder/objectform/StoryEditorForm';
import { Button } from '@/src/shared/components/Button';
import { deepCopy } from '@/src/tools';
import { IDict } from '@/src/types';

interface IStoryPanelProps {
model: IJupyterGISModel;
commands: CommandRegistry;
}

const storyMapSchema: IDict = deepCopy(jgisSchema.definitions.jGISStoryMap);

const AddStorySegmentButton = ({ model }: IStoryPanelProps) => (
<Button onClick={() => model.addStorySegment()}>
const AddStorySegmentButton = ({ model, commands }: IStoryPanelProps) => (
<Button onClick={() => commands.execute(CommandIDs.addStorySegment)}>
<FontAwesomeIcon icon={faLink} /> Add Story Segment
</Button>
);

export function StoryEditorPanel({ model }: IStoryPanelProps) {
export function StoryEditorPanel({ model, commands }: IStoryPanelProps) {
const { storySegmentId, story } = useMemo(() => {
return model.getSelectedStory();
}, [model, model.sharedModel.stories]);
Expand All @@ -42,7 +45,7 @@ export function StoryEditorPanel({ model }: IStoryPanelProps) {
current map view. You can add markdown text and an image to each
segment to tell your story.
</p>
<AddStorySegmentButton model={model} />
<AddStorySegmentButton model={model} commands={commands} />
</div>
);
}
Expand All @@ -57,7 +60,7 @@ export function StoryEditorPanel({ model }: IStoryPanelProps) {
syncData={syncStoryData}
filePath={model.filePath}
/>
<AddStorySegmentButton model={model} />
<AddStorySegmentButton model={model} commands={commands} />
</div>
);
}
Expand Down
40 changes: 28 additions & 12 deletions packages/base/src/panelview/rightpanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
IJupyterGISClientState,
IJupyterGISModel,
} from '@jupytergis/schema';
import { CommandRegistry } from '@lumino/commands';
import * as React from 'react';

import { AnnotationsPanel } from './annotationPanel';
Expand All @@ -23,22 +24,33 @@ interface IRightPanelProps {
formSchemaRegistry: IJGISFormSchemaRegistry;
annotationModel: IAnnotationModel;
model: IJupyterGISModel;
commands: CommandRegistry;
}

export const RightPanel: React.FC<IRightPanelProps> = props => {
const [displayEditor, setDisplayEditor] = React.useState(true);
const [editorMode, setEditorMode] = React.useState(true);
const [settings, setSettings] = React.useState(props.model.jgisSettings);
const [options, setOptions] = React.useState(props.model.getOptions());
const [storyMapPresentationMode, setStoryMapPresentationMode] =
React.useState(props.model.getOptions().storyMapPresentationMode ?? false);

// Only show editor when not in presentation mode and editorMode is true
const showEditor = !storyMapPresentationMode && editorMode;

// Tab title: "Story Map" in presentation mode, otherwise based on editorMode
const storyPanelTitle = storyMapPresentationMode
? 'Story Map'
: editorMode
? 'Story Editor'
: 'Story Map';

const storyMapPresentationMode = options.storyMapPresentationMode ?? false;
const tabInfo = [
!settings.objectPropertiesDisabled && !storyMapPresentationMode
? { name: 'objectProperties', title: 'Object Properties' }
: false,
!settings.storyMapsDisabled
? {
name: 'storyPanel',
title: displayEditor ? 'Story Editor' : 'Story Map',
title: storyPanelTitle,
}
: false,
!settings.annotationsDisabled
Expand All @@ -61,7 +73,8 @@ export const RightPanel: React.FC<IRightPanelProps> = props => {
setSettings({ ...props.model.jgisSettings });
};
const onOptionsChanged = () => {
setOptions({ ...props.model.getOptions() });
const { storyMapPresentationMode } = props.model.getOptions();
setStoryMapPresentationMode(storyMapPresentationMode ?? false);
};
let currentlyIdentifiedFeatures: any = undefined;
const onAwerenessChanged = (
Expand Down Expand Up @@ -104,7 +117,7 @@ export const RightPanel: React.FC<IRightPanelProps> = props => {
React.useState(undefined);

const toggleEditor = () => {
setDisplayEditor(!displayEditor);
setEditorMode(!editorMode);
};

return (
Expand All @@ -117,7 +130,7 @@ export const RightPanel: React.FC<IRightPanelProps> = props => {
{tabInfo.map(tab => (
<TabsTrigger
className="jGIS-layer-browser-category"
key={tab.name}
key={`${tab.name}-${tab.title}`}
value={tab.name}
onClick={() => {
if (curTab !== tab.name) {
Expand Down Expand Up @@ -153,17 +166,20 @@ export const RightPanel: React.FC<IRightPanelProps> = props => {
style={{ paddingTop: 0 }}
>
<div style={{ padding: '0 0.5rem 0.5rem 0.5rem' }}>
{/* Don't want to see the toggle switch in presentation mode */}
{/* Only show switch when NOT in presentation mode */}
{!storyMapPresentationMode && (
<PreviewModeSwitch
checked={!displayEditor}
checked={!editorMode}
onCheckedChange={toggleEditor}
/>
)}
{storyMapPresentationMode || !displayEditor ? (
<StoryViewerPanel model={props.model} />
{showEditor ? (
<StoryEditorPanel
model={props.model}
commands={props.commands}
/>
) : (
<StoryEditorPanel model={props.model} />
<StoryViewerPanel model={props.model} />
)}
</div>
</TabsContent>
Expand Down
12 changes: 12 additions & 0 deletions packages/base/src/toolbar/widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ export class ToolbarWidget extends ReactiveToolbar {
this.addItem('addMarker', addMarkerButton);
addMarkerButton.node.dataset.testid = 'add-marker-controller-button';

const storyModePresentationToggleButton = new CommandToolbarButton({
id: CommandIDs.toggleStoryPresentationMode,
label: '',
commands: options.commands,
});

this.addItem(
'toggleStoryPresentationMode',
storyModePresentationToggleButton,
);
identifyButton.node.dataset.testid = 'toggleStoryPresentationMode-button';

this.addItem('separator2', new Separator());

const toggleConsoleButton = new CommandToolbarButton({
Expand Down
4 changes: 4 additions & 0 deletions packages/base/style/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ button.jp-mod-styled.jp-mod-reject {
z-index: 40;
}

.jgis-icon-adjust {
padding-top: 5px;
}

@media (max-width: 768px) {
.jgis-panels-wrapper {
position: fixed;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading