@saltcorn/server 0.9.0-beta.1 → 0.9.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.js +58 -6
- package/auth/routes.js +16 -20
- package/errors.js +15 -4
- package/help/Actions.tmd +9 -0
- package/help/Extra state formula.tmd +62 -0
- package/help/Field views.tmd +22 -0
- package/help/JavaScript action code.tmd +161 -0
- package/help/Table formula constraint.tmd +2 -0
- package/help/View patterns.tmd +35 -0
- package/help/Where formula.tmd +30 -0
- package/help/index.js +11 -5
- package/locales/da.json +709 -709
- package/locales/de.json +1049 -1049
- package/locales/en.json +18 -2
- package/locales/pl.json +1155 -1155
- package/locales/ru.json +1101 -1101
- package/locales/si.json +1196 -1196
- package/locales/uk.json +1168 -1168
- package/locales/zh.json +886 -886
- package/package.json +10 -9
- package/public/saltcorn-builder.css +4 -0
- package/public/saltcorn-common.js +69 -9
- package/public/saltcorn.js +29 -3
- package/routes/actions.js +17 -7
- package/routes/admin.js +19 -4
- package/routes/fields.js +15 -3
- package/routes/menu.js +1 -1
- package/routes/packs.js +134 -9
- package/routes/page.js +1 -0
- package/routes/pageedit.js +9 -2
- package/routes/plugins.js +186 -36
- package/routes/sync.js +4 -1
- package/routes/tables.js +4 -3
- package/routes/viewedit.js +21 -1
- package/tests/admin.test.js +2 -2
- package/tests/sync.test.js +140 -6
- package/tests/viewedit.test.js +244 -1
- package/wrapper.js +6 -3
package/tests/admin.test.js
CHANGED
|
@@ -568,11 +568,11 @@ describe("tags", () => {
|
|
|
568
568
|
.post("/tag")
|
|
569
569
|
.set("Cookie", loginCookie)
|
|
570
570
|
.send("name=MyNewTestTag")
|
|
571
|
-
.expect(toRedirect("/tag/
|
|
571
|
+
.expect(toRedirect("/tag/2?show_list=tables"));
|
|
572
572
|
});
|
|
573
573
|
|
|
574
574
|
itShouldIncludeTextForAdmin("/tag", "MyNewTestTag");
|
|
575
|
-
itShouldIncludeTextForAdmin("/tag/
|
|
575
|
+
itShouldIncludeTextForAdmin("/tag/2", "MyNewTestTag");
|
|
576
576
|
itShouldIncludeTextForAdmin("/tag-entries/add/tables/1", "Add entries");
|
|
577
577
|
itShouldIncludeTextForAdmin("/tag-entries/add/pages/1", "Add entries");
|
|
578
578
|
itShouldIncludeTextForAdmin("/tag-entries/add/views/1", "Add entries");
|
package/tests/sync.test.js
CHANGED
|
@@ -5,11 +5,15 @@ const {
|
|
|
5
5
|
getAdminLoginCookie,
|
|
6
6
|
resetToFixtures,
|
|
7
7
|
respondJsonWith,
|
|
8
|
+
toRedirect,
|
|
9
|
+
toInclude,
|
|
10
|
+
toSucceed,
|
|
8
11
|
} = require("../auth/testhelp");
|
|
9
12
|
const db = require("@saltcorn/data/db");
|
|
10
13
|
const { sleep } = require("@saltcorn/data/tests/mocks");
|
|
11
14
|
|
|
12
15
|
const Table = require("@saltcorn/data/models/table");
|
|
16
|
+
const TableConstraint = require("@saltcorn/data/models/table_constraints");
|
|
13
17
|
const Field = require("@saltcorn/data/models/field");
|
|
14
18
|
const User = require("@saltcorn/data/models/user");
|
|
15
19
|
|
|
@@ -181,6 +185,52 @@ describe("load remote insert/updates", () => {
|
|
|
181
185
|
}
|
|
182
186
|
});
|
|
183
187
|
|
|
188
|
+
it("sync table with capitals", async () => {
|
|
189
|
+
const app = await getApp({ disableCsrf: true });
|
|
190
|
+
const loginCookie = await getAdminLoginCookie();
|
|
191
|
+
// create table
|
|
192
|
+
await request(app)
|
|
193
|
+
.post("/table")
|
|
194
|
+
.set("Cookie", loginCookie)
|
|
195
|
+
.send(`name=${encodeURIComponent("Table with capitals")}`)
|
|
196
|
+
.expect(toRedirect("/table/16"));
|
|
197
|
+
// add a field
|
|
198
|
+
await request(app)
|
|
199
|
+
.post("/field/")
|
|
200
|
+
.send("stepName=Basic properties")
|
|
201
|
+
.send("name=string_field")
|
|
202
|
+
.send("label=StringField")
|
|
203
|
+
.send("type=String")
|
|
204
|
+
.send(
|
|
205
|
+
`contextEnc=${encodeURIComponent(JSON.stringify({ table_id: 16 }))}`
|
|
206
|
+
)
|
|
207
|
+
.set("Cookie", loginCookie)
|
|
208
|
+
.expect(toInclude("options"));
|
|
209
|
+
// init sync_info table
|
|
210
|
+
await request(app)
|
|
211
|
+
.post("/table")
|
|
212
|
+
.send("id=16")
|
|
213
|
+
.send("has_sync_info=on")
|
|
214
|
+
.set("Cookie", loginCookie)
|
|
215
|
+
.expect(toRedirect("/table/16"));
|
|
216
|
+
const dbTime = await db.time();
|
|
217
|
+
|
|
218
|
+
// call load changes
|
|
219
|
+
await request(app)
|
|
220
|
+
.post("/sync/load_changes")
|
|
221
|
+
.set("Cookie", loginCookie)
|
|
222
|
+
.send({
|
|
223
|
+
loadUntil: (await db.time()).valueOf(),
|
|
224
|
+
syncInfos: {
|
|
225
|
+
"Table with capitals": {
|
|
226
|
+
maxLoadedId: 0,
|
|
227
|
+
syncFrom: dbTime.valueOf(),
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
})
|
|
231
|
+
.expect(toSucceed());
|
|
232
|
+
});
|
|
233
|
+
|
|
184
234
|
it("load sync not authorized", async () => {
|
|
185
235
|
const app = await getApp({ disableCsrf: true });
|
|
186
236
|
const loginCookie = await getUserLoginCookie();
|
|
@@ -300,8 +350,9 @@ describe("Upload changes", () => {
|
|
|
300
350
|
.get(`/sync/upload_finished?dir_name=${encodeURIComponent(syncDir)}`)
|
|
301
351
|
.set("Cookie", loginCookie);
|
|
302
352
|
expect(resp.status).toBe(200);
|
|
303
|
-
const { finished, translatedIds, error } = resp._body;
|
|
304
|
-
if (finished)
|
|
353
|
+
const { finished, translatedIds, uniqueConflicts, error } = resp._body;
|
|
354
|
+
if (finished)
|
|
355
|
+
return translatedIds ? { translatedIds, uniqueConflicts } : error;
|
|
305
356
|
await sleep(1000);
|
|
306
357
|
}
|
|
307
358
|
return null;
|
|
@@ -352,7 +403,7 @@ describe("Upload changes", () => {
|
|
|
352
403
|
});
|
|
353
404
|
expect(resp.status).toBe(200);
|
|
354
405
|
const { syncDir } = resp._body;
|
|
355
|
-
const translatedIds = await getResult(app, loginCookie, syncDir);
|
|
406
|
+
const { translatedIds } = await getResult(app, loginCookie, syncDir);
|
|
356
407
|
await cleanSyncDir(app, loginCookie, syncDir);
|
|
357
408
|
expect(translatedIds).toBeDefined();
|
|
358
409
|
expect(translatedIds).toEqual({
|
|
@@ -365,6 +416,89 @@ describe("Upload changes", () => {
|
|
|
365
416
|
});
|
|
366
417
|
});
|
|
367
418
|
|
|
419
|
+
it("handles inserts with TableConstraint conflicts", async () => {
|
|
420
|
+
const books = Table.findOne({ name: "books" });
|
|
421
|
+
const oldCount = await books.countRows();
|
|
422
|
+
// unique constraint for author + pages
|
|
423
|
+
const constraint = await TableConstraint.create({
|
|
424
|
+
table: books,
|
|
425
|
+
type: "Unique",
|
|
426
|
+
configuration: {
|
|
427
|
+
fields: ["author", "pages"],
|
|
428
|
+
},
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
const app = await getApp({ disableCsrf: true });
|
|
432
|
+
const loginCookie = await getAdminLoginCookie();
|
|
433
|
+
const resp = await doUpload(app, loginCookie, new Date().valueOf(), {
|
|
434
|
+
books: {
|
|
435
|
+
inserts: [
|
|
436
|
+
{
|
|
437
|
+
author: "Herman Melville",
|
|
438
|
+
pages: 967,
|
|
439
|
+
publisher: 1,
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
author: "Leo Tolstoy",
|
|
443
|
+
pages: "728",
|
|
444
|
+
publisher: 2,
|
|
445
|
+
},
|
|
446
|
+
],
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
expect(resp.status).toBe(200);
|
|
451
|
+
const { syncDir } = resp._body;
|
|
452
|
+
const { uniqueConflicts } = await getResult(app, loginCookie, syncDir);
|
|
453
|
+
await constraint.delete();
|
|
454
|
+
await cleanSyncDir(app, loginCookie, syncDir);
|
|
455
|
+
expect(uniqueConflicts).toBeDefined();
|
|
456
|
+
expect(uniqueConflicts).toEqual({
|
|
457
|
+
books: [
|
|
458
|
+
{ id: 1, author: "Herman Melville", pages: 967, publisher: null },
|
|
459
|
+
{ id: 2, author: "Leo Tolstoy", pages: 728, publisher: 1 },
|
|
460
|
+
],
|
|
461
|
+
});
|
|
462
|
+
const newCount = await books.countRows();
|
|
463
|
+
expect(newCount).toBe(oldCount);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it("denies updates with TableConstraint conflicts", async () => {
|
|
467
|
+
const books = Table.findOne({ name: "books" });
|
|
468
|
+
const oldCount = await books.countRows();
|
|
469
|
+
// unique constraint for author + pages
|
|
470
|
+
const constraint = await TableConstraint.create({
|
|
471
|
+
table: books,
|
|
472
|
+
type: "Unique",
|
|
473
|
+
configuration: {
|
|
474
|
+
fields: ["author", "pages"],
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
const app = await getApp({ disableCsrf: true });
|
|
479
|
+
const loginCookie = await getAdminLoginCookie();
|
|
480
|
+
const resp = await doUpload(app, loginCookie, new Date().valueOf(), {
|
|
481
|
+
books: {
|
|
482
|
+
updates: [
|
|
483
|
+
{
|
|
484
|
+
id: 2,
|
|
485
|
+
author: "Herman Melville",
|
|
486
|
+
pages: 967,
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
expect(resp.status).toBe(200);
|
|
492
|
+
const { syncDir } = resp._body;
|
|
493
|
+
const error = await getResult(app, loginCookie, syncDir);
|
|
494
|
+
await constraint.delete();
|
|
495
|
+
await cleanSyncDir(app, loginCookie, syncDir);
|
|
496
|
+
expect(error).toBeDefined();
|
|
497
|
+
expect(error).toEqual({
|
|
498
|
+
message: "Duplicate value for unique field: author_pages",
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
|
|
368
502
|
it("update with translation", async () => {
|
|
369
503
|
const app = await getApp({ disableCsrf: true });
|
|
370
504
|
const loginCookie = await getAdminLoginCookie();
|
|
@@ -389,7 +523,7 @@ describe("Upload changes", () => {
|
|
|
389
523
|
});
|
|
390
524
|
expect(resp.status).toBe(200);
|
|
391
525
|
const { syncDir } = resp._body;
|
|
392
|
-
const translatedIds = await getResult(app, loginCookie, syncDir);
|
|
526
|
+
const { translatedIds } = await getResult(app, loginCookie, syncDir);
|
|
393
527
|
await cleanSyncDir(app, loginCookie, syncDir);
|
|
394
528
|
expect(translatedIds).toBeDefined();
|
|
395
529
|
expect(translatedIds).toEqual({
|
|
@@ -427,7 +561,7 @@ describe("Upload changes", () => {
|
|
|
427
561
|
});
|
|
428
562
|
expect(resp.status).toBe(200);
|
|
429
563
|
const { syncDir } = resp._body;
|
|
430
|
-
const translatedIds = await getResult(app, loginCookie, syncDir);
|
|
564
|
+
const { translatedIds } = await getResult(app, loginCookie, syncDir);
|
|
431
565
|
await cleanSyncDir(app, loginCookie, syncDir);
|
|
432
566
|
expect(translatedIds).toBeDefined();
|
|
433
567
|
const afterDelete = await books.getRows();
|
|
@@ -471,7 +605,7 @@ describe("Upload changes", () => {
|
|
|
471
605
|
});
|
|
472
606
|
expect(resp.status).toBe(200);
|
|
473
607
|
const { syncDir } = resp._body;
|
|
474
|
-
const translatedIds = await getResult(app, loginCookie, syncDir);
|
|
608
|
+
const { translatedIds } = await getResult(app, loginCookie, syncDir);
|
|
475
609
|
await cleanSyncDir(app, loginCookie, syncDir);
|
|
476
610
|
expect(translatedIds).toBeDefined();
|
|
477
611
|
const afterDelete = await books.getRows();
|
package/tests/viewedit.test.js
CHANGED
|
@@ -396,7 +396,7 @@ describe("viewedit new Show", () => {
|
|
|
396
396
|
it("delete new view", async () => {
|
|
397
397
|
const loginCookie = await getAdminLoginCookie();
|
|
398
398
|
const app = await getApp({ disableCsrf: true });
|
|
399
|
-
const id =
|
|
399
|
+
const id = View.findOne({ name: "mybook" }).id;
|
|
400
400
|
|
|
401
401
|
await request(app)
|
|
402
402
|
.post("/viewedit/delete/" + id)
|
|
@@ -404,6 +404,249 @@ describe("viewedit new Show", () => {
|
|
|
404
404
|
.expect(toRedirect("/viewedit"));
|
|
405
405
|
});
|
|
406
406
|
});
|
|
407
|
+
|
|
408
|
+
describe("viewedit new Edit", () => {
|
|
409
|
+
// create two edit views for 'books'
|
|
410
|
+
// the first has inputs for all books-fields
|
|
411
|
+
// => 'Fixed and blocked fields (step 2 / max 3)' won't show up
|
|
412
|
+
// the second has no input for 'pages'
|
|
413
|
+
// => 'Fixed and blocked fields (step 2 / max 3)' shows up
|
|
414
|
+
// and the configration gets a fixed property
|
|
415
|
+
const colsWithoutPages = [
|
|
416
|
+
{
|
|
417
|
+
type: "Field",
|
|
418
|
+
fieldview: "edit",
|
|
419
|
+
field_name: "author",
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
type: "Field",
|
|
423
|
+
fieldview: "select",
|
|
424
|
+
field_name: "publisher",
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
type: "Action",
|
|
428
|
+
rndid: "f61f38",
|
|
429
|
+
minRole: 100,
|
|
430
|
+
action_name: "Save",
|
|
431
|
+
action_style: "btn-primary",
|
|
432
|
+
},
|
|
433
|
+
];
|
|
434
|
+
const colsWithPages = [
|
|
435
|
+
{
|
|
436
|
+
type: "Field",
|
|
437
|
+
fieldview: "edit",
|
|
438
|
+
field_name: "pages",
|
|
439
|
+
},
|
|
440
|
+
...colsWithoutPages,
|
|
441
|
+
];
|
|
442
|
+
|
|
443
|
+
const layoutWithoutPages = {
|
|
444
|
+
above: [
|
|
445
|
+
{
|
|
446
|
+
type: "field",
|
|
447
|
+
fieldview: "edit",
|
|
448
|
+
field_name: "author",
|
|
449
|
+
},
|
|
450
|
+
|
|
451
|
+
{
|
|
452
|
+
type: "field",
|
|
453
|
+
fieldview: "select",
|
|
454
|
+
field_name: "publisher",
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
type: "action",
|
|
458
|
+
rndid: "f61f38",
|
|
459
|
+
minRole: 100,
|
|
460
|
+
action_name: "Save",
|
|
461
|
+
action_style: "btn-primary",
|
|
462
|
+
},
|
|
463
|
+
],
|
|
464
|
+
};
|
|
465
|
+
const layoutWithPages = {
|
|
466
|
+
above: [
|
|
467
|
+
{
|
|
468
|
+
type: "field",
|
|
469
|
+
fieldview: "edit",
|
|
470
|
+
field_name: "pages",
|
|
471
|
+
},
|
|
472
|
+
...layoutWithoutPages.above,
|
|
473
|
+
],
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
it("submits new view", async () => {
|
|
477
|
+
const loginCookie = await getAdminLoginCookie();
|
|
478
|
+
const app = await getApp({ disableCsrf: true });
|
|
479
|
+
// edit_mybook
|
|
480
|
+
await request(app)
|
|
481
|
+
.post("/viewedit/save")
|
|
482
|
+
.send("viewtemplate=Edit")
|
|
483
|
+
.send("table_name=books")
|
|
484
|
+
.send("name=edit_mybook")
|
|
485
|
+
.send("min_role=100")
|
|
486
|
+
.set("Cookie", loginCookie)
|
|
487
|
+
.expect(toRedirect("/viewedit/config/edit_mybook"));
|
|
488
|
+
// edit_mybook_without_pages
|
|
489
|
+
await request(app)
|
|
490
|
+
.post("/viewedit/save")
|
|
491
|
+
.send("viewtemplate=Edit")
|
|
492
|
+
.send("table_name=books")
|
|
493
|
+
.send("name=edit_mybook_without_pages")
|
|
494
|
+
.send("min_role=100")
|
|
495
|
+
.set("Cookie", loginCookie)
|
|
496
|
+
.expect(toRedirect("/viewedit/config/edit_mybook_without_pages"));
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it("saves new view layout", async () => {
|
|
500
|
+
const loginCookie = await getAdminLoginCookie();
|
|
501
|
+
const table = Table.findOne({ name: "books" });
|
|
502
|
+
const app = await getApp({ disableCsrf: true });
|
|
503
|
+
// edit_mybook
|
|
504
|
+
await request(app)
|
|
505
|
+
.post("/viewedit/config/edit_mybook")
|
|
506
|
+
.send(
|
|
507
|
+
"contextEnc=" +
|
|
508
|
+
encodeURIComponent(
|
|
509
|
+
JSON.stringify({
|
|
510
|
+
table_id: table.id,
|
|
511
|
+
viewname: "edit_mybook",
|
|
512
|
+
})
|
|
513
|
+
)
|
|
514
|
+
)
|
|
515
|
+
.send("stepName=Layout")
|
|
516
|
+
.send("columns=" + encodeURIComponent(JSON.stringify(colsWithPages)))
|
|
517
|
+
.send("layout=" + encodeURIComponent(JSON.stringify(layoutWithPages)))
|
|
518
|
+
.set("Cookie", loginCookie)
|
|
519
|
+
.expect(toInclude("Edit options (step 3 / 3)"));
|
|
520
|
+
// edit_mybook_without_pages
|
|
521
|
+
await request(app)
|
|
522
|
+
.post("/viewedit/config/edit_mybook_without_pages")
|
|
523
|
+
.send(
|
|
524
|
+
"contextEnc=" +
|
|
525
|
+
encodeURIComponent(
|
|
526
|
+
JSON.stringify({
|
|
527
|
+
table_id: table.id,
|
|
528
|
+
viewname: "edit_mybook_without_pages",
|
|
529
|
+
})
|
|
530
|
+
)
|
|
531
|
+
)
|
|
532
|
+
.send("stepName=Layout")
|
|
533
|
+
.send("columns=" + encodeURIComponent(JSON.stringify(colsWithoutPages)))
|
|
534
|
+
.send("layout=" + encodeURIComponent(JSON.stringify(layoutWithoutPages)))
|
|
535
|
+
.set("Cookie", loginCookie)
|
|
536
|
+
.expect(toInclude("Fixed and blocked fields (step 2 / max 3)"));
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
it("saves new view fixed fields", async () => {
|
|
540
|
+
const loginCookie = await getAdminLoginCookie();
|
|
541
|
+
const table = Table.findOne({ name: "books" });
|
|
542
|
+
const app = await getApp({ disableCsrf: true });
|
|
543
|
+
// only edit_mybook_without_pages
|
|
544
|
+
await request(app)
|
|
545
|
+
.post("/viewedit/config/edit_mybook_without_pages")
|
|
546
|
+
.send(
|
|
547
|
+
"contextEnc=" +
|
|
548
|
+
encodeURIComponent(
|
|
549
|
+
JSON.stringify({
|
|
550
|
+
table_id: table.id,
|
|
551
|
+
viewname: "edit_mybook_without_pages",
|
|
552
|
+
layout: layoutWithoutPages,
|
|
553
|
+
columns: colsWithoutPages,
|
|
554
|
+
})
|
|
555
|
+
)
|
|
556
|
+
)
|
|
557
|
+
.send("stepName=Fixed+and+blocked+fields")
|
|
558
|
+
.send("pages=2")
|
|
559
|
+
.set("Cookie", loginCookie)
|
|
560
|
+
.expect(toInclude("Edit options (step 3 / 3)"));
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
it("saves view when done", async () => {
|
|
564
|
+
const loginCookie = await getAdminLoginCookie();
|
|
565
|
+
const table = Table.findOne({ name: "books" });
|
|
566
|
+
const app = await getApp({ disableCsrf: true });
|
|
567
|
+
// edit_mybook
|
|
568
|
+
await request(app)
|
|
569
|
+
.post("/viewedit/config/edit_mybook")
|
|
570
|
+
.send(
|
|
571
|
+
"contextEnc=" +
|
|
572
|
+
encodeURIComponent(
|
|
573
|
+
JSON.stringify({
|
|
574
|
+
table_id: table.id,
|
|
575
|
+
viewname: "edit_mybook",
|
|
576
|
+
layout: layoutWithPages,
|
|
577
|
+
columns: colsWithPages,
|
|
578
|
+
})
|
|
579
|
+
)
|
|
580
|
+
)
|
|
581
|
+
.send("stepName=Edit+options")
|
|
582
|
+
.send("destination_type=View")
|
|
583
|
+
.send("view_when_done=authorlist")
|
|
584
|
+
.send("auto_save=on")
|
|
585
|
+
.send("split_paste=on")
|
|
586
|
+
.set("Cookie", loginCookie)
|
|
587
|
+
.expect(toRedirect("/viewedit"));
|
|
588
|
+
const viewWithPages = View.findOne({ name: "edit_mybook" });
|
|
589
|
+
expect(viewWithPages.configuration.layout).toEqual(layoutWithPages);
|
|
590
|
+
expect(viewWithPages.configuration.columns).toEqual(colsWithPages);
|
|
591
|
+
// edit_mybook_without_pages
|
|
592
|
+
await request(app)
|
|
593
|
+
.post("/viewedit/config/edit_mybook_without_pages")
|
|
594
|
+
.send(
|
|
595
|
+
"contextEnc=" +
|
|
596
|
+
encodeURIComponent(
|
|
597
|
+
JSON.stringify({
|
|
598
|
+
table_id: table.id,
|
|
599
|
+
viewname: "edit_mybook_without_pages",
|
|
600
|
+
layout: layoutWithoutPages,
|
|
601
|
+
columns: colsWithoutPages,
|
|
602
|
+
fixed: {
|
|
603
|
+
pages: 22,
|
|
604
|
+
_block_pages: false,
|
|
605
|
+
},
|
|
606
|
+
})
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
.send("stepName=Edit+options")
|
|
610
|
+
.send("destination_type=View")
|
|
611
|
+
.send("view_when_done=authorlist")
|
|
612
|
+
.send("auto_save=on")
|
|
613
|
+
.send("split_paste=on")
|
|
614
|
+
.set("Cookie", loginCookie)
|
|
615
|
+
.expect(toRedirect("/viewedit"));
|
|
616
|
+
|
|
617
|
+
const viewWithoutPages = View.findOne({
|
|
618
|
+
name: "edit_mybook_without_pages",
|
|
619
|
+
});
|
|
620
|
+
expect(viewWithoutPages.configuration.fixed).toEqual({
|
|
621
|
+
pages: 22,
|
|
622
|
+
_block_pages: false,
|
|
623
|
+
});
|
|
624
|
+
expect(viewWithoutPages.configuration.layout).toEqual(layoutWithoutPages);
|
|
625
|
+
expect(viewWithoutPages.configuration.columns).toEqual(colsWithoutPages);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it("deletes new view", async () => {
|
|
629
|
+
const loginCookie = await getAdminLoginCookie();
|
|
630
|
+
const app = await getApp({ disableCsrf: true });
|
|
631
|
+
const idA = View.findOne({ name: "edit_mybook" }).id;
|
|
632
|
+
// edit_mybook
|
|
633
|
+
await request(app)
|
|
634
|
+
.post("/viewedit/delete/" + idA)
|
|
635
|
+
.set("Cookie", loginCookie)
|
|
636
|
+
.expect(toRedirect("/viewedit"));
|
|
637
|
+
// edit_mybook_without_pages
|
|
638
|
+
const idB = View.findOne({ name: "edit_mybook_without_pages" }).id;
|
|
639
|
+
await request(app)
|
|
640
|
+
.post("/viewedit/delete/" + idB)
|
|
641
|
+
.set("Cookie", loginCookie)
|
|
642
|
+
.expect(toRedirect("/viewedit"));
|
|
643
|
+
});
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
describe("viewedit new Edit with fixed fields", () => {
|
|
647
|
+
it("submit new view", async () => {});
|
|
648
|
+
});
|
|
649
|
+
|
|
407
650
|
describe("Library", () => {
|
|
408
651
|
it("should save new from builder", async () => {
|
|
409
652
|
const loginCookie = await getAdminLoginCookie();
|
package/wrapper.js
CHANGED
|
@@ -187,7 +187,9 @@ const get_headers = (req, version_tag, description, extras = []) => {
|
|
|
187
187
|
: [];
|
|
188
188
|
const stdHeaders = [
|
|
189
189
|
{
|
|
190
|
-
headerTag: `<script>var
|
|
190
|
+
headerTag: `<script>var _sc_loglevel = ${
|
|
191
|
+
state.logLevel
|
|
192
|
+
}, _sc_globalCsrf = "${req.csrfToken()}", _sc_version_tag = "${version_tag}";</script>`,
|
|
191
193
|
},
|
|
192
194
|
{ css: `/static_assets/${version_tag}/saltcorn.css` },
|
|
193
195
|
{ script: `/static_assets/${version_tag}/saltcorn-common.js` },
|
|
@@ -309,6 +311,7 @@ module.exports = (version_tag) =>
|
|
|
309
311
|
const alerts = getFlashes(req);
|
|
310
312
|
const state = getState();
|
|
311
313
|
const layout = state.getLayout(req.user);
|
|
314
|
+
const no_menu = opts.no_menu;
|
|
312
315
|
|
|
313
316
|
if (req.xhr) {
|
|
314
317
|
const renderToHtml = layout.renderBody
|
|
@@ -335,8 +338,8 @@ module.exports = (version_tag) =>
|
|
|
335
338
|
res.send(
|
|
336
339
|
layout.wrap({
|
|
337
340
|
title,
|
|
338
|
-
brand: get_brand(state),
|
|
339
|
-
menu: get_menu(req),
|
|
341
|
+
brand: no_menu ? undefined : get_brand(state),
|
|
342
|
+
menu: no_menu ? undefined : get_menu(req),
|
|
340
343
|
currentUrl,
|
|
341
344
|
originalUrl: req.originalUrl,
|
|
342
345
|
|