mirror of
https://github.com/directus/directus.git
synced 2026-02-14 23:35:00 -05:00
Add new advanced filters experience (#8570)
* Remove advanced filter sidebar detail So long, and thanks for all the fish. * Remove filter conversion logic * Start replacing/removing old skool filters * Add inline mode for usages in search bar * Make filter work in header bar * Emit empty string as null in filter * Move shared filter types to shared * Upgrade use-items * Fix manual sort on tabular * Cleanup styling in search bar usage * Tweak styling * Fix filtering issues * Update cards * Remove activeFilterCount from tabular * Update maps to work with new filters * Update calendar to new filter/sort structure * Fix activity module nav/search * Fix no-results message * Update file library filtering * Finalize user search * Allow filtering in drawer-collection * Handle cancelled responses semi-gracefully * Add loading start state timeout * Replace sort type in api * Last commit before redoing a bunch * Finish new visual style * Remove unused rounded prop from v-menu * Tweak sizing * Enough size tweaking for now * Count all filter operators instead of top * Fix archive casting * Fix api build * Add merge filters util * Split filter in user vs system * Fix export sidebar detail * Show field label on permissions configuration * Add migration for filter/sort * Use filters in insights
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import ExportSidebarDetail from '@/views/private/components/export-sidebar-detail';
|
||||
import FilterSidebarDetail from '@/views/private/components/filter-sidebar-detail';
|
||||
import RenderDisplay from '@/views/private/components/render-display';
|
||||
import RenderTemplate from '@/views/private/components/render-template';
|
||||
import SidebarDetail from '@/views/private/components/sidebar-detail/';
|
||||
@@ -113,7 +112,6 @@ export function registerComponents(app: App): void {
|
||||
|
||||
app.component('RenderDisplay', RenderDisplay);
|
||||
app.component('RenderTemplate', RenderTemplate);
|
||||
app.component('FilterSidebarDetail', FilterSidebarDetail);
|
||||
app.component('ExportSidebarDetail', ExportSidebarDetail);
|
||||
app.component('SidebarDetail', SidebarDetail);
|
||||
app.component('UserPopover', UserPopover);
|
||||
|
||||
@@ -11,12 +11,21 @@ interface HTMLExpandElement extends HTMLElement {
|
||||
};
|
||||
}
|
||||
|
||||
export default function (expandedParentClass = '', xAxis = false): Record<string, any> {
|
||||
export default function (
|
||||
expandedParentClass = '',
|
||||
xAxis = false,
|
||||
emit: (
|
||||
event: 'beforeEnter' | 'enter' | 'afterEnter' | 'enterCancelled' | 'leave' | 'afterLeave' | 'leaveCancelled',
|
||||
...args: any[]
|
||||
) => void
|
||||
): Record<string, any> {
|
||||
const sizeProperty = xAxis ? 'width' : ('height' as 'width' | 'height');
|
||||
const offsetProperty = `offset${capitalizeFirst(sizeProperty)}` as 'offsetHeight' | 'offsetWidth';
|
||||
|
||||
return {
|
||||
beforeEnter(el: HTMLExpandElement) {
|
||||
emit('beforeEnter');
|
||||
|
||||
el._parent = el.parentNode as (Node & ParentNode & HTMLElement) | null;
|
||||
el._initialStyle = {
|
||||
transition: el.style.transition,
|
||||
@@ -27,6 +36,8 @@ export default function (expandedParentClass = '', xAxis = false): Record<string
|
||||
},
|
||||
|
||||
enter(el: HTMLExpandElement) {
|
||||
emit('enter');
|
||||
|
||||
const initialStyle = el._initialStyle;
|
||||
if (!initialStyle) return;
|
||||
const offset = `${el[offsetProperty]}px`;
|
||||
@@ -51,10 +62,19 @@ export default function (expandedParentClass = '', xAxis = false): Record<string
|
||||
});
|
||||
},
|
||||
|
||||
afterEnter: resetStyles,
|
||||
enterCancelled: resetStyles,
|
||||
afterEnter(el: HTMLExpandElement) {
|
||||
emit('afterEnter');
|
||||
resetStyles(el);
|
||||
},
|
||||
|
||||
enterCancelled(el: HTMLExpandElement) {
|
||||
emit('enterCancelled');
|
||||
resetStyles(el);
|
||||
},
|
||||
|
||||
leave(el: HTMLExpandElement) {
|
||||
emit('leave');
|
||||
|
||||
el._initialStyle = {
|
||||
transition: '',
|
||||
visibility: '',
|
||||
@@ -69,16 +89,25 @@ export default function (expandedParentClass = '', xAxis = false): Record<string
|
||||
requestAnimationFrame(() => (el.style[sizeProperty] = '0'));
|
||||
},
|
||||
|
||||
afterLeave,
|
||||
leaveCancelled: afterLeave,
|
||||
};
|
||||
afterLeave(el: HTMLExpandElement) {
|
||||
emit('afterLeave');
|
||||
|
||||
function afterLeave(el: HTMLExpandElement) {
|
||||
if (expandedParentClass && el._parent) {
|
||||
el._parent.classList.remove(expandedParentClass);
|
||||
}
|
||||
resetStyles(el);
|
||||
}
|
||||
if (expandedParentClass && el._parent) {
|
||||
el._parent.classList.remove(expandedParentClass);
|
||||
}
|
||||
|
||||
resetStyles(el);
|
||||
},
|
||||
leaveCancelled(el: HTMLExpandElement) {
|
||||
emit('leaveCancelled');
|
||||
|
||||
if (expandedParentClass && el._parent) {
|
||||
el._parent.classList.remove(expandedParentClass);
|
||||
}
|
||||
|
||||
resetStyles(el);
|
||||
},
|
||||
};
|
||||
|
||||
function resetStyles(el: HTMLExpandElement) {
|
||||
if (!el._initialStyle) return;
|
||||
|
||||
@@ -19,8 +19,9 @@ export default defineComponent({
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const methods = ExpandMethods(props.expandedParentClass, props.xAxis);
|
||||
emits: ['beforeEnter', 'enter', 'afterEnter', 'enterCancelled', 'leave', 'afterLeave', 'leaveCancelled'],
|
||||
setup(props, { emit }) {
|
||||
const methods = ExpandMethods(props.expandedParentClass, props.xAxis, emit);
|
||||
return { methods };
|
||||
},
|
||||
});
|
||||
|
||||
@@ -46,8 +46,8 @@ export default defineComponent({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
<style lang="scss" scoped>
|
||||
:global(body) {
|
||||
--v-badge-color: var(--white);
|
||||
--v-badge-background-color: var(--danger);
|
||||
--v-badge-border-color: var(--background-page);
|
||||
@@ -55,9 +55,7 @@ body {
|
||||
--v-badge-offset-y: 0px;
|
||||
--v-badge-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-badge {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
@@ -12,7 +12,9 @@ import { onUnmounted, ref, Ref, watch } from 'vue';
|
||||
export function usePopper(
|
||||
reference: Ref<HTMLElement | null>,
|
||||
popper: Ref<HTMLElement | null>,
|
||||
options: Readonly<Ref<Readonly<{ placement: Placement; attached: boolean; arrow: boolean }>>>
|
||||
options: Readonly<
|
||||
Ref<Readonly<{ placement: Placement; attached: boolean; arrow: boolean; offsetY: number; offsetX: number }>>
|
||||
>
|
||||
): Record<string, any> {
|
||||
const popperInstance = ref<Instance | null>(null);
|
||||
const styles = ref({});
|
||||
@@ -72,7 +74,7 @@ export function usePopper(
|
||||
{
|
||||
...offset,
|
||||
options: {
|
||||
offset: options.value.attached ? [0, 0] : [0, 8],
|
||||
offset: options.value.attached ? [0, 0] : [options.value.offsetX ?? 0, options.value.offsetY ?? 8],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -103,6 +103,14 @@ export default defineComponent({
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
offsetY: {
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
offsetX: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, { emit }) {
|
||||
@@ -138,6 +146,8 @@ export default defineComponent({
|
||||
placement: props.placement,
|
||||
attached: props.attached,
|
||||
arrow: props.showArrow,
|
||||
offsetY: props.offsetY,
|
||||
offsetX: props.offsetX,
|
||||
}))
|
||||
);
|
||||
|
||||
@@ -311,17 +321,16 @@ body {
|
||||
}
|
||||
|
||||
.arrow,
|
||||
.arrow::before,
|
||||
.arrow::after {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
&::before,
|
||||
&::after {
|
||||
background: var(--card-face-color);
|
||||
transform: rotate(45deg) scale(0);
|
||||
@@ -330,16 +339,10 @@ body {
|
||||
content: '';
|
||||
}
|
||||
|
||||
&.active::before,
|
||||
&.active::after {
|
||||
transform: rotate(45deg) scale(1);
|
||||
transition: transform var(--medium) var(--transition-in);
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: var(--card-face-color);
|
||||
box-shadow: -2.5px -2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
[data-placement^='top'] .arrow {
|
||||
@@ -347,7 +350,7 @@ body {
|
||||
|
||||
&::after {
|
||||
bottom: 2px;
|
||||
box-shadow: 2.5px 2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
// box-shadow: 2.5px 2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +359,7 @@ body {
|
||||
|
||||
&::after {
|
||||
top: 2px;
|
||||
box-shadow: -2.5px -2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
// box-shadow: -2.5px -2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +368,7 @@ body {
|
||||
|
||||
&::after {
|
||||
left: 2px;
|
||||
box-shadow: -2.5px 2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
// box-shadow: -2.5px 2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +377,7 @@ body {
|
||||
|
||||
&::after {
|
||||
right: 2px;
|
||||
box-shadow: 2.5px -2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
// box-shadow: 2.5px -2.5px 4px 0px rgba(var(--card-shadow-color), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user