@omnitend/dashboard-for-laravel 0.41.1 → 0.41.2
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/dist/components/base/DModal.vue.d.ts +26 -2
- package/dist/components/extended/DXLoading.vue.d.ts +9 -0
- package/dist/components/extended/DXModalActions.vue.d.ts +12 -0
- package/dist/components/extended/DXSwitch.vue.d.ts +1 -1
- package/dist/components/extended/DXTable.vue.d.ts +2 -0
- package/dist/dashboard-for-laravel.js +1273 -1208
- package/dist/dashboard-for-laravel.js.map +1 -1
- package/dist/dashboard-for-laravel.umd.cjs +7 -7
- package/dist/dashboard-for-laravel.umd.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/style.css +1 -1
- package/docs/public/api-reference.json +58 -7
- package/docs/public/docs-map.md +1 -1
- package/docs/public/llms.txt +5 -2
- package/package.json +1 -1
- package/resources/css/theme.scss +12 -14
- package/resources/js/components/base/DModal.vue +13 -2
- package/resources/js/components/extended/DXLoading.vue +47 -0
- package/resources/js/components/extended/DXModalActions.vue +13 -0
- package/resources/js/components/extended/DXSwitch.vue +8 -5
- package/resources/js/components/extended/DXTable.vue +14 -7
- package/resources/js/components/extended/DXTablePagination.vue +1 -1
- package/resources/js/index.ts +3 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generated": "2026-09-
|
|
2
|
+
"generated": "2026-09-30T05:13:05.340Z",
|
|
3
3
|
"package": {
|
|
4
4
|
"name": "@omnitend/dashboard-for-laravel",
|
|
5
|
-
"version": "0.41.
|
|
5
|
+
"version": "0.41.2"
|
|
6
6
|
},
|
|
7
7
|
"components": {
|
|
8
8
|
"base": [
|
|
@@ -911,6 +911,16 @@
|
|
|
911
911
|
"props": [],
|
|
912
912
|
"events": [],
|
|
913
913
|
"slots": [
|
|
914
|
+
{
|
|
915
|
+
"name": "default",
|
|
916
|
+
"description": "",
|
|
917
|
+
"bindings": []
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"name": "actions",
|
|
921
|
+
"description": "",
|
|
922
|
+
"bindings": []
|
|
923
|
+
},
|
|
914
924
|
{
|
|
915
925
|
"name": "name",
|
|
916
926
|
"description": "",
|
|
@@ -2737,6 +2747,47 @@
|
|
|
2737
2747
|
"slots": [],
|
|
2738
2748
|
"methods": []
|
|
2739
2749
|
},
|
|
2750
|
+
{
|
|
2751
|
+
"name": "DXLoading",
|
|
2752
|
+
"category": "extended",
|
|
2753
|
+
"filePath": "resources/js/components/extended/DXLoading.vue",
|
|
2754
|
+
"description": "",
|
|
2755
|
+
"props": [
|
|
2756
|
+
{
|
|
2757
|
+
"name": "text",
|
|
2758
|
+
"type": "string",
|
|
2759
|
+
"required": false,
|
|
2760
|
+
"default": "\"Loading…\"",
|
|
2761
|
+
"description": ""
|
|
2762
|
+
},
|
|
2763
|
+
{
|
|
2764
|
+
"name": "delay",
|
|
2765
|
+
"type": "number",
|
|
2766
|
+
"required": false,
|
|
2767
|
+
"default": "300",
|
|
2768
|
+
"description": ""
|
|
2769
|
+
}
|
|
2770
|
+
],
|
|
2771
|
+
"events": [],
|
|
2772
|
+
"slots": [],
|
|
2773
|
+
"methods": []
|
|
2774
|
+
},
|
|
2775
|
+
{
|
|
2776
|
+
"name": "DXModalActions",
|
|
2777
|
+
"category": "extended",
|
|
2778
|
+
"filePath": "resources/js/components/extended/DXModalActions.vue",
|
|
2779
|
+
"description": "Shared secondary modal actions; distinct from the modal footer controls.",
|
|
2780
|
+
"props": [],
|
|
2781
|
+
"events": [],
|
|
2782
|
+
"slots": [
|
|
2783
|
+
{
|
|
2784
|
+
"name": "default",
|
|
2785
|
+
"description": "",
|
|
2786
|
+
"bindings": []
|
|
2787
|
+
}
|
|
2788
|
+
],
|
|
2789
|
+
"methods": []
|
|
2790
|
+
},
|
|
2740
2791
|
{
|
|
2741
2792
|
"name": "DXNumericField",
|
|
2742
2793
|
"category": "extended",
|
|
@@ -3079,7 +3130,7 @@
|
|
|
3079
3130
|
"name": "DXSwitch",
|
|
3080
3131
|
"category": "extended",
|
|
3081
3132
|
"filePath": "resources/js/components/extended/DXSwitch.vue",
|
|
3082
|
-
"description": "DXSwitch — a \"filled box\" toggle switch. An opinionated switch built on `DFormCheckbox` (`switch`): a bordered box sized like a `.form-control` with the label on the left and the toggle on the right, colour-coding its state. By default (`onVariant=\"success\"`) it reads the house green-on / red-off style: a light-red box with a grey toggle when off, a soft-green box with a muted green-grey toggle when on. `onVariant=\"neutral\"` (brand primary on / grey off) is for semantically-mixed switches that shouldn't imply good/bad (#158). Used standalone or, internally, by `DXField`'s `switch` field type so a form switch and a lone switch share one look. Usage: ```vue <DXSwitch v-model=\"isCurrent\" label=\"Product is current\" /> ``` For a form field, prefer a `DXField`/`DXForm` `type: 'switch'`; reach for `DXSwitch` directly when you want the styled toggle outside a form. Pass a `label` prop for simple text, or the default slot for richer label content.",
|
|
3133
|
+
"description": "DXSwitch — a \"filled box\" toggle switch. An opinionated switch built on `DFormCheckbox` (`switch`): a bordered box sized like a `.form-control` with the label on the left and the toggle on the right, colour-coding its state. By default (`onVariant=\"success\"`) it reads the house green-on / red-off style: a light-red box with a muted red-grey toggle when off, a soft-green box with a muted green-grey toggle when on. `onVariant=\"neutral\"` (brand primary on / grey off) is for semantically-mixed switches that shouldn't imply good/bad (#158). Used standalone or, internally, by `DXField`'s `switch` field type so a form switch and a lone switch share one look. Usage: ```vue <DXSwitch v-model=\"isCurrent\" label=\"Product is current\" /> ``` For a form field, prefer a `DXField`/`DXForm` `type: 'switch'`; reach for `DXSwitch` directly when you want the styled toggle outside a form. Pass a `label` prop for simple text, or the default slot for richer label content.",
|
|
3083
3134
|
"props": [
|
|
3084
3135
|
{
|
|
3085
3136
|
"name": "modelValue",
|
|
@@ -3117,7 +3168,7 @@
|
|
|
3117
3168
|
"name": "size",
|
|
3118
3169
|
"type": "\"sm\"",
|
|
3119
3170
|
"required": false,
|
|
3120
|
-
"description": "`\"sm\"` renders a compact
|
|
3171
|
+
"description": "`\"sm\"` renders a compact rounded pill (a few px shorter than the default, which\nmatches the input height) for dense rows that repeat the switch per item (a\nper-line visibility toggle in a modal). Omit for the standard size, which\nlines the switch up with the `.form-control`\nheight so a switch lines up with inputs beside it."
|
|
3121
3172
|
}
|
|
3122
3173
|
],
|
|
3123
3174
|
"events": [
|
|
@@ -4000,7 +4051,7 @@
|
|
|
4000
4051
|
"name": "DXTablePagination",
|
|
4001
4052
|
"category": "extended",
|
|
4002
4053
|
"filePath": "resources/js/components/extended/DXTablePagination.vue",
|
|
4003
|
-
"description": "
|
|
4054
|
+
"description": "Pagination + per-page footer shared by `DXTable` and standalone tables. Renders the pager, the per-page selector, and the \"X to Y out of Z items\" info line (with the \"Filtered from N\" note when a column filter is active). Extracted because `DXTable` used to carry three byte-identical copies of this footer — one per data mode (client-side / inertia / provider) — that differed only in which `PaginationData` object and page-change handler they used, so every footer fix had to be written three times (#123). `DXTable` now derives the active pagination + handler and renders this once. It owns its own `:deep(.pagination …)` styling (rather than leaving it in `DXTable`), because a scoped `:deep()` in `DXTable` would not reach the pager once it lives in a child component — the scope-id doesn't cross the boundary. Anchoring the rules on this component's own `.dx-table-pagination` root (a plain element it owns) gives the scope-id a deterministic host. In a row too narrow for the full windowed pager, the number strip collapses to a \"current / last\" status with Previous/Next either side (#162). The decision is CONTAINER-driven, not viewport-driven — see `compactThreshold`.",
|
|
4004
4055
|
"props": [
|
|
4005
4056
|
{
|
|
4006
4057
|
"name": "pagination",
|
|
@@ -4163,8 +4214,8 @@
|
|
|
4163
4214
|
]
|
|
4164
4215
|
},
|
|
4165
4216
|
"stats": {
|
|
4166
|
-
"totalComponents":
|
|
4217
|
+
"totalComponents": 86,
|
|
4167
4218
|
"baseComponents": 60,
|
|
4168
|
-
"extendedComponents":
|
|
4219
|
+
"extendedComponents": 26
|
|
4169
4220
|
}
|
|
4170
4221
|
}
|
package/docs/public/docs-map.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Documentation Map
|
|
2
2
|
|
|
3
3
|
> Auto-generated hierarchical overview of all documentation
|
|
4
|
-
> Last updated: 2026-09-
|
|
4
|
+
> Last updated: 2026-09-30T05:13:05.394Z
|
|
5
5
|
|
|
6
6
|
This file provides a complete map of all available documentation for AI agents and developers.
|
|
7
7
|
|
package/docs/public/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Vue 3 dashboard components for Laravel with Bootstrap Vue Next
|
|
4
4
|
>
|
|
5
|
-
> A dual-package library (NPM + Composer) providing
|
|
5
|
+
> A dual-package library (NPM + Composer) providing 76 Vue 3 components for building Laravel dashboards with Bootstrap Vue Next.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -84,7 +84,7 @@ Lightweight type-safe wrappers around Bootstrap Vue Next components providing AP
|
|
|
84
84
|
- [DToaster](/components/base/dtoaster): Bootstrap Vue Next Toaster wrapper
|
|
85
85
|
- [DTooltip](/components/base/dtooltip): Bootstrap Vue Next Tooltip wrapper
|
|
86
86
|
|
|
87
|
-
## Extended Components (
|
|
87
|
+
## Extended Components (16 components)
|
|
88
88
|
|
|
89
89
|
Custom dashboard components with advanced functionality beyond Bootstrap Vue Next.
|
|
90
90
|
|
|
@@ -96,10 +96,13 @@ Custom dashboard components with advanced functionality beyond Bootstrap Vue Nex
|
|
|
96
96
|
- [DXField](/components/extended/dxfield): Single-field renderer for any field type with value/span/info/hint slots
|
|
97
97
|
- [DXFieldLabel](/components/extended/dxfieldlabel): Extended dashboard component
|
|
98
98
|
- [DXForm](/components/extended/dxform): Form renderer driven by field definitions, with optional tabs, conditional fields, per-field slots, async options, nested repeaters, and auto error-tab switching
|
|
99
|
+
- [DXLoading](/components/extended/dxloading): Extended dashboard component
|
|
100
|
+
- [DXModalActions](/components/extended/dxmodalactions): Extended dashboard component
|
|
99
101
|
- [DXRepeater](/components/extended/dxrepeater): Repeatable nested sub-form (field array) primitive
|
|
100
102
|
- [DXStatCard](/components/extended/dxstatcard): Extended dashboard component
|
|
101
103
|
- [DXSwitch](/components/extended/dxswitch): Extended dashboard component
|
|
102
104
|
- [DXTable](/components/extended/dxtable): Data table with pagination, filtering, and sorting
|
|
105
|
+
- [DXTablePagination](/components/extended/dxtablepagination): Extended dashboard component
|
|
103
106
|
- [DXUserAvatar](/components/extended/dxuseravatar): Extended dashboard component
|
|
104
107
|
|
|
105
108
|
## Composables
|
package/package.json
CHANGED
package/resources/css/theme.scss
CHANGED
|
@@ -694,6 +694,11 @@ $bootstrap-icons-font-src: url("bootstrap-icons/font/fonts/bootstrap-icons.woff2
|
|
|
694
694
|
vertical-align: middle;
|
|
695
695
|
}
|
|
696
696
|
|
|
697
|
+
// Column help uses the table's header colour rather than the form-label ink.
|
|
698
|
+
.table > thead th .dx-field-label__text {
|
|
699
|
+
color: inherit;
|
|
700
|
+
}
|
|
701
|
+
|
|
697
702
|
.table > thead {
|
|
698
703
|
vertical-align: middle;
|
|
699
704
|
}
|
|
@@ -750,7 +755,7 @@ $bootstrap-icons-font-src: url("bootstrap-icons/font/fonts/bootstrap-icons.woff2
|
|
|
750
755
|
// theme `@import`s `bootstrap-icons/font/bootstrap-icons` (declaring the
|
|
751
756
|
// `@font-face`), and #77's post-build extraction ships that woff2 with the
|
|
752
757
|
// stylesheet — so this needs no new dependency and no data-URI. Values signed
|
|
753
|
-
// off after one padding iteration in the
|
|
758
|
+
// off after one padding iteration in the interim UI; the glyph metrics
|
|
754
759
|
// are tunable via the variables below.
|
|
755
760
|
$dx-dropdown-caret-size: 0.75em; // glyph size relative to the label
|
|
756
761
|
$dx-dropdown-caret-gap: 0.4em; // space between label and chevron
|
|
@@ -806,23 +811,16 @@ $dx-switch-on-soft: map.get(map.get($dx-variants, "success"), "soft-bg"); // #cd
|
|
|
806
811
|
--dx-switch-off-well: #{color.mix($dx-switch-off, #fff, 10%)};
|
|
807
812
|
--dx-switch-off-line: #{color.mix($dx-switch-off, #fff, 45%)};
|
|
808
813
|
--dx-switch-off-ink: #{color.mix($dx-switch-off, #000, 30%)};
|
|
809
|
-
--dx-switch-pill: var(--bs-gray-400, #ced4da);
|
|
814
|
+
--dx-switch-pill: var(--bs-gray-400, #ced4da);
|
|
815
|
+
--dx-switch-off-pill: #{color.mix(map.get(map.get($dx-variants, "danger"), "soft-text"), $gray-400, 50%)};
|
|
810
816
|
--dx-switch-on-pill: #{color.mix(map.get(map.get($dx-variants, "success"), "soft-text"), $gray-400, 50%)};
|
|
811
817
|
}
|
|
812
818
|
|
|
813
|
-
//
|
|
814
|
-
//
|
|
815
|
-
//
|
|
816
|
-
// reads visibly HIGH beside the text (same optical-metrics issue as the B14
|
|
817
|
-
// dropdown caret). `0.325em` lands the box centre on Poppins' visual centre —
|
|
818
|
-
// judged against a rendered filmstrip (0.25/0.30/0.325/0.35em) with Poppins
|
|
819
|
-
// loaded, not from the maths. A top MARGIN (not flex-centring) is deliberate:
|
|
820
|
-
// it aligns to the first line, so a multi-line label keeps the box on line one
|
|
821
|
-
// rather than floating to the block's vertical centre. DXSwitch is unaffected —
|
|
822
|
-
// it flex-centres and zeroes this margin on its inner input at higher
|
|
823
|
-
// specificity (`.dx-switch :deep(.form-check-input) { margin: 0 }`).
|
|
819
|
+
// Centre checkboxes/radios on the first label line using their actual size.
|
|
820
|
+
// The old em offset assumed a 1em box; these controls are now 1.25rem tall.
|
|
821
|
+
// A margin keeps wrapped labels aligned to line one rather than the whole block.
|
|
824
822
|
.form-check-input {
|
|
825
|
-
margin-top:
|
|
823
|
+
margin-top: calc((1lh - #{$form-check-input-width}) / 2);
|
|
826
824
|
}
|
|
827
825
|
|
|
828
826
|
.form-switch .form-check-input {
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<BModal v-bind="$attrs">
|
|
3
|
-
<template
|
|
2
|
+
<BModal size="lg" v-bind="$attrs">
|
|
3
|
+
<template #default="slotProps">
|
|
4
|
+
<slot v-bind="slotProps" />
|
|
5
|
+
<DXModalActions v-if="$slots.actions" class="mt-3">
|
|
6
|
+
<slot name="actions" v-bind="slotProps" />
|
|
7
|
+
</DXModalActions>
|
|
8
|
+
</template>
|
|
9
|
+
<template v-for="name in forwardedSlots" #[name]="slotProps">
|
|
4
10
|
<slot :name="name" v-bind="slotProps" />
|
|
5
11
|
</template>
|
|
6
12
|
</BModal>
|
|
7
13
|
</template>
|
|
8
14
|
|
|
9
15
|
<script setup lang="ts">
|
|
16
|
+
import { computed, useSlots } from "vue";
|
|
10
17
|
import { BModal } from "bootstrap-vue-next";
|
|
18
|
+
import DXModalActions from "../extended/DXModalActions.vue";
|
|
19
|
+
|
|
20
|
+
const slots = useSlots();
|
|
21
|
+
const forwardedSlots = computed(() => Object.keys(slots).filter(name => name !== "default" && name !== "actions"));
|
|
11
22
|
</script>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-if="isVisible"
|
|
4
|
+
class="dx-loading text-center text-muted py-5"
|
|
5
|
+
role="status"
|
|
6
|
+
aria-live="polite"
|
|
7
|
+
>
|
|
8
|
+
<DSpinner variant="primary" aria-hidden="true" />
|
|
9
|
+
<div class="mt-2">{{ text }}</div>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
15
|
+
import DSpinner from "../base/DSpinner.vue";
|
|
16
|
+
|
|
17
|
+
const props = withDefaults(
|
|
18
|
+
defineProps<{
|
|
19
|
+
text?: string;
|
|
20
|
+
delay?: number;
|
|
21
|
+
}>(),
|
|
22
|
+
{
|
|
23
|
+
text: "Loading…",
|
|
24
|
+
delay: 300,
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const isVisible = ref(false);
|
|
29
|
+
let showTimer: ReturnType<typeof setTimeout> | undefined;
|
|
30
|
+
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
if (props.delay <= 0) {
|
|
33
|
+
isVisible.value = true;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
showTimer = setTimeout(() => {
|
|
38
|
+
isVisible.value = true;
|
|
39
|
+
}, props.delay);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
onBeforeUnmount(() => {
|
|
43
|
+
if (showTimer !== undefined) {
|
|
44
|
+
clearTimeout(showTimer);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Shared secondary modal actions; distinct from the modal footer controls. -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="dx-modal-actions"><slot /></div>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<style scoped>
|
|
7
|
+
.dx-modal-actions {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
align-items: stretch;
|
|
11
|
+
gap: 0.75rem;
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
An opinionated switch built on `DFormCheckbox` (`switch`): a bordered box sized
|
|
6
6
|
like a `.form-control` with the label on the left and the toggle on the right,
|
|
7
7
|
colour-coding its state. By default (`onVariant="success"`) it reads the house
|
|
8
|
-
green-on / red-off style: a light-red box with a grey toggle when off, a
|
|
8
|
+
green-on / red-off style: a light-red box with a muted red-grey toggle when off, a
|
|
9
9
|
soft-green box with a muted green-grey toggle when on. `onVariant="neutral"` (brand primary on / grey off)
|
|
10
10
|
is for semantically-mixed switches that shouldn't imply good/bad (#158). Used
|
|
11
11
|
standalone or, internally, by `DXField`'s `switch` field type so a form switch
|
|
@@ -64,7 +64,7 @@ interface Props {
|
|
|
64
64
|
*/
|
|
65
65
|
onVariant?: "success" | "neutral";
|
|
66
66
|
/**
|
|
67
|
-
* `"sm"` renders a compact
|
|
67
|
+
* `"sm"` renders a compact rounded pill (a few px shorter than the default, which
|
|
68
68
|
* matches the input height) for dense rows that repeat the switch per item (a
|
|
69
69
|
* per-line visibility toggle in a modal). Omit for the standard size, which
|
|
70
70
|
* lines the switch up with the `.form-control`
|
|
@@ -147,6 +147,7 @@ defineOptions({
|
|
|
147
147
|
chrome tightens. */
|
|
148
148
|
.dx-switch--sm :deep(.form-check) {
|
|
149
149
|
font-size: 0.875rem;
|
|
150
|
+
border-radius: var(--bs-border-radius-pill, 50rem);
|
|
150
151
|
min-height: auto;
|
|
151
152
|
padding: 0.25rem 0.625rem;
|
|
152
153
|
}
|
|
@@ -173,6 +174,10 @@ defineOptions({
|
|
|
173
174
|
glance (the house style). `success` (default) is green ON / light-red OFF;
|
|
174
175
|
`neutral` keeps a brand primary panel for mixed-semantics switches. Pair with
|
|
175
176
|
`textWhenTrue`/`textWhenFalse` so the LABEL also names each state. */
|
|
177
|
+
.dx-switch--success {
|
|
178
|
+
--dx-switch-pill: var(--dx-switch-off-pill);
|
|
179
|
+
}
|
|
180
|
+
|
|
176
181
|
.dx-switch--success :deep(.form-check) {
|
|
177
182
|
background-color: var(--dx-switch-off-bg);
|
|
178
183
|
border-color: var(--dx-switch-off-line);
|
|
@@ -189,14 +194,13 @@ defineOptions({
|
|
|
189
194
|
|
|
190
195
|
.dx-switch--success.dx-switch--on :deep(.form-check-label) {
|
|
191
196
|
color: var(--dx-switch-on-ink);
|
|
192
|
-
font-weight: 500;
|
|
193
197
|
}
|
|
194
198
|
|
|
195
199
|
.dx-switch--success.dx-switch--on {
|
|
196
200
|
--dx-switch-pill: var(--dx-switch-on-pill);
|
|
197
201
|
}
|
|
198
202
|
|
|
199
|
-
/* Muted pill with a white sliding thumb: green-grey ON,
|
|
203
|
+
/* Muted pill with a white sliding thumb: green-grey ON, red-grey OFF.
|
|
200
204
|
The stronger box colour and position continue to communicate the state. Explicit `:checked`/`:focus` selectors so they out-specify the global
|
|
201
205
|
`.form-switch .form-check-input:checked` rule. */
|
|
202
206
|
.dx-switch--success :deep(.form-check-input),
|
|
@@ -220,6 +224,5 @@ defineOptions({
|
|
|
220
224
|
|
|
221
225
|
.dx-switch--neutral.dx-switch--on :deep(.form-check-label) {
|
|
222
226
|
color: var(--bs-primary-text-emphasis);
|
|
223
|
-
font-weight: 500;
|
|
224
227
|
}
|
|
225
228
|
</style>
|
|
@@ -174,7 +174,10 @@
|
|
|
174
174
|
<template v-for="field in fields" :key="`head-${field.key}`" #[`head(${field.key})`]="{ label }">
|
|
175
175
|
<div class="d-flex align-items-center justify-content-between gap-2">
|
|
176
176
|
<div class="flex-grow-1">
|
|
177
|
-
<div class="fw-semibold">
|
|
177
|
+
<div class="fw-semibold">
|
|
178
|
+
<DXFieldLabel v-if="field.info" :label="headerLabel(field, label)" :info="field.info" />
|
|
179
|
+
<template v-else>{{ headerLabel(field, label) }}</template>
|
|
180
|
+
</div>
|
|
178
181
|
<small v-if="field.hint" class="text-muted d-block" style="font-weight: normal;">{{ field.hint }}</small>
|
|
179
182
|
</div>
|
|
180
183
|
|
|
@@ -326,6 +329,7 @@ import DTable from "../base/DTable.vue";
|
|
|
326
329
|
import DFormInput from "../base/DFormInput.vue";
|
|
327
330
|
import DFormSelect from "../base/DFormSelect.vue";
|
|
328
331
|
import DAutocomplete from "../base/DAutocomplete.vue";
|
|
332
|
+
import DXFieldLabel from "./DXFieldLabel.vue";
|
|
329
333
|
import DButton from "../base/DButton.vue";
|
|
330
334
|
import DXTablePagination from "./DXTablePagination.vue";
|
|
331
335
|
import DXTableEditorModal from "./DXTableEditorModal.vue";
|
|
@@ -404,6 +408,8 @@ export interface TableField {
|
|
|
404
408
|
filterAllText?: string;
|
|
405
409
|
sortable?: boolean;
|
|
406
410
|
hint?: string;
|
|
411
|
+
/** Help revealed from a focusable info icon beside the column label. */
|
|
412
|
+
info?: string;
|
|
407
413
|
/**
|
|
408
414
|
* The inline filter control for this column, or `false`/omit for none. See
|
|
409
415
|
* `FilterType`. `'select'` (typeahead) and `'select-native'` (plain
|
|
@@ -1767,6 +1773,7 @@ watch(clientSideLastPage, (lastPage) => {
|
|
|
1767
1773
|
// Client-side paginated items (final output)
|
|
1768
1774
|
const clientSidePaginatedItems = computed<T[]>(() => {
|
|
1769
1775
|
if (!isClientSideMode.value) return [];
|
|
1776
|
+
if (!props.showPagination) return clientSideSortedItems.value;
|
|
1770
1777
|
|
|
1771
1778
|
const perPage = effectivePerPage.value;
|
|
1772
1779
|
const start = (clientSidePage.value - 1) * perPage;
|
|
@@ -1783,19 +1790,19 @@ const clientSidePagination = computed<PaginationData>(() => {
|
|
|
1783
1790
|
const lastPage = clientSideLastPage.value;
|
|
1784
1791
|
|
|
1785
1792
|
// Same clamped page the slice uses — see `clientSidePage` (#118).
|
|
1786
|
-
const validPage = clientSidePage.value;
|
|
1793
|
+
const validPage = props.showPagination ? clientSidePage.value : 1;
|
|
1787
1794
|
|
|
1788
|
-
const from = total > 0 ? (validPage - 1) * perPage + 1 : 0;
|
|
1789
|
-
const to = Math.min(validPage * perPage, total);
|
|
1795
|
+
const from = total > 0 ? (props.showPagination ? (validPage - 1) * perPage + 1 : 1) : 0;
|
|
1796
|
+
const to = props.showPagination ? Math.min(validPage * perPage, total) : total;
|
|
1790
1797
|
|
|
1791
1798
|
return {
|
|
1792
1799
|
current_page: validPage,
|
|
1793
|
-
per_page: perPage,
|
|
1800
|
+
per_page: props.showPagination ? perPage : Math.max(1, total),
|
|
1794
1801
|
total,
|
|
1795
1802
|
total_unfiltered: totalUnfiltered !== total ? totalUnfiltered : undefined,
|
|
1796
1803
|
from,
|
|
1797
1804
|
to,
|
|
1798
|
-
last_page: lastPage,
|
|
1805
|
+
last_page: props.showPagination ? lastPage : 1,
|
|
1799
1806
|
};
|
|
1800
1807
|
});
|
|
1801
1808
|
|
|
@@ -1822,7 +1829,7 @@ const handleClientSidePageChange = (page: number) => {
|
|
|
1822
1829
|
// Computed: determine if per-page selector should be shown
|
|
1823
1830
|
// Hide it when total items is less than the smallest page size option
|
|
1824
1831
|
const shouldShowPerPageSelector = computed(() => {
|
|
1825
|
-
if (!props.showPerPageSelector) return false;
|
|
1832
|
+
if (!props.showPagination || !props.showPerPageSelector) return false;
|
|
1826
1833
|
|
|
1827
1834
|
const smallestOption = Math.min(...props.perPageOptions);
|
|
1828
1835
|
const total = isClientSideMode.value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
-
|
|
3
|
+
Pagination + per-page footer shared by `DXTable` and standalone tables. Renders the pager, the
|
|
4
4
|
per-page selector, and the "X to Y out of Z items" info line (with the
|
|
5
5
|
"Filtered from N" note when a column filter is active).
|
|
6
6
|
|
package/resources/js/index.ts
CHANGED
|
@@ -9,6 +9,8 @@ export { default as DXDashboard } from "./components/extended/DXDashboard.vue";
|
|
|
9
9
|
export { default as DXForm } from "./components/extended/DXForm.vue";
|
|
10
10
|
export { default as DXField } from "./components/extended/DXField.vue";
|
|
11
11
|
export { default as DXFieldLabel } from "./components/extended/DXFieldLabel.vue";
|
|
12
|
+
export { default as DXModalActions } from "./components/extended/DXModalActions.vue";
|
|
13
|
+
export { default as DXLoading } from "./components/extended/DXLoading.vue";
|
|
12
14
|
export { default as DXSwitch } from "./components/extended/DXSwitch.vue";
|
|
13
15
|
export { default as DXCurrencyInput } from "./components/extended/DXCurrencyInput.vue";
|
|
14
16
|
export { default as DXStatCard } from "./components/extended/DXStatCard.vue";
|
|
@@ -23,6 +25,7 @@ export { default as DXRepeater } from "./components/extended/DXRepeater.vue";
|
|
|
23
25
|
*/
|
|
24
26
|
export { default as DXBasicForm } from "./components/extended/DXBasicForm.vue";
|
|
25
27
|
export { default as DXTable } from "./components/extended/DXTable.vue";
|
|
28
|
+
export { default as DXTablePagination } from "./components/extended/DXTablePagination.vue";
|
|
26
29
|
export { default as DXDashboardSidebar } from "./components/extended/DXDashboardSidebar.vue";
|
|
27
30
|
export { default as DXDashboardNavbar } from "./components/extended/DXDashboardNavbar.vue";
|
|
28
31
|
export { default as DXUserAvatar } from "./components/extended/DXUserAvatar.vue";
|