Correcao Sidebar Classico e Rail, Correcao Layout, Ajuste de Breakpoint para Tailwind, Ajuste AppTopbar, Ajuste Menu PopOver, Recriado Paleta de Cores, Inserido algumas animações leves, Reajuste Cor items NOVOS da tabela, Drawer Ajuda Corrigido no Logout, Whatsapp, sms, email, recursos extras
This commit is contained in:
+138
-160
@@ -15,211 +15,189 @@
|
||||
|--------------------------------------------------------------------------
|
||||
-->
|
||||
<script setup>
|
||||
import { computed, inject } from 'vue'
|
||||
import { useLayout } from '@/layout/composables/layout'
|
||||
import { primaryColors, surfaces, presetOptions, applyThemeEngine } from '@/theme/theme.options'
|
||||
import { computed, inject } from 'vue';
|
||||
import { useLayout } from '@/layout/composables/layout';
|
||||
import { primaryColors, surfaces, presetOptions, applyThemeEngine } from '@/theme/theme.options';
|
||||
|
||||
const { layoutConfig, isDarkTheme, changeMenuMode, setVariant } = useLayout()
|
||||
const { layoutConfig, isDarkTheme, changeMenuMode, setVariant } = useLayout();
|
||||
|
||||
// ✅ vem do AppTopbar (mesma instância)
|
||||
const queuePatch = inject('queueUserSettingsPatch', null)
|
||||
const queuePatch = inject('queueUserSettingsPatch', null);
|
||||
|
||||
// menu mode options
|
||||
const menuModeOptions = [
|
||||
{ label: 'Static', value: 'static' },
|
||||
{ label: 'Overlay', value: 'overlay' }
|
||||
]
|
||||
{ label: 'Static', value: 'static' },
|
||||
{ label: 'Overlay', value: 'overlay' }
|
||||
];
|
||||
|
||||
// ✅ v-model sincronizado (sem state local)
|
||||
const presetModel = computed({
|
||||
get: () => layoutConfig.preset,
|
||||
set: (val) => {
|
||||
if (!val || val === layoutConfig.preset) return
|
||||
layoutConfig.preset = val
|
||||
get: () => layoutConfig.preset,
|
||||
set: (val) => {
|
||||
if (!val || val === layoutConfig.preset) return;
|
||||
layoutConfig.preset = val;
|
||||
|
||||
applyThemeEngine(layoutConfig)
|
||||
queuePatch?.({ preset: val })
|
||||
}
|
||||
})
|
||||
applyThemeEngine(layoutConfig);
|
||||
queuePatch?.({ preset: val });
|
||||
}
|
||||
});
|
||||
|
||||
const menuModeModel = computed({
|
||||
get: () => layoutConfig.menuMode,
|
||||
set: (val) => {
|
||||
if (!val || val === layoutConfig.menuMode) return
|
||||
layoutConfig.menuMode = val
|
||||
get: () => layoutConfig.menuMode,
|
||||
set: (val) => {
|
||||
if (!val || val === layoutConfig.menuMode) return;
|
||||
layoutConfig.menuMode = val;
|
||||
|
||||
// ✅ changeMenuMode espera event.value (seu composable usa event.value)
|
||||
try { changeMenuMode({ value: val }) } catch {}
|
||||
// ✅ changeMenuMode espera event.value (seu composable usa event.value)
|
||||
try {
|
||||
changeMenuMode({ value: val });
|
||||
} catch {}
|
||||
|
||||
queuePatch?.({ menu_mode: val })
|
||||
}
|
||||
})
|
||||
queuePatch?.({ menu_mode: val });
|
||||
}
|
||||
});
|
||||
|
||||
function updateColors (type, item) {
|
||||
if (type === 'primary') {
|
||||
layoutConfig.primary = item.name
|
||||
applyThemeEngine(layoutConfig)
|
||||
queuePatch?.({ primary_color: item.name })
|
||||
return
|
||||
}
|
||||
function updateColors(type, item) {
|
||||
if (type === 'primary') {
|
||||
layoutConfig.primary = item.name;
|
||||
applyThemeEngine(layoutConfig);
|
||||
queuePatch?.({ primary_color: item.name });
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 'surface') {
|
||||
layoutConfig.surface = item.name
|
||||
applyThemeEngine(layoutConfig)
|
||||
queuePatch?.({ surface_color: item.name })
|
||||
}
|
||||
if (type === 'surface') {
|
||||
layoutConfig.surface = item.name;
|
||||
applyThemeEngine(layoutConfig);
|
||||
queuePatch?.({ surface_color: item.name });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="config-panel hidden absolute top-[3.25rem] right-0 w-64 p-4 bg-surface-0 dark:bg-surface-900 border border-surface rounded-border origin-top shadow-[0px_3px_5px_rgba(0,0,0,0.02),0px_0px_2px_rgba(0,0,0,0.05),0px_1px_4px_rgba(0,0,0,0.08)]"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<span class="text-sm text-muted-color font-semibold">Primary</span>
|
||||
<div class="pt-2 flex gap-2 flex-wrap justify-between">
|
||||
<button
|
||||
v-for="c of primaryColors"
|
||||
:key="c.name"
|
||||
type="button"
|
||||
:title="c.name"
|
||||
@click="updateColors('primary', c)"
|
||||
:class="[
|
||||
'border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1',
|
||||
{ 'outline-primary': layoutConfig.primary === c.name }
|
||||
]"
|
||||
:style="{ backgroundColor: `${c.name === 'noir' ? 'var(--text-color)' : c.palette['500']}` }"
|
||||
/>
|
||||
<div
|
||||
class="config-panel hidden absolute top-[3.25rem] right-0 w-64 p-4 bg-surface-0 dark:bg-surface-900 border border-surface rounded-border origin-top shadow-[0px_3px_5px_rgba(0,0,0,0.02),0px_0px_2px_rgba(0,0,0,0.05),0px_1px_4px_rgba(0,0,0,0.08)]"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<span class="text-sm text-muted-color font-semibold">Primary</span>
|
||||
<div class="pt-2 flex gap-2 flex-wrap justify-between">
|
||||
<button
|
||||
v-for="c of primaryColors"
|
||||
:key="c.name"
|
||||
type="button"
|
||||
:title="c.name"
|
||||
@click="updateColors('primary', c)"
|
||||
:class="['border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1', { 'outline-primary': layoutConfig.primary === c.name }]"
|
||||
:style="{ backgroundColor: `${c.name === 'noir' ? 'var(--text-color)' : c.palette['500']}` }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="text-sm text-muted-color font-semibold">Surface</span>
|
||||
<div class="pt-2 flex gap-2 flex-wrap justify-between">
|
||||
<button
|
||||
v-for="s of surfaces"
|
||||
:key="s.name"
|
||||
type="button"
|
||||
:title="s.name"
|
||||
@click="updateColors('surface', s)"
|
||||
:class="[
|
||||
'border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1',
|
||||
{ 'outline-primary': layoutConfig.surface ? layoutConfig.surface === s.name : isDarkTheme ? s.name === 'zinc' : s.name === 'slate' }
|
||||
]"
|
||||
:style="{ backgroundColor: `${s.palette['500']}` }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Presets</span>
|
||||
<SelectButton v-model="presetModel" :options="presetOptions" :allowEmpty="false" />
|
||||
</div>
|
||||
|
||||
<!-- Menu Mode: visível apenas no Layout Clássico -->
|
||||
<div v-show="layoutConfig.variant === 'classic'" class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Menu Mode</span>
|
||||
<SelectButton v-model="menuModeModel" :options="menuModeOptions" :allowEmpty="false" optionLabel="label" optionValue="value" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Layout</span>
|
||||
<div class="flex flex-col gap-1">
|
||||
<!-- Layout Rail -->
|
||||
<button type="button" class="layout-option" :class="{ 'layout-option--active': layoutConfig.variant === 'rail' }" @click="setVariant('rail')">
|
||||
<i :class="layoutConfig.variant === 'rail' ? 'pi pi-check-circle' : 'pi pi-circle'" class="layout-option__icon" />
|
||||
<span class="layout-option__label">Layout Rail</span>
|
||||
<span v-if="layoutConfig.variant === 'rail'" class="layout-option__badge layout-option__badge--default">Padrão</span>
|
||||
</button>
|
||||
|
||||
<!-- Layout Clássico -->
|
||||
<button type="button" class="layout-option" :class="{ 'layout-option--active': layoutConfig.variant === 'classic' }" @click="setVariant('classic')">
|
||||
<i :class="layoutConfig.variant === 'classic' ? 'pi pi-check-circle' : 'pi pi-circle'" class="layout-option__icon" />
|
||||
<span class="layout-option__label">Layout Clássico</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="text-sm text-muted-color font-semibold">Surface</span>
|
||||
<div class="pt-2 flex gap-2 flex-wrap justify-between">
|
||||
<button
|
||||
v-for="s of surfaces"
|
||||
:key="s.name"
|
||||
type="button"
|
||||
:title="s.name"
|
||||
@click="updateColors('surface', s)"
|
||||
:class="[
|
||||
'border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1',
|
||||
{ 'outline-primary': layoutConfig.surface ? layoutConfig.surface === s.name : (isDarkTheme ? s.name === 'zinc' : s.name === 'slate') }
|
||||
]"
|
||||
:style="{ backgroundColor: `${s.palette['500']}` }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Presets</span>
|
||||
<SelectButton v-model="presetModel" :options="presetOptions" :allowEmpty="false" />
|
||||
</div>
|
||||
|
||||
<!-- Menu Mode: visível apenas no Layout Clássico -->
|
||||
<div v-show="layoutConfig.variant === 'classic'" class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Menu Mode</span>
|
||||
<SelectButton
|
||||
v-model="menuModeModel"
|
||||
:options="menuModeOptions"
|
||||
:allowEmpty="false"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-sm text-muted-color font-semibold">Layout</span>
|
||||
<div class="flex flex-col gap-1">
|
||||
<!-- Layout Rail -->
|
||||
<button
|
||||
type="button"
|
||||
class="layout-option"
|
||||
:class="{ 'layout-option--active': layoutConfig.variant === 'rail' }"
|
||||
@click="setVariant('rail')"
|
||||
>
|
||||
<i
|
||||
:class="layoutConfig.variant === 'rail' ? 'pi pi-check-circle' : 'pi pi-circle'"
|
||||
class="layout-option__icon"
|
||||
/>
|
||||
<span class="layout-option__label">Layout Rail</span>
|
||||
<span v-if="layoutConfig.variant === 'rail'" class="layout-option__badge layout-option__badge--default">Padrão</span>
|
||||
</button>
|
||||
|
||||
<!-- Layout Clássico -->
|
||||
<button
|
||||
type="button"
|
||||
class="layout-option"
|
||||
:class="{ 'layout-option--active': layoutConfig.variant === 'classic' }"
|
||||
@click="setVariant('classic')"
|
||||
>
|
||||
<i
|
||||
:class="layoutConfig.variant === 'classic' ? 'pi pi-check-circle' : 'pi pi-circle'"
|
||||
class="layout-option__icon"
|
||||
/>
|
||||
<span class="layout-option__label">Layout Clássico</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.layout-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.45rem 0.6rem;
|
||||
border-radius: var(--border-radius, 6px);
|
||||
border: 1px solid var(--surface-border);
|
||||
background: var(--surface-ground);
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition: border-color 0.15s, background 0.15s;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.45rem 0.6rem;
|
||||
border-radius: var(--border-radius, 6px);
|
||||
border: 1px solid var(--surface-border);
|
||||
background: var(--surface-ground);
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition:
|
||||
border-color 0.15s,
|
||||
background 0.15s;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layout-option:hover {
|
||||
border-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.layout-option--active {
|
||||
border-color: var(--primary-color);
|
||||
background: color-mix(in srgb, var(--primary-color) 8%, transparent);
|
||||
border-color: var(--primary-color);
|
||||
background: color-mix(in srgb, var(--primary-color) 8%, transparent);
|
||||
}
|
||||
|
||||
.layout-option__icon {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-color-secondary);
|
||||
flex-shrink: 0;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-color-secondary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.layout-option--active .layout-option__icon {
|
||||
color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.layout-option__label {
|
||||
flex: 1;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.layout-option__badge {
|
||||
font-size: 0.6rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
padding: 0.1rem 0.45rem;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
font-size: 0.6rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
padding: 0.1rem 0.45rem;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.layout-option__badge--default {
|
||||
background: var(--primary-color);
|
||||
color: var(--primary-color-text, #fff);
|
||||
background: var(--primary-color);
|
||||
color: var(--primary-color-text, #fff);
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user