feat: Sidebar and StoreProvider

This commit is contained in:
Anoop M D
2021-12-04 01:07:38 +05:30
parent 07fc8af7ed
commit a863f9730d
22 changed files with 759 additions and 18 deletions

View File

@@ -0,0 +1,11 @@
const SIDEBAR_COLLECTION_CLICK = "SIDEBAR_COLLECTION_CLICK";
const SIDEBAR_COLLECTION_ITEM_CLICK = "SIDEBAR_COLLECTION_ITEM_CLICK";
const REQUEST_TAB_CLICK = "REQUEST_TAB_CLICK";
const REQUEST_TAB_CLOSE = "REQUEST_TAB_CLOSE";
export default {
SIDEBAR_COLLECTION_CLICK,
SIDEBAR_COLLECTION_ITEM_CLICK,
REQUEST_TAB_CLICK,
REQUEST_TAB_CLOSE
};

View File

@@ -0,0 +1,79 @@
import React, { useContext, useReducer, createContext } from 'react';
import reducer from './reducer';
import { nanoid } from 'nanoid';
export const StoreContext = createContext();
const tabId1 = nanoid();
const collection = {
"id": nanoid(),
"name": "SpaceX",
"items": [
{
"id": nanoid(),
"name": "Launches",
"depth": 1,
"items": [
{
"id": nanoid(),
"depth": 2,
"name": "Capsules",
"request": {
"url": "https://api.spacex.land/graphql/",
"method": "POST",
"headers": [],
"body": {
"mimeType": "application/graphql",
"graphql": {
"query": "{\n launchesPast(limit: 10) {\n mission_name\n launch_date_local\n launch_site {\n site_name_long\n }\n links {\n article_link\n video_link\n }\n rocket {\n rocket_name\n first_stage {\n cores {\n flight\n core {\n reuse_count\n status\n }\n }\n }\n second_stage {\n payloads {\n payload_type\n payload_mass_kg\n payload_mass_lbs\n }\n }\n }\n ships {\n name\n home_port\n image\n }\n }\n}",
"variables": ""
}
}
}
},
{
"id": nanoid(),
"depth": 2,
"name": "Missions",
"request": {
"url": "https://api.spacex.land/graphql/",
"method": "POST",
"headers": [],
"body": {
"mimeType": "application/graphql",
"graphql": {
"query": "{\n launches {\n launch_site {\n site_id\n site_name\n site_name_long\n }\n launch_success\n }\n}",
"variables": ""
}
}
}
}
]
}
]
};
const initialState = {
collections: [collection],
activeRequestTabId: null,
requestTabs: []
};
export const StoreProvider = props => {
const [state, dispatch] = useReducer(reducer, initialState);
return <StoreContext.Provider value={[state, dispatch]} {...props} />;
};
export const useStore = () => {
const context = useContext(StoreContext);
if (context === undefined) {
throw new Error(`useStore must be used within a StoreProvider`);
}
return context;
};
export default StoreProvider;

View File

@@ -0,0 +1,79 @@
import produce from 'immer';
import find from 'lodash/find';
import filter from 'lodash/filter';
import actions from './actions';
import {
flattenItems,
findItem,
isItemARequest,
itemIsOpenedInTabs
} from './utils';
const reducer = (state, action) => {
switch (action.type) {
case actions.SIDEBAR_COLLECTION_CLICK: {
return produce(state, (draft) => {
const collecton = find(draft.collections, (c) => c.id === action.id);
if(collecton) {
collecton.collapsed = !collecton.collapsed;
}
});
}
case actions.SIDEBAR_COLLECTION_ITEM_CLICK: {
return produce(state, (draft) => {
const collecton = find(draft.collections, (c) => c.id === action.collectionId);
if(collecton) {
let flattenedItems = flattenItems(collecton.items);
let item = findItem(flattenedItems, action.itemId);
if(item) {
item.collapsed = !item.collapsed;
if(isItemARequest(item)) {
if(itemIsOpenedInTabs(item, draft.requestTabs)) {
draft.activeRequestTabId = item.id;
} else {
draft.requestTabs.push({
id: item.id,
name: item.name,
method: item.request.method,
collectionId: collecton.id
});
draft.activeRequestTabId = item.id;
}
}
}
}
});
}
case actions.REQUEST_TAB_CLICK: {
return produce(state, (draft) => {
draft.activeRequestTabId = action.requestTab.id;
});
}
case actions.REQUEST_TAB_CLOSE: {
return produce(state, (draft) => {
draft.requestTabs = filter(draft.requestTabs, (rt) => rt.id !== action.requestTab.id);
if(draft.requestTabs && draft.requestTabs.length) {
draft.activeRequestTabId = draft.requestTabs[0].id;
console.log(draft.activeRequestTabId);
} else {
draft.activeRequestTabId = null;
}
});
}
default: {
return state;
}
}
}
export default reducer;

View File

@@ -0,0 +1,32 @@
import each from 'lodash/each';
import find from 'lodash/find';
export const flattenItems = (items = []) => {
const flattenedItems = [];
const flatten = (itms, flattened) => {
each(itms, (i) => {
flattened.push(i);
if(i.items && i.items.length) {
flatten(i.items, flattened);
}
})
}
flatten(items, flattenedItems);
return flattenedItems;
};
export const findItem = (items = [], itemId) => {
return find(items, (i) => i.id === itemId);
};
export const isItemARequest = (item) => {
return item.hasOwnProperty('request');
};
export const itemIsOpenedInTabs = (item, tabs) => {
return find(tabs, (t) => t.id === item.id);
};