Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 9 additions & 0 deletions app/controllers/StatusController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,13 @@ class StatusController @Inject()(cc:ControllerComponents, override val bearerTok
})
}}

def recordsForProject(projectId:Int) = IsAuthenticatedAsync {uid=>{request=>
StatusChangeDAO.getRecordsForProject(projectId).map({
case Success(results)=>Ok(Json.obj("status"->"ok","result"->results))
case Failure(error)=>
logger.error("Could not list status changes: ", error)
InternalServerError(Json.obj("status"->"error","detail"->error.toString))
})
}}

}
5 changes: 5 additions & 0 deletions app/models/StatusChange.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ object StatusChangeDAO extends ((Option[Int], Int, Timestamp, String, String, St
db.run(
TableQuery[StatusChange].sortBy(_.id.desc).drop(startAt).take(limit).result.asTry
)

def getRecordsForProject(projectId:Int)(implicit db:slick.jdbc.PostgresProfile#Backend#Database) =
db.run(
TableQuery[StatusChange].filter(_.projectId===projectId).result.asTry
)
}

class StatusChange(tag:Tag) extends Table[StatusChangeDAO](tag, "StatusChange") {
Expand Down
1 change: 1 addition & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ GET /api/project/:id/fileDownload @controllers.ProjectEntryController.
PUT /api/project/:id/restore/:version @controllers.ProjectEntryController.restoreBackup(id:Int, version:Int)
PUT /api/project/:id/restoreForAssetFolder @controllers.ProjectEntryController.restoreAssetFolderBackup(id:Int)
PUT /api/project/:id/statusChange @controllers.StatusController.record(id: Int)
GET /api/project/:id/statusChanges @controllers.StatusController.recordsForProject(id:Int)
GET /api/statusChanges @controllers.StatusController.records(startAt:Int ?=0,length:Int ?=100)

GET /api/valid-users @controllers.ProjectEntryController.queryUsersForAutocomplete(prefix:String ?= "", limit:Option[Int])
Expand Down
97 changes: 96 additions & 1 deletion frontend/app/ProjectEntryList/ProjectEntryEditComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ import {
styled,
Select,
MenuItem,
Table,
TableHead,
TableRow,
TableCell,
TableSortLabel,
TableBody,
TableContainer,
} from "@material-ui/core";
import {
getProject,
Expand All @@ -29,6 +36,7 @@ import {
getMissingFiles,
downloadProjectFile,
recordStatusChange,
getStatusChanges,
} from "./helpers";
import {
SystemNotification,
Expand All @@ -54,7 +62,7 @@ import ProjectFileUpload from "./ProjectFileUpload";
import FolderIcon from "@material-ui/icons/Folder";
import BuildIcon from "@material-ui/icons/Build";
import LaunchIcon from "@material-ui/icons/Launch";
import { sortListByOrder } from "../utils/lists";
import { SortDirection, sortListByOrder } from "../utils/lists";

declare var deploymentRootPath: string;

Expand Down Expand Up @@ -114,6 +122,12 @@ const EMPTY_FILE: FileEntry = {
premiereVersion: 0,
};

const tableHeaderTitles: HeaderTitle<StatusChange>[] = [
{ label: "User", key: "user" },
{ label: "Time", key: "time" },
{ label: "Status", key: "status" },
];

const ProjectEntryEditComponent: React.FC<ProjectEntryEditComponentProps> = (
props
) => {
Expand All @@ -139,6 +153,9 @@ const ProjectEntryEditComponent: React.FC<ProjectEntryEditComponentProps> = (
const [fileData, setFileData] = useState<FileEntry>(EMPTY_FILE);
const [premiereProVersion, setPremiereProVersion] = useState<number>(1);
const [userName, setUserName] = useState<string>("");
const [statusChanges, setStatusChanges] = useState<StatusChange[]>([]);
const [order, setOrder] = useState<SortDirection>("desc");
const [orderBy, setOrderBy] = useState<keyof StatusChange>("id");

const getProjectTypeData = async (projectTypeId: number) => {
try {
Expand All @@ -165,6 +182,16 @@ const ProjectEntryEditComponent: React.FC<ProjectEntryEditComponentProps> = (
}
};

const fetchStatusChanges = async () => {
try {
const id = Number(props.match.params.itemid);
const statusChanges = await getStatusChanges(id);
setStatusChanges(statusChanges);
} catch {
console.log("Could not load status changes.");
}
};

// Fetch project from URL path
useEffect(() => {
// No need to fetch data if we navigated from the project list.
Expand Down Expand Up @@ -218,6 +245,8 @@ const ProjectEntryEditComponent: React.FC<ProjectEntryEditComponentProps> = (

getPremiereVersionData();

fetchStatusChanges();

return () => {
isMounted = false;
};
Expand Down Expand Up @@ -526,6 +555,14 @@ const ProjectEntryEditComponent: React.FC<ProjectEntryEditComponentProps> = (
}
};

const sortByColumn = (property: keyof StatusChange) => (
_event: React.MouseEvent<unknown>
) => {
const isAsc = orderBy === property && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(property);
};

return (
<>
{userAllowedBoolean ? (
Expand Down Expand Up @@ -956,6 +993,64 @@ const ProjectEntryEditComponent: React.FC<ProjectEntryEditComponentProps> = (
</Grid>
</Paper>
)}
{statusChanges.length === 0 ? null : (
<Paper style={{ marginTop: 18 }}>
<Typography
variant="h4"
style={{ paddingTop: 18, marginLeft: 16 }}
>
Status Changes
</Typography>
<TableContainer>
<Table className={classes.table}>
<TableHead>
<TableRow>
{tableHeaderTitles.map((title, index) => (
<TableCell
key={title.label ? title.label : index}
sortDirection={orderBy === title.key ? order : false}
>
{title.key ? (
<TableSortLabel
active={orderBy === title.key}
direction={orderBy === title.key ? order : "asc"}
onClick={sortByColumn(title.key)}
>
{title.label}
{orderBy === title.key && (
<span className={classes.visuallyHidden}>
{order === "desc"
? "sorted descending"
: "sorted ascending"}
</span>
)}
</TableSortLabel>
) : (
title.label
)}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{sortListByOrder(statusChanges, orderBy, order).map(
({ id, projectId, time, user, status, title }) => (
<TableRow key={id}>
<TableCell>{user}</TableCell>
<TableCell>
<span className="datetime">
{moment(time).format("DD/MM/YYYY HH:mm")}
</span>
</TableCell>
<TableCell>{status}</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
</TableContainer>
</Paper>
)}
<Dialog
open={errorDialog}
onClose={closeDialog}
Expand Down
21 changes: 21 additions & 0 deletions frontend/app/ProjectEntryList/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,3 +652,24 @@ export const recordStatusChange = async (
throw error;
}
};

export const getStatusChanges = async (id: number): Promise<StatusChange[]> => {
try {
const {
status,
data: { result },
} = await Axios.get<PlutoApiResponse<StatusChange[]>>(
`${API_PROJECTS}/${id}/statusChanges`
);

if (status === 200) {
console.log(result);
return result;
}

throw new Error(`Could not retrieve status changes. ${status}`);
} catch (error) {
console.error(error);
throw error;
}
};
4 changes: 2 additions & 2 deletions frontend/app/StatusChanges/StatusChanges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const StatusChanges: React.FC<RouteComponentProps> = (props) => {
const [orderBy, setOrderBy] = useState<keyof StatusChange>("id");

useEffect(() => {
const fetchDeletionRecordsOnPage = async () => {
const fetchStatusChangesOnPage = async () => {
const statusChanges = await getStatusChangesOnPage({ page, pageSize });
setStatusChanges(statusChanges);
};
Expand All @@ -57,7 +57,7 @@ const StatusChanges: React.FC<RouteComponentProps> = (props) => {

fetchWhoIsLoggedIn();

fetchDeletionRecordsOnPage();
fetchStatusChangesOnPage();
}, [page, pageSize]);

const handleChangePage = (
Expand Down
Loading