Extending list and detail screen (v 2.x)

Hi I want to extend both Entity and Screens (list & detail) from one add-on to another. I have ensured the dependency is correct. I have extended the Entity and added few fields to it now I want to extend the screen accordingly and to add those fields in the extended screens in host add-on within my composite project.

I looked at the user guide here but I found them from the older version (Cuba or V1.5x) of the platform but seems not Flow UI. The studio doesn’t have the option to extend visually too. Thanks for any help.

I tried and discovered that it is somehow shows in preview in development environment when I use the extends without a path as below.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
     title="msg://projectOpportunityListView.title"
      extends="sales-opportunity-list-view.xml"
       focusComponent="projectOpportunitiesDataGrid">
    <layout>

    </layout>
</view>

However, at runtime, it is looking for the Ancestor path.
I tried in different was but i suppose I am making some mistake in putting a valid path.

DevelopmentException: Template is not found

Ancestor's template path: /src/main/resources/com/company/crm/view/salesopportunity/sales-opportunity-list-view.xml

What will be the path when i am extending the screen from an add-on “myappcrm” to “myappred”

When I search for the desired xml file, I see it shows as follows:

sales-opportunity-list-view.xml~/Projects/mycomposite/mycrm/mycrm/src/main/resources/com/company/crm/view/salesopportunity

What will be the correct path here?

Hello, does it work with

extends="com/company/crm/view/salesopportunity/sales-opportunity-list-view.xml"

1 Like

Hi Timur
Thank you. It works just perfect!

Now I have another question.
When I extend, I see the xml file is clear something like the following with the data and component hierarchy displyed on the right panel from the ancestor screen.

image

However, When I try to add any field, it copies the whole ancestor screen xml (in this example, from sales-opportunity-detail.xml to project-opportunity-detail.xml).

Problem:

  1. If I do not copy the xml contents into the extended screen xml (by default), the list screen create/edit button takes me to the ancestor detail screen (sales-opportinity) instead of the extended detail screen (project-opportunity).

  2. To overcome the problem in #1 above, I let the studio inheret the XML codes (literally copy) into the extended screen but the xml file would remain no more as extended screen.

Question
a) Do I have to manually change the data source and update the containers i.e. from crm_salesOpportunity to red_projectOpportunity, Is this the recommended process?
b) When I try to add any component or data container, the studio copies the whole xml contents from the ancestor screen (sales-opportunity-detail.xml). Then If I change the data source to project-opportunity then i can use the related additional fields. Thus, this screen becomes copy of the ancestor screen and if there is any change I make in salesOpportunity screen, there will be no corresponding change in projectOpportunity screen that means I have to maintain both screens. Is this what you designed or I am missing something?

Now I am having some issues when calling the extended detail screen from the extended list screen.
SalesOpportunity is base and ProjectOpportunity is extended.

Here is the message:

java.lang.IllegalArgumentException: Container 'salesOpportunityDc' not found
	at io.jmix.flowui.model.impl.ViewDataImpl.getContainer(ViewDataImpl.java:64)
	at io.jmix.flowui.view.StandardDetailView.getEditedEntityContainer(StandardDetailView.java:469)
	at io.jmix.flowui.view.StandardDetailView.initNewEntity(StandardDetailView.java:537)
	at io.jmix.flowui.view.StandardDetailView.setupEntityToEdit(StandardDetailView.java:524)
	at io.jmix.flowui.view.StandardDetailView.setupEntityToEdit(StandardDetailView.java:512)
	at io.jmix.flowui.view.StandardDetailView.onBeforeShow(StandardDetailView.java:102)
	at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:233)
	at com.vaadin.flow.component.ComponentEventBus.fireEvent(ComponentEventBus.java:222)
	at com.vaadin.flow.component.Component.fireEvent(Component.java:411)
	at io.jmix.flowui.view.View.beforeEnter(View.java:104)
	at io.jmix.flowui.view.StandardDetailView.beforeEnter(StandardDetailView.java:165)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.sendBeforeEnterEvent(AbstractNavigationStateRenderer.java:601)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.sendBeforeEnterEvent(AbstractNavigationStateRenderer.java:578)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.sendBeforeEnterEventAndPopulateChain(AbstractNavigationStateRenderer.java:489)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.createChainIfEmptyAndExecuteBeforeEnterNavigation(AbstractNavigationStateRenderer.java:461)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.handle(AbstractNavigationStateRenderer.java:211)
	at com.vaadin.flow.component.internal.JavaScriptNavigationStateRenderer.handle(JavaScriptNavigationStateRenderer.java:78)
	at com.vaadin.flow.component.UI.handleNavigation(UI.java:1862)
	at com.vaadin.flow.component.UI.navigate(UI.java:1247)
	at io.jmix.flowui.view.navigation.ViewNavigationSupport.navigate(ViewNavigationSupport.java:56)
	at io.jmix.flowui.view.navigation.AbstractNavigationProcessor.lambda$processNavigation$28d5aa88$1(AbstractNavigationProcessor.java:58)
	at com.vaadin.flow.component.page.Page.lambda$fetchCurrentURL$fb993594$1(Page.java:597)
	at com.vaadin.flow.component.page.PendingJavaScriptResult.lambda$then$3fde283c$1(PendingJavaScriptResult.java:113)
	at com.vaadin.flow.component.internal.PendingJavaScriptInvocation.complete(PendingJavaScriptInvocation.java:96)
	at com.vaadin.flow.server.communication.UidlWriter.lambda$createReturnValueChannel$d9004ac5$1(UidlWriter.java:320)
	at com.vaadin.flow.internal.nodefeature.ReturnChannelMap.lambda$registerChannel$2a20409b$1(ReturnChannelMap.java:124)
	at com.vaadin.flow.internal.nodefeature.ReturnChannelMap$ChannelImpl.invoke(ReturnChannelMap.java:74)
	at com.vaadin.flow.server.communication.ReturnChannelHandler.handleNode(ReturnChannelHandler.java:78)
	at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:74)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:459)
	at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$2(ServerRpcHandler.java:440)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:440)
	at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:323)
	at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:114)
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1529)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398)
	at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:642)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:408)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:313)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:277)
	at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141)
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:178)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at io.jmix.core.impl.logging.LogMdcFilter.doFilterInternal(LogMdcFilter.java:28)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
	at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365)
	at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:110)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:151)
	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:129)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:117)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
	at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
	at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:225)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:833)

I do not see ‘salesOpportunityDc’ anywhere in the screen.

Is my Base List xml and controller:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      xmlns:c="http://jmix.io/schema/flowui/jpql-condition"
      title="msg://salesOpportunityListView.title"
      focusComponent="salesOpportunitiesDataGrid">
    <data>
        <collection id="salesOpportunitiesDc"
                    class="com.company.crm.entity.SalesOpportunity">
            <fetchPlan extends="_base"/>
            <loader id="salesOpportunitiesDl" readOnly="true">
                <query>
                    <![CDATA[select e from crm_SalesOpportunity e]]>
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
        <urlQueryParameters>
            <genericFilter component="genericFilter"/>
            <pagination component="pagination"/>
        </urlQueryParameters>
    </facets>
    <actions>
        <action id="selectAction" type="lookup_select"/>
        <action id="discardAction" type="lookup_discard"/>
    </actions>
    <layout>
        <genericFilter id="genericFilter"
                       dataLoader="salesOpportunitiesDl">
            <properties include=".*"/>
        </genericFilter>
        <hbox id="buttonsPanel" classNames="buttons-panel">
            <button id="createBtn" action="salesOpportunitiesDataGrid.create"/>
            <button id="editBtn" action="salesOpportunitiesDataGrid.edit"/>
            <button id="removeBtn" action="salesOpportunitiesDataGrid.remove"/>
            <simplePagination id="pagination" dataLoader="salesOpportunitiesDl"/>
        </hbox>
        <dataGrid id="salesOpportunitiesDataGrid"
                  width="100%"
                  minHeight="20em"
                  dataContainer="salesOpportunitiesDc"
                  columnReorderingAllowed="true">
            <actions>
                <action id="create" type="list_create"/>
                <action id="edit" type="list_edit"/>
                <action id="remove" type="list_remove"/>
            </actions>
            <columns resizable="true">
                <column property="name"/>

            </columns>
        </dataGrid>
        <hbox id="lookupActions" visible="false">
            <button id="selectBtn" action="selectAction"/>
            <button id="discardBtn" action="discardAction"/>
        </hbox>
    </layout>
</view>

Controller:

package com.company.crm.view.salesopportunity;

import com.company.crm.entity.SalesOpportunity;

import io.jmix.flowui.view.DefaultMainViewParent;

import com.vaadin.flow.router.Route;
import io.jmix.flowui.view.*;

@Route(value = "salesOpportunities", layout = DefaultMainViewParent.class)
@ViewController("crm_SalesOpportunity.list")
@ViewDescriptor("sales-opportunity-list-view.xml")
@LookupComponent("salesOpportunitiesDataGrid")
@DialogMode(width = "64em")
public class SalesOpportunityListView extends StandardListView<SalesOpportunity> {
}

Base Detail screen xml and controller

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      title="msg://salesOpportunityDetailView.title"
      focusComponent="form">
    <data>
        <instance id="salesOpportunityDc"
                  class="com.company.crm.entity.SalesOpportunity">
            <fetchPlan extends="_base">
                <property name="contact" fetchPlan="_base"/>
            </fetchPlan>
            <loader/>
            <collection id="contactDc" property="contact"/>
        </instance>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <actions>
        <action id="saveAction" type="detail_saveClose"/>
        <action id="closeAction" type="detail_close"/>
    </actions>
    <layout>
        <formLayout id="form" dataContainer="salesOpportunityDc">
            <textField id="nameField" property="name"/>
            <textField id="prospectNameField" property="prospectName"/>
        </formLayout>
        <h4 text="msg://com.company.crm.entity/SalesOpportunity.contact"/>
        <hbox id="buttonsPanel" classNames="buttons-panel">
            <button action="contactDataGrid.create"/>
            <button action="contactDataGrid.edit"/>
            <button action="contactDataGrid.remove"/>
        </hbox>
        <dataGrid id="contactDataGrid" dataContainer="contactDc" width="100%" minHeight="20em">
            <actions>
                <action id="create" type="list_create">
                    <properties>
                        <property name="openMode" value="DIALOG"/>
                    </properties>
                </action>
                <action id="edit" type="list_edit">
                    <properties>
                        <property name="openMode" value="DIALOG"/>
                    </properties>
                </action>
                <action id="remove" type="list_remove"/>
            </actions>
            <columns>
                <column property="name"/>
                <column property="address"/>
                <column property="email"/>
            </columns>
        </dataGrid>
        <hbox id="detailActions">
            <button id="saveAndCloseBtn" action="saveAction"/>
            <button id="closeBtn" action="closeAction"/>
        </hbox>
    </layout>
</view>
package com.company.crm.view.salesopportunity;

import com.company.crm.entity.SalesOpportunity;

import io.jmix.flowui.view.DefaultMainViewParent;

import com.vaadin.flow.router.Route;
import io.jmix.flowui.view.*;

@Route(value = "salesOpportunities/:id", layout = DefaultMainViewParent.class)
@ViewController("crm_SalesOpportunity.detail")
@ViewDescriptor("sales-opportunity-detail-view.xml")
@EditedEntityContainer("salesOpportunityDc")
public class SalesOpportunityDetailView extends StandardDetailView<SalesOpportunity> {
}

Extended List xml and controller:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      xmlns:c="http://jmix.io/schema/flowui/jpql-condition"
      title="msg://projectOpportunityListView.title"
      focusComponent="projectOpportunitiesDataGrid">
    <data>
        <collection id="projectOpportunitiesDc"
                    class="com.company.red.entity.ProjectOpportunity">
            <fetchPlan extends="_base"/>
            <loader id="projectOpportunitiesDl" readOnly="true">
                <query>
                    <![CDATA[select e from red_ProjectOpportunity e]]>
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
        <urlQueryParameters>
            <genericFilter component="genericFilter"/>
            <pagination component="pagination"/>
        </urlQueryParameters>
    </facets>
    <actions>
        <action id="selectAction" type="lookup_select"/>
        <action id="discardAction" type="lookup_discard"/>
    </actions>
    <layout>
        <genericFilter id="genericFilter"
                       dataLoader="projectOpportunitiesDl">
            <properties include=".*"/>
        </genericFilter>
        <hbox id="buttonsPanel" classNames="buttons-panel">
            <button id="createBtn" action="projectOpportunitiesDataGrid.create"/>
            <button id="editBtn" action="projectOpportunitiesDataGrid.edit"/>
            <button id="removeBtn" action="projectOpportunitiesDataGrid.remove"/>
            <simplePagination id="pagination" dataLoader="projectOpportunitiesDl"/>
        </hbox>
        <dataGrid id="projectOpportunitiesDataGrid"
                  width="100%"
                  minHeight="20em"
                  dataContainer="projectOpportunitiesDc"
                  columnReorderingAllowed="true">
            <actions>
                <action id="create" type="list_create"/>
                <action id="edit" type="list_edit"/>
                <action id="remove" type="list_remove"/>
            </actions>
            <columns resizable="true">
                <column property="name"/>
                <column property="prospectName"/>
                <column property="preferredLocation"/>
            </columns>
        </dataGrid>
        <hbox id="lookupActions" visible="false">
            <button id="selectBtn" action="selectAction"/>
            <button id="discardBtn" action="discardAction"/>
        </hbox>
    </layout>
</view>

Controller:

package com.company.red.view.projectopportunity;

import com.company.crm.view.salesopportunity.SalesOpportunityListView;
import com.company.red.entity.ProjectOpportunity;

import io.jmix.flowui.view.DefaultMainViewParent;

import com.vaadin.flow.router.Route;
import io.jmix.flowui.view.*;

@Route(value = "projectOpportunities", layout = DefaultMainViewParent.class)
@ViewController("red_ProjectOpportunity.list")
@ViewDescriptor("project-opportunity-list-view.xml")
@LookupComponent("projectOpportunitiesDataGrid")
@DialogMode(width = "64em")
public class ProjectOpportunityListView extends SalesOpportunityListView {
}

Extended Detail screen

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      title="msg://projectOpportunityDetailView.title"
      focusComponent="form">
    <data>
        <instance id="projectOpportunityDc"
                  class="com.company.red.entity.ProjectOpportunity">
            <fetchPlan extends="_base">
                <property name="contact" fetchPlan="_base"/>
            </fetchPlan>
            <loader/>
            <collection id="contactDc" property="contact"/>
        </instance>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <actions>
        <action id="saveAction" type="detail_saveClose"/>
        <action id="closeAction" type="detail_close"/>
    </actions>
    <layout>
        <formLayout id="form" dataContainer="projectOpportunityDc">
            <textField id="nameField" property="name"/>
            <textField id="prospectNameField" property="prospectName"/>
        </formLayout>

        <hbox id="buttonsPanel" classNames="buttons-panel">
            <button action="contactDataGrid.create"/>
            <button action="contactDataGrid.edit"/>
            <button action="contactDataGrid.remove"/>
        </hbox>
        <dataGrid id="contactDataGrid" dataContainer="contactDc" width="100%" minHeight="20em">
            <actions>
                <action id="create" type="list_create">
                    <properties>
                        <property name="openMode" value="DIALOG"/>
                    </properties>
                </action>
                <action id="edit" type="list_edit">
                    <properties>
                        <property name="openMode" value="DIALOG"/>
                    </properties>
                </action>
                <action id="remove" type="list_remove"/>
            </actions>
            <columns>
                <column property="name"/>
                <column property="address"/>
                <column property="email"/>
            </columns>
        </dataGrid>
        <hbox id="detailActions">
            <button id="saveAndCloseBtn" action="saveAction"/>
            <button id="closeBtn" action="closeAction"/>
        </hbox>
    </layout>
</view>
package com.company.red.view.projectopportunity;

import com.company.crm.view.salesopportunity.SalesOpportunityDetailView;
import com.company.red.entity.ProjectOpportunity;

import io.jmix.flowui.view.DefaultMainViewParent;

import com.vaadin.flow.router.Route;
import io.jmix.flowui.view.*;

@Route(value = "projectOpportunities/:id", layout = DefaultMainViewParent.class)
@ViewController("red_ProjectOpportunity.detail")
@ViewDescriptor("project-opportunity-detail-view.xml")
public class ProjectOpportunityDetailView extends SalesOpportunityDetailView {
}
@JmixEntity
@Entity(name = "red_ProjectOpportunity")
public class ProjectOpportunity extends SalesOpportunity {
    @Column(name = "PREFERRED_LOCATION")
    private String preferredLocation;

Thanks for sharing this information. The first problem you describe is a known one. In your case I don’t recommend extending the view from the parent entity, it would be better to just create new views for red_projectOpportunity. However, I tried to reproduce your case and I confirm there is strange behavior with data containers in the expanding screen. I created a new ticket in Jmix Studio.

Thanks Timur.