mirror of
https://github.com/directus/directus.git
synced 2026-02-16 17:35:39 -05:00
Add useFormFields composable (#691)
* Extract use-form-fields into separate composable * Use new composable on fields detail
This commit is contained in:
@@ -23,13 +23,10 @@ import { defineComponent, PropType, computed, ref } from '@vue/composition-api';
|
||||
import { useFieldsStore } from '@/stores/fields';
|
||||
import { Field } from '@/stores/fields/types';
|
||||
import { useElementSize } from '@/composables/use-element-size';
|
||||
import { isEmpty } from '@/utils/is-empty';
|
||||
import { clone } from 'lodash';
|
||||
import { FormField as TFormField } from './types';
|
||||
import interfaces from '@/interfaces';
|
||||
import marked from 'marked';
|
||||
import getDefaultInterfaceForType from '@/utils/get-default-interface-for-type';
|
||||
import FormField from './form-field.vue';
|
||||
import useFormFields from '@/composables/use-form-fields';
|
||||
|
||||
type FieldValues = {
|
||||
[field: string]: any;
|
||||
@@ -46,7 +43,7 @@ export default defineComponent({
|
||||
default: undefined,
|
||||
},
|
||||
fields: {
|
||||
type: Array as PropType<TFormField[]>,
|
||||
type: Array as PropType<Field[]>,
|
||||
default: undefined,
|
||||
},
|
||||
initialValues: {
|
||||
@@ -111,76 +108,7 @@ export default defineComponent({
|
||||
throw new Error('[v-form]: You need to pass either the collection or fields prop.');
|
||||
});
|
||||
|
||||
const formFields = computed(() => {
|
||||
let formFields = [...fields.value];
|
||||
|
||||
/**
|
||||
* @NOTE
|
||||
*
|
||||
* This can be optimized by combining a bunch of these maps and filters
|
||||
*/
|
||||
|
||||
// Filter out the fields that are marked hidden on detail
|
||||
formFields = formFields.filter((field) => {
|
||||
const hiddenDetail = field.hidden_detail;
|
||||
if (isEmpty(hiddenDetail)) return true;
|
||||
return hiddenDetail === false;
|
||||
});
|
||||
|
||||
// Sort the fields on the sort column value
|
||||
formFields = formFields.sort((a, b) => {
|
||||
if (a.sort == b.sort) return 0;
|
||||
if (a.sort === null || a.sort === undefined) return 1;
|
||||
if (b.sort === null || b.sort === undefined) return -1;
|
||||
return a.sort > b.sort ? 1 : -1;
|
||||
});
|
||||
|
||||
// Make sure all form fields have a width associated with it
|
||||
formFields = formFields.map((field) => {
|
||||
if (!field.width) {
|
||||
field.width = 'full';
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
|
||||
formFields = formFields.map((field) => {
|
||||
const interfaceUsed = interfaces.find((int) => int.id === field.interface);
|
||||
const interfaceExists = interfaceUsed !== undefined;
|
||||
|
||||
if (interfaceExists === false) {
|
||||
field.interface = getDefaultInterfaceForType(field.type);
|
||||
}
|
||||
|
||||
if (interfaceUsed?.hideLabel === true) {
|
||||
(field as TFormField).hideLabel = true;
|
||||
}
|
||||
|
||||
if (interfaceUsed?.hideLoader === true) {
|
||||
(field as TFormField).hideLoader = true;
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
|
||||
// Change the class to half-right if the current element is preceded by another half width field
|
||||
// this makes them align side by side
|
||||
formFields = formFields.map((field, index, formFields) => {
|
||||
if (index === 0) return field;
|
||||
|
||||
if (field.width === 'half') {
|
||||
const prevField = formFields[index - 1];
|
||||
|
||||
if (prevField.width === 'half') {
|
||||
field.width = 'half-right';
|
||||
}
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
|
||||
return formFields;
|
||||
});
|
||||
const { formFields } = useFormFields(fields);
|
||||
|
||||
const { width } = useElementSize(el);
|
||||
|
||||
|
||||
4
src/composables/use-form-fields/index.ts
Normal file
4
src/composables/use-form-fields/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import useFormFields from './use-form-fields';
|
||||
|
||||
export { useFormFields };
|
||||
export default useFormFields;
|
||||
81
src/composables/use-form-fields/use-form-fields.ts
Normal file
81
src/composables/use-form-fields/use-form-fields.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { computed, Ref } from '@vue/composition-api';
|
||||
import { isEmpty } from '@/utils/is-empty';
|
||||
import getDefaultInterfaceForType from '@/utils/get-default-interface-for-type';
|
||||
import interfaces from '@/interfaces';
|
||||
import { FormField } from '@/components/v-form/types';
|
||||
import { Field } from '@/stores/fields/types';
|
||||
|
||||
export default function useFormFields(fields: Ref<Field[]>) {
|
||||
const formFields = computed(() => {
|
||||
let formFields = [...fields.value];
|
||||
|
||||
/**
|
||||
* @TODO
|
||||
*
|
||||
* This can be optimized by combining a bunch of these maps and filters
|
||||
*/
|
||||
|
||||
// Filter out the fields that are marked hidden on detail
|
||||
formFields = formFields.filter((field) => {
|
||||
const hiddenDetail = field.hidden_detail;
|
||||
if (isEmpty(hiddenDetail)) return true;
|
||||
return hiddenDetail === false;
|
||||
});
|
||||
|
||||
// Sort the fields on the sort column value
|
||||
formFields = formFields.sort((a, b) => {
|
||||
if (a.sort == b.sort) return 0;
|
||||
if (a.sort === null || a.sort === undefined) return 1;
|
||||
if (b.sort === null || b.sort === undefined) return -1;
|
||||
return a.sort > b.sort ? 1 : -1;
|
||||
});
|
||||
|
||||
// Make sure all form fields have a width associated with it
|
||||
formFields = formFields.map((field) => {
|
||||
if (!field.width) {
|
||||
field.width = 'full';
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
|
||||
formFields = formFields.map((field) => {
|
||||
const interfaceUsed = interfaces.find((int) => int.id === field.interface);
|
||||
const interfaceExists = interfaceUsed !== undefined;
|
||||
|
||||
if (interfaceExists === false) {
|
||||
field.interface = getDefaultInterfaceForType(field.type);
|
||||
}
|
||||
|
||||
if (interfaceUsed?.hideLabel === true) {
|
||||
(field as FormField).hideLabel = true;
|
||||
}
|
||||
|
||||
if (interfaceUsed?.hideLoader === true) {
|
||||
(field as FormField).hideLoader = true;
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
|
||||
// Change the class to half-right if the current element is preceded by another half width field
|
||||
// this makes them align side by side
|
||||
formFields = formFields.map((field, index, formFields) => {
|
||||
if (index === 0) return field;
|
||||
|
||||
if (field.width === 'half') {
|
||||
const prevField = formFields[index - 1];
|
||||
|
||||
if (prevField.width === 'half') {
|
||||
field.width = 'half-right';
|
||||
}
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
|
||||
return formFields;
|
||||
});
|
||||
|
||||
return { formFields };
|
||||
}
|
||||
@@ -135,6 +135,7 @@ import useFieldsStore from '@/stores/fields';
|
||||
import { Field } from '@/stores/fields/types';
|
||||
import FileInfoDrawerDetail from './components/file-info-drawer-detail.vue';
|
||||
import marked from 'marked';
|
||||
import useFormFields from '@/composables/use-form-fields';
|
||||
|
||||
type Values = {
|
||||
[field: string]: any;
|
||||
@@ -193,12 +194,14 @@ export default defineComponent({
|
||||
// These are the fields that will be prevented from showing up in the form
|
||||
const fieldsBlacklist: string[] = ['type', 'width', 'height', 'filesize', 'checksum'];
|
||||
|
||||
const formFields = computed(() => {
|
||||
const fieldsFiltered = computed(() => {
|
||||
return fieldsStore
|
||||
.getFieldsForCollection('directus_files')
|
||||
.filter((field: Field) => fieldsBlacklist.includes(field.field) === false);
|
||||
});
|
||||
|
||||
const { formFields } = useFormFields(fieldsFiltered);
|
||||
|
||||
const confirmLeave = ref(false);
|
||||
const leaveTo = ref<string | null>(null);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user