@directus/composables 10.1.2 → 10.1.4

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/dist/use-items.js DELETED
@@ -1,234 +0,0 @@
1
- import { getEndpoint, moveInArray } from '@directus/utils';
2
- import axios from 'axios';
3
- import { isEqual, throttle } from 'lodash-es';
4
- import { computed, ref, unref, watch } from 'vue';
5
- import { useCollection } from './use-collection.js';
6
- import { useApi } from './use-system.js';
7
- export function useItems(collection, query) {
8
- const api = useApi();
9
- const { primaryKeyField } = useCollection(collection);
10
- const { fields, limit, sort, search, filter, page, alias: queryAlias, deep: queryDeep } = query;
11
- const alias = queryAlias ?? ref();
12
- const deep = queryDeep ?? ref();
13
- const endpoint = computed(() => {
14
- if (!collection.value)
15
- return null;
16
- return getEndpoint(collection.value);
17
- });
18
- const items = ref([]);
19
- const loading = ref(false);
20
- const error = ref(null);
21
- const itemCount = ref(null);
22
- const totalCount = ref(null);
23
- const totalPages = computed(() => {
24
- if (itemCount.value === null)
25
- return 1;
26
- if (itemCount.value < (unref(limit) ?? 100))
27
- return 1;
28
- return Math.ceil(itemCount.value / (unref(limit) ?? 100));
29
- });
30
- const existingRequests = {
31
- items: null,
32
- total: null,
33
- filter: null,
34
- };
35
- let loadingTimeout = null;
36
- const fetchItems = throttle(getItems, 500);
37
- watch([collection, limit, sort, search, filter, fields, page, alias, deep], async (after, before) => {
38
- if (isEqual(after, before))
39
- return;
40
- const [newCollection, newLimit, newSort, newSearch, newFilter] = after;
41
- const [oldCollection, oldLimit, oldSort, oldSearch, oldFilter] = before;
42
- if (!newCollection || !query)
43
- return;
44
- if (newCollection !== oldCollection) {
45
- reset();
46
- }
47
- if (!isEqual(newFilter, oldFilter) ||
48
- !isEqual(newSort, oldSort) ||
49
- newLimit !== oldLimit ||
50
- newSearch !== oldSearch) {
51
- if (oldCollection) {
52
- page.value = 1;
53
- }
54
- }
55
- if (newCollection !== oldCollection || !isEqual(newFilter, oldFilter) || newSearch !== oldSearch) {
56
- getItemCount();
57
- }
58
- fetchItems();
59
- }, { deep: true, immediate: true });
60
- return {
61
- itemCount,
62
- totalCount,
63
- items,
64
- totalPages,
65
- loading,
66
- error,
67
- changeManualSort,
68
- getItems,
69
- getItemCount,
70
- getTotalCount,
71
- };
72
- async function getItems() {
73
- if (!endpoint.value)
74
- return;
75
- let isCurrentRequestCanceled = false;
76
- if (existingRequests.items)
77
- existingRequests.items.abort();
78
- existingRequests.items = new AbortController();
79
- error.value = null;
80
- if (loadingTimeout) {
81
- clearTimeout(loadingTimeout);
82
- }
83
- loadingTimeout = setTimeout(() => {
84
- loading.value = true;
85
- }, 150);
86
- if (unref(totalCount) === null) {
87
- getTotalCount();
88
- }
89
- let fieldsToFetch = [...(unref(fields) ?? [])];
90
- // Make sure the primary key is always fetched
91
- if (!unref(fields)?.includes('*') &&
92
- primaryKeyField.value &&
93
- fieldsToFetch.includes(primaryKeyField.value.field) === false) {
94
- fieldsToFetch.push(primaryKeyField.value.field);
95
- }
96
- // Filter out fake internal columns. This is (among other things) for a fake $thumbnail m2o field
97
- // on directus_files
98
- fieldsToFetch = fieldsToFetch.filter((field) => field.startsWith('$') === false);
99
- try {
100
- const response = await api.get(endpoint.value, {
101
- params: {
102
- limit: unref(limit),
103
- fields: fieldsToFetch,
104
- ...(alias ? { alias: unref(alias) } : {}),
105
- sort: unref(sort),
106
- page: unref(page),
107
- search: unref(search),
108
- filter: unref(filter),
109
- deep: unref(deep),
110
- },
111
- signal: existingRequests.items.signal,
112
- });
113
- let fetchedItems = response.data.data;
114
- existingRequests.items = null;
115
- /**
116
- * @NOTE
117
- *
118
- * This is used in conjunction with the fake field in /src/stores/fields/fields.ts to be
119
- * able to render out the directus_files collection (file library) using regular layouts
120
- *
121
- * Layouts expect the file to be a m2o of a `file` type, however, directus_files is the
122
- * only collection that doesn't have this (obviously). This fake $thumbnail field is used to
123
- * pretend there is a file m2o, so we can use the regular layout logic for files as well
124
- */
125
- if (collection.value === 'directus_files') {
126
- fetchedItems = fetchedItems.map((file) => ({
127
- ...file,
128
- $thumbnail: file,
129
- }));
130
- }
131
- items.value = fetchedItems;
132
- if (page && fetchedItems.length === 0 && page?.value !== 1) {
133
- page.value = 1;
134
- }
135
- }
136
- catch (err) {
137
- if (axios.isCancel(err)) {
138
- isCurrentRequestCanceled = true;
139
- }
140
- else {
141
- error.value = err;
142
- }
143
- }
144
- finally {
145
- if (loadingTimeout && !isCurrentRequestCanceled) {
146
- clearTimeout(loadingTimeout);
147
- loadingTimeout = null;
148
- }
149
- if (!loadingTimeout)
150
- loading.value = false;
151
- }
152
- }
153
- function reset() {
154
- items.value = [];
155
- totalCount.value = null;
156
- itemCount.value = null;
157
- }
158
- async function changeManualSort({ item, to }) {
159
- const pk = primaryKeyField.value?.field;
160
- if (!pk)
161
- return;
162
- const fromIndex = items.value.findIndex((existing) => existing[pk] === item);
163
- const toIndex = items.value.findIndex((existing) => existing[pk] === to);
164
- items.value = moveInArray(items.value, fromIndex, toIndex);
165
- const endpoint = computed(() => `/utils/sort/${collection.value}`);
166
- await api.post(endpoint.value, { item, to });
167
- }
168
- async function getTotalCount() {
169
- if (!endpoint.value)
170
- return;
171
- try {
172
- if (existingRequests.total)
173
- existingRequests.total.abort();
174
- existingRequests.total = new AbortController();
175
- const aggregate = primaryKeyField.value
176
- ? {
177
- countDistinct: primaryKeyField.value.field,
178
- }
179
- : {
180
- count: '*',
181
- };
182
- const response = await api.get(endpoint.value, {
183
- params: {
184
- aggregate,
185
- },
186
- signal: existingRequests.total.signal,
187
- });
188
- const count = primaryKeyField.value
189
- ? Number(response.data.data[0].countDistinct[primaryKeyField.value.field])
190
- : Number(response.data.data[0].count);
191
- existingRequests.total = null;
192
- totalCount.value = count;
193
- }
194
- catch (err) {
195
- if (!axios.isCancel(err)) {
196
- throw err;
197
- }
198
- }
199
- }
200
- async function getItemCount() {
201
- if (!endpoint.value)
202
- return;
203
- try {
204
- if (existingRequests.filter)
205
- existingRequests.filter.abort();
206
- existingRequests.filter = new AbortController();
207
- const aggregate = primaryKeyField.value
208
- ? {
209
- countDistinct: primaryKeyField.value.field,
210
- }
211
- : {
212
- count: '*',
213
- };
214
- const response = await api.get(endpoint.value, {
215
- params: {
216
- filter: unref(filter),
217
- search: unref(search),
218
- aggregate,
219
- },
220
- signal: existingRequests.filter.signal,
221
- });
222
- const count = primaryKeyField.value
223
- ? Number(response.data.data[0].countDistinct[primaryKeyField.value.field])
224
- : Number(response.data.data[0].count);
225
- existingRequests.filter = null;
226
- itemCount.value = count;
227
- }
228
- catch (err) {
229
- if (!axios.isCancel(err)) {
230
- throw err;
231
- }
232
- }
233
- }
234
- }
@@ -1,4 +0,0 @@
1
- import type { Component, ComputedRef, Ref } from 'vue';
2
- export declare function useLayout<Options = any, Query = any>(layoutId: Ref<string | null>): {
3
- layoutWrapper: ComputedRef<Component>;
4
- };
@@ -1,100 +0,0 @@
1
- import { computed, defineComponent, reactive, toRefs } from 'vue';
2
- import { useExtensions } from './use-system.js';
3
- const NAME_SUFFIX = 'wrapper';
4
- const WRITABLE_PROPS = ['selection', 'layoutOptions', 'layoutQuery'];
5
- function isWritableProp(prop) {
6
- return WRITABLE_PROPS.includes(prop);
7
- }
8
- function createLayoutWrapper(layout) {
9
- return defineComponent({
10
- name: `${layout.id}-${NAME_SUFFIX}`,
11
- props: {
12
- collection: {
13
- type: String,
14
- required: true,
15
- },
16
- selection: {
17
- type: Array,
18
- default: () => [],
19
- },
20
- layoutOptions: {
21
- type: Object,
22
- default: () => ({}),
23
- },
24
- layoutQuery: {
25
- type: Object,
26
- default: () => ({}),
27
- },
28
- layoutProps: {
29
- type: Object,
30
- default: () => ({}),
31
- },
32
- filter: {
33
- type: Object,
34
- default: null,
35
- },
36
- filterUser: {
37
- type: Object,
38
- default: null,
39
- },
40
- filterSystem: {
41
- type: Object,
42
- default: null,
43
- },
44
- search: {
45
- type: String,
46
- default: null,
47
- },
48
- showSelect: {
49
- type: String,
50
- default: 'multiple',
51
- },
52
- selectMode: {
53
- type: Boolean,
54
- default: false,
55
- },
56
- readonly: {
57
- type: Boolean,
58
- default: false,
59
- },
60
- resetPreset: {
61
- type: Function,
62
- default: null,
63
- },
64
- clearFilters: {
65
- type: Function,
66
- default: null,
67
- },
68
- },
69
- emits: WRITABLE_PROPS.map((prop) => `update:${prop}`),
70
- setup(props, { emit }) {
71
- const state = reactive({ ...layout.setup(props, { emit }), ...toRefs(props) });
72
- for (const key in state) {
73
- state[`onUpdate:${key}`] = (value) => {
74
- if (isWritableProp(key)) {
75
- emit(`update:${key}`, value);
76
- }
77
- else if (!Object.keys(props).includes(key)) {
78
- state[key] = value;
79
- }
80
- };
81
- }
82
- return { state };
83
- },
84
- render(ctx) {
85
- return ctx.$slots.default !== undefined ? ctx.$slots.default({ layoutState: ctx.state }) : null;
86
- },
87
- });
88
- }
89
- export function useLayout(layoutId) {
90
- const { layouts } = useExtensions();
91
- const layoutWrappers = computed(() => layouts.value.map((layout) => createLayoutWrapper(layout)));
92
- const layoutWrapper = computed(() => {
93
- const layout = layoutWrappers.value.find((layout) => layout.name === `${layoutId.value}-${NAME_SUFFIX}`);
94
- if (layout === undefined) {
95
- return layoutWrappers.value.find((layout) => layout.name === `tabular-${NAME_SUFFIX}`);
96
- }
97
- return layout;
98
- });
99
- return { layoutWrapper };
100
- }
@@ -1,27 +0,0 @@
1
- import type { ComputedRef } from 'vue';
2
- export declare const sizeProps: {
3
- xSmall: {
4
- type: BooleanConstructor;
5
- default: boolean;
6
- };
7
- small: {
8
- type: BooleanConstructor;
9
- default: boolean;
10
- };
11
- large: {
12
- type: BooleanConstructor;
13
- default: boolean;
14
- };
15
- xLarge: {
16
- type: BooleanConstructor;
17
- default: boolean;
18
- };
19
- };
20
- interface SizeProps {
21
- xSmall?: boolean;
22
- small?: boolean;
23
- large?: boolean;
24
- xLarge?: boolean;
25
- }
26
- export declare function useSizeClass<T>(props: T & SizeProps): ComputedRef<string | null>;
27
- export {};
@@ -1,33 +0,0 @@
1
- import { computed } from 'vue';
2
- export const sizeProps = {
3
- xSmall: {
4
- type: Boolean,
5
- default: false,
6
- },
7
- small: {
8
- type: Boolean,
9
- default: false,
10
- },
11
- large: {
12
- type: Boolean,
13
- default: false,
14
- },
15
- xLarge: {
16
- type: Boolean,
17
- default: false,
18
- },
19
- };
20
- export function useSizeClass(props) {
21
- const sizeClass = computed(() => {
22
- if (props.xSmall)
23
- return 'x-small';
24
- if (props.small)
25
- return 'small';
26
- if (props.large)
27
- return 'large';
28
- if (props.xLarge)
29
- return 'x-large';
30
- return null;
31
- });
32
- return sizeClass;
33
- }
@@ -1,2 +0,0 @@
1
- import type { Ref } from 'vue';
2
- export declare function useSync<T, K extends keyof T & string, E extends (event: `update:${K}`, ...args: any[]) => void>(props: T, key: K, emit: E): Ref<T[K]>;
package/dist/use-sync.js DELETED
@@ -1,11 +0,0 @@
1
- import { computed } from 'vue';
2
- export function useSync(props, key, emit) {
3
- return computed({
4
- get() {
5
- return props[key];
6
- },
7
- set(newVal) {
8
- emit(`update:${key}`, newVal);
9
- },
10
- });
11
- }
@@ -1,5 +0,0 @@
1
- import type { AppExtensionConfigs, RefRecord } from '@directus/types';
2
- import type { AxiosInstance } from 'axios';
3
- export declare function useStores(): Record<string, any>;
4
- export declare function useApi(): AxiosInstance;
5
- export declare function useExtensions(): RefRecord<AppExtensionConfigs>;
@@ -1,20 +0,0 @@
1
- import { API_INJECT, EXTENSIONS_INJECT, STORES_INJECT } from '@directus/constants';
2
- import { inject } from 'vue';
3
- export function useStores() {
4
- const stores = inject(STORES_INJECT);
5
- if (!stores)
6
- throw new Error('[useStores]: The stores could not be found.');
7
- return stores;
8
- }
9
- export function useApi() {
10
- const api = inject(API_INJECT);
11
- if (!api)
12
- throw new Error('[useApi]: The api could not be found.');
13
- return api;
14
- }
15
- export function useExtensions() {
16
- const extensions = inject(EXTENSIONS_INJECT);
17
- if (!extensions)
18
- throw new Error('[useExtensions]: The extensions could not be found.');
19
- return extensions;
20
- }