Use your demo sites:
Accordian: It isn't possible without maximising the sidebar first. If the visual settings is set to set show the sidebar menu as an accordian no submenu is shown.
If is set as a dropdown it shows the dropdown pops up at with an odd offset
Both screenshots taken from your demo applications, so completely unchanged code.
Believe it is a bug introduced in changes when upgrading to metronic v7. The notifications used to be wrapped in a 'kt-checkbox-list' class and is now wrapped in a 'checkbox-inline' class. Changing it to 'checkbox-list' seems to solve it
No - gave up in the end. Would be great to get it to work as it would make it much easier to develop integrations tests, i.e. build a sequence/workflow of api calls, and performance tests for workflows using a test database.
Spent the day copying logic into the template only to have a moment of clarity after it was all done:
From docs
Filters can only be defined for the root Entity Type of an inheritance hierarchy.
Thank you - found a hack and it seems to work. Have a new issue with the data filter following the article though.
When I evaluate the generated SQL command of the IQuerayable prior to execution all seems fine. The filter and parameters seems to be captured (replaced the select columns with * for readability)
SELECT `c*
FROM `Comments` AS `c`
INNER JOIN (
SELECT `p*
FROM `Programmes` AS `p`
WHERE (@__ef_filter__p_1 OR NOT (`p`.`IsDeleted`)) AND ((@__ef_filter__p_2 AND (@__ef_filter__p_3 OR EXISTS (
SELECT 1
FROM `ProgrammeBrokers` AS `p0`
WHERE ((@__ef_filter__p_6 OR NOT (`p0`.`IsDeleted`)) AND (`p`.`Id` = `p0`.`ProgrammeId`)) AND ((`p0`.`BrokerId` = @__ef_filter__CurrentTenantId_4) AND (`p0`.`Status` <> 2))))) AND (@__ef_filter__p_5 OR ((`p`.`ProtectionBuyerId` = @__ef_filter__CurrentTenantId_4) OR (`p`.`ProtectionBuyerId` IS NULL AND @__ef_filter__CurrentTenantId_4 IS NULL))))
) AS `t` ON `c`.`ProgrammeId` = `t`.`Id`
LEFT JOIN (
SELECT `p1*
FROM `ProgrammeAccess` AS `p1`
INNER JOIN (
SELECT `a*
FROM `Approvals` AS `a`
WHERE @__ef_filter__p_8 OR NOT (`a`.`IsDeleted`)
) AS `t0` ON `p1`.`AccessStatusId` = `t0`.`Id`
WHERE @__ef_filter__p_7 OR NOT (`p1`.`IsDeleted`)
) AS `t1` ON `t`.`Id` = `t1`.`ProgrammeId`
LEFT JOIN (
SELECT `p2`.`*
FROM `ProgrammeBrokers` AS `p2`
WHERE @__ef_filter__p_6 OR NOT (`p2`.`IsDeleted`)
) AS `t2` ON `t`.`Id` = `t2`.`ProgrammeId`
WHERE (`c`.`Discriminator` = 'ProgrammeComment') AND (@__ef_filter__p_0 OR NOT (`c`.`IsDeleted`))
ORDER BY `c`.`Id`, `t`.`Id`, `t1`.`Id`, `t1`.`Id0`, `t2`.`Id`
The final query only includes the isDeleted filter though and everything else is dropped
DbCommand (3ms) [Parameters=[@__ef_filter__p_0='False'], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM `Comments` AS `c`
WHERE (`c`.`Discriminator` = 'ProgrammeComment') AND (@__ef_filter__p_0 OR NOT (`c`.`IsDeleted`))
The documentation suggests that it should pass the values via the property and it should all flow through. My code includes
In the context:
protected virtual bool CurrentIsBroker => GetCurrentIsBroker();
protected virtual bool CurrentIsBuyer => GetCurrentIsBuyer();
protected virtual bool CurrentIsSeller => GetCurrentIsSeller();
...
protected override bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType)
{
if (typeof(IMustHaveProgramme).IsAssignableFrom(typeof(TEntity)))
return true;
...
return base.ShouldFilterEntity<TEntity>(entityType);
}
protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
{
if (typeof(IMustHaveProgramme).IsAssignableFrom(typeof(TEntity)))
{
Expression<Func<TEntity, bool>> progFilter = p => !CurrentIsBroker || !IsMustHaveProgrammeFilterEnabled
|| ((IMustHaveProgramme)p).Programme.Brokers.Any(b => b.BrokerId == this.CurrentTenantId && b.Status != BrokerAppointmentStatus.BrokerWithdrawn);
Expression<Func<TEntity, bool>> buyerExpr = p => !CurrentIsBuyer || !IsMustHaveProgrammeFilterEnabled
|| (((IMustHaveProgramme)p).Programme.ProtectionBuyerId == this.CurrentTenantId);
progFilter = progFilter == null ? buyerExpr : CombineExpressions(progFilter, buyerExpr);
Expression<Func<TEntity, bool>> sellerExpr = p => !CurrentIsSeller || !IsMustHaveProgrammeFilterEnabled
|| ((IMustHaveProgramme)p).Programme.AccessRequests.Any(a => a.AccessStatus.Status == ApprovalStatus.Approved && a.TenantId == this.CurrentTenantId);
progFilter = progFilter == null ? sellerExpr : CombineExpressions(progFilter, sellerExpr);
expression = expression == null ? progFilter : CombineExpressions(expression, progFilter);
}
...
}
and in core module - PreInitialize
Configuration.UnitOfWork.RegisterFilter(ReinsuranceConst.IMustHaveProgramme, true);
I can also see my filters are enabled and the property values are correctly set when debugging, but the final query doesn't filter.
The 3 properties have the correct value:
The filter is enabled and correctly refelcts in the property in the context:
Is there anything else I need to do that is not included in the documentation?
Many thanks
Code that replicates the issue from a clean demo project sent to [email protected]
I'll see if I can replicate in a demo project and send you the code.
No - the issue lies in step 3. the rest is just to show the issue. using wrap around div with classname, e.g.
<div class class="par-wrapper">...<div>
and then
.par-wrapper { display: ... }
solves it, but I know other components also set the body, e.g. select-edition-component.less, so these components changing the body all have a risk of breaking the overall layout once navigating away from them.
Don't know if this is metronic problem or not, but the workaround is simple enough in my case