update components with changes from other plugins

This commit is contained in:
joshuaboud 2022-06-13 16:11:40 -03:00
parent 8d498d925b
commit 6b201edc55
No known key found for this signature in database
GPG Key ID: 17EFB59E2A8BF50E
6 changed files with 168 additions and 300 deletions

View File

@ -1,9 +1,26 @@
<!--
Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com>
This file is part of Cockpit Navigator.
Cockpit Navigator is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.
Cockpit Navigator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Cockpit Navigator.
If not, see <https://www.gnu.org/licenses/>.
-->
<template> <template>
<SwitchGroup as="div" :class="[labelRight ? 'flex-row-reverse' : 'flex-row', 'inline-flex items-center']"> <SwitchGroup as="div" :class="[labelRight ? 'flex-row-reverse' : 'flex-row', 'inline-flex items-center']">
<span :class="[labelRight ? 'grow' : '', 'flex flex-col']"> <span :class="[labelRight ? 'grow' : '', 'flex flex-col']">
<SwitchLabel as="span" class="text-label" passive><slot /></SwitchLabel> <SwitchLabel as="div" class="text-label"><slot /></SwitchLabel>
<SwitchDescription <SwitchDescription
as="span" as="div"
class="text-sm text-muted" class="text-sm text-muted"
><slot name="description" /></SwitchDescription> ><slot name="description" /></SwitchDescription>
</span> </span>
@ -11,11 +28,11 @@
<Switch <Switch
:modelValue="modelValue" :modelValue="modelValue"
@update:modelValue="newValue => { $emit('update:modelValue', newValue); $emit('change', newValue); $emit('input', newValue); }" @update:modelValue="newValue => { $emit('update:modelValue', newValue); $emit('change', newValue); $emit('input', newValue); }"
:class="[modelValue ? 'bg-45d' : 'bg-well', 'relative inline-flex flex-shrink-0 h-6 w-11 p-[2px] rounded-full cursor-pointer focus:outline-none focus:ring-0 shadow-inner']" :class="[modelValue ? 'bg-45d' : 'bg-well', 'inline-flex shrink-0 h-6 w-11 p-[2px] rounded-full cursor-pointer shadow-inner']"
> >
<span <span
aria-hidden="true" aria-hidden="true"
:class="[modelValue ? 'translate-x-5' : 'translate-x-0', 'pointer-events-none inline-block h-5 w-5 rounded-full bg-default shadow-md transform ring-0 transition-transform ease-in-out duration-200 top-px']" :class="[modelValue ? 'translate-x-5' : 'translate-x-0', 'pointer-events-none inline-block h-5 w-5 rounded-full bg-default shadow-md transform transition-transform ease-in-out duration-200']"
/> />
</Switch> </Switch>
</SwitchGroup> </SwitchGroup>
@ -29,18 +46,6 @@ export default {
modelValue: Boolean, modelValue: Boolean,
labelRight: Boolean, labelRight: Boolean,
}, },
// setup(props, { emit }) {
// const internalModel = ref(props.modelValue);
// const updateModelValue = () => emit('update:modelValue', internalModel.value);
// watch(() => props.modelValue, (newValue) => internalModel.value = newValue);
// return {
// internalModel,
// updateModelValue,
// };
// },
components: { components: {
Switch, Switch,
SwitchDescription, SwitchDescription,

View File

@ -1,37 +1,20 @@
<!-- <!--
Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com> Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com>
This file is part of Cockpit File Sharing. This file is part of Cockpit Navigator.
Cockpit File Sharing is free software: you can redistribute it and/or modify it under the terms Cockpit Navigator is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either version 3 of the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
Cockpit File Sharing is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; Cockpit Navigator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Cockpit File Sharing. You should have received a copy of the GNU General Public License along with Cockpit Navigator.
If not, see <https://www.gnu.org/licenses/>. If not, see <https://www.gnu.org/licenses/>.
--> -->
<template> <template>
<div class="aspect-square loading-spinner border-neutral-300 border-t-neutral-500 dark:border-neutral-500 dark:border-t-neutral-200 rounded-full"></div> <div class="aspect-square animate-spin border-neutral-300 border-t-neutral-500 dark:border-neutral-500 dark:border-t-neutral-200 rounded-full"></div>
</template> </template>
<style>
.loading-spinner {
border-width: 0.2rem;
animation: spin 2s linear infinite;
display: inline-block;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@ -1,72 +1,63 @@
<template> <!--
<TransitionRoot as="template" :show="showModal"> Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com>
<Dialog as="div" class="fixed z-10 inset-0 overflow-y-auto">
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0 text-default"
>
<TransitionChild
as="template"
enter="ease-out duration-300"
enter-from="opacity-0"
enter-to="opacity-100"
leave="ease-in duration-200"
leave-from="opacity-100"
leave-to="opacity-0"
>
<DialogOverlay class="fixed inset-0 bg-neutral-500/75 dark:bg-black/50 transition-opacity" />
</TransitionChild>
<!-- This element is to trick the browser into centering the modal contents. --> This file is part of Cockpit Navigator.
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<TransitionChild Cockpit Navigator is free software: you can redistribute it and/or modify it under the terms
as="template" of the GNU General Public License as published by the Free Software Foundation, either version 3
enter="ease-out duration-300" of the License, or (at your option) any later version.
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enter-to="opacity-100 translate-y-0 sm:scale-100" Cockpit Navigator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
leave="ease-in duration-200" without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Cockpit Navigator.
If not, see <https://www.gnu.org/licenses/>.
-->
<template>
<TransitionRoot as="div" class="fixed inset-0 z-10 overflow-visible" :show="showModal">
<TransitionChild as="template" enter="ease-out duration-500" enter-from="opacity-0" enter-to="opacity-100"
leave="ease-in duration-500" leave-from="opacity-100" leave-to="opacity-0">
<div class="fixed z-10 inset-0 bg-neutral-500/75 dark:bg-black/50 transition-opacity" />
</TransitionChild>
<div class="fixed z-10 inset-0 overflow-hidden flex items-end sm:items-center justify-center px-4 pb-20 sm:p-0">
<TransitionChild as="template" enter="ease-out duration-300"
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-90"
enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-100"
leave-from="opacity-100 translate-y-0 sm:scale-100" leave-from="opacity-100 translate-y-0 sm:scale-100"
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-75">
>
<div <div
:class="[autoWidth ? 'sm:max-w-full' : 'sm:max-w-lg', 'relative inline-flex flex-col items-stretch align-bottom overflow-hidden transform transition-all sm:my-8 sm:align-middle text-left card']" :class="[autoWidth ? 'sm:max-w-full' : 'sm:max-w-lg', 'inline-flex flex-col items-stretch overflow-hidden transform transition-all text-left z-10']">
> <div class="block w-[512px]" /> <!-- set min width of div -->
<div class="block w-[512px]"></div> <div class="card flex flex-col items-stretch overflow-hidden">
<div class="card-header"> <div class="card-header">
<slot name="header"> <slot name="header">
<h3 class="text-header">{{ headerText }}</h3> <h3 class="text-header">{{ headerText }}</h3>
</slot> </slot>
</div> </div>
<div class="card-body flex flex-row items-center"> <div class="card-body flex flex-row items-center">
<div class="shrink-0">
<slot name="icon" /> <slot name="icon" />
</div> <div class="grow ml-2 only:ml-0 overflow-x-auto">
<div class="grow">
<slot /> <slot />
</div> </div>
</div> </div>
<div class="card-footer button-group-row w-full justify-end"> <div class="card-footer button-group-row justify-end">
<button <button v-if="!noCancel" type="button" class="btn btn-secondary" @click="$emit('cancel')">{{
v-if="!noCancel" cancelText
type="button" }}</button>
class="btn btn-secondary" <button type="button" :class="['btn', applyDangerous ? 'btn-danger' : 'btn-primary']"
@click="$emit('cancel')" @click="$emit('apply')" :disabled="disableContinue">{{ applyText }}</button>
>{{ cancelText }}</button> </div>
<button
type="button"
:class="['btn', applyDangerous ? 'btn-danger' : 'btn-primary']"
@click="$emit('apply')"
:disabled="disableContinue"
>{{ applyText }}</button>
</div> </div>
</div> </div>
</TransitionChild> </TransitionChild>
</div> </div>
</Dialog>
</TransitionRoot> </TransitionRoot>
</template> </template>
<script> <script>
import { Dialog, DialogOverlay, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'; import { TransitionChild, TransitionRoot } from '@headlessui/vue';
export default { export default {
props: { props: {
@ -92,9 +83,6 @@ export default {
disableContinue: Boolean, disableContinue: Boolean,
}, },
components: { components: {
Dialog,
DialogOverlay,
DialogTitle,
TransitionChild, TransitionChild,
TransitionRoot, TransitionRoot,
}, },

View File

@ -1,76 +1,62 @@
<!--
Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com>
This file is part of Cockpit Navigator.
Cockpit Navigator is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.
Cockpit Navigator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Cockpit Navigator.
If not, see <https://www.gnu.org/licenses/>.
-->
<template> <template>
<!-- Global notification live region, render this permanently at the end of the document --> <div aria-live="assertive"
<div class="fixed inset-0 flex items-end px-4 py-6 pointer-events-none sm:p-6 sm:items-start z-20 h-screen overflow-y-auto">
aria-live="assertive" <transition-group tag="div" class="w-full flex flex-col-reverse items-center sm:items-end sm:flex-col space-y-content"
class="fixed inset-0 flex items-end px-4 py-6 pointer-events-none sm:p-6 sm:items-start z-20 h-screen overflow-y-auto" enter-active-class="transition-all transform ease-out duration-300"
> enter-from-class="translate-y-8 opacity-0 scale-95 sm:translate-y-0 sm:translate-x-8"
<div class="w-full flex flex-col items-center sm:items-end space-y-content"> enter-to-class="translate-y-0 opacity-100 scale-100 sm:translate-x-0"
<!-- Notification panel, dynamically insert this into the live region when it needs to be displayed --> leave-active-class="transition-all transform ease-in duration-100"
<transition leave-from-class="opacity-100 scale-100 sm:translate-x-0"
v-for="notification in notificationList" leave-to-class="opacity-0 scale-95 sm:translate-x-8">
:key="notification.id" <div v-for="notification in notificationList" :key="notification.id"
enter-active-class="transform ease-out duration-300 transition"
enter-from-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
leave-active-class="transition ease-in duration-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
class="transition-transform"
>
<div
v-if="notification.show"
class="max-w-sm w-full shadow-lg pointer-events-auto overflow-hidden bg-default text-default" class="max-w-sm w-full shadow-lg pointer-events-auto overflow-hidden bg-default text-default"
@mouseenter="notification.clearTimeouts?.()" @mouseenter="notification.clearTimeouts?.()" @mouseleave="notification.setTimeouts?.()">
@mouseleave="notification.setTimeouts?.()"
>
<div class="p-4"> <div class="p-4">
<div class="flex items-start"> <div class="flex items-start">
<div class="flex-shrink-0" aria-hidden="true"> <div class="flex-shrink-0" aria-hidden="true">
<ExclamationCircleIcon <ExclamationCircleIcon v-if="notification.level === 'error'" class="icon-error size-icon-lg"
v-if="notification.level === 'error'" aria-hidden="true" />
class="icon-error size-icon-lg" <ExclamationCircleIcon v-else-if="notification.level === 'warning'"
aria-hidden="true" class="icon-warning size-icon-lg" aria-hidden="true" />
/> <CheckCircleIcon v-else-if="notification.level === 'success'"
<ExclamationCircleIcon class="icon-success size-icon-lg" aria-hidden="true" />
v-else-if="notification.level === 'warning'" <MinusCircleIcon v-else-if="notification.level === 'denied'" class="icon-error size-icon-lg"
class="icon-warning size-icon-lg" aria-hidden="true" />
aria-hidden="true"
/>
<CheckCircleIcon
v-else-if="notification.level === 'success'"
class="icon-success size-icon-lg"
aria-hidden="true"
/>
<MinusCircleIcon
v-else-if="notification.level === 'denied'"
class="icon-error size-icon-lg"
aria-hidden="true"
/>
<InformationCircleIcon v-else class="icon-info size-icon-lg" /> <InformationCircleIcon v-else class="icon-info size-icon-lg" />
</div> </div>
<div class="ml-3 w-0 flex-1 pt-0.5"> <div class="ml-3 w-0 flex-1 pt-0.5">
<p class="text-sm font-medium">{{ notification.title }}</p> <p class="text-sm font-medium">{{ notification.title }}</p>
<p class="mt-1 text-sm text-muted whitespace-pre-wrap" v-html="notification.body"></p> <p class="mt-1 text-sm text-muted whitespace-pre-wrap" v-html="notification.body">
</p>
<div v-if="notification.actions?.length" class="mt-3 flex space-x-7"> <div v-if="notification.actions?.length" class="mt-3 flex space-x-7">
<button <button v-for="action in notification.actions" @click="action.callback"
v-for="action in notification.actions" class="rounded-md text-sm font-medium text-primary">
@click="action.callback"
class="rounded-md text-sm font-medium text-primary focus:outline-none focus:ring-0 focus:ring-offset-0"
>
{{ action.text }} {{ action.text }}
</button> </button>
<button <button @click="notification.show = false" type="button"
@click="notification.show = false" class="rounded-md text-sm font-medium text-secondary">Dismiss</button>
type="button"
class="rounded-md text-sm font-medium text-secondary focus:outline-none focus:ring-0 focus:ring-offset-0"
>Dismiss</button>
</div> </div>
</div> </div>
<div class="ml-4 flex-shrink-0 flex"> <div class="ml-4 flex-shrink-0 flex">
<button <button @click="notification.show = false"
@click="notification.show = false" class="icon-default">
class="icon-default focus:outline-none focus:ring-0 focus:ring-offset-0"
>
<span class="sr-only">Close</span> <span class="sr-only">Close</span>
<XIcon class="size-icon" aria-hidden="true" /> <XIcon class="size-icon" aria-hidden="true" />
</button> </button>
@ -78,8 +64,7 @@
</div> </div>
</div> </div>
</div> </div>
</transition> </transition-group>
</div>
</div> </div>
</template> </template>
@ -87,7 +72,7 @@
import { ref, watch, reactive, onUnmounted } from 'vue'; import { ref, watch, reactive, onUnmounted } from 'vue';
import { InformationCircleIcon, ExclamationCircleIcon, MinusCircleIcon, CheckCircleIcon } from '@heroicons/vue/outline'; import { InformationCircleIcon, ExclamationCircleIcon, MinusCircleIcon, CheckCircleIcon } from '@heroicons/vue/outline';
import { XIcon } from '@heroicons/vue/solid'; import { XIcon } from '@heroicons/vue/solid';
import { FIFO, UniqueIDGenerator } from '@45drives/cockpit-helpers'; import { FIFO } from '@45drives/cockpit-helpers';
/** Notification passed to showNotification /** Notification passed to showNotification
* *
@ -106,13 +91,11 @@ export default {
setup(props) { setup(props) {
const notificationList = ref([]); const notificationList = ref([]);
const uniqueIDGenerator = new UniqueIDGenerator();
/** Construct new notification and show it /** Construct new notification and show it
* *
* @param {string} title - Header text * @param {string} title - Header text
* @param {string} body - Notification content * @param {string} body - Notification content
* @param {string} [level='info'] - 'info'|'warning'|'error'|'success' * @param {string} [level='info'] - 'info'|'warning'|'error'|'success'|'denied'
* @param {number} [timeout=10000] - time to display notification in milliseconds, or zero to display forever * @param {number} [timeout=10000] - time to display notification in milliseconds, or zero to display forever
* *
* @returns {Notification} - Object to chain add actions to * @returns {Notification} - Object to chain add actions to
@ -120,7 +103,6 @@ export default {
const constructNotification = (title, body, level = 'info', timeout = 10000) => { const constructNotification = (title, body, level = 'info', timeout = 10000) => {
const actions = []; const actions = [];
const obj = reactive({ const obj = reactive({
show: true,
title, title,
body, body,
level, level,
@ -137,8 +119,8 @@ export default {
obj.actions.push({ obj.actions.push({
text, text,
callback: () => { callback: () => {
obj.show = false;
callback(); callback();
obj.removeSelf();
} }
}); });
return obj; return obj;
@ -153,27 +135,27 @@ export default {
*/ */
const showNotificationObj = (notificationObj) => { const showNotificationObj = (notificationObj) => {
notificationObj.show = true; notificationObj.show = true;
notificationObj.id = uniqueIDGenerator.get(); // backwards compat for setting show to false to remove notification
notificationObj.stopShowWatch = watch(() => notificationObj.show, (value) => {
if (!value) notificationObj.removeSelf();
})
notificationObj.id = Math.floor(Math.random() * Date.now());
notificationObj.removeSelf = () => {
const idToRemove = notificationObj.id
notificationList.value = notificationList.value.filter(({ id }) => id !== idToRemove);
notificationObj.stopShowWatch();
}
notificationObj.setTimeouts = () => { notificationObj.setTimeouts = () => {
if (notificationObj.timeout > 0) { if (notificationObj.timeout > 0) {
notificationObj.timeout1 = setTimeout( notificationObj.removerTimeout = setTimeout(
() => notificationObj.show = false, notificationObj.removeSelf,
notificationObj.timeout notificationObj.timeout
); );
notificationObj.timeout2 = setTimeout(
() => {
notificationList.value = notificationList.value.filter(obj => obj !== notificationObj);
uniqueIDGenerator.release(notificationObj.id);
},
notificationObj.timeout + 2000
);
} }
} }
notificationObj.clearTimeouts = () => { notificationObj.clearTimeouts = () => {
if (notificationObj.timeout1 !== undefined) if (notificationObj.removerTimeout !== undefined)
clearTimeout(notificationObj.timeout1); clearTimeout(notificationObj.removerTimeout);
if (notificationObj.timeout2 !== undefined)
clearTimeout(notificationObj.timeout2);
} }
notificationList.value = [notificationObj, ...notificationList.value]; notificationList.value = [notificationObj, ...notificationList.value];
if (notificationObj.level === 'error') { if (notificationObj.level === 'error') {
@ -196,12 +178,6 @@ export default {
} }
}); });
let cleanupHandle = setInterval(() => {
notificationList.value = notificationList.value.filter(n => n.show);
}, 1000);
onUnmounted(() => clearInterval(cleanupHandle));
return { return {
notificationList, notificationList,
constructNotification, constructNotification,

View File

@ -1,8 +1,25 @@
<!--
Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com>
This file is part of Cockpit Navigator.
Cockpit Navigator is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.
Cockpit Navigator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Cockpit Navigator.
If not, see <https://www.gnu.org/licenses/>.
-->
<template> <template>
<div class="shadow border border-default h-full"> <div class="shadow border border-default h-full overflow-hidden">
<div <div
v-if="!noHeader" v-if="!noHeader"
class="bg-accent py-3 px-4 lg:pl-8 lg:pr-6 text-sm font-semibold flex flex-row" class="bg-accent py-3 px-4 lg:px-6 text-sm font-semibold flex flex-row"
> >
<div class="grow"> <div class="grow">
<slot name="header">{{ headerText }}</slot> <slot name="header">{{ headerText }}</slot>
@ -80,7 +97,7 @@ table.houston-table thead.use-sticky tr th {
table.houston-table th, table.houston-table th,
table.houston-table td { table.houston-table td {
@apply py-2 px-4 lg:pl-8 lg:pr-6 whitespace-nowrap text-sm; @apply py-2 px-4 lg:px-6 whitespace-nowrap text-sm;
} }
table.houston-table th:not(.text-right):not(.text-center), table.houston-table th:not(.text-right):not(.text-center),

View File

@ -1,101 +0,0 @@
<template>
<div class="flex flex-col h-full">
<div class="inline-block w-full align-middle h-full">
<div class="shadow md:rounded-[9px] border border-default h-full">
<div
v-if="!noHeader"
class="md:rounded-t-[8px] bg-accent py-3 px-4 lg:pl-8 lg:pr-6 text-sm font-semibold flex flex-row"
>
<div class="grow">
<slot name="header">
{{ headerText }}
</slot>
</div>
<div :class="[noScroll ? '' : 'overflow-y-auto']" :style="{'scrollbar-gutter': noScroll ? 'auto' : 'stable'}"></div>
</div>
<div
:class="[noShrink ? noShrinkHeight : shrinkHeight, noScroll ? '' : 'overflow-y-scroll', noHeader ? 'md:rounded-t-[8px]' : '', 'flex flex-col md:rounded-b-[8px] overflow-x-auto']"
:style="{'scrollbar-gutter': noScroll ? 'auto' : 'stable'}"
>
<table class="min-w-full divide houston-table">
<thead :class="[stickyHeaders ? 'use-sticky' : '']">
<slot name="thead" />
</thead>
<tbody class="bg-default w-full">
<slot name="tbody">
<tr>
<td colspan="100%" class="text-center align-middle text-muted text-sm">{{ emptyText }}</td>
</tr>
</slot>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
headerText: {
type: String,
required: false,
default: "Table",
},
emptyText: {
type: String,
required: false,
default: "Nothing to show.",
},
noShrink: {
type: Boolean,
required: false,
default: false,
},
stickyHeaders: {
type: Boolean,
required: false,
default: false,
},
noShrinkHeight: {
type: String,
required: false,
default: 'h-80'
},
shrinkHeight: {
type: String,
required: false,
default: 'max-h-80'
},
noScroll: Boolean,
noHeader: Boolean,
}
}
</script>
<style>
@import '@45drives/cockpit-css/src/index.css';
table.houston-table thead.use-sticky tr th {
@apply sticky z-10 top-0;
}
table.houston-table th,
table.houston-table td {
@apply py-2 px-4 lg:pl-8 lg:pr-6 whitespace-nowrap text-sm;
}
table.houston-table th:not(.text-right):not(.text-center),
table.houston-table td:not(.text-right):not(.text-center) {
@apply text-left;
}
table.houston-table th {
@apply bg-accent font-semibold;
}
table.houston-table tr {
@apply even:bg-accent;
}
</style>