Skip to content

Commit

Permalink
adapt code to work with some server side json property renamings, dis…
Browse files Browse the repository at this point in the history
…tinguish between tracingId and annotationId, fix unit tests (#1759)
  • Loading branch information
daniel-wer committed Aug 10, 2017
1 parent 6c83a90 commit 59114bc
Show file tree
Hide file tree
Showing 27 changed files with 368 additions and 515 deletions.
8 changes: 4 additions & 4 deletions app/assets/javascripts/oxalis/api/api_latest.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ class TracingApi {
*/
async finishAndGetNextTask() {
const state = Store.getState();
const { tracingType, tracingId } = state.tracing;
const { tracingType, annotationId } = state.tracing;
const task = state.task;
const finishUrl = `/annotations/${tracingType}/${tracingId}/finish`;
const finishUrl = `/annotations/${tracingType}/${annotationId}/finish`;
const requestTaskUrl = "/user/tasks/request";

await Model.save();
Expand Down Expand Up @@ -277,12 +277,12 @@ class TracingApi {
*/
async restart(
newTracingType: SkeletonTracingTypeTracingType,
newTracingId: string,
newAnnotationId: string,
newControlMode: ControlModeType,
) {
Store.dispatch(restartSagaAction());
UrlManager.reset();
await Model.fetch(newTracingType, newTracingId, newControlMode, false);
await Model.fetch(newTracingType, newAnnotationId, newControlMode, false);
Store.dispatch(wkReadyAction());
UrlManager.updateUnthrottled(true);
}
Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/oxalis/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import type { OxalisState, SkeletonTracingTypeTracingType } from "oxalis/store";
class Controller extends React.PureComponent {
props: {
initialTracingType: SkeletonTracingTypeTracingType,
initialTracingId: string,
initialAnnotationId: string,
initialControlmode: ControlModeType,
// Delivered by connect()
viewMode: ModeType,
Expand Down Expand Up @@ -84,7 +84,7 @@ class Controller extends React.PureComponent {

Model.fetch(
this.props.initialTracingType,
this.props.initialTracingId,
this.props.initialAnnotationId,
this.props.initialControlmode,
true,
)
Expand Down
12 changes: 8 additions & 4 deletions app/assets/javascripts/oxalis/controller/url_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,24 +126,28 @@ class UrlManager {
}

getActiveNode(tracing).map(node => state.push(node.id));
const newBaseUrl = updateTypeAndId(this.baseUrl, tracing.tracingType, tracing.tracingId);
const newBaseUrl = updateTypeAndId(this.baseUrl, tracing.tracingType, tracing.annotationId);
return `${newBaseUrl}#${state.join(",")}`;
}
}

export function updateTypeAndId(baseUrl: string, tracingType: string, tracingId: string): string {
export function updateTypeAndId(
baseUrl: string,
tracingType: string,
annotationId: string,
): string {
// Update the baseUrl with a potentially new tracing id and or tracing type.
// There are two possible routes (annotations or datasets) which will be handled
// both here. Chaining the replace function is possible, since they are mutually
// exclusive and thus can't apply both simultaneously.
return baseUrl
.replace(
/^(.*\/annotations)\/(.*?)\/([^/]*)(\/?.*)$/,
(all, base, type, id, rest) => `${base}/${tracingType}/${tracingId}${rest}`,
(all, base, type, id, rest) => `${base}/${tracingType}/${annotationId}${rest}`,
)
.replace(
/^(.*\/datasets)\/([^/]*)(\/.*)$/,
(all, base, id, rest) => `${base}/${tracingId}${rest}`,
(all, base, id, rest) => `${base}/${annotationId}${rest}`,
);
}

Expand Down
22 changes: 12 additions & 10 deletions app/assets/javascripts/oxalis/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import update from "immutability-helper";
import UrlManager from "oxalis/controller/url_manager";

type ServerSkeletonTracingTreeType = {
id: number,
treeId: number,
color: ?Vector3,
name: string,
timestamp: number,
Expand All @@ -65,11 +65,12 @@ type ServerSkeletonTracingTreeType = {
};

export type ServerSkeletonTracingType = {
activeNode?: number,
activeNodeId?: number,
boundingBox?: BoundingBoxObjectType,
customLayers: Array<Object>,
customLayers?: Array<Object>,
editPosition: Vector3,
editRotation: Vector3,
id: string,
trees: Array<ServerSkeletonTracingTreeType>,
version: number,
zoomLevel: number,
Expand All @@ -78,9 +79,10 @@ export type ServerSkeletonTracingType = {
export type ServerVolumeTracingType = {
activeCell?: number,
boundingBox?: BoundingBoxObjectType,
customLayers: Array<Object>,
customLayers?: Array<Object>,
editPosition: Vector3,
editRotation: Vector3,
id: string,
nextCell: ?number,
version: number,
zoomLevel: number,
Expand Down Expand Up @@ -133,7 +135,7 @@ export class OxalisModel {

async fetch(
tracingType: SkeletonTracingTypeTracingType,
tracingId: string,
annotationId: string,
controlMode: ControlModeType,
initialFetch: boolean,
) {
Expand All @@ -144,9 +146,9 @@ export class OxalisModel {
// Include /readOnly part whenever it is in the pathname
const isReadOnly = window.location.pathname.endsWith("/readOnly");
const readOnlyPart = isReadOnly ? "readOnly/" : "";
infoUrl = `/annotations/${tracingType}/${tracingId}/${readOnlyPart}info`;
infoUrl = `/annotations/${tracingType}/${annotationId}/${readOnlyPart}info`;
} else {
infoUrl = `/annotations/${tracingType}/${tracingId}/info`;
infoUrl = `/annotations/${tracingType}/${annotationId}/info`;
}

const annotation: ServerAnnotationType = await Request.receiveJSON(infoUrl);
Expand All @@ -160,7 +162,7 @@ export class OxalisModel {
} else if (!dataset) {
error = "Selected dataset doesn't exist";
} else if (!dataset.dataSource.dataLayers) {
const datasetName = dataset.dataSource.id.name;
const datasetName = annotation.dataSetName;
if (datasetName) {
error = `Please, double check if you have the dataset '${datasetName}' imported.`;
} else {
Expand Down Expand Up @@ -238,7 +240,7 @@ export class OxalisModel {
const { allowedModes, preferredMode } = this.determineAllowedModes(annotation.settings);
_.extend(annotation.settings, { allowedModes, preferredMode });

const isVolume = annotation.settings.allowedModes.includes("volume");
const isVolume = annotation.content.typ === "volume";
const controlMode = Store.getState().temporaryConfiguration.controlMode;
if (controlMode === ControlModeEnum.TRACE) {
if (isVolume) {
Expand All @@ -259,7 +261,7 @@ export class OxalisModel {

if (initialFetch) {
// TODO remove default value
Store.dispatch(setZoomStepAction(tracing.zoomLevel || 2));
Store.dispatch(setZoomStepAction(tracing.zoomLevel != null ? tracing.zoomLevel : 2));
}

// Initialize 'flight', 'oblique' or 'orthogonal'/'volume' mode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* save_actions.js
* @flow
*/
import Date from "libs/date";
import type { UpdateAction } from "oxalis/model/sagas/update_actions";

type PushSaveQueueActionType = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ function ReadOnlyTracingReducer(state: OxalisState, action: ActionType): OxalisS
);

const readonlyTracing: ReadOnlyTracingType = {
annotationId: action.annotation.id,
type: "readonly",
restrictions,
name: action.annotation.name,
tracingType: "View",
tracingId: action.annotation.id,
tracingId: action.tracing.id,
version: action.tracing.version,
boundingBox: convertBoundingBox(action.tracing.boundingBox),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@ function SkeletonTracingReducer(state: OxalisState, action: ActionType): OxalisS
const trees = _.keyBy(
action.tracing.trees.map(tree =>
update(tree, {
treeId: { $set: tree.id },
nodes: { $set: _.keyBy(tree.nodes, "id") },
color: { $set: tree.color || ColorGenerator.distinctColorForId(tree.id) },
color: { $set: tree.color || ColorGenerator.distinctColorForId(tree.treeId) },
isVisible: { $set: true },
}),
),
"id",
"treeId",
);

const activeNodeIdMaybe = Maybe.fromNullable(action.tracing.activeNode);
const activeNodeIdMaybe = Maybe.fromNullable(action.tracing.activeNodeId);
let cachedMaxNodeId = _.max(_.flatMap(trees, __ => _.map(__.nodes, node => node.id)));
cachedMaxNodeId = cachedMaxNodeId != null ? cachedMaxNodeId : Constants.MIN_NODE_ID - 1;

Expand Down Expand Up @@ -87,6 +86,7 @@ function SkeletonTracingReducer(state: OxalisState, action: ActionType): OxalisS
const activeTreeId = Utils.toNullable(activeTreeIdMaybe);

const skeletonTracing: SkeletonTracingType = {
annotationId: action.annotation.id,
type: "skeleton",
activeNodeId,
cachedMaxNodeId,
Expand All @@ -95,7 +95,7 @@ function SkeletonTracingReducer(state: OxalisState, action: ActionType): OxalisS
trees,
name: action.annotation.name,
tracingType: action.annotation.typ,
tracingId: action.annotation.id,
tracingId: action.tracing.id,
version: action.tracing.version,
boundingBox: convertBoundingBox(action.tracing.boundingBox),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function VolumeTracingReducer(state: OxalisState, action: VolumeTracingActionTyp
}

const volumeTracing: VolumeTracingType = {
annotationId: action.annotation.id,
type: "volume",
activeCellId: 0,
lastCentroid: null,
Expand All @@ -44,7 +45,7 @@ function VolumeTracingReducer(state: OxalisState, action: VolumeTracingActionTyp
volumeTraceOrMoveMode: Constants.VOLUME_MODE_MOVE,
name: action.annotation.name,
tracingType: action.annotation.typ,
tracingId: action.annotation.id,
tracingId: action.tracing.id,
version: action.tracing.version,
boundingBox: convertBoundingBox(action.tracing.boundingBox),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Request from "libs/request";

export function* pushTracingNameAsync(): Generator<*, *, *> {
const tracing = yield select(state => state.tracing);
const url = `/annotations/${tracing.tracingType}/${tracing.tracingId}/name`;
const url = `/annotations/${tracing.tracingType}/${tracing.annotationId}/name`;
yield [
call(Request.sendJSONReceiveJSON, url, {
data: { name: tracing.name },
Expand Down
26 changes: 16 additions & 10 deletions app/assets/javascripts/oxalis/model/sagas/save_saga.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,19 @@ export function* pushAnnotationAsync(): Generator<*, *, *> {
export function* sendRequestToServer(timestamp: number = Date.now()): Generator<*, *, *> {
const batch = yield select(state => state.save.queue);
let compactBatch = compactUpdateActions(batch);
const { version, tracingType, tracingId } = yield select(state => state.tracing);
const { version, type, tracingId } = yield select(state => state.tracing);
const dataStoreUrl = yield select(state => state.dataset.dataStore.url);
compactBatch = addVersionNumbers(compactBatch, version);
try {
yield call(Request.sendJSONReceiveJSON, `/annotations/${tracingType}/${tracingId}`, {
method: "PUT",
headers: { "X-Date": timestamp },
data: compactBatch,
});
yield call(
Request.sendJSONReceiveJSON,
`${dataStoreUrl}/data/tracings/${type}/${tracingId}/update`,
{
method: "POST",
headers: { "X-Date": timestamp },
data: compactBatch,
},
);
yield put(setVersionNumberAction(version + compactBatch.length));
yield put(setLastSaveTimestampAction());
yield put(shiftSaveQueueAction(batch.length));
Expand Down Expand Up @@ -227,13 +232,14 @@ function compactDeletedTrees(updateActions: Array<UpdateAction>) {
const deletedTreeIds = updateActions
.filter(ua => ua.name === "deleteTree")
.map(ua => (ua.name === "deleteTree" ? ua.value.id : -1));
_.remove(
return _.filter(
updateActions,
ua =>
(ua.name === "deleteNode" || ua.name === "deleteEdge") &&
deletedTreeIds.includes(ua.value.treeId),
!(
(ua.name === "deleteNode" || ua.name === "deleteEdge") &&
deletedTreeIds.includes(ua.value.treeId)
),
);
return updateActions;
}

export function compactUpdateActions(
Expand Down
7 changes: 6 additions & 1 deletion app/assets/javascripts/oxalis/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export type SkeletonTracingTypeTracingType = $Keys<typeof SkeletonTracingTypeTra
export type VolumeTracingTypeTracingType = SkeletonTracingTypeTracingType;

export type SkeletonTracingType = {
+annotationId: string,
+type: "skeleton",
+trees: TreeMapType,
+name: string,
Expand All @@ -174,6 +175,7 @@ export type SkeletonTracingType = {
};

export type VolumeTracingType = {
+annotationId: string,
+type: "volume",
+name: string,
+version: number,
Expand All @@ -190,6 +192,7 @@ export type VolumeTracingType = {
};

export type ReadOnlyTracingType = {
+annotationId: string,
+type: "readonly",
+name: string,
+version: number,
Expand Down Expand Up @@ -273,7 +276,7 @@ export type SaveQueueEntryType = {
version: number,
timestamp: number,
actions: Array<UpdateAction>,
}
};

export type SaveStateType = {
+isBusy: boolean,
Expand Down Expand Up @@ -392,6 +395,8 @@ export const defaultState: OxalisState = {
dataLayers: [],
},
tracing: {
annotationId: "",
boundingBox: null,
type: "skeleton",
trees: {},
name: "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ class DatasetActionsView extends PureComponent {
handleCopyToAccount = async (event: SyntheticInputEvent) => {
event.target.blur();
const url = `/annotations/${this.props.tracing.tracingType}/${this.props.tracing
.tracingId}/duplicate`;
.annotationId}/duplicate`;
app.router.loadURL(url);
};

handleFinish = async (event: SyntheticInputEvent) => {
event.target.blur();
const url = `/annotations/${this.props.tracing.tracingType}/${this.props.tracing
.tracingId}/finishAndRedirect`;
.annotationId}/finishAndRedirect`;
await this.handleSave();
if (confirm(messages["finish.confirm"])) {
app.router.loadURL(url);
Expand Down
Loading

0 comments on commit 59114bc

Please sign in to comment.