Giter VIP home page Giter VIP logo

korzhcom / easydata Goto Github PK

View Code? Open in Web Editor NEW
579.0 22.0 60.0 25.65 MB

Adaptive CRUD for ASP.NET Core. With EasyData you can get both API endpoints and client-side UI for all CRUD operations in a matter of minutes using just your DbContext and a few lines of code.

License: MIT License

C# 53.70% TypeScript 36.87% JavaScript 1.89% Batchfile 0.02% CSS 5.69% HTML 1.68% PowerShell 0.15%
crud-ui net5 ef-core asp-net-core crud-api crud-generator crud-operations net6

easydata's People

Contributors

antifree avatar eqteamlead avatar kant2002 avatar korzh avatar melnalex avatar olton avatar vaital3000 avatar vasiliy-chefonov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easydata's Issues

More correct default columns' widths

Currently (version 1.3), the default sizes for columns are wider than necessary in most cases.

For example, an Int32 "ID" column has 120px width while it really needs only a half of this size to show numbers up to billions.

The default size for date/time columns is 200px but for short dates 100px would be enough.

The search of related data model does not work in Create mode

Hi. I found that search modal can't be opened when you are creating new record.

For example, in the .net core 3.1 sample you can click on "..." button and search employee to make a reference

image

And sub modal window will be opened:

image

(p.s Look at the name of sub modal window. May be it should be changed :)

But when I want to create new order buttons "..." that should show modals don't work:

image

Integrate Claims Based data filtering

Hello, I am interested in this. But it seems outdated with the core versions, with the new version there are many new features, can you show a sample if this would work role based and claims based access. The current identity and new EF core allows ClientCascade to delete / update records with dependencies even if they have cyclic references.

Index not working

When you use MetaEntityAttr Index it is work only in Edit view and didn't work on standart view.

Typescript error with i18n.d.ts

I'm trying to use the 1.2.1 version of @easydata/core and I'm getting this error in Typescript version 3.9 and 4.1.

C:\Source\node_modules\@easydata\core\dist\lib\i18n\i18n.d.ts(21,9): error TS2411: Build:Property 'ButtonOK' of type 'string | undefined' is not assignable to string index type 'string | TextResources'.
C:\Source\node_modules\@easydata\core\dist\lib\i18n\i18n.d.ts(22,9): error TS2411: Build:Property 'ButtonCancel' of type 'string | undefined' is not assignable to string index type 'string | TextResources'.

From what I understand, your index lookup doesn't match the defined variables in that file. So either ButtonOK and ButtonCancel should be string | TextResources or [propName: string] should just be string. Regardless, it is also complaining if you don't have a | undefined in the [propName] property.

    interface TextResources {
        ButtonOK?: string;
        ButtonCancel?: string;
        [propName: string]: string | TextResources;
    }

Not sure if that is the correct fix or not, the compiler just complains less.

Multiline Text Field

Hello, I would like to use the library however I did not see an attribute or definition for textarea or htmleditor type fields, could you please let me know if there is any or how we can implement?

Thank you.

Cannot remove entity if ID disabled

I don't want to fill the ID property, because it will be generated. So I added [MetaEntityAttr(Enabled = false)] to not display it on the creation form. But now I can't remove this entity, because lib cannot get the Id. Please review my screenshots:
image
image

Support for Fluent API

Sometimes it's necessary to keep all model classes as just POCO (plain old C# objects) without any additional attributes (annotations).
It would be great to have a possibility to define all these entity filters, column options, display formats, etc. via some kind of Fluent API as we have for model configuring in Entity Framework (Core)

Skip intermediate entities by default

It's better to skip by default all intermediate entities (the ones that used to join other entities in many-to-many relationships).

If there is a necessity to show some of them, it will still be possible to use either annotations [MetaEntity(true)] or the Fluent API for that.

http://<site_name>/<application_name> in IIS, EasyDataViewDispatcherOptions property 'endPoint' resolving not working properly

Hello EasyData contributors, your library is great, but I think there exist one bug with EasyDataViewDispatcher class resolving with routes.
Example: I have an application located in IIS like this: http://<site_name>/<application_name>
and when I try to testing that all is working properly, URL (http://<site_name>/api/easydata/models/__default) in DevTools giving the result of 404 (Not Found). So the problem is that, aforementioned URL must be http://<site_name>/<application_name>/api/easydata/models/__default instead of http://<site_name>/api/easydata/models/__default. I hope that I'm doing wrong, but my attempts to get around it were in vain. Thanks! Have a good day!

Does not run and build in VS 2022

Hello, I got a new machine with VS 2022 and using both .NET 5 and Core .NET 6 but the samples dont build

Another issue is that the samples are based on old EasyData V 1.3.1 they need to be updated v 1.3.6 and targets need to be updated to .Net Core 6

image

Long col names over run - need to over-ride col names

It looks like its taking the col names from the table. Is it possible to over ride these col & table names, for e.g. they maybe long or we may have

Site1_Table, Site1_Tableb and dont want to show those table/col names

Default Entity fields sorting

Let's not sort Entity Fields by default - consider to configure this as an option.
It's not always the best choice if API decide whenever your fields should be sorted or not - but it's still valuable to control it explicitly

Cannot find module '@easydata/crud' on the "dev" solution

downloading the repo and open the "EasyData.Dev.sln" solution (i'd like to explore and debug the dev code)

i got this errors on build phase

Error TS2307 (TS) Cannot find module '@easydata/crud' or its corresponding type declarations.
on the "EasyDataAspNetCoreTestXX" projects

does i have to launch some client sctipt before build the server code ?

Some Foreign Keys are completely ignored casing INSERTs to fail

This is a follow up to #49, although I'm not sure if the issues are technically related, other than having been discovered in the same scenario (trying to manage the ASP.NET Core Identity data model with EasyData).

EasyData seems to ignore some FK columns in some entities. The corresponding column/value is not shown in the data grid, the field is not rendered at all in the CRUD form, and any INSERT will fail because the FK ends up being NULL.

Two examples:

  • IdentityRoleClaim: EasyData shows Id, ClaimType and ClaimValue. The property/column RoleId is completely ignored;
  • IdentityUserClaim: Same, we have Id, ClaimType and ClaimValue, and UserId is ignored;

Trying to create a new record on either table will fail with (example for IdentityUserClaim):

Ooops, smth went wrong

Cannot insert the value NULL into column 'UserId', table 'EasyDataDB.dbo.AspNetUserClaims'; column does not allow nulls. INSERT fails. The statement has been terminated.

Steps to reproduce

  • Create a new project with "Individual accounts" (dotnet new webapp --auth Individual)
  • Setup EasyData
  • Browse for example /easydata/IdentityRoleClaim or /easydata/IdentityUserClaim

Expected result

  • An empty grid (as there are no records yet), including the column RoleId (for Identity Role Claim) and UserId (for Identity User Claim)
  • Trying to add a new record should render the field RoleId / UserId, accordingly

Actual result

  • The columns RoleId or UserId are not shown in the query
  • The fields RoleId or UserId are not rendered in the CRUD form

Simple example for MVC

Is it possible to use the library without Razor Pages?

How to setup the basic controller for it?

endpoints.MapControllerRoute("easydata", "/easydata/{**entity}", defaults: new { controller = "easydata" }); - no luck

Thank you.

Support for many filters in GetEntities request

Currently, we can set only one filter with any GetEntities request (a kind of contains for string and, in some cases, numeric values).

However, it could be very useful to have a possibility to define several different filters when we retrieve data from a database.

For example, users may want to work only with the data that belongs to a particular period of time (e.g. "this year") or fits some other common criteria (e.g. department = 'sales').

So, to allow to implement the behavior mentioned above we need to make the following changes:

  1. GetEntitites request must accept filter: [ {...}. {...}, ...] parameter (an array of objects) instead of filter: 'text' accepted now.
  2. Each object in that list will define one filter. The object must contain one required property class that will define the class (type) of the filter. Other properties will define different filter parameters.
  3. We will have a number of default filter classes. For example, there will be the __substring class (will act the same way as the current filter parameter) or __datePeriod class that will allow filtering by a period of time. The class name for the default filters will be prefixed with __.
  4. EasyData users (I mean developers here) will be able to define any custom filters via a kind of registration mechanism (this is a matter of a separate issue) both on the client-side and server-side.

Custom EasyData page URL

It's not an issue but question.
How can I use base page URL other than "/easydata/{url?}" for my EasyData page?
Right now I have this as a first line on my page:

@page "/easydata/{url?}"

It works fine but when I change it to something like @page "/data/{url?}" I have blank page and this in browser's console:

image

A possibility to set up a "one entity" view

Currently, we can set up a "catch-all" page that will serve CRUD for all entities in our DB (or at least the ones we make as available in our DbContext).

However, it's often necessary to quickly set up a CRUD page for one entity (e.g. only "Customer") on a separate page that does not fits to /easydata/{entity} pattern.

It would be possible if our EasyDataViewDispatched could accept a rootEntity option, so its behavior would be the same as we opened /easydata/{rootEntity} page.

An example of the EasyData initialization code in such a case:

window.addEventListener('load', () => {
    new EasyDataViewDispatcher({
        rootEntity: 'Customer'
    }).run()
});

EasyDataManagerEF fails with entities that are generic types

I'm trying to use EasyData in a project that has the "Individual Accounts" feature enabled, i.e., it has the ASP.NET Identity data model. Several of the entities won't load, and the culprit seems to be the generic types (IdentityUserClaim<TKey>, IdentityUserRole<TKey>, etc.)

When EasyDataManagerEF tries to find the entity type, it fails:

        private IEntityType GetCurrentEntityType(DbContext dbContext, string entityContainer)
        {
            var entityType = dbContext.Model.GetEntityTypes()
                .FirstOrDefault(ent => 
                    ent.Name.Split('.').LastOrDefault() == entityContainer);

            if (entityType == null) {
                throw new ContainerNotFoundException(entityContainer);
            }

            return entityType;
        }

In this scenario, entityContainer is for example IdentityRoleClaim, while the model's entity type is IdentityRoleClaim<int>.

As a quick test/workaround, I implemented my own EasyDataManager based on EasyDataManagerEF, and these two changes seem to do the trick:

diff --git a/easydata.net/src/EasyData.EntityFrameworkCore.Relational/Services/EasyDataManagerEF.cs b/easydata.net/src/EasyData.EntityFrameworkCore.Relational/Services/EasyDataManagerEF.cs
index 55f2075..6c96d56 100644
--- a/easydata.net/src/EasyData.EntityFrameworkCore.Relational/Services/EasyDataManagerEF.cs
+++ b/easydata.net/src/EasyData.EntityFrameworkCore.Relational/Services/EasyDataManagerEF.cs
@@ -69,7 +69,7 @@ namespace EasyData.Services
             var result = new EasyDataResultSet();
 
             var modelEntity = Model.EntityRoot.SubEntities.FirstOrDefault(e => e.ClrType == entityType.ClrType);
-            var attrIdProps = entityType.GetProperties().ToDictionary(prop => DataUtils.ComposeKey(entityType.Name.Split('.').Last(), prop.Name), prop => prop );
+            var attrIdProps = entityType.GetProperties().ToDictionary(prop => DataUtils.ComposeKey(entityType.Name.Split('.').Last().Split('<').First(), prop.Name), prop => prop );
 
             var attrs = modelEntity.Attributes.Where(attr => attr.Kind != EntityAttrKind.Lookup);
             foreach (var attr in attrs) {
@@ -169,7 +169,7 @@ namespace EasyData.Services
         {
             var entityType = dbContext.Model.GetEntityTypes()
                 .FirstOrDefault(ent => 
-                    ent.Name.Split('.').LastOrDefault() == entityContainer);
+                    ent.Name.Split('.').LastOrDefault().Split('<').FirstOrDefault() == entityContainer);
 
             if (entityType == null) {
                 throw new ContainerNotFoundException(entityContainer);

The idea is the same in both places: Split by < and take the first element, so when the entity type is generic, the generic part is omitted.

I'm not sure about creating a PR, because I'm not familiarized with the code, and I'm not sure if this is the optimal solution. Also, this might be kind of a niche use case for EasyData.

Steps to reproduce

  1. Create a new project with "Individual accounts" (dotnet new webapp --auth Individual)
  2. Setup EasyData
  3. Browse any generic entity, for example /easydata/IdentityRoleClaim

Expected result

An empty grid (as there are no records yet), with the option to add a new one.

Actual result

EasyData fails, and the grid is not rendered. There's a 404 during the request to fetch data: POST https://localhost:5001/api/easydata/models/EasyData/crud/IdentityRoleClaim/fetch

Export to Excel converts some date value to numbers

It does not happen for all values. I believe it occurs only for those ones where the month number is less than 13. Probably Excel confuses the month and day part in this case.

Here is an example of exported data. All values in the second column are dates.
image

The actual value in the 3d row is 12/02/2020. In 4th - 03/06/2021. So, I guess we can see the pattern.

.NET 6 support

There is a problem with .NET 6 version while loading DbContext metadata. Possibly there are other issues.
Need investigation

Set default order for each entity

Sometimes it's necessary to specify a particular order for entity records. For example, we may want to see Users sorted by DateCreated fields in descending order.

So, we need a way to specify this default order somewhere.

Any document about the entity CRUD restful apis

hi, as the title say, for now, i can find is :

private static readonly Endpoint[] _routing =
            {
                new Endpoint(DataAction.GetModel, @"^/models/([^/]+?)$", "GET"),
                new Endpoint(DataAction.GetEntities, @"^/models/([^/]+?)/crud/([^/]+?)/fetch$", "POST"),
                new Endpoint(DataAction.GetEntity, @"^/models/([^/]+?)/crud/([^/]+?)/fetch/([^/]+?)$", "GET"),
                new Endpoint(DataAction.CreateEntity, @"^/models/([^/]+?)/crud/([^/]+?)/create$", "POST"),
                new Endpoint(DataAction.UpdateEntity,@"^/models/([^/]+?)/crud/([^/]+?)/update/([^/]+?)$", "POST"),
                new Endpoint(DataAction.DeleteEntity, @"^/models/([^/]+?)/crud/([^/]+?)/delete/([^/]+?)$", "POST")
            };

...

public virtual async Task HandleGetEntitiesAsync(string modelId, string entityContainer, CancellationToken ct = default)
        {
            int? offset = null;
            int? fetch = null;

            bool isLookup = false;

            IEnumerable<EasyFilter> filters = null;
         
            bool needTotal = false;

            JObject requestParams;
            using (var requestReader = new HttpRequestStreamReader(HttpContext.Request.Body, Encoding.UTF8))
            using (var jsonReader = new JsonTextReader(requestReader)) {
                requestParams = await JObject.LoadAsync(jsonReader, ct);
            }

            if (requestParams.TryGetValue("offset", out var value)) {
                offset = value.ToObject<int?>();
            }
            if (requestParams.TryGetValue("limit", out value)) {
                fetch = value.ToObject<int?>();
            }
            if (requestParams.TryGetValue("needTotal", out value)) {
                needTotal = value.ToObject<bool>();
            }
            if (requestParams.TryGetValue("lookup", out value)) {
                isLookup = value.ToObject<bool>();
            }
            if (requestParams.TryGetValue("filters", out value) && value.HasValues) {
                filters = await GetFiltersAsync(modelId, (JArray)value, ct);
            }

            long? total = null;
            if (needTotal) {
                total = await Manager.GetTotalEntitiesAsync(modelId, entityContainer, filters, isLookup, ct);
            }

            var sorters = await Manager.GetDefaultSortersAsync(modelId, entityContainer);

            var result = await Manager.GetEntitiesAsync(modelId, entityContainer, filters, sorters, isLookup, offset, fetch);
            await WriteOkJsonResponseAsync(HttpContext, async (jsonWriter, cancellationToken) => {
                await WriteGetEntitiesResponseAsync(jsonWriter, result, total, cancellationToken);
            }, ct);
        }

any detail documentation about these above apis ?

thanks very much !

Convert all samples to .NET 6

We can leave one of the samples (EasyDataBasicDemo.RazorPages most likely) on .NET 5 just to make sure everything works well after the latest updates.

A possibility to change text on dialog buttons

When we create a dialog with dialogOptions.submittable === true we automatically get "OK" and "Cancel" button at the bottom.

However, it would be great to have a possibility to change the default text for those buttons.

Let's do it by adding two more fields to DialogOptions structure:

{
       .      .      .      .
   submitButtonText?: string,
   cancelButtonText?: string
}

Minimal API sample

We need a "pure" .NET 6 sample project with minimal API Entity Framework 6 and all the latest C# 10 features we can use there.

Add Export to EasyData middleware and entity page

Currently, we have all export packages for different formats but do not use them in the library.

What we need is to:

  1. Implement registering exporters
  2. Add export endpoint to Middleware
  3. Add dialog on EntityView

Blazor support

It would be great to have a sample project that demonstrates how to use EasyData in Blazor applications. Or, better, 2 sample projects, one for Blazor Server hosting type, another - for Blazor WebAssembly

EasyData support for Master Detail CRUD

Hello, I was looking at your demo, majority of the applications we have use Master-Details CRUD with auditing/Tenant ID, there is a free plugin by zzz for auto-autdits here

  • If you could add the master detail it would be very helpful.
  • Selected row on the master while editing master or detail page show be clear
  • Also, how can we merge this with the save query choice to user after setting

"Create" record does not show related entities

Steps to reproduce

  1. Launch EasyDataBasicDemo.NetCore31
  2. Go to /easydata/OrderDetail
  3. Click "Add Column" button (which should be called "Add Row" though)
  4. Try to add Order or Product in "Create Order Detail" dialog window

Actual Result

"Navigation Values" buttons do not work.

image

Expected Result

A dialog is shown which allows to choose Order or Product

Model Extension

Hi Devs,

Can I extend the models and inject instead of using the default model.

Explanation:
For example the customer model has 10 properties, I want 5 from the existing model and add my own new properties into model.

Is that possible in EasyData.

thanks and regards.

Feature: Add security/role/claim for what user can do

This is very nice now I understand, the 5.0 Sample builds fine with the latest,

Must - Master Details is a Must.
The columns, grid should be responsive (fit page/container)
Option to use DTO's
Option to use AutoMapper ORM Mapper
Must - Security is very important, on what role the user can do, for e.g it should create a new view with the list of tables and which ones are, options/checkboxes on C R U D permissions and Map it or create a role.
Change the Icon for the navigation properties, or let user configure, if the page is small height its hidden
Allow to select which items are viewable.
Option for Audit Table, which user performed which action/Update on what date.
Notification to user when data has been saved
Manager/Data Handler would be nice if it was fluent.
Option for lazy loading and searching the table for records.

Doesn't work with byte[]

It is possible to configure EasyData to be able to work with byte arrays?
byte[] fields are not displayed for editing

Cannot find node module

Hi Devs,

I'm trying to start EasyDataAspNetCoreTest01 in the dev playground. But I have an error in my browser console:

Uncaught Error: Cannot find module '../node_modules/@easydata/ui/dist/assets/css/easy-grid.css'

I installed all packages defined in package.json dependencies but still have the error. Can you help me?

image

best regards.

MongoDb support

Let consider adding mongo db support.

Also I think it worth to move an object editor's UI and logic to another package to get ability to use it separately. Like just by giving a model instance for edition.

And thank you for a great library!

Exception when Context contains [Keyless] Views

DbContext implementation:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyCustomView>(entity =>
    {
        entity.ToView("MyCustomView", "dbo");
    });
    // ...
}

Model:

[Keyless]
public partial class MyCustomView
{
    // ...
}

Snippet from my dev tools:

GET https://localhost:44346/api/easydata/models/__default returned HTTP Status Code 400: Bad Request
easydata.min.js:2 Error: Value cannot be null. (Parameter 'key'). Source: undefined

Sure, I might add an [MetaEntity(false)] to my view's POCO representation, but lot of my contexts have lots of views. It should be possible to detect and just skip [Keyless] entities.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.