@innertia-solutions/innertia-nuxt 0.1.1
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/auto-publish.yml +64 -0
- package/.github/workflows/release.yml +59 -0
- package/README.md +60 -0
- package/app.config.ts +70 -0
- package/components/Admin/Base.vue +144 -0
- package/components/Admin/Header.vue +32 -0
- package/components/Admin/Page.vue +65 -0
- package/components/Admin/PageHeader.vue +31 -0
- package/components/App/Button.vue +59 -0
- package/components/App/DevEnvironmentBar.vue +43 -0
- package/components/App/Dropdown.vue +286 -0
- package/components/App/EmptyState.vue +433 -0
- package/components/App/LoadingState.vue +40 -0
- package/components/App/PageLoadingSpinner.vue +118 -0
- package/components/App/PreviewDock.vue +64 -0
- package/components/App/SwitchColorTheme.vue +51 -0
- package/components/App/Tag.vue +193 -0
- package/components/DataTable.vue +713 -0
- package/components/Forms/DatePicker.vue +255 -0
- package/components/Forms/Input.vue +75 -0
- package/components/Forms/Select.vue +100 -0
- package/components/Forms/SelectServer.vue +726 -0
- package/components/Layout/Admin.vue +32 -0
- package/components/Layout/Auth.vue +29 -0
- package/components/Layout/SidebarWithAppColumn.vue +388 -0
- package/components/Layout/TopBar.vue +113 -0
- package/components/MobileBlocker.vue +85 -0
- package/components/MobileLoginPicker.vue +83 -0
- package/components/Modal/Base.vue +29 -0
- package/components/Modal/DeleteConfirm.vue +48 -0
- package/components/Modal.vue +103 -0
- package/components/Nav/Tabs.vue +55 -0
- package/components/PermissionsTree.vue +272 -0
- package/components/Table/Database.vue +183 -0
- package/components/Table/DownloadDropdown.vue +111 -0
- package/components/Table/Enterprise.vue +540 -0
- package/components/Table/FilterDropdown.vue +226 -0
- package/components/Table/Grid.vue +62 -0
- package/components/Table/Kanban.vue +188 -0
- package/components/Table/List.vue +128 -0
- package/components/Table/PreviewTimeline.vue +118 -0
- package/components/Table/Standard.vue +1217 -0
- package/components/Table/index.vue +974 -0
- package/components/TableExportable.vue +172 -0
- package/components/TableFilter.vue +93 -0
- package/components/Toast/Alert.vue +113 -0
- package/components/Toast/Container.vue +34 -0
- package/components/Toast/Notification.vue +45 -0
- package/components/Toast/Process.vue +88 -0
- package/composables/useApi.js +95 -0
- package/composables/useApp.ts +46 -0
- package/composables/useAuth.js +82 -0
- package/composables/useContext.js +44 -0
- package/composables/useDate.js +241 -0
- package/composables/useDevice.js +21 -0
- package/composables/useDockedPreviews.js +56 -0
- package/composables/useDownload.js +87 -0
- package/composables/useEntity.js +82 -0
- package/composables/useForm.js +119 -0
- package/composables/useInnertiaMode.ts +25 -0
- package/composables/useMobileGuard.ts +81 -0
- package/composables/useNotifications.js +22 -0
- package/composables/usePermissions.js +23 -0
- package/composables/useRealtime.js +123 -0
- package/composables/useRequestInterceptors.js +27 -0
- package/composables/useRoles.js +53 -0
- package/composables/useRutFormatter.js +39 -0
- package/composables/useTable.ts +94 -0
- package/composables/useTablePreferences.ts +33 -0
- package/composables/useTenant.js +27 -0
- package/composables/useTimeAgo.js +37 -0
- package/composables/useToast.js +69 -0
- package/composables/useUserRealtime.js +17 -0
- package/composables/useUsers.js +111 -0
- package/css/themes/autumn.css +401 -0
- package/css/themes/bubblegum.css +408 -0
- package/css/themes/cashmere.css +412 -0
- package/css/themes/harvest.css +416 -0
- package/css/themes/moon.css +140 -0
- package/css/themes/ocean.css +273 -0
- package/css/themes/olive.css +413 -0
- package/css/themes/retro.css +431 -0
- package/css/themes/theme.css +725 -0
- package/error.vue +78 -0
- package/middleware/01.detect-subdomain.global.ts +43 -0
- package/middleware/02.validate-tenant.global.ts +67 -0
- package/middleware/03.apps.global.ts +88 -0
- package/middleware/auth.ts +9 -0
- package/middleware/guest.ts +9 -0
- package/nuxt.config.ts +42 -0
- package/package.json +60 -0
- package/pages/tenant-error.vue +50 -0
- package/plugins/api-auth.ts +12 -0
- package/plugins/api-tenant.client.ts +21 -0
- package/plugins/appearance.ts +8 -0
- package/plugins/auth-init.ts +34 -0
- package/plugins/dark-state.client.ts +29 -0
- package/plugins/dockedPreviewsSync.client.js +17 -0
- package/plugins/preline.client.ts +68 -0
- package/plugins/theme.client.ts +7 -0
- package/plugins/vue-query.ts +29 -0
- package/public/init-theme.js +15 -0
- package/spark.css +721 -0
- package/stores/auth.js +130 -0
- package/stores/dockedPreviews.js +34 -0
- package/stores/notifications.js +24 -0
- package/stores/tenant.js +54 -0
- package/stores/toast.js +129 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
// Props
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
triggerText: {
|
|
5
|
+
type: String,
|
|
6
|
+
default: "Dropdown",
|
|
7
|
+
},
|
|
8
|
+
triggerLabel: {
|
|
9
|
+
type: String,
|
|
10
|
+
default: "Dropdown menu",
|
|
11
|
+
},
|
|
12
|
+
triggerClass: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: "",
|
|
15
|
+
},
|
|
16
|
+
triggerSize: {
|
|
17
|
+
type: String,
|
|
18
|
+
default: "sm",
|
|
19
|
+
validator: (value) => ["xs", "sm", "md", "lg"].includes(value),
|
|
20
|
+
},
|
|
21
|
+
triggerSeverity: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: "secondary",
|
|
24
|
+
validator: (value) =>
|
|
25
|
+
["primary", "secondary", "success", "danger", "warning", "info"].includes(
|
|
26
|
+
value
|
|
27
|
+
),
|
|
28
|
+
},
|
|
29
|
+
triggerOutline: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: true,
|
|
32
|
+
},
|
|
33
|
+
wrapperClass: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: "",
|
|
36
|
+
},
|
|
37
|
+
menuClass: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: "",
|
|
40
|
+
},
|
|
41
|
+
placement: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: "bottom-right",
|
|
44
|
+
validator: (value) =>
|
|
45
|
+
[
|
|
46
|
+
"bottom",
|
|
47
|
+
"bottom-left",
|
|
48
|
+
"bottom-right",
|
|
49
|
+
"top",
|
|
50
|
+
"top-left",
|
|
51
|
+
"top-right",
|
|
52
|
+
"left",
|
|
53
|
+
"right",
|
|
54
|
+
].includes(value),
|
|
55
|
+
},
|
|
56
|
+
items: {
|
|
57
|
+
type: Array,
|
|
58
|
+
default: () => [],
|
|
59
|
+
},
|
|
60
|
+
autoClose: {
|
|
61
|
+
type: String,
|
|
62
|
+
default: "true",
|
|
63
|
+
validator: (value) =>
|
|
64
|
+
["true", "false", "inside", "outside"].includes(value),
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Emits
|
|
69
|
+
const emit = defineEmits(["item-click", "open", "close"]);
|
|
70
|
+
|
|
71
|
+
// Reactive data
|
|
72
|
+
const triggerId = ref(
|
|
73
|
+
`dropdown-trigger-${Math.random().toString(36).substr(2, 9)}`
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Computed
|
|
77
|
+
const triggerSizeClasses = computed(() => {
|
|
78
|
+
const sizes = {
|
|
79
|
+
xs: "py-0.5 px-2 text-xs font-light",
|
|
80
|
+
sm: "py-1 px-2.5 text-sm font-light",
|
|
81
|
+
md: "py-2.5 px-3 text-sm font-light",
|
|
82
|
+
lg: "py-3 px-4 text-base font-light",
|
|
83
|
+
};
|
|
84
|
+
return sizes[props.triggerSize] || sizes.sm;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const triggerSeverityClasses = computed(() => {
|
|
88
|
+
const base = "rounded-lg border transition-colors";
|
|
89
|
+
const variants = {
|
|
90
|
+
primary: props.triggerOutline
|
|
91
|
+
? "border-blue-600 text-blue-600 hover:bg-blue-50 dark:border-blue-500 dark:text-blue-500 dark:hover:bg-blue-900/20"
|
|
92
|
+
: "border-transparent bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700",
|
|
93
|
+
secondary: props.triggerOutline
|
|
94
|
+
? "border-card-line text-foreground hover:bg-muted-hover"
|
|
95
|
+
: "border-transparent bg-muted text-foreground hover:bg-muted-hover",
|
|
96
|
+
success: props.triggerOutline
|
|
97
|
+
? "border-green-600 text-green-600 hover:bg-green-50 dark:border-green-500 dark:text-green-500 dark:hover:bg-green-900/20"
|
|
98
|
+
: "border-transparent bg-green-600 text-white hover:bg-green-700 dark:bg-green-600 dark:hover:bg-green-700",
|
|
99
|
+
danger: props.triggerOutline
|
|
100
|
+
? "border-red-600 text-red-600 hover:bg-red-50 dark:border-red-500 dark:text-red-500 dark:hover:bg-red-900/20"
|
|
101
|
+
: "border-transparent bg-red-600 text-white hover:bg-red-700 dark:bg-red-600 dark:hover:bg-red-700",
|
|
102
|
+
warning: props.triggerOutline
|
|
103
|
+
? "border-yellow-600 text-yellow-600 hover:bg-yellow-50 dark:border-yellow-500 dark:text-yellow-500 dark:hover:bg-yellow-900/20"
|
|
104
|
+
: "border-transparent bg-yellow-600 text-white hover:bg-yellow-700 dark:bg-yellow-600 dark:hover:bg-yellow-700",
|
|
105
|
+
info: props.triggerOutline
|
|
106
|
+
? "border-cyan-600 text-cyan-600 hover:bg-cyan-50 dark:border-cyan-500 dark:text-cyan-500 dark:hover:bg-cyan-900/20"
|
|
107
|
+
: "border-transparent bg-cyan-600 text-white hover:bg-cyan-700 dark:bg-cyan-600 dark:hover:bg-cyan-700",
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
return `${base} ${variants[props.triggerSeverity] || variants.secondary}`;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const triggerButtonClasses = computed(() => {
|
|
114
|
+
const disabled = "disabled:opacity-50 disabled:pointer-events-none";
|
|
115
|
+
const focus =
|
|
116
|
+
"focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-offset-gray-800";
|
|
117
|
+
|
|
118
|
+
return `hs-dropdown-toggle ${triggerSizeClasses.value} ${triggerSeverityClasses.value} ${disabled} ${focus} inline-flex justify-center items-center gap-x-2 ${props.triggerClass}`;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const placementClass = computed(() => {
|
|
122
|
+
const placements = {
|
|
123
|
+
bottom: "[--placement:bottom]",
|
|
124
|
+
"bottom-left": "[--placement:bottom-left]",
|
|
125
|
+
"bottom-right": "[--placement:bottom-right]",
|
|
126
|
+
top: "[--placement:top]",
|
|
127
|
+
"top-left": "[--placement:top-left]",
|
|
128
|
+
"top-right": "[--placement:top-right]",
|
|
129
|
+
left: "[--placement:left]",
|
|
130
|
+
right: "[--placement:right]",
|
|
131
|
+
};
|
|
132
|
+
return placements[props.placement] || "[--placement:bottom-left]";
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const defaultItems = computed(() => {
|
|
136
|
+
return props.items.length
|
|
137
|
+
? props.items
|
|
138
|
+
: [
|
|
139
|
+
{
|
|
140
|
+
label: "Editar",
|
|
141
|
+
type: "button",
|
|
142
|
+
severity: "primary",
|
|
143
|
+
action: () => {},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
label: "Duplicar",
|
|
147
|
+
type: "button",
|
|
148
|
+
severity: "success",
|
|
149
|
+
action: () => {},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
label: "Eliminar",
|
|
153
|
+
type: "button",
|
|
154
|
+
severity: "danger",
|
|
155
|
+
action: () => {},
|
|
156
|
+
},
|
|
157
|
+
{ label: "Ver detalles", type: "link", href: "#" },
|
|
158
|
+
];
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Methods
|
|
162
|
+
const getItemButtonClasses = (item) => {
|
|
163
|
+
const severity = item.severity || "default";
|
|
164
|
+
|
|
165
|
+
const severityClasses = {
|
|
166
|
+
default:
|
|
167
|
+
"text-foreground hover:bg-muted-hover",
|
|
168
|
+
primary:
|
|
169
|
+
"text-blue-600 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-900/20",
|
|
170
|
+
success:
|
|
171
|
+
"text-green-600 hover:bg-green-50 dark:text-green-400 dark:hover:bg-green-900/20",
|
|
172
|
+
danger:
|
|
173
|
+
"text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20",
|
|
174
|
+
warning:
|
|
175
|
+
"text-yellow-600 hover:bg-yellow-50 dark:text-yellow-400 dark:hover:bg-yellow-900/20",
|
|
176
|
+
info: "text-cyan-600 hover:bg-cyan-50 dark:text-cyan-400 dark:hover:bg-cyan-900/20",
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
return severityClasses[severity] || severityClasses.default;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const toggleDropdown = () => {
|
|
183
|
+
// Handled by Preline JS automatically
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const closeDropdown = () => {
|
|
187
|
+
// Handled by Preline JS automatically
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const handleItemClick = (item, event) => {
|
|
191
|
+
emit("item-click", { item, event });
|
|
192
|
+
|
|
193
|
+
if (item.action && typeof item.action === "function") {
|
|
194
|
+
item.action();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (item.href === "#" || item.href === "") {
|
|
198
|
+
event.preventDefault();
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
</script>
|
|
202
|
+
<template>
|
|
203
|
+
<div class="hs-dropdown relative inline-flex" :class="wrapperClass">
|
|
204
|
+
<!-- Trigger button -->
|
|
205
|
+
<button
|
|
206
|
+
:id="triggerId"
|
|
207
|
+
type="button"
|
|
208
|
+
:class="triggerButtonClasses"
|
|
209
|
+
aria-haspopup="menu"
|
|
210
|
+
:aria-expanded="false"
|
|
211
|
+
:aria-label="triggerLabel"
|
|
212
|
+
>
|
|
213
|
+
<slot name="trigger" :toggle="toggleDropdown">
|
|
214
|
+
{{ triggerText }}
|
|
215
|
+
<svg
|
|
216
|
+
class="hs-dropdown-open:rotate-180 size-4 transition-transform duration-200"
|
|
217
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
218
|
+
width="24"
|
|
219
|
+
height="24"
|
|
220
|
+
viewBox="0 0 24 24"
|
|
221
|
+
fill="none"
|
|
222
|
+
stroke="currentColor"
|
|
223
|
+
stroke-width="2"
|
|
224
|
+
stroke-linecap="round"
|
|
225
|
+
stroke-linejoin="round"
|
|
226
|
+
>
|
|
227
|
+
<path d="m6 9 6 6 6-6" />
|
|
228
|
+
</svg>
|
|
229
|
+
</slot>
|
|
230
|
+
</button>
|
|
231
|
+
|
|
232
|
+
<!-- Dropdown menu -->
|
|
233
|
+
<div
|
|
234
|
+
class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden min-w-40 bg-dropdown shadow-md rounded-lg p-1 space-y-0.5 mt-2 dark:border dark:border-dropdown-line dark:divide-card-line z-50 border border-dropdown-line"
|
|
235
|
+
:class="[menuClass, placementClass]"
|
|
236
|
+
role="menu"
|
|
237
|
+
:aria-orientation="'vertical'"
|
|
238
|
+
:aria-labelledby="triggerId"
|
|
239
|
+
>
|
|
240
|
+
<slot name="header" v-if="$slots.header"></slot>
|
|
241
|
+
|
|
242
|
+
<slot name="items" :close="closeDropdown">
|
|
243
|
+
<!-- Default items if no slot content provided -->
|
|
244
|
+
<template v-for="(item, index) in defaultItems" :key="index">
|
|
245
|
+
<!-- Button if type is button or has action -->
|
|
246
|
+
<button
|
|
247
|
+
v-if="item.type === 'button' || item.action"
|
|
248
|
+
type="button"
|
|
249
|
+
class="w-full flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm transition-colors text-left focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-offset-gray-800"
|
|
250
|
+
:class="[
|
|
251
|
+
item.class || getItemButtonClasses(item),
|
|
252
|
+
{ 'opacity-50 pointer-events-none': item.disabled },
|
|
253
|
+
]"
|
|
254
|
+
:disabled="item.disabled"
|
|
255
|
+
@click="handleItemClick(item, $event)"
|
|
256
|
+
>
|
|
257
|
+
<component
|
|
258
|
+
:is="item.icon"
|
|
259
|
+
v-if="item.icon"
|
|
260
|
+
class="size-4 shrink-0"
|
|
261
|
+
/>
|
|
262
|
+
{{ item.label }}
|
|
263
|
+
</button>
|
|
264
|
+
|
|
265
|
+
<!-- Link if type is link or has href -->
|
|
266
|
+
<a
|
|
267
|
+
v-else
|
|
268
|
+
class="flex items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 text-foreground hover:bg-muted-hover"
|
|
269
|
+
:class="item.class"
|
|
270
|
+
:href="item.href || '#'"
|
|
271
|
+
@click="handleItemClick(item, $event)"
|
|
272
|
+
>
|
|
273
|
+
<component
|
|
274
|
+
:is="item.icon"
|
|
275
|
+
v-if="item.icon"
|
|
276
|
+
class="size-4 shrink-0"
|
|
277
|
+
/>
|
|
278
|
+
{{ item.label }}
|
|
279
|
+
</a>
|
|
280
|
+
</template>
|
|
281
|
+
</slot>
|
|
282
|
+
|
|
283
|
+
<slot name="footer" v-if="$slots.footer"></slot>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
</template>
|