@projectcaluma/ember-form-builder 11.0.0-beta.4 → 11.0.0-beta.40

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/addon/components/cfb-code-editor.hbs +26 -9
  3. package/addon/components/cfb-code-editor.js +60 -11
  4. package/addon/components/cfb-form-editor/general.hbs +1 -3
  5. package/addon/components/cfb-form-editor/general.js +6 -7
  6. package/addon/components/cfb-form-editor/question/default.hbs +11 -9
  7. package/addon/components/cfb-form-editor/question/default.js +9 -4
  8. package/addon/components/cfb-form-editor/question/options.hbs +3 -3
  9. package/addon/components/cfb-form-editor/question/validation.hbs +16 -14
  10. package/addon/components/cfb-form-editor/question/validation.js +17 -13
  11. package/addon/components/cfb-form-editor/question-list/item.hbs +44 -38
  12. package/addon/components/cfb-form-editor/question-list.hbs +2 -2
  13. package/addon/components/cfb-form-editor/question-list.js +9 -3
  14. package/addon/components/cfb-form-editor/question.hbs +55 -96
  15. package/addon/components/cfb-form-editor/question.js +53 -34
  16. package/addon/components/cfb-form-list.hbs +7 -7
  17. package/addon/components/cfb-form-list.js +44 -11
  18. package/addon/controllers/index.js +6 -0
  19. package/addon/engine.js +1 -1
  20. package/addon/gql/mutations/add-form-question.graphql +1 -1
  21. package/addon/gql/mutations/remove-form-question.graphql +1 -1
  22. package/addon/gql/mutations/reorder-form-questions.graphql +1 -1
  23. package/addon/gql/mutations/save-calculated-float-question.graphql +1 -0
  24. package/addon/gql/mutations/save-choice-question.graphql +1 -0
  25. package/addon/gql/mutations/save-date-question.graphql +3 -0
  26. package/addon/gql/mutations/save-dynamic-choice-question.graphql +1 -0
  27. package/addon/gql/mutations/save-dynamic-multiple-choice-question.graphql +1 -0
  28. package/addon/gql/mutations/save-files-question.graphql +14 -0
  29. package/addon/gql/mutations/save-float-question.graphql +1 -0
  30. package/addon/gql/mutations/save-integer-question.graphql +1 -0
  31. package/addon/gql/mutations/save-multiple-choice-question.graphql +1 -0
  32. package/addon/gql/mutations/save-table-question.graphql +1 -0
  33. package/addon/gql/mutations/save-text-question.graphql +1 -0
  34. package/addon/gql/mutations/save-textarea-question.graphql +1 -0
  35. package/addon/gql/queries/all-format-validators.graphql +10 -0
  36. package/addon/gql/queries/check-form-slug.graphql +1 -1
  37. package/addon/gql/queries/check-question-slug.graphql +1 -1
  38. package/addon/gql/queries/form-editor-general.graphql +1 -1
  39. package/addon/gql/queries/form-editor-question.graphql +30 -2
  40. package/addon/gql/queries/search-form-question.graphql +3 -3
  41. package/addon/instance-initializers/form-builder-widget-overrides.js +15 -0
  42. package/addon/routes/edit/questions/edit.js +2 -1
  43. package/addon/routes/edit.js +1 -1
  44. package/addon/templates/index.hbs +8 -1
  45. package/addon/validations/question.js +13 -4
  46. package/addon/validators/gt-lt.js +17 -38
  47. package/addon/validators/jexl.js +49 -0
  48. package/app/instance-initializers/form-builder-widget-overrides.js +4 -0
  49. package/app/styles/@projectcaluma/ember-form-builder.scss +2 -2
  50. package/app/styles/_cfb-uikit-powerselect.scss +2 -0
  51. package/blueprints/@projectcaluma/ember-form-builder/index.js +1 -1
  52. package/config/environment.js +0 -7
  53. package/index.js +4 -2
  54. package/package.json +57 -46
  55. package/translations/de.yaml +7 -6
  56. package/translations/en.yaml +4 -3
  57. package/translations/fr.yaml +154 -1
  58. package/addon/components/cfb-float-input.hbs +0 -14
  59. package/addon/components/cfb-label.hbs +0 -12
  60. package/addon/gql/fragments/field.graphql +0 -247
  61. package/addon/gql/mutations/save-file-question.graphql +0 -11
  62. package/app/components/cfb-float-input.js +0 -1
  63. package/app/components/cfb-label.js +0 -1
  64. package/app/styles/_cfb-powerselect.scss +0 -31
@@ -5,6 +5,9 @@ mutation SaveDateQuestion($input: SaveDateQuestionInput!) {
5
5
  question {
6
6
  id
7
7
  ...QuestionInfo
8
+ ... on DateQuestion {
9
+ hintText
10
+ }
8
11
  }
9
12
  clientMutationId
10
13
  }
@@ -7,6 +7,7 @@ mutation SaveDynamicChoiceQuestion($input: SaveDynamicChoiceQuestionInput!) {
7
7
  ...QuestionInfo
8
8
  ... on DynamicChoiceQuestion {
9
9
  dataSource
10
+ hintText
10
11
  }
11
12
  }
12
13
  clientMutationId
@@ -9,6 +9,7 @@ mutation SaveDynamicMultipleChoiceQuestion(
9
9
  ...QuestionInfo
10
10
  ... on DynamicMultipleChoiceQuestion {
11
11
  dataSource
12
+ hintText
12
13
  }
13
14
  }
14
15
  clientMutationId
@@ -0,0 +1,14 @@
1
+ #import QuestionInfo from '../fragments/question-info.graphql'
2
+
3
+ mutation SaveFilesQuestion($input: SaveFilesQuestionInput!) {
4
+ saveFilesQuestion(input: $input) {
5
+ question {
6
+ id
7
+ ...QuestionInfo
8
+ ... on FilesQuestion {
9
+ hintText
10
+ }
11
+ }
12
+ clientMutationId
13
+ }
14
+ }
@@ -8,6 +8,7 @@ mutation SaveFloatQuestion($input: SaveFloatQuestionInput!) {
8
8
  ... on FloatQuestion {
9
9
  floatMinValue: minValue
10
10
  floatMaxValue: maxValue
11
+ hintText
11
12
  }
12
13
  }
13
14
  clientMutationId
@@ -8,6 +8,7 @@ mutation SaveIntegerQuestion($input: SaveIntegerQuestionInput!) {
8
8
  ... on IntegerQuestion {
9
9
  integerMinValue: minValue
10
10
  integerMaxValue: maxValue
11
+ hintText
11
12
  }
12
13
  }
13
14
  clientMutationId
@@ -15,6 +15,7 @@ mutation SaveMultipleChoiceQuestion($input: SaveMultipleChoiceQuestionInput!) {
15
15
  }
16
16
  }
17
17
  }
18
+ hintText
18
19
  }
19
20
  }
20
21
  clientMutationId
@@ -10,6 +10,7 @@ mutation SaveTableQuestion($input: SaveTableQuestionInput!) {
10
10
  id
11
11
  slug
12
12
  }
13
+ hintText
13
14
  }
14
15
  }
15
16
  clientMutationId
@@ -8,6 +8,7 @@ mutation SaveTextQuestion($input: SaveTextQuestionInput!) {
8
8
  ... on TextQuestion {
9
9
  minLength
10
10
  maxLength
11
+ hintText
11
12
  }
12
13
  }
13
14
  clientMutationId
@@ -8,6 +8,7 @@ mutation SaveTextareaQuestion($input: SaveTextareaQuestionInput!) {
8
8
  ... on TextareaQuestion {
9
9
  minLength
10
10
  maxLength
11
+ hintText
11
12
  }
12
13
  }
13
14
  clientMutationId
@@ -0,0 +1,10 @@
1
+ query AllFormatValidators {
2
+ allFormatValidators {
3
+ edges {
4
+ node {
5
+ slug
6
+ name
7
+ }
8
+ }
9
+ }
10
+ }
@@ -1,5 +1,5 @@
1
1
  query CheckFormSlug($slug: String!) {
2
- allForms(filter: [{ slug: $slug }]) {
2
+ allForms(filter: [{ slugs: [$slug] }]) {
3
3
  edges {
4
4
  node {
5
5
  id
@@ -1,5 +1,5 @@
1
1
  query CheckQuestionSlug($slug: String!) {
2
- allQuestions(filter: [{ slug: $slug }]) {
2
+ allQuestions(filter: [{ slugs: [$slug] }]) {
3
3
  edges {
4
4
  node {
5
5
  id
@@ -1,7 +1,7 @@
1
1
  #import FormInfo from '../fragments/form-info.graphql'
2
2
 
3
3
  query FormEditorGeneral($slug: String!) {
4
- allForms(filter: [{ slug: $slug }]) {
4
+ allForms(filter: [{ slugs: [$slug] }]) {
5
5
  edges {
6
6
  node {
7
7
  id
@@ -1,8 +1,8 @@
1
1
  #import QuestionInfo from '../fragments/question-info.graphql'
2
- #import FieldQuestion, FieldTableQuestion, SimpleAnswer, SimpleQuestion from '../fragments/field.graphql'
2
+ #import FieldQuestion, FieldTableQuestion, SimpleAnswer, SimpleQuestion from '@projectcaluma/ember-form/gql/fragments/field.graphql'
3
3
 
4
4
  query FormEditorQuestion($slug: String!) {
5
- allQuestions(filter: [{ slug: $slug }]) {
5
+ allQuestions(filter: [{ slugs: [$slug] }]) {
6
6
  edges {
7
7
  node {
8
8
  id
@@ -11,6 +11,7 @@ query FormEditorQuestion($slug: String!) {
11
11
  integerMaxValue: maxValue
12
12
  integerMinValue: minValue
13
13
  placeholder
14
+ hintText
14
15
  defaultAnswer {
15
16
  id
16
17
  integerValue: value
@@ -20,6 +21,7 @@ query FormEditorQuestion($slug: String!) {
20
21
  floatMaxValue: maxValue
21
22
  floatMinValue: minValue
22
23
  placeholder
24
+ hintText
23
25
  defaultAnswer {
24
26
  id
25
27
  floatValue: value
@@ -29,21 +31,38 @@ query FormEditorQuestion($slug: String!) {
29
31
  minLength
30
32
  maxLength
31
33
  placeholder
34
+ hintText
32
35
  defaultAnswer {
33
36
  id
34
37
  stringValue: value
35
38
  }
39
+ formatValidators {
40
+ edges {
41
+ node {
42
+ slug
43
+ }
44
+ }
45
+ }
36
46
  }
37
47
  ... on TextareaQuestion {
38
48
  minLength
39
49
  maxLength
40
50
  placeholder
51
+ formatValidators {
52
+ edges {
53
+ node {
54
+ slug
55
+ }
56
+ }
57
+ }
58
+ hintText
41
59
  defaultAnswer {
42
60
  id
43
61
  stringValue: value
44
62
  }
45
63
  }
46
64
  ... on DateQuestion {
65
+ hintText
47
66
  defaultAnswer {
48
67
  id
49
68
  dateValue: value
@@ -60,6 +79,7 @@ query FormEditorQuestion($slug: String!) {
60
79
  }
61
80
  }
62
81
  }
82
+ hintText
63
83
  defaultAnswer {
64
84
  id
65
85
  listValue: value
@@ -76,6 +96,7 @@ query FormEditorQuestion($slug: String!) {
76
96
  }
77
97
  }
78
98
  }
99
+ hintText
79
100
  defaultAnswer {
80
101
  id
81
102
  stringValue: value
@@ -83,9 +104,11 @@ query FormEditorQuestion($slug: String!) {
83
104
  }
84
105
  ... on DynamicMultipleChoiceQuestion {
85
106
  dataSource
107
+ hintText
86
108
  }
87
109
  ... on DynamicChoiceQuestion {
88
110
  dataSource
111
+ hintText
89
112
  }
90
113
  ... on TableQuestion {
91
114
  rowForm {
@@ -101,6 +124,7 @@ query FormEditorQuestion($slug: String!) {
101
124
  }
102
125
  }
103
126
  }
127
+ hintText
104
128
  defaultAnswer {
105
129
  id
106
130
  tableValue: value {
@@ -137,6 +161,10 @@ query FormEditorQuestion($slug: String!) {
137
161
  }
138
162
  ... on CalculatedFloatQuestion {
139
163
  calcExpression
164
+ hintText
165
+ }
166
+ ... on FilesQuestion {
167
+ hintText
140
168
  }
141
169
  ... on ActionButtonQuestion {
142
170
  action
@@ -1,12 +1,12 @@
1
1
  #import QuestionInfo from '../fragments/question-info.graphql'
2
2
 
3
- query SearchFormQuestion($slug: String!, $search: String, $archived: Boolean) {
4
- allForms(filter: [{ slug: $slug }]) {
3
+ query SearchFormQuestion($slug: String!, $search: String) {
4
+ allForms(filter: [{ slugs: [$slug] }]) {
5
5
  edges {
6
6
  node {
7
7
  id
8
8
  slug
9
- questions(search: $search, isArchived: $archived) {
9
+ questions(filter: [{ search: $search }]) {
10
10
  edges {
11
11
  node {
12
12
  id
@@ -0,0 +1,15 @@
1
+ import DefaultTableComponent from "@projectcaluma/ember-form-builder/components/cfb-form-editor/question/default/table";
2
+
3
+ export function initialize(appInstance) {
4
+ const options = appInstance.lookup("service:caluma-options");
5
+
6
+ options.registerComponentOverride({
7
+ component: "cfb-form-editor/question/default/table",
8
+ componentClass: DefaultTableComponent,
9
+ types: [],
10
+ });
11
+ }
12
+
13
+ export default {
14
+ initialize,
15
+ };
@@ -20,9 +20,10 @@ export default class EditQuestionsEditRoute extends Route {
20
20
  {
21
21
  query: gql`
22
22
  query QuestionLabel($slug: String!) {
23
- allQuestions(slug: $slug) {
23
+ allQuestions(filter: [{ slugs: [$slug] }]) {
24
24
  edges {
25
25
  node {
26
+ id
26
27
  label
27
28
  }
28
29
  }
@@ -20,7 +20,7 @@ export default class EditRoute extends Route {
20
20
  {
21
21
  query: gql`
22
22
  query FormName($slug: String!) {
23
- allForms(slug: $slug) {
23
+ allForms(filter: [{ slugs: [$slug] }]) {
24
24
  edges {
25
25
  node {
26
26
  name
@@ -1 +1,8 @@
1
- <CfbFormList @onNewForm={{this.newForm}} @onEditForm={{this.editForm}} />
1
+ <CfbFormList
2
+ @search={{this.search}}
3
+ @category={{this.category}}
4
+ @onNewForm={{this.newForm}}
5
+ @onEditForm={{this.editForm}}
6
+ @onUpdateSearch={{fn (mut this.search)}}
7
+ @onUpdateCategory={{fn (mut this.category)}}
8
+ />
@@ -9,6 +9,7 @@ import validateOptions from "../validators/options";
9
9
 
10
10
  import and from "@projectcaluma/ember-form-builder/utils/and";
11
11
  import or from "@projectcaluma/ember-form-builder/utils/or";
12
+ import validateJexl from "@projectcaluma/ember-form-builder/validators/jexl";
12
13
  import validateSlug from "@projectcaluma/ember-form-builder/validators/slug";
13
14
  import validateType from "@projectcaluma/ember-form-builder/validators/type";
14
15
 
@@ -16,18 +17,24 @@ export default {
16
17
  label: and(validatePresence(true), validateLength({ max: 1024 })),
17
18
  slug: validateSlug(),
18
19
 
20
+ hintText: or(
21
+ validateType("FormQuestion", true),
22
+ validateType("StaticQuestion", true),
23
+ validateType("FilesQuestion", true),
24
+ validateLength({ max: 1024, allowBlank: true })
25
+ ),
19
26
  integerMinValue: or(
20
27
  validateType("IntegerQuestion", false),
21
28
  and(
22
29
  validateNumber({ allowBlank: true, integer: true }),
23
- validateGtLt({ lt: "integerMaxValue" })
30
+ validateGtLt({ lt: "integerMaxValue", allowNone: true })
24
31
  )
25
32
  ),
26
33
  integerMaxValue: or(
27
34
  validateType("IntegerQuestion", false),
28
35
  and(
29
36
  validateNumber({ allowBlank: true, integer: true }),
30
- validateGtLt({ gt: "integerMinValue" })
37
+ validateGtLt({ gt: "integerMinValue", allowNone: true })
31
38
  )
32
39
  ),
33
40
 
@@ -35,14 +42,14 @@ export default {
35
42
  validateType("FloatQuestion", false),
36
43
  and(
37
44
  validateNumber({ allowBlank: true }),
38
- validateGtLt({ lt: "floatMaxValue" })
45
+ validateGtLt({ lt: "floatMaxValue", allowNone: true })
39
46
  )
40
47
  ),
41
48
  floatMaxValue: or(
42
49
  validateType("FloatQuestion", false),
43
50
  and(
44
51
  validateNumber({ allowBlank: true }),
45
- validateGtLt({ gt: "floatMinValue" })
52
+ validateGtLt({ gt: "floatMinValue", allowNone: true })
46
53
  )
47
54
  ),
48
55
 
@@ -76,4 +83,6 @@ export default {
76
83
  validateType("FormQuestion", false),
77
84
  validatePresence(true)
78
85
  ),
86
+ isHidden: validateJexl(),
87
+ isRequired: validateJexl(),
79
88
  };
@@ -1,47 +1,26 @@
1
- import getMessages from "ember-changeset-validations/utils/get-messages";
2
- import buildMessage from "ember-changeset-validations/utils/validation-errors";
1
+ import { validateNumber } from "ember-changeset-validations/validators";
3
2
 
4
- export default function validateGtLt(options = { gt: null, lt: null }) {
3
+ export default function validateGtLt(options = {}) {
5
4
  return (key, newValue, oldValue, changes, content) => {
6
- newValue = Number(newValue);
7
-
8
- if (!newValue) {
9
- return true;
10
- }
11
-
12
- const messages = getMessages();
13
5
  const data = { ...content, ...changes };
14
6
 
15
- if (options.gt) {
16
- const dependentValue = data[options.gt];
17
-
18
- return dependentValue
19
- ? Number(newValue) > Number(dependentValue) ||
20
- buildMessage(key, {
21
- type: "greaterThan",
22
- value: newValue,
23
- context: {
24
- gt: messages.getDescriptionFor(options.gt),
25
- },
26
- })
27
- : true;
28
- }
7
+ const parsedOptions = Object.entries(options).reduce((parsed, [k, v]) => {
8
+ const value =
9
+ /^(g|l)t(e)?$/.test(k) && typeof v === "string" ? data[v] : v;
29
10
 
30
- if (options.lt) {
31
- const dependentValue = data[options.lt];
11
+ if (value) {
12
+ return { ...parsed, [k]: value };
13
+ }
32
14
 
33
- return dependentValue
34
- ? Number(newValue) < Number(dependentValue) ||
35
- buildMessage(key, {
36
- type: "lessThan",
37
- value: newValue,
38
- context: {
39
- lt: messages.getDescriptionFor(options.lt),
40
- },
41
- })
42
- : true;
43
- }
15
+ return parsed;
16
+ }, {});
44
17
 
45
- return true;
18
+ return validateNumber(parsedOptions)(
19
+ key,
20
+ newValue,
21
+ oldValue,
22
+ changes,
23
+ content
24
+ );
46
25
  };
47
26
  }
@@ -0,0 +1,49 @@
1
+ import jexl from "jexl";
2
+
3
+ const TRANSFORMS = [
4
+ "answer",
5
+ "mapby",
6
+ "debug",
7
+ "min",
8
+ "max",
9
+ "round",
10
+ "ceil",
11
+ "floor",
12
+ "sum",
13
+ "avg",
14
+ "stringify",
15
+ ];
16
+ const BINARY_OPS = ["intersects"];
17
+
18
+ const documentJexl = new jexl.Jexl();
19
+
20
+ const noop = () => {};
21
+
22
+ TRANSFORMS.forEach((transform) => documentJexl.addTransform(transform, noop));
23
+ BINARY_OPS.forEach((binaryOp) => documentJexl.addBinaryOp(binaryOp, 0, noop));
24
+
25
+ function parseError(error) {
26
+ const str = String(error)
27
+ .replace(/^Error:/, "") // Remove "Error:" prefix
28
+ .replace(/(of expression):.*$/, (_, match) => match) // Remove everything after "of expression"
29
+ .replace(/in expression:.*$/, "") // Remove "in expression: [expression]"
30
+ .replace(/\.$/g, "") // Remove trailing dot
31
+ .replace(/\s\s+/g, " ") // Remove double whitespace chars
32
+ .trim();
33
+
34
+ return str;
35
+ }
36
+
37
+ export default function validateJexl() {
38
+ return (key, newValue) => {
39
+ try {
40
+ if (newValue) {
41
+ documentJexl.evalSync(newValue);
42
+ }
43
+
44
+ return true;
45
+ } catch (error) {
46
+ return parseError(error);
47
+ }
48
+ };
49
+ }
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ initialize,
4
+ } from "@projectcaluma/ember-form-builder/instance-initializers/form-builder-widget-overrides";
@@ -3,7 +3,7 @@
3
3
  @import "../cfb-form-editor/question-list/item";
4
4
  @import "../cfb-form-editor/question";
5
5
  @import "../cfb-navigation";
6
- @import "../cfb-powerselect";
6
+ @import "../cfb-uikit-powerselect";
7
7
 
8
8
  .cfb-pointer {
9
9
  cursor: pointer;
@@ -22,7 +22,7 @@
22
22
  .cfb-code-editor {
23
23
  font-family: $base-code-font-family;
24
24
  letter-spacing: normal;
25
- height: 70px;
25
+ min-height: 70px;
26
26
  line-height: 16px;
27
27
  tab-size: 4;
28
28
  }
@@ -0,0 +1,2 @@
1
+ @import "@projectcaluma/ember-core";
2
+ @import "ember-power-select";
@@ -10,7 +10,7 @@ module.exports = {
10
10
  { name: "@projectcaluma/ember-form" },
11
11
  { name: "ember-engines" },
12
12
  { name: "ember-math-helpers" },
13
- { name: "ember-pikaday" },
13
+ { name: "ember-flatpickr" },
14
14
  { name: "ember-power-select" },
15
15
  ],
16
16
  });
@@ -4,12 +4,5 @@ module.exports = function (environment) {
4
4
  return {
5
5
  modulePrefix: require("../package.json").name,
6
6
  environment,
7
-
8
- "ember-validated-form": {
9
- theme: "uikit",
10
- defaults: {
11
- label: "cfb-label",
12
- },
13
- },
14
7
  };
15
8
  };
package/index.js CHANGED
@@ -11,8 +11,10 @@ module.exports = buildEngine({
11
11
  },
12
12
 
13
13
  included(...args) {
14
- this._super.included.apply(this, args);
14
+ const app = this._findHost(this);
15
+
16
+ app.options["ember-validated-form"] = { theme: "uikit" };
15
17
 
16
- this.import("node_modules/prismjs/themes/prism.css");
18
+ this._super.included.apply(this, args);
17
19
  },
18
20
  });