Skip to content

Commit

Permalink
Add origins loaded selectors. Try login socket as anonymous user. Lis…
Browse files Browse the repository at this point in the history
…ten to all origins socket events
  • Loading branch information
javierbrea committed Mar 2, 2019
1 parent d6e52aa commit a3aacd0
Show file tree
Hide file tree
Showing 28 changed files with 253 additions and 158 deletions.
9 changes: 9 additions & 0 deletions mocks/features/errors.js
@@ -0,0 +1,9 @@
const { base } = require("./base");

const { getLogsError } = require("./fixtures/logs/get");

const logsError = base.extend([getLogsError]);

module.exports = {
logsError
};
14 changes: 14 additions & 0 deletions mocks/features/fixtures/logs/get.js
Expand Up @@ -76,6 +76,19 @@ const getLogsSuccess = {
}
};

const getLogsError = {
url: "/api/logs",
method: "GET",
response: {
status: 500,
body: {
statusCode: 500,
error: "Internal server error",
message: "Internal server error"
}
}
};

const countLogsSuccess = {
url: "/api/logs/stats",
method: "GET",
Expand All @@ -89,5 +102,6 @@ const countLogsSuccess = {

module.exports = {
getLogsSuccess,
getLogsError,
countLogsSuccess
};
94 changes: 49 additions & 45 deletions src/components/logs-list/LogsList.js
@@ -1,7 +1,8 @@
import React, { Component } from "react";
import React from "react";
import PropTypes from "prop-types";

import { Table } from "semantic-ui-react";
import { Component as ErrorComponent } from "src/components/error";

import "./logsList.css";

Expand All @@ -11,6 +12,18 @@ export const NoResults = () => (
</Table.Row>
);

export const ResultsError = ({ message }) => (
<Table.Row>
<Table.Cell colSpan="5">
<ErrorComponent>{message}</ErrorComponent>
</Table.Cell>
</Table.Row>
);

ResultsError.propTypes = {
message: PropTypes.string
};

export const Log = ({ module, ability, type, data, dateTime, loading }) => (
<Table.Row className={loading ? "logs__row--loading" : ""}>
<Table.Cell>{dateTime}</Table.Cell>
Expand All @@ -30,57 +43,48 @@ Log.propTypes = {
type: PropTypes.string
};

export class LogsList extends Component {
constructor(props) {
super(props);
this.state = {
loaded: props.logs.length > 0
};
if (this.state.loaded && props.onLoaded) {
props.onLoaded();
}
}

componentDidUpdate() {
if (!this.state.loaded && this.props.logsLoading === false && this.props.onLoaded) {
this.setState({
loaded: true
});
this.props.onLoaded();
}
export const LogsList = ({
logs = [],
logsLoading,
logsError,
logsLoaded,
showPlaceHolders,
showNoResults,
showError
}) => {
const placeHolders = [];
if (logsError) {
return showError ? <ResultsError message={logsError.message} /> : null;
}

render() {
const placeHolders = [];
const { logs = [], logsLoading, showPlaceHolders, showNoResults } = this.props;
if (logs.length < 1 && logsLoading && showPlaceHolders) {
for (let i = 0; i < showPlaceHolders + 1; i++) {
placeHolders.push(<Log key={i} loading={true} dateTime="..." ability=" " />);
}
return <React.Fragment>{placeHolders.map(placeHolder => placeHolder)}</React.Fragment>;
if (!logsLoaded && logsLoading && showPlaceHolders) {
for (let i = 0; i < showPlaceHolders + 1; i++) {
placeHolders.push(<Log key={i} loading={true} dateTime="..." ability=" " />);
}
return (
<React.Fragment>
{showNoResults && logs.length < 1 && !logsLoading ? <NoResults /> : null}
{logs.map(log => (
<Log
key={log._id}
module={log.module}
ability={log.ability}
type={log.type}
data={log.data}
dateTime={log.dateTime}
/>
))}
</React.Fragment>
);
return <React.Fragment>{placeHolders.map(placeHolder => placeHolder)}</React.Fragment>;
}
}
return (
<React.Fragment>
{showNoResults && logs.length < 1 && !logsLoading ? <NoResults /> : null}
{logs.map(log => (
<Log
key={log._id}
module={log.module}
ability={log.ability}
type={log.type}
data={log.data}
dateTime={log.dateTime}
/>
))}
</React.Fragment>
);
};

LogsList.propTypes = {
logs: PropTypes.array,
logsError: PropTypes.instanceOf(Error),
logsLoaded: PropTypes.bool,
logsLoading: PropTypes.bool,
onLoaded: PropTypes.func,
showError: PropTypes.bool,
showNoResults: PropTypes.bool,
showPlaceHolders: PropTypes.number
};
32 changes: 8 additions & 24 deletions src/components/scroll-paginated-list/ScrollPaginatedList.js
@@ -1,35 +1,23 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroller";
import { throttle } from "lodash";

import { ScrollContext } from "src/contexts/ScrollContext";

export class ScrollPaginatedList extends Component {
constructor(props) {
super(props);
this.state = {
currentPage: 1,
hasLoaded: {}
currentPage: 1
};
this.loadMore = this.loadMore.bind(this);
this.setLoaded = this.setLoaded.bind(this);
this.loadMore = throttle(this.loadMore.bind(this), 500);
}

loadMore(page) {
this.setState(state => ({
...state,
this.setState({
currentPage: page
}));
}

setLoaded(listId) {
this.setState(state => ({
...state,
hasLoaded: {
...state.hasLoaded,
[listId]: true
}
}));
});
}

hasMore() {
Expand All @@ -46,20 +34,16 @@ export class ScrollPaginatedList extends Component {
<List
page={i}
key={listId}
showPlaceHolders={this.state.hasLoaded[listId] ? 0 : this.props.pageSize}
showPlaceHolders={this.props.pageSize}
extraFilter={this.props.extraFilter}
onLoaded={() => {
if (!this.state.hasLoaded[listId]) {
this.setLoaded(listId);
}
}}
showError={i === 1}
/>
);
}
if (!this.props.itemsCountLoading && this.props.itemsCount.total === 0) {
return (
<ListWrapper>
<List showNoResults={true} />
<List showNoResults={true} showError={true} />
</ListWrapper>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/data-layer/authentication/index.js
@@ -0,0 +1 @@
export * from "./origins";
@@ -1,6 +1,6 @@
import { origins } from "reactive-data-source";

import { baseConfig } from "../../setup";
import { baseConfig } from "../setup";

// AUTHENTICATION SESSION

Expand Down
2 changes: 1 addition & 1 deletion src/data-layer/login.js
Expand Up @@ -2,7 +2,7 @@

import queryString from "query-string";

import { authSession, authJwt } from "./users";
import { authSession, authJwt } from "./authentication";
import { config, removeAuth, setJwtAuth, setApiKeyAuth, cleanAll } from "./setup";

class Login {
Expand Down
5 changes: 5 additions & 0 deletions src/data-layer/services/abilities/origins.js
@@ -1,6 +1,7 @@
import { origins } from "reactive-data-source";

import { authConfig } from "../../setup";
import { socket } from "../../socket";

import { ofService } from "./filters";

Expand All @@ -18,3 +19,7 @@ export const abilitiesCollection = new origins.Api(
abilitiesCollection.addCustomFilter({
ofService
});

socket.addListener(["ability:created", "ability:deleted", "ability:updated"], () => {
abilitiesCollection.clean();
});
12 changes: 8 additions & 4 deletions src/data-layer/services/ability/origins.js
Expand Up @@ -20,6 +20,10 @@ abilityModels.addCustomFilter({
byId: byIdFilter
});

socket.addListener(["ability:updated", "ability:deleted"], eventData => {
abilityModels.byId(eventData._id).clean();
});

export const abilityStates = new origins.Api(
"/abilities/:id/state",
{},
Expand All @@ -33,6 +37,10 @@ abilityStates.addCustomFilter({
byId: byIdFilter
});

socket.addListener("ability:event", eventData => {
abilityStates.byId(eventData._id).clean();
});

export const abilityActions = new origins.Api(
"/abilities/:id/action",
{
Expand All @@ -47,7 +55,3 @@ export const abilityActions = new origins.Api(
abilityActions.addCustomFilter({
byId: byIdFilter
});

socket.addListener("ability:event", eventData => {
abilityStates.byId(eventData._id).clean();
});
17 changes: 16 additions & 1 deletion src/data-layer/services/ability/selectors.js
Expand Up @@ -4,7 +4,7 @@ import { byIdFilter } from "../../helpers";
import { modulesCollection } from "../services/selectors";
import { addAbilityExtraData } from "./helpers";

import { abilityModels } from "./origins";
import { abilityModels, abilityStates } from "./origins";

export const abilityModelsWithExtraData = new Selector(
{
Expand All @@ -21,3 +21,18 @@ export const abilityModelsWithExtraData = new Selector(
abilityModelsWithExtraData.addCustomFilter({
byId: id => id
});

export const abilityStatesLoaded = new Selector(
{
source: abilityStates,
filter: id => byIdFilter(id)
},
() => {
return true;
},
false
);

abilityStatesLoaded.addCustomFilter({
byId: id => id
});
15 changes: 15 additions & 0 deletions src/data-layer/services/logs/filters.js
@@ -0,0 +1,15 @@
export const byPageAndAbility = filter => {
const query = {};
if (filter) {
if (filter.page) {
query.page = filter.page;
}
if (filter.ability) {
query.ability = filter.ability;
}
return {
query
};
}
return null;
};
18 changes: 6 additions & 12 deletions src/data-layer/services/logs/origins.js
@@ -1,10 +1,10 @@
import { debounce } from "lodash";
import { throttle } from "lodash";
import { origins } from "reactive-data-source";

import { authConfig } from "../../setup";
import { socket } from "../../socket";

const REFRESH_LOGS_MAX_INTERVAL = 10000;
const REFRESH_LOGS_MAX_INTERVAL = 5000;

export const logs = new origins.Api(
"/logs",
Expand Down Expand Up @@ -36,14 +36,8 @@ countLogs.addCustomFilter({

socket.addListener(
"log:created",
debounce(
() => {
countLogs.clean();
logs.clean();
},
REFRESH_LOGS_MAX_INTERVAL,
{
maxWait: REFRESH_LOGS_MAX_INTERVAL
}
)
throttle(() => {
countLogs.clean();
logs.clean();
}, REFRESH_LOGS_MAX_INTERVAL)
);

0 comments on commit a3aacd0

Please sign in to comment.