Skip to content
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

Add stories moderation #2928

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 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
7 changes: 6 additions & 1 deletion src/commons/application/ApplicationTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,12 @@ export const defaultSession: SessionState = {
};

export const defaultStories: StoriesState = {
storyList: [],
storyLists: {
draft: [],
pending: [],
rejected: [],
published: []
},
currentStoryId: null,
currentStory: null,
envs: {}
Expand Down
37 changes: 33 additions & 4 deletions src/commons/sagas/StoriesSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
SET_CURRENT_STORY_ID,
StoryData,
StoryListView,
StoryListViews,
StoryStatus,
StoryView
} from 'src/features/stories/StoriesTypes';

Expand All @@ -33,11 +35,34 @@ import { safeTakeEvery as takeEvery } from './SafeEffects';
export function* storiesSaga(): SagaIterator {
yield takeLatest(GET_STORIES_LIST, function* () {
const tokens: Tokens = yield selectTokens();
const allStories: StoryListView[] = yield call(async () => {
const resp = await getStories(tokens);

const draftStories: StoryListView[] = yield call(async () => {
const resp = await getStories(tokens, StoryStatus.Draft);
return resp ?? [];
});

const pendingStories: StoryListView[] = yield call(async () => {
const resp = await getStories(tokens, StoryStatus.Pending);
return resp ?? [];
});

const rejectedStories: StoryListView[] = yield call(async () => {
const resp = await getStories(tokens, StoryStatus.Rejected);
return resp ?? [];
});

const publishedStories: StoryListView[] = yield call(async () => {
const resp = await getStories(tokens, StoryStatus.Published);
return resp ?? [];
});

const allStories: StoryListViews = {
draft: draftStories,
pending: pendingStories,
rejected: rejectedStories,
published: publishedStories
};
Comment on lines +34 to +60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This design doesn't look right to me. To the user/the frontend, the "listing" of stories should be transparent.

In other words, the FE just makes one "list stories" query, and the backend returns a list of stories that the user has access to. The permissions/different types of stories should be transparent and the frontend can subsequently later filter the story by the status. You are adding a status field inside the story model in the backend but it's not being utilised here at all.


yield put(actions.updateStoriesList(allStories));
});

Expand All @@ -55,7 +80,9 @@ export function* storiesSaga(): SagaIterator {
const defaultStory: StoryData = {
title: '',
content: defaultStoryContent,
pinOrder: null
pinOrder: null,
status: StoryStatus.Draft,
statusMessage: ''
};
yield put(actions.setCurrentStory(defaultStory));
}
Expand Down Expand Up @@ -98,7 +125,9 @@ export function* storiesSaga(): SagaIterator {
id,
story.title,
story.content,
story.pinOrder
story.pinOrder,
story.status,
story.statusMessage
);

// TODO: Check correctness
Expand Down
4 changes: 2 additions & 2 deletions src/features/stories/StoriesActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
SET_CURRENT_STORY,
SET_CURRENT_STORY_ID,
StoryData,
StoryListView,
StoryListViews,
StoryParams,
TOGGLE_STORIES_USING_SUBST,
UPDATE_STORIES_LIST
Expand Down Expand Up @@ -70,7 +70,7 @@ export const toggleStoriesUsingSubst = createAction(
export const getStoriesList = createAction(GET_STORIES_LIST, () => ({ payload: {} }));
export const updateStoriesList = createAction(
UPDATE_STORIES_LIST,
(storyList: StoryListView[]) => ({ payload: storyList })
(storyLists: StoryListViews) => ({ payload: storyLists })
);
export const setCurrentStory = createAction(SET_CURRENT_STORY, (story: StoryData | null) => ({
payload: story
Expand Down
2 changes: 1 addition & 1 deletion src/features/stories/StoriesReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ const oldStoriesReducer: Reducer<StoriesState, SourceActionType> = (
case UPDATE_STORIES_LIST:
return {
...state,
storyList: action.payload
storyLists: action.payload
};
case SET_CURRENT_STORY_ID:
return {
Expand Down
18 changes: 17 additions & 1 deletion src/features/stories/StoriesTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,19 @@ export type StoryData = {
title: string;
content: string;
pinOrder: number | null;
status: StoryStatus;
statusMessage: string;
};

export type StoryParams = StoryData;

export enum StoryStatus {
Draft = 0,
Pending,
Rejected,
Published
}
Comment on lines +28 to +33
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, enum values should be UPPER_SNAKE_CASE (e.g. DRAFT)


export type StoryListView = StoryData &
StoryMetadata & {
id: number;
Expand Down Expand Up @@ -69,8 +78,15 @@ export type StoriesAuthState = {
readonly role?: StoriesRole;
};

export type StoryListViews = {
readonly draft: StoryListView[];
readonly pending: StoryListView[];
readonly rejected: StoryListView[];
readonly published: StoryListView[];
};

export type StoriesState = {
readonly storyList: StoryListView[];
readonly storyLists: StoryListViews;
readonly currentStoryId: number | null;
readonly currentStory: StoryData | null;
readonly envs: { [key: string]: StoriesEnvState };
Expand Down
26 changes: 21 additions & 5 deletions src/features/stories/storiesComponents/BackendAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { store } from 'src/pages/createStore';

import { Tokens } from '../../../commons/application/types/SessionTypes';
import { NameUsernameRole } from '../../../pages/academy/adminPanel/subcomponents/AddStoriesUserPanel';
import { StoryListView, StoryView } from '../StoriesTypes';
import { StoryListView, StoryStatus, StoryView } from '../StoriesTypes';

// Helpers

Expand Down Expand Up @@ -75,8 +75,22 @@ export const postNewStoriesUsers = async (
// TODO: Return response JSON directly.
};

export const getStories = async (tokens: Tokens): Promise<StoryListView[] | null> => {
const resp = await requestStoryBackend(`/groups/${getStoriesGroupId()}/stories`, 'GET', {
export const getStories = async (
tokens: Tokens,
status: StoryStatus | null = null
): Promise<StoryListView[] | null> => {
const route =
status === StoryStatus.Draft
? '/draft'
: status === StoryStatus.Pending
? '/pending'
: status === StoryStatus.Rejected
? '/rejected'
: status === StoryStatus.Published
? '/published'
: '';
Comment on lines +83 to +91
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filters are generally done using a query parameter instead of a different route/path (which would conventionally mean a different resource.)


const resp = await requestStoryBackend(`/groups/${getStoriesGroupId()}/stories${route}`, 'GET', {
...tokens
});
if (!resp) {
Expand Down Expand Up @@ -124,10 +138,12 @@ export const updateStory = async (
id: number,
title: string,
content: string,
pinOrder: number | null
pinOrder: number | null,
status: StoryStatus,
statusMessage: string
): Promise<StoryView | null> => {
const resp = await requestStoryBackend(`/groups/${getStoriesGroupId()}/stories/${id}`, 'PUT', {
body: { title, content, pinOrder },
body: { title, content, pinOrder, status, statusMessage },
...tokens
});
if (!resp) {
Expand Down
Loading
Loading