Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
This repository was archived by the owner on Jul 18, 2023. It is now read-only.
/CrudPublic archive

CRUD PORTO Containers for apiato and Angular2 modules generator, based on Laravel 5.4 and Angular 2.4+

License

NotificationsYou must be signed in to change notification settings

llstarscreamll/Crud

Repository files navigation

This is aPORTO Container forapiato 4.0.2 to scaffold you applications, at the moment the package generates the API stuff only, and generates an Angular 2+ module that consumes the generated container API. There is a lot of work to do, pull requests are very welcome!! ^_^

If you don't know apiato already, go to theapiato DOCS site and give it a try, it's an amazing project!!

NOTE:This container is tested onLaravel Homestead, so I sugest you to use Homestead as your development environment.

Install

From the apiato root folder:

git clone https://github.com/llstarscreamll/Crud.git app/Containers/Crud# this will add some Codeception helpers and criterias on Ship folderphp artisan vendor:publish --provider="App\Containers\Crud\Providers\MainServiceProvider" --tag=classescomposer update

If you have foreign keys on your table, the generated transformer will try to hash that foreign keys with this method that you must put inApp\Ship\Parents\Transformers\Transformer abstract class:

publicfunctionhashKey($id)    {if (config('apiato.hash-id')) {return Hashids::encode($id);        }return$id;    }

If you will use theSelectListFrom{Entity} endpoint, add this method onApp\Ship\Parents\Repositories\Repository:

/**     * Return model list to be used on selects. The $key and $value parameters     * says what the array item keys names should be. Example with $key = 'id'     * and $value = 'label':     * [     *     [ 'id' => 1, 'label' => 'Foo' ],     *     [ 'id' => 2, 'label' => 'Bar' ],     * ]     *     * @param  string $key     * @param  string $value     * @return array     */publicfunctionselectList(string$key ='id',string$value ='text')    {return$this->model            ->orderBy('name')            ->get(['id','name'])            ->map(function ($item)use($key,$value) {return [$key =>$item->getHashedKey(),$value =>$item->name,// add more info for you convinience, if any                ];            })->all();    }

Usage

Let's suppose that we want to create a container calledLibrary that will managebooks data, so let's create that container folder and the migration file:

# from the apiato root foldermkdir -p app/Containers/Library/Data/Migrationsphp artisan make:migration create_books_table --create=books --path=app/Containers/Library/Data/Migrations

Next we add some columns to that migration table and run the migration:

php artisan migrate

Since this package useCodeception to generate the CRUD app test suit, youMUST bootstrap and generate the api suit for your container:

# from the apiato root foldercodecept bootstrap --namespace=Library app/Containers/Library/codecept g:suit api -c app/Containers/Library/

Now you can go toapiato.dev/crud to start configuring your CRUD container/module.

NOTE: the codeception stuff is required to run once per container, from here you can add more migration tables without setup codecept again.

After you have generated your container/module, you should run the generated tests to make shure that the generated code it's ok:

# from the apiato root foldercodecept build -c app/Containers/Library/# required each time you generate CRUD for newly created tablecodecept run -c app/Containers/Library/phpcbf app/Containers/Library/ --standard=PEAR,PSR1,PSR2# optional, run any Code Beautifier you preffer# from the Hello-Angular root folderng tests

What is Generated?

Here are a quick overview of the generated folders/files to give you the big idea of what is generated from a package namedLibrary with an migration table calledbooks, off course not a real life example, just have different kind of fields to prove some functionalities, this example is taking from the functional tests,check the up to date final generated code for this example in theCrudExample folder. So with the following setup:

CRUD Setup GUI

The generated code will be:

apiato 4.0.2 Container

The generated container intends to follow thePORTO architectural pattern. A small difference with theapiato containers is that tests are generated withCodeception unlessphpunit, these tests arenamespaced with the container name. The generated API has some end points useful to work with the generated Angular module forms, e.g. serving a entity "Form Model/Select List" to build forms from server without update the Angular module, and have an entity list array to be used on select dropdowns (like some DB users list or something else). Obviosly the form builder on the Angular side is providen by theHello-Angular project, the generated Angular module fits very well withHello-Angular, but you can use it on your own main Angular project, just make sure to satisfy the dependencies from the generated module.

|─── Library    ├── Actions    │   └── Book    │       ├── CreateBookAction.php    │       ├── DeleteBookAction.php    │       ├── GetBookAction.php    │       ├── ListAndSearchBooksAction.php    │       ├── RestoreBookAction.php    │       ├── SelectListFromBookAction.php    │       └── UpdateBookAction.php    ├── composer.json    ├── Configs    │   └── book-form-model.php    ├── Data    │   ├── Criterias    │   │   └── AdvancedBookSearchCriteria.php    │   ├── Factories    │   │   └── BookFactory.php    │   ├── Migrations    │   ├── Repositories    │   │   └── BookRepository.php    │   └── Seeders    │       └── BookPermissionsSeeder.php    ├── Exceptions    │   ├── BookCreationFailedException.php    │   └── BookNotFoundException.php    ├── Models    │   └── Book.php    ├── Tasks    │   └── Book    │       ├── CreateBookTask.php    │       ├── DeleteBookTask.php    │       ├── GetBookTask.php    │       ├── ListAndSearchBooksTask.php    │       ├── RestoreBookTask.php    │       └── UpdateBookTask.php    ├── tests    │   ├── acceptance    │   │   └── _bootstrap.php    │   ├── acceptance.suite.yml    │   ├── api    │   │   ├── Book    │   │   │   ├── BookFormModelCest.php    │   │   │   ├── CreateBookCest.php    │   │   │   ├── DeleteBookCest.php    │   │   │   ├── GetBookCest.php    │   │   │   ├── ListAndSearchBooksCest.php    │   │   │   ├── RestoreBookCest.php    │   │   │   ├── SelectListFromBookCest.php    │   │   │   └── UpdateBookCest.php    │   │   └── _bootstrap.php    │   ├── api.suite.yml    │   ├── _bootstrap.php    │   ├── _data    │   │   └── dump.sql    │   ├── _envs    │   ├── functional    │   │   └── _bootstrap.php    │   ├── functional.suite.yml    │   ├── _output    │   ├── _support    │   │   ├── AcceptanceTester.php    │   │   ├── ApiTester.php    │   │   ├── FunctionalTester.php    │   │   ├── _generated    │   │   │   ├── AcceptanceTesterActions.php    │   │   │   ├── FunctionalTesterActions.php    │   │   │   └── UnitTesterActions.php    │   │   ├── Helper    │   │   │   ├── Acceptance.php    │   │   │   ├── Api.php    │   │   │   ├── Functional.php    │   │   │   ├── LibraryHelper.php    │   │   │   └── Unit.php    │   │   └── UnitTester.php    │   ├── unit    │   │   └── _bootstrap.php    │   └── unit.suite.yml    └── UI        └── API            ├── Controllers            │   └── BookController.php            ├── Requests            │   └── Book            │       ├── CreateBookRequest.php            │       ├── DeleteBookRequest.php            │       ├── FormModelFromBookRequest.php            │       ├── GetBookRequest.php            │       ├── ListAndSearchBooksRequest.php            │       ├── RestoreBookRequest.php            │       ├── SelectListFromBookRequest.php            │       └── UpdateBookRequest.php            ├── Routes            │   ├── CreateBook.v1.private.php            │   ├── DeleteBook.v1.private.php            │   ├── FormModelFromBook.v1.private.php            │   ├── GetBook.v1.private.php            │   ├── ListAndSearchBooks.v1.private.php            │   ├── RestoreBook.v1.private.php            │   ├── SelectListFromBook.v1.private.php            │   └── UpdateBook.v1.private.php            └── Transformers                └── BookTransformer.php

If you don't want the main classes to be grouped on entity folders (e.g. Actions\Book\CreateBookAction), just leave unchecked theGroup main apiato classes? on the GUI.

You should run the generated tests executing this command inside of the container to make sure that all is ok:

codecept run api

Angular Module

NOTE:To generate your Angular module you must have the respective generated apiato Container first. Why? Because the generator create fake data with the generated container factories on the Angular module tests.

This module is intended to work with thisHello-Angular application, when the generated module is placed in theHello-Angular app (or your Angular app), then you must declare the module on the main modules arraysrc/app/modules.ts file and reducers on thesrc/app/reducers.ts file, the reducers to be copied are commented on the generatedentity.reducers.ts file to make things easy, following theLibrary/books exampĺe, said reducers should look something like this:

/* -----------------------------------------------------------------------------Don't forget to import these reducer on the main app reducer!!import * as fromBook from './library/reducers/book.reducer';export interface State {  book: fromBook.State;}const reducers = {  book: fromBook.reducer,};// Book selectorsexport const getBookState = (state: State) => state.book;export const getBookSearchQuery = createSelector(getBookState, fromBook.getSearchQuery);export const getBookFormModel = createSelector(getBookState, fromBook.getFormModel);export const getBookFormData = createSelector(  getReasonList,  getUserList,  (    Reasons,    Users,  ) => ({    Reasons,    Users,  }));export const getBookList = createSelector(getBookState, fromBook.getItemsList);export const getBooksPagination = createSelector(getBookState, fromBook.getItemsPagination);export const getSelectedBook = createSelector(getBookState, fromBook.getSelectedItem);export const getBookLoading = createSelector(getBookState, fromBook.getLoading);export const getBookMessages = createSelector(getBookState, fromBook.getMessages);----------------------------------------------------------------------------- */

The generated module intends to follow all the best practices on the Angular world based on thengrx example app,Yatrum and many other resources. Some libraries used on the generated code are:

  • @ngrx/store
  • @ngrx/effects
  • @ngrx/router-store
  • ReactiveForms
  • @ngx-translate/core
  • ngx-bootstrap
  • etc...

The generated Angular module has many tests, you should execute these tests to ensure that everything is working as intendet by runningng test.

├── library    ├── actions    │   └── book.actions.ts    ├── components    │   ├── book    │   │   ├── book-abstract.component.ts    │   │   ├── book-form.component.html    │   │   ├── book-form.component.spec.ts    │   │   ├── book-form.component.ts    │   │   ├── book-search-advanced.component.html    │   │   ├── book-search-advanced.component.spec.ts    │   │   ├── book-search-advanced.component.ts    │   │   ├── book-search-basic.component.html    │   │   ├── book-search-basic.component.spec.ts    │   │   ├── book-search-basic.component.ts    │   │   ├── books-table.component.html    │   │   ├── books-table.component.spec.ts    │   │   ├── books-table.component.ts    │   │   └── index.ts    │   └── index.ts    ├── effects    │   ├── book.effects.ts    │   └── index.ts    ├── library.module.ts    ├── library-routing.module.ts    ├── models    │   ├── bookPagination.ts    │   └── book.ts    ├── pages    │   ├── book    │   │   ├── book-abstract.page.ts    │   │   ├── book-form.page.html    │   │   ├── book-form.page.spec.ts    │   │   ├── book-form.page.ts    │   │   ├── index.ts    │   │   ├── list-and-search-books.page.html    │   │   ├── list-and-search-books.page.spec.ts    │   │   └── list-and-search-books.page.ts    │   └── index.ts    ├── reducers    │   └── book.reducer.ts    ├── routes    │   ├── book.routes.ts    │   └── index.ts    ├── services    │   ├── book.service.ts    │   └── index.ts    ├── translations    │   └── es    │       ├── book.ts    │       └── index.ts    └── utils        └── book-testing.util.ts

Tests

To execute this packages tests, you will need a file named.env.mysql.testing on your root folder like this:

APP_ENV=testingAPP_DEBUG=trueAPP_NAME="apiato"APP_URL=http://apiato.devAPI_URL=http://apiato.devAPP_KEY=generatedKeyUSER_NAMESPACE=App\Containers\User\Models\DB_CONNECTION=mysqlDB_HOST=localhostDB_PORT=3306DB_DATABASE=testDB_USERNAME=homesteadDB_PASSWORD=secret

Now go to the packageapp/Containers/Crud folder and execute:

codecept run functional

[8]ページ先頭

©2009-2025 Movatter.jp