Skip to content

Commit

Permalink
Badges REST API #2
Browse files Browse the repository at this point in the history
  • Loading branch information
Siluky committed May 12, 2022
1 parent 9e7184f commit 94b2f25
Show file tree
Hide file tree
Showing 22 changed files with 297 additions and 108 deletions.
15 changes: 0 additions & 15 deletions .history/cvat/apps/gamification/models_20220421175244.py

This file was deleted.

4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
{
"filePath": "cvat/settings/base.py",
"group": "Default"
},
{
"filePath": "cvat-ui/src/gamification/components/badges/badge-overview.tsx",
"group": "Default"
}
],
"favorites.sortOrder": "MANUAL"
Expand Down
10 changes: 10 additions & 0 deletions cvat-core/src/api-implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,16 @@ const config = require('./config');
config.organizationID = null;
};

cvat.badges.get.implementation = async () => {
const badges = await serverProxy.badges.get();
return badges;
};

cvat.badges.getStatus.implementation = async () => {
const badges = await serverProxy.badges.getStatus();
return badges;
};

return cvat;
}

Expand Down
28 changes: 28 additions & 0 deletions cvat-core/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,31 @@ function build() {
return result;
},
},

/**
* Namespace is used for access to badges
* @namespace badges
* @memberof module:API.cvat
*/
badges: {
/**
* TODO:
* @returns
*/
async get() {
const result = await PluginRegistry.apiWrapper(cvat.badges.get);
return result;
},
/**
* TODO:
* @returns the status of all badges regarding the currently active user
*/
async getStatus() {
const result = await PluginRegistry.apiWrapper(cvat.badges.getStatus);
return result;
},
},

/**
* Namespace is used for access to classes
* @namespace classes
Expand All @@ -865,6 +890,7 @@ function build() {
CloudStorage,
Organization,
},

};

cvat.server = Object.freeze(cvat.server);
Expand All @@ -879,6 +905,8 @@ function build() {
cvat.cloudStorages = Object.freeze(cvat.cloudStorages);
cvat.organizations = Object.freeze(cvat.organizations);

cvat.badges = Object.freeze(cvat.badges);

const implementAPI = require('./api-implementation');

Math.clamp = function clamp(value, min, max) {
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/plugins.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2019-2021 Intel Corporation
// Copyright (C) 2019-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT

Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/project.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2019-2021 Intel Corporation
// Copyright (C) 2019-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT

Expand Down
29 changes: 29 additions & 0 deletions cvat-core/src/server-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -1759,6 +1759,26 @@
return response.data;
}

// Gamification part from here
async function getBadges() {
const { backendAPI } = config;
let response = null;
response = await Axios.get(`${backendAPI}/badges`);
return response.data.results;
}

//
async function getBadgeStatus() {
const { backendAPI } = config;
let response = null;
response = await Axios.get(`${backendAPI}/badges/user-badges`);
return response.data.results;
}

/* async function updateBadges() {
const { backendAPI } = config;
} */

Object.defineProperties(
this,
Object.freeze({
Expand Down Expand Up @@ -1917,6 +1937,15 @@
}),
writable: false,
},

badges: {
value: Object.freeze({
get: getBadges,
getStatus: getBadgeStatus,
// update: updateBadges, //TODO:
}),
writable: false,
},
}),
);
}
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/src/actions/tasks-actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2019-2021 Intel Corporation
// Copyright (C) 2022 Intel Corporation
//
// SPDX-License-Identifier: MIT

Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/src/containers/tasks-page/tasks-list.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2022 Intel Corporation
//
// SPDX-License-Identifier: MIT

Expand Down
63 changes: 51 additions & 12 deletions cvat-ui/src/gamification/actions/badge-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,68 @@
//
// SPDX-License-Identifier: MIT

import { AnyAction } from 'redux';
// import getCore from 'cvat-core-wrapper';
import { ActionCreator, AnyAction, Dispatch } from 'redux';
import getCore from 'cvat-core-wrapper';
import { ThunkAction } from 'redux-thunk';
import { Badge } from '../gamif-interfaces';

// const cvat = getCore();
const cvat = getCore();

export enum BadgeActionTypes {
LOAD_BADGES = 'LOAD_BADGES',
LOAD_BADGES_FAILED = 'LOAD_BADGES_FAILED',
LOAD_BADGES_SUCCESS = 'LOAD_BADGES_SUCCESS',
SET_CURRENT_BADGE = 'SET_CURRENT_BADGE',
INCREMENT_BADGE = 'INCREMENT_BADGE',
SAVE_BADGES = 'SAVE_BADGES',
}

export async function loadBadges(badges: Badge[]): Promise<AnyAction> {
/*
try {
badges = await cvat.badges.list();
} catch (error) {
// do something to handle the error
} */
function loadBadgesFailed(error: any): AnyAction {
const action = {
type: BadgeActionTypes.LOAD_BADGES_FAILED,
payload: { error },
};
return action;
}

return {
type: BadgeActionTypes.LOAD_BADGES,
function loadBadgesSuccess(badges: any[]): AnyAction {
console.log('LOAD_BADGES_SUCCESS should be dispatched now with data: ');
console.log(badges);

const action = {
type: BadgeActionTypes.LOAD_BADGES_SUCCESS,
payload: badges,
};
return action;
}

export function loadBadgesAsync(): ThunkAction<void, {}, {}, AnyAction> {
return async function loadBadgesThunk(dispatch: ActionCreator<Dispatch>): Promise<void> {
let allBadges = null;
try {
allBadges = await cvat.badges.getStatus();
} catch (error) {
dispatch(loadBadgesFailed(error));
}

dispatch(loadBadgesSuccess(allBadges));
};
}

export function incrementBadge(badge: Badge): AnyAction {
return {
type: BadgeActionTypes.INCREMENT_BADGE,
payload: badge,
};
}

export function saveBadges(): AnyAction {
// TODO:

return {
type: BadgeActionTypes.SAVE_BADGES,
payload: { },
};
}

export function setCurrentBadge(badge: Badge): AnyAction {
Expand Down
40 changes: 24 additions & 16 deletions cvat-ui/src/gamification/components/badges/badge-overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,49 @@ import {
Progress,
Button,
Tabs,
notification,
} from 'antd';
import { connect, useDispatch, useSelector } from 'react-redux';
import { CombinedState } from 'reducers/interfaces';

import { BadgeIcon, BadgeGreyIcon } from '../../../icons';
import { Badge } from '../../gamif-interfaces';
import { setCurrentBadge } from '../../actions/badge-actions';
import {
setCurrentBadge,
loadBadgesAsync,
incrementBadge,
saveBadges,
} from '../../actions/badge-actions';

// TODO: add if necessary
interface BadgeOverviewProps {
currentBadge: Badge;
availableBadges: Badge[];
setCurrentBadge: (badge: Badge) => void;
loadBadges: () => void;
}

interface StateToProps {
currentBadge: Badge;
availableBadges: Badge[];
}

interface DispatchToProps {
setCurrentBadge: (badge: Badge) => void;
loadBadges: () => void;
}

function mapStateToProps(state: CombinedState): StateToProps {
const { badges } = state;

return {
currentBadge: badges.selectedBadge,
availableBadges: badges.availableBadges,
};
}

function mapDispatchToProps(dispatch: any): DispatchToProps {
return {
loadBadges: (): void => dispatch(loadBadgesAsync()),
setCurrentBadge: (badge: Badge): void => dispatch(setCurrentBadge(badge)),
};
}
Expand All @@ -62,26 +72,18 @@ const showSelectedBadge = (badge: Badge): JSX.Element => (
);

export function BadgeOverview(props: BadgeOverviewProps): JSX.Element {
const badges = useSelector((state: CombinedState) => state.badges); // TODO:
const badges = useSelector((state: CombinedState) => state.badges);
const dispatch = useDispatch();

const { currentBadge } = props;
const { currentBadge, loadBadges } = props;

// Load in badges from database on open of profile.
// TODO: Remove the "currentBadge" in dependency array once done
useEffect(() => {
try {
// const loadedBadges: any = {}; // TODO: Check if this typing is okay
// TODO: Load in badges from database // update badge data
// for-loop
console.log('Badge-Overview: useEffect Hook triggered');
loadBadges();
}, [currentBadge]);

// dispatch(loadBadges(loadedBadges));
} catch {
notification.error({
message: 'Failed to load badges.',
className: 'gamif-badge-load-fail',
});
}
}, []);
// TODO: Add that only visible badges get shown
return (
<Tabs type='card' defaultActiveKey='1' className='badge-overview-tabs'>
Expand All @@ -99,6 +101,12 @@ export function BadgeOverview(props: BadgeOverviewProps): JSX.Element {
/>
</Col>
))}
<Button type='text' onClick={(): void => { dispatch(incrementBadge(currentBadge)); }}>
+
</Button>
<Button type='text' onClick={(): void => { dispatch(saveBadges()); }}>
Save
</Button>
</Row>
</div>
<div className='gamif-badge-detail-view'>
Expand Down
1 change: 1 addition & 0 deletions cvat-ui/src/gamification/gamif-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Badge {
export interface BadgeState {
availableBadges: Badge[];
selectedBadge: Badge;
loading: boolean;
}

export enum ChallengeType {
Expand Down
Loading

0 comments on commit 94b2f25

Please sign in to comment.