From b63ff09a17027901dfa81fd2fd81e73053695008 Mon Sep 17 00:00:00 2001 From: Jonas Chow Date: Fri, 30 Jul 2021 20:19:55 +0800 Subject: [PATCH 1/5] Achievement UI update --- .../achievement/AchievementManualEditor.tsx | 58 ++++++++++++++----- src/commons/achievement/AchievementView.tsx | 3 +- .../achievementEditor/AchievementSettings.tsx | 12 ++-- .../achievementSettings/EditableGoalUuids.tsx | 28 +++++---- .../EditablePrerequisiteUuids.tsx | 25 ++++---- .../utils/AchievementInferencer.ts | 9 +++ .../utils/InsertFakeAchievements.ts | 7 +-- src/commons/sagas/AchievementSaga.ts | 9 ++- src/commons/sagas/RequestsSaga.ts | 2 +- .../achievement/AchievementActions.ts | 2 +- .../subcomponents/AchievementDashboard.tsx | 27 +++++++-- .../AchievementDashboardContainer.ts | 2 + 12 files changed, 127 insertions(+), 57 deletions(-) diff --git a/src/commons/achievement/AchievementManualEditor.tsx b/src/commons/achievement/AchievementManualEditor.tsx index d16f105c36..a57f399f2b 100644 --- a/src/commons/achievement/AchievementManualEditor.tsx +++ b/src/commons/achievement/AchievementManualEditor.tsx @@ -1,5 +1,5 @@ -import { Button, MenuItem, NumericInput } from '@blueprintjs/core'; -import { ItemRenderer, Select } from '@blueprintjs/select'; +import { Button, Checkbox, MenuItem, NumericInput } from '@blueprintjs/core'; +import { ItemPredicate, ItemRenderer, Select } from '@blueprintjs/select'; import { useContext, useEffect, useState } from 'react'; import { AchievementContext } from 'src/features/achievement/AchievementConstants'; import { @@ -8,7 +8,11 @@ import { GoalProgress } from 'src/features/achievement/AchievementTypes'; +import { showSuccessMessage, showWarningMessage } from '../utils/NotificationsHelper'; + type AchievementManualEditorProps = { + hiddenState: [boolean, any]; + userState: [AchievementUser | undefined, any]; studio: string; users: AchievementUser[]; getUsers: () => void; @@ -19,9 +23,22 @@ const GoalSelect = Select.ofType(); const goalRenderer: ItemRenderer = (goal, { handleClick }) => ( ); +const goalPredicate: ItemPredicate = (query, item) => + item.text.toLowerCase().includes(query.toLowerCase()); + +const UserSelect = Select.ofType(); +const userRenderer: ItemRenderer = (user, { handleClick }) => ( + +); +const userPredicate: ItemPredicate = (query, item) => + item.name.toLowerCase().includes(query.toLowerCase()); + +export function updateGoalProcessed() { + showSuccessMessage('Goal updated'); +} function AchievementManualEditor(props: AchievementManualEditorProps) { - const { studio, getUsers, updateGoalProgress } = props; + const { userState, hiddenState, studio, getUsers, updateGoalProgress } = props; const users = studio === 'Staff' ? // The name can be null for users who have yet to log in. We push these to the back of the array. @@ -39,24 +56,23 @@ function AchievementManualEditor(props: AchievementManualEditorProps) { .getAllGoals() .filter(goals => goals.meta.type === 'Manual'); - const [goal, changeGoal] = useState(manualAchievements[0]); - const [selectedUser, changeSelectedUser] = useState(users[0]); - const [count, changeCount] = useState(0); - - const UserSelect = Select.ofType(); - const userRenderer: ItemRenderer = (user, { handleClick }) => ( - - ); + const [goal, changeGoal] = useState(undefined); + const [selectedUser, changeSelectedUser] = userState; + const [count, changeCount] = useState(0); + const [viewHidden, changeViewHidden] = hiddenState; const updateGoal = () => { - if (goal) { + if (goal && selectedUser) { const progress: GoalProgress = { uuid: goal.uuid, - count: count, + count: count < 0 ? 0 : Math.floor(count), targetCount: goal.targetCount, completed: count >= goal.targetCount }; updateGoalProgress(selectedUser.courseRegId, progress); + } else { + !goal && showWarningMessage('Goal not selected'); + !selectedUser && showWarningMessage('User not selected'); } }; @@ -64,10 +80,12 @@ function AchievementManualEditor(props: AchievementManualEditorProps) {

User:

} >
); } diff --git a/src/commons/achievement/AchievementView.tsx b/src/commons/achievement/AchievementView.tsx index cc6344741d..8f2d4785d7 100644 --- a/src/commons/achievement/AchievementView.tsx +++ b/src/commons/achievement/AchievementView.tsx @@ -44,7 +44,8 @@ function AchievementView(props: AchievementViewProps) {

{title.toUpperCase()}

diff --git a/src/commons/achievement/control/achievementEditor/AchievementSettings.tsx b/src/commons/achievement/control/achievementEditor/AchievementSettings.tsx index 7589242e17..2338508f2c 100644 --- a/src/commons/achievement/control/achievementEditor/AchievementSettings.tsx +++ b/src/commons/achievement/control/achievementEditor/AchievementSettings.tsx @@ -1,4 +1,4 @@ -import { Button, Dialog, EditableText } from '@blueprintjs/core'; +import { Button, Checkbox, Dialog, EditableText } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import { Tooltip2 } from '@blueprintjs/popover2'; import { useState } from 'react'; @@ -58,9 +58,13 @@ function AchievementSettings(props: AchievementSettingsProps) { />

Goals

- -
diff --git a/src/commons/achievement/control/achievementEditor/achievementSettings/EditableGoalUuids.tsx b/src/commons/achievement/control/achievementEditor/achievementSettings/EditableGoalUuids.tsx index dc955c793d..5af9df0e44 100644 --- a/src/commons/achievement/control/achievementEditor/achievementSettings/EditableGoalUuids.tsx +++ b/src/commons/achievement/control/achievementEditor/achievementSettings/EditableGoalUuids.tsx @@ -1,8 +1,9 @@ import { MenuItem } from '@blueprintjs/core'; -import { ItemRenderer, MultiSelect } from '@blueprintjs/select'; +import { ItemPredicate, ItemRenderer, MultiSelect } from '@blueprintjs/select'; import { without } from 'lodash'; import { useContext } from 'react'; import { AchievementContext } from 'src/features/achievement/AchievementConstants'; +import { AchievementGoal } from 'src/features/achievement/AchievementTypes'; type EditableGoalUuidsProps = { changeGoalUuids: (goalUuids: string[]) => void; @@ -19,12 +20,13 @@ function EditableGoalUuids(props: EditableGoalUuidsProps) { ); const getUuid = (text: string) => inferencer.getUuidByText(text); - const getText = (uuid: string) => inferencer.getTextByUuid(uuid); - const GoalSelect = MultiSelect.ofType(); - const goalRenderer: ItemRenderer = (uuid, { handleClick }) => ( - + const GoalSelect = MultiSelect.ofType(); + const goalRenderer: ItemRenderer = (goal, { handleClick }) => ( + ); + const goalPredicate: ItemPredicate = (query, item) => + item.text.toLowerCase().includes(query.toLowerCase()); const selectedGoals = new Set(selectedUuids); const availableGoals = new Set(without(allGoalUuids, ...goalUuids)); @@ -36,22 +38,24 @@ function EditableGoalUuids(props: EditableGoalUuidsProps) { }; const removeGoal = (removeUuid?: string) => { - if (removeUuid === undefined) return; + if (removeGoal === undefined) return; - selectedGoals.delete(removeUuid); - availableGoals.add(removeUuid); + selectedGoals.delete(removeUuid!); + availableGoals.add(removeUuid!); changeGoalUuids([...selectedGoals]); }; return ( inferencer.getGoal(uuid))} noResults={} - onItemSelect={selectGoal} - selectedItems={[...selectedGoals]} + onItemSelect={goal => selectGoal(goal.uuid)} + selectedItems={[...selectedGoals].map(uuid => inferencer.getGoal(uuid))} tagInputProps={{ onRemove: text => removeGoal(getUuid(text!.toString())) }} - tagRenderer={getText} + tagRenderer={goal => goal.text} + itemPredicate={goalPredicate} + resetOnSelect={true} /> ); } diff --git a/src/commons/achievement/control/achievementEditor/achievementSettings/EditablePrerequisiteUuids.tsx b/src/commons/achievement/control/achievementEditor/achievementSettings/EditablePrerequisiteUuids.tsx index 88336f2a6b..71ae238334 100644 --- a/src/commons/achievement/control/achievementEditor/achievementSettings/EditablePrerequisiteUuids.tsx +++ b/src/commons/achievement/control/achievementEditor/achievementSettings/EditablePrerequisiteUuids.tsx @@ -1,7 +1,9 @@ import { MenuItem } from '@blueprintjs/core'; -import { ItemRenderer, MultiSelect } from '@blueprintjs/select'; +import { ItemPredicate, ItemRenderer, MultiSelect } from '@blueprintjs/select'; +import { without } from 'lodash'; import { useContext } from 'react'; import { AchievementContext } from 'src/features/achievement/AchievementConstants'; +import { AchievementItem } from 'src/features/achievement/AchievementTypes'; type EditablePrerequisiteUuidsProps = { changePrerequisiteUuids: (prerequisiteUuids: string[]) => void; @@ -19,15 +21,16 @@ function EditablePrerequisiteUuids(props: EditablePrerequisiteUuidsProps) { ); const getUuid = (title: string) => inferencer.getUuidByTitle(title); - const getTitle = (uuid: string) => inferencer.getTitleByUuid(uuid); - const PrerequisiteSelect = MultiSelect.ofType(); - const prerequisiteRenderer: ItemRenderer = (uuid, { handleClick }) => ( - + const PrerequisiteSelect = MultiSelect.ofType(); + const prerequisiteRenderer: ItemRenderer = (achievement, { handleClick }) => ( + ); + const prerequisitePredicate: ItemPredicate = (query, item) => + item.title.toLowerCase().includes(query.toLowerCase()); const selectedPrereqs = new Set(selectedUuids); - const availablePrereqs = new Set(availableUuids); + const availablePrereqs = new Set(without(availableUuids, ...selectedUuids)); const selectPrereq = (selectUuid: string) => { selectedPrereqs.add(selectUuid); @@ -46,12 +49,14 @@ function EditablePrerequisiteUuids(props: EditablePrerequisiteUuidsProps) { return ( inferencer.getAchievement(uuid))} noResults={} - onItemSelect={selectPrereq} - selectedItems={[...selectedPrereqs]} + onItemSelect={achievement => selectPrereq(achievement.uuid)} + selectedItems={[...selectedPrereqs].map(uuid => inferencer.getAchievement(uuid))} tagInputProps={{ onRemove: title => removePrereq(getUuid(title!.toString())) }} - tagRenderer={getTitle} + tagRenderer={achievement => achievement.title} + itemPredicate={prerequisitePredicate} + resetOnSelect={true} /> ); } diff --git a/src/commons/achievement/utils/AchievementInferencer.ts b/src/commons/achievement/utils/AchievementInferencer.ts index 78a87ca0ea..5b302d4cf2 100644 --- a/src/commons/achievement/utils/AchievementInferencer.ts +++ b/src/commons/achievement/utils/AchievementInferencer.ts @@ -495,6 +495,15 @@ class AchievementInferencer { .map(sortedTask => sortedTask.uuid); } + /** + * Returns an array of achievementId sorted by position + */ + public listAllSortedAchievementUuids() { + return this.getAllAchievements() + .sort((taskA, taskB) => taskA.position - taskB.position) + .map(sortedTask => sortedTask.uuid); + } + /** * Returns whether an achievement is completed or not. * diff --git a/src/commons/achievement/utils/InsertFakeAchievements.ts b/src/commons/achievement/utils/InsertFakeAchievements.ts index 434790a97d..49aa7c496e 100644 --- a/src/commons/achievement/utils/InsertFakeAchievements.ts +++ b/src/commons/achievement/utils/InsertFakeAchievements.ts @@ -1,7 +1,4 @@ -import { - cardBackgroundUrl, - coverImageUrl -} from '../../../features/achievement/AchievementConstants'; +import { cardBackgroundUrl } from '../../../features/achievement/AchievementConstants'; import { AchievementAbility, GoalType } from '../../../features/achievement/AchievementTypes'; import { AssessmentOverview } from '../../assessment/AssessmentTypes'; import AchievementInferencer from './AchievementInferencer'; @@ -69,7 +66,7 @@ function insertFakeAchievements( goalUuids: [idString + '0', idString + '1'], // need to create a mock completed goal to reference to be considered complete cardBackground: `${cardBackgroundUrl}/default.png`, view: { - coverImage: `${coverImageUrl}/default.png`, + coverImage: assessmentOverview.coverImage, description: assessmentOverview.shortSummary, completionText: `XP: ${assessmentOverview.xp} / ${assessmentOverview.maxXp}` } diff --git a/src/commons/sagas/AchievementSaga.ts b/src/commons/sagas/AchievementSaga.ts index 9511bd58ee..36d4520d64 100644 --- a/src/commons/sagas/AchievementSaga.ts +++ b/src/commons/sagas/AchievementSaga.ts @@ -17,6 +17,7 @@ import { UPDATE_GOAL_PROGRESS, UPDATE_OWN_GOAL_PROGRESS } from '../../features/achievement/AchievementTypes'; +import { updateGoalProcessed } from '../achievement/AchievementManualEditor'; import AchievementInferencer from '../achievement/utils/AchievementInferencer'; import { goalIncludesEvents, incrementCount } from '../achievement/utils/EventHandler'; import { OverallState } from '../application/ApplicationTypes'; @@ -88,9 +89,9 @@ export default function* AchievementSaga(): SagaIterator { yield takeEvery(GET_GOALS, function* (action: ReturnType): any { const tokens: Tokens = yield selectTokens(); - const studentId = action.payload; + const studentCourseRegId = action.payload; - const goals = yield call(getGoals, tokens, studentId); + const goals = yield call(getGoals, tokens, studentCourseRegId); if (goals) { yield put(actions.saveGoals(goals)); @@ -171,6 +172,10 @@ export default function* AchievementSaga(): SagaIterator { if (!resp) { return; } + if (resp.ok) { + yield put(actions.getGoals(studentCourseRegId)); + updateGoalProcessed(); + } } ); diff --git a/src/commons/sagas/RequestsSaga.ts b/src/commons/sagas/RequestsSaga.ts index b045ea5540..8d3b321602 100644 --- a/src/commons/sagas/RequestsSaga.ts +++ b/src/commons/sagas/RequestsSaga.ts @@ -247,7 +247,7 @@ export const getGoals = async ( tokens: Tokens, studentId: number ): Promise => { - const resp = await request(`${courseId()}/achievements/goals/${studentId}`, 'GET', { + const resp = await request(`${courseId()}/admin/goals/${studentId}`, 'GET', { ...tokens, shouldRefresh: true }); diff --git a/src/features/achievement/AchievementActions.ts b/src/features/achievement/AchievementActions.ts index dde12ba83e..601db78c24 100644 --- a/src/features/achievement/AchievementActions.ts +++ b/src/features/achievement/AchievementActions.ts @@ -31,7 +31,7 @@ export const bulkUpdateGoals = (goals: GoalDefinition[]) => action(BULK_UPDATE_G export const getAchievements = () => action(GET_ACHIEVEMENTS); -export const getGoals = (studentId: number) => action(GET_GOALS, studentId); +export const getGoals = (studentCourseRegId: number) => action(GET_GOALS, studentCourseRegId); export const getOwnGoals = () => action(GET_OWN_GOALS); diff --git a/src/pages/achievement/subcomponents/AchievementDashboard.tsx b/src/pages/achievement/subcomponents/AchievementDashboard.tsx index 282391e888..9e29512cb4 100644 --- a/src/pages/achievement/subcomponents/AchievementDashboard.tsx +++ b/src/pages/achievement/subcomponents/AchievementDashboard.tsx @@ -20,6 +20,7 @@ import { export type DispatchProps = { fetchAssessmentOverviews: () => void; getAchievements: () => void; + getGoals: (studentId: number) => void; getOwnGoals: () => void; getUsers: () => void; updateGoalProgress: (studentCourseRegId: number, progress: GoalProgress) => void; @@ -60,6 +61,7 @@ function Dashboard(props: DispatchProps & StateProps) { const { getAchievements, getOwnGoals, + getGoals, getUsers, updateGoalProgress, fetchAssessmentOverviews, @@ -71,13 +73,17 @@ function Dashboard(props: DispatchProps & StateProps) { users } = props; + // default nothing selected + const userIdState = useState(undefined); + const [selectedUser] = userIdState; + /** * Fetch the latest achievements and goals from backend when the page is rendered */ useEffect(() => { - getOwnGoals(); + selectedUser ? getGoals(selectedUser.courseRegId) : getOwnGoals(); getAchievements(); - }, [getAchievements, getOwnGoals]); + }, [selectedUser, getAchievements, getGoals, getOwnGoals]); if (name && role && !assessmentOverviews) { // If assessment overviews are not loaded, fetch them @@ -85,9 +91,11 @@ function Dashboard(props: DispatchProps & StateProps) { } // one goal for submit, one goal for graded - assessmentOverviews?.forEach(assessmentOverview => - insertFakeAchievements(assessmentOverview, inferencer) - ); + if (role === Role.Student) { + assessmentOverviews?.forEach(assessmentOverview => + insertFakeAchievements(assessmentOverview, inferencer) + ); + } const filterState = useState(FilterStatus.ALL); const [filterStatus] = filterState; @@ -99,12 +107,17 @@ function Dashboard(props: DispatchProps & StateProps) { const focusState = useState(''); const [focusUuid] = focusState; + const hiddenState = useState(false); + const [seeHidden] = hiddenState; + return (
{role && role !== Role.Student && ( {generateAchievementTasks( - inferencer.listSortedReleasedTaskUuids(), + role === Role.Student || !seeHidden + ? inferencer.listSortedReleasedTaskUuids() + : inferencer.listAllSortedAchievementUuids(), filterStatus, focusState )} diff --git a/src/pages/achievement/subcomponents/AchievementDashboardContainer.ts b/src/pages/achievement/subcomponents/AchievementDashboardContainer.ts index b506433e65..c29fe3cf5e 100644 --- a/src/pages/achievement/subcomponents/AchievementDashboardContainer.ts +++ b/src/pages/achievement/subcomponents/AchievementDashboardContainer.ts @@ -6,6 +6,7 @@ import { fetchAssessmentOverviews } from '../../../commons/application/actions/S import { OverallState } from '../../../commons/application/ApplicationTypes'; import { getAchievements, + getGoals, getOwnGoals, getUsers, updateGoalProgress @@ -26,6 +27,7 @@ const mapDispatchToProps: MapDispatchToProps = (dispatch: Dis { fetchAssessmentOverviews, getAchievements, + getGoals, getOwnGoals, getUsers, updateGoalProgress From 5b324aeb25f1d07f6213652c325336e0226718a6 Mon Sep 17 00:00:00 2001 From: Chow En Rong <53928333+chownces@users.noreply.github.com> Date: Wed, 4 Aug 2021 12:57:21 +0800 Subject: [PATCH 2/5] Update route to match backend --- src/commons/sagas/RequestsSaga.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commons/sagas/RequestsSaga.ts b/src/commons/sagas/RequestsSaga.ts index 8d3b321602..d090e31a3c 100644 --- a/src/commons/sagas/RequestsSaga.ts +++ b/src/commons/sagas/RequestsSaga.ts @@ -241,13 +241,13 @@ export const getAchievements = async (tokens: Tokens): Promise => { - const resp = await request(`${courseId()}/admin/goals/${studentId}`, 'GET', { + const resp = await request(`${courseId()}/admin/users/${studentCourseRegId}/goals`, 'GET', { ...tokens, shouldRefresh: true }); From daf663f29b0526694afdb29fc2229969adb78ae2 Mon Sep 17 00:00:00 2001 From: Chow En Rong <53928333+chownces@users.noreply.github.com> Date: Wed, 4 Aug 2021 13:16:51 +0800 Subject: [PATCH 3/5] Update display of group name in achievements dashboard --- src/pages/achievement/subcomponents/AchievementDashboard.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pages/achievement/subcomponents/AchievementDashboard.tsx b/src/pages/achievement/subcomponents/AchievementDashboard.tsx index 9e29512cb4..7f9a1aeac7 100644 --- a/src/pages/achievement/subcomponents/AchievementDashboard.tsx +++ b/src/pages/achievement/subcomponents/AchievementDashboard.tsx @@ -113,7 +113,10 @@ function Dashboard(props: DispatchProps & StateProps) { return (
- + {role && role !== Role.Student && ( Date: Wed, 4 Aug 2021 13:03:13 +0800 Subject: [PATCH 4/5] Removed achievement ability --- src/commons/achievement/AchievementCard.tsx | 9 ++--- src/commons/achievement/AchievementTask.tsx | 2 +- src/commons/achievement/AchievementView.tsx | 4 +-- .../achievement/card/AchievementDeadline.tsx | 5 +-- .../achievementEditor/AchievementTemplate.ts | 2 -- .../achievementEditor/EditableAbility.tsx | 34 ------------------- .../achievementEditor/EditableCard.tsx | 16 +-------- .../achievementEditor/EditableCardTypes.ts | 6 ---- .../achievement/utils/AchievementBackender.ts | 2 -- .../utils/AchievementInferencer.ts | 2 -- .../utils/InsertFakeAchievements.ts | 6 +--- .../__tests__/AchievementInferencer.test.ts | 2 -- src/commons/mocks/AchievementMocks.ts | 13 ------- .../achievement/AchievementConstants.ts | 33 ++++++++++++------ src/features/achievement/AchievementTypes.ts | 10 ------ 15 files changed, 32 insertions(+), 114 deletions(-) delete mode 100644 src/commons/achievement/control/achievementEditor/EditableAbility.tsx diff --git a/src/commons/achievement/AchievementCard.tsx b/src/commons/achievement/AchievementCard.tsx index 335c56480f..3651ef5fb2 100644 --- a/src/commons/achievement/AchievementCard.tsx +++ b/src/commons/achievement/AchievementCard.tsx @@ -22,7 +22,7 @@ function AchievementCard(props: AchievementCardProps) { const [focusUuid, setFocusUuid] = focusState; - const { ability, cardBackground, title } = inferencer.getAchievement(uuid); + const { cardBackground, title } = inferencer.getAchievement(uuid); const displayDeadline = inferencer.getDisplayDeadline(uuid); const displayXp = inferencer.getAchievementXp(uuid); const progressFrac = inferencer.getProgressFrac(uuid); @@ -38,7 +38,7 @@ function AchievementCard(props: AchievementCardProps) { onClick={() => setFocusUuid(uuid)} onClickCapture={toggleDropdown} style={{ - ...handleGlow(uuid, focusUuid, ability), + ...handleGlow(uuid, focusUuid), opacity: shouldRender ? '100%' : '20%', background: `url(${cardBackground}) center/cover` }} @@ -58,10 +58,7 @@ function AchievementCard(props: AchievementCardProps) {
-
-

{ability}

-
- +
diff --git a/src/commons/achievement/AchievementTask.tsx b/src/commons/achievement/AchievementTask.tsx index 67b0911566..ee46f8c364 100644 --- a/src/commons/achievement/AchievementTask.tsx +++ b/src/commons/achievement/AchievementTask.tsx @@ -19,7 +19,7 @@ function AchievementTask(props: AchievementTaskProps) { const inferencer = useContext(AchievementContext); const prerequisiteUuids = [...inferencer.getImmediateChildren(uuid)]; - const taskColor = getAbilityColor(inferencer.getAchievement(uuid).ability); + const taskColor = getAbilityColor(); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen); diff --git a/src/commons/achievement/AchievementView.tsx b/src/commons/achievement/AchievementView.tsx index 8f2d4785d7..5e22421747 100644 --- a/src/commons/achievement/AchievementView.tsx +++ b/src/commons/achievement/AchievementView.tsx @@ -32,7 +32,7 @@ function AchievementView(props: AchievementViewProps) { } const achievement = inferencer.getAchievement(focusUuid); - const { ability, deadline, title, view } = achievement; + const { deadline, title, view } = achievement; const { coverImage, completionText, description } = view; const awardedXp = inferencer.getAchievementXp(focusUuid); const goals = inferencer.listGoals(focusUuid); @@ -40,7 +40,7 @@ function AchievementView(props: AchievementViewProps) { const status = inferencer.getStatus(focusUuid); return ( -
+
void; -}; - -function EditableAbility(props: EditableAbilityProps) { - const { ability, changeAbility } = props; - - const AbilitySelect = Select.ofType(); - - const abilityRenderer: ItemRenderer = (ability, { handleClick }) => ( - - ); - - return ( - - -
-
diff --git a/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts b/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts index 2bd1f66d00..7080c82727 100644 --- a/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts +++ b/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts @@ -1,11 +1,9 @@ import { - AchievementAbility, AchievementItem, AchievementView } from 'src/features/achievement/AchievementTypes'; export enum EditableCardActionType { - CHANGE_ABILITY = 'CHANGE_ABILITY', CHANGE_CARD_BACKGROUND = 'CHANGE_CARD_BACKGROUND', CHANGE_DEADLINE = 'CHANGE_DEADLINE', CHANGE_GOAL_UUIDS = 'CHANGE_GOAL_UUIDS', @@ -22,10 +20,6 @@ export enum EditableCardActionType { } export type EditableCardAction = - | { - type: EditableCardActionType.CHANGE_ABILITY; - payload: AchievementAbility; - } | { type: EditableCardActionType.CHANGE_CARD_BACKGROUND; payload: string; diff --git a/src/commons/achievement/utils/AchievementBackender.ts b/src/commons/achievement/utils/AchievementBackender.ts index 11dd76fcb9..dff95395b3 100644 --- a/src/commons/achievement/utils/AchievementBackender.ts +++ b/src/commons/achievement/utils/AchievementBackender.ts @@ -1,5 +1,4 @@ import { - AchievementAbility, AchievementGoal, AchievementItem, GoalDefinition, @@ -38,7 +37,6 @@ export const frontendifyAchievementItem = (achievement: any) => ({ uuid: achievement.uuid || '', title: achievement.title || '', - ability: achievement.ability as AchievementAbility, xp: achievement.xp, isVariableXp: achievement.isVariableXp, deadline: achievement.deadline === null ? undefined : new Date(achievement.deadline), diff --git a/src/commons/achievement/utils/AchievementInferencer.ts b/src/commons/achievement/utils/AchievementInferencer.ts index 5b302d4cf2..f51644d76d 100644 --- a/src/commons/achievement/utils/AchievementInferencer.ts +++ b/src/commons/achievement/utils/AchievementInferencer.ts @@ -3,7 +3,6 @@ import { v4 } from 'uuid'; import { showDangerMessage } from '../../../commons/utils/NotificationsHelper'; import { - AchievementAbility, AchievementGoal, AchievementItem, AchievementStatus, @@ -86,7 +85,6 @@ class AchievementInferencer { private invalidAchievement: AchievementItem = { uuid: 'invalid', title: 'invalid', - ability: AchievementAbility.EXPLORATION, xp: 0, isVariableXp: false, deadline: undefined, diff --git a/src/commons/achievement/utils/InsertFakeAchievements.ts b/src/commons/achievement/utils/InsertFakeAchievements.ts index 49aa7c496e..6ec6c1ab53 100644 --- a/src/commons/achievement/utils/InsertFakeAchievements.ts +++ b/src/commons/achievement/utils/InsertFakeAchievements.ts @@ -1,5 +1,5 @@ import { cardBackgroundUrl } from '../../../features/achievement/AchievementConstants'; -import { AchievementAbility, GoalType } from '../../../features/achievement/AchievementTypes'; +import { GoalType } from '../../../features/achievement/AchievementTypes'; import { AssessmentOverview } from '../../assessment/AssessmentTypes'; import AchievementInferencer from './AchievementInferencer'; import { isExpired, isReleased } from './DateHelper'; @@ -49,10 +49,6 @@ function insertFakeAchievements( inferencer.insertFakeAchievement({ uuid: idString, title: assessmentOverview.title, - ability: - assessmentOverview.type === 'Missions' || assessmentOverview.type === 'Paths' - ? AchievementAbility.CORE - : AchievementAbility.EFFORT, xp: assessmentOverview.gradingStatus === 'graded' ? assessmentOverview.xp diff --git a/src/commons/achievement/utils/__tests__/AchievementInferencer.test.ts b/src/commons/achievement/utils/__tests__/AchievementInferencer.test.ts index 934de898c6..73e7cf6d46 100644 --- a/src/commons/achievement/utils/__tests__/AchievementInferencer.test.ts +++ b/src/commons/achievement/utils/__tests__/AchievementInferencer.test.ts @@ -1,6 +1,5 @@ import { mockAchievements, mockGoals } from 'src/commons/mocks/AchievementMocks'; import { - AchievementAbility, AchievementGoal, AchievementItem, AchievementStatus, @@ -15,7 +14,6 @@ import AchievementInferencer from '../AchievementInferencer'; const testAchievement: AchievementItem = { uuid: '0', title: 'Test Achievement', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, isTask: false, diff --git a/src/commons/mocks/AchievementMocks.ts b/src/commons/mocks/AchievementMocks.ts index dea737e283..2c919c347b 100644 --- a/src/commons/mocks/AchievementMocks.ts +++ b/src/commons/mocks/AchievementMocks.ts @@ -1,5 +1,4 @@ import { - AchievementAbility, AchievementGoal, AchievementItem, GoalType @@ -10,7 +9,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '0', title: 'Rune Master', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, isTask: true, @@ -30,7 +28,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '1', title: 'Beyond the Second Dimension', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, deadline: new Date(2020, 7, 6, 12, 30, 0), @@ -51,7 +48,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '2', title: 'Colorful Carpet', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, deadline: new Date(2020, 7, 8, 9, 0, 0), @@ -72,7 +68,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '3', title: '', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, isTask: false, @@ -89,7 +84,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '4', title: 'Curve Wizard', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, deadline: new Date(2020, 8, 15, 0, 0, 0), @@ -110,7 +104,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '5', title: 'Curve Introduction', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, deadline: new Date(2020, 7, 28, 0, 0, 0), @@ -131,7 +124,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '6', title: 'Curve Manipulation', - ability: AchievementAbility.CORE, xp: 100, isVariableXp: false, deadline: new Date(2020, 8, 5, 0, 0, 0), @@ -152,7 +144,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '21', title: 'The Source-rer', - ability: AchievementAbility.EFFORT, xp: 100, isVariableXp: false, deadline: new Date(2020, 7, 21, 0, 0, 0), @@ -173,7 +164,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '8', title: 'Power of Friendship', - ability: AchievementAbility.COMMUNITY, xp: 100, isVariableXp: false, isTask: true, @@ -193,7 +183,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '9', title: 'Piazza Guru', - ability: AchievementAbility.COMMUNITY, xp: 100, isVariableXp: false, isTask: false, @@ -213,7 +202,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '16', title: "That's the Spirit", - ability: AchievementAbility.EXPLORATION, xp: 100, isVariableXp: false, isTask: true, @@ -233,7 +221,6 @@ export const mockAchievements: AchievementItem[] = [ { uuid: '13', title: 'Kool Kidz', - ability: AchievementAbility.FLEX, xp: 100, isVariableXp: false, isTask: true, diff --git a/src/features/achievement/AchievementConstants.ts b/src/features/achievement/AchievementConstants.ts index 1cc50be447..0e2a171c1c 100644 --- a/src/features/achievement/AchievementConstants.ts +++ b/src/features/achievement/AchievementConstants.ts @@ -2,7 +2,7 @@ import React from 'react'; import AchievementInferencer from '../../commons/achievement/utils/AchievementInferencer'; import { Links } from '../../commons/utils/Constants'; -import { AchievementAbility, FilterStatus } from './AchievementTypes'; +import { FilterStatus } from './AchievementTypes'; export const AchievementContext = React.createContext(new AchievementInferencer([], [])); @@ -21,7 +21,11 @@ export const backgroundUrl = `${achievementAssets}/view-background`; export const cardBackgroundUrl = `${achievementAssets}/card-background`; export const coverImageUrl = `${achievementAssets}/cover-image`; -export const getAbilityBackground = (ability: AchievementAbility) => { +export const getAbilityBackground = () => { + return { + background: `url(${backgroundUrl}/exploration.png) no-repeat center/cover` + }; + /* switch (ability) { case AchievementAbility.CORE: return { @@ -48,9 +52,12 @@ export const getAbilityBackground = (ability: AchievementAbility) => { background: `` }; } + */ }; -export const getAbilityColor = (ability: AchievementAbility) => { +export const getAbilityColor = () => { + return '#9ce'; // blue + /* switch (ability) { case AchievementAbility.CORE: return '#fb0'; // gold @@ -65,27 +72,33 @@ export const getAbilityColor = (ability: AchievementAbility) => { default: return ''; } + */ }; -export const getAbilityGlow = (ability: AchievementAbility) => +export const getAbilityGlow = () => ({ + border: `1px solid ${getAbilityColor()}`, + boxShadow: `0 0 10px ${getAbilityColor()}` +}); + /* ability === AchievementAbility.FLEX ? { border: `1px solid ${getAbilityColor(ability)}`, boxShadow: ` - 0 0 10px #ff0, /* yellow */ - -1px 0 9px #f0f, /* magenta */ - 1px 0 9px #0ff /* cyan */` + 0 0 10px #ff0, + -1px 0 9px #f0f, + 1px 0 9px #0ff` } : { border: `1px solid ${getAbilityColor(ability)}`, boxShadow: `0 0 10px ${getAbilityColor(ability)}` }; + */ export const getFilterColor = (globalStatus: FilterStatus, ownStatus: FilterStatus) => globalStatus === ownStatus ? FilterColors.BLUE : FilterColors.WHITE; -// Make selected achievements + view and Flex achievements glow -export const handleGlow = (uuid: string, focusUuid: string, ability: AchievementAbility) => - ability === AchievementAbility.FLEX || uuid === focusUuid ? getAbilityGlow(ability) : undefined; +// Make selected achievement + view glow +export const handleGlow = (uuid: string, focusUuid: string) => + uuid === focusUuid ? getAbilityGlow() : undefined; export const xpPerLevel = 1000; diff --git a/src/features/achievement/AchievementTypes.ts b/src/features/achievement/AchievementTypes.ts index 5e3abe3e14..67bba402ca 100644 --- a/src/features/achievement/AchievementTypes.ts +++ b/src/features/achievement/AchievementTypes.ts @@ -18,14 +18,6 @@ export const SAVE_USERS = 'SAVE_USERS'; export const UPDATE_GOAL_PROGRESS = 'UPDATE_GOAL_PROGRESS'; export const UPDATE_OWN_GOAL_PROGRESS = 'UPDATE_OWN_GOAL_PROGRESS'; -export enum AchievementAbility { - CORE = 'Core', - EFFORT = 'Effort', - EXPLORATION = 'Exploration', - COMMUNITY = 'Community', - FLEX = 'Flex' -} - export enum AchievementStatus { ACTIVE = 'ACTIVE', // deadline not over and not completed COMPLETED = 'COMPLETED', // completed, regardless of deadline @@ -44,7 +36,6 @@ export enum FilterStatus { * * @param {string} uuid unique uuid of the achievement item * @param {string} title title of the achievement - * @param {AchievementAbility} ability ability of the achievement, string enum * @param {number} xp the xp gained when completing the achievement * @param {Date} deadline Optional, the deadline of the achievement * @param {Date} release Optional, the release date of the achievement @@ -58,7 +49,6 @@ export enum FilterStatus { export type AchievementItem = { uuid: string; title: string; - ability: AchievementAbility; xp: number; isVariableXp: boolean; deadline?: Date; From dca9cb07a28a68ef15ea68e66174236553e57c99 Mon Sep 17 00:00:00 2001 From: Jonas Chow Date: Wed, 4 Aug 2021 13:36:29 +0800 Subject: [PATCH 5/5] Fixed formatting --- src/commons/achievement/card/AchievementDeadline.tsx | 4 +--- .../control/achievementEditor/EditableCardTypes.ts | 5 +---- src/features/achievement/AchievementConstants.ts | 4 +++- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/commons/achievement/card/AchievementDeadline.tsx b/src/commons/achievement/card/AchievementDeadline.tsx index 1da4a8c5c8..e33697624b 100644 --- a/src/commons/achievement/card/AchievementDeadline.tsx +++ b/src/commons/achievement/card/AchievementDeadline.tsx @@ -15,9 +15,7 @@ function AchievementDeadline(props: AchievementDeadlineProps) { // red deadline color for core achievements that are expiring in less than 2 days const deadlineColor = - deadline !== undefined && - !isExpired(deadline) && - timeFromExpired(deadline) <= twoDays + deadline !== undefined && !isExpired(deadline) && timeFromExpired(deadline) <= twoDays ? DeadlineColors.RED : DeadlineColors.BLACK; diff --git a/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts b/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts index 7080c82727..f04157f6a6 100644 --- a/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts +++ b/src/commons/achievement/control/achievementEditor/EditableCardTypes.ts @@ -1,7 +1,4 @@ -import { - AchievementItem, - AchievementView -} from 'src/features/achievement/AchievementTypes'; +import { AchievementItem, AchievementView } from 'src/features/achievement/AchievementTypes'; export enum EditableCardActionType { CHANGE_CARD_BACKGROUND = 'CHANGE_CARD_BACKGROUND', diff --git a/src/features/achievement/AchievementConstants.ts b/src/features/achievement/AchievementConstants.ts index 0e2a171c1c..aacfae36d5 100644 --- a/src/features/achievement/AchievementConstants.ts +++ b/src/features/achievement/AchievementConstants.ts @@ -21,6 +21,8 @@ export const backgroundUrl = `${achievementAssets}/view-background`; export const cardBackgroundUrl = `${achievementAssets}/card-background`; export const coverImageUrl = `${achievementAssets}/cover-image`; +// Keeping these urls in as comments in case future changes want to use them + export const getAbilityBackground = () => { return { background: `url(${backgroundUrl}/exploration.png) no-repeat center/cover` @@ -79,7 +81,7 @@ export const getAbilityGlow = () => ({ border: `1px solid ${getAbilityColor()}`, boxShadow: `0 0 10px ${getAbilityColor()}` }); - /* +/* ability === AchievementAbility.FLEX ? { border: `1px solid ${getAbilityColor(ability)}`,