Skip to content

Commit

Permalink
Add super rough list of changes UI/API
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed May 19, 2020
1 parent 402476b commit 89a6cfd
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 1 deletion.
3 changes: 2 additions & 1 deletion backend/atlas/queries/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import graphene

from . import departments, employeetypes, me, offices, users
from . import changes, departments, employeetypes, me, offices, users


class RootQuery(
me.Query,
changes.Query,
departments.Query,
employeetypes.Query,
offices.Query,
Expand Down
54 changes: 54 additions & 0 deletions backend/atlas/queries/changes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from uuid import UUID

import graphene
import graphene_django_optimizer as gql_optimizer
from graphql.error import GraphQLError

from atlas.models import Change
from atlas.schema import ChangeNode


class Query(object):
changes = graphene.List(
ChangeNode,
id=graphene.UUID(),
object_type=graphene.String(),
object_id=graphene.UUID(),
offset=graphene.Int(),
limit=graphene.Int(),
)

def resolve_changes(
self,
info,
id: str = None,
object_type: str = None,
object_id: UUID = None,
offset: int = 0,
limit: int = 1000,
**kwargs
):
assert limit <= 1000
assert offset >= 0

current_user = info.context.user
if not current_user.is_authenticated:
raise GraphQLError("You must be authenticated")

if not current_user.is_superuser:
raise GraphQLError("You must be superuser")

qs = Change.objects.all().distinct()

if id:
qs = qs.filter(id=id)

if object_type:
qs = qs.filter(object_type=object_type)

if object_id:
qs = qs.filter(object_id=object_id)

qs = qs.order_by("-timestamp")

return list(gql_optimizer.query(qs, info)[offset:limit])
13 changes: 13 additions & 0 deletions backend/atlas/queries/test_changes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from atlas.models import Change


def test_changes(gql_client, default_user, default_office):
change = Change.objects.create(
object_type="user",
object_id=default_user.id,
changes={"name": "Joe Dirt"},
user=default_user,
)

executed = gql_client.execute("""{changes {id}}""", user=default_user)
assert executed["data"]["changes"] == [{"id": str(change.id)}]
1 change: 1 addition & 0 deletions backend/atlas/schema/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .binary import * # NOQA
from .change import * # NOQA
from .decimal import * # NOQA
from .department import * # NOQA
from .departmentinput import * # NOQA
Expand Down
18 changes: 18 additions & 0 deletions backend/atlas/schema/change.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import graphene_django_optimizer as gql_optimizer

from atlas.models import Change


class ChangeNode(gql_optimizer.OptimizedDjangoObjectType):
class Meta:
model = Change
name = "Change"
fields = (
"id",
"object_type",
"object_id",
"user",
"changes",
"timestamp",
"version",
)
47 changes: 47 additions & 0 deletions frontend/src/pages/AdminChanges.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import { Link } from "react-router";
import { Flex, Box } from "@rebass/grid/emotion";
import { Query } from "react-apollo";

import Card from "../components/Card";
import PageLoader from "../components/PageLoader";
import { LIST_CHANGES_QUERY } from "../queries";

export default () => (
<section>
<Card>
<h1>Changes</h1>
</Card>
<Card withPadding>
<Query
query={LIST_CHANGES_QUERY}
variables={{
limit: 1000
}}
>
{({ loading, error, data }) => {
if (error) throw error;
if (loading) return <PageLoader />;
const { changes } = data;
return changes.map(c => (
<div style={{ marginBottom: "0.5rem" }}>
<Flex>
<Box flex="1">
<Link to={`/admin/changes/${c.id}`}>
{c.objectType} {c.objectId}
</Link>
<div>
<small>{c.changes}</small>
</div>
</Box>
<Box style={{ width: 50 }}>{c.version}</Box>
<Box style={{ width: 200 }}>{c.user && c.user.email}</Box>
<Box style={{ textAlign: "right" }}>{c.timestamp}</Box>
</Flex>
</div>
));
}}
</Query>
</Card>
</section>
);
4 changes: 4 additions & 0 deletions frontend/src/pages/AdminLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export default ({ children }) => (
Create Department
</NavigationLink>
</Card>
<Card withPadding>
<h2>Changes</h2>
<NavigationLink to="/admin/changes">All Changes</NavigationLink>
</Card>
</Box>
<Box flex="1" mx={3}>
{children}
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ export const GET_OFFICE_QUERY = gql`
}
`;

export const LIST_CHANGES_QUERY = gql`
query listChanges($id: UUID, $objectType: String, $objectId: UUID) {
changes(id: $id, objectType: $objectType, objectId: $objectId) {
id
objectType
objectId
timestamp
user {
name
email
}
version
changes
}
}
`;

export const LIST_DEPARTMENTS_QUERY = gql`
query listDepartments(
$id: UUID
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import App from "./pages/App";
import AdminLayout from "./pages/AdminLayout";
import AdminAudit from "./pages/AdminAudit";
import AdminBulkUpdatePeople from "./pages/AdminBulkUpdatePeople";
import AdminChanges from "./pages/AdminChanges";
import AdminCreateDepartment from "./pages/AdminCreateDepartment";
import AdminDepartments from "./pages/AdminDepartments";
import AdminDeleteDepartment from "./pages/AdminDeleteDepartment";
Expand Down Expand Up @@ -45,6 +46,7 @@ export default (
<Route path="/people/:email" component={Profile} />
<Route path="/people/:email/update" component={UpdateProfile} />
<Route path="/admin" component={AdminLayout}>
<Route path="/admin/changes" component={AdminChanges} />
<Route path="/admin/departments" component={AdminDepartments} />
<Route path="/admin/departments/create" component={AdminCreateDepartment} />
<Route path="/admin/departments/:departmentId" component={AdminUpdateDepartment} />
Expand Down

0 comments on commit 89a6cfd

Please sign in to comment.