Repository: directus/directus
File: app/src/layouts/kanban/kanban.vue (Vue)

Code before:
	return url;
}

function cancelChanges() {
	editDialogOpen.value = null;
	editTitle.value = '';
}

function saveChanges() {
	if (editDialogOpen.value === '+') {
		props.addGroup(editTitle.value);
	} else if (editDialogOpen.value) {
		props.editGroup(editDialogOpen.value, editTitle.value);
	}

	editDialogOpen.value = null;
	editTitle.value = '';
}

const titleFieldConfiguration = computed<Field | undefined>(() => {
	return props.fieldsInCollection.find((field) => field.field === props.layoutOptions?.titleField);
});

const textFieldConfiguration = computed<Field | undefined>(() => {
	return props.fieldsInCollection.find((field) => field.field === props.layoutOptions?.textField);
});
</script>

<template>
	<div class="kanban-layout">
		<slot v-if="error" name="error" :error="error" :reset="resetPresetAndRefresh" />

		<template v-else>
			<v-notice v-if="atLimit" type="warning" class="limit">
				{{ t('dataset_too_large_currently_showing_n_items', { n: n(props.totalCount ?? 0) }) }}
			</v-notice>

			<div class="kanban">
				<draggable
					:model-value="groupedItems"
					group="groups"
					item-key="id"
					draggable=".draggable"
					:disabled="selectMode"
					:animation="150"
					class="draggable"
					:class="{ sortable: groupsSortField !== null }"
					@change="changeGroupSort"
				>
					<template #item="{ element: group }">
						<div class="group" :class="{ draggable: group.id !== null, disabled: selectMode }">

Review comment (suggestion):
@formfcw thoughts on maybe combining these into a single computed prop, seeing as they're basically exactly the same?

```
const fieldConfigurations = computed<{ textField: Field | undefined; titleField: Field | undefined }>(() => {
	return {
		textField: props.fieldsInCollection.find((field) => field.field === props.layoutOptions?.textField),
		titleField: props.fieldsInCollection.find((field) => field.field === props.layoutOptions?.titleField),
	};
});
```

Code after:
	return url;
}

function cancelChanges() {
	editDialogOpen.value = null;
	editTitle.value = '';
}

function saveChanges() {
	if (editDialogOpen.value === '+') {
		props.addGroup(editTitle.value);
	} else if (editDialogOpen.value) {
		props.editGroup(editDialogOpen.value, editTitle.value);
	}

	editDialogOpen.value = null;
	editTitle.value = '';
}

const fieldDisplay = computed(() => {
	return {
		titleField: getRenderDisplayOptions('titleField'),
		textField: getRenderDisplayOptions('textField'),
	};

	function getRenderDisplayOptions(fieldName: keyof LayoutOptions) {
		const fieldConfiguration = props.fieldsInCollection.find(
			(field) => field.field === props.layoutOptions?.[fieldName],
		);

		if (!fieldConfiguration) return;
		const { field, type, meta } = fieldConfiguration;
		return {
			collection: props.collection,
			field,
			type,
			display: meta?.display,
			options: meta?.display_options,
			interface: meta?.interface,
			interfaceOptions: meta?.options,
		};
	}
});
</script>

<template>
	<div class="kanban-layout">
		<slot v-if="error" name="error" :error="error" :reset="resetPresetAndRefresh" />

		<template v-else>
			<v-notice v-if="atLimit" type="warning" class="limit">