Skip to content

Commit 16fbbda

Browse files
authored
Merge pull request #142 from cotype/feature/setPosition
fix(server+client): Fix Set Position and Test Position
2 parents 14df3d4 + 4cb7939 commit 16fbbda

File tree

4 files changed

+89
-47
lines changed

4 files changed

+89
-47
lines changed

client/src/Edit/PositionModal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ class PositionModal extends Component<Props, State> {
124124
if (this.props.model.order !== "asc") {
125125
[prev, post] = [post, prev];
126126
}
127-
this.props.onSave(middleString(prev, post));
127+
128+
this.props.onSave(middleString(prev, prev !== post ? post : undefined));
128129
};
129130
render() {
130131
let { items } = this.state;

src/model/getPositionFields.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,20 @@ const getPositionFields = (model: Cotype.Model): string[] => {
1212
};
1313

1414
export default getPositionFields;
15+
16+
export const getPositionFieldsWithValue = (
17+
data: any,
18+
model: Cotype.Model
19+
): Array<{ fieldPath: string; value: string }> => {
20+
const fields: Array<{ fieldPath: string; value: string }> = [];
21+
visit(data, model, {
22+
position(s: string, f, d, stringPath) {
23+
if (stringPath)
24+
fields.push({
25+
value: s,
26+
fieldPath: stringPath
27+
});
28+
}
29+
});
30+
return fields;
31+
};

src/model/setPosition.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@ export default function setPosition(
1313
model: Cotype.Model,
1414
lastPos: string = firstMudderCharacter,
1515
nextPos?: string,
16-
forcePositionSet?: boolean
16+
forcePositionSet?: boolean,
17+
stringPath?: string
1718
) {
1819
visit(obj, model, {
19-
position(pos: string) {
20-
if (!pos || forcePositionSet) {
21-
return middleString(
22-
lastPos,
23-
nextPos === lastPos ? nextPos + "z" : nextPos
24-
);
20+
position(pos: string, f, d, path: string) {
21+
if ((stringPath && stringPath === path) || !stringPath) {
22+
if (!pos || forcePositionSet) {
23+
return middleString(
24+
lastPos,
25+
nextPos === lastPos ? nextPos + "z" : nextPos
26+
);
27+
}
2528
}
2629
}
2730
});

src/persistence/adapter/knex/KnexContent.ts

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ import UniqueFieldError, {
1313
} from "../../errors/UniqueFieldError";
1414
import setPosition from "../../../model/setPosition";
1515
import getAlwaysUniqueFields from "../../../model/getAlwaysUniqueFields";
16-
import getPositionFields from "../../../model/getPositionFields";
16+
import { getPositionFieldsWithValue } from "../../../model/getPositionFields";
1717
import getInverseReferenceFields from "../../../model/getInverseReferenceFields";
1818
import log from "../../../log";
1919
import visitModel from "../../../model/visitModel";
2020
import { Migration } from "../../ContentPersistence";
2121
import { Model } from "../../../../typings";
22+
import visit from "../../../model/visit";
2223

2324
const ops: any = {
2425
eq: "=",
@@ -199,47 +200,67 @@ export default class KnexContent implements ContentAdapter {
199200
data: any,
200201
id: string
201202
): Promise<any> {
202-
const positionFields = getPositionFields(model);
203-
if (positionFields) {
203+
const positionFields = getPositionFieldsWithValue(data, model);
204+
if (positionFields.length > 0) {
204205
await Promise.all(
205-
positionFields.map(async f => {
206-
const criteria: any = {};
207-
208-
const value = (f.split(".").reduce((obj, key) => {
209-
if (obj && obj[key] !== "undefined") {
210-
return obj[key];
211-
} else {
212-
obj[key] = "";
213-
return obj[key];
214-
}
215-
}, data) as unknown) as string;
216-
if (value !== undefined) {
217-
criteria[`data.${f}`] = { gte: value };
218-
}
219-
220-
const opts = { offset: 0, limit: 3, orderBy: f, order: "asc" };
221-
const items = await this.list(model, models, opts, criteria);
222-
items.items = items.items.filter(item => item.id === id);
223-
let nextPos;
206+
positionFields.map(async ({ fieldPath, value }) => {
207+
const criteria: any = value
208+
? {
209+
[`data.${fieldPath}`]: { gte: value }
210+
}
211+
: {};
212+
const opts = {
213+
offset: 0,
214+
limit: 3,
215+
orderBy: fieldPath,
216+
order: value ? "asc" : "desc"
217+
};
218+
const items = await this.list(model, models, opts, criteria, {
219+
ignoreSchedule: true
220+
});
224221
if (items.items[0]) {
225-
nextPos = (f
226-
.split(".")
227-
.reduce(
228-
(obj: any, key) =>
229-
obj && obj[key] !== "undefined" ? obj[key] : undefined,
230-
items.items[0].data
231-
) as unknown) as string;
232-
if (value === nextPos && items.items[1]) {
233-
nextPos = (f
234-
.split(".")
235-
.reduce(
236-
(obj: any, key) =>
237-
obj && obj[key] !== "undefined" ? obj[key] : undefined,
238-
items.items[1].data
239-
) as unknown) as string;
240-
}
222+
visit(items.items[0].data, model, {
223+
position(s: string, f, d, stringPath) {
224+
if (stringPath === fieldPath) {
225+
if (!value) {
226+
// No Position Value passed, use end of list
227+
data = setPosition(data, model, s, "z", true, fieldPath);
228+
} else if (
229+
s === value &&
230+
String(items.items[0].id) !== String(id) // Value exists, and is not same document
231+
) {
232+
if (items.items[1]) {
233+
// get next one and middle it
234+
visit(items.items[0].data, model, {
235+
position(nextPosition: string, g, h, nextStringPath) {
236+
if (nextStringPath === fieldPath) {
237+
data = setPosition(
238+
data,
239+
model,
240+
value,
241+
nextPosition,
242+
true,
243+
fieldPath
244+
);
245+
}
246+
}
247+
});
248+
} else {
249+
// No next one, just middle to end
250+
data = setPosition(
251+
data,
252+
model,
253+
value,
254+
"z",
255+
true,
256+
fieldPath
257+
);
258+
}
259+
}
260+
}
261+
}
262+
});
241263
}
242-
data = setPosition(data, model, value, nextPos, true);
243264
})
244265
);
245266
}

0 commit comments

Comments
 (0)