aloha-vue 1.2.85 → 1.2.87

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.
@@ -5,10 +5,13 @@ import PageFilterEmailExample from "./PageFilterEmailExample/PageFilterEmailExam
5
5
  import PageFilterEmailLinkClass from "./PageFilterEmailLinkClass/PageFilterEmailLinkClass.vue";
6
6
  import PageFilterImportCompositionApi from "../Components/PageFilterImportCompositionApi/PageFilterImportCompositionApi.vue";
7
7
  import PageFilterImportFunction from "../Components/PageFilterImportFunction/PageFilterImportFunction.vue";
8
+ import PageFilterTest from "../Components/PageFilterTest/PageFilterTest.vue";
8
9
 
9
10
  import ArgumentsAPI from "./compositionAPI/ArgumentsAPI";
10
11
  import PageTitleAPI from "./compositionAPI/PageTitleAPI";
11
12
 
13
+ import filterEmailTest from "../../../../../src/filters/__tests__/filterEmail.test.js?raw";
14
+
12
15
  export default {
13
16
  name: "PageFilterEmail",
14
17
  components: {
@@ -19,6 +22,7 @@ export default {
19
22
  PageFilterEmailLinkClass,
20
23
  PageFilterImportCompositionApi,
21
24
  PageFilterImportFunction,
25
+ PageFilterTest,
22
26
  },
23
27
  setup() {
24
28
  const {
@@ -29,9 +33,12 @@ export default {
29
33
  argumentsText,
30
34
  } = ArgumentsAPI();
31
35
 
36
+ const test = filterEmailTest;
37
+
32
38
  return {
33
39
  argumentsText,
34
40
  pageTitle,
41
+ test,
35
42
  };
36
43
  },
37
44
  };
@@ -26,3 +26,6 @@ aloha-page(
26
26
 
27
27
  page-filter-email-link-class
28
28
 
29
+ page-filter-test(
30
+ :test="test"
31
+ )
@@ -4,10 +4,13 @@ import PageFilterArguments from "../Components/PageFilterArguments/PageFilterArg
4
4
  import PageFilterImportCompositionApi from "../Components/PageFilterImportCompositionApi/PageFilterImportCompositionApi.vue";
5
5
  import PageFilterImportFunction from "../Components/PageFilterImportFunction/PageFilterImportFunction.vue";
6
6
  import PageFilterKeyValueExample from "./PageFilterKeyValueExample/PageFilterKeyValueExample.vue";
7
+ import PageFilterTest from "../Components/PageFilterTest/PageFilterTest.vue";
7
8
 
8
9
  import ArgumentsAPI from "./compositionAPI/ArgumentsAPI";
9
10
  import PageTitleAPI from "./compositionAPI/PageTitleAPI";
10
11
 
12
+ import filterKeyValueTest from "../../../../../src/filters/__tests__/filterKeyValue.test.js?raw";
13
+
11
14
  export default {
12
15
  name: "PageFilterKeyValue",
13
16
  components: {
@@ -17,6 +20,7 @@ export default {
17
20
  PageFilterImportCompositionApi,
18
21
  PageFilterImportFunction,
19
22
  PageFilterKeyValueExample,
23
+ PageFilterTest,
20
24
  },
21
25
  setup() {
22
26
  const {
@@ -27,9 +31,12 @@ export default {
27
31
  argumentsText,
28
32
  } = ArgumentsAPI();
29
33
 
34
+ const test = filterKeyValueTest;
35
+
30
36
  return {
31
37
  argumentsText,
32
38
  pageTitle,
39
+ test,
33
40
  };
34
41
  },
35
42
  };
@@ -23,3 +23,7 @@ aloha-page(
23
23
  )
24
24
 
25
25
  page-filter-key-value-example
26
+
27
+ page-filter-test(
28
+ :test="test"
29
+ )
@@ -5,10 +5,13 @@ import PageFilterImportCompositionApi from "../Components/PageFilterImportCompos
5
5
  import PageFilterImportFunction from "../Components/PageFilterImportFunction/PageFilterImportFunction.vue";
6
6
  import PageFilterLimitToLimit from "./PageFilterLimitToLimit/PageFilterLimitToLimit.vue";
7
7
  import PageFilterLimitToMaxThreeDots from "./PageFilterLimitToMaxThreeDots/PageFilterLimitToMaxThreeDots.vue";
8
+ import PageFilterTest from "../Components/PageFilterTest/PageFilterTest.vue";
8
9
 
9
10
  import ArgumentsAPI from "./compositionAPI/ArgumentsAPI";
10
11
  import PageTitleAPI from "./compositionAPI/PageTitleAPI";
11
12
 
13
+ import filterLimitToTest from "../../../../../src/filters/__tests__/filterLimitTo.test.js?raw";
14
+
12
15
  export default {
13
16
  name: "PageFilterLimitTo",
14
17
  components: {
@@ -19,6 +22,7 @@ export default {
19
22
  PageFilterImportFunction,
20
23
  PageFilterLimitToLimit,
21
24
  PageFilterLimitToMaxThreeDots,
25
+ PageFilterTest,
22
26
  },
23
27
  setup() {
24
28
  const {
@@ -29,9 +33,12 @@ export default {
29
33
  argumentsText,
30
34
  } = ArgumentsAPI();
31
35
 
36
+ const test = filterLimitToTest;
37
+
32
38
  return {
33
39
  argumentsText,
34
40
  pageTitle,
41
+ test,
35
42
  };
36
43
  },
37
44
  };
@@ -26,3 +26,6 @@ aloha-page(
26
26
 
27
27
  page-filter-limit-to-max-three-dots
28
28
 
29
+ page-filter-test(
30
+ :test="test"
31
+ )
@@ -8,10 +8,13 @@ import PageFilterLinkLinkClass from "./PageFilterLinkLinkClass/PageFilterLinkLin
8
8
  import PageFilterLinkLinkText from "./PageFilterLinkLinkText/PageFilterLinkLinkText.vue";
9
9
  import PageFilterLinkProtocol from "./PageFilterLinkProtocol/PageFilterLinkProtocol.vue";
10
10
  import PageFilterLinkTarget from "./PageFilterLinkTarget/PageFilterLinkTarget.vue";
11
+ import PageFilterTest from "../Components/PageFilterTest/PageFilterTest.vue";
11
12
 
12
13
  import ArgumentsAPI from "./compositionAPI/ArgumentsAPI";
13
14
  import PageTitleAPI from "./compositionAPI/PageTitleAPI";
14
15
 
16
+ import filterLinkTest from "../../../../../src/filters/__tests__/filterLink.test.js?raw";
17
+
15
18
  export default {
16
19
  name: "PageFilterLink",
17
20
  components: {
@@ -25,6 +28,7 @@ export default {
25
28
  PageFilterLinkLinkText,
26
29
  PageFilterLinkProtocol,
27
30
  PageFilterLinkTarget,
31
+ PageFilterTest,
28
32
  },
29
33
  setup() {
30
34
  const {
@@ -35,9 +39,12 @@ export default {
35
39
  argumentsText,
36
40
  } = ArgumentsAPI();
37
41
 
42
+ const test = filterLinkTest;
43
+
38
44
  return {
39
45
  argumentsText,
40
46
  pageTitle,
47
+ test,
41
48
  };
42
49
  },
43
50
  };
@@ -31,3 +31,7 @@ aloha-page(
31
31
  page-filter-link-target
32
32
 
33
33
  page-filter-link-link-class
34
+
35
+ page-filter-test(
36
+ :test="test"
37
+ )
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "Vue.js"
15
15
  ],
16
16
  "homepage": "https://github.com/ilia-brykin/aloha/#README.md",
17
- "version": "1.2.85",
17
+ "version": "1.2.87",
18
18
  "author": {
19
19
  "name": "Ilia Brykin",
20
20
  "email": "brykin.ilia@gmail.com"
@@ -18,12 +18,20 @@ export default function FilterSpecificTypeAPI(props) {
18
18
 
19
19
  const filterSpecificAttributes = computed(() => {
20
20
  const ATTRIBUTES = {};
21
- if (typesMapInputNumberRange[filter.value.type] || typesMapDatepickerRange[filter.value.type]) {
21
+ const IS_NUMBER_RANGE = typesMapInputNumberRange[filter.value.type];
22
+ const IS_DATEPICKER_RANGE = typesMapDatepickerRange[filter.value.type];
23
+ if (IS_NUMBER_RANGE || IS_DATEPICKER_RANGE) {
22
24
  if (isUndefined(filter.value.inputWidth)) {
23
25
  ATTRIBUTES.inputWidth = "auto";
24
26
  }
25
27
  }
26
28
 
29
+ if (IS_DATEPICKER_RANGE) {
30
+ ATTRIBUTES.inputAttributes = {
31
+ style: "min-width: 181px",
32
+ };
33
+ }
34
+
27
35
  return ATTRIBUTES;
28
36
  });
29
37
 
@@ -0,0 +1,36 @@
1
+ import filterEmail from "../filterEmail";
2
+
3
+ describe("filterEmail", () => {
4
+ test("basic email", () => {
5
+ expect(filterEmail("user@aloha.com")).toBe("<a href=\"mailto:user@aloha.com\">user@aloha.com</a>");
6
+ });
7
+
8
+ test("email with CSS class", () => {
9
+ expect(filterEmail("contact@aloha.com", { linkClass: "email-link" })).toBe("<a href=\"mailto:contact@aloha.com\" class=\"email-link\">contact@aloha.com</a>");
10
+ });
11
+
12
+ test("empty email", () => {
13
+ expect(filterEmail("")).toBe("");
14
+ });
15
+
16
+ test("null email", () => {
17
+ expect(filterEmail(null)).toBe("");
18
+ });
19
+
20
+ test("undefined email", () => {
21
+ expect(filterEmail(undefined)).toBe("");
22
+ });
23
+
24
+ test("numeric value (invalid email)", () => {
25
+ expect(filterEmail(12345)).toBe("");
26
+ });
27
+
28
+ test("email with special characters", () => {
29
+ expect(filterEmail("name.surname+filter@company.org")).toBe("<a href=\"mailto:name.surname+filter@company.org\">name.surname+filter@company.org</a>");
30
+ });
31
+
32
+ test("email with combined class attribute", () => {
33
+ expect(filterEmail("hr@enterprise.net", { linkClass: "external contact" })).toBe("<a href=\"mailto:hr@enterprise.net\" class=\"external contact\">hr@enterprise.net</a>");
34
+ });
35
+ });
36
+
@@ -0,0 +1,44 @@
1
+ import filterKeyValue from "../filterKeyValue";
2
+
3
+ describe("filterKeyValue", () => {
4
+ test("single key-value pair", () => {
5
+ expect(filterKeyValue({ greeting: "aloha" })).toBe("greeting: aloha");
6
+ });
7
+
8
+ test("multiple key-value pairs", () => {
9
+ expect(filterKeyValue({ greeting: "aloha", farewell: "aloha" })).toBe("greeting: aloha, farewell: aloha");
10
+ });
11
+
12
+ test("empty object", () => {
13
+ expect(filterKeyValue({})).toBe("");
14
+ });
15
+
16
+ test("null input", () => {
17
+ expect(filterKeyValue(null)).toBe("");
18
+ });
19
+
20
+ test("undefined input", () => {
21
+ expect(filterKeyValue(undefined)).toBe("");
22
+ });
23
+
24
+ test("numeric and string values", () => {
25
+ expect(filterKeyValue({ alohaCount: 3, message: "aloha" })).toBe("alohaCount: 3, message: aloha");
26
+ });
27
+
28
+ test("nested object", () => {
29
+ expect(filterKeyValue({ level1: { greeting: "aloha" } })).toBe("level1: [object Object]");
30
+ });
31
+
32
+ test("object with array values", () => {
33
+ expect(filterKeyValue({ alohas: ["aloha", "hello", "hi"] })).toBe("alohas: aloha,hello,hi");
34
+ });
35
+
36
+ test("object with boolean and null values", () => {
37
+ expect(filterKeyValue({ isActive: true, isEmpty: null })).toBe("isActive: true, isEmpty: null");
38
+ });
39
+
40
+ test("complex object", () => {
41
+ expect(filterKeyValue({ greeting: "aloha", number: 42, nested: { key: "value" }, list: [1, 2, 3] }))
42
+ .toBe("greeting: aloha, number: 42, nested: [object Object], list: 1,2,3");
43
+ });
44
+ });
@@ -0,0 +1,33 @@
1
+ import filterLimitTo from "../filterLimitTo";
2
+
3
+ describe("filterLimitTo", () => {
4
+ test("text exactly at limit", () => {
5
+ expect(filterLimitTo("Lorem ipsum dolor sit amet, cons", { limit: 30 })).toBe("Lorem ipsum dolor sit amet, co...");
6
+ });
7
+
8
+ test("long text exceeding limit", () => {
9
+ expect(filterLimitTo("Lorem ipsum dolor sit amet, consectetur adipiscing elit", { limit: 30 })).toBe("Lorem ipsum dolor sit amet, co...");
10
+ });
11
+
12
+ test("text ending with a period", () => {
13
+ expect(filterLimitTo("Lorem ipsum dolor sit amet.", { limit: 30 })).toBe("Lorem ipsum dolor sit amet.");
14
+ });
15
+
16
+ test("text with multiple periods at the end", () => {
17
+ expect(filterLimitTo("Lorem ipsum dolor sit amet...", { limit: 30 })).toBe("Lorem ipsum dolor sit amet...");
18
+ });
19
+
20
+ test("numeric value treated as text", () => {
21
+ expect(filterLimitTo(1234567890, { limit: 10 })).toBe("1234567890");
22
+ expect(filterLimitTo(1234567890, { limit: 9 })).toBe("123456789...");
23
+ });
24
+
25
+ test("null value", () => {
26
+ expect(filterLimitTo(null, { limit: 30 })).toBe("");
27
+ });
28
+
29
+ test("maxThreeDots false", () => {
30
+ expect(filterLimitTo("Lorem ipsum dolor sit amet, c..", { limit: 30, maxThreeDots: false })).toBe("Lorem ipsum dolor sit amet, c....");
31
+ expect(filterLimitTo("Lorem ipsum dolor sit ame, c...", { limit: 30, maxThreeDots: false })).toBe("Lorem ipsum dolor sit ame, c.....");
32
+ });
33
+ });
@@ -0,0 +1,35 @@
1
+ import filterLink from "../filterLink";
2
+
3
+ describe("filterLink", () => {
4
+ test("default behavior", () => {
5
+ expect(filterLink("example.com")).toBe("<a href=\"https://example.com\">example.com</a>");
6
+ expect(filterLink("http://example.com")).toBe("<a href=\"http://example.com\">http://example.com</a>");
7
+ });
8
+
9
+ test("with linkText", () => {
10
+ expect(filterLink("example.com", { linkText: "Example" })).toBe("<a href=\"https://example.com\">Example</a>");
11
+ });
12
+
13
+ test("with protocol", () => {
14
+ expect(filterLink("example.com", { protocol: "http://" })).toBe("<a href=\"http://example.com\">example.com</a>");
15
+ });
16
+
17
+ test("with target", () => {
18
+ expect(filterLink("example.com", { target: "_blank" })).toBe("<a href=\"https://example.com\" target=\"_blank\">example.com</a>");
19
+ });
20
+
21
+ test("with linkClass", () => {
22
+ expect(filterLink("example.com", { linkClass: "custom-class" })).toBe("<a href=\"https://example.com\" class=\"custom-class\">example.com</a>");
23
+ });
24
+
25
+ test("invalid URL", () => {
26
+ expect(filterLink(null)).toBe("");
27
+ expect(filterLink(undefined)).toBe("");
28
+ expect(filterLink(123)).toBe("");
29
+ });
30
+
31
+ test("combined options", () => {
32
+ expect(filterLink("example.com", { linkText: "Example", target: "_blank", linkClass: "custom-class" }))
33
+ .toBe("<a href=\"https://example.com\" target=\"_blank\" class=\"custom-class\">Example</a>");
34
+ });
35
+ });
@@ -1,9 +1,13 @@
1
1
  import {
2
2
  isNil,
3
+ isString,
3
4
  } from "lodash-es";
4
5
 
5
6
  export default function(value, { linkClass } = {}) {
6
- if (isNil(value) || value === "") {
7
+ if (isNil(value) ||
8
+ value === "" ||
9
+ !isString(value) ||
10
+ !/^\S+@\S+\.\S+$/.test(value)) {
7
11
  return "";
8
12
  }
9
13
  let classAttribut = "";
@@ -29,6 +29,22 @@
29
29
  .a_select__search {
30
30
  margin-bottom: 10px;
31
31
  }
32
+ .a_select__search__group {
33
+ display: flex;
34
+ width: 100%;
35
+ & > div {
36
+ width: 100%;
37
+ .a_form_control {
38
+ border-top-right-radius: 0;
39
+ border-bottom-right-radius: 0;
40
+ }
41
+ }
42
+ & > button {
43
+ border-top-left-radius: 0;
44
+ border-bottom-left-radius: 0;
45
+ white-space: nowrap;
46
+ }
47
+ }
32
48
 
33
49
  .a_select_menu {
34
50
  --a_select_divider_margin_y: 0.5rem;
@@ -5,6 +5,7 @@ import {
5
5
  } from "vue";
6
6
 
7
7
  import AButton from "../../AButton/AButton";
8
+ import ACloak from "../../ACloak/ACloak";
8
9
  import ACheckboxRadioGroup from "../ACheckboxRadioGroups/ACheckboxRadioGroups";
9
10
  import AErrorsText from "../AErrorsText/AErrorsText";
10
11
  import AFormHelpText from "../AFormHelpText/AFormHelpText";
@@ -703,7 +704,7 @@ export default {
703
704
  onSubmit: this.onSearchOutside,
704
705
  }, [
705
706
  h("div", {
706
- class: "input-group",
707
+ class: "a_select__search__group",
707
708
  }, [
708
709
  h(AInput, {
709
710
  label: "_A_SELECT_SEARCH_",
@@ -718,6 +719,7 @@ export default {
718
719
  class: "a_btn a_btn_primary a_select__element_clickable",
719
720
  type: "submit",
720
721
  iconLeft: "Search",
722
+ loadingAlign: "left",
721
723
  }),
722
724
  ]),
723
725
  ]),
@@ -776,6 +778,9 @@ export default {
776
778
  class: "a_select__divider",
777
779
  ariaHidden: true,
778
780
  }),
781
+ (this.loadingLocal || this.loadingSearchApi) ?
782
+ h(ACloak) :
783
+ "",
779
784
  this.hasDataExtra && h("div", {}, [
780
785
  ...this.dataExtraLocal.map((item, itemIndex) => {
781
786
  return h(ASelectElement, {
@@ -153,7 +153,7 @@ export default function UiDataFromServerAPI(props, {
153
153
  url: url.value,
154
154
  params: {
155
155
  ...(urlParams.value || {}),
156
- searchApiKey: search,
156
+ [searchApiKey.value]: search,
157
157
  },
158
158
  }).then(
159
159
  response => {
@@ -174,6 +174,7 @@ export default function UiDataFromServerAPI(props, {
174
174
  !modelArrayWithoutDataExtra.value.length) {
175
175
  return;
176
176
  }
177
+ loadingDataFromServer.value = true;
177
178
  const URL_PARAMS = {
178
179
  ...urlParams.value,
179
180
  ...{
@@ -188,7 +189,9 @@ export default function UiDataFromServerAPI(props, {
188
189
  response => {
189
190
  dataFromServer.value = response || [];
190
191
  }
191
- );
192
+ ).finally(() => {
193
+ loadingDataFromServer.value = false;
194
+ });
192
195
  };
193
196
 
194
197
  return {