@projectcaluma/ember-analytics 1.0.0-beta.1

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 (84) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/addon/components/ca-field-form.hbs +82 -0
  3. package/addon/components/ca-field-form.js +100 -0
  4. package/addon/components/ca-field-select.hbs +30 -0
  5. package/addon/components/ca-field-select.js +111 -0
  6. package/addon/components/ca-field-selector-list/ca-field-alias-input.hbs +21 -0
  7. package/addon/components/ca-field-selector-list/ca-field-alias-input.js +28 -0
  8. package/addon/components/ca-field-selector-list/ca-field-function-select.hbs +8 -0
  9. package/addon/components/ca-field-selector-list/ca-field-function-select.js +49 -0
  10. package/addon/components/ca-field-selector-list.hbs +82 -0
  11. package/addon/components/ca-field-selector-list.js +54 -0
  12. package/addon/components/ca-filter-modal.hbs +77 -0
  13. package/addon/components/ca-filter-modal.js +59 -0
  14. package/addon/components/ca-report-builder.hbs +26 -0
  15. package/addon/components/ca-report-builder.js +52 -0
  16. package/addon/components/ca-report-list.hbs +27 -0
  17. package/addon/components/ca-report-preview.hbs +42 -0
  18. package/addon/components/ca-report-preview.js +61 -0
  19. package/addon/components/ca-toggle-switch.hbs +19 -0
  20. package/addon/controllers/reports/edit/index.js +17 -0
  21. package/addon/controllers/reports/edit.js +44 -0
  22. package/addon/controllers/reports/index.js +11 -0
  23. package/addon/engine.js +17 -0
  24. package/addon/gql/fragments/analytics-available-field.graphql +8 -0
  25. package/addon/gql/fragments/analytics-field.graphql +9 -0
  26. package/addon/gql/fragments/analytics-table-fields-of-field.graphql +11 -0
  27. package/addon/gql/fragments/analytics-table-result.graphql +22 -0
  28. package/addon/gql/fragments/analytics-table.graphql +23 -0
  29. package/addon/gql/mutations/remove-analytics-field.graphql +5 -0
  30. package/addon/gql/mutations/remove-analytics-table.graphql +5 -0
  31. package/addon/gql/mutations/save-analytics-field.graphql +19 -0
  32. package/addon/gql/mutations/save-analytics-table.graphql +9 -0
  33. package/addon/gql/queries/get-all-analytics-fields.graphql +12 -0
  34. package/addon/gql/queries/get-all-analytics-tables.graphql +11 -0
  35. package/addon/gql/queries/get-analytics-results.graphql +20 -0
  36. package/addon/gql/queries/get-analytics-table.graphql +7 -0
  37. package/addon/gql/queries/get-available-fields-for-field.graphql +8 -0
  38. package/addon/routes/reports/edit/index.js +7 -0
  39. package/addon/routes/reports/edit/preview.js +7 -0
  40. package/addon/routes/reports/edit.js +14 -0
  41. package/addon/routes/reports/index.js +26 -0
  42. package/addon/routes/reports/new.js +32 -0
  43. package/addon/routes.js +11 -0
  44. package/addon/tasks/get-analytics-table.js +19 -0
  45. package/addon/tasks/save-analytics-field.js +19 -0
  46. package/addon/templates/reports/edit/index.hbs +8 -0
  47. package/addon/templates/reports/edit/preview.hbs +1 -0
  48. package/addon/templates/reports/edit.hbs +51 -0
  49. package/addon/templates/reports/index.hbs +4 -0
  50. package/addon/templates/reports/new.hbs +2 -0
  51. package/addon/validations/analytics-table.js +6 -0
  52. package/addon/validations/field.js +14 -0
  53. package/app/components/ca-field-form.js +1 -0
  54. package/app/components/ca-field-select.js +1 -0
  55. package/app/components/ca-field-selector-list/ca-field-alias-input.js +1 -0
  56. package/app/components/ca-field-selector-list/ca-field-function-select.js +1 -0
  57. package/app/components/ca-field-selector-list.js +1 -0
  58. package/app/components/ca-filter-modal.js +1 -0
  59. package/app/components/ca-report-builder.js +1 -0
  60. package/app/components/ca-report-list.js +1 -0
  61. package/app/components/ca-report-preview.js +1 -0
  62. package/app/components/ca-toggle-switch.js +1 -0
  63. package/app/controllers/reports/edit/index.js +1 -0
  64. package/app/controllers/reports/edit.js +1 -0
  65. package/app/controllers/reports/index.js +1 -0
  66. package/app/routes/reports/edit/index.js +1 -0
  67. package/app/routes/reports/edit/preview.js +1 -0
  68. package/app/routes/reports/edit.js +1 -0
  69. package/app/routes/reports/index.js +1 -0
  70. package/app/routes/reports/new.js +1 -0
  71. package/app/styles/@projectcaluma/ember-analytics.scss +1 -0
  72. package/app/styles/_ca-uikit-powerselect.scss +2 -0
  73. package/app/templates/reports/edit/index.js +1 -0
  74. package/app/templates/reports/edit/preview.js +1 -0
  75. package/app/templates/reports/edit.js +1 -0
  76. package/app/templates/reports/index.js +1 -0
  77. package/app/templates/reports/new.js +1 -0
  78. package/blueprints/@projectcaluma/ember-analytics/index.js +18 -0
  79. package/config/environment.js +16 -0
  80. package/index.js +13 -0
  81. package/package.json +90 -0
  82. package/translations/de.yaml +44 -0
  83. package/translations/en.yaml +44 -0
  84. package/translations/fr.yaml +44 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # @projectcaluma/ember-analytics-v1.0.0-beta.1 (2022-08-02)
2
+
3
+
4
+ ### chore
5
+
6
+ * **deps:** update dependencies and drop support for node 10 ([51d6dee](https://github.com/projectcaluma/ember-caluma/commit/51d6deeda9811518622ba0cefd8d3876651dab4f))
7
+
8
+
9
+ ### Features
10
+
11
+ * **analytics:** adds analytics module for caluma ([#1655](https://github.com/projectcaluma/ember-caluma/issues/1655)) ([9573abe](https://github.com/projectcaluma/ember-caluma/commit/9573abe95cd39cb1467113026f2ab7773c3c9143))
12
+
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ * **deps:** Remove support for node v10
@@ -0,0 +1,82 @@
1
+ {{#if this.showForm}}
2
+ <ValidatedForm @model={{this.field}} @on-submit={{this.submitField}} as |f|>
3
+ <div
4
+ data-test-add-field-form
5
+ class="uk-flex uk-flex-between uk-flex-middle"
6
+ >
7
+ <h3>{{t "caluma.analytics.edit.add-field"}}</h3>
8
+ <div class="uk-flex uk-flex-middle">
9
+ <div class="uk-margin-right uk-flex uk-flex-middle">
10
+ <f.input
11
+ @name="showOutput"
12
+ @label={{t "caluma.analytics.edit.show-in-output"}}
13
+ @required={{true}}
14
+ @renderComponent={{component
15
+ (ensure-safe-component "ca-toggle-switch")
16
+ value=f.model.showOutput
17
+ size="small"
18
+ onToggle=(mut f.model.showOutput)
19
+ }}
20
+ />
21
+ </div>
22
+ </div>
23
+ </div>
24
+
25
+ <f.input
26
+ @type="select"
27
+ @name="dataSource"
28
+ @label={{t "caluma.analytics.edit.field"}}
29
+ >
30
+ <div class="uk-grid-small uk-child-width-1-5" uk-grid>
31
+ <CaFieldSelect
32
+ @onSelect={{this.setFieldPath}}
33
+ @selectedPath={{this.field.dataSource}}
34
+ @slug={{@analyticsTable.slug}}
35
+ />
36
+ </div>
37
+ </f.input>
38
+ {{#if this.showAggregationSelect}}
39
+ <f.input
40
+ @name="aggregateFunction"
41
+ @type="select"
42
+ @label={{t "caluma.analytics.edit.aggregation"}}
43
+ @options={{this.supportedFunctions}}
44
+ class="uk-width-small"
45
+ />
46
+ {{/if}}
47
+ <f.input
48
+ @name="alias"
49
+ @type="text"
50
+ @label={{t "caluma.analytics.edit.display-title"}}
51
+ @placeholder={{t "caluma.analytics.edit.display-title-placeholder"}}
52
+ />
53
+ <div class="uk-flex uk-flex-right">
54
+ <f.button
55
+ data-test-form-cancel
56
+ class="uk-margin-small-right"
57
+ @disabled={{this.saveField.isRunning}}
58
+ {{on "click" this.toggleForm}}
59
+ >
60
+ {{t "caluma.analytics.cancel"}}
61
+ </f.button>
62
+
63
+ <f.submit
64
+ data-test-form-submit
65
+ @loading={{this.saveField.isRunning}}
66
+ @disabled={{or this.saveField.isRunning (not this.isValueField)}}
67
+ >
68
+ {{t "caluma.analytics.edit.add-field"}}
69
+ </f.submit>
70
+ </div>
71
+ </ValidatedForm>
72
+ {{else}}
73
+ <div class="uk-flex uk-flex-right">
74
+ <UkButton
75
+ @color="primary"
76
+ data-test-add-field-button
77
+ {{on "click" this.toggleForm}}
78
+ >
79
+ {{t "caluma.analytics.edit.add-field"}}
80
+ </UkButton>
81
+ </div>
82
+ {{/if}}
@@ -0,0 +1,100 @@
1
+ import { action } from "@ember/object";
2
+ import { inject as service } from "@ember/service";
3
+ import Component from "@glimmer/component";
4
+ import { tracked } from "@glimmer/tracking";
5
+ import { queryManager } from "ember-apollo-client";
6
+ import { Changeset } from "ember-changeset";
7
+ import lookupValidator from "ember-changeset-validations";
8
+ import { enqueueTask } from "ember-concurrency";
9
+
10
+ import saveAnalyticsField from "@projectcaluma/ember-analytics/tasks/save-analytics-field";
11
+ import FieldValidations from "@projectcaluma/ember-analytics/validations/field";
12
+
13
+ class Field {
14
+ @tracked alias;
15
+ @tracked dataSource;
16
+ @tracked aggregateFunction = "VALUE";
17
+ @tracked showOutput = true;
18
+ }
19
+
20
+ export default class CaFieldFormComponent extends Component {
21
+ @queryManager apollo;
22
+ @service notification;
23
+ @service intl;
24
+
25
+ @tracked supportedFunctions = [];
26
+ @tracked isValueField = false;
27
+ @tracked showForm = false;
28
+
29
+ @enqueueTask saveField = saveAnalyticsField;
30
+
31
+ constructor(...args) {
32
+ super(...args);
33
+ this.field = Changeset(
34
+ new Field(),
35
+ lookupValidator(FieldValidations),
36
+ FieldValidations
37
+ );
38
+ }
39
+
40
+ get tableId() {
41
+ return this.args.analyticsTable?.id;
42
+ }
43
+
44
+ get analyticsFields() {
45
+ return this.args.analyticsTable?.fields.edges.map((edge) => edge.node);
46
+ }
47
+
48
+ get tableSlug() {
49
+ return this.args.analyticsTable?.slug;
50
+ }
51
+
52
+ get showAggregationSelect() {
53
+ return this.field.dataSource && this.supportedFunctions.length;
54
+ }
55
+
56
+ @action
57
+ toggleForm() {
58
+ this.showForm = !this.showForm;
59
+ this.field.rollback();
60
+ }
61
+
62
+ @action
63
+ setFieldPath(field) {
64
+ this.field.dataSource = field.sourcePath;
65
+ this.field.alias = field.label;
66
+ this.supportedFunctions = field.supportedFunctions;
67
+ this.isValueField = field.isValue;
68
+ }
69
+
70
+ @action
71
+ async submitField() {
72
+ this.field.validate();
73
+
74
+ if (this.field.isInvalid) {
75
+ this.notification.danger(
76
+ this.intl.t(`caluma.analytics.notification.field-invalid`)
77
+ );
78
+ } else if (
79
+ this.analyticsFields.find(
80
+ (existing) => existing.alias === this.field.get("alias")
81
+ )
82
+ ) {
83
+ this.notification.danger(
84
+ this.intl.t(`caluma.analytics.notification.alias-exists`)
85
+ );
86
+ } else {
87
+ const { id, alias, dataSource, aggregateFunction, showOutput } =
88
+ this.field.pendingData;
89
+ await this.saveField.perform({
90
+ table: this.tableId,
91
+ id,
92
+ alias,
93
+ dataSource,
94
+ showOutput,
95
+ function: aggregateFunction,
96
+ });
97
+ this.toggleForm();
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,30 @@
1
+ {{#if @child}}
2
+ <span
3
+ data-test-field-select-seperator
4
+ uk-icon="icon: triangle-right; ratio: 1.5"
5
+ class="uk-width-auto uk-text-center uk-margin-auto-vertical"
6
+ ></span>
7
+ {{/if}}
8
+ <div ...attributes data-test-field-select-primary-selector={{not @child}}>
9
+ <PowerSelect
10
+ class={{this.selectedOption.value}}
11
+ @options={{this.options}}
12
+ @selected={{this.selectedOption}}
13
+ @onChange={{this.update}}
14
+ @triggerId={{this.fieldPath}}
15
+ @onOpen={{this.fetchOptions.perform}}
16
+ as |option|
17
+ >
18
+ {{option.label}}
19
+ </PowerSelect>
20
+ </div>
21
+ {{#if this.isBranch}}
22
+ <CaFieldSelect
23
+ data-test-field-select-secondary-selector
24
+ @child={{true}}
25
+ @onSelect={{@onSelect}}
26
+ @parentPath={{this.fieldPath}}
27
+ @selectedPath={{@selectedPath}}
28
+ @slug={{@slug}}
29
+ />
30
+ {{/if}}
@@ -0,0 +1,111 @@
1
+ import { assert } from "@ember/debug";
2
+ import { action, set } from "@ember/object";
3
+ import { inject as service } from "@ember/service";
4
+ import Component from "@glimmer/component";
5
+ import { tracked } from "@glimmer/tracking";
6
+ import { queryManager } from "ember-apollo-client";
7
+ import { restartableTask } from "ember-concurrency";
8
+
9
+ import getAvailableFieldsForFieldQuery from "@projectcaluma/ember-analytics/gql/queries/get-available-fields-for-field.graphql";
10
+
11
+ export default class CaFieldSelectComponent extends Component {
12
+ @queryManager apollo;
13
+ @service notification;
14
+ @service intl;
15
+
16
+ @tracked _selectedOption;
17
+ @tracked options;
18
+
19
+ get selectedOption() {
20
+ if (!this.currentPathSegment) {
21
+ return {};
22
+ }
23
+ return { ...this._selectedOption, ...{ value: this.currentPathSegment } };
24
+ }
25
+
26
+ get currentPathSegment() {
27
+ if (!this.args.selectedPath) return "";
28
+ const remainingFromParentPath = this.args.parentPath
29
+ ? this.args.selectedPath.substring(this.args.parentPath.length + 1)
30
+ : this.args.selectedPath;
31
+ return this.firstSegment(remainingFromParentPath);
32
+ }
33
+
34
+ get hasRemainingPath() {
35
+ if (!this.args.selectedPath) return false;
36
+ const remainingFromParentPath = this.args.parentPath
37
+ ? this.args.selectedPath.substring(this.args.parentPath.length + 1)
38
+ : this.args.selectedPath;
39
+ return remainingFromParentPath.length > this.currentPathSegment.length + 1;
40
+ }
41
+
42
+ get fieldPath() {
43
+ if (!this.currentPathSegment) return "";
44
+ return (
45
+ (this.args.parentPath ? `${this.args.parentPath}.` : "") +
46
+ this.currentPathSegment
47
+ );
48
+ }
49
+
50
+ get isBranch() {
51
+ if (
52
+ (this.isRoot && this.fetchedFor === "_root_") ||
53
+ this.fetchedFor === this.args.parentPath
54
+ ) {
55
+ return this._selectedOption ? !this._selectedOption.isLeaf : false;
56
+ }
57
+ return this.hasRemainingPath;
58
+ }
59
+
60
+ get isRoot() {
61
+ return !this.args.parentPath;
62
+ }
63
+
64
+ @action
65
+ update(value) {
66
+ assert(
67
+ "A listener for updates on CaFieldSelectComponent has to be set.",
68
+ this.args.onSelect
69
+ );
70
+ set(this, "_selectedOption", value);
71
+ this.args.onSelect(this._selectedOption);
72
+ }
73
+
74
+ @restartableTask
75
+ *fetchOptions() {
76
+ try {
77
+ if (
78
+ !this.fetchedFor ||
79
+ (!this.isRoot && this.fetchedFor !== this.args.parentPath)
80
+ ) {
81
+ const options = yield this.apollo.query(
82
+ {
83
+ query: getAvailableFieldsForFieldQuery,
84
+ fetchPolicy: "no-cache",
85
+ variables: {
86
+ slug: this.args.slug,
87
+ prefix: this.args.parentPath ?? "",
88
+ },
89
+ },
90
+ "analyticsTable.availableFields"
91
+ );
92
+ this.fetchedFor = this.isRoot ? "_root_" : this.args.parentPath;
93
+ this.options = options.edges.map((edge) => edge.node);
94
+ }
95
+ } catch (error) {
96
+ console.error(error);
97
+ this.notification.danger(
98
+ this.intl.t("caluma.analytics.notification.fetch-error")
99
+ );
100
+ }
101
+ }
102
+
103
+ firstSegment(path) {
104
+ if (!path) return "";
105
+ if (path.indexOf(".") === -1) {
106
+ return path;
107
+ }
108
+ const delimiterIndex = path.indexOf(".");
109
+ return path.substring(0, delimiterIndex);
110
+ }
111
+ }
@@ -0,0 +1,21 @@
1
+ <div class="uk-inline">
2
+ <button
3
+ data-test-delete-field
4
+ type="button"
5
+ class="uk-form-icon uk-form-icon-flip"
6
+ uk-icon="check"
7
+ hidden={{not this.hasChanged}}
8
+ name={{t "caluma.analytics.edit.delete-field"}}
9
+ {{on "click" this.trimAndSave}}
10
+ >
11
+ <span hidden>{{t "caluma.analytics.edit.delete-field"}}</span>
12
+ </button>
13
+
14
+ <input
15
+ data-test-field-alias-input
16
+ aria-label={{t "caluma.analytics.edit.display-title"}}
17
+ class="uk-input {{if this.hasChanged 'uk-form-success'}}"
18
+ value={{this.value}}
19
+ {{on "input" (perform this.debounceInput)}}
20
+ />
21
+ </div>
@@ -0,0 +1,28 @@
1
+ import { action } from "@ember/object";
2
+ import Component from "@glimmer/component";
3
+ import { tracked } from "@glimmer/tracking";
4
+ import { restartableTask, timeout } from "ember-concurrency";
5
+
6
+ export default class CaFieldSelectorListCaFieldAliasInputComponent extends Component {
7
+ @tracked _value = null;
8
+
9
+ get value() {
10
+ return this._value ?? this.args.value;
11
+ }
12
+
13
+ get hasChanged() {
14
+ return this._value !== null && this._value !== this.args.value;
15
+ }
16
+
17
+ @action
18
+ async trimAndSave() {
19
+ await this.args.onSave(this._value);
20
+ this._value = null;
21
+ }
22
+
23
+ @restartableTask
24
+ *debounceInput(event) {
25
+ yield timeout(200);
26
+ this._value = event.target.value;
27
+ }
28
+ }
@@ -0,0 +1,8 @@
1
+ <PowerSelect
2
+ @onChange={{fn @update "function"}}
3
+ @options={{this.aggregationFunctions.value}}
4
+ @selected={{@field.function}}
5
+ as |function|
6
+ >
7
+ {{function}}
8
+ </PowerSelect>
@@ -0,0 +1,49 @@
1
+ import { inject as service } from "@ember/service";
2
+ import Component from "@glimmer/component";
3
+ import { tracked } from "@glimmer/tracking";
4
+ import { queryManager } from "ember-apollo-client";
5
+ import { task } from "ember-concurrency";
6
+ import { trackedTask } from "ember-resources/util/ember-concurrency";
7
+
8
+ import getAvailableFieldsForFieldQuery from "@projectcaluma/ember-analytics/gql/queries/get-available-fields-for-field.graphql";
9
+
10
+ export default class CaFieldSelectorListCaFieldFunctionSelectComponent extends Component {
11
+ @queryManager apollo;
12
+ @service notification;
13
+ @service intl;
14
+
15
+ @tracked aggregationFunctions = trackedTask(
16
+ this,
17
+ this.getAggregationFunctions,
18
+ () => [this.args.field, this.args.tableSlug]
19
+ );
20
+
21
+ @task
22
+ *getAggregationFunctions() {
23
+ try {
24
+ // Get the base path without the field so we can fetch the necessary fields later on.
25
+ const pathList = this.args.field.dataSource.split(".");
26
+ const prefix = pathList.slice(0, -1).join(".");
27
+ const options = yield this.apollo.query(
28
+ {
29
+ query: getAvailableFieldsForFieldQuery,
30
+ variables: {
31
+ slug: this.args.tableSlug,
32
+ prefix,
33
+ },
34
+ },
35
+ "analyticsTable.availableFields"
36
+ );
37
+ const fields = options.edges.map((edge) => edge.node);
38
+ const field = fields.find(
39
+ (field) => field.sourcePath === this.args.field.dataSource
40
+ );
41
+ return field?.supportedFunctions ?? [];
42
+ } catch (error) {
43
+ console.error(error);
44
+ this.notification.danger(
45
+ this.intl.t("caluma.analytics.notification.fetch-error")
46
+ );
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,82 @@
1
+ <table class="uk-table uk-table-divider uk-table-hover" uk-overflow-auto>
2
+ <thead>
3
+ <tr>
4
+ <th>{{t "caluma.analytics.edit.question"}}</th>
5
+ <th>{{t "caluma.analytics.edit.display-title"}}</th>
6
+ <th>{{t "caluma.analytics.edit.aggregation"}}</th>
7
+ <th class="uk-text-center">{{t
8
+ "caluma.analytics.edit.show-in-output"
9
+ }}</th>
10
+ <th>{{t "caluma.analytics.edit.filter"}}</th>
11
+ <th></th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ {{#each this.fields as |field|}}
16
+ {{#let (fn this.updateField field) as |update|}}
17
+ <tr>
18
+ <td>
19
+ {{field.dataSource}}
20
+ </td>
21
+ <td>
22
+ <CaFieldSelectorList::CaFieldAliasInput
23
+ @value={{field.alias}}
24
+ @onSave={{fn update "alias"}}
25
+ />
26
+ </td>
27
+ <td>
28
+ <CaFieldSelectorList::CaFieldFunctionSelect
29
+ @field={{field}}
30
+ @tableSlug={{@analyticsTable.slug}}
31
+ @update={{update}}
32
+ />
33
+ </td>
34
+ <td class="uk-flex uk-flex-center uk-flex-middle">
35
+ <UkToggleSwitch
36
+ @value={{field.showOutput}}
37
+ @size="small"
38
+ @onToggle={{fn update "showOutput"}}
39
+ />
40
+ </td>
41
+ <td>
42
+ <CaFilterModal
43
+ @table={{@analyticsTable.id}}
44
+ @field={{field}}
45
+ as |TriggerButton|
46
+ >
47
+ <TriggerButton
48
+ @label={{if
49
+ field.filters.length
50
+ (t
51
+ "caluma.analytics.edit.edit-filters"
52
+ num=field.filters.length
53
+ )
54
+ (t "caluma.analytics.edit.add-filters")
55
+ }}
56
+ />
57
+ </CaFilterModal>
58
+ </td>
59
+ <td>
60
+ <button
61
+ data-test-delete-field
62
+ type="button"
63
+ class="uk-icon-button"
64
+ uk-icon="trash"
65
+ name={{t "caluma.analytics.edit.delete-field"}}
66
+ {{on "click" (perform this.removeAnalyticsField field.id)}}
67
+ >
68
+ <span hidden>{{t "caluma.analytics.edit.delete-field"}}</span>
69
+ </button>
70
+ </td>
71
+ </tr>
72
+ {{/let}}
73
+ {{else}}
74
+ <td colspan="5">
75
+ <h3 class="uk-flex uk-flex-center uk-flex-middle">
76
+ <UkIcon @icon="search" @ratio="1.5" class="uk-margin-small-right" />
77
+ {{t "caluma.analytics.edit.empty"}}
78
+ </h3>
79
+ </td>
80
+ {{/each}}
81
+ </tbody>
82
+ </table>
@@ -0,0 +1,54 @@
1
+ import { action } from "@ember/object";
2
+ import { inject as service } from "@ember/service";
3
+ import Component from "@glimmer/component";
4
+ import { queryManager, getObservable } from "ember-apollo-client";
5
+ import { enqueueTask } from "ember-concurrency";
6
+
7
+ import removeAnalyticsFieldMutation from "@projectcaluma/ember-analytics/gql/mutations/remove-analytics-field.graphql";
8
+ import saveAnalyticsField from "@projectcaluma/ember-analytics/tasks/save-analytics-field";
9
+
10
+ export default class CaFieldSelectorListComponent extends Component {
11
+ @queryManager apollo;
12
+ @service notification;
13
+ @service intl;
14
+
15
+ @enqueueTask saveField = saveAnalyticsField;
16
+
17
+ get fields() {
18
+ return (
19
+ this.args.analyticsTable?.fields?.edges?.map((edge) => edge.node) ?? []
20
+ );
21
+ }
22
+
23
+ @action
24
+ async updateField(field, key, value) {
25
+ const requiredInput = {
26
+ id: field.id,
27
+ alias: field.alias,
28
+ dataSource: field.dataSource,
29
+ function: field.function,
30
+ table: this.args.analyticsTable.id,
31
+ };
32
+ await this.saveField.perform({
33
+ ...requiredInput,
34
+ [key]: value,
35
+ });
36
+ }
37
+
38
+ @enqueueTask
39
+ *removeAnalyticsField(id) {
40
+ try {
41
+ yield this.apollo.mutate({
42
+ mutation: removeAnalyticsFieldMutation,
43
+ variables: { input: { id } },
44
+ });
45
+ const observableQuery = getObservable(this.args.analyticsTable);
46
+ yield observableQuery.refetch();
47
+ } catch (error) {
48
+ console.error(error);
49
+ this.notification.danger(
50
+ this.intl.t("caluma.analytics.notification.delete-error")
51
+ );
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,77 @@
1
+ <UkModal
2
+ @visible={{this.visible}}
3
+ @onHide={{fn (mut this.visible) false}}
4
+ as |modal|
5
+ >
6
+ <modal.header>
7
+ <h2 class="uk-modal-title">{{t
8
+ "caluma.analytics.filter-modal.filters"
9
+ }}</h2>
10
+ </modal.header>
11
+ <modal.body>
12
+
13
+ <div class="uk-flex">
14
+ <input
15
+ class="uk-input"
16
+ type="text"
17
+ placeholder={{t "caluma.analytics.filter-modal.filter-placeholder"}}
18
+ value={{this.newFilter}}
19
+ aria-label={{t "caluma.analytics.filter-modal.filter-placeholder"}}
20
+ {{on "input" this.updateNewFilter}}
21
+ />
22
+
23
+ <UkButton
24
+ @color="primary"
25
+ @disabled={{not this.newFilter}}
26
+ class="uk-flex uk-flex-middle"
27
+ {{on "click" this.addFilter}}
28
+ >
29
+ <UkIcon @icon="plus" @ratio="1.5" />
30
+ </UkButton>
31
+ </div>
32
+
33
+ <UkList
34
+ @divider="true"
35
+ class="uk-padding-small uk-padding-remove-left"
36
+ uk-overflow-auto
37
+ as |List|
38
+ >
39
+ {{#each this.filters as |filter|}}
40
+ <List.item class="uk-flex uk-flex-between uk-flex-middle">
41
+ <span>{{filter}}</span>
42
+ <button
43
+ type="button"
44
+ class="uk-icon-button"
45
+ uk-icon="trash"
46
+ name={{t "caluma.analytics.filter-modal.delete-filter"}}
47
+ {{on "click" (fn this.removeFilter filter)}}
48
+ >
49
+ <span hidden>{{t
50
+ "caluma.analytics.filter-modal.delete-filter"
51
+ }}</span>
52
+ </button>
53
+ </List.item>
54
+ {{else}}
55
+ <List.item>{{t "caluma.analytics.filter-modal.empty"}}</List.item>
56
+ {{/each}}
57
+ <List.item />
58
+ </UkList>
59
+ </modal.body>
60
+ <modal.footer class="uk-flex uk-flex-between">
61
+ <UkButton
62
+ @label={{t "caluma.analytics.cancel"}}
63
+ @onClick={{fn (mut this.visible) false}}
64
+ />
65
+ <UkButton
66
+ @color="primary"
67
+ @onClick={{perform this.saveField this.graphqlInput}}
68
+ @loading={{this.saveField.isRunning}}
69
+ @label={{t "caluma.analytics.save"}}
70
+ />
71
+ </modal.footer>
72
+ </UkModal>
73
+ {{yield
74
+ (component
75
+ (ensure-safe-component "uk-button") onClick=(fn (mut this.visible) true)
76
+ )
77
+ }}