Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

WIP - Feature/admin mode#412

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ShMcK merged 8 commits intomasterfromfeature/admin-mode
Jul 27, 2020
Merged
Show file tree
Hide file tree
Changes fromall 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
14 changes: 10 additions & 4 deletionssrc/actions/onRunReset.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,15 +3,21 @@ import * as TT from 'typings/tutorial'
import Context from '../services/context/context'
import { exec } from '../services/node'
import reset from '../services/reset'
importgetLastCommitHash from '../services/reset/lastHash'
importgetCommitHashByPosition from '../services/reset/lastHash'

const onRunReset = async (context: Context) => {
type ResetAction = {
type: 'LATEST' | 'POSITION'
position?: T.Position
}

// reset to the start of the last test
const onRunReset = async (action: ResetAction, context: Context) => {
// reset to timeline
const tutorial: TT.Tutorial | null = context.tutorial.get()
const position: T.Position = context.position.get()
const position: T.Position =action.position ? action.position :context.position.get()

// get last pass commit
const hash = getLastCommitHash(position, tutorial?.levels || [])
const hash: string = getCommitHashByPosition(position, tutorial)

const branch = tutorial?.config.repo.branch

Expand Down
7 changes: 5 additions & 2 deletionssrc/channel.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,8 +79,11 @@ class Channel implements Channel {
case 'EDITOR_RUN_TEST':
actions.onRunTest(action)
return
case 'EDITOR_RUN_RESET':
actions.onRunReset(this.context)
case 'EDITOR_RUN_RESET_LATEST':
actions.onRunReset({ type: 'LATEST' }, this.context)
return
case 'EDITOR_RUN_RESET_POSITION':
actions.onRunReset({ type: 'POSITION', position: action.payload.position }, this.context)
return
default:
logger(`No match for action type: ${actionType}`)
Expand Down
111 changes: 71 additions & 40 deletionssrc/services/reset/lastHash.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,52 +5,83 @@ import getLastCommitHash from './lastHash'
describe('lastHash', () => {
it('should grab the last passing hash from a step', () => {
const position: T.Position = { levelId: '1', stepId: '1.2' }
const levels: TT.Level[] = [
{
id: '1',
title: '',
summary: '',
content: '',
steps: [
{
id: '1.1',
content: '',
setup: { commits: ['abcdef1'] },
},
{
id: '1.2',
content: '',
setup: { commits: ['abcdef2'] },
},
],
},
]
const result = getLastCommitHash(position, levels)
// @ts-ignore
const tutorial: TT.Tutorial = {
levels: [
{
id: '1',
title: '',
summary: '',
content: '',
steps: [
{
id: '1.1',
content: '',
setup: { commits: ['abcdef1'] },
},
{
id: '1.2',
content: '',
setup: { commits: ['abcdef2'] },
},
],
},
],
}
const result = getLastCommitHash(position, tutorial)
expect(result).toBe('abcdef2')
})
it('should grab the last passing hash from a step with several commits', () => {
const position: T.Position = { levelId: '1', stepId: '1.2' }
const levels: TT.Level[] = [
{
id: '1',
title: '',
summary: '',
content: '',
steps: [
{
id: '1.1',
content: '',
setup: { commits: ['abcdef1'] },
},
{
id: '1.2',
content: '',
setup: { commits: ['abcdef2', 'abcdef3'] },
// @ts-ignore
const tutorial: TT.Tutorial = {
levels: [
{
id: '1',
title: '',
summary: '',
content: '',
steps: [
{
id: '1.1',
content: '',
setup: { commits: ['abcdef1'] },
},
{
id: '1.2',
content: '',
setup: { commits: ['abcdef2', 'abcdef3'] },
},
],
},
],
}
const result = getLastCommitHash(position, tutorial)
expect(result).toBe('abcdef3')
})
it('should grab the last passing hash when level has no steps', () => {
const position: T.Position = { levelId: '1', stepId: null }
// @ts-ignore
const tutorial: TT.Tutorial = {
config: {
// @ts-ignore
testRunner: {
setup: {
commits: ['abcdef2', 'abcdef3'],
},
],
},
},
]
const result = getLastCommitHash(position, levels)
levels: [
{
id: '1',
title: '',
summary: '',
content: '',
steps: [],
},
],
}
const result = getLastCommitHash(position, tutorial)
expect(result).toBe('abcdef3')
})
})
32 changes: 30 additions & 2 deletionssrc/services/reset/lastHash.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
import * as TT from '../../../typings/tutorial'
import * as T from '../../../typings'

const getLastCommitHash = (position: T.Position, levels: TT.Level[]) => {
const getLastCommitHash = (position: T.Position, tutorial: TT.Tutorial | null) => {
if (!tutorial) {
throw new Error('No tutorial found')
}
const { levels } = tutorial
// get previous position
const { levelId, stepId } = position

const level: TT.Level | undefined = levels.find((l) => levelId === l.id)
let level: TT.Level | undefined = levels.find((l) => levelId === l.id)
if (!level) {
throw new Error(`No level found matching ${levelId}`)
}

// handle a level with no steps
if (!level.steps || !level.steps.length) {
if (level.setup && level.setup.commits) {
// return level commit
const levelCommits = level.setup.commits
return levelCommits[levelCommits.length - 1]
} else {
// is there a previous level?
// @ts-ignore
const levelIndex = levels.findIndex((l: TT.Level) => level.id === l.id)
if (levelIndex > 0) {
level = levels[levelIndex - 1]
} else {
// use init commit
const configCommits = tutorial.config.testRunner.setup?.commits
if (!configCommits) {
throw new Error('No commits found to reset back to')
}
return configCommits[configCommits.length - 1]
}
}
}

const step = level.steps.find((s) => stepId === s.id)
if (!step) {
throw new Error(`No step found matching ${stepId}`)
Expand Down
91 changes: 77 additions & 14 deletionsweb-app/src/containers/Tutorial/containers/Review.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
import * as React from 'react'
import * as T from 'typings'
import { Switch } from '@alifd/next'
import Steps from '../components/Steps'
import { Button, Icon } from '@alifd/next'
import Step from '../components/Step'
import Hints from '../components/Hints'
import Content from '../components/Content'
import { Theme } from '../../../styles/theme'
import AdminContext from '../../../services/admin/context'

interface Props {
levels: T.LevelUI[]
onResetToPosition(position: T.Position): void
}

const styles = {
Expand DownExpand Up@@ -36,28 +39,88 @@ const styles = {
fontSize: '70%',
},
levels: {},
steps: {
padding: '1rem 1rem',
},
adminNav: {
position: 'absolute' as 'absolute',
right: '1rem',
lineHeight: '16px',
},
}

const ReviewPage = (props: Props) => {
const [stepVisibility, setStepVisibility] = React.useState(true)
const {
state: { adminMode },
} = React.useContext(AdminContext)
const show = (status: T.ProgressStatus): boolean => {
return adminMode || status !== 'INCOMPLETE'
}
return (
<div css={styles.container}>
<div css={styles.header}>
<div>Review</div>
<div css={styles.control}>
<span>Show steps&nbsp;</span>
<Switch checked={stepVisibility} onChange={(checked) => setStepVisibility(checked)} />
</div>
</div>

<div css={styles.levels}>
{props.levels.map((level: T.LevelUI, index: number) => (
<>
<Content title={level.title} content={level.content} />
{stepVisibility ? <Steps steps={level.steps} displayAll /> : null}
{index < props.levels.length - 1 ? <hr /> : null}
</>
))}
{props.levels.map((level: T.LevelUI, index: number) =>
show(level.status) ? (
<div key={level.id}>
{adminMode && (
<div css={styles.adminNav}>
<Button
type="normal"
warning
onClick={() =>
props.onResetToPosition({
levelId: level.id,
stepId: level.steps.length ? level.steps[0].id : null,
})
}
>
{level.id}&nbsp;
<Icon type="refresh" />
</Button>
</div>
)}
<Content title={level.title} content={level.content} />

<div css={styles.steps}>
{level.steps.map((step: T.StepUI) => {
if (!step) {
return null
}
return show(step.status) ? (
<div key={step.id}>
{adminMode && (
<div css={styles.adminNav}>
<Button
type="normal"
warning
onClick={() => props.onResetToPosition({ levelId: level.id, stepId: step.id })}
>
{step.id}&nbsp;
<Icon type="refresh" />
</Button>
</div>
)}
<Step
key={step.id}
status={step.status}
displayAll={true}
content={step.content}
subtasks={step.subtasks}
/>
<Hints hints={step.hints || []} />
</div>
) : null
})}
</div>

{index < props.levels.length - 1 ? <hr /> : null}
</div>
) : null,
)}
</div>
</div>
)
Expand Down
17 changes: 10 additions & 7 deletionsweb-app/src/containers/Tutorial/formatLevels.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,17 +32,24 @@ const formatLevels = ({ progress, position, levels, testStatus }: Input): Output

const currentLevel = levels[levelIndex]

let stepIndex = currentLevel.steps.findIndex((s: TT.Step) => s.id === position.stepId)
if (stepIndex === -1) {
stepIndex = levels[levelIndex].steps.length
}

const levelUI: T.LevelUI = {
...currentLevel,
status: progress.levels[position.levelId] ? 'COMPLETE' : 'ACTIVE',
steps: currentLevel.steps.map((step: TT.Step) => {
steps: currentLevel.steps.map((step: TT.Step, index) => {
// label step status for step component
let status: T.ProgressStatus = 'INCOMPLETE'
let subtasks
if (progress.steps[step.id]) {
if (index < stepIndex || (index === stepIndex &&progress.steps[step.id])) {
status = 'COMPLETE'
} else if (step.id ===position.stepId) {
} else if (index ===stepIndex) {
status = 'ACTIVE'
} else {
status = 'INCOMPLETE'
}
if (step.subtasks && step.subtasks) {
const testSummaries = Object.keys(testStatus?.summary || {})
Expand DownExpand Up@@ -95,10 +102,6 @@ const formatLevels = ({ progress, position, levels, testStatus }: Input): Output

const levelsUI: T.LevelUI[] = [...completed, levelUI, ...incompleted]

let stepIndex = levelUI.steps.findIndex((s: T.StepUI) => s.status === 'ACTIVE')
if (stepIndex === -1) {
stepIndex = levels[levelIndex].steps.length
}
return { level: levelUI, levels: levelsUI, levelIndex, stepIndex }
}

Expand Down
6 changes: 5 additions & 1 deletionweb-app/src/containers/Tutorial/index.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,6 +119,10 @@ const TutorialPage = (props: PageProps) => {
props.send({ type: 'RUN_RESET' })
}

const onResetToPosition = (position: T.Position): void => {
props.send({ type: 'RUN_RESET_TO_POSITION', payload: { position } })
}

const [menuVisible, setMenuVisible] = React.useState(false)

const [page, setPage] = React.useState<'about' | 'level' | 'review' | 'settings'>('level')
Expand DownExpand Up@@ -150,7 +154,7 @@ const TutorialPage = (props: PageProps) => {
<Level level={level} />
</ScrollContent>
)}
{page === 'review' && <ReviewPage levels={levels} />}
{page === 'review' && <ReviewPage levels={levels}onResetToPosition={onResetToPosition}/>}

{/* {page === 'settings' && <SettingsPage />} */}
</div>
Expand Down
3 changes: 1 addition & 2 deletionsweb-app/src/environment.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,5 +16,4 @@ export const TUTORIAL_LIST_URL: string = process.env.REACT_APP_TUTORIAL_LIST_URL
export const DISPLAY_RUN_TEST_BUTTON =
(process.env.CODEROAD_DISPLAY_RUN_TEST_BUTTON || 'true').toLowerCase() !== 'false' // default true

export const ADMIN_MODE = false
// (process.env.CODEROAD_ADMIN_MODE || process.env.STORYBOOK_ADMIN_MODE || '').toLowerCase() === 'true' // default false
export const ADMIN_MODE = (process.env.CODEROAD_ADMIN_MODE || '').toLowerCase() === 'true' // default false
Loading

[8]ページ先頭

©2009-2025 Movatter.jp