alchemy-chimera 1.0.2 → 1.0.5

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 1.0.5 (2022-07-06)
2
+
3
+ * Fix page title containing 'undefined'
4
+ * Update styles
5
+ * Add support for "private" document fields
6
+
7
+ ## 1.0.4 (2022-05-31)
8
+
9
+ * Add delete page
10
+
11
+ ## 1.0.3 (2022-03-16)
12
+
13
+ * Make table filtering case insensitive
14
+
1
15
  ## 1.0.2 (2022-02-20)
2
16
 
3
17
  * Improve editor styling
@@ -48,11 +48,21 @@ body {
48
48
  border-radius: 2px;
49
49
  font-weight: 500;
50
50
  cursor: pointer;
51
+ padding: 0.4rem 0.7rem;
52
+
53
+ display: inline-flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ gap: 0.2rem;
51
57
 
52
58
  &:hover {
53
59
  background-color: var(--button-bg-hover-color);
54
60
  //filter: brightness(1.05);
55
61
  }
62
+
63
+ al-ico {
64
+ margin-right: 4px;
65
+ }
56
66
  }
57
67
 
58
68
  .primary {
@@ -127,7 +137,7 @@ body {
127
137
 
128
138
  .chimera-content {
129
139
  background-color: var(--main-bg-color);
130
- flex: 1 0;
140
+ flex: 10 0;
131
141
  display: flex;
132
142
  flex-flow: column;
133
143
 
@@ -163,6 +173,8 @@ body {
163
173
  .chimera-main {
164
174
  flex: 1;
165
175
  padding: 0.5rem;
176
+ display: flex;
177
+ flex-flow: column;
166
178
 
167
179
  &[data-he-template="chimera/widgets"] {
168
180
  h1 {
@@ -254,198 +266,235 @@ alchemy-widgets-navigation {
254
266
  opacity: 0;
255
267
  }
256
268
 
257
- alchemy-table .aft-column-filters input {
258
- @extend .chimera-input-field;
259
- width: 100%;
260
- }
269
+ .chimera-wrapper {
261
270
 
262
- alchemy-form {
263
- .error-area:not(:empty) {
264
- @extend .error, .alert-box;
265
- margin-top: 0;
271
+ alchemy-table .aft-column-filters input {
272
+ @extend .chimera-input-field;
273
+ width: 100%;
266
274
  }
267
- }
268
275
 
269
- alchemy-field {
270
- border: 1px solid var(--color-box-border);
271
- background-color: white;
272
- border-radius: 4px;
273
-
274
- // In case something goes wrong:
275
- min-height: 1rem;
276
-
277
- alchemy-label {
278
- padding-left: 1rem;
279
- line-height: 3rem;
280
- font-size: 16px;
281
- font-weight: 500;
282
- color: var(--color-title);
283
- border-bottom: 1px solid var(--color-box-border);
276
+ alchemy-form {
277
+ .error-area:not(:empty) {
278
+ @extend .error, .alert-box;
279
+ margin-top: 0;
280
+ }
284
281
  }
285
282
 
286
- alchemy-field-translatable {
287
- .prefix-buttons {
288
- width: 100%;
283
+ alchemy-field:not([view-type="view_inline"]):not([view-type="inline"]) {
284
+ border: 1px solid var(--color-box-border);
285
+ background-color: white;
286
+ border-radius: 4px;
287
+
288
+ // In case something goes wrong:
289
+ min-height: 1rem;
290
+
291
+ alchemy-label {
292
+ padding-left: 1rem;
293
+ line-height: 3rem;
294
+ font-size: 16px;
295
+ font-weight: 500;
296
+ color: var(--color-title);
289
297
  border-bottom: 1px solid var(--color-box-border);
298
+ }
299
+
300
+ alchemy-field-translatable {
301
+ .prefix-buttons {
302
+ width: 100%;
303
+ border-bottom: 1px solid var(--color-box-border);
304
+ display: flex;
305
+
306
+ button {
307
+ flex: 10;
308
+ font-size: 16px;
309
+ font-weight: 500;
310
+ color: var(--button-text-color);
311
+ letter-spacing: 0px;
312
+ background: transparent;
313
+ border: none;
314
+ cursor: pointer;
315
+
316
+ height: 3rem;
317
+ display: flex;
318
+ flex-flow: column;
319
+ justify-content: center;
320
+ align-items: center;
321
+
322
+ &.active {
323
+ box-shadow: inset 0 -2px var(--color-active);
324
+ }
325
+
326
+ &:hover {
327
+ background-color: var(--button-bg-hover-color);
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ .field {
290
334
  display: flex;
335
+ padding: 1rem;
336
+ flex: 10;
291
337
 
292
- button {
293
- flex: 1;
294
- font-size: 16px;
295
- font-weight: 500;
296
- color: var(--button-text-color);
297
- letter-spacing: 0px;
298
- background: transparent;
299
- border: none;
300
- cursor: pointer;
338
+ > * {
339
+ flex: 10;
340
+ }
301
341
 
342
+ > alchemy-widget {
343
+ border: 1px solid var(--color-input-border);
344
+ padding: 0 12px;
345
+ }
346
+ }
347
+
348
+ .field {
349
+ input[type="text"],
350
+ input[type="number"],
351
+ input[type="color"],
352
+ input[type="datetime-local"],
353
+ input[type="password"] {
354
+ @extend .chimera-input-field;
302
355
  height: 3rem;
303
- display: flex;
304
- flex-flow: column;
305
- justify-content: center;
306
- align-items: center;
356
+ }
307
357
 
308
- &.active {
309
- box-shadow: inset 0 -2px var(--color-active);
310
- }
358
+ textarea {
359
+ @extend .chimera-input-field;
360
+ min-height: 5rem;
361
+ padding: 1rem;
362
+ }
311
363
 
312
- &:hover {
313
- background-color: var(--button-bg-hover-color);
314
- }
364
+ input[type="color"] {
365
+ background-color: transparent;
366
+ border: none;
367
+ padding: 0;
315
368
  }
316
369
  }
317
370
  }
318
371
 
319
- .field {
320
- display: flex;
321
- padding: 1rem;
322
- flex: 1;
323
-
324
- > * {
325
- flex: 1;
372
+ alchemy-field-array {
373
+ .add-entry {
374
+ @extend .btn;
375
+ margin: 1rem 0 0 1rem;
326
376
  }
327
377
 
328
- > alchemy-widget {
329
- border: 1px solid var(--color-input-border);
330
- padding: 0 12px;
378
+ button.remove {
379
+ @extend .btn;
380
+ @extend .danger;
381
+ min-width: 6rem;
382
+ margin: 0 1rem 1rem 0;
331
383
  }
332
- }
333
384
 
334
- .field {
335
- input[type="text"],
336
- input[type="number"],
337
- input[type="color"],
338
- input[type="datetime-local"],
339
- input[type="password"] {
340
- @extend .chimera-input-field;
341
- height: 3rem;
385
+ .entries {
386
+ margin-top: 0.5rem;
342
387
  }
343
388
 
344
- textarea {
345
- @extend .chimera-input-field;
346
- min-height: 5rem;
347
- padding: 1rem;
389
+ alchemy-field-array-entry:not(:last-of-type) {
390
+ //border-bottom: 1px solid gray;
391
+ position: relative;
392
+
393
+ &::after {
394
+ display: block;
395
+ content: " ";
396
+ background-color: lightgray;
397
+ position: absolute;
398
+ bottom: 0;
399
+ height: 1px;
400
+ left: 50%;
401
+ transform: translateX(-50%);
402
+ width: 80%;
403
+ }
348
404
  }
349
405
 
350
- input[type="color"] {
351
- background-color: transparent;
352
- border: none;
353
- padding: 0;
406
+ alchemy-field-array-entry:not(:first-of-type) {
407
+ margin-top: 1rem;
354
408
  }
355
409
  }
356
- }
357
410
 
358
- alchemy-field-array {
359
- .add-entry {
360
- @extend .btn;
361
- margin: 1rem 0 0 1rem;
362
- }
411
+ .chimera-editor-widgets {
363
412
 
364
- button.remove {
365
- @extend .btn;
366
- @extend .danger;
367
- min-width: 6rem;
368
- margin: 0 1rem 1rem 0;
369
- }
413
+ alchemy-widgets-column.toc-col {
414
+ flex: 2 2;
415
+ }
370
416
 
371
- .entries {
372
- margin-top: 0.5rem;
417
+ table-of-contents[elements-selector="alchemy-field"] {
418
+ align-self: start;
419
+ top: 2rem;
420
+ position: sticky;
421
+
422
+ ol {
423
+ list-style: none;
424
+ margin: 0 0 0 2rem;
425
+ padding: 0;
426
+
427
+ li {
428
+ a {
429
+ display: block;
430
+ line-height: 2rem;
431
+ border-bottom: 1px solid #aaa;
432
+ text-decoration: none;
433
+ opacity: 0.5;
434
+ color: #0070e4;
435
+ }
436
+ }
437
+
438
+ li a.visible {
439
+ opacity: 1;
440
+ }
441
+ }
442
+ }
373
443
  }
374
444
 
375
- alchemy-field-array-entry:not(:last-of-type) {
376
- //border-bottom: 1px solid gray;
377
- position: relative;
378
-
379
- &::after {
380
- display: block;
381
- content: " ";
382
- background-color: lightgray;
383
- position: absolute;
384
- bottom: 0;
385
- height: 1px;
386
- left: 50%;
387
- transform: translateX(-50%);
388
- width: 80%;
445
+ alchemy-field-schema {
446
+ alchemy-field {
447
+ border: none;
448
+ margin-bottom: 1rem;
389
449
  }
390
450
  }
391
451
 
392
- alchemy-field-array-entry:not(:first-of-type) {
393
- margin-top: 1rem;
452
+ .aft-actions {
453
+ a {
454
+ color: var(--button-text-color);
455
+ background-color: var(--button-bg-color);
456
+ padding: 0.5rem;
457
+ border-radius: 6px;
458
+ margin: 0.2rem;
459
+ display: inline-block;
460
+
461
+ &:hover {
462
+ background-color: var(--button-bg-hover-color);
463
+ }
464
+ }
394
465
  }
395
- }
396
466
 
397
- .chimera-editor-widgets {
467
+ .chimera-confirm-page {
468
+ flex: 1;
469
+ justify-content: center;
470
+ display: flex;
471
+ align-items: center;
472
+ flex-flow: column;
473
+ flex-direction: column;
398
474
 
399
- alchemy-widgets-column.toc-col {
400
- flex: 1 1;
475
+ .action-buttons {
476
+ display: flex;
477
+ gap: 1rem;
478
+ }
401
479
  }
402
480
 
403
- table-of-contents[elements-selector="alchemy-field"] {
404
- align-self: start;
405
- top: 2rem;
406
- position: sticky;
407
-
408
- ol {
409
- list-style: none;
410
- margin: 0 0 0 2rem;
411
- padding: 0;
412
-
413
- li {
414
- a {
415
- display: block;
416
- line-height: 2rem;
417
- border-bottom: 1px solid #aaa;
418
- text-decoration: none;
419
- opacity: 0.5;
420
- color: #0070e4;
421
- }
422
- }
423
-
424
- li a.visible {
425
- opacity: 1;
426
- }
481
+ al-file {
482
+ button {
483
+ @extend .btn;
427
484
  }
428
485
  }
429
- }
430
486
 
431
- alchemy-field-schema {
432
- alchemy-field {
433
- border: none;
434
- margin-bottom: 1rem;
435
- }
436
- }
487
+ alchemy-password-input {
488
+ label:first-of-type {
489
+ margin-bottom: 0;
490
+ }
491
+
492
+ .repeat-input-label {
493
+ margin-top: 1rem;
494
+ }
437
495
 
438
- .aft-actions {
439
- a {
440
- color: var(--button-text-color);
441
- background-color: var(--button-bg-color);
442
- padding: 0.5rem;
443
- border-radius: 6px;
444
- margin: 0.2rem;
445
- display: inline-block;
446
-
447
- &:hover {
448
- background-color: var(--button-bg-hover-color);
496
+ .inputbox {
497
+ background: initial;
449
498
  }
450
499
  }
451
500
  }
package/bootstrap.js CHANGED
@@ -1,4 +1,5 @@
1
1
  alchemy.requirePlugin('widget');
2
+ alchemy.requirePlugin('form');
2
3
 
3
4
  // Define the default options
4
5
  let options = {
package/config/routes.js CHANGED
@@ -35,6 +35,14 @@ chimera_section.add({
35
35
  breadcrumb : 'chimera.editor.{model}.edit.{pk}'
36
36
  });
37
37
 
38
+ // Editor trash action
39
+ chimera_section.add({
40
+ name : 'Chimera.Editor#trash',
41
+ methods : ['get', 'post'],
42
+ paths : '/editor/{model}/trash/{pk}',
43
+ breadcrumb : 'chimera.editor.{model}.trash.{pk}'
44
+ });
45
+
38
46
  // Editor data action
39
47
  chimera_section.add({
40
48
  name : 'Chimera.Editor#records',
@@ -12,7 +12,7 @@ const Editor = Function.inherits('Alchemy.Controller.Chimera', 'Editor');
12
12
  *
13
13
  * @author Jelle De Loecker <jelle@elevenways.be>
14
14
  * @since 1.0.1
15
- * @version 1.0.1
15
+ * @version 1.0.5
16
16
  *
17
17
  * @param {String} title
18
18
  */
@@ -27,6 +27,8 @@ Editor.setMethod(function setTitle(title) {
27
27
  if (title && window_title) {
28
28
  window_title += ' | ';
29
29
  }
30
+ } else {
31
+ window_title = '';
30
32
  }
31
33
 
32
34
  if (title) {
@@ -123,7 +125,7 @@ Editor.setAction(async function add(conduit, model_name) {
123
125
  *
124
126
  * @author Jelle De Loecker <jelle@elevenways.be>
125
127
  * @since 0.1.0
126
- * @version 1.0.2
128
+ * @version 1.0.5
127
129
  *
128
130
  * @param {Conduit} conduit
129
131
  * @param {String} model_name
@@ -138,6 +140,8 @@ Editor.setAction(async function edit(conduit, model_name, pk_val) {
138
140
  let record = await model.findByPk(pk_val);
139
141
  let message_type = conduit.param('message');
140
142
 
143
+ record.keepPrivateFields();
144
+
141
145
  let context_variables = {
142
146
  record,
143
147
  };
@@ -178,12 +182,52 @@ Editor.setAction(async function edit(conduit, model_name, pk_val) {
178
182
  this.render('chimera/widgets');
179
183
  });
180
184
 
185
+ /**
186
+ * The trash action
187
+ *
188
+ * @author Jelle De Loecker <jelle@elevenways.be>
189
+ * @since 1.0.4
190
+ * @version 1.0.4
191
+ *
192
+ * @param {Conduit} conduit
193
+ * @param {String} model_name
194
+ * @param {String} pk_val
195
+ */
196
+ Editor.setAction(async function trash(conduit, model_name, pk_val) {
197
+
198
+ let model = this.getModel(model_name);
199
+
200
+ model.translateItems = false;
201
+
202
+ let record = await model.findByPk(pk_val);
203
+
204
+ if (!record) {
205
+ return conduit.notFound();
206
+ }
207
+
208
+ let index_url = alchemy.routeUrl('Chimera.Editor#index', {
209
+ model : model_name
210
+ });
211
+
212
+ if (conduit.method == 'post') {
213
+ await record.remove();
214
+ conduit.redirect(index_url);
215
+ return;
216
+ }
217
+
218
+ let referer = conduit.headers.referer || index_url;
219
+
220
+ this.set('back_url', referer);
221
+ this.set('record', record);
222
+ this.render('chimera/editor/trash');
223
+ });
224
+
181
225
  /**
182
226
  * The records API action
183
227
  *
184
228
  * @author Jelle De Loecker <jelle@elevenways.be>
185
229
  * @since 1.0.0
186
- * @version 1.0.0
230
+ * @version 1.0.5
187
231
  *
188
232
  * @param {Conduit} conduit
189
233
  * @param {String} model_name
@@ -229,7 +273,7 @@ Editor.setAction(async function records(conduit, model_name) {
229
273
  continue;
230
274
  }
231
275
 
232
- val = RegExp.interpretWildcard('*' + val + '*');
276
+ val = RegExp.interpretWildcard('*' + val + '*', 'i');
233
277
  crit.where(key).equals(val);
234
278
  }
235
279
  }
@@ -238,18 +282,34 @@ Editor.setAction(async function records(conduit, model_name) {
238
282
  result = [],
239
283
  record,
240
284
  main;
285
+
286
+ records.keepPrivateFields();
241
287
 
242
288
  for (record of records) {
243
289
 
244
- record.$hold.actions = [
245
- {
246
- name : 'edit',
247
- icon : 'edit',
248
- url : alchemy.routeUrl('Chimera.Editor#edit', {
290
+ let edit_action = new Classes.Alchemy.Form.Action.Url({
291
+ name : 'edit',
292
+ icon : 'edit',
293
+ placement : ['row', 'context'],
294
+ url : alchemy.routeUrl('Chimera.Editor#edit', {
295
+ model : model_name,
296
+ pk : record.$pk,
297
+ })
298
+ });
299
+
300
+ let trash_action = new Classes.Alchemy.Form.Action.Url({
301
+ name : 'trash',
302
+ icon : 'trash',
303
+ placement : ['context'],
304
+ url : alchemy.routeUrl('Chimera.Editor#trash', {
249
305
  model : model_name,
250
306
  pk : record.$pk,
251
307
  })
252
- }
308
+ });
309
+
310
+ record.$hold.actions = [
311
+ edit_action,
312
+ trash_action,
253
313
  ];
254
314
  }
255
315
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemy-chimera",
3
3
  "description": "Chimera plugin for Alchemy MVC",
4
- "version": "1.0.2",
4
+ "version": "1.0.5",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -12,12 +12,11 @@
12
12
  "repository": "11ways/alchemy-chimera",
13
13
  "peerDependencies": {
14
14
  "alchemy-acl" : "~0.7.0",
15
- "alchemy-menu" : "~0.6.0",
16
- "alchemymvc" : "~1.1.0",
17
- "alchemy-widget": "~0.1.0"
15
+ "alchemymvc" : "~1.2.4",
16
+ "alchemy-widget": "~0.1.2"
18
17
  },
19
18
  "license": "MIT",
20
19
  "engines": {
21
- "node" : ">=12.0.0"
20
+ "node" : ">=14.0.0"
22
21
  }
23
22
  }
@@ -0,0 +1,34 @@
1
+ {% include "layouts/chimera_basics" %}
2
+
3
+ {% block "main" %}
4
+ <div class="chimera-confirm-page">
5
+ <h1>{%t "confirm-delete-title" %}</h1>
6
+
7
+ <p>
8
+ {%t "confirm-delete-text" model=record.$model_name title=record.getDisplayFieldValue() %}
9
+ </p>
10
+
11
+ <br>
12
+
13
+ <form class="action-buttons">
14
+ <a class="btn" href={% back_url %}>
15
+ {%t "cancel" %}
16
+ </a>
17
+ <button class="btn danger">
18
+ <al-ico type="trash" class="fas fa-trash"></al-ico>
19
+ {%t "delete" %}
20
+ </button>
21
+ </form>
22
+ </div>
23
+ {% /block %}
24
+
25
+ {% block "page-actions" %}
26
+ <a
27
+ !Route="Chimera.Editor#add"
28
+ #model={% model_name %}
29
+ class="btn"
30
+ >
31
+ <al-ico type="plus"></al-ico>
32
+ {%t "new" model=model_name %}
33
+ </a>
34
+ {% /block %}