glib-web 4.44.6 → 5.0.4

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 (98) hide show
  1. package/.github/workflows/lint.yml +2 -2
  2. package/.nycrc.json +3 -1
  3. package/README.md +9 -1
  4. package/agent/commands/generate_test.yaml +5 -5
  5. package/components/charts/series.js +23 -11
  6. package/components/component.vue +0 -5
  7. package/components/fields/checkGroup.vue +14 -7
  8. package/components/fields/richText2.vue +33 -3
  9. package/components/fields/upload.vue +5 -3
  10. package/components/mixins/styles.js +0 -1
  11. package/components/popover.vue +107 -78
  12. package/cypress/component/{inputUpload.cy.ts → inputUpload.cy.js} +3 -3
  13. package/cypress/component/{multiUpload.cy.ts → multiUpload.cy.js} +3 -3
  14. package/cypress/component/{placeholderUpload.cy.ts → placeholderUpload.cy.js} +3 -3
  15. package/cypress/component/{testUtils.ts → testUtils.js} +3 -15
  16. package/cypress/e2e/glib-web/{auth.cy.ts → auth.cy.js} +22 -1
  17. package/cypress/e2e/glib-web/{autoValidate.cy.ts → autoValidate.cy.js} +1 -1
  18. package/cypress/e2e/glib-web/{browsers.cy.ts → browsers.cy.js} +1 -1
  19. package/cypress/e2e/glib-web/{calendar.cy.ts → calendar.cy.js} +1 -1
  20. package/cypress/e2e/glib-web/{calendarEmptyData.cy.ts → calendarEmptyData.cy.js} +1 -1
  21. package/cypress/e2e/glib-web/{carousel.cy.ts → carousel.cy.js} +1 -1
  22. package/cypress/e2e/glib-web/{charts.cy.ts → charts.cy.js} +1 -1
  23. package/cypress/e2e/glib-web/{column.cy.ts → column.cy.js} +1 -1
  24. package/cypress/e2e/glib-web/{commands.cy.ts → commands.cy.js} +1 -1
  25. package/cypress/e2e/glib-web/{components.cy.ts → components.cy.js} +1 -1
  26. package/cypress/e2e/glib-web/{cookies.cy.ts → cookies.cy.js} +1 -1
  27. package/cypress/e2e/glib-web/{custom.cy.ts → custom.cy.js} +1 -1
  28. package/cypress/e2e/glib-web/dialog.cy.js +63 -0
  29. package/cypress/e2e/glib-web/{dialogOpen.cy.ts → dialogOpen.cy.js} +1 -1
  30. package/cypress/e2e/glib-web/{dirtyState.cy.ts → dirtyState.cy.js} +9 -24
  31. package/cypress/e2e/glib-web/{display.cy.ts → display.cy.js} +1 -1
  32. package/cypress/e2e/glib-web/{fields.cy.ts → fields.cy.js} +1 -1
  33. package/cypress/e2e/glib-web/{fieldsCaptcha.cy.ts → fieldsCaptcha.cy.js} +1 -1
  34. package/cypress/e2e/glib-web/fieldsCreditCard.cy.js +22 -0
  35. package/cypress/e2e/glib-web/fieldsDateTime.cy.js +48 -0
  36. package/cypress/e2e/glib-web/{fieldsDynamicSelect.cy.ts → fieldsDynamicSelect.cy.js} +1 -1
  37. package/cypress/e2e/glib-web/fieldsLocation.cy.js +40 -0
  38. package/cypress/e2e/glib-web/fieldsOtp.cy.js +68 -0
  39. package/cypress/e2e/glib-web/fieldsPhone.cy.js +87 -0
  40. package/cypress/e2e/glib-web/fieldsRating.cy.js +91 -0
  41. package/cypress/e2e/glib-web/fieldsRichText.cy.js +136 -0
  42. package/cypress/e2e/glib-web/{fieldsSelect.cy.ts → fieldsSelect.cy.js} +1 -1
  43. package/cypress/e2e/glib-web/{fieldsSign.cy.ts → fieldsSign.cy.js} +1 -1
  44. package/cypress/e2e/glib-web/fieldsStripeToken.cy.js +47 -0
  45. package/cypress/e2e/glib-web/{fieldsTimer.cy.ts → fieldsTimer.cy.js} +1 -1
  46. package/cypress/e2e/glib-web/fieldsUpload.cy.js +159 -0
  47. package/cypress/e2e/glib-web/{fieldsUrlFragment.cy.ts → fieldsUrlFragment.cy.js} +1 -1
  48. package/cypress/e2e/glib-web/{flow.cy.ts → flow.cy.js} +1 -1
  49. package/cypress/e2e/glib-web/{form.cy.ts → form.cy.js} +1 -1
  50. package/cypress/e2e/glib-web/{formDynamic.cy.ts → formDynamic.cy.js} +1 -1
  51. package/cypress/e2e/glib-web/{forms.cy.ts → forms.cy.js} +1 -1
  52. package/cypress/e2e/glib-web/{grid.cy.ts → grid.cy.js} +1 -1
  53. package/cypress/e2e/glib-web/{horizontal.cy.ts → horizontal.cy.js} +1 -1
  54. package/cypress/e2e/glib-web/{http.cy.ts → http.cy.js} +1 -1
  55. package/cypress/e2e/glib-web/{image.cy.ts → image.cy.js} +1 -1
  56. package/cypress/e2e/glib-web/{lifecycle.cy.ts → lifecycle.cy.js} +1 -1
  57. package/cypress/e2e/glib-web/{list.cy.ts → list.cy.js} +1 -1
  58. package/cypress/e2e/glib-web/{listEditable.cy.ts → listEditable.cy.js} +1 -1
  59. package/cypress/e2e/glib-web/{listsAppend.cy.ts → listsAppend.cy.js} +1 -1
  60. package/cypress/e2e/glib-web/{logicsSet.cy.ts → logicsSet.cy.js} +1 -1
  61. package/cypress/e2e/glib-web/{multimediaVideo.cy.ts → multimediaVideo.cy.js} +1 -1
  62. package/cypress/e2e/glib-web/{pagination.cy.ts → pagination.cy.js} +1 -1
  63. package/cypress/e2e/glib-web/{panels.cy.ts → panels.cy.js} +1 -1
  64. package/cypress/e2e/glib-web/{panelsBulkEdit2.cy.ts → panelsBulkEdit2.cy.js} +1 -1
  65. package/cypress/e2e/glib-web/{popovers.cy.ts → popovers.cy.js} +1 -1
  66. package/cypress/e2e/glib-web/{progressCircle.cy.ts → progressCircle.cy.js} +1 -1
  67. package/cypress/e2e/glib-web/{responsive.cy.ts → responsive.cy.js} +1 -1
  68. package/cypress/e2e/glib-web/{scroll.cy.ts → scroll.cy.js} +1 -1
  69. package/cypress/e2e/glib-web/{selectable.cy.ts → selectable.cy.js} +1 -1
  70. package/cypress/e2e/glib-web/{sheets.cy.ts → sheets.cy.js} +1 -1
  71. package/cypress/e2e/glib-web/{snackbars.cy.ts → snackbars.cy.js} +1 -1
  72. package/cypress/e2e/glib-web/{split.cy.ts → split.cy.js} +1 -1
  73. package/cypress/e2e/glib-web/{storageItems.cy.ts → storageItems.cy.js} +1 -1
  74. package/cypress/e2e/glib-web/{table.cy.ts → table.cy.js} +1 -1
  75. package/cypress/e2e/glib-web/{timeline.cy.ts → timeline.cy.js} +1 -1
  76. package/cypress/e2e/glib-web/{timeouts.cy.ts → timeouts.cy.js} +1 -1
  77. package/cypress/e2e/glib-web/{ul.cy.ts → ul.cy.js} +1 -1
  78. package/cypress/e2e/glib-web/{vertical.cy.ts → vertical.cy.js} +1 -1
  79. package/cypress/e2e/glib-web/{web.cy.ts → web.cy.js} +1 -1
  80. package/cypress/e2e/glib-web/window.cy.js +21 -0
  81. package/cypress/e2e/glib-web/{windows.cy.ts → windows.cy.js} +34 -2
  82. package/cypress/helper.js +19 -0
  83. package/cypress/support/{commands.ts → commands.js} +2 -2
  84. package/cypress/support/component.js +27 -0
  85. package/cypress/support/{e2e.ts → e2e.js} +18 -3
  86. package/{cypress.config.ts → cypress.config.js} +3 -2
  87. package/cypress.yml.example +6 -7
  88. package/doc/TESTING.md +2 -2
  89. package/package.json +1 -1
  90. package/components/composable/dropable.js +0 -52
  91. package/components/fields/googlePlace.vue +0 -162
  92. package/components/mixins/tooltip.js +0 -57
  93. package/cypress/e2e/glib-web/dialog.cy.ts +0 -25
  94. package/cypress/e2e/glib-web/fieldsUpload.cy.ts +0 -48
  95. package/cypress/e2e/glib-web/multiupload.cy.ts +0 -25
  96. package/cypress/e2e/glib-web/window.cy.ts +0 -14
  97. package/cypress/helper.ts +0 -7
  98. package/cypress/support/component.ts +0 -12
@@ -1,4 +1,4 @@
1
- import { testPageUrl } from "../../helper"
1
+ import { testPageUrl } from "../../helper.js"
2
2
 
3
3
  const url = testPageUrl('timeline')
4
4
 
@@ -1,4 +1,4 @@
1
- import { testPageUrl } from "../../helper"
1
+ import { testPageUrl } from "../../helper.js"
2
2
 
3
3
  const url = testPageUrl('timeouts')
4
4
 
@@ -1,4 +1,4 @@
1
- import { testPageUrl } from "../../helper"
1
+ import { testPageUrl } from "../../helper.js"
2
2
 
3
3
  const url = testPageUrl('ul')
4
4
 
@@ -1,4 +1,4 @@
1
- import { testPageUrl } from "../../helper"
1
+ import { testPageUrl } from "../../helper.js"
2
2
 
3
3
  const url = testPageUrl('vertical')
4
4
 
@@ -1,4 +1,4 @@
1
- import { testPageUrl } from "../../helper"
1
+ import { testPageUrl } from "../../helper.js"
2
2
 
3
3
  const url = testPageUrl('web')
4
4
 
@@ -0,0 +1,21 @@
1
+ import { testPageUrl } from "../../helper.js"
2
+
3
+ const url = testPageUrl('window')
4
+
5
+ describe('window', () => {
6
+ it('opens a new window with updateExisting', () => {
7
+ cy.visit(url)
8
+
9
+ cy.contains('windows/open updateExisting: true').click()
10
+ cy.location('href').should('contain', 'fields_upload')
11
+ })
12
+
13
+ it('closes the current window', () => {
14
+ const previousUrl = testPageUrl('fields_upload')
15
+
16
+ cy.visit(previousUrl)
17
+ cy.visit(url)
18
+
19
+ cy.contains('windows/close').click()
20
+ })
21
+ })
@@ -1,4 +1,4 @@
1
- import { testPageUrl } from "../../helper"
1
+ import { testPageUrl } from "../../helper.js"
2
2
 
3
3
  const url = testPageUrl('windows')
4
4
 
@@ -36,8 +36,26 @@ describe('windows', () => {
36
36
  cy.get('@windowOpen').should('have.been.calledWith', 'http://www.google.com')
37
37
  })
38
38
 
39
+ it('reloads the current window', () => {
40
+ cy.visit(url)
41
+
42
+ cy.contains('windows/reload').click()
43
+ cy.location('href').should('contain', 'path=test_page%2Fwindows')
44
+ })
45
+
46
+ it('prints the current window', () => {
47
+ cy.visit(url)
48
+
49
+ cy.window().then((win) => {
50
+ cy.stub(win, 'print').as('windowPrint')
51
+ })
52
+
53
+ cy.contains('windows/print').click()
54
+ cy.get('@windowPrint').should('have.been.called')
55
+ })
56
+
39
57
  it('closes the current window and returns to the previous view', () => {
40
- const previousUrl = testPageUrl('multiupload')
58
+ const previousUrl = testPageUrl('fields_upload')
41
59
 
42
60
  cy.visit(previousUrl)
43
61
  cy.visit(url)
@@ -52,6 +70,13 @@ describe('windows', () => {
52
70
  cy.location('href').should('contain', 'path=home%2Fprint')
53
71
  })
54
72
 
73
+ it('closes the current window and reloads with fallback', () => {
74
+ cy.visit(url)
75
+
76
+ cy.contains('windows/closeWithReload').click()
77
+ cy.location('href').should('contain', 'path=home%2Findex')
78
+ })
79
+
55
80
  it('closes all windows and opens the home view', () => {
56
81
  cy.visit(url)
57
82
 
@@ -60,6 +85,13 @@ describe('windows', () => {
60
85
  cy.location('href').should('contain', 'path=home%2Findex')
61
86
  })
62
87
 
88
+ it('closes all windows and opens home view from onClose', () => {
89
+ cy.visit(url)
90
+
91
+ cy.contains('windows/closeAll').click()
92
+ cy.location('href').should('contain', 'path=home%2Findex')
93
+ })
94
+
63
95
  it('opens a window with a loader view', () => {
64
96
  cy.visit(url)
65
97
 
@@ -0,0 +1,19 @@
1
+ import { realComponent } from "../components/helper.js"
2
+
3
+ // const DEV_TEST_PAGE = 'http://localhost:3000/glib/json_ui_garage?path=test_page%2F{{testPage}}'
4
+
5
+ function testPageUrl(testPage) {
6
+ const port = Cypress.env('BACKEND_PORT') || '3000';
7
+ const baseUrl = `http://localhost:${port}/glib/json_ui_garage?path=test_page%2F${testPage}`;
8
+ return baseUrl;
9
+ }
10
+
11
+ function withComponent(id, callback) {
12
+ return cy.window().should((win) => {
13
+ const comp = realComponent(win.GLib.component.findById(id))
14
+ expect(comp).to.exist
15
+ callback(comp)
16
+ })
17
+ }
18
+
19
+ export { testPageUrl, withComponent }
@@ -1,6 +1,6 @@
1
1
  /// <reference types="cypress" />
2
2
  // ***********************************************
3
- // This example commands.ts shows you how to
3
+ // This example commands.js shows you how to
4
4
  // create various custom commands and overwrite
5
5
  // existing commands.
6
6
  //
@@ -34,4 +34,4 @@
34
34
  // visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
35
35
  // }
36
36
  // }
37
- // }
37
+ // }
@@ -0,0 +1,27 @@
1
+ import "./commands.js";
2
+ import "@cypress/code-coverage/support.js";
3
+ import { isFunction, isObject } from "../../utils/type.js";
4
+
5
+ const win = window;
6
+
7
+ if (!win.__settings) {
8
+ win.__settings = { theme: {} };
9
+ }
10
+
11
+ if (!win.__page) {
12
+ win.__page = {};
13
+ }
14
+
15
+ Cypress.on("window:before:load", (win) => {
16
+ if (!isObject(win) || !isObject(win.console)) return;
17
+
18
+ if (isFunction(win.console.log)) {
19
+ win.console.log = () => {};
20
+ }
21
+ if (isFunction(win.console.warn)) {
22
+ win.console.warn = () => {};
23
+ }
24
+ if (isFunction(win.console.info)) {
25
+ win.console.info = () => {};
26
+ }
27
+ });
@@ -1,5 +1,5 @@
1
1
  // ***********************************************************
2
- // This example support/e2e.ts is processed and
2
+ // This example support/e2e.js is processed and
3
3
  // loaded automatically before your test files.
4
4
  //
5
5
  // This is a great place to put global configuration and
@@ -14,8 +14,23 @@
14
14
  // ***********************************************************
15
15
 
16
16
  // Import commands.js using ES2015 syntax:
17
- import './commands'
18
- import '@cypress/code-coverage/support'
17
+ import "./commands.js";
18
+ import "@cypress/code-coverage/support.js";
19
+ import { isFunction, isObject } from "../../utils/type.js";
20
+
21
+ Cypress.on("window:before:load", (win) => {
22
+ if (!isObject(win) || !isObject(win.console)) return;
23
+
24
+ if (isFunction(win.console.log)) {
25
+ win.console.log = () => {};
26
+ }
27
+ if (isFunction(win.console.warn)) {
28
+ win.console.warn = () => {};
29
+ }
30
+ if (isFunction(win.console.info)) {
31
+ win.console.info = () => {};
32
+ }
33
+ });
19
34
 
20
35
  // Ignore retry failures from backend error pages so specs can assert UI state.
21
36
  Cypress.on('uncaught:exception', (err) => {
@@ -43,8 +43,8 @@ export default defineConfig({
43
43
  },
44
44
  },
45
45
  },
46
- specPattern: "cypress/component/**/*.cy.{js,jsx,ts,tsx}",
47
- supportFile: "cypress/support/component.ts",
46
+ specPattern: "cypress/component/**/*.cy.{js,jsx}",
47
+ supportFile: "cypress/support/component.js",
48
48
  setupNodeEvents(on, config) {
49
49
  codeCoverageTask(on, config);
50
50
  return config;
@@ -55,6 +55,7 @@ export default defineConfig({
55
55
  pageLoadTimeout: 60000,
56
56
  requestTimeout: 15000,
57
57
  responseTimeout: 15000,
58
+ specPattern: "cypress/e2e/**/*.cy.{js,jsx}",
58
59
  setupNodeEvents(on, config) {
59
60
  codeCoverageTask(on, config);
60
61
  return config;
@@ -5,7 +5,7 @@ on:
5
5
  - "yarn.lock"
6
6
  - ".github/workflows/cypress.yml"
7
7
  jobs:
8
- build-and-test:
8
+ cypress-test:
9
9
  env:
10
10
  RAILS_ENV: test
11
11
  POSTGRES_USER: postgres
@@ -27,26 +27,25 @@ jobs:
27
27
  --health-timeout 5s
28
28
  --health-retries 5
29
29
  steps:
30
- - uses: actions/checkout@v2
30
+ - uses: actions/checkout@v6
31
31
  - name: Setup Ruby
32
32
  uses: ruby/setup-ruby@v1
33
33
  with:
34
34
  ruby-version: 3.2.1
35
35
  bundler-cache: true
36
36
  - name: Setup Node
37
- uses: actions/setup-node@v2
37
+ uses: actions/setup-node@v6
38
38
  with:
39
39
  cache: "yarn"
40
- node-version: 20.0.0
40
+ node-version: 24.11.1
41
41
  - run: yarn install --frozen-lockfile
42
42
  - run: sudo apt-get -yqq install libpq-dev
43
43
  - run: cp config/database.yml.github-actions config/database.yml
44
44
  - run: bundle exec rake db:test:prepare
45
45
  - run: bundle exec rails server -d
46
+ - run: until curl -s http://localhost:3000 >/dev/null; do sleep 1; done
46
47
  - name: Cypress run (e2e)
47
- run: env -u ELECTRON_RUN_AS_NODE yarn cypress run --browser chrome
48
- - name: Cypress run (component)
49
- run: env -u ELECTRON_RUN_AS_NODE yarn cypress run --component
48
+ run: env -u ELECTRON_RUN_AS_NODE yarn run cypress run --browser chrome
50
49
  - name: Upload screenshots
51
50
  uses: actions/upload-artifact@v4
52
51
  if: failure()
package/doc/TESTING.md CHANGED
@@ -21,8 +21,8 @@ This is fundamentally different from typical frontend testing (Jest/Vitest with
21
21
 
22
22
  ### 3. **Test Page as Contract**
23
23
  Each Cypress test has a **matching backend test page** (jbuilder file):
24
- - `form.cy.ts` → `test_page/form.json.jbuilder`
25
- - `dialog.cy.ts` → `test_page/dialog.json.jbuilder`
24
+ - `form.cy.js` → `test_page/form.json.jbuilder`
25
+ - `dialog.cy.js` → `test_page/dialog.json.jbuilder`
26
26
 
27
27
  The test page acts as the **contract** between frontend and backend tests.
28
28
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "glib-web",
4
- "version": "4.44.6",
4
+ "version": "5.0.4",
5
5
  "description": "",
6
6
  "main": "index.js",
7
7
  "scripts": {
@@ -1,52 +0,0 @@
1
- import { onMounted } from "vue";
2
-
3
- function useDropUpload({ container, fileSelect, files, spec, uploader }) {
4
- const { onDragStyle } = spec;
5
- onMounted(() => {
6
- uploader.setBusyWhenUploading({ files });
7
-
8
- // handle style changes
9
- let dragEl = null;
10
- container.value.ondragenter = (event) => {
11
- dragEl = event.target;
12
- container.value.classList.add(...onDragStyle);
13
- };
14
- container.value.ondragleave = (event) => {
15
- if (dragEl == event.target) {
16
- container.value.classList.remove(...onDragStyle);
17
- }
18
- };
19
-
20
- // handle upload
21
- container.value.ondragover = (event) => event.preventDefault();
22
- container.value.ondrop = (event) => {
23
- event.preventDefault();
24
- uploader.uploadFiles({
25
- droppedFiles: event.dataTransfer.files,
26
- container,
27
- files,
28
- spec
29
- });
30
- container.value.classList.remove(...onDragStyle);
31
- };
32
-
33
- container.value.onclick = (event) => {
34
- const onchange = () => {
35
- uploader.uploadFiles(
36
- {
37
- droppedFiles: event.target.files,
38
- files,
39
- spec,
40
- container
41
- }
42
- );
43
- };
44
-
45
- fileSelect.value.onchange = onchange;
46
- fileSelect.value.click();
47
- };
48
- });
49
-
50
- }
51
-
52
- export { useDropUpload };
@@ -1,162 +0,0 @@
1
- <!-- TODO: This probably can be merged with latLong-v1 or map-v1, i.e. add infoWindow support to latLong or map -->
2
-
3
- <template>
4
- <v-container v-if="loadIf" fluid class="pa-0">
5
- <div class="v-input v-text-field theme--light">
6
- <div class="v-input__control">
7
- <div class="v-input__slot">
8
- <div class="v-text-field__slot">
9
- <label class="v-label theme--light v-label--active"
10
- style="left: 0px; right: auto; position: absolute;">Address</label>
11
- <!-- <gmap-place-input :default-place="placeName" :placeholder="Address" @place_changed="setPlace" /> -->
12
- <gmap-autocomplete :name="spec.name" placeholder="Address" @place_changed="setPlace" />
13
- </div>
14
- </div>
15
- </div>
16
- </div>
17
-
18
- <gmap-map ref="map" :center="{ lat: 25.105497, lng: 121.597366 }" :zoom="13" map-type-id="roadmap"
19
- style="width: 100%; height: 300px" @click="onMapClick">
20
- <gmap-info-window :options="infoOptions" :position="markerPos" :opened="infoWinOpen"
21
- @closeclick="closeInfoWindow">
22
- <div v-if="place !== null">
23
- <strong>{{ place.name }}</strong>
24
- <div>Place ID: {{ place.place_id }}</div>
25
- <div>Address: {{ place.formatted_address }}</div>
26
- <div>
27
- Longitude: {{ place.geometry.location.lng() }}, Latitude:
28
- {{ place.geometry.location.lat() }}
29
- </div>
30
- </div>
31
- <div v-if="
32
- spec.hasOwnProperty('infoWindow') &&
33
- spec.infoWindow['actionButtons'].length > 0
34
- ">
35
- <v-btn v-for="(buttonSpec, i) in spec.infoWindow.actionButtons" :key="i"
36
- @click="onActionButtonClick($event, buttonSpec)">
37
- {{ buttonSpec.text }}
38
- </v-btn>
39
- </div>
40
- </gmap-info-window>
41
-
42
- <gmap-marker :position="markerPos" :clickable="true" @click="openInfoWindow" />
43
- <template #visible>
44
- <div id="loading-container" ref="loading" class="d-none">
45
- <v-progress-circular indeterminate color="primary" />
46
- </div>
47
- </template>
48
- </gmap-map>
49
- </v-container>
50
- </template>
51
-
52
- <script>
53
- import GlibBase from "../base/glibBase.js";
54
- import Action from "../../action";
55
-
56
- export default {
57
- extends: GlibBase,
58
- props: ["spec"],
59
- data() {
60
- return {
61
- infoOptions: {
62
- pixelOffset: {
63
- width: 0,
64
- height: -35
65
- }
66
- },
67
- markerPos: { lat: 0, lng: 0 },
68
- infoWinOpen: false,
69
- place: null
70
- };
71
- },
72
- computed: {
73
- placeName() {
74
- return this.place == null ? "" : this.place.name;
75
- }
76
- },
77
- methods: {
78
- closeInfoWindow() {
79
- this.infoWinOpen = false;
80
- },
81
- openInfoWindow() {
82
- this.infoWinOpen = true;
83
- },
84
- toggleLoadingIndicator() {
85
- this.$refs.loading.classList.toggle("d-none");
86
- this.$refs.loading.classList.toggle("d-flex");
87
- },
88
- onActionButtonClick(event, properties) {
89
- properties.onClick["formData"] = {
90
- "place[google_place_id]": this.place.place_id,
91
- "place[name]": this.place.name,
92
- "place[address]": this.place.formatted_address,
93
- "place[longitude]": this.place.geometry.location.lng(),
94
- "place[latitude]": this.place.geometry.location.lat()
95
- };
96
-
97
- Action.execute(properties.onClick, this);
98
- },
99
- onMapClick(e) {
100
- this.closeInfoWindow();
101
-
102
- if (e.placeId === undefined) {
103
- return;
104
- }
105
-
106
- e.stop();
107
- this.toggleLoadingIndicator();
108
-
109
- const request = {
110
- placeId: e.placeId,
111
- fields: ["place_id", "geometry", "name", "formatted_address"]
112
- };
113
- var service = new google.maps.places.PlacesService(
114
- this.$refs.map.$mapObject
115
- );
116
- service.getDetails(request, place => {
117
- this.toggleLoadingIndicator();
118
- this.markerPos = place.geometry.location;
119
- this.place = place;
120
- this.openInfoWindow();
121
- });
122
- },
123
- setLocationField(name, value) {
124
- let field = document.querySelector(`input[name="${name}"]`);
125
- field.closest("div.v-input").classList.add("v-input--is-label-active");
126
- field.closest("div.v-input").classList.add("v-input--is-dirty");
127
- field.previousSibling.classList.add("v-label--active");
128
- field.value = value;
129
- },
130
- setPlace(place) {
131
- const { location } = place.geometry;
132
- this.place = place;
133
- this.markerPos = location;
134
- this.$refs.map.$mapObject.setCenter(location);
135
-
136
- if (Object.hasOwn(this.spec, "locationFields")) {
137
- this.setLocationField(
138
- this.spec.locationFields.latitudeName,
139
- location.lat()
140
- );
141
- this.setLocationField(
142
- this.spec.locationFields.longitudeName,
143
- location.lng()
144
- );
145
- }
146
- }
147
- }
148
- };
149
- </script>
150
-
151
- <style scoped>
152
- #loading-container {
153
- position: absolute;
154
- width: 100%;
155
- height: 300px;
156
- top: 0;
157
- z-index: 100;
158
- background: rgba(196, 154, 154, 0.1);
159
- align-items: center;
160
- justify-content: center;
161
- }
162
- </style>
@@ -1,57 +0,0 @@
1
- import { defineComponent } from "vue";
2
- import launch from "../../utils/launch";
3
- import { htmlElement } from "../helper";
4
-
5
- export default defineComponent({
6
- data() {
7
- return {
8
- key: Math.random().toString(36).slice(2, 7)
9
- };
10
- },
11
- computed: {
12
- properties() {
13
- return {
14
- view: 'p',
15
- text: this.spec.tooltip.text,
16
- styleClasses: ['tooltip']
17
- };
18
- }
19
- },
20
- methods: {
21
- handleMouseEnter() {
22
- const properties = {
23
- body: { childViews: [this.properties] },
24
- key: this.key,
25
- placement: this.spec.tooltip.placement || 'top',
26
- styleClass: 'views-tooltip'
27
- };
28
- launch.popover.open(properties, this);
29
- },
30
- handleMouseLeave() {
31
- launch.popover.close({ key: this.key });
32
- },
33
- $mounted() {
34
- const tooltip = this.spec.tooltip;
35
-
36
- if (!tooltip) return;
37
-
38
- this.initTooltip();
39
- },
40
- $tearDown() {
41
- const el = htmlElement(this);
42
-
43
- if (el) {
44
- el.removeEventListener('mouseenter', this.handleMouseEnter);
45
- el.removeEventListener('mouseleave', this.handleMouseLeave);
46
- }
47
-
48
- this.handleMouseLeave();
49
- },
50
- initTooltip() {
51
- const el = htmlElement(this);
52
-
53
- el.addEventListener('mouseenter', this.handleMouseEnter.bind(this));
54
- el.addEventListener('mouseleave', this.handleMouseLeave.bind(this));
55
- }
56
- }
57
- });
@@ -1,25 +0,0 @@
1
- import { testPageUrl } from "../../helper"
2
- const url = testPageUrl('dialog')
3
-
4
- describe('dialog', () => {
5
- it('updateExisting', () => {
6
- cy.visit(url)
7
- cy.contains('Dialog updateExisting').click()
8
- cy.get('.v-dialog h1').should('contain.text', 'Hello world')
9
- cy.get('.v-dialog .v-icon').should('exist')
10
- cy.get('.v-dialog').contains('change dialog content').click()
11
- cy.get('.v-dialog h1').should('contain.text', 'Hello world (updated)')
12
- cy.get('.v-dialog .v-icon').should('not.exist')
13
- })
14
-
15
- it('open dialog', () => {
16
- cy.visit(url)
17
- cy.contains('Dialog open').click()
18
- cy.get('.dialog-title > .close-btn').click()
19
-
20
- cy.contains('Dialog open').click()
21
- cy.get('.v-dialog').contains('close').click()
22
-
23
- cy.get('.v-dialog').should('not.exist')
24
- })
25
- })
@@ -1,48 +0,0 @@
1
- import { testPageUrl } from "../../helper"
2
-
3
- const url = testPageUrl('fields_upload')
4
-
5
- const getRealComponent = (win, component) => {
6
- const { isObject, isNotNull } = win.Utils.type
7
- let realComp = component
8
-
9
- while (isObject(realComp) && isNotNull(realComp.$refs?.delegate)) {
10
- realComp = realComp.$refs.delegate
11
- }
12
-
13
- return realComp
14
- }
15
-
16
- describe('fields_upload', () => {
17
- it('invokes upload triggers and resets', () => {
18
- cy.visit(url)
19
-
20
- cy.window().then((win) => {
21
- const basicComp = getRealComponent(win, win.GLib.component.findById('fields_upload_basic'))
22
- const filesComp = getRealComponent(win, win.GLib.component.findById('fields_upload_files'))
23
-
24
- cy.wrap(basicComp).should('exist')
25
- cy.wrap(filesComp).should('exist')
26
-
27
- cy.spy(basicComp, 'trigger').as('basicTrigger')
28
- cy.spy(basicComp, 'reset').as('basicReset')
29
- cy.spy(filesComp, 'trigger').as('filesTrigger')
30
- })
31
-
32
- cy.contains('Trigger').click()
33
- cy.get('@basicTrigger').should('have.been.calledOnce')
34
-
35
- cy.contains('Reset').click()
36
- cy.get('@basicReset').should('have.been.calledOnce')
37
-
38
- cy.contains('Select file').click()
39
- cy.get('@filesTrigger').should('have.been.calledOnce')
40
- })
41
-
42
- it('submits the form', () => {
43
- cy.visit(url)
44
-
45
- cy.contains('submit').click()
46
- cy.get('.unformatted').should('contain.text', 'Method: POST')
47
- })
48
- })
@@ -1,25 +0,0 @@
1
- import { testPageUrl } from "../../helper"
2
- const url = testPageUrl('multiupload')
3
-
4
- describe('multiUpload', () => {
5
- it('can change files', () => {
6
- cy.visit(url)
7
-
8
- cy.contains('clear files').click()
9
- cy.contains('File (Example)').should('not.exist')
10
- cy.contains('populate files').click()
11
- cy.contains('File (Example)').should('exist')
12
-
13
- cy.contains('submit').click()
14
-
15
- // const result = `Method: POST
16
- // Form Data:
17
- // {
18
- // "multi2": [
19
- // "eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBSUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--e773c3169f0bac71fa589bddb1f77a04bc3771c9"
20
- // ]
21
- // }`
22
-
23
- // cy.get('.unformatted').should('contain.text', result)
24
- })
25
- })