Giter Site home page Giter Site logo

dsuryd / dotnetify-elements Goto Github PK

View Code? Open in Web Editor NEW
58.0 58.0 9.0 12.44 MB

Backend-ready React components for .NET web apps.

Home Page: https://dotnetify.net/elements

License: Other

JavaScript 83.26% CSS 0.60% C# 13.53% HTML 2.32% Dockerfile 0.03% ASP.NET 0.22% Batchfile 0.04%
components csharp dotnet form react

dotnetify-elements's People

Contributors

area55git avatar dependabot[bot] avatar dsuryd 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

Watchers

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

dotnetify-elements's Issues

TypeScript Definitions?

Hello,

Awesome work on the library! I was just curious, though, if you had any plans to create TypeScript definitions for dotNetify-elements?

Support for DOCTYPE html

Spent the most part of today trying to figure out why the new Layout component 'Main' wasn't filling whole screen in my new project as it does in the SPA template.

Turns out the 'dotnet new react' template generates an index.html with DOCTYPE html at the top. The SPA template does not have a DOCTYPE set.

I can leave the doctype out for now but wanted to see if this was on the to do list for future versions.

Can definition of an onclick in a button not override default behaviour?

The button with id=New does an action defined in the server viewmoder:

            AddProperty<object>("New")
                .Subscribe(_ => ClearForm());

Problem is if I define for that button a custom function for onclick then the action in the server is not called, only is called the one in the client. How can I make both are executed?

class FamilyForm extends React.Component {

    state = { updateEdit: false, newEdit: false };

    toggleUpdateEdit = _ => this.setState({ updateEdit: !this.state.updateEdit });
    toggleNewEdit = _ => {
        this.setState({ newEdit: !this.state.newEdit });
    }

    render() {
        const { updateEdit, newEdit } = this.state;
        const edit = () => updateEdit || newEdit; 
        return (
            <VMContext vm="FamilyVM">
                        {!edit() && <TextField label="Go to" />}
                        <Button label="New" id="New" onClick={this.toggleNewEdit} show={!edit()} enable={!edit()} />
             </VMContext>

Non core support

Unfortunately we cannot move our architecture fully to .net core 2 because of bindings to WCF parts that will not be coming to .Net core.

Support for .Net framework 4.7 would be nice.

Forgot that I actually used the Framework setup

Is it possible to set the submited value of a modal dialog to a TextField?

I manage to get the submitted data to the dialog from its parent. But I don't know how to update the viewmodel setting that value for the GoTo textbox. A hack would be to use jquery to simulate user input on that textfield putting that value but I was trying to avoiding that. Any idea?

import React from 'react';
import SearchDialog from './SearchDialog';
import { withTheme, VMContext, Form, Element, Alert, Panel, TextField, Button  } from 'dotnetify-elements';

class FamilyForm extends React.Component {

    state = { openDialog: false };
    VMState = {};

    toggleDialog = _ => { this.setState({ openDialog: !this.state.openDialog}) };
    handleFamilyVMStateChange = VMState => { this.VMState = VMState }
    //Following line is wrong cause VMState don't have available that method.
    handleSearchSubmit = item => { this.VMState.dispatchState({ GoTo: item.SelectedResult }) };

    render() {
        const { openDialog  } = this.state;
        return (
            <VMContext vm="FamilyVM" onStateChange={this.handleFamilyVMStateChange}>
                <Panel horizontal>
                        {!edit() && <TextField id="GoTo" label="Go to" />}
                       <Button label="Search" onClick={this.openDialog} show={!edit()} />
                </Panel>
                {openDialog && <SearchDialog onClose={this.closeDialog} onSubmit={this.handleSearchSubmit} />}
            </VMContext>
        );
    }
};
export default withTheme(FamilyForm);

Elements for rendering collection items

It would be great if it could be possible to be able to work with collections (sth like this sample http://dotnetify.net/core/examples/simplelist ) but with elements. Allowing us to declare behavior of all the records for each one of its properties using WithAttibute(), With..Validation.

This is related with this issue #37 but not the same cause now I'm not asking anything related with datagrid element.

Frame is not documented

What provides Frame element, I didn't found an explanation in the docc

I'm enjoying a lot with my firsts steps with dotNetify thank you.

Is it possible to change option of a dropdownlist after initializacion?

This is related with this other one issue dsuryd/dotNetify#125
I need to pass an argument to a viewmodel and depending on that argument fulfill controls on that modal.
It is not possible to pass that argument through contructor, so, I use a text element in the modal to pass that value.
Problem is when this text element is changed I cannot provide new DropdownListAttribute based on the new value passed to an existing DropDownList within that modal.
Is there a way of doing that?

[Elements] Is it possible to access the VMContext state outside of an Element component?

Great Library i must say ๐Ÿ‘

I am building a Form and this is how i want the workflow to look.

Submit Form > display a progress/loading indicator > redirect to another page using the form response.

So far i have the form submitting fine. For the second step, i think it could be solved by adding a bool property onto the ViewModel and performing a conditional render on the client.
But if i have a property like "SubmitInProgress", how would i then access this from the React Component?

The third step, i already have the ServerReponse outputting to an Alert component, but again ideally i would need this property in a function. I can't see in the documentation, but does the form have anything like onSuccess function? where you can access the response?

Here is the code for reference

import React, { Component } from "react";
import dotnetify from "dotnetify";
import {
  Alert,
  Button,
  Form,
  Panel,
  TextField,
  VMContext,
  withTheme
} from "dotnetify-elements";
import MuiButton from "@material-ui/core/Button";
import MuiTextField from "@material-ui/core/TextField";

const TrialFormContainer = props => (
  <VMContext vm="NewTrialForm">
    <Form>
      <Alert id="ServerResponse" />
      <Panel>
        <TextField id="FirstName" inputComponent={MuiTextField} />
        <TextField id="LastName" inputComponent={MuiTextField} />
        <TextField id="EmailAddress" inputComponent={MuiTextField} />
        <TextField id="Company" inputComponent={MuiTextField} />
        <TextField id="PhoneNumber" inputComponent={MuiTextField} />
        <Button id="ActivateTrial" inputComponent={MuiButton} submit />
      </Panel>
    </Form>
  </VMContext>
);

export default withTheme(TrialFormContainer);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotNetify;
using DotNetify.Elements;
using Newtonsoft.Json;

namespace One.Veeam.Web.Model
{
    public class NewTrialForm : BaseVM
    {
        private class FormData
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string EmailAddress { get; set; }
            public string Company { get; set; }
            public string PhoneNumber { get; set; }
        }

        public NewTrialForm()
        {
            AddProperty<string>("FirstName")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "First Name",
                    MaxLength = 20
                })
                .WithMinValidation(2)
                .WithMaxValidation(20)
                .WithRequiredValidation();

            AddProperty<string>("LastName")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Last Name",
                    MaxLength = 20
                })
                .WithMinValidation(2)
                .WithMaxValidation(20)
                .WithRequiredValidation();

            AddProperty<string>("EmailAddress")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Email Address",
                    MaxLength = 50
                })
                .WithMinValidation(3)
                .WithMaxValidation(50)
                .WithPatternValidation(Pattern.Email, "Please enter a valid email address.")
                .WithRequiredValidation();

            AddProperty<string>("Company")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Company Name",
                    MaxLength = 100
                })
                .WithMinValidation(2)
                .WithMaxValidation(100)
                .WithServerValidation(ValidateCompanyNotRegistered, "Only one Trial allowed per Company.")
                .WithRequiredValidation();

            AddProperty<string>("PhoneNumber")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Phone Number",
                    MaxLength = 25
                })
                .WithMinValidation(8)
               // .WithMaxValidation(25)
                .WithRequiredValidation();

            AddProperty<FormData>("ActivateTrial")
                .WithAttribute(new { Label = "Active Free Trial" })
                .SubscribedBy(
                    AddProperty<string>("ServerResponse"), submittedData => Save(submittedData));

        }

        private string Save(FormData data)
        {
            // post it to veeam
            // return the username and password
            // fire off emails

            return JsonConvert.SerializeObject(new
            {
                username = "User1",
                password = "12345"
            });
        }

        private bool ValidateCompanyNotRegistered(string company)
        {
            // check the company is not registered
           return true;
        }
    }
}


Thanks in advance!

TypeScript support

It would be nice to have TypeScript support.

I have tried to generate via dts-gen

dts-gen -m dotnetify-elements

but I unfortunately get a ReferenceError: window is not defined

Is it possible configure validation to don't execute always?

I don't want to execute server side validations when I load an entity following an approach like described here #29 (comment)
By the moment I reduce the extra cycles on server side with an `if(loading) return true on server side. However I would prefer to avoid this unedeed communication when loading is true.

Another scenario on which I would like to avoid server side validation is executed is when for a property there is defined a With...Validation() and next a WithServerValidation(). If client side validation fails some for some field I don't want server side validation is executed. Is it possible to configure it in any way?

Is it possible to use this library with Material UI Layout/Styling?

Hello,

I'm currently using https://material-ui.com/ for my layout/styling needs, most of the styles are defined at the top level in the theme provider.

I'm trying to get a form working, this is the implementation

      <VMContext
        vm="NewTrialForm"
        onStateChange={state => {
          console.log(JSON.stringify(state));
          if (state.RequestId !== "") {
            this.props.getRequestID(state.RequestId);
          }
        }}
      >
        <Form>
          <TextField
            id="FirstName"
            label="FirstName"
            required
            autoFocus
            fullWidth
            inputComponent={MuiTextField}
          />
        </Form>
      </VMContext>

however this throws an error in the console

dotnetify-elements.js:655 Uncaught TypeError: Cannot read property 'Container' of undefined
at dotnetify-elements.js:655
at styled-components.browser.es.js:95
at Array.reduce ()
at flatten (styled-components.browser.es.js:73)
at ComponentStyle.generateAndInjectStyles (styled-components.browser.es.js:2048)
at StyledComponent.generateAndInjectStyles (styled-components.browser.es.js:1739)
at StyledComponent.componentWillMount (styled-components.browser.es.js:1780)
at callComponentWillMount (react-dom.development.js:13025)
at mountClassInstance (react-dom.development.js:13123)
at updateClassComponent (react-dom.development.js:14854)
at beginWork (react-dom.development.js:15716)
at performUnitOfWork (react-dom.development.js:18750)
at workLoop (react-dom.development.js:18791)
at HTMLUnknownElement.callCallback (react-dom.development.js:147)
at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
at invokeGuardedCallback (react-dom.development.js:250)
at replayUnitOfWork (react-dom.development.js:17998)
at renderRoot (react-dom.development.js:18909)
at performWorkOnRoot (react-dom.development.js:19812)
at performWork (react-dom.development.js:19722)
at performSyncWork (react-dom.development.js:19696)
at requestWork (react-dom.development.js:19551)
at scheduleWork (react-dom.development.js:19358)
at Object.enqueueSetState (react-dom.development.js:12789)
at t.push../node_modules/dotnetify-elements/node_modules/react/cjs/react.development.js.Component.setState (react.development.js:242)
at setState (dotnetify-elements.js:1465)
at dotnetifyVM.State (dotnetify-react.js:851)
at dotnetifyVM.$update (dotnetify-react.js:1057)
at Object._responseVM (dotnetify-react.js:394)
at dotnetify-react.js:319
at dotnetify-react.js:709
at Array.forEach ()
at Object.emit (dotnetify-react.js:708)
at HubConnection._dotnetifyHub2.default.client.response_VM (dotnetify-react.js:2160)
at HubConnection.js:544
at Array.forEach ()
at HubConnection.invokeClientMethod (HubConnection.js:543)
at HubConnection.processIncomingData (HubConnection.js:450)
at WebSocketTransport.HubConnection.connection.onreceive (HubConnection.js:165)
at WebSocket.webSocket.onmessage (WebSocketTransport.js:215)
(anonymous) @ dotnetify-elements.js:655
(anonymous) @ styled-components.browser.es.js:95
flatten @ styled-components.browser.es.js:73
generateAndInjectStyles @ styled-components.browser.es.js:2048
generateAndInjectStyles @ styled-components.browser.es.js:1739
componentWillMount @ styled-components.browser.es.js:1780
callComponentWillMount @ react-dom.development.js:13025
mountClassInstance @ react-dom.development.js:13123
updateClassComponent @ react-dom.development.js:14854
beginWork @ react-dom.development.js:15716
performUnitOfWork @ react-dom.development.js:18750
workLoop @ react-dom.development.js:18791
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
replayUnitOfWork @ react-dom.development.js:17998
renderRoot @ react-dom.development.js:18909
performWorkOnRoot @ react-dom.development.js:19812
performWork @ react-dom.development.js:19722
performSyncWork @ react-dom.development.js:19696
requestWork @ react-dom.development.js:19551
scheduleWork @ react-dom.development.js:19358
enqueueSetState @ react-dom.development.js:12789
push../node_modules/dotnetify-elements/node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:242
setState @ dotnetify-elements.js:1465
State @ dotnetify-react.js:851
$update @ dotnetify-react.js:1057
_responseVM @ dotnetify-react.js:394
(anonymous) @ dotnetify-react.js:319
(anonymous) @ dotnetify-react.js:709
emit @ dotnetify-react.js:708
_dotnetifyHub2.default.client.response_VM @ dotnetify-react.js:2160
(anonymous) @ HubConnection.js:544
HubConnection.invokeClientMethod @ HubConnection.js:543
HubConnection.processIncomingData @ HubConnection.js:450
HubConnection.connection.onreceive @ HubConnection.js:165
webSocket.onmessage @ WebSocketTransport.js:215
index.js:1452 The above error occurred in the <Field__Container> component:
in Field__Container
in t
in t (at TrialFormContainer/index.js:37)
in form
in t (at TrialFormContainer/index.js:36)
in t (at TrialFormContainer/index.js:27)
in TrialFormContainer (at Create.js:14)
in Create (created by Route)
in Route (created by withRouter(Create))
in withRouter(Create) (at page/index.js:20)
in StoreProvider (at page/index.js:15)
in ErrorBoundary (at Layout/index.js:53)
in div (at Layout/index.js:52)
in div (at Layout/index.js:51)
in Transition (created by Fade)
in Fade (created by WithTheme(Fade))
in WithTheme(Fade) (at Layout/index.js:50)
in div (at Layout/index.js:23)
in Layout (created by WithStyles(Layout))
in WithStyles(Layout) (at page/index.js:14)
in Page (at app/index.js:36)
in Suspense (at app/index.js:35)
in CssBaseline (created by WithStyles(CssBaseline))
in WithStyles(CssBaseline) (at app/index.js:34)
in MuiThemeProviderOld (at app/index.js:33)
in Router (created by BrowserRouter)
in BrowserRouter (at app/index.js:32)
in ErrorBoundary (at app/index.js:31)
in Unknown (at src/index.js:11)

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.

So then i have to add a <Panel> in, which also throws an error if it's not nested in a <Theme> component.

After that, the form works fine and renders, but then the styles that have been defined for the label/error message are no longer used and it seems to pull the styles from the withTheme HOC.

Is it possible to ignore the styles? Or would it be possible to use the native Material UI attributes such as error/helperText?

Thanks
Tom

Is source code available for the React components of DotNetify-Elements?

Have you made the javascript/react code available on GitHub? I only see the server-side code.

Could I see for example, the React code for the NavMenu?

I'd like to make a NavMenu that collapses but shows the icons rather than hiding the whole component.
I'd like to see how you made your control as an example.

Thank you,

Jeremy

A Modal with onSubmit handler doesn't allow to use onChange like Form element

Hi,
I have a modal element with an onSubmit handler. It makes client doesn't dispatch to server fields till submit is called. However I need some of the fields (a textfield and a dropdownlist) within this modal to be updated on the server when the dropdownlist selection changes or when a textfield receives a new keystroke.
I have tried to use onChanged event, but I've seen it is only available for forms not for modals.
Can be this event added to modal? Would I need sth else to dispatch the value of those fields to the server?

Many thanks for your quick answers

Checkbox doesn't enable Submit button?

Using a Form and only Checkboxes as input elements, it doesn't look like the Submit button is getting enabled so user can submit data to the back end.

Bundle Size Optimizations

I wanted to open this issue as a place to discuss the current bundle size and offer any solutions for reducing this.

with a basic react application and webpack set to production, currently i'm getting a bundle size of about 1.7mb which is huge!

Here is the react application for reference

import React from "react";
import ReactDOM from "react-dom";

import Element from "dotnetify-elements";

const Index = () => {
  return (
    <div>
      <Element id="1234" />
    </div>
  );
};

ReactDOM.render(<Index />, document.getElementById("app"));

After using the webpack-bundle-analyzer webpack plugin, there are a few areas that catch my eye but maybe some other suggestions could be added.

image

So here are a few

  • React is bundled with the library.
  • All the moment locales are bundled.
  • react-data-grid is huge.

and i'm sure there are other issues that people might spot. I'll try and get a pr raised this weekend to resolve the first item, but it might require a bit more thought to tackle the others.

Anyway, its a great library and i just want to help any way i can.

Logo Proposal for dotNetify

Hi, I'm a graphic designer and I like to collaborate with open source projects. Do you know that the graphic image of a project is very important? thinking about it I would like to design a logo for your Project dotNetify.

I will be pleased to collaborate with you.

Uncaught (in promise) TypeError: t.dom.focus is not a function

Bit of an odd one. I can successfully submit the form, however when i return to the form in the same browser, it throws the above error. Any ideas?

here is the error from chrome console.

Uncaught (in promise) TypeError: t.dom.focus is not a function
at t.value (Form.js:344)
at Form.js:351
value @ Form.js:344
(anonymous) @ Form.js:351
Promise.then (async)
r.handleClick @ Button.js:221
(anonymous) @ react-dom.production.min.js:49
d @ react-dom.production.min.js:69
(anonymous) @ react-dom.production.min.js:73
S @ react-dom.production.min.js:140
P @ react-dom.production.min.js:169
T @ react-dom.production.min.js:158
A @ react-dom.production.min.js:232
_n @ react-dom.production.min.js:1718
Ru @ react-dom.production.min.js:5990
Le @ react-dom.production.min.js:660
Pn @ react-dom.production.min.js:1760
(anonymous) @ react-dom.production.min.js:6017
t.unstable_runWithPriority @ scheduler.production.min.js:274
Iu @ react-dom.production.min.js:6016
On @ react-dom.production.min.js:1737

Which references this function

setInputFocus(inputId) {
const input = this.inputs.filter(input => input.propId === inputId).shift();
if (input && input.dom) input.dom.focus();
}

Because this error is thrown, i am unable to submit the form.

[Elements] I'm not able to execute a simple action when a button inside a Form is clicked

This samples works properly for me without problems. However when I try to add a button that executes an action in the viewmodel I don't manage to get it done:

[React]
...
<Button label="Next" id="Next" show={!edit} />
...

[VM contructor in C# Alternative 1]
...
AddProperty<object>("Next")
                .Subscribe(_ => LoadFormWithNextItemAsync().GetAwaiter().GetResult());
...                

[VM contructor in C# Alternative 2]
...
AddProperty<object>("Next")
                .SubscribedBy(AddProperty<bool>("NextSuccess"), _ => LoadFormWithNextItemAsync().GetAwaiter().GetResult());
...

For anyone of these two alternatives it does nothing. I use dotnetify.debug=true in React Code but after the click there is not any tranmision of data. I set a breakpoint int the body of the lambda but it never stops there so no calls to LoadFormWithNextItemAsync().GetAwaiter().GetResult()

Any idea of what am I doing wrong?

Strange behavior submitting a form

This sample shows a strange behavior I'm experiencing when a form is submitted after is is loaded.
The view:

import React from 'react';
import PropTypes from 'prop-types';
import dotnetify from 'dotnetify';
import { Scope } from 'dotnetify';
import { withTheme, VMContext, Form, Element, Panel, TextField, Button  } from 'dotnetify-elements';

dotnetify.debug = true

class TestForm extends React.Component {
    state = {};
    
    render() {
        return (
            <VMContext vm="TestVM">
                <TextField label="IdToLoad" id="IdToLoad" />
                <Form>
                    <Panel>
                        <Panel horizontal>
                            <Button label="Save" submit id="SubmitUpdate" />
                        </Panel>
                    </Panel>
                    <Panel >
                        <TextField label="Id" id="Id"  />
                        <TextField label="Description" id="Descrip" />
                        <TextField label="Observations" id="Observations" />
                    </Panel>
                </Form>
            </VMContext>
        );
    }
};
export default withTheme(TestForm);

The viewmodel:

public class TestVM : BaseVM
    {
        TestDTO myTestDto = new TestDTO() { Id = 2, Descrip = "Test", Observations = "Observa Test" };
        private readonly IServiceProvider _serviceProvider;

        public TestVM(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            
            var id = AddProperty<int>("Id");
            var descrip = AddProperty<string>("Descrip");
            var observations = AddProperty<string>("Observations");
            
            var idToLoad = AddProperty<int>("IdToLoad");
            idToLoad.WithServerValidation((i) => true,"Error");
            idToLoad.Subscribe(i =>
            {
                if (i == default(int))
                {
                    id.Value = null;
                    descrip.Value = null;
                    observations.Value = null;
                    return;
                }

                id.Value = myTestDto.Id;
                descrip.Value = myTestDto.Descrip;
                observations.Value = myTestDto.Observations;
                PushUpdates();
            });

            AddProperty<TestDTO>("SubmitUpdate")
                .Subscribe(formData =>
                {
                    if (formData.Id==0)
                        throw new Exception("Why Id is not initialized?");
                });
        }
}
public class TestDTO 
    {
        public int Id { get; set; }
        public string Descrip { get; set; }
        public string Observations { get; set; }
    }

If I set an int on IdToLoad textfield (no matter which) and press enter it loads properly data on the form. The strange thing happens after I modify Descrip and click on Save. You will see data formData sumbitted to server on SubmitUpdate property is not the current data in the form, Id is 0 when it should be 2, and Observations are null when should be "Observa Test". The only valid data is the one you input (Descrip. In fact if you edit all of them the data edited will be send properly to server side.
The expected behavior is data is submited as it is on the view.

Thank you

Dotnetify for Composite UI provided by microservices

I'm evaluating the posibility of using dotnetify for an app based on microservices where each microservice also provides its own VMs and UI elements with dotnetify.

The idea is to use for certain views composition of different components dinamically loaded from different urls.
For example catalog microservice will provide composite view named product that will be composed by a product_catalog component that is a form element loaded from the same microservice, product_commercialTerms is a component with a form element loaded from commercial term microservice and other elements related with product entity loaded from other microservices.
If I show only a submit button for all the view. When it is pressed it will submit data on product_catalog view model, if validation of data in server side is ok view will be informed and an event on client side named Product_catalog_Update_Validated will be emited (using a library like that https://github.com/chrisdavies/eev ) it will be handled by all the other commponents in the view that will validate its part of the data on server side, product_commercialTerms for this example. If all of them emit an event saying everything is ok like product_catalog then container view will use same procedure for commiting all the data each one on its own microservice.

All of that is theoretical. Do you think there is any problem on using Dotnetify in this scenario? Do you think it is a reasonable approach?
Thank you

marked dependency should be upgraded to fix vulnerabilities

When dotnetify-elements is installed into the project, npm audit currently reports that 'marked' should be upgraded to at least 0.7.0 and it can only be done by the author of dotnetify-elements.

                       === npm audit security report ===


                                 Manual Review
             Some vulnerabilities require your attention to resolve

          Visit https://go.npm.me/audit-guide for additional guidance


  Moderate        Regular Expression Denial of Service

  Package         marked

  Patched in      >=0.6.2

  Dependency of   dotnetify-elements

  Path            dotnetify-elements > marked

  More info       https://npmjs.com/advisories/812


  Low             Regular Expression Denial of Service

  Package         marked

  Patched in      >=0.7.0

  Dependency of   dotnetify-elements

  Path            dotnetify-elements > marked

  More info       https://npmjs.com/advisories/1076

The first vulnerability appears quite a long time ago. The second is much newer.

Server Validation doesn't seem to trigger from Component that extends Element

Hello,

I am try to build a form that integrates with Google ReCaptcha. I want the token returned to become part of the View Model so i can verify it on the server side.

My first implementation was using a standard TextField component, but the value didn't seem to get posted back to the View Model.

So i've instead decided to extend the Element class. Here is the component

import React, { Fragment } from "react";
import PropTypes from "prop-types";
import { Element } from "dotnetify-elements";
import { ReCaptcha as Re } from "react-recaptcha-google";

class ReCaptcha extends Element {
  static propTypes = {
    id: PropTypes.string.isRequired
  };

  componentDidMount() {
    if (this.trialCaptcha) {
      console.log("started, just a second...");
      this.trialCaptcha.reset();
    }
  }

  onLoadRecaptcha = () => {
    if (this.trialCaptcha) {
      this.trialCaptcha.reset();
    }
  };
  verifyCallback = recaptchaToken => {
    // Here you will get the final recaptchaToken!!!
    console.log(recaptchaToken, "<= your recaptcha token");
    this.dispatchProp("ReCaptchaToken", recaptchaToken);
  };

  render() {
    const { fullId, ...props } = this.attrs;
    const src = this.value == null ? "" : this.value;
    console.log("value: " + src);
    return (
      <Fragment>
        <Re
          ref={el => {
            this.trialCaptcha = el;
          }}
          size="small"
          render="explicit"
          sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
          onloadCallback={this.onLoadRecaptcha}
          verifyCallback={this.verifyCallback}
        />
        <input id={fullId} value={src} {...props} onChange={val => {}} />
      </Fragment>
    );
  }
}

export default ReCaptcha;

which seems to work fine posting the value back to the View Model, however the server side validation is never triggered. Also, i did originally use this.dispatch(value), but this didn't seem to update the value at all so i used this.dispatchProp("prop",value) instead.

the corresponding ViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using DotNetify;
using DotNetify.Elements;
using Newtonsoft.Json;

namespace One.Veeam.Web.Model
{
    using LogMagic;
    using Microsoft.Extensions.Configuration;
    using Threading;

    public class NewTrialForm : BaseVM
    {
        public NewTrialForm(IConfiguration config)
        {

            Configuration = config;
    
            // .... other props

            AddProperty<string>("ReCaptchaToken")
                .WithServerValidation(ValidateReCaptchaToken, "Invalid ReCaptcha")
                .WithRequiredValidation();
         
            AddProperty<FormData>("ActivateTrial")
                .SubscribedBy(
                    AddProperty<string>("RequestId", ""), submittedData => Save(submittedData));

        }

        private bool ValidateReCaptchaToken(string token)
        {
             // never hits here
        }

        private string Save(FormData data)
        {
            return Guid.NewGuid().ToString();
        }
    }
}

Is there any reason the ValidateReCaptchaToken method would not get called?

Thanks

Allow to declare DataGrid Column as Editable

Can editable and editor properties be used with GridColumn Element for harnessing those react-data-grid properties for editing data of a selected cell.
Adding those properties doesn't seem to have any effect on the underlying react-data-grid.
Is it on purpose for any reason?

Thank you

Panel right disables default vertical

In the Panel example selecting right disables the default vertical. I would have expected the boxes to be on the right vertically. It is like right expect horizontal to be active.

panel no right
panel right

Property validation

The validation is only for the client side (so I need to write same validation in WithServerValidation) or is the validation also done on the server when receiving the data from the client?
Client validation is mainly the usability validation but the server validation is the data validation you can trust. I hope it is data validation you aim for but documentation is not clear. I will test it tomorrow.

React 16.5 breaks DataGrid component

Updating past react 16.4.2 breaks the DataGrid component.

image

My project was at 16.5.2 and I started to put in a DataGrid and had these errors. I checked the sample template and it was using 16.3.2 so I started there and increased versions.

I'll stay at 16.4.2 for now. I don't have a requirement for later versions, I was using the latest since I am starting a new project.

Multiple messages for a validation

Is it possible to produce different error messages by an on server validation for a field?
I'm working on an app that that shares app logic between a webapp based on dontnetify and a webapi.
Both share validation, so my application layer provides methods for validating entities when are received on server side.
It checks foreign keys integrity and other business rules. So, a validation of an entity can return multiple errors, that should be shown after an unsuccessful server side validation after user submit.
I've guessed that this is not possible if previously I didn't define a With...Validation() for each property of those that can show an error message.
Is it possible to have a With...Validation() method that only provides the error properties to communicate from server the errors related to a field but do not force to do any validation on client or server side when the field changes?
Is it possible to let the server side to provide the message at validation time, instead of having to provide all the possible errors when the form is loaded?
Is it possible to have a kind of generic method WithServerValidationOnSubmit() for all the form that allows to set errors for different fields?
Finally, if I use .WithServerValidation() for a field is it possible to provide also differente messages at validation time?

Cross Browser support

Using the SPA template as an example,
FireFox - does not load the dotNetify logo.
Edge - does not load the dotNetify logo. Can't enter anything into the login screen.

No errors in the console to indicate what's wrong.

Any ideas?

Can an element access to other fields on the same VMContext?

This is a fragment of the render method of the component I use for my view:

render() {
        const { formMode, loading, currentId } = this.state;
        return ( 
            <VMContext vm="RateVM"
                ref={el => this.VMContext= el}
                onStateChange={state => { if (state) { this.setState({ loading: state.Loading, currentId: state.Id, formMode: state.FormMode }) } }} >
                {!loading &&
                    <Form>
                    <CRUDToolbar
                            IdToLoad={currentId}
                            formMode={formMode}
                            />

CRUDToolbar inherits by the moment from React.Component.

import React from 'react';
import PropTypes from 'prop-types';
import dotnetify from 'dotnetify';
import { Scope } from 'dotnetify';
import { withTheme, Modal, TextAreaField, VMContext, Form, Element,DataGrid, DropdownList, Alert, Panel, TextField, Button  } from 'dotnetify-elements';

export const FormModeEnum = { browse: 0, update: 1, new: 2 };
dotnetify.debug = true;

class CRUDToolbar extends React.Component {
    createButton = (cmdButtonProps) => {
        return <Button id={cmdButtonProps.id}
            key={cmdButtonProps.id}
            label={cmdButtonProps.label}
            onClick={cmdButtonProps.onClick}
            show={(this.props.formMode === FormModeEnum.browse)}
        />;
    }

    createButtons = (cmdButtons) => {
        if (cmdButtons)
        {
            return cmdButtons.map(this.createButton);
        }
    }
    
    render() {
        const { ...props } = this.attrs;
        const isBrowseable = () => this.props.formMode === FormModeEnum.browse;

        return (
            <Panel horizontal>
                <Button label="Edit" id="Edit" show={isBrowseable() && (this.props.IdToLoad > 0)}  />
                <Button label="Save" id="SubmitUpdate" submit show={this.props.formMode === FormModeEnum.update} />
                <Button label="Save" id="SubmitNew" submit show={this.props.formMode === FormModeEnum.new}  />
                <Button label="Cancel" id="Cancel" secondary show={this.props.formMode !== FormModeEnum.browse} />
                <Panel right>
                    {this.createButtons(this.props.extraButtons)}
                    <Button label="Add" id="Add" show={isBrowseable()} />
                </Panel>
            </Panel>
        )
    }
}
export default CRUDToolbar;

The question is: If CRUDToolbar inherits from React.Component could it access directly to other properties in the viewmodel to don't need to receive IdToLoad and FormMode as parameters?

Adapt style of a button after hide another one

I have following page when a form is shown.
image
But when the user edits it I hide Button Edit and show Update and Cancel.
Problem is Update is using a margin-left cause is is using a style for the second element of a list intead of using the style of the first element (cause first one has disappeared).
image
image
This behavior is caused by nYAAE class.
Is it possible to replace nYAAE per lcVREt class for second button when it is enabled? I haven't been able. I've also tried to use css attrib without success, for changing it depending on

const cssForFirstButton = editable => {
            if (editable)
                return "margin - left: 0px;";
            return "";
        };
<Panel horizontal>
    <Button label="Edit" show={!edit && this.state.Editable} onClick={this.toggleEdit}  />
    <Button label="Update" submit show={edit} onClick={this.toggleEdit} css={cssForFirstButton} />
    <Button label="Cancel" cancel secondary show={edit} onClick={this.toggleEdit} />
</Panel>

Potential Google Maps Integrations?

Do you have any plans to integrate a Google Maps component? Could make this package pretty hot!

Also, this is amazing work! Following Core and Elements!

OnSubmit on a Modal element doesn't work on some circumstances

Take a look to this sample:

import React from 'react';
import dotnetify from 'dotnetify';
import { withTheme, Modal, TextAreaField, VMContext, Form, Element,DataGrid, DropdownList, Alert, Panel, TextField, Button  } from 'dotnetify-elements';

dotnetify.debug = true
class SearchDialog extends React.Component {
    handleClose = _ => this.props.onClose();
    handleSubmit = item => { this.props.onSubmit(item); return false; };
    
    render() {
        return (
            <VMContext vm="SearchDialogVM"  >
                <Modal header="Search Dialog" large open={() => open} onSubmit={this.handleSubmit} >
                    <Panel horizontal>
                        <TextField label="Value" id="Value" />
                        <TextField id="SelectedResult" show={true} />
                    </Panel>
                    <footer>
                        <Panel right>
                            <Button label="Cancel" cancel secondary onClick={this.handleClose} enable={true} />
                            <Button id="Submit" label="Submit" submit onClick={this.handleClose} enable={true} />
                        </Panel>
                    </footer>
                </Modal>
            </VMContext>
        )
    }
}
export default withTheme(SearchDialog);
using System;
using DotNetify;
using DotNetify.Elements;

namespace PCCOM.Distrib.SPA.ProductsManagement.SPAViewModel
{
    
    public class SearchDialogVM : BaseVM
    {
        public SearchDialogVM() : base()
        {
            AddProperty("Value", "");
            AddProperty("SelectedResult", "0");
        }
    }
}

Previous example works properly and handleSubmit is called.
If I replace this AddProperty("Value", "") per this: AddProperty("Value", "0"); or per this AddProperty("Value", "0").WithServerValidation(input => true, ""); it also works properly.
However if I replace it per this AddProperty("Value", "").WithServerValidation(input => true, ""); the handleSubmit is not called.
Why?

Thank you

React won't pick up state object from .Net if field has an attribute

If I add attribute to a "state object" field (what is Observed), then it won't show up in the activity feed. If I remove the attributes, it works fine. Is there a way we could make it work even with attributes?

thanks!

public class Activity {

    [JsonProperty("ID")]
    public int Id { get; set; }

    [JsonProperty("personName")]
    public string PersonName { get; set; }
}

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.