glib-web 4.42.2 → 4.43.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.
- package/.github/workflows/lint.yml +29 -0
- package/.nycrc.json +7 -3
- package/AGENTS.md +3 -0
- package/action.js +2 -0
- package/actions/analytics/logEvent.js +2 -2
- package/actions/bottom_banners/close.js +1 -1
- package/actions/bottom_banners/open.js +1 -1
- package/actions/browsers/setLocation.js +16 -0
- package/actions/cables/push.js +1 -1
- package/actions/components/invoke.js +1 -1
- package/actions/components/replace.js +1 -1
- package/actions/components/replaceChildren.js +1 -1
- package/actions/components/set.js +1 -1
- package/actions/dialogs/close.js +0 -2
- package/actions/fields/getValues.js +3 -7
- package/actions/http/patch.js +1 -1
- package/actions/http/post.js +1 -1
- package/actions/http/put.js +1 -1
- package/actions/http/retry.js +1 -1
- package/actions/logics/set.js +0 -11
- package/actions/popovers/open.js +0 -1
- package/actions/sheets/show.js +2 -2
- package/actions/timeouts/clear.js +6 -2
- package/actions/timeouts/set.js +5 -1
- package/actions/tours/stop.js +1 -1
- package/actions/windows/open.js +1 -1
- package/actions/windows/print.js +1 -1
- package/agent/{glib_test_sync.yaml → commands/generate_test.yaml} +3 -2
- package/agent/commands/scan_state_issue.yaml +64 -0
- package/app.vue +33 -27
- package/components/_avatar.vue +6 -6
- package/components/_badge.vue +7 -5
- package/components/_button.vue +2 -0
- package/components/_chip.vue +6 -5
- package/components/_dropdownMenu.vue +10 -15
- package/components/_icon.vue +4 -2
- package/components/_internal_button.vue +2 -0
- package/components/_internal_icon.vue +3 -3
- package/components/_message.vue +3 -1
- package/components/avatar.vue +2 -0
- package/components/banners/alert.vue +2 -0
- package/components/banners/select.vue +6 -4
- package/components/{mixins/events.js → base/eventsBase.js} +16 -26
- package/components/base/glibBase.js +10 -0
- package/components/button.vue +2 -0
- package/components/calendar.vue +11 -4
- package/components/charts/area.vue +8 -0
- package/components/charts/column.vue +8 -0
- package/components/charts/line.vue +8 -0
- package/components/charts/pie.vue +8 -0
- package/components/chip.vue +2 -0
- package/components/component.vue +25 -29
- package/components/composable/form.js +10 -5
- package/components/composable/inputVariant.js +43 -0
- package/components/composable/listAutoload.js +240 -0
- package/components/composable/socket.js +2 -2
- package/components/composable/tableAutoload.js +182 -0
- package/components/composable/tableExport.js +84 -0
- package/components/composable/tableImport.js +163 -0
- package/components/composable/tooltip.js +100 -0
- package/components/composable/upload.js +2 -2
- package/components/composable/upload_delegator.js +2 -2
- package/components/composable/upload_nothing.js +3 -3
- package/components/datetime.vue +18 -1
- package/components/fab.vue +2 -0
- package/components/fields/_buttonDate.vue +24 -18
- package/components/fields/_dynamicGroupEntry2.vue +3 -0
- package/components/fields/_patternText.vue +8 -6
- package/components/fields/_select.vue +23 -20
- package/components/fields/_selectItemDefault.vue +10 -2
- package/components/fields/_selectItemWithIcon.vue +9 -1
- package/components/fields/_selectItemWithImage.vue +11 -3
- package/components/fields/check/_featured.vue +12 -1
- package/components/fields/check/_thumbnail.vue +2 -0
- package/components/fields/check.vue +32 -22
- package/components/fields/checkGroup.vue +26 -16
- package/components/fields/chipGroup.vue +8 -5
- package/components/fields/creditCard.vue +15 -4
- package/components/fields/date.vue +2 -0
- package/components/fields/datetime.vue +2 -0
- package/components/fields/dynamicGroup2.vue +27 -16
- package/components/fields/dynamicSelect.vue +21 -15
- package/components/fields/file.vue +27 -8
- package/components/fields/googlePlace.vue +5 -3
- package/components/fields/hidden.vue +4 -7
- package/components/fields/inputUpload.vue +11 -3
- package/components/fields/location.vue +13 -11
- package/components/fields/multiUpload.vue +16 -14
- package/components/fields/newRichText.vue +15 -5
- package/components/fields/otpField.vue +13 -10
- package/components/fields/phone/field.vue +15 -7
- package/components/fields/phone.vue +17 -12
- package/components/fields/placeholderUpload.vue +10 -2
- package/components/fields/radio/_featured.vue +5 -3
- package/components/fields/radio/_subtitle.vue +5 -3
- package/components/fields/radio/_thumbnail.vue +3 -1
- package/components/fields/radio.vue +10 -8
- package/components/fields/radioGroup.vue +8 -6
- package/components/fields/rating.vue +2 -0
- package/components/fields/rawText.vue +8 -0
- package/components/fields/richText2.vue +35 -17
- package/components/fields/sign.vue +40 -32
- package/components/fields/stripe/stripeFields.vue +29 -15
- package/components/fields/stripe/stripeIndividualFields.vue +41 -27
- package/components/fields/stripeExternalAccount.vue +29 -5
- package/components/fields/stripeToken.vue +3 -1
- package/components/fields/submit.vue +7 -5
- package/components/fields/text.vue +11 -8
- package/components/fields/textarea.vue +8 -5
- package/components/fields/timeZone.vue +2 -0
- package/components/fields/timer.vue +15 -3
- package/components/fields/upload.vue +11 -3
- package/components/h1.vue +2 -0
- package/components/h2.vue +2 -0
- package/components/h3.vue +2 -0
- package/components/h4.vue +2 -0
- package/components/h5.vue +2 -0
- package/components/h6.vue +2 -0
- package/components/hr.vue +2 -0
- package/components/html.vue +2 -0
- package/components/icon.vue +3 -1
- package/components/image.vue +16 -5
- package/components/label.vue +2 -0
- package/components/map.vue +8 -3
- package/components/markdown.vue +25 -10
- package/components/mixins/generic.js +27 -28
- package/components/mixins/scrolling.js +5 -0
- package/components/mixins/styles.js +5 -3
- package/components/multimedia/video.vue +4 -4
- package/components/p.vue +2 -0
- package/components/panels/association.vue +3 -1
- package/components/panels/bulkEdit2.vue +41 -33
- package/components/panels/carousel.vue +8 -22
- package/components/panels/column.vue +45 -69
- package/components/panels/custom.vue +3 -1
- package/components/panels/flow.vue +39 -42
- package/components/panels/form.vue +9 -4
- package/components/panels/grid.vue +3 -1
- package/components/panels/horizontal.vue +23 -6
- package/components/panels/list.vue +13 -7
- package/components/panels/pagination.vue +23 -4
- package/components/panels/scroll.vue +3 -1
- package/components/panels/split.vue +3 -1
- package/components/panels/table.vue +39 -13
- package/components/panels/timeline.vue +19 -8
- package/components/panels/tree/standard.vue +21 -13
- package/components/panels/tree.vue +14 -6
- package/components/panels/ul.vue +3 -1
- package/components/panels/vertical.vue +4 -4
- package/components/panels/web.vue +2 -0
- package/components/popover.vue +4 -2
- package/components/progressCircle.vue +5 -3
- package/components/progressbar.vue +2 -0
- package/components/responsive.vue +3 -1
- package/components/shareButton.vue +19 -2
- package/components/skeleton.vue +8 -0
- package/components/skeletons/commentList.vue +1 -1
- package/components/spacer.vue +2 -0
- package/components/switch.vue +12 -2
- package/components/tabBar.vue +18 -7
- package/components/treeView.vue +64 -62
- package/components/validation.js +1 -2
- package/cypress/component/inputUpload.cy.ts +103 -0
- package/cypress/component/multiUpload.cy.ts +107 -0
- package/cypress/component/placeholderUpload.cy.ts +91 -0
- package/cypress/component/testUtils.ts +74 -0
- package/cypress/e2e/glib-web/auth.cy.ts +33 -0
- package/cypress/e2e/glib-web/browsers.cy.ts +14 -4
- package/cypress/e2e/glib-web/calendar.cy.ts +4 -4
- package/cypress/e2e/glib-web/carousel.cy.ts +7 -7
- package/cypress/e2e/glib-web/column.cy.ts +4 -4
- package/cypress/e2e/glib-web/commands.cy.ts +5 -5
- package/cypress/e2e/glib-web/components.cy.ts +18 -18
- package/cypress/e2e/glib-web/cookies.cy.ts +41 -0
- package/cypress/e2e/glib-web/custom.cy.ts +2 -2
- package/cypress/e2e/glib-web/fields.cy.ts +52 -0
- package/cypress/e2e/glib-web/fieldsDynamicSelect.cy.ts +81 -0
- package/cypress/e2e/glib-web/fieldsSelect.cy.ts +82 -0
- package/cypress/e2e/glib-web/fieldsSign.cy.ts +54 -0
- package/cypress/e2e/glib-web/fieldsTimer.cy.ts +39 -0
- package/cypress/e2e/glib-web/fieldsUpload.cy.ts +48 -0
- package/cypress/e2e/glib-web/flow.cy.ts +4 -4
- package/cypress/e2e/glib-web/forms.cy.ts +4 -5
- package/cypress/e2e/glib-web/grid.cy.ts +2 -2
- package/cypress/e2e/glib-web/horizontal.cy.ts +10 -10
- package/cypress/e2e/glib-web/http.cy.ts +8 -8
- package/cypress/e2e/glib-web/image.cy.ts +21 -21
- package/cypress/e2e/glib-web/list.cy.ts +19 -4
- package/cypress/e2e/glib-web/multimediaVideo.cy.ts +6 -6
- package/cypress/e2e/glib-web/pagination.cy.ts +4 -4
- package/cypress/e2e/glib-web/panels.cy.ts +1 -1
- package/cypress/e2e/glib-web/panelsBulkEdit2.cy.ts +21 -0
- package/cypress/e2e/glib-web/popovers.cy.ts +4 -4
- package/cypress/e2e/glib-web/progressCircle.cy.ts +14 -14
- package/cypress/e2e/glib-web/responsive.cy.ts +3 -3
- package/cypress/e2e/glib-web/scroll.cy.ts +4 -4
- package/cypress/e2e/glib-web/sheets.cy.ts +4 -4
- package/cypress/e2e/glib-web/snackbars.cy.ts +6 -6
- package/cypress/e2e/glib-web/split.cy.ts +1 -1
- package/cypress/e2e/glib-web/storageItems.cy.ts +7 -7
- package/cypress/e2e/glib-web/table.cy.ts +13 -3
- package/cypress/e2e/glib-web/timeline.cy.ts +3 -3
- package/cypress/e2e/glib-web/timeouts.cy.ts +3 -3
- package/cypress/e2e/glib-web/ul.cy.ts +2 -2
- package/cypress/e2e/glib-web/vertical.cy.ts +10 -10
- package/cypress/e2e/glib-web/web.cy.ts +4 -4
- package/cypress/fixtures/bulk_edit.csv +3 -0
- package/cypress/fixtures/upload.txt +1 -0
- package/cypress/support/component.ts +1 -0
- package/cypress.config.ts +14 -1
- package/eslint-rules/index.js +264 -0
- package/eslint.config.js +70 -0
- package/index.js +2 -17
- package/nav/appBar.vue +4 -2
- package/nav/dialog.vue +14 -12
- package/nav/drawer.vue +15 -13
- package/nav/drawerButton.vue +2 -0
- package/nav/drawerLabel.vue +3 -0
- package/nav/layout.vue +3 -1
- package/nav/sheet.vue +5 -2
- package/nav/snackbar.vue +13 -4
- package/package.json +9 -3
- package/plugins/driverCustomBehavior.js +1 -1
- package/settings.json.example +9 -4
- package/templates/_menu.vue +2 -0
- package/templates/comment.vue +46 -59
- package/templates/editable.vue +9 -7
- package/templates/featured.vue +7 -5
- package/templates/thumbnail.vue +6 -4
- package/utils/app.js +4 -0
- package/utils/form.js +1 -1
- package/utils/format.js +2 -2
- package/utils/history.js +5 -1
- package/utils/http.js +3 -3
- package/utils/panels/breakpoint.js +105 -0
- package/utils/settings.js +1 -1
- package/.claude/settings.local.json +0 -24
- package/.eslintrc.js +0 -41
- package/components/mixins/inputVariant.js +0 -13
- package/components/mixins/list/autoload.js +0 -212
- package/components/mixins/table/autoload.js +0 -135
- package/components/mixins/table/export.js +0 -52
- package/components/mixins/table/import.js +0 -141
- package/components/mixins/tooltip.js +0 -58
- package/components/mixins/ws/phoenixSocket.js +0 -120
- package/components/panels/bulkEdit.vue +0 -342
- package/cypress/component/component.cy.ts +0 -423
- package/cypress/e2e/glib-web/fileUploadNew.cy.ts +0 -12
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- "**"
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: "24"
|
|
20
|
+
cache: "yarn"
|
|
21
|
+
|
|
22
|
+
- name: Enable corepack
|
|
23
|
+
run: corepack enable
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: yarn install --frozen-lockfile
|
|
27
|
+
|
|
28
|
+
- name: Run lint
|
|
29
|
+
run: yarn lint
|
package/.nycrc.json
CHANGED
|
@@ -26,8 +26,12 @@
|
|
|
26
26
|
"utils/**"
|
|
27
27
|
],
|
|
28
28
|
"exclude": [
|
|
29
|
-
"actions/cables",
|
|
30
|
-
"actions/analytics",
|
|
31
|
-
"utils/private"
|
|
29
|
+
"actions/cables/*",
|
|
30
|
+
"actions/analytics/*",
|
|
31
|
+
"utils/private/*",
|
|
32
|
+
"extensions/*",
|
|
33
|
+
"components/treeView.vue",
|
|
34
|
+
"actions/files/*",
|
|
35
|
+
"actions/bottom_banners/*"
|
|
32
36
|
]
|
|
33
37
|
}
|
package/AGENTS.md
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
- For working examples on how to use `glib` UI components, see all the jbuilder
|
|
13
13
|
files located in `doc/garage/`.
|
|
14
14
|
|
|
15
|
+
## Agent commands
|
|
16
|
+
- Available agent command definitions live in `agent/commands/` (see the `.yaml` files there).
|
|
17
|
+
|
|
15
18
|
## Behaviour and tendency
|
|
16
19
|
- Read [behavior.md](doc/common/ai/behavior.md)
|
|
17
20
|
|
package/action.js
CHANGED
|
@@ -87,6 +87,7 @@ import ActionBottomBannersClose from "./actions/bottom_banners/close";
|
|
|
87
87
|
|
|
88
88
|
import ActionDetectCountry from "./actions/browsers/detectCountry";
|
|
89
89
|
import ActionDetectTimezone from "./actions/browsers/detectTimezone";
|
|
90
|
+
import ActionSetLocation from "./actions/browsers/setLocation";
|
|
90
91
|
|
|
91
92
|
import ActionsCookiesRemove from "./actions/cookies/remove";
|
|
92
93
|
import ActionsCookiesClear from "./actions/cookies/clear";
|
|
@@ -190,6 +191,7 @@ const actions = {
|
|
|
190
191
|
|
|
191
192
|
"browsers/detectCountry": ActionDetectCountry,
|
|
192
193
|
"browsers/detectTimezone": ActionDetectTimezone,
|
|
194
|
+
"browsers/setLocation": ActionSetLocation,
|
|
193
195
|
|
|
194
196
|
"cookies/remove": ActionsCookiesRemove,
|
|
195
197
|
"cookies/clear": ActionsCookiesClear,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Action from "../../action";
|
|
2
|
+
import { jsonView } from "../../store";
|
|
3
|
+
import history from "../../utils/history";
|
|
4
|
+
|
|
5
|
+
export default class {
|
|
6
|
+
execute(spec, component) {
|
|
7
|
+
Utils.type.ifString(spec.url, (url) => {
|
|
8
|
+
if (spec.replace) {
|
|
9
|
+
history.updatePage(jsonView.page, url);
|
|
10
|
+
} else {
|
|
11
|
+
history.pushPage(jsonView.page, url);
|
|
12
|
+
}
|
|
13
|
+
Action.execute(spec.onSet, component);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
package/actions/cables/push.js
CHANGED
package/actions/dialogs/close.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import Action from "../../action";
|
|
2
|
-
import {
|
|
3
|
-
import { isPresent } from "../../utils/type";
|
|
2
|
+
import { getAllFormData } from "../../components/composable/form";
|
|
4
3
|
|
|
5
4
|
export default class {
|
|
6
5
|
execute(spec, component) {
|
|
7
|
-
const
|
|
8
|
-
const formEl = inputEl.form;
|
|
9
|
-
|
|
10
|
-
const formData = getFormData(formEl);
|
|
6
|
+
const formData = getAllFormData();
|
|
11
7
|
// const values = spec.fieldNames.reduce((prev, curr) => {
|
|
12
8
|
// Object.assign(prev, { [curr]: formData[curr] });
|
|
13
9
|
// return prev;
|
|
@@ -20,7 +16,7 @@ export default class {
|
|
|
20
16
|
}, {});
|
|
21
17
|
|
|
22
18
|
Utils.type.ifObject(spec.onGet, onGet => {
|
|
23
|
-
Action.executeWithFormData(onGet, component, values)
|
|
19
|
+
Action.executeWithFormData(onGet, component, values);
|
|
24
20
|
});
|
|
25
21
|
}
|
|
26
22
|
}
|
package/actions/http/patch.js
CHANGED
package/actions/http/post.js
CHANGED
package/actions/http/put.js
CHANGED
package/actions/http/retry.js
CHANGED
package/actions/logics/set.js
CHANGED
|
@@ -2,7 +2,6 @@ import jsonLogic from 'json-logic-js';
|
|
|
2
2
|
import merge from 'lodash.merge';
|
|
3
3
|
import { nextTick } from "vue";
|
|
4
4
|
import { sanitize } from "../../components/composable/date";
|
|
5
|
-
import { htmlElement } from "../../components/helper";
|
|
6
5
|
import { isPresent } from "../../utils/type";
|
|
7
6
|
import { getFormData as _getFormData } from "../../components/composable/form";
|
|
8
7
|
|
|
@@ -95,16 +94,6 @@ export default class {
|
|
|
95
94
|
if (!targetComponent) {
|
|
96
95
|
console.warn("Component ID not found", id);
|
|
97
96
|
}
|
|
98
|
-
Utils.type.ifObject(targetComponent, (component) => {
|
|
99
|
-
const element = htmlElement(component);
|
|
100
|
-
Utils.type.ifObject(element, (el) => {
|
|
101
|
-
Utils.type.ifFunction(el.closest, () => {
|
|
102
|
-
if (!el.closest('form')) {
|
|
103
|
-
console.warn("Target component is not inside a form", component.viewId || id);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
97
|
return targetComponent;
|
|
109
98
|
}).filter((comp) => comp);
|
|
110
99
|
|
package/actions/popovers/open.js
CHANGED
package/actions/sheets/show.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { timerIds } from "./state";
|
|
2
2
|
|
|
3
3
|
export default class {
|
|
4
|
-
execute(properties
|
|
4
|
+
execute(properties) {
|
|
5
5
|
const { repeat, timerId } = properties;
|
|
6
6
|
|
|
7
7
|
if (timerIds[timerId]) {
|
|
8
|
-
|
|
8
|
+
if (repeat) {
|
|
9
|
+
clearInterval(timerIds[timerId]);
|
|
10
|
+
} else {
|
|
11
|
+
clearTimeout(timerIds[timerId]);
|
|
12
|
+
}
|
|
9
13
|
delete timerIds[timerId];
|
|
10
14
|
}
|
|
11
15
|
}
|
package/actions/timeouts/set.js
CHANGED
|
@@ -6,7 +6,11 @@ export default class {
|
|
|
6
6
|
|
|
7
7
|
// clear timeout/interval if there is same timerId exist
|
|
8
8
|
if (timerId && timerIds[timerId]) {
|
|
9
|
-
|
|
9
|
+
if (repeat) {
|
|
10
|
+
clearInterval(timerIds[timerId]);
|
|
11
|
+
} else {
|
|
12
|
+
clearTimeout(timerIds[timerId]);
|
|
13
|
+
}
|
|
10
14
|
delete timerIds[timerId];
|
|
11
15
|
}
|
|
12
16
|
|
package/actions/tours/stop.js
CHANGED
package/actions/windows/open.js
CHANGED
package/actions/windows/print.js
CHANGED
|
@@ -19,6 +19,7 @@ inputs:
|
|
|
19
19
|
- Click every button defined in {{doc_page_path}} (include nested buttons in dialogs/sheets/menus).
|
|
20
20
|
- For each button click, assert the expected result implied by its onClick action.
|
|
21
21
|
- Use one or more it blocks; revisit the page when state needs a reset.
|
|
22
|
+
- Prefer cy.contains('BUTTON_TEXT') over cy.contains('button', 'BUTTON_TEXT').
|
|
22
23
|
- Match existing project patterns (describe/it, cy.visit, selectors, etc).
|
|
23
24
|
- Use ASCII only.
|
|
24
25
|
fallback_test_template: |
|
|
@@ -44,7 +45,7 @@ inputs:
|
|
|
44
45
|
|
|
45
46
|
cy.wrap(labels).each((label) => {
|
|
46
47
|
cy.visit(url)
|
|
47
|
-
cy.contains(
|
|
48
|
+
cy.contains(label).click({ force: true })
|
|
48
49
|
cy.location('href').then((hrefAfter) => {
|
|
49
50
|
if (hrefAfter !== url) {
|
|
50
51
|
expect(hrefAfter).to.not.eq(url)
|
|
@@ -55,7 +56,7 @@ inputs:
|
|
|
55
56
|
if ($body.find(overlaySelectors).length) {
|
|
56
57
|
cy.get(overlaySelectors).should('exist')
|
|
57
58
|
} else {
|
|
58
|
-
cy.contains(
|
|
59
|
+
cy.contains(label).should('exist')
|
|
59
60
|
}
|
|
60
61
|
})
|
|
61
62
|
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
name: glib-web-stale-state-scan
|
|
3
|
+
description: >
|
|
4
|
+
Scan glib-web components for stale state risks caused by spec updates via
|
|
5
|
+
components/set or logics/set, focusing on Vue2 mixins and Vue3 setup patterns.
|
|
6
|
+
|
|
7
|
+
inputs:
|
|
8
|
+
component_dir: components
|
|
9
|
+
actions_dir: actions
|
|
10
|
+
mixins_dir: components/mixins
|
|
11
|
+
utils_dir: utils
|
|
12
|
+
report_path: /tmp/glib-web-stale-state-scan/report.md
|
|
13
|
+
|
|
14
|
+
constraints:
|
|
15
|
+
- Use utils/type.js for any type checks in helper scripts.
|
|
16
|
+
- Use ASCII only in generated outputs.
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- id: scan-setup-nonreactive
|
|
20
|
+
instruction: |
|
|
21
|
+
Find setup() blocks that read props.spec non-reactively.
|
|
22
|
+
Use rg to list matches for:
|
|
23
|
+
- "setup(" within {{inputs.component_dir}}
|
|
24
|
+
- "props.spec" or "ref(props.spec" or "= props.spec"
|
|
25
|
+
Output: setup_nonreactive_hits (file:line, matched_text).
|
|
26
|
+
|
|
27
|
+
- id: scan-options-data-created
|
|
28
|
+
instruction: |
|
|
29
|
+
Find Options API initialization that derives state once from spec.
|
|
30
|
+
Use rg for:
|
|
31
|
+
- "data()" or "created()" or "mounted()" within {{inputs.component_dir}}
|
|
32
|
+
- inspect for "this.spec" assignments in same file.
|
|
33
|
+
Output: options_init_hits (file:line, matched_text).
|
|
34
|
+
|
|
35
|
+
- id: scan-lifecycle-mixin-usage
|
|
36
|
+
instruction: |
|
|
37
|
+
Find components that implement $ready/$updated or rely on Vue2 mixins.
|
|
38
|
+
Use rg for "$ready(" or "$updated(" within {{inputs.component_dir}}.
|
|
39
|
+
Output: lifecycle_hook_hits (file:line, matched_text).
|
|
40
|
+
|
|
41
|
+
- id: scan-action-merge-usage
|
|
42
|
+
instruction: |
|
|
43
|
+
Identify where action_merge / components/set / logics/set are used.
|
|
44
|
+
Use rg for:
|
|
45
|
+
- "action_merge" within {{inputs.component_dir}} and {{inputs.actions_dir}}
|
|
46
|
+
- "components/set" or "logics/set" within {{inputs.actions_dir}}
|
|
47
|
+
Output: merge_action_hits (file:line, matched_text).
|
|
48
|
+
|
|
49
|
+
- id: correlate-risk
|
|
50
|
+
instruction: |
|
|
51
|
+
Correlate hits to flag components with stale-state risks:
|
|
52
|
+
- setup_nonreactive_hits are high risk.
|
|
53
|
+
- options_init_hits without watchers on spec are medium risk.
|
|
54
|
+
- lifecycle_hook_hits indicate reliance on $ready/$updated.
|
|
55
|
+
Produce a concise markdown report at {{inputs.report_path}} with:
|
|
56
|
+
- Summary counts by risk level.
|
|
57
|
+
- Tables of findings per risk level (file, line, reason).
|
|
58
|
+
- Note where components are likely affected by components/set/logics/set.
|
|
59
|
+
Output: report_path.
|
|
60
|
+
|
|
61
|
+
- id: review-report
|
|
62
|
+
instruction: |
|
|
63
|
+
Open {{inputs.report_path}} and verify the report is readable and concise.
|
|
64
|
+
Output: report_preview.
|
package/app.vue
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-app
|
|
2
|
+
<v-app ref="appRef" :class="pageClasses">
|
|
3
3
|
<component :is="containerComponent" :spec="formSpec" :style="'height: 100%;'">
|
|
4
|
-
<nav-layout ref="navBar"
|
|
4
|
+
<nav-layout ref="navBar" :key="`navBar-${page.key}`" :page="page" @mounted="updateMainHeight()" />
|
|
5
5
|
|
|
6
|
-
<v-progress-linear
|
|
6
|
+
<v-progress-linear v-if="vueApp.indicator" color="primary" :indeterminate="true" height="5"
|
|
7
7
|
style="position: fixed; z-index: 4">
|
|
8
8
|
</v-progress-linear>
|
|
9
9
|
|
|
10
10
|
<v-main :style="`height: ${mainHeight}px;`">
|
|
11
11
|
<v-container v-show="!vueApp.loading" :fluid="page.template == 'fullWidth'" :class="containerClasses">
|
|
12
|
-
<div
|
|
12
|
+
<div :key="`page-header-${page.key}`" class="pages-header">
|
|
13
13
|
<panels-responsive :spec="header" />
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<panels-responsive :key="`footer-${page.key}`" class="body-footer" :spec="bodyFooter" />
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
-
<div
|
|
22
|
+
<div :key="`page-footer-${page.key}`" class="pages-footer">
|
|
23
23
|
<panels-responsive :spec="footer" />
|
|
24
24
|
</div>
|
|
25
25
|
</v-container>
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
</v-sheet>
|
|
49
49
|
</Transition>
|
|
50
50
|
<div class="glib-bottomBanner">
|
|
51
|
-
<glib-component v-for="(bottomBanner, index) in Object.values(vueApp.bottomBanners)" :
|
|
52
|
-
:
|
|
51
|
+
<glib-component v-for="(bottomBanner, index) in Object.values(vueApp.bottomBanners)" :key="index"
|
|
52
|
+
:spec="bottomBanner"></glib-component>
|
|
53
53
|
</div>
|
|
54
54
|
</v-app>
|
|
55
55
|
</template>
|
|
@@ -71,6 +71,14 @@ import { nextTick } from "vue";
|
|
|
71
71
|
|
|
72
72
|
export default {
|
|
73
73
|
expose: ['updateMainHeight'],
|
|
74
|
+
components: {
|
|
75
|
+
"nav-layout": NavLayout,
|
|
76
|
+
"panels-form": FormPanel,
|
|
77
|
+
},
|
|
78
|
+
// mixins: [phoenixSocketMixin, actionCableMixin],
|
|
79
|
+
props: {
|
|
80
|
+
page: { type: Object, required: true },
|
|
81
|
+
},
|
|
74
82
|
setup(props) {
|
|
75
83
|
const filePaster = computed(() => props.page.filePaster);
|
|
76
84
|
usePasteable(filePaster);
|
|
@@ -105,14 +113,6 @@ export default {
|
|
|
105
113
|
|
|
106
114
|
return { vueApp, tooltipId, appRef };
|
|
107
115
|
},
|
|
108
|
-
components: {
|
|
109
|
-
"nav-layout": NavLayout,
|
|
110
|
-
"panels-form": FormPanel,
|
|
111
|
-
},
|
|
112
|
-
// mixins: [phoenixSocketMixin, actionCableMixin],
|
|
113
|
-
props: {
|
|
114
|
-
page: { type: Object, required: true },
|
|
115
|
-
},
|
|
116
116
|
data() {
|
|
117
117
|
return {
|
|
118
118
|
title: "...",
|
|
@@ -121,6 +121,7 @@ export default {
|
|
|
121
121
|
tabWasBlurred: false,
|
|
122
122
|
onWindowFocus: null,
|
|
123
123
|
onWindowBlur: null,
|
|
124
|
+
onWindowResize: null,
|
|
124
125
|
};
|
|
125
126
|
},
|
|
126
127
|
computed: {
|
|
@@ -147,6 +148,7 @@ export default {
|
|
|
147
148
|
},
|
|
148
149
|
containerComponent() {
|
|
149
150
|
if (this.formSpec) {
|
|
151
|
+
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
150
152
|
this.name = "panels-form";
|
|
151
153
|
return "panels-form";
|
|
152
154
|
}
|
|
@@ -161,13 +163,16 @@ export default {
|
|
|
161
163
|
},
|
|
162
164
|
},
|
|
163
165
|
watch: {
|
|
164
|
-
"vueApp.indicator": function (val
|
|
166
|
+
"vueApp.indicator": function (val) {
|
|
165
167
|
document.title = val ? "..." : this.page.title;
|
|
166
168
|
},
|
|
167
169
|
page: {
|
|
168
|
-
handler(val
|
|
170
|
+
handler(val) {
|
|
169
171
|
if (!val) return;
|
|
170
172
|
this.handleActionCable(val);
|
|
173
|
+
this.$nextTick(() => {
|
|
174
|
+
this.handlePageReady();
|
|
175
|
+
});
|
|
171
176
|
},
|
|
172
177
|
immediate: true
|
|
173
178
|
}
|
|
@@ -187,6 +192,16 @@ export default {
|
|
|
187
192
|
},
|
|
188
193
|
beforeUnmount() {
|
|
189
194
|
this.unbindForegroundListeners();
|
|
195
|
+
if (this.onWindowResize) {
|
|
196
|
+
window.removeEventListener("resize", this.onWindowResize, true);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
mounted() {
|
|
200
|
+
this.onWindowResize = () => {
|
|
201
|
+
this.updateMainHeight();
|
|
202
|
+
};
|
|
203
|
+
window.addEventListener("resize", this.onWindowResize, true);
|
|
204
|
+
this.updateMainHeight();
|
|
190
205
|
},
|
|
191
206
|
methods: {
|
|
192
207
|
closeSheet() {
|
|
@@ -228,16 +243,7 @@ export default {
|
|
|
228
243
|
this.actionCableConsumer = null;
|
|
229
244
|
}
|
|
230
245
|
},
|
|
231
|
-
|
|
232
|
-
window.addEventListener(
|
|
233
|
-
"resize",
|
|
234
|
-
(event) => {
|
|
235
|
-
this.updateMainHeight();
|
|
236
|
-
},
|
|
237
|
-
true
|
|
238
|
-
);
|
|
239
|
-
},
|
|
240
|
-
$ready() {
|
|
246
|
+
handlePageReady() {
|
|
241
247
|
this.$type.ifString(this.page.title, (title) => {
|
|
242
248
|
document.title = title;
|
|
243
249
|
});
|
package/components/_avatar.vue
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<common-badge :spec="spec">
|
|
3
3
|
<v-avatar :size="spec.size" :color="spec.backgroundColor || 'surface-variant'" :class="cssClasses">
|
|
4
|
-
<p
|
|
4
|
+
<p v-if="spec.initials" class="initials" :style="{ color: spec.initials.color || 'white' }">{{ spec.initials.text }}</p>
|
|
5
5
|
<!-- Use `img` instead of `v-img` otherwise the rounded border will not work. -->
|
|
6
6
|
<!-- <img :style="$styles()" :src="spec.url || spec.base64Data" @click="$onClick()" /> -->
|
|
7
|
-
<v-img :style="$styles()" :class="$classes()" :src="spec.url || spec.base64Data"
|
|
8
|
-
|
|
7
|
+
<v-img v-else :style="$styles()" :class="$classes()" :src="spec.url || spec.base64Data"
|
|
8
|
+
@click="$onClick()"></v-img>
|
|
9
9
|
</v-avatar>
|
|
10
10
|
</common-badge>
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script>
|
|
14
|
+
import GlibBase from "./base/glibBase.js";
|
|
14
15
|
export default {
|
|
16
|
+
extends: GlibBase,
|
|
15
17
|
props: {
|
|
16
18
|
spec: { type: Object, required: true }
|
|
17
19
|
},
|
|
18
20
|
computed: {
|
|
19
21
|
cssClasses() {
|
|
20
22
|
// Icons are nameless when used in other components, e.g. buttons
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return this.$classes();
|
|
23
|
+
return this.$classes(this.spec, "avatar");
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
26
|
};
|
package/components/_badge.vue
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-badge :color="badge.backgroundColor || 'red'" overlap :model-value="badgeExists()" :style="styles()">
|
|
3
|
-
<template
|
|
3
|
+
<template #badge>{{ badge.text }}</template>
|
|
4
4
|
<slot />
|
|
5
5
|
</v-badge>
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script>
|
|
9
|
+
import GlibBase from "./base/glibBase.js";
|
|
9
10
|
export default {
|
|
11
|
+
extends: GlibBase,
|
|
10
12
|
props: {
|
|
11
13
|
spec: { type: Object, required: true }
|
|
12
14
|
},
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
15
|
+
computed: {
|
|
16
|
+
badge() {
|
|
17
|
+
return this.spec.badge || {};
|
|
18
|
+
}
|
|
17
19
|
},
|
|
18
20
|
methods: {
|
|
19
21
|
badgeExists() {
|
package/components/_button.vue
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script>
|
|
9
|
+
import GlibBase from "./base/glibBase.js";
|
|
9
10
|
import InternalButton from "./_internal_button.vue";
|
|
10
11
|
|
|
11
12
|
export default {
|
|
12
13
|
components: {
|
|
13
14
|
"internal-button": InternalButton,
|
|
14
15
|
},
|
|
16
|
+
extends: GlibBase,
|
|
15
17
|
props: {
|
|
16
18
|
spec: { type: Object, required: true }
|
|
17
19
|
},
|