Skip to content

Disable persistence methods in Folder mode #2403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 2, 2023
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
42 changes: 25 additions & 17 deletions src/commons/controlBar/ControlBarGoogleDriveButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ControlButton from '../ControlButton';
import { useResponsive } from '../utils/Hooks';

export type ControlBarGoogleDriveButtonsProps = {
isFolderModeEnabled: boolean;
loggedInAs?: string;
currentFile?: PersistenceFile;
isDirty?: boolean;
Expand Down Expand Up @@ -36,6 +37,7 @@ export const ControlBarGoogleDriveButtons: React.FC<ControlBarGoogleDriveButtons
label={(props.currentFile && props.currentFile.name) || 'Google Drive'}
icon={IconNames.CLOUD}
options={{ intent: stateToIntent[state] }}
isDisabled={props.isFolderModeEnabled}
/>
);
const openButton = (
Expand All @@ -58,24 +60,30 @@ export const ControlBarGoogleDriveButtons: React.FC<ControlBarGoogleDriveButtons
<ControlButton label="Log out" icon={IconNames.LOG_OUT} onClick={props.onClickLogOut} />
</Tooltip2>
);
const tooltipContent = props.isFolderModeEnabled
? 'Currently unsupported in Folder mode'
: undefined;

return (
<Popover2
autoFocus={false}
content={
<div>
<ButtonGroup large={!isMobileBreakpoint}>
{openButton}
{saveButton}
{saveAsButton}
{logoutButton}
</ButtonGroup>
</div>
}
onOpening={props.onPopoverOpening}
popoverClassName={Classes.POPOVER_DISMISS}
>
{mainButton}
</Popover2>
<Tooltip2 content={tooltipContent} disabled={tooltipContent === undefined}>
<Popover2
autoFocus={false}
content={
<div>
<ButtonGroup large={!isMobileBreakpoint}>
{openButton}
{saveButton}
{saveAsButton}
{logoutButton}
</ButtonGroup>
</div>
}
onOpening={props.onPopoverOpening}
popoverClassName={Classes.POPOVER_DISMISS}
disabled={props.isFolderModeEnabled}
>
{mainButton}
</Popover2>
</Tooltip2>
);
};
6 changes: 5 additions & 1 deletion src/commons/controlBar/ControlBarToggleFolderModeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import ControlButton from '../ControlButton';
type ControlBarToggleFolderModeButtonProps = {
isFolderModeEnabled: boolean;
isSessionActive: boolean;
isPersistenceActive: boolean;
toggleFolderMode: () => void;
};

export const ControlBarToggleFolderModeButton: React.FC<ControlBarToggleFolderModeButtonProps> = ({
isFolderModeEnabled,
isSessionActive,
isPersistenceActive,
toggleFolderMode
}) => {
const tooltipContent = isSessionActive
? 'Currently unsupported while a collaborative session is active'
: isPersistenceActive
? 'Currently unsupported while a persistence method is active'
: `${isFolderModeEnabled ? 'Disable' : 'Enable'} Folder mode`;
return (
<Tooltip2 content={tooltipContent}>
Expand All @@ -28,7 +32,7 @@ export const ControlBarToggleFolderModeButton: React.FC<ControlBarToggleFolderMo
iconColor: isFolderModeEnabled ? Colors.BLUE4 : undefined
}}
onClick={toggleFolderMode}
isDisabled={isSessionActive}
isDisabled={isSessionActive || isPersistenceActive}
/>
</Tooltip2>
);
Expand Down
43 changes: 26 additions & 17 deletions src/commons/controlBar/github/ControlBarGitHubButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ButtonGroup, Classes, Intent } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { Popover2 } from '@blueprintjs/popover2';
import { Popover2, Tooltip2 } from '@blueprintjs/popover2';
import { Octokit } from '@octokit/rest';
import * as React from 'react';
import { useResponsive } from 'src/commons/utils/Hooks';
Expand All @@ -9,6 +9,7 @@ import { GitHubSaveInfo } from '../../../features/github/GitHubTypes';
import ControlButton from '../../ControlButton';

export type ControlBarGitHubButtonsProps = {
isFolderModeEnabled: boolean;
loggedInAs?: Octokit;
githubSaveInfo: GitHubSaveInfo;
isDirty: boolean;
Expand Down Expand Up @@ -47,6 +48,7 @@ export const ControlBarGitHubButtons: React.FC<ControlBarGitHubButtonsProps> = p
label={mainButtonDisplayText}
icon={IconNames.GIT_BRANCH}
options={{ intent: mainButtonIntent }}
isDisabled={props.isFolderModeEnabled}
/>
);

Expand Down Expand Up @@ -83,22 +85,29 @@ export const ControlBarGitHubButtons: React.FC<ControlBarGitHubButtonsProps> = p
<ControlButton label="Log In" icon={IconNames.LOG_IN} onClick={props.onClickLogIn} />
);

const tooltipContent = props.isFolderModeEnabled
? 'Currently unsupported in Folder mode'
: undefined;

return (
<Popover2
autoFocus={false}
content={
<div>
<ButtonGroup large={!isMobileBreakpoint}>
{openButton}
{saveButton}
{saveAsButton}
{loginButton}
</ButtonGroup>
</div>
}
popoverClassName={Classes.POPOVER_DISMISS}
>
{mainButton}
</Popover2>
<Tooltip2 content={tooltipContent} disabled={tooltipContent === undefined}>
<Popover2
autoFocus={false}
content={
<div>
<ButtonGroup large={!isMobileBreakpoint}>
{openButton}
{saveButton}
{saveAsButton}
{loginButton}
</ButtonGroup>
</div>
}
popoverClassName={Classes.POPOVER_DISMISS}
disabled={props.isFolderModeEnabled}
>
{mainButton}
</Popover2>
</Tooltip2>
);
};
28 changes: 23 additions & 5 deletions src/commons/sagas/GitHubPersistenceSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
GetResponseTypeFromEndpointMethod
} from '@octokit/types';
import { SagaIterator } from 'redux-saga';
import { call, put, takeLatest } from 'redux-saga/effects';
import { call, put, select, takeLatest } from 'redux-saga/effects';

import {
GITHUB_OPEN_FILE,
Expand All @@ -13,13 +13,15 @@ import {
import * as GitHubUtils from '../../features/github/GitHubUtils';
import { getGitHubOctokitInstance } from '../../features/github/GitHubUtils';
import { store } from '../../pages/createStore';
import { OverallState } from '../application/ApplicationTypes';
import { LOGIN_GITHUB, LOGOUT_GITHUB } from '../application/types/SessionTypes';
import FileExplorerDialog, { FileExplorerDialogProps } from '../gitHubOverlay/FileExplorerDialog';
import RepositoryDialog, { RepositoryDialogProps } from '../gitHubOverlay/RepositoryDialog';
import { actions } from '../utils/ActionsHelper';
import Constants from '../utils/Constants';
import { promisifyDialog } from '../utils/DialogHelper';
import { showSuccessMessage, showWarningMessage } from '../utils/NotificationsHelper';
import { EditorTabState } from '../workspace/WorkspaceTypes';

export function* GitHubPersistenceSaga(): SagaIterator {
yield takeLatest(LOGIN_GITHUB, githubLoginSaga);
Expand Down Expand Up @@ -121,8 +123,16 @@ function* githubSaveFile(): any {
const githubEmail = authUser.data.email;
const githubName = authUser.data.name;
const commitMessage = 'Changes made from Source Academy';
// TODO: Hardcoded to make use of the first editor tab. Rewrite after editor tabs are added.
const content = store.getState().workspaces.playground.editorTabs[0].value;
const activeEditorTabIndex: number | null = yield select(
(state: OverallState) => state.workspaces.playground.activeEditorTabIndex
);
if (activeEditorTabIndex === null) {
throw new Error('No active editor tab found.');
}
const editorTabs: EditorTabState[] = yield select(
(state: OverallState) => state.workspaces.playground.editorTabs
);
const content = editorTabs[activeEditorTabIndex].value;

GitHubUtils.performOverwritingSave(
octokit,
Expand Down Expand Up @@ -160,8 +170,16 @@ function* githubSaveFileAs(): any {
}));
const repoName = yield call(getRepoName);

// TODO: Hardcoded to make use of the first editor tab. Rewrite after editor tabs are added.
const editorContent = store.getState().workspaces.playground.editorTabs[0].value;
const activeEditorTabIndex: number | null = yield select(
(state: OverallState) => state.workspaces.playground.activeEditorTabIndex
);
if (activeEditorTabIndex === null) {
throw new Error('No active editor tab found.');
}
const editorTabs: EditorTabState[] = yield select(
(state: OverallState) => state.workspaces.playground.editorTabs
);
const editorContent = editorTabs[activeEditorTabIndex].value;

if (repoName !== '') {
const pickerType = 'Save';
Expand Down
51 changes: 35 additions & 16 deletions src/commons/sagas/PersistenceSaga.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,13 @@ export function* persistenceSaga(): SagaIterator {
fields: 'appProperties'
});
const contents = yield call([gapi.client.drive.files, 'get'], { fileId: id, alt: 'media' });
// TODO: Hardcoded to make use of the first editor tab. Rewrite after editor tabs are added.
yield put(actions.updateEditorValue('playground', 0, contents.body));
const activeEditorTabIndex: number | null = yield select(
(state: OverallState) => state.workspaces.playground.activeEditorTabIndex
);
if (activeEditorTabIndex === null) {
throw new Error('No active editor tab found.');
}
yield put(actions.updateEditorValue('playground', activeEditorTabIndex, contents.body));
yield put(actions.playgroundUpdatePersistenceFile({ id, name, lastSaved: new Date() }));
if (meta && meta.appProperties) {
yield put(
Expand Down Expand Up @@ -114,13 +119,20 @@ export function* persistenceSaga(): SagaIterator {
try {
yield call(ensureInitialisedAndAuthorised);

const [code, chapter, variant, external] = yield select((state: OverallState) => [
// TODO: Hardcoded to make use of the first editor tab. Rewrite after editor tabs are added.
state.workspaces.playground.editorTabs[0].value,
state.workspaces.playground.context.chapter,
state.workspaces.playground.context.variant,
state.workspaces.playground.externalLibrary
]);
const [activeEditorTabIndex, editorTabs, chapter, variant, external] = yield select(
(state: OverallState) => [
state.workspaces.playground.activeEditorTabIndex,
state.workspaces.playground.editorTabs,
state.workspaces.playground.context.chapter,
state.workspaces.playground.context.variant,
state.workspaces.playground.externalLibrary
]
);

if (activeEditorTabIndex === null) {
throw new Error('No active editor tab found.');
}
const code = editorTabs[activeEditorTabIndex].value;

const pickedDir: PickFileResult = yield call(
pickFile,
Expand Down Expand Up @@ -237,13 +249,20 @@ export function* persistenceSaga(): SagaIterator {

yield call(ensureInitialisedAndAuthorised);

const [code, chapter, variant, external] = yield select((state: OverallState) => [
// TODO: Hardcoded to make use of the first editor tab. Rewrite after editor tabs are added.
state.workspaces.playground.editorTabs[0].value,
state.workspaces.playground.context.chapter,
state.workspaces.playground.context.variant,
state.workspaces.playground.externalLibrary
]);
const [activeEditorTabIndex, editorTabs, chapter, variant, external] = yield select(
(state: OverallState) => [
state.workspaces.playground.activeEditorTabIndex,
state.workspaces.playground.editorTabs,
state.workspaces.playground.context.chapter,
state.workspaces.playground.context.variant,
state.workspaces.playground.externalLibrary
]
);

if (activeEditorTabIndex === null) {
throw new Error('No active editor tab found.');
}
const code = editorTabs[activeEditorTabIndex].value;

const config: IPlaygroundConfig = {
chapter,
Expand Down
Loading