public ActionResult Drilldown() { Applet currentApplet = viewInfo.CurrentPopupApplet ?? viewInfo.CurrentApplet; currentApplet = context.Applets .AsNoTracking() .Select(a => new { id = a.Id, name = a.Name, type = a.Type, busComp = new { id = a.BusComp.Id, name = a.BusComp.Name, routing = a.BusComp.Routing }, drilldowns = a.Drilldowns.Select(d => new { id = d.Id, name = d.Name, hyperLinkFieldId = d.HyperLinkFieldId, sourceField = new { id = d.SourceField.Id, name = d.SourceField.Name }, destinationBusinessComponent = new { id = d.DestinationBusinessComponent.Id, name = d.DestinationBusinessComponent.Name, routing = d.DestinationBusinessComponent.Routing }, destinationField = new { id = d.DestinationField.Id, name = d.DestinationField.Name }, destinationScreenId = d.DestinationScreenId, destinationScreenItemId = d.DestinationScreenItemId, destinationScreenItem = new { id = d.DestinationScreenItem.Id, view = new { id = d.DestinationScreenItem.View.Id, busObjectId = d.DestinationScreenItem.View.BusObjectId } } }) }) .Select(a => new Applet { Id = a.id, Name = a.name, Type = a.type, BusComp = new BusinessComponent { Id = a.busComp.id, Name = a.busComp.name, Routing = a.busComp.routing }, Drilldowns = a.drilldowns.Select(d => new Drilldown { Id = d.id, Name = d.name, HyperLinkFieldId = d.hyperLinkFieldId, SourceField = new Field { Id = d.sourceField.id, Name = d.sourceField.name }, DestinationBusinessComponent = new BusinessComponent { Id = d.destinationBusinessComponent.id, Name = d.destinationBusinessComponent.name, Routing = d.destinationBusinessComponent.routing }, DestinationField = new Field { Id = d.destinationField.id, Name = d.destinationField.name }, DestinationScreenId = d.destinationScreenId, DestinationScreenItem = new ScreenItem { Id = d.destinationScreenItem.id, View = new View { Id = d.destinationScreenItem.view.id, BusObjectId = d.destinationScreenItem.view.busObjectId } } }).ToList() }) .FirstOrDefault(i => i.Id == currentApplet.Id); if (currentApplet != null) { string controlName; Field field; switch (currentApplet.Type) { case "Tile": controlName = viewInfo.CurrentColumn.Name; field = viewInfo.CurrentColumn.Field; break; default: controlName = viewInfo.CurrentPopupControl?.Name ?? viewInfo.CurrentControl?.Name; field = viewInfo.CurrentPopupControl?.Field ?? viewInfo.CurrentControl?.Field; break; } if (field != null) { TBUSFactory BUSFactory = new TBUSFactory(); Drilldown drilldown = currentApplet.Drilldowns.FirstOrDefault(i => i.HyperLinkFieldId == field.Id); if (drilldown != null && drilldown.DestinationBusinessComponent?.Name != null && drilldown.DestinationField?.Name != null && drilldown.SourceField?.Name != null) { // Целевой экран Screen destinationScreen = context.Screens.AsNoTracking().FirstOrDefault(i => i.Id == drilldown.DestinationScreenId); if (destinationScreen != null) { applicationInfo.CurrentScreen = destinationScreen; // Целевыое представление View destinationView = context.Views.AsNoTracking().FirstOrDefault(i => i.Id == drilldown.DestinationScreenItem.View.Id); if (destinationView != null) { applicationInfo.CurrentView = destinationView; // Исходное поле dynamic sourceRecord = BUSFactory.GetRecord(null, context, viewInfo, currentApplet.BusComp, "Id", viewInfo.CurrentRecord); PropertyInfo sourceProperty = sourceRecord.GetType().GetProperty(drilldown.SourceField.Name); if (sourceProperty != null) { // Очистка старой информации о выбранных записях if (screenInfo.Screen.Name != destinationScreen.Name) { ComponentsRecordsInfo.Dispose(); } // Установка текущей выбранной записи на целевой бизнес компоненте var sourcePropertyValue = sourceProperty.GetValue(sourceRecord); if (sourcePropertyValue != null) { dynamic destinationRecord = BUSFactory.GetRecord(null, context, viewInfo, drilldown.DestinationBusinessComponent, drilldown.DestinationField.Name, sourcePropertyValue.ToString()); if (destinationRecord != null) { ComponentsRecordsInfo.SetSelectedRecord(drilldown.DestinationBusinessComponent.Name, destinationRecord.Id.ToString()); } // Установка текущих выбранных записей на всех родительских бизнес компонентах целевой компоненты BusinessObject destinationBO = context.BusinessObjects .AsNoTracking() .Include(boc => boc.BusObjectComponents) .ThenInclude(l => l.Link) .ThenInclude(cf => cf.ChildField) .Include(boc => boc.BusObjectComponents) .ThenInclude(l => l.Link) .ThenInclude(pf => pf.ParentField) .FirstOrDefault(i => i.Id == destinationView.BusObjectId); BusinessObjectComponent destinationComponent = destinationBO.BusObjectComponents.FirstOrDefault(i => i.BusCompId == drilldown.DestinationBusinessComponent.Id); dynamic childRecord = destinationRecord; if (destinationComponent.Link != null) { BusinessComponent parentBusComp = context.BusinessComponents .AsNoTracking() .Select(bc => new { id = bc.Id, name = bc.Name, table = new { id = bc.Table.Id, name = bc.Table.Name } }) .Select(bc => new BusinessComponent { Id = bc.id, Name = bc.name, Table = new Table { Id = bc.table.id, Name = bc.table.name } }) .FirstOrDefault(i => i.Id == destinationComponent.Link.ParentBCId); BusinessComponent childBusComp = context.BusinessComponents .AsNoTracking() .Select(bc => new { id = bc.Id, name = bc.Name }) .Select(bc => new BusinessComponent { Id = bc.id, Name = bc.name }) .FirstOrDefault(i => i.Id == destinationComponent.Link.ChildBCId); string childFieldValue = childRecord.GetType().GetProperty(destinationComponent.Link.ChildField.Name).GetValue(childRecord).ToString(); string parentFieldName = destinationComponent.Link.ParentField.Name; IEnumerable <dynamic> parentRecords = (IEnumerable <dynamic>)(context.GetType().GetProperty(parentBusComp.Table.Name).GetValue(context)); string searchSpecificationByParent = $"{parentFieldName} = \"{childFieldValue}\""; dynamic parentRecord = parentRecords.AsQueryable().Where(searchSpecificationByParent).FirstOrDefault(); ComponentsRecordsInfo.SetSearchSpecification(childBusComp.Name, SearchSpecTypes.SearchSpecificationByParent, searchSpecificationByParent); ComponentsRecordsInfo.SetSelectedRecord(parentBusComp.Name, parentRecord.Id.ToString()); destinationComponent = destinationBO.BusObjectComponents.FirstOrDefault(i => i.BusCompId == destinationComponent.Link.ParentBCId); childRecord = parentRecord; } // Установка хлебных крошек ScreenItem crumb = screenInfo.Screen.ScreenItems.FirstOrDefault(n => n.View != null && n.View.Name == screenInfo.CurrentView.Name); ComponentsRecordsInfo.AppendCrumb(crumb); if (screenInfo.Screen.Name == destinationScreen.Name) { screenInfo.Initialize(screenInfo.Screen.Name, destinationView.Name, context); screenInfoUI.Initialize(screenInfo, context); viewInfo.View = destinationView; } viewInfo.ActionType = ActionType.Drilldown; } } } } } } } return(Ok()); }
public virtual ActionResult <object> UpdateScreenInfo([FromBody] RequestScreenModel model) { switch (model.Action) { case "SelectScreenItem": Screen newScreen = context.Screens .Include(si => si.ScreenItems) .ThenInclude(v => v.View) .FirstOrDefault(n => n.Name == model.NewScreenName); View oldView = context.Views.FirstOrDefault(n => n.Name == model.OldViewName); View newView = context.Views .Include(bo => bo.BusObject) .ThenInclude(boc => boc.BusObjectComponents) .ThenInclude(bc => bc.BusComp) .FirstOrDefault(n => n.Name == model.NewViewName); ScreenItem oldScreenItem = newScreen.ScreenItems.FirstOrDefault(n => n.ViewId == oldView.Id); ScreenItem newScreenItem = newScreen.ScreenItems.FirstOrDefault(n => n.ViewId == newView.Id); List <ScreenItem> crumbs = ComponentsRecordsInfo.GetCrumbs(); /* Если не произошел переход на представление того же уровня внутри того же родителя и выполняется одно из двух следующих условий: * - уже есть хлебные крошки; * - у выбранного представления есть родитель, который не является последней хлебной крошкой. * Тогда текущее выбранное представление добавляется в хлебные крошки */ if (oldScreenItem.ParentItemId != newScreenItem.ParentItemId && (crumbs.Count > 0 || newScreenItem.ParentItemId != null)) { ComponentsRecordsInfo.AppendCrumbs("SelectScreenItem", newScreen, oldScreenItem, newScreenItem); } // Обновление контекста в случае, если представление, на которое произошел переход уже есть в хлебных крошках и если для него уничтожен контекст if (crumbs.FirstOrDefault(i => i.ViewId == newView.Id) != null && !ComponentsRecordsInfo.IsInitComponent(newView.BusObject.BusObjectComponents.FirstOrDefault()?.Name)) { ComponentsRecordsInfo.RestoreContext(new List <View>() { newView }); } screenInfo.Initialize(model.NewScreenName, model.NewViewName, context); break; case "SelectScreen": if (screenInfo.Screen.Name != model.NewScreenName) { // Добавление хлебной крошки if (screenInfo.Crumbs?.Count > 0) { Screen oldScreen = context.Screens .Include(si => si.ScreenItems) .ThenInclude(v => v.View) .FirstOrDefault(n => n.Name == model.OldScreenName); ComponentsRecordsInfo.AppendCrumb(oldScreen.ScreenItems.FirstOrDefault(n => n.View != null && n.View.Name == model.OldViewName)); screenInfo.Initialize(model.OldScreenName, model.OldViewName, context); } ComponentsRecordsInfo.Dispose(); } break; case "SelectCrumb": // Удаление хлебных крошек ComponentsRecordsInfo.RemoveCrumbs(model.CrumbId); List <ScreenItem> screenItems = ComponentsRecordsInfo.GetCrumbs(); List <View> viewsToResore = new List <View>(); // Добавление всех представлений, оставшихся в хлебных крошках в представления, контекст которых необходимо восстановить screenItems.ForEach(crumb => { viewsToResore.Add(context.Views .Include(bo => bo.BusObject) .ThenInclude(boc => boc.BusObjectComponents) .ThenInclude(bc => bc.BusComp) .FirstOrDefault(i => i.Id == crumb.ViewId)); }); // Добавление представления, на которое перешли по хлебным крошкам в представления, контекст которых необходимо восстановить viewsToResore.Add(context.Views .Include(bo => bo.BusObject) .ThenInclude(boc => boc.BusObjectComponents) .ThenInclude(bc => bc.BusComp) .FirstOrDefault(n => n.Name == model.NewViewName)); // При переходе не другой экран необходимо очистить информацию о выбранных и отображаемых записях if (screenInfo.Screen.Name != model.NewScreenName) { ComponentsRecordsInfo.Dispose(); } // Восстановление контекста ComponentsRecordsInfo.RestoreContext(viewsToResore); screenInfo.Initialize(model.NewScreenName, model.NewViewName, context); break; } screenInfo.ActionType = (ActionType)Enum.Parse(typeof(ActionType), model.Action); screenInfoUI.Initialize(screenInfo, context); return(Ok(screenInfoUI.Serialize())); }