mirror of https://github.com/portainer/portainer
chore(project): add angular components code snippets (#3649)
* chore(project): add angular components code snippets * chore(project): add plopjs templates * feat(project): use class in controller template * chore(client): rename generators * chore(vscode): fix controller snippets * chore(git): ignore only specific files in .vscode * chore(plop): move generators to app * chore(plop): fix portainer module * fix(git): fix gitignore vscode * chore(vscode): remove symling to code-snippets * refactor(build): move plop templates to root * feat(build): add readme for ploppull/3442/merge
parent
38066ece33
commit
766ced7cb1
|
@ -4,5 +4,7 @@ dist
|
||||||
portainer-checksum.txt
|
portainer-checksum.txt
|
||||||
api/cmd/portainer/portainer*
|
api/cmd/portainer/portainer*
|
||||||
.tmp
|
.tmp
|
||||||
.vscode
|
**/.vscode/settings.json
|
||||||
|
**/.vscode/tasks.json
|
||||||
|
|
||||||
.eslintcache
|
.eslintcache
|
|
@ -0,0 +1,162 @@
|
||||||
|
{
|
||||||
|
// Place your portainer workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
|
||||||
|
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
|
||||||
|
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
|
||||||
|
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
||||||
|
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
|
||||||
|
// Placeholders with the same ids are connected.
|
||||||
|
// Example:
|
||||||
|
// "Print to console": {
|
||||||
|
// "scope": "javascript,typescript",
|
||||||
|
// "prefix": "log",
|
||||||
|
// "body": [
|
||||||
|
// "console.log('$1');",
|
||||||
|
// "$2"
|
||||||
|
// ],
|
||||||
|
// "description": "Log output to console"
|
||||||
|
// }
|
||||||
|
"Component": {
|
||||||
|
"scope": "javascript",
|
||||||
|
"prefix": "mycomponent",
|
||||||
|
"description": "Dummy Angularjs Component",
|
||||||
|
"body": [
|
||||||
|
"import angular from 'angular';",
|
||||||
|
"import ${TM_FILENAME_BASE/(.*)/${1:/capitalize}/}Controller from './${TM_FILENAME_BASE}Controller'",
|
||||||
|
"",
|
||||||
|
"angular.module('portainer.${TM_DIRECTORY/.*\\/app\\/([^\\/]*)(\\/.*)?$/$1/}').component('$TM_FILENAME_BASE', {",
|
||||||
|
" templateUrl: './$TM_FILENAME_BASE.html',",
|
||||||
|
" controller: ${TM_FILENAME_BASE/(.*)/${1:/capitalize}/}Controller,",
|
||||||
|
"});",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Controller": {
|
||||||
|
"scope": "javascript",
|
||||||
|
"prefix": "mycontroller",
|
||||||
|
"body": [
|
||||||
|
"class ${TM_FILENAME_BASE/(.*)/${1:/capitalize}/} {",
|
||||||
|
"\t/* @ngInject */",
|
||||||
|
"\tconstructor($0) {",
|
||||||
|
"\t}",
|
||||||
|
"}",
|
||||||
|
"",
|
||||||
|
"export default ${TM_FILENAME_BASE/(.*)/${1:/capitalize}/};"
|
||||||
|
],
|
||||||
|
"description": "Dummy ES6+ controller"
|
||||||
|
},
|
||||||
|
"Model": {
|
||||||
|
"scope": "javascript",
|
||||||
|
"prefix": "mymodel",
|
||||||
|
"description": "Dummy ES6+ model",
|
||||||
|
"body": [
|
||||||
|
"/**",
|
||||||
|
" * $1 Model",
|
||||||
|
" */",
|
||||||
|
"const _$1 = Object.freeze({",
|
||||||
|
" $0",
|
||||||
|
"});",
|
||||||
|
"",
|
||||||
|
"export class $1 {",
|
||||||
|
" constructor() {",
|
||||||
|
" Object.assign(this, JSON.parse(JSON.stringify(_$1)));",
|
||||||
|
" }",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Service": {
|
||||||
|
"scope": "javascript",
|
||||||
|
"prefix": "myservice",
|
||||||
|
"description": "Dummy ES6+ service",
|
||||||
|
"body": [
|
||||||
|
"import angular from 'angular';",
|
||||||
|
"import PortainerError from 'Portainer/error';",
|
||||||
|
"",
|
||||||
|
"class $1 {",
|
||||||
|
" /* @ngInject */",
|
||||||
|
" constructor(\\$async, $0) {",
|
||||||
|
" this.\\$async = \\$async;",
|
||||||
|
"",
|
||||||
|
" this.getAsync = this.getAsync.bind(this);",
|
||||||
|
" this.getAllAsync = this.getAllAsync.bind(this);",
|
||||||
|
" this.createAsync = this.createAsync.bind(this);",
|
||||||
|
" this.updateAsync = this.updateAsync.bind(this);",
|
||||||
|
" this.deleteAsync = this.deleteAsync.bind(this);",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" /**",
|
||||||
|
" * GET",
|
||||||
|
" */",
|
||||||
|
" async getAsync() {",
|
||||||
|
" try {",
|
||||||
|
"",
|
||||||
|
" } catch (err) {",
|
||||||
|
" throw new PortainerError('', err);",
|
||||||
|
" }",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" async getAllAsync() {",
|
||||||
|
" try {",
|
||||||
|
"",
|
||||||
|
" } catch (err) {",
|
||||||
|
" throw new PortainerError('', err);",
|
||||||
|
" }",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" get() {",
|
||||||
|
" if () {",
|
||||||
|
" return this.\\$async(this.getAsync);",
|
||||||
|
" }",
|
||||||
|
" return this.\\$async(this.getAllAsync);",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" /**",
|
||||||
|
" * CREATE",
|
||||||
|
" */",
|
||||||
|
" async createAsync() {",
|
||||||
|
" try {",
|
||||||
|
"",
|
||||||
|
" } catch (err) {",
|
||||||
|
" throw new PortainerError('', err);",
|
||||||
|
" }",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" create() {",
|
||||||
|
" return this.\\$async(this.createAsync);",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" /**",
|
||||||
|
" * UPDATE",
|
||||||
|
" */",
|
||||||
|
" async updateAsync() {",
|
||||||
|
" try {",
|
||||||
|
"",
|
||||||
|
" } catch (err) {",
|
||||||
|
" throw new PortainerError('', err);",
|
||||||
|
" }",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" update() {",
|
||||||
|
" return this.\\$async(this.updateAsync);",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" /**",
|
||||||
|
" * DELETE",
|
||||||
|
" */",
|
||||||
|
" async deleteAsync() {",
|
||||||
|
" try {",
|
||||||
|
"",
|
||||||
|
" } catch (err) {",
|
||||||
|
" throw new PortainerError('', err);",
|
||||||
|
" }",
|
||||||
|
" }",
|
||||||
|
"",
|
||||||
|
" delete() {",
|
||||||
|
" return this.\\$async(this.deleteAsync);",
|
||||||
|
" }",
|
||||||
|
"}",
|
||||||
|
"",
|
||||||
|
"export default $1;",
|
||||||
|
"angular.module('portainer.${TM_DIRECTORY/.*\\/app\\/([^\\/]*)(\\/.*)?$/$1/}').service('$1', $1);"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -131,6 +131,7 @@
|
||||||
"lodash-webpack-plugin": "^0.11.5",
|
"lodash-webpack-plugin": "^0.11.5",
|
||||||
"mini-css-extract-plugin": "^0.4.4",
|
"mini-css-extract-plugin": "^0.4.4",
|
||||||
"ngtemplate-loader": "^2.0.1",
|
"ngtemplate-loader": "^2.0.1",
|
||||||
|
"plop": "^2.6.0",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"prettier": "^2.0.2",
|
"prettier": "^2.0.2",
|
||||||
"speed-measure-webpack-plugin": "^1.2.3",
|
"speed-measure-webpack-plugin": "^1.2.3",
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Plop generator
|
||||||
|
|
||||||
|
We use [plop.js](https://plopjs.com/) to generate angular components in our app (in the future we might use it for other things).
|
||||||
|
in order to create a component with the name `exampleComponent`, go in your terminal to the folder in which you want to create the component (for example, if I want to create it in the portainer module components, I'll go to `./app/portainer/components`). then execute the following line:
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn plop exampleComponent
|
||||||
|
```
|
||||||
|
|
||||||
|
this will create the following files and folders:
|
||||||
|
|
||||||
|
```
|
||||||
|
example-component/index.js - the component file
|
||||||
|
example-component/exampleComponent.html - the template file
|
||||||
|
example-component/exampleComponentController.js - the component controller file
|
||||||
|
```
|
|
@ -0,0 +1,6 @@
|
||||||
|
class {{properCase name}}Controller {
|
||||||
|
/* @ngInject */
|
||||||
|
constructor() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {{properCase name}}Controller;
|
|
@ -0,0 +1 @@
|
||||||
|
{{name}}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import {{properCase name}}Controller from './{{dashCase name}}/{{camelCase name}}Controller.js'
|
||||||
|
|
||||||
|
angular.module('portainer.{{module}}').component('{{camelCase name}}', {
|
||||||
|
templateUrl: './{{camelCase name}}.html',
|
||||||
|
controller: {{properCase name}}Controller,
|
||||||
|
});
|
|
@ -0,0 +1,46 @@
|
||||||
|
module.exports = function (plop) {
|
||||||
|
// use of INIT_CWD instead of process.cwd() because yarn changes the cwd
|
||||||
|
const cwd = process.env.INIT_CWD;
|
||||||
|
plop.addHelper('cwd', () => cwd);
|
||||||
|
plop.setGenerator('component', {
|
||||||
|
prompts: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'name',
|
||||||
|
message: 'component name please',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'module',
|
||||||
|
message: 'module name please',
|
||||||
|
default: `${getCurrentPortainerModule(cwd)}`,
|
||||||
|
// when: false
|
||||||
|
},
|
||||||
|
], // array of inquirer prompts
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'add',
|
||||||
|
path: `{{cwd}}/{{dashCase name}}/index.js`,
|
||||||
|
templateFile: './plop-templates/component.js.hbs',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'add',
|
||||||
|
path: `{{cwd}}/{{dashCase name}}/{{camelCase name}}Controller.js`,
|
||||||
|
templateFile: './plop-templates/component-controller.js.hbs',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'add',
|
||||||
|
path: `{{cwd}}/{{dashCase name}}/{{camelCase name}}.html`,
|
||||||
|
templateFile: './plop-templates/component.html.hbs',
|
||||||
|
},
|
||||||
|
], // array of actions
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function getCurrentPortainerModule(cwd) {
|
||||||
|
const match = cwd.match(/\/app\/([^\/]*)(\/.*)?$/);
|
||||||
|
if (!match || !match.length || match[1] === 'portainer') {
|
||||||
|
return 'app';
|
||||||
|
}
|
||||||
|
return match[1];
|
||||||
|
}
|
Loading…
Reference in New Issue