Merge branch 'main' into issue/14546

This commit is contained in:
Azri Kahar
2022-07-25 17:20:33 +08:00
514 changed files with 1029 additions and 2437 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "directus",
"version": "9.14.3",
"version": "9.14.5",
"license": "GPL-3.0-only",
"homepage": "https://github.com/directus/directus#readme",
"description": "Directus is a real-time API and App dashboard for managing SQL database content.",

View File

@@ -1250,7 +1250,7 @@ export class GraphQLService {
if (!selections) return null;
const args: Record<string, any> = this.parseArgs(info.fieldNodes[0].arguments || [], info.variableValues);
let query: Record<string, any>;
let query: Query;
const isAggregate = collection.endsWith('_aggregated') && collection in this.schema.collections === false;
@@ -1280,13 +1280,15 @@ export class GraphQLService {
}
// Transform count(a.b.c) into a.b.count(c)
for (let fieldIndex = 0; fieldIndex < query.fields.length; fieldIndex++) {
if (query.fields[fieldIndex].includes('(') && query.fields[fieldIndex].includes(')')) {
const functionName = query.fields[fieldIndex].split('(')[0];
const columnNames = query.fields[fieldIndex].match(REGEX_BETWEEN_PARENS)![1].split('.');
if (columnNames.length > 1) {
const column = columnNames.pop();
query.fields[fieldIndex] = columnNames.join('.') + '.' + functionName + '(' + column + ')';
if (query.fields?.length) {
for (let fieldIndex = 0; fieldIndex < query.fields.length; fieldIndex++) {
if (query.fields[fieldIndex].includes('(') && query.fields[fieldIndex].includes(')')) {
const functionName = query.fields[fieldIndex].split('(')[0];
const columnNames = query.fields[fieldIndex].match(REGEX_BETWEEN_PARENS)![1].split('.');
if (columnNames.length > 1) {
const column = columnNames.pop();
query.fields[fieldIndex] = columnNames.join('.') + '.' + functionName + '(' + column + ')';
}
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@directus/app",
"version": "9.14.3",
"version": "9.14.5",
"private": false,
"description": "Directus is an Open-Source Headless CMS & API for Managing Custom Databases",
"author": "Rijk van Zanten <rijkvanzanten@me.com>",

View File

@@ -1,5 +1,5 @@
import { logout, LogoutReason, refresh } from '@/auth';
import { useRequestsStore } from '@/stores/';
import { useRequestsStore } from '@/stores/requests';
import { getRootPath } from '@/utils/get-root-path';
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
import { addQueryToPath } from './utils/add-query-to-path';

View File

@@ -23,11 +23,13 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, toRefs, watch, computed, onMounted, onUnmounted, StyleValue } from 'vue';
import { useAppStore, useUserStore, useServerStore } from '@/stores';
import { useAppStore } from '@/stores/app';
import { useUserStore } from '@/stores/user';
import { useServerStore } from '@/stores/server';
import { startIdleTracking, stopIdleTracking } from './idle';
import useSystem from '@/composables/use-system';
import { useSystem } from '@/composables/use-system';
import setFavicon from '@/utils/set-favicon';
import { setFavicon } from '@/utils/set-favicon';
import { User } from '@directus/shared/types';
export default defineComponent({

View File

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 152 KiB

View File

@@ -1,7 +1,7 @@
import api from '@/api';
import { dehydrate, hydrate } from '@/hydrate';
import { router } from '@/router';
import { useAppStore } from '@/stores';
import { useAppStore } from '@/stores/app';
import { RouteLocationRaw } from 'vue-router';
import { idleTracker } from './idle';
import { DEFAULT_AUTH_PROVIDER } from '@/constants';

View File

@@ -1,59 +1,72 @@
import ExportSidebarDetail from '@/views/private/components/export-sidebar-detail.vue';
import RenderDisplay from '@/views/private/components/render-display';
import RenderTemplate from '@/views/private/components/render-template';
import SidebarDetail from '@/views/private/components/sidebar-detail/';
import UserPopover from '@/views/private/components/user-popover';
import ValueNull from '@/views/private/components/value-null';
import DocsWrapper from '@/views/private/components/docs-wrapper';
import RenderDisplay from '@/views/private/components/render-display.vue';
import RenderTemplate from '@/views/private/components/render-template.vue';
import SidebarDetail from '@/views/private/components/sidebar-detail.vue';
import UserPopover from '@/views/private/components/user-popover.vue';
import ValueNull from '@/views/private/components/value-null.vue';
import DocsWrapper from '@/views/private/components/docs-wrapper.vue';
import { App } from 'vue';
import TransitionBounce from './transition/bounce';
import TransitionDialog from './transition/dialog';
import TransitionExpand from './transition/expand';
import VAvatar from './v-avatar/';
import VBadge from './v-badge/';
import VBreadcrumb from './v-breadcrumb';
import VButton from './v-button/';
import VCard, { VCardActions, VCardSubtitle, VCardText, VCardTitle } from './v-card';
import VCheckbox from './v-checkbox/';
import VCheckboxTree from './v-checkbox-tree/';
import VChip from './v-chip/';
import VDetail from './v-detail';
import VDialog from './v-dialog';
import VDivider from './v-divider';
import VDrawer from './v-drawer/';
import VError from './v-error';
import VFancySelect from './v-fancy-select';
import VFieldTemplate from './v-field-template';
import VAvatar from './v-avatar.vue';
import VBadge from './v-badge.vue';
import VBreadcrumb from './v-breadcrumb.vue';
import VButton from './v-button.vue';
import VCard from './v-card.vue';
import VCardActions from './v-card-actions.vue';
import VCardSubtitle from './v-card-subtitle.vue';
import VCardText from './v-card-text.vue';
import VCardTitle from './v-card-title.vue';
import VCheckbox from './v-checkbox.vue';
import VCheckboxTree from './v-checkbox-tree/v-checkbox-tree.vue';
import VChip from './v-chip.vue';
import VDetail from './v-detail.vue';
import VDialog from './v-dialog.vue';
import VDivider from './v-divider.vue';
import VDrawer from './v-drawer.vue';
import VError from './v-error.vue';
import VFancySelect from './v-fancy-select.vue';
import VFieldTemplate from './v-field-template/v-field-template.vue';
import VFieldList from './v-field-list/v-field-list.vue';
import VForm from './v-form';
import VHover from './v-hover/';
import VForm from './v-form/v-form.vue';
import VHover from './v-hover.vue';
import VHighlight from './v-highlight.vue';
import VIcon from './v-icon/';
import VIcon from './v-icon/v-icon.vue';
import VImage from './v-image.vue';
import VIconFile from './v-icon-file.vue';
import VInfo from './v-info/';
import VInput from './v-input/';
import VItemGroup, { VItem } from './v-item-group';
import VList, { VListGroup, VListItem, VListItemContent, VListItemHint, VListItemIcon } from './v-list/';
import VMenu from './v-menu/';
import VNotice from './v-notice/';
import VOverlay from './v-overlay/';
import VPagination from './v-pagination/';
import VProgressCircular from './v-progress/circular/';
import VProgressLinear from './v-progress/linear/';
import VRadio from './v-radio/';
import VSelect from './v-select/';
import VSheet from './v-sheet/';
import VSkeletonLoader from './v-skeleton-loader/';
import VSlider from './v-slider/';
import VSwitch from './v-switch/';
import VTable from './v-table/';
import VTabs, { VTab, VTabItem, VTabsItems } from './v-tabs/';
import VInfo from './v-info.vue';
import VInput from './v-input.vue';
import VItemGroup from './v-item-group.vue';
import VItem from './v-item.vue';
import VList from './v-list.vue';
import VListGroup from './v-list-group.vue';
import VListItem from './v-list-item.vue';
import VListItemContent from './v-list-item-content.vue';
import VListItemHint from './v-list-item-hint.vue';
import VListItemIcon from './v-list-item-icon.vue';
import VMenu from './v-menu.vue';
import VNotice from './v-notice.vue';
import VOverlay from './v-overlay.vue';
import VPagination from './v-pagination.vue';
import VProgressCircular from './v-progress-circular.vue';
import VProgressLinear from './v-progress-linear.vue';
import VRadio from './v-radio.vue';
import VSelect from './v-select/v-select.vue';
import VSheet from './v-sheet.vue';
import VSkeletonLoader from './v-skeleton-loader.vue';
import VSlider from './v-slider.vue';
import VSwitch from './v-switch.vue';
import VTable from './v-table/v-table.vue';
import VTabs from './v-tabs.vue';
import VTab from './v-tab.vue';
import VTabItem from './v-tab-item.vue';
import VTabsItems from './v-tabs-items.vue';
import VTemplateInput from './v-template-input.vue';
import VTextOverflow from './v-text-overflow.vue';
import VTextarea from './v-textarea';
import VUpload from './v-upload';
import VDatePicker from './v-date-picker';
import VTextarea from './v-textarea.vue';
import VUpload from './v-upload.vue';
import VDatePicker from './v-date-picker.vue';
import VEmojiPicker from './v-emoji-picker.vue';
import VWorkspace from './v-workspace.vue';
import VWorkspaceTile from './v-workspace-tile.vue';

View File

@@ -1,4 +1,4 @@
import capitalizeFirst from '@/utils/capitalize-first';
import { capitalizeFirst } from '@/utils/capitalize-first';
interface HTMLExpandElement extends HTMLElement {
_parent?: (Node & ParentNode & HTMLElement) | null;

View File

@@ -6,7 +6,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import useSizeClass, { sizeProps } from '@/composables/size-class';
import { useSizeClass, sizeProps } from '@/composables/use-size-class';
export default defineComponent({
props: {

View File

@@ -1,4 +0,0 @@
import VAvatar from './v-avatar.vue';
export { VAvatar };
export default VAvatar;

View File

@@ -1,4 +0,0 @@
import VBadge from './v-badge.vue';
export { VBadge };
export default VBadge;

View File

@@ -1,4 +0,0 @@
import VBreadcrumb from './v-breadcrumb.vue';
export { VBreadcrumb };
export default VBreadcrumb;

View File

@@ -41,8 +41,8 @@
<script lang="ts">
import { defineComponent, computed, PropType } from 'vue';
import { RouteLocation, useRoute, useLink } from 'vue-router';
import useSizeClass, { sizeProps } from '@/composables/size-class';
import { useGroupable } from '@/composables/groupable';
import { useSizeClass, sizeProps } from '@/composables/use-size-class';
import { useGroupable } from '@/composables/use-groupable';
import { notEmpty } from '@/utils/is-empty';
import { isEqual } from 'lodash';

View File

@@ -1,4 +0,0 @@
import VButton from './v-button.vue';
export { VButton };
export default VButton;

View File

@@ -1,8 +0,0 @@
import VCardActions from './v-card-actions.vue';
import VCardSubtitle from './v-card-subtitle.vue';
import VCardText from './v-card-text.vue';
import VCardTitle from './v-card-title.vue';
import VCard from './v-card.vue';
export { VCard, VCardTitle, VCardSubtitle, VCardActions, VCardText };
export default VCard;

View File

@@ -1,4 +0,0 @@
import VCheckboxTree from './v-checkbox-tree.vue';
export { VCheckboxTree };
export default VCheckboxTree;

View File

@@ -1,4 +0,0 @@
import VCheckbox from './v-checkbox.vue';
export { VCheckbox };
export default VCheckbox;

View File

@@ -16,7 +16,7 @@
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
import useSizeClass, { sizeProps } from '@/composables/size-class';
import { useSizeClass, sizeProps } from '@/composables/use-size-class';
export default defineComponent({
props: {

View File

@@ -1,4 +0,0 @@
import VChip from './v-chip.vue';
export { VChip };
export default VChip;

View File

@@ -151,11 +151,6 @@ export default defineComponent({
});
</script>
<style>
@import 'flatpickr/dist/flatpickr.css';
@import './flatpickr-overrides.css';
</style>
<style lang="scss" scoped>
.v-date-picker {
.input {

View File

@@ -1,4 +0,0 @@
import VDatePicker from './v-date-picker.vue';
export { VDatePicker };
export default VDatePicker;

View File

@@ -1,4 +0,0 @@
import VDetail from './v-detail.vue';
export { VDetail };
export default VDetail;

View File

@@ -21,7 +21,7 @@
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
import { nanoid } from 'nanoid';
import useShortcut from '@/composables/use-shortcut';
import { useShortcut } from '@/composables/use-shortcut';
import { useDialogRouteLeave } from '@/composables/use-dialog-route';
export default defineComponent({

View File

@@ -1,4 +0,0 @@
import VDialog from './v-dialog.vue';
export { VDialog };
export default VDialog;

View File

@@ -1,4 +0,0 @@
import VDivider from './v-divider.vue';
export { VDivider };
export default VDivider;

View File

@@ -63,7 +63,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, ref, computed, provide } from 'vue';
import HeaderBar from '@/views/private/components/header-bar/header-bar.vue';
import HeaderBar from '@/views/private/components/header-bar.vue';
import { i18n } from '@/lang';
export default defineComponent({

View File

@@ -1,4 +0,0 @@
import VDrawer from './v-drawer.vue';
export { VDrawer };
export default VDrawer;

View File

@@ -17,7 +17,7 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, computed, PropType, ref } from 'vue';
import { isPlainObject } from 'lodash';
import useClipboard from '@/composables/use-clipboard';
import { useClipboard } from '@/composables/use-clipboard';
export default defineComponent({
props: {

View File

@@ -1,4 +0,0 @@
import VError from './v-error.vue';
export default VError;
export { VError };

View File

@@ -36,8 +36,17 @@
<script lang="ts" setup>
import { computed } from 'vue';
export type FancySelectItem = {
icon: string;
value?: string | number;
text: string;
description?: string;
divider?: boolean;
iconRight?: string;
};
interface Props {
items: Record<string, any>[];
items: FancySelectItem[];
modelValue?: string | number | null;
disabled?: boolean;
itemText?: string;

View File

@@ -1,4 +0,0 @@
import VFancySelect from './v-fancy-select.vue';
export { VFancySelect };
export default VFancySelect;

View File

@@ -1,8 +0,0 @@
export type FancySelectItem = {
icon: string;
value?: string | number;
text: string;
description?: string;
divider?: boolean;
iconRight?: string;
};

View File

@@ -29,7 +29,7 @@ import { computed, ref, toRefs, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import VFieldListItem from './v-field-list-item.vue';
import { debounce } from 'lodash';
import { useFieldsStore } from '@/stores';
import { useFieldsStore } from '@/stores/fields';
interface Props {
collection: string;

View File

@@ -1,4 +0,0 @@
import VFieldTemplate from './v-field-template.vue';
export default VFieldTemplate;
export { VFieldTemplate };

View File

@@ -51,7 +51,7 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, PropType, computed } from 'vue';
import { Field } from '@directus/shared/types';
import useClipboard from '@/composables/use-clipboard';
import { useClipboard } from '@/composables/use-clipboard';
export default defineComponent({
props: {

View File

@@ -82,7 +82,7 @@ import FormFieldInterface from './form-field-interface.vue';
import FormFieldLabel from './form-field-label.vue';
import FormFieldMenu from './form-field-menu.vue';
import { formatFieldFunction } from '@/utils/format-field-function';
import useClipboard from '@/composables/use-clipboard';
import { useClipboard } from '@/composables/use-clipboard';
interface Props {
field: Field;

View File

@@ -1,4 +0,0 @@
import VForm from './v-form.vue';
export { VForm };
export default VForm;

View File

@@ -77,8 +77,8 @@
<script lang="ts">
import { useElementSize } from '@/composables/use-element-size';
import useFormFields from '@/composables/use-form-fields';
import { useFieldsStore } from '@/stores/';
import { useFormFields } from '@/composables/use-form-fields';
import { useFieldsStore } from '@/stores/fields';
import { applyConditions } from '@/utils/apply-conditions';
import { extractFieldFromFunction } from '@/utils/extract-field-from-function';
import { Field, ValidationError } from '@directus/shared/types';
@@ -285,7 +285,7 @@ export default defineComponent({
});
const fieldsInGroup = computed(() =>
fields.value.filter(
formFields.value.filter(
(field: Field) => field.meta?.group === props.group || (props.group === null && isNil(field.meta?.group))
)
);

View File

@@ -1,4 +0,0 @@
import VHover from './v-hover.vue';
export { VHover };
export default VHover;

View File

@@ -1,4 +0,0 @@
import VIcon from './v-icon.vue';
export { VIcon };
export default VIcon;

View File

@@ -17,7 +17,7 @@
import { defineComponent, computed } from 'vue';
import { library } from '@fortawesome/fontawesome-svg-core';
import { fab } from '@fortawesome/free-brands-svg-icons';
import useSizeClass, { sizeProps } from '@/composables/size-class';
import { useSizeClass, sizeProps } from '@/composables/use-size-class';
import CustomIconDirectus from './custom-icons/directus.vue';
import CustomIconBookmarkSave from './custom-icons/bookmark_save.vue';

View File

@@ -1,4 +0,0 @@
import VInfo from './v-info.vue';
export { VInfo };
export default VInfo;

View File

@@ -1,4 +0,0 @@
import VInput from './v-input.vue';
export { VInput };
export default VInput;

View File

@@ -6,7 +6,7 @@
<script lang="ts">
import { defineComponent, PropType, toRefs } from 'vue';
import { useGroupableParent } from '@/composables/groupable';
import { useGroupableParent } from '@/composables/use-groupable';
export default defineComponent({
props: {

View File

@@ -1,5 +0,0 @@
import VItemGroup from './v-item-group.vue';
import VItem from './v-item.vue';
export { VItemGroup, VItem };
export default VItemGroup;

View File

@@ -6,7 +6,7 @@
<script lang="ts">
import { defineComponent, toRefs } from 'vue';
import { useGroupable } from '@/composables/groupable';
import { useGroupable } from '@/composables/use-groupable';
export default defineComponent({
props: {

View File

@@ -38,7 +38,7 @@
<script lang="ts">
import { defineComponent, computed } from 'vue';
import { useGroupable } from '@/composables/groupable';
import { useGroupable } from '@/composables/use-groupable';
export default defineComponent({
props: {

View File

@@ -23,7 +23,7 @@
<script lang="ts">
import { RouteLocation, useLink, useRoute } from 'vue-router';
import { defineComponent, PropType, computed } from 'vue';
import { useGroupable } from '@/composables/groupable';
import { useGroupable } from '@/composables/use-groupable';
import { isEqual } from 'lodash';
export default defineComponent({

View File

@@ -6,7 +6,7 @@
<script lang="ts">
import { defineComponent, PropType, toRefs } from 'vue';
import { useGroupableParent } from '@/composables/groupable';
import { useGroupableParent } from '@/composables/use-groupable';
export default defineComponent({
props: {

View File

@@ -1,10 +0,0 @@
import VListGroup from './v-list-group.vue';
import VListItemContent from './v-list-item-content.vue';
import VListItemHint from './v-list-item-hint.vue';
import VListItemIcon from './v-list-item-icon.vue';
import VListItem from './v-list-item.vue';
import VList from './v-list.vue';
export { VList, VListItem, VListItemContent, VListItemIcon, VListItemHint, VListGroup };
export default VList;

View File

@@ -59,11 +59,18 @@
</template>
<script lang="ts">
import { defineComponent, ref, PropType, computed, watch, nextTick } from 'vue';
import { usePopper } from './use-popper';
import { Placement } from '@popperjs/core';
import { nanoid } from 'nanoid';
import { Instance, Modifier, Placement } from '@popperjs/core';
import arrow from '@popperjs/core/lib/modifiers/arrow';
import computeStyles from '@popperjs/core/lib/modifiers/computeStyles';
import eventListeners from '@popperjs/core/lib/modifiers/eventListeners';
import flip from '@popperjs/core/lib/modifiers/flip';
import offset from '@popperjs/core/lib/modifiers/offset';
import popperOffsets from '@popperjs/core/lib/modifiers/popperOffsets';
import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow';
import { createPopper } from '@popperjs/core/lib/popper-lite';
import { debounce } from 'lodash';
import { nanoid } from 'nanoid';
import { computed, defineComponent, nextTick, onUnmounted, PropType, ref, Ref, watch } from 'vue';
export default defineComponent({
props: {
@@ -297,6 +304,126 @@ export default defineComponent({
isHovered.value = false;
}
}
function usePopper(
reference: Ref<HTMLElement | null>,
popper: Ref<HTMLElement | null>,
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({});
const arrowStyles = ref({});
// The internal placement can change based on the flip / overflow modifiers
const placement = ref(options.value.placement);
onUnmounted(() => {
stop();
});
watch(
options,
() => {
popperInstance.value?.setOptions({
placement: options.value.attached ? 'bottom-start' : options.value.placement,
modifiers: getModifiers(),
});
},
{ immediate: true }
);
const observer = new MutationObserver(() => {
popperInstance.value?.forceUpdate();
});
return { popperInstance, placement, start, stop, styles, arrowStyles };
function start() {
return new Promise((resolve) => {
popperInstance.value = createPopper(reference.value!, popper.value!, {
placement: options.value.attached ? 'bottom-start' : options.value.placement,
modifiers: getModifiers(resolve),
strategy: 'fixed',
});
popperInstance.value.forceUpdate();
observer.observe(popper.value!, {
attributes: false,
childList: true,
characterData: true,
subtree: true,
});
});
}
function stop() {
popperInstance.value?.destroy();
observer.disconnect();
}
function getModifiers(callback: (value?: unknown) => void = () => undefined) {
const modifiers: Modifier<string, any>[] = [
popperOffsets,
{
...offset,
options: {
offset: options.value.attached ? [0, 0] : [options.value.offsetX ?? 0, options.value.offsetY ?? 8],
},
},
{
...preventOverflow,
options: {
padding: 8,
},
},
computeStyles,
flip,
eventListeners,
{
name: 'placementUpdater',
enabled: true,
phase: 'afterWrite',
fn({ state }) {
placement.value = state.placement;
},
},
{
name: 'applyStyles',
enabled: true,
phase: 'write',
fn({ state }) {
styles.value = state.styles.popper;
arrowStyles.value = state.styles.arrow;
callback();
},
},
];
if (options.value.arrow === true) {
modifiers.push({
...arrow,
options: {
padding: 6,
},
});
}
if (options.value.attached === true) {
modifiers.push({
name: 'sameWidth',
enabled: true,
fn: ({ state }) => {
state.styles.popper.width = `${state.rects.reference.width}px`;
},
phase: 'beforeWrite',
requires: ['computeStyles'],
});
}
return modifiers;
}
}
},
});
</script>

View File

@@ -1,4 +0,0 @@
import VMenu from './v-menu.vue';
export { VMenu };
export default VMenu;

View File

@@ -1,130 +0,0 @@
import { createPopper } from '@popperjs/core/lib/popper-lite';
import { Instance, Modifier, Placement } from '@popperjs/core';
import arrow from '@popperjs/core/lib/modifiers/arrow';
import computeStyles from '@popperjs/core/lib/modifiers/computeStyles';
import eventListeners from '@popperjs/core/lib/modifiers/eventListeners';
import flip from '@popperjs/core/lib/modifiers/flip';
import offset from '@popperjs/core/lib/modifiers/offset';
import popperOffsets from '@popperjs/core/lib/modifiers/popperOffsets';
import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow';
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; offsetY: number; offsetX: number }>>
>
): Record<string, any> {
const popperInstance = ref<Instance | null>(null);
const styles = ref({});
const arrowStyles = ref({});
// The internal placement can change based on the flip / overflow modifiers
const placement = ref(options.value.placement);
onUnmounted(() => {
stop();
});
watch(
options,
() => {
popperInstance.value?.setOptions({
placement: options.value.attached ? 'bottom-start' : options.value.placement,
modifiers: getModifiers(),
});
},
{ immediate: true }
);
const observer = new MutationObserver(() => {
popperInstance.value?.forceUpdate();
});
return { popperInstance, placement, start, stop, styles, arrowStyles };
function start() {
return new Promise((resolve) => {
popperInstance.value = createPopper(reference.value!, popper.value!, {
placement: options.value.attached ? 'bottom-start' : options.value.placement,
modifiers: getModifiers(resolve),
strategy: 'fixed',
});
popperInstance.value.forceUpdate();
observer.observe(popper.value!, {
attributes: false,
childList: true,
characterData: true,
subtree: true,
});
});
}
function stop() {
popperInstance.value?.destroy();
observer.disconnect();
}
function getModifiers(callback: (value?: unknown) => void = () => undefined) {
const modifiers: Modifier<string, any>[] = [
popperOffsets,
{
...offset,
options: {
offset: options.value.attached ? [0, 0] : [options.value.offsetX ?? 0, options.value.offsetY ?? 8],
},
},
{
...preventOverflow,
options: {
padding: 8,
},
},
computeStyles,
flip,
eventListeners,
{
name: 'placementUpdater',
enabled: true,
phase: 'afterWrite',
fn({ state }) {
placement.value = state.placement;
},
},
{
name: 'applyStyles',
enabled: true,
phase: 'write',
fn({ state }) {
styles.value = state.styles.popper;
arrowStyles.value = state.styles.arrow;
callback();
},
},
];
if (options.value.arrow === true) {
modifiers.push({
...arrow,
options: {
padding: 6,
},
});
}
if (options.value.attached === true) {
modifiers.push({
name: 'sameWidth',
enabled: true,
fn: ({ state }) => {
state.styles.popper.width = `${state.rects.reference.width}px`;
},
phase: 'beforeWrite',
requires: ['computeStyles'],
});
}
return modifiers;
}
}

View File

@@ -1,4 +0,0 @@
import VNotice from './v-notice.vue';
export { VNotice };
export default VNotice;

View File

@@ -1,4 +0,0 @@
import VOverlay from './v-overlay.vue';
export { VOverlay };
export default VOverlay;

View File

@@ -1,4 +0,0 @@
import VPagination from './v-pagination.vue';
export { VPagination };
export default VPagination;

View File

@@ -24,7 +24,7 @@
<script lang="ts">
import { defineComponent, computed } from 'vue';
import useSizeClass, { sizeProps } from '@/composables/size-class';
import { useSizeClass, sizeProps } from '@/composables/use-size-class';
export default defineComponent({
props: {

View File

@@ -1,4 +0,0 @@
import VProgressCircular from './v-progress-circular.vue';
export { VProgressCircular };
export default VProgressCircular;

View File

@@ -1,70 +0,0 @@
# Progress (circular)
```html
<v-progress-circular />
```
## Colors
The color of the circular progressbar can be changed through the `--v-progress-circular-color` and
`--v-progress-circular-background-color` css variable.
```html
<v-progress-circular />
<style>
.v-progress-circular {
--v-progress-circular-color: var(--red-100);
--v-progress-circular-background-color: var(--red-600);
}
</style>
```
## Sizes
The circular progress component supports the following sizes through the use of props:
- x-small
- small
- (default)
- large
- x-large
```html
<v-progress-circular x-small />
<v-progress-circular small />
<v-progress-circular />
<v-progress-circular large />
<v-progress-circular x-large />
```
## Props
| Prop | Description | Default |
| --------------- | ------------------------------ | ------- |
| `value` | The percentage value | `0` |
| `indeterminate` | Displays the loading animation | `false` |
| `x-small` | Render extra small | `false` |
| `small` | Render small | `false` |
| `large` | Render large | `false` |
| `x-large` | Render extra large | `false` |
## Slots
| Slot | Description | Data |
| --------- | ------------------------------------ | ---- |
| _default_ | Rendered in the center of the circle | -- |
## Events
n/a
## CSS Variables
| Variable | Default |
| ---------------------------------------- | ---------------------------------------- |
| `--v-progress-circular-color` | `var(--loading-background-color-accent)` |
| `--v-progress-circular-background-color` | `var(--loading-background-color)` |
| `--v-progress-circular-transition` | `400ms` |
| `--v-progress-circular-speed` | `1s` |
| `--v-progress-circular-size` | `28px` |
| `--v-progress-circular-line-size` | `3px` |

View File

@@ -1,4 +0,0 @@
import VProgressLinear from './v-progress-linear.vue';
export { VProgressLinear };
export default VProgressLinear;

View File

@@ -1,55 +0,0 @@
# Progress (Linear)
```html
<v-progress-linear :value="75" />
```
## Colors
The linear progress component supports colors. Colors can be changed via the css variables `--v-progress-linear-color`
and `--v-progress-linear-background-color`
```html
<v-progress-linear />
<style>
.v-overlay {
--v-progress-linear-color: red;
--v-progress-linear-background-color: var(--black);
}
</style>
```
## Indeterminate
The progress indicator can be rendered in indeterminate mode by passing the `indeterminate` prop. Use this when it's
unclear when the progress will be done.
## Props
| Prop | Description | Default |
| --------------- | ------------------------------------------------------ | ------- |
| `absolute` | Applies `position: absolute` | `false` |
| `bottom` | Align the progress bar to the bottom | `false` |
| `fixed` | Applies `position: fixed;` to the element | `false` |
| `indeterminate` | Animates the bar, use when loading progress is unknown | `false` |
| `rounded` | Add a border radius to the bar | `false` |
| `top` | Align progress bar to the top of the parent container | `false` |
| `value` | Percentage value for current progress | `0` |
## Events
n/a
## Slots
| Slots | Description | Value |
| --------- | ----------- | ----- |
| _default_ | | -- |
## CSS Variables
| Variable | Default |
| -------------------------------------- | -------------------------- |
| `--v-progress-linear-height` | `4px` |
| `--v-progress-linear-color` | `var(--foreground-normal)` |
| `--v-progress-linear-background-color` | `var(--border-normal)` |

View File

@@ -1,4 +0,0 @@
import VRadio from './v-radio.vue';
export { VRadio };
export default VRadio;

View File

@@ -1,4 +0,0 @@
import VSelect from './v-select.vue';
export { VSelect };
export default VSelect;

View File

@@ -1,4 +0,0 @@
import VSheet from './v-sheet.vue';
export { VSheet };
export default VSheet;

View File

@@ -1,4 +0,0 @@
import VSkeletonLoader from './v-skeleton-loader.vue';
export { VSkeletonLoader };
export default VSkeletonLoader;

View File

@@ -1,4 +0,0 @@
import VSlider from './v-slider.vue';
export { VSlider };
export default VSlider;

View File

@@ -1,4 +0,0 @@
import VSwitch from './v-switch.vue';
export { VSwitch };
export default VSwitch;

View File

@@ -6,7 +6,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { useGroupable } from '@/composables/groupable';
import { useGroupable } from '@/composables/use-groupable';
export default defineComponent({
props: {

View File

@@ -9,7 +9,7 @@
<script lang="ts">
import { defineComponent, inject, ref } from 'vue';
import { useGroupable } from '@/composables/groupable';
import { useGroupable } from '@/composables/use-groupable';
export default defineComponent({
props: {

View File

@@ -1,4 +0,0 @@
import VTable from './v-table.vue';
export { VTable };
export default VTable;

View File

@@ -101,11 +101,11 @@
import { useI18n } from 'vue-i18n';
import { computed, ref, useSlots } from 'vue';
import { ShowSelect } from '@directus/shared/types';
import useEventListener from '@/composables/use-event-listener';
import { useEventListener } from '@/composables/use-event-listener';
import { Header, Sort } from './types';
import { throttle, clone } from 'lodash';
import Draggable from 'vuedraggable';
import hideDragImage from '@/utils/hide-drag-image';
import { hideDragImage } from '@/utils/hide-drag-image';
import { useSync } from '@directus/shared/composables';
interface Props {

View File

@@ -98,7 +98,7 @@ import TableRow from './table-row.vue';
import { sortBy, clone, forEach, pick } from 'lodash';
import { i18n } from '@/lang/';
import Draggable from 'vuedraggable';
import hideDragImage from '@/utils/hide-drag-image';
import { hideDragImage } from '@/utils/hide-drag-image';
const HeaderDefaults: Header = {
text: '',

View File

@@ -9,7 +9,7 @@
<script lang="ts">
import { defineComponent, PropType, toRefs, provide, ref } from 'vue';
import { useGroupableParent } from '@/composables/groupable';
import { useGroupableParent } from '@/composables/use-groupable';
export default defineComponent({
props: {

Some files were not shown because too many files have changed in this diff Show More