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
@ -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);"
|
||||
]
|
||||
}
|
||||
}
|
@ -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