aloha-vue 2.64.0 → 2.65.0

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.
@@ -0,0 +1,101 @@
1
+ import {
2
+ computed,
3
+ reactive,
4
+ } from "vue";
5
+ import {
6
+ describe,
7
+ expect,
8
+ it,
9
+ } from "@jest/globals";
10
+
11
+ import SelectedFirstAPI from "../compositionAPI/SelectedFirstAPI";
12
+
13
+ import {
14
+ AKeyId,
15
+ } from "../../../const/AKeys";
16
+
17
+ const item = (id, label, extra = {}) => ({
18
+ [AKeyId]: id,
19
+ _a_label: label,
20
+ ...extra,
21
+ });
22
+
23
+ describe("ASelect SelectedFirstAPI", () => {
24
+ it("keeps source order and removes selected values from all source lists", () => {
25
+ const props = reactive({
26
+ modelValue: [3, 1, 3, "exclusive"],
27
+ showSelectedFirst: true,
28
+ type: "multiselect",
29
+ });
30
+ const data = computed(() => [
31
+ item(1, "One", { group: "A" }),
32
+ item(2, "Two", { group: "A" }),
33
+ item(3, "Three", { __invalidEntry__: true, group: "B" }),
34
+ ]);
35
+ const dataExtra = computed(() => [item(1, "Extra one"), item(4, "Four")]);
36
+ const exclusiveOption = computed(() => item("exclusive", "Exclusive"));
37
+
38
+ const result = SelectedFirstAPI(props, {
39
+ data,
40
+ dataExtra,
41
+ exclusiveOption,
42
+ });
43
+
44
+ expect(result.dataSelected.value.map(currentItem => currentItem[AKeyId]))
45
+ .toEqual(["exclusive", 1, 3]);
46
+ expect(result.dataSelected.value[2]).toEqual(expect.objectContaining({
47
+ __invalidEntry__: true,
48
+ group: "B",
49
+ }));
50
+ expect(result.dataWithoutSelected.value.map(currentItem => currentItem[AKeyId]))
51
+ .toEqual([2]);
52
+ expect(result.dataExtraWithoutSelected.value.map(currentItem => currentItem[AKeyId]))
53
+ .toEqual([4]);
54
+ expect(result.exclusiveOptionWithoutSelected.value).toBeUndefined();
55
+ });
56
+
57
+ it("reuses the sorted data order instead of the model order", () => {
58
+ const props = reactive({
59
+ modelValue: [1, 3],
60
+ showSelectedFirst: true,
61
+ type: "multiselect",
62
+ });
63
+ const data = computed(() => [item(3, "Three"), item(2, "Two"), item(1, "One")]);
64
+
65
+ const result = SelectedFirstAPI(props, { data });
66
+
67
+ expect(result.dataSelected.value.map(currentItem => currentItem[AKeyId]))
68
+ .toEqual([3, 1]);
69
+ });
70
+
71
+ it("supports false as a selected value in select mode", () => {
72
+ const props = reactive({
73
+ modelValue: false,
74
+ showSelectedFirst: true,
75
+ type: "select",
76
+ });
77
+ const data = computed(() => [item(false, "No"), item(true, "Yes")]);
78
+
79
+ const result = SelectedFirstAPI(props, { data });
80
+
81
+ expect(result.dataSelected.value.map(currentItem => currentItem[AKeyId]))
82
+ .toEqual([false]);
83
+ expect(result.dataWithoutSelected.value.map(currentItem => currentItem[AKeyId]))
84
+ .toEqual([true]);
85
+ });
86
+
87
+ it("does not change lists when the prop is disabled", () => {
88
+ const props = reactive({
89
+ modelValue: [1],
90
+ showSelectedFirst: false,
91
+ type: "multiselect",
92
+ });
93
+ const sourceData = [item(1, "One"), item(2, "Two")];
94
+ const data = computed(() => sourceData);
95
+
96
+ const result = SelectedFirstAPI(props, { data });
97
+
98
+ expect(result.dataSelected.value).toEqual([]);
99
+ expect(result.dataWithoutSelected.value).toBe(sourceData);
100
+ });
101
+ });
@@ -0,0 +1,98 @@
1
+ import {
2
+ ref,
3
+ } from "vue";
4
+ import {
5
+ describe,
6
+ expect,
7
+ it,
8
+ } from "@jest/globals";
9
+
10
+ import SelectedVisibleAPI from "../compositionAPI/SelectedVisibleAPI";
11
+
12
+ import {
13
+ AKeyId,
14
+ } from "../../../const/AKeys";
15
+
16
+ const item = (id, label, extra = {}) => ({
17
+ [AKeyId]: id,
18
+ _a_label: label,
19
+ ...extra,
20
+ });
21
+
22
+ describe("ASelect SelectedVisibleAPI", () => {
23
+ it("filters selected values using matches from all data sources", () => {
24
+ const dataSelected = ref([
25
+ item(1, "Apple"),
26
+ item(2, "Banana"),
27
+ item(3, "Carrot"),
28
+ ]);
29
+
30
+ const {
31
+ dataSelectedVisible,
32
+ } = SelectedVisibleAPI({
33
+ dataSelected,
34
+ searching: ref(true),
35
+ searchingElements: ref({ 2: true }),
36
+ searchingElementsExtra: ref({ 3: true }),
37
+ });
38
+
39
+ expect(dataSelectedVisible.value.map(currentItem => currentItem[AKeyId]))
40
+ .toEqual([2, 3]);
41
+ });
42
+
43
+ it("includes selected values when their nested group matches", () => {
44
+ const dataSelected = ref([
45
+ item(1, "Apple", { category: "Food", group: "Fruit" }),
46
+ item(2, "Carrot", { category: "Food", group: "Vegetables" }),
47
+ ]);
48
+
49
+ const {
50
+ dataSelectedVisible,
51
+ searchingGroupsVisible,
52
+ } = SelectedVisibleAPI({
53
+ dataSelected,
54
+ keyGroupArray: ref(["category", "group"]),
55
+ searching: ref(true),
56
+ searchingGroupsWithSearchInGroup: ref({ Food_Fruit: true }),
57
+ });
58
+
59
+ expect(dataSelectedVisible.value.map(currentItem => currentItem[AKeyId]))
60
+ .toEqual([1]);
61
+ expect(searchingGroupsVisible.value).toEqual({
62
+ Food: true,
63
+ Food_Fruit: true,
64
+ });
65
+ });
66
+
67
+ it("does not expose a group matched only in another section", () => {
68
+ const dataSelected = ref([
69
+ item(2, "Banana", { group: "Fruit" }),
70
+ ]);
71
+
72
+ const {
73
+ dataSelectedVisible,
74
+ searchingGroupsVisible,
75
+ } = SelectedVisibleAPI({
76
+ dataSelected,
77
+ keyGroupArray: ref(["group"]),
78
+ searching: ref(true),
79
+ searchingElements: ref({ 1: true }),
80
+ });
81
+
82
+ expect(dataSelectedVisible.value).toEqual([]);
83
+ expect(searchingGroupsVisible.value).toEqual({});
84
+ });
85
+
86
+ it("returns all selected values when search is inactive", () => {
87
+ const dataSelected = ref([item(1, "Apple"), item(2, "Banana")]);
88
+
89
+ const {
90
+ dataSelectedVisible,
91
+ } = SelectedVisibleAPI({
92
+ dataSelected,
93
+ searching: ref(false),
94
+ });
95
+
96
+ expect(dataSelectedVisible.value).toBe(dataSelected.value);
97
+ });
98
+ });
@@ -0,0 +1,78 @@
1
+ import {
2
+ computed,
3
+ toRef,
4
+ } from "vue";
5
+
6
+ import {
7
+ AKeyId,
8
+ } from "../../../const/AKeys";
9
+ import {
10
+ isArray,
11
+ isNil,
12
+ } from "lodash-es";
13
+
14
+ export default function SelectedFirstAPI(props, {
15
+ data = computed(() => []),
16
+ dataExtra = computed(() => []),
17
+ exclusiveOption = computed(() => undefined),
18
+ }) {
19
+ const modelValue = toRef(props, "modelValue");
20
+ const showSelectedFirst = toRef(props, "showSelectedFirst");
21
+ const type = toRef(props, "type");
22
+
23
+ const selectedValues = computed(() => {
24
+ if (!showSelectedFirst.value || isNil(modelValue.value)) {
25
+ return [];
26
+ }
27
+
28
+ if (type.value === "multiselect") {
29
+ return isArray(modelValue.value) ? [...new Set(modelValue.value)] : [];
30
+ }
31
+
32
+ return [modelValue.value];
33
+ });
34
+
35
+ const selectedValuesSet = computed(() => new Set(selectedValues.value));
36
+
37
+ const dataSelected = computed(() => {
38
+ const ADDED_VALUES = new Set();
39
+
40
+ return [exclusiveOption.value, ...dataExtra.value, ...data.value]
41
+ .filter(item => {
42
+ if (!item ||
43
+ !selectedValuesSet.value.has(item[AKeyId]) ||
44
+ ADDED_VALUES.has(item[AKeyId])) {
45
+ return false;
46
+ }
47
+
48
+ ADDED_VALUES.add(item[AKeyId]);
49
+ return true;
50
+ });
51
+ });
52
+
53
+ const filterSelected = currentData => {
54
+ if (!showSelectedFirst.value || !selectedValuesSet.value.size) {
55
+ return currentData;
56
+ }
57
+
58
+ return currentData.filter(item => !selectedValuesSet.value.has(item[AKeyId]));
59
+ };
60
+
61
+ const dataWithoutSelected = computed(() => filterSelected(data.value));
62
+ const dataExtraWithoutSelected = computed(() => filterSelected(dataExtra.value));
63
+ const exclusiveOptionWithoutSelected = computed(() => {
64
+ if (!exclusiveOption.value ||
65
+ !selectedValuesSet.value.has(exclusiveOption.value[AKeyId])) {
66
+ return exclusiveOption.value;
67
+ }
68
+
69
+ return undefined;
70
+ });
71
+
72
+ return {
73
+ dataExtraWithoutSelected,
74
+ dataSelected,
75
+ dataWithoutSelected,
76
+ exclusiveOptionWithoutSelected,
77
+ };
78
+ }
@@ -0,0 +1,76 @@
1
+ import {
2
+ computed,
3
+ } from "vue";
4
+
5
+ import {
6
+ AKeyId,
7
+ } from "../../../const/AKeys";
8
+ import {
9
+ get,
10
+ isNil,
11
+ } from "lodash-es";
12
+
13
+ export default function SelectedVisibleAPI({
14
+ dataSelected = computed(() => []),
15
+ keyGroupArray = computed(() => []),
16
+ searching = computed(() => false),
17
+ searchingElements = computed(() => ({})),
18
+ searchingElementsExclusive = computed(() => ({})),
19
+ searchingElementsExtra = computed(() => ({})),
20
+ searchingGroupsWithSearchInGroup = computed(() => ({})),
21
+ } = {}) {
22
+ const searchingElementsSelected = computed(() => ({
23
+ ...searchingElements.value,
24
+ ...searchingElementsExtra.value,
25
+ ...searchingElementsExclusive.value,
26
+ }));
27
+
28
+ const dataSelectedVisible = computed(() => {
29
+ if (!searching.value) {
30
+ return dataSelected.value;
31
+ }
32
+
33
+ return dataSelected.value.filter(item => {
34
+ if (searchingElementsSelected.value[item[AKeyId]]) {
35
+ return true;
36
+ }
37
+
38
+ let allGroupKeys = "";
39
+ return keyGroupArray.value.some(keyGroup => {
40
+ let group = get(item, keyGroup);
41
+ if (isNil(group) || group === "") {
42
+ group = "_not_grouped";
43
+ }
44
+ allGroupKeys += `${ allGroupKeys ? "_" : "" }${ group }`;
45
+ return searchingGroupsWithSearchInGroup.value[allGroupKeys];
46
+ });
47
+ });
48
+ });
49
+
50
+ const searchingGroupsVisible = computed(() => {
51
+ if (!searching.value) {
52
+ return {};
53
+ }
54
+
55
+ const GROUPS_VISIBLE = {};
56
+ dataSelectedVisible.value.forEach(item => {
57
+ let allGroupKeys = "";
58
+ keyGroupArray.value.forEach(keyGroup => {
59
+ let group = get(item, keyGroup);
60
+ if (isNil(group) || group === "") {
61
+ group = "_not_grouped";
62
+ }
63
+ allGroupKeys += `${ allGroupKeys ? "_" : "" }${ group }`;
64
+ GROUPS_VISIBLE[allGroupKeys] = true;
65
+ });
66
+ });
67
+
68
+ return GROUPS_VISIBLE;
69
+ });
70
+
71
+ return {
72
+ dataSelectedVisible,
73
+ searchingElementsSelected,
74
+ searchingGroupsVisible,
75
+ };
76
+ }