npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vst-gridform

v6.2.0-beta.1

Published

A biblioteca vst-gridform digamos que é um syntax-sugar, ou mais específico, uma biblioteca que ajuda na implementação de um CRUD usando o devextreme. Esta biblioteca é completamente dependente do devextreme, assim não tendo direitos nenhum. Muito pelo co

Downloads

27

Readme

vst-gridform. O que é?

A biblioteca vst-gridform digamos que é um syntax-sugar, ou mais específico, uma biblioteca que ajuda na implementação de um CRUD usando o devextreme. Esta biblioteca é completamente dependente do devextreme, assim não tendo direitos nenhum. Muito pelo contrário, essa biblioteca tem única intenção de ajudar o programador a desenvolver certos códigos de forma mais rápida e mais amigável, utilizando a checagem estática que o typescript fornece.

Disclaimer

A idéia foi para me ajudar a desenvolver projetos mais elaborados mais rapidamente.

A única licença para essa biblioteca é a do DevExtreme. Para usar o devextreme em projetos privados, por favor, pague a licença necessária (não é barato, mas vale a pena).

ATENÇÃO!! USE POR SUA CONTA E RISCO!!!

Dependencias

  • Angular 12 ou 13
  • DevExtreme 21

Por que?

Usar o devextreme no angular segue uma linha diferente ao de como o devextreme foi inicialmente proposto, com o uso em paralelo com o jQuery.

Para usar com o angular, apesar de muito bom, foi necessário ligar-se ao HTML, como porta de entrada dos parametros e funções. Funciona muito bem, porém em algumas situações o desenvolvedor perde o monitoramente de erros estáticos que os arquivos em typescript fornecem. Os seguintes componentes datagrid e form oferecem muitas opções de configurações em uma camada mais profunda que a checagem de tipo no HTML consegue monitorar.

Só foi escrito o datagrid e form de maneira schematica, pois são os mais usados com comportamentos padrões, de uma tela pra outra.

O desenvolvedor pode muito bem usar o @ViewChild do angular, e usar o lint do ts. Porém, o segundo motivo é: Funcionalidades adicionais. Existe funcionalidades que é necessário em toda dela de crud (ou comportamento), e não existe implementação no devextreme, por ser algo muito específico com o tipo de desenvolvimento.

E o último motivo, mas o principal é: COMPONENTES CUSTOMIZADOS E FORMULARIO COMPLETO NA DATAGRID.

A datagrid do devextreme abre um formulário muito limitado, e fica a cargo do desenvolvedor criar um formulário mais elaborado e ter que gerenciar tanto o formulário quando a datagrid. O novo modelo, a própria datagrid gerencia o formulário que pode receber N customizações possíveis, que podem ser modulares, estando em múltiplos projetos.

Como funciona

Essa biblioteca segue o padrão composition (mais conhecida no java). Que diz o seguinte:

The composition is a design technique in which your class can have an instance of another class as a field of your class. - Fonte: Google

A herança de componentes não funciona muito bem no angular, pois não herda a parte visual, somente o código escrito do js.

Então segue a documentação dos dois componentes:

O DxDataGridComponent equivale a VsGridComponent, e o seletor dx-data-grid equivale a vs-grid. Equivale pois tanto o component quando o seletor do componente datagrid original ainda pode ser usado normalmente, o vs-grid é só uma camada, ele não reescreve o comportamente original. E o mesmo vale para o form, que tem as equivalências DxFormComponent para VsFormComponent, e dx-form para vs-form.

DOCS

FORMULÁRIO

O básico, import { VsFormModule } from 'vst-gridform'.

O component VsForm recebe apenas 6 entradas:

  • hasSubmit: boolean
  • formOperation: "create" | "read" | "update"
  • data: T
  • keys: any
  • schema: VsFormSchema
  • format: 'readonly' | 'edit'

e possui 5 saídas:

  • dataChange: EventEmitter
  • keysChange: EventEmitter
  • onValueChanged: EventEmitter
  • formatChange: EventEmitter
  • onEvent: EventEmitter

@Input() hasSubmit: boolean; (Default: false)

O hasSubmit é responsável por colocar as tags form ao redor do vs-form, e internamente todo submit event é encaminhado a uma função que é necessário ser escrito no schema

Exemplo:

<vs-form ... [hasSubmit]="true"></vs-form>

@Input() formOperation: "create" | "read" | "update"; (Default: undefined)

O formOperation é apenas um valor que a grid passa ao formulário quando está em alguma operação informada. Por exemplo, se o usuário aperta no botão mais na grid, então a grid renderiza o formulário e seta a variável formOperation do formulário que ela está cuidando como "create", assim, para algumas funcionalidades dentro do schema, esse formOperation é passado, e o desenvolvedor pode ou não deixar alguns campos visíveis.

@Input() data: T; (Default: undefined)

O data é o armazenamento onde o formulário insere os valores dos editores, e onde os editores fazem a leitura para renderizarem o conteúdo.

Exemplo:

<vs-form ... [data]="myFormData"></vs-form>

@Input() keys: any; (Default: undefined)

O keys é a chave do data que está sendo renderizado. Usado mais pelo datagrid quando em submit do handler do schema.

@Input() format: CustomTemplateFormat; (Default: 'edit')

O format informa ao formulário como ele deve ser renderizado, se normal, quando "edit", ou se em modo leitura, quando format é igual a "readonly".

@Output() dataChange: EventEmitter;

Emite um sinal quando o data é alterado.

@Output() keysChange: EventEmitter;

Emite um sinal quando o keys é alterado.

@Output() onValueChanged: EventEmitter;

Emite um sinal quando qualquer editor realiza uma alteração no data.

@Output() formatChange: EventEmitter;

Emite um sinal quando o format é alterado.

@Output() onEvent: EventEmitter;

Documentação aqui

VsFormSchema

O schema é a parte mais importante do <vs-form ... [schema]="schema"></vs-form>, é o responsável por levar as instruções iniciais para o formulário se renderizar, e também regula o comportamento. Em sua maioria é composta por instruções e parametros definidos no DxForm, logo a maior parte da documentação do vsSchema é proprío da documentação original.

Porém, para as customizações realizadas no VsForm, adiante está maiores detalhes sobre o schema.

id: number | string;

É um identificador de formulário. Não tem utilidades.

handler: VsFormHandler;

Handler é uma interface. Algumas dessas implementações só funcionam se hasSubmit for igual a true.

interface VsFormHandler {
    onAppearing?: (e: VsOnAppearing) => void;
    onAppeared?: (e: VsOnAppeared) => void;
    onSubmiting?: (e: VsOnSubmiting) => any;
    onSubmited?: (e: VsOnSubmited) => any;
    toolbar?: VsFormToolbar;
    toolbarTop?: VsFormToolbar;
    cloneToolbarOnTop?: boolean;
    cancelButton?: VsFormButton;
    saveButton?: VsFormButton;
    backButton?: VsFormButton;
    showSubmitErrorSummary?: boolean;
}

| CAMPO | DESCRIÇÃO | |---------|-------------| | onAppearing | É um evento que é disparado quando o formulário se torna visível, muito usado pelo datagrid, que gerencia o formulário. Ele é chamado depois do onInitialized (método do devextreme). O onAppearing recebe um objeto com informações do dado, component e instancia do VsFormComponent. Se quiser alterar, ou editar alguma informação dos dados pode ser aqui, usando o data, que a alteração é enviado para o formulário | | onAppeared | É um evento disparado após o formulário aparecer. Muito parecido com o onAppearing| | onSubmiting | É chamado quando hasSubmit==true. Recebe um objeto do tipo VsOnSubmiting que refere as chaves de alguma atualização no campo keys. Referencia os dados do formulário. Pode cancelar o envio de dados da datagrid com o cancel. Ele retorna um objeto dos dados enviados, ou um Promise do tipo resultado da operação. | | onSubmited | É chamado quando hasSubmit==true. Recebe um objeto do tipo VsOnSubmited que refere keys e data parecido com o onSubmiting. Refere ao campo response que é o resultado do retorno do onSubmited. E refere ao campo goToGrid que bloqueia o retorno para a datagrid, se o formulário for gerenciado pela datagrid | | toolbar | É usado quando hasSubmit==true. É o toolbar que será incluido os botões configurados em backButton, cancelButton, saveButton | | toolbarTop | Não funciona. É usado quando hasSubmit==true. Ainda tem que terminar a implementaçao. Mas seria um toolbar no topo do formulário também, igual como no bottom. | | cloneToolbarOnTop | Não funciona. É usado quando hasSubmit==true. Seria pra copiar o toolbar no bottom no topo do formulário. Ainda é necessário implementação. | | cancelButton | É usado quando hasSubmit==true. É aplicado quando o format do formulário for igual a "edit", e também tiver enabled.| | saveButton | É usado quando hasSubmit==true. É aplicado quando o format do formulário for igual a "edit", e também tiver enabled.| | backButton | É usado quando hasSubmit==true. É aplicado quando o format do formulário for igual a "readonly", e também tiver enabled. | | showSubmitErrorSummary | É usado quando hasSubmit==true. Mostra o erro de submir no summario do devextreme. Mais fácil do que fazer widget de erro de submit para formulário. |

Obs.: Os Botões tem:

  • confirmClick: boolean;
  • confirmMsg: string;

São responsáveis de confirmar ao usuário se ele tem certeza da operação. (Botões cancelButton, saveButton e cancelButton no Handler)

items: VsFormItems;

Novamente, é igual ao devextreme, só tem algumas adições para facilitar o desenvolvimento interno de algumas funcionalidades. Segue as customizações:

Todos os tipos de items tem o atributo name e dynamicOptions que logo será abordado.

Para o itemType igual a simple, o editorType tem uma nova opção, que é "vsCustomComponent", com isso o VsFormComponent liga os eventos e valores do dataField com o valor implementado no template. Leia mais em Componentes Customizados.

transform: VsTransform;

Ele aplica uma transformação no campo, e aplica css no html. // TODO: melhorar documentação

formClass: string;

Bota css na tag html.

savePartial

O savePartial é interessante. Ele salva no browser a atividade de preenchimento do formulário do usuário, se a internet cair, ou der erro, em vez do usuário perder o preenchimento que ele fez, a proxima vez que o formulário for aberto uma mensagem de recuperação de formulário entra como popup, se ele quiser todos os dados que o usuário pensou que perderia volta e o formulário é automaticamente preenchido. O problema que para formulários grandes pode dar uma travada ou outra, mas nada fora do comum.

| CAMPO | DESCRIÇÃO | |-------|-----------| | active: boolean | Ativa ou desativa a funcionalidade. Default: false | | saveas: string | Obrigatório. Nome para salvar o formulário no cache | | loadMode?: VsPartialLoadMode | Tipo de leitura, pode ser ask ou always. Caso seja o primeiro, é aberto um popup para perguntar ao usuário se ele quer recuperar os dados. O segundo ele sempre vai recuperar, e preencher automaticamente. Default: "ask" | | onOperation?: "insert" | Tipo de operação do formulário para que essa funcionarlidade funcione. Default: "insert" | | askMessage?: string | Mensagem para perguntar se gostaria de recuperar os dados. Default: "Observamos que a última inclusão não foi salva. Deseja recuperar os dados?" | | delay?: number | Tempo de delay para salvar os dados. Default: 400 |

COMPONENTES CUSTOMIZADOS

Chamamos de Componente Customizado o componente que pode entrar em um editorType: "vsCustomComponent" de um formulário. O componente tem que extender a classe abstrata e genérica VsCustomTemplateComponent<T>, sendo T o tipo do valor que seu componente assume, podendo ser um void, string, array, como até um objeto com formulário próprio.

Para instanciar um componente customizado no devextreme é necessário chamar o serviço de "ligação de nós". O VsTieCustomComponents é um serviço fornecido em root pelo vst-template. Nele existe dois métodos que devem ser usados nos atributos template dos items do devextreme.

Segue exemplo:

Implementando a classe customizada:

// FILE: endereco.component.ts
// Digamos que a classe seguinte é um componente customizado

@Component({
    ...
})
export class EnderecoComponent extends VsCustomComponent<Endereco> {
    
    ////////
    /// ...
    /// LOGICA
    /// ...
    ///////

    alterarEndereco(address) {
        // para alterar o valor e informar a árvore do devextreme. Basta fazer o seguinte:
        this.value = address;
    }

    // Esse método é usado para converter o valor iniciado pelo tiecomponentservice
    setValue(v: any) {
        if (typeof v !== "object") v = new Endereco(); // Inicializa endereço se por acaso não existe
        super.setValue(v); // Volta a inicializar normalmente o pai
    }

}

Usando a classe customizada:

// FILE: usuario.component.ts
// A CLASSE SEGUINTE EH UM CADASTRO DE USUARIO

@Component({
    ...
})
export class PerfilUsuarioComponent {

    // Segue com a definição de schema
    schema: VsFormSchema = {
        items: [
            { dataField: "name", label: {text: "Nome"}, ...},
            { dataField: "email", label: {text: "Email"}, ...},
            { dataField: "password", label: {text: "Senha"}, ...},
            // Agora queremos pedir o endereço do usuário
            { dataField: "address", label: {text: "Endereço"}, editorType: "vsCustomComponent", template: this.tie.onForm(EnderecoComponent) }, 
            // Pronto, o formulário desenvolvido dentro do componente endereço agora obedece ao formulário Perfil de Usuário
        ]
    }

    // Eh necessário pedir o servico de amarração
    constructor(private tie: VsTieCustomComponents) {}

}

Mais opções podem ser usada quando for usar this.tie.onForm, pois o método onForm recebe 3 entradas, primeiro a classe do componente, depois os inputs caso seja necessário usar o editorOptions, e também um callback que é chamado quando a classe está instanciada.

Exemplo2:

Usando a classe customizada:

// FILE: usuario.component.ts
// A CLASSE SEGUINTE EH UM CADASTRO DE USUARIO

@Component({
    ...
})
export class PerfilUsuarioComponent {

    // Segue com a definição de schema
    schema: VsFormSchema = {
        items: [
            ...
            // Agora queremos pedir o endereço do usuário.
            // Porem, quero inserir uma imagem no componente do endereço.
            // E o endereço pode ficar desabilitado enquanto o usuário ainda não digitou nem email e senha. 
            // O endereço tem um evento que ativa quando o usuário clica
            { dataField: "address", label: {text: "Endereço"}, 
                editorType: "vsCustomComponent", 
                template: this.tie.onForm(EnderecoComponent, ["disabled", "imageSrc"], (instance) => {
                    instance.someEvent.subscribe((e: any) => {
                        // DO SOMETHING
                    });
                }),
                editorOptions: {
                    imageSrc: "/assets/nome-da-imagem.jpg",
                },
                dynamicOptions: [{
                    toSet: "editorOptions.disabled",
                    value: (e) => (e.data.email && e.data.password)
                }]
            }, 
            // Pronto, o formulário desenvolvido dentro do componente endereço agora obedece ao formulário Perfil de Usuário
        ]
    }

    // Eh necessário pedir o servico de amarração
    constructor(private tie: VsTieCustomComponents) {}

}

Existe também o método onTemplate, que insere um componente em qualquer área que tem o atributo template do devextreme.

// todo: doc do onTemplate

GRADE

O básico, import { VsGridModule } from 'vst-gridform'.

O component VsFormComponent recebe apenas 4 components:

  • format: CustomTemplateFormat
  • templates: Array
  • useCssHiden: boolean = false
  • schema: VsGridSchema

e possui 3 saídas:

  • onEvent: EventEmitter
  • onFormEvent: EventEmitter
  • formatChange: EventEmitter

@Input() useCssHiden: boolean; (Default: false)

Se true insere o formulário no DOM, e gerencia usando CSS para esconder e aparecer. Caso contrário, o funcionamento padrão, trabalha com o formulário na memória. Usando useCssHiden pode demorar mais pra abrir a grid pela primeira vez, porém o formulário fica mais rápido.

@Input() format: CustomTemplateFormat; (Default: 'edit')

Como o datagrid deve ser renderizado.

@Input() templates: Array;

Templates customizados. É complicado dessa maneita. Recomendo usar o Customtemplate.

@Input('schema') schema: VsGridSchema;

Logo abaixo terá a definição do schema.

@Output() onEvent: EventEmitter;

Documentação aqui

@Output() onFormEvent: EventEmitter;

Entrega eventos que acontecem no formulário interno. Mesma definição do onEvent dentro do formulário acima.

@Output() formatChange: EventEmitter;

Emite um sinal quando o format é alterado.

VsGridSchema

O schema é a parte mais importante do <vs-grid ... [schema]="schema"></vs-grid>, é o responsável por levar as instruções iniciais para a datagrid se renderizar, e também regula o comportamento. Em sua maioria é composta por instruções e parametros definidos no DxDataGrid, logo a maior parte da documentação do VsGridSchema é proprío da documentação original.

O VsGrid tem muito menos customização que o VsForm. São apenas 3 customizações:

allowRefresh?: boolean;

Insere um botão na toolbar do datagrid. E esse botão permite ao usuário fazer refresh dos dados da tabela.

transform?: VsTransform;

Mesmo que o transform do formulário. Só que usa a transformação antes de enviar os dados para o datasurce.

gridClass?: string;

Uma classe CSS para a grade.

auxiliarDetail?: Array;

Lista de detalhes auxiliares. Para usar mais de um master details.

// toto: doc

auxiliarDetailStyle?: "tabs" | "rows" | "columns"; (Default: "rows")

Tipo de estilo em que os detalhes serão renderizados

columns[n].mask

Adição de máscara para o campo ficar visualmente melhor na datagrid.

DOC onEvent

@Output() onEvent: EventEmitter;

Emite sinais nas seguintes fases: | ENUM | DESCRIÇÃO | |------|-----------| | VsWidgetEvent.beforeInit | Dispara junto ao ngOnInit do Angular e antes do onInitialized do Devextreme. Porém esse Evento dispara antes das inicializações e configurações internas do VsWidget | | VsWidgetEvent.onInit | Dispara junto ao ngOnInit do Angular e antes do onInitialized do Devextreme. Porém esse Evento dispara depois das inicializações e configurações internas do VsWidget | | VsWidgetEvent.afterInit | Dispara junto ao ngAfterViewInit do Angular | | VsWidgetEvent.onDestroy | Dispara quando o componente entra em no processo de destruição pelo Angular | | VsWidgetEvent.hide | Quando o componente está se escondendo na tela. | | VsWidgetEvent.show | Quando o componente está aparecendo na tela. |