Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Labels display in O2M is truncated when in Table (OK in List) #17204

Open
Pachat opened this issue Jan 17, 2023 · 2 comments
Open

Labels display in O2M is truncated when in Table (OK in List) #17204

Pachat opened this issue Jan 17, 2023 · 2 comments

Comments

@Pachat
Copy link

Pachat commented Jan 17, 2023

Describe the Bug

A dropdown with Displays set at labels, shows as ... when the O2M field is set to Table.
They do show correctly when the O2M field is set to List

To Reproduce

In an O2M collection create a dropdown field of type string and set the display to Labels
In the parent collection set an O2M field and set the display to List: the labels show correctly.
Now, set the display to Table: instead of List, set to Tables

Errors Shown

The labels are replaced with ...

What version of Directus are you using?

9.22.4

What version of Node.js are you using?

19.0.1

What database are you using?

Postgresql 15

What browser are you using?

Firefox & Edge

How are you deploying Directus?

VPS

@github-actions
Copy link

Linear: ENG-511

@azrikahar
Copy link
Contributor

shows as ... when the O2M field is set to Table.

I believe this is more of truncating caused by narrow column width when the value itself is short, but the Label display is long:

(here the value is a/b/c, but the label display is Type A/Type B/Type C)

Can you help confirm whether that's the case on your end?


This seems to be due to the width is determined based on the value's length (String(item[key]).length):

const contentWidth: Record<string, number> = {};
(displayItems.value ?? []).forEach((item: Record<string, any>) => {
props.fields.forEach((key) => {
if (!contentWidth[key]) {
contentWidth[key] = 5;
}
if (String(item[key]).length > contentWidth[key]) {
contentWidth[key] = String(item[key]).length;
}
});
});
headers.value = props.fields
.map((key) => {
const field = fieldsStore.getField(relatedCollection, key);
// when user has no permission to this field or junction collection
if (!field) return null;
return {
text: field.name,
value: key,
width: contentWidth[key] < 10 ? contentWidth[key] * 16 + 10 : 160,
sortable: !['json'].includes(field.type),
};
})
.filter((key) => key !== null);

const contentWidth: Record<string, number> = {};
(displayItems.value ?? []).forEach((item: Record<string, any>) => {
props.fields.forEach((key) => {
if (!contentWidth[key]) {
contentWidth[key] = 5;
}
if (String(item[key]).length > contentWidth[key]) {
contentWidth[key] = String(item[key]).length;
}
});
});
headers.value = props.fields
.map((key) => {
const field = fieldsStore.getField(junctionCollection, key);
// when user has no permission to this field or junction collection
if (!field) return null;
return {
text: field.name,
value: key,
width: contentWidth[key] < 10 ? contentWidth[key] * 16 + 10 : 160,
sortable: !['json'].includes(field.type),
};
})
.filter((key) => key !== null);

A potential enhancement would be to use the display handler to ensure the width is derived from the display used, similar to how "save as csv" uses it:

const display = useExtension(
'display',
computed(() => fieldsUsed[key]?.meta?.display ?? null)
);
if (value !== undefined && value !== null) {
parsedItem[name] = display.value?.handler
? await display.value.handler(value, fieldsUsed[key]?.meta?.display_options ?? {}, {
interfaceOptions: fieldsUsed[key]?.meta?.options ?? {},
field: fieldsUsed[key] ?? undefined,
collection: collection,
})
: value;
} else {

Tested the following changes which seems to work, but there might be room for optimization:

                const contentWidth: Record<string, number> = {};
                (displayItems.value ?? []).forEach((item: Record<string, any>) => {
                        props.fields.forEach((key) => {
+                               const field = fieldsStore.getField(relatedCollection, key);
+
+                               const display = useExtension(
+                                       'display',
+                                       computed(() => field?.meta?.display ?? null)
+                               );
+
                                if (!contentWidth[key]) {
                                        contentWidth[key] = 5;
                                }
-                               if (String(item[key]).length > contentWidth[key]) {
-                                       contentWidth[key] = String(item[key]).length;
+
+                               const content = display.value?.handler
+                                       ? display.value.handler(item[key], field?.meta?.display_options ?? {}, {
+                                                       interfaceOptions: field?.meta?.options ?? {},
+                                                       field: field ?? undefined,
+                                                       collection: relatedCollection,
+                                         })
+                                       : item[key];
+
+                               if (String(content).length > contentWidth[key]) {
+                                       contentWidth[key] = String(content).length;
                                }
                        });
                });

@azrikahar azrikahar changed the title Labels display do not show in O2M when in Table (OK in List) Labels display in O2M is truncated when in Table (OK in List) Jan 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 📋 Backlog
Development

No branches or pull requests

3 participants