{"id":15134343,"url":"https://github.com/mraible/idea-live-templates","last_synced_at":"2025-05-16T12:11:08.313Z","repository":{"id":64477664,"uuid":"138767563","full_name":"mraible/idea-live-templates","owner":"mraible","description":"My IntelliJ Live Templates","archived":false,"fork":false,"pushed_at":"2024-11-02T16:06:27.000Z","size":3184,"stargazers_count":283,"open_issues_count":2,"forks_count":84,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-04-02T08:09:23.896Z","etag":null,"topics":["angular","cloud-foundry","heroku","intellij","intellij-idea","jhipster","live-templates","react","spring-boot"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mraible.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-26T16:57:53.000Z","updated_at":"2025-03-30T00:44:47.000Z","dependencies_parsed_at":"2023-12-06T21:25:35.404Z","dependency_job_id":"244aac20-c39f-4632-8052-e8be4ee81874","html_url":"https://github.com/mraible/idea-live-templates","commit_stats":{"total_commits":67,"total_committers":2,"mean_commits":33.5,"dds":"0.14925373134328357","last_synced_commit":"25e17e91dd3509d484a6da055c2b97a49a0e1393"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mraible%2Fidea-live-templates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mraible%2Fidea-live-templates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mraible%2Fidea-live-templates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mraible%2Fidea-live-templates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mraible","download_url":"https://codeload.github.com/mraible/idea-live-templates/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248018050,"owners_count":21034047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","cloud-foundry","heroku","intellij","intellij-idea","jhipster","live-templates","react","spring-boot"],"created_at":"2024-09-26T05:04:38.295Z","updated_at":"2025-04-09T10:03:23.546Z","avatar_url":"https://github.com/mraible.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"= Matt Raible's IntelliJ IDEA Live Templates\n\nThese are the https://www.jetbrains.com/help/idea/using-live-templates.html[IntelliJ IDEA Live Templates] that I've used in many demos and screencasts over the years.\n\nI used IntelliJ's https://www.jetbrains.com/help/idea/sharing-live-templates.html[sharing live templates] feature, to create `idea-settings.jar`. You should be able to import \"Matt Raible's Shortcuts\" using the following steps:\n\n1. On the **File** menu, click **Import Settings**.\n2. Specify the path to the JAR file with the exported live template configuration.\n3. In the **Import Settings** dialog box, select the **Live templates** check box and click **OK**.\n4. After restarting IntelliJ IDEA, you will see the imported live templates on the Live Templates page of the Settings / Preferences Dialog.\n\nhttps://www.jetbrains.com/idea/download/[Download IntelliJ IDEA] today! It's a spectacular IDEA for Java, Kotlin, TypeScript, JavaScript, S/CSS, and HTML.\n\nIf you'd rather not import _all_ of my templates, you can clone this project and open it in IntelliJ (with the Asciidoctor plugin installed). You should be able to edit this file and add the shortcuts below as live templates (**Tools** \u003e **Save as Live Template**). Make sure to set the file type to match the language.\n\n== Spring Boot\n\n**boot-entity**\n[source,java]\n----\n@javax.persistence.Entity\nclass $entity$ {\n\n    @javax.persistence.Id\n    @javax.persistence.GeneratedValue\n    private java.lang.Long id;\n    private java.lang.String name;\n\n    public $entity$() {}\n\n    public $entity$(String name) {\n        this.name = name;\n    }\n\n    public java.lang.Long getId() {\n        return id;\n    }\n\n    public void setId(java.lang.Long id) {\n        this.id = id;\n    }\n\n    public java.lang.String getName() {\n        return name;\n    }\n\n    public void setName(java.lang.String name) {\n        this.name = name;\n    }\n\n    @java.lang.Override\n    public java.lang.String toString() {\n        return \"$entity${\" +\n                \"id=\" + id +\n                \", name='\" + name + '\\'' +\n                '}';\n    }\n}\n----\n\n**boot-entity-lombok**\n[source,java]\n----\n@lombok.Data\n@lombok.AllArgsConstructor\n@lombok.NoArgsConstructor\n@javax.persistence.Entity\nclass $name$ {\n\n    public $name$(java.lang.String name) {\n        this.name = name;\n    }\n\n    @javax.persistence.Id\n    @javax.persistence.GeneratedValue\n    private java.lang.Long id;\n\n    private java.lang.String name;\n}\n----\n\n**boot-h2**\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.h2database\u003c/groupId\u003e\n    \u003cartifactId\u003eh2\u003c/artifactId\u003e\n\u003c/dependency\u003e\n----\n\n**boot-sql**\n[source,sql]\n----\ninsert into $entity$ (name) values ('First');\ninsert into $entity$ (name) values ('Second');\n----\n\n**boot-repository**\n[source,java]\n----\ninterface $entity$Repository extends JpaRepository\u003c$entity$, java.lang.Long\u003e {}\n----\n\n**boot-command**\n[source,java]\n----\n@org.springframework.stereotype.Component\nclass $entity$CommandLineRunner implements org.springframework.boot.CommandLineRunner {\n\n    private final $entity$Repository repository;\n\n    public $entity$CommandLineRunner($entity$Repository repository) {\n        this.repository = repository;\n    }\n\n    @java.lang.Override\n    public void run(java.lang.String... strings) throws java.lang.Exception {\n        repository.findAll().forEach(System.out::println);\n    }\n}\n----\n\n**boot-add**\n[source,java]\n----\n// Top beers from https://www.beeradvocate.com/lists/top/\nStream.of(\"Kentucky Brunch Brand Stout\", \"Good Morning\", \"Very Hazy\", \"King Julius\",\n        \"Budweiser\", \"Coors Light\", \"PBR\").forEach(name -\u003e\n        repository.save(new Beer(name))\n);\n----\n\n**boot-controller**\n[source,java]\n----\n@org.springframework.web.bind.annotation.RestController\nclass $entity$Controller {\n\n    private $entity$Repository repository;\n\n    public $entity$Controller($entity$Repository repository) {\n        this.repository = repository;\n    }\n\n    @org.springframework.web.bind.annotation.GetMapping(\"/$uriMapping$\")\n    java.util.Collection\u003c$entity$\u003e list() {\n        return repository.findAll();\n    }\n}\n----\n\n**boot-good**\n[source,java]\n----\n@GetMapping(\"/good-beers\")\npublic Collection\u003cBeer\u003e goodBeers() {\n\n    return repository.findAll().stream()\n            .filter(this::isGreat)\n            .collect(Collectors.toList());\n}\n\n    private boolean isGreat(Beer beer) {\n        return !beer.getName().equals(\"Budweiser\") \u0026\u0026\n            !beer.getName().equals(\"Coors Light\") \u0026\u0026\n            !beer.getName().equals(\"PBR\");\n    }\n----\n\n**okta-maven-boot**\n[source,xml]\n----\n \u003cdependency\u003e\n    \u003cgroupId\u003ecom.okta.spring\u003c/groupId\u003e\n    \u003cartifactId\u003eokta-spring-boot-starter\u003c/artifactId\u003e\n    \u003cversion\u003e$version$\u003c/version\u003e\n\u003c/dependency\u003e\n----\n\n**spring-oauth2-yaml**\n[source,yaml]\n----\nspring:\n  security:\n    oauth2:\n      client:\n        registration:\n          okta:\n            client-id: $clientId$\n            client-secret: $clientSecret$\n        provider:\n          okta:\n            authorization-uri: https://$yourOktaDomain$/oauth2/v1/authorize\n            token-uri: https://$yourOktaDomain$/oauth2/v1/token\n            user-info-uri: https://$yourOktaDomain$/oauth2/v1/userinfo\n            jwk-set-uri: https://$yourOktaDomain$/oauth2/v1/keys\n----\n\n**okta-oauth2**\n[source,yaml]\n----\nokta.oauth2.issuer=https://$youtOktaDomain$/oauth2/default\nokta.oauth2.clientId=$clientId$\n----\n\n**cors-filter**\n[source,java]\n----\n@org.springframework.context.annotation.Bean\npublic org.springframework.boot.web.servlet.FilterRegistrationBean simpleCorsFilter() {\n    org.springframework.web.cors.UrlBasedCorsConfigurationSource source = new org.springframework.web.cors.UrlBasedCorsConfigurationSource();\n    org.springframework.web.cors.CorsConfiguration config = new org.springframework.web.cors.CorsConfiguration();\n    config.setAllowCredentials(true);\n    config.setAllowedOrigins(java.util.Collections.singletonList(\"http://localhost:4200\"));\n    config.setAllowedMethods(java.util.Collections.singletonList(\"*\"));\n    config.setAllowedHeaders(java.util.Collections.singletonList(\"*\"));\n    source.registerCorsConfiguration(\"/**\", config);\n    org.springframework.boot.web.servlet.FilterRegistrationBean bean = new org.springframework.boot.web.servlet.FilterRegistrationBean(new org.springframework.web.filter.CorsFilter(source));\n    bean.setOrder(org.springframework.core.Ordered.HIGHEST_PRECEDENCE);\n    return bean;\n}\n----\n\n== Angular\n\n**ng-giphy-service**\n[source,typescript]\n----\nimport { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport 'rxjs/add/operator/map';\n\n@Injectable()\n// http://tutorials.pluralsight.com/front-end-javascript/getting-started-with-angular-2-by-building-a-giphy-search-application\nexport class GiphyService {\n\n  // Public beta key: https://github.com/Giphy/GiphyAPI#public-beta-key\n  giphyApi = '//api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC\u0026limit=1\u0026q=';\n\n  constructor(public http: HttpClient) {\n  }\n\n  get(searchTerm) {\n    const apiLink = this.giphyApi + searchTerm;\n    return this.http.get(apiLink).map((response: any) =\u003e {\n      if (response.data.length \u003e 0) {\n        return response.data[0].images.original.url;\n      } else {\n        return 'https://media.giphy.com/media/YaOxRsmrv9IeA/giphy.gif'; // dancing cat for 404\n      }\n    });\n  }\n}\n----\n\n**ng-giphy-foreach**\n[source,typescript]\n----\nfor (const $item$ of this.$item$s) {\n  this.giphyService.get($item$.name).subscribe(url =\u003e $item$.giphyUrl = url);\n}\n----\n\n**ng-okta-service**\n[source,typescript]\n----\nimport { Injectable } from '@angular/core';\nimport * as OktaSignIn from '@okta/okta-signin-widget/dist/js/okta-sign-in.min.js'\nimport { ReplaySubject } from 'rxjs/ReplaySubject';\nimport { Observable } from 'rxjs/Observable';\n\n@Injectable()\nexport class OktaAuthService {\n\n  signIn = new OktaSignIn({\n    baseUrl: 'https://$yourOktaDomain$',\n    clientId: '$clientId$',\n    authParams: {\n      issuer: 'https://$yourOktaDomain$',\n      responseType: ['id_token', 'token'],\n      scopes: ['openid', 'email', 'profile']\n    }\n  });\n\n  public user$: Observable\u003cany\u003e;\n  public userSource: ReplaySubject\u003cany\u003e;\n\n  constructor() {\n    this.userSource = new ReplaySubject\u003cany\u003e(1);\n    this.user$ = this.userSource.asObservable();\n  }\n\n  isAuthenticated() {\n    // Checks if there is a current accessToken in the TokenManger.\n    return !!this.signIn.tokenManager.get('accessToken');\n  }\n\n  login() {\n    // Launches the widget and stores the tokens.\n    this.signIn.renderEl({el: '#okta-signin-container'}, response =\u003e {\n      if (response.status === 'SUCCESS') {\n        response.forEach(token =\u003e {\n          if (token.idToken) {\n            this.signIn.tokenManager.add('idToken', token);\n          }\n          if (token.accessToken) {\n            this.signIn.tokenManager.add('accessToken', token);\n          }\n          this.userSource.next(this.idTokenAsUser);\n          this.signIn.hide();\n        });\n      } else {\n        console.error(response);\n      }\n    });\n  }\n\n  get idTokenAsUser() {\n    const token = this.signIn.tokenManager.get('idToken');\n    return {\n      name: token.claims.name,\n      email: token.claims.email,\n      username: token.claims.preferred_username\n    }\n  }\n\n  async logout() {\n    // Terminates the session with Okta and removes current tokens.\n    this.signIn.tokenManager.clear();\n    await this.signIn.signOut();\n    this.signIn.remove();\n    this.userSource.next(undefined);\n  }\n}\n----\n\n**ng-okta-headers**\n[source,ts]\n----\nconst headers: Headers = new Headers();\nif (this.oktaService.isAuthenticated()) {\n  const accessToken = this.oktaService.signIn.tokenManager.get('accessToken');\n  headers.append('Authorization', accessToken.tokenType + ' ' + accessToken.accessToken);\n}\nconst options = new RequestOptions({ headers: headers });\n----\n\n**ng-okta-oninit**\n[source,ts]\n----\nuser;\n\n  constructor(public oktaService: OktaAuthService, private changeDetectorRef: ChangeDetectorRef) {\n  }\n\n  ngOnInit() {\n    // 1. for initial load and browser refresh\n    if (this.oktaService.isAuthenticated()) {\n      this.user = this.oktaService.idTokenAsUser;\n    } else {\n      this.oktaService.login();\n    }\n\n    // 2. register a listener for authentication and logout\n    this.oktaService.user$.subscribe(user =\u003e {\n      this.user = user;\n      if (!user) {\n        this.oktaService.login();\n      }\n      // Let Angular know that model changed.\n      // See https://github.com/okta/okta-signin-widget/issues/268 for more info.\n      this.changeDetectorRef.detectChanges();\n    });\n  }\n----\n\n**ng-okta-login**\n[source,html]\n----\n\u003c!-- Container to inject the Sign-In Widget --\u003e\n\u003cdiv id=\"okta-signin-container\"\u003e\u003c/div\u003e\n\n\u003cdiv *ngIf=\"user\"\u003e\n  \u003ch2\u003e\n    Welcome {{user?.name}}!\n  \u003c/h2\u003e\n\n  \u003cbutton mat-raised-button (click)=\"oktaService.logout()\"\u003eLogout\u003c/button\u003e\n\u003c/div\u003e\n\u003cdiv [hidden]=\"!user\"\u003e\n  \u003capp-beer-list\u003e\u003c/app-beer-list\u003e\n\u003c/div\u003e\n----\n\n**ng-okta-css**\n[source,css]\n----\n@import '~https://ok1static.oktacdn.com/assets/js/sdk/okta-signin-widget/2.1.0/css/okta-sign-in.min.css';\n@import '~https://ok1static.oktacdn.com/assets/js/sdk/okta-signin-widget/2.1.0/css/okta-theme.css';\n----\n\n== Cloud Foundry\n\n**cf-manifest**\n[source,yaml]\n----\napplications:\n\n- name: beer-server\n  host: beer-server\n  path: ./server/target/demo-0.0.1-SNAPSHOT.jar\n  env :\n    FORCE_HTTPS: true\n\n- name: beer-client\n  host: beer-client\n  path: ./client/dist/\n  env :\n    FORCE_HTTPS: true\n----\n\n**cf-build**\n[source,yaml]\n----\n#!/bin/bash\n\n# set origin for client on server\nsed -i -e \"s|http://localhost:4200|https://beer-server.cfapps.io|g\" $start/server/src/main/java/com/okta/developer/demo/DemoApplication.java\n\nmvn clean package -f $start/server/pom.xml\n\ncd $start/client\nrm -rf dist\n# set API URL\nsed -i -e \"s|http://localhost:8080|https://beer-server.cfapps.io|g\" $start/client/src/app/shared/beer/beer.service.ts\n# set redirectURI to client URI\nsed -i -e \"s|http://localhost:4200|https://beer-client.cfapps.io|g\" $start/client/src/app/shared/okta/okta.service.ts\nyarn \u0026\u0026 ng build -prod --aot\ntouch dist/Staticfile\n# enable pushstate so no 404s on refresh\necho 'pushstate: enabled' \u003e dist/Staticfile\n\ncd $start\ncf push\n\n# reset and remove changed files\ngit checkout $start\nrm -rf $start/server/src/main/java/com/okta/developer/demo/DemoApplication.java-e\nrm -rf $start/client/src/app/shared/beer/beer.service.ts-e\nrm -rf $start/client/src/app/shared/okta/okta.service.ts-e\n----\n\n**cf-react**\n[source,bash]\n----\n#!/bin/bash\n# Warning: this script has only been tested on macOS Sierra. There's a good chance\n# it won't work on other operating systems. If you get it working on another OS,\n# please send a pull request with any changes required. Thanks!\nset -e\n\n### CloudFoundry CLI utilities\nCLOUD_DOMAIN=${DOMAIN:-run.pivotal.io}\nCLOUD_TARGET=api.${DOMAIN}\n\nfunction login(){\n    cf api | grep ${CLOUD_TARGET} || cf api ${CLOUD_TARGET} --skip-ssl-validation\n    cf apps | grep OK || cf login\n}\n\nfunction app_domain(){\n    D=`cf apps | grep $1 | tr -s ' ' | cut -d' ' -f 6 | cut -d, -f1`\n    echo $D\n}\n\nfunction deploy_service(){\n    N=$1\n    D=`app_domain $N`\n    JSON='{\"uri\":\"http://'$D'\"}'\n    cf create-user-provided-service $N -p $JSON\n}\n\n### Installation\n\ncd `dirname $0`\nr=`pwd`\necho $r\n\n## Reset\ncf d -f react-client\ncf d -f good-beer-server\n\ncf a\n\n# Deploy the server\ncd $r/server\nmvn clean package\ncf push -p target/*jar good-beer-server --no-start  --random-route\ncf set-env good-beer-server FORCE_HTTPS true\n\n# Get the URL for the server\nserverUri=https://`app_domain good-beer-server`\n\n# Deploy the client\ncd $r/client\nrm -rf build\n# replace the server URL in the client\nsed -i -e \"s|http://localhost:8080|$serverUri|g\" $r/client/src/BeerList.tsx\nyarn \u0026\u0026 yarn build\ncd build\ntouch Staticfile\necho 'pushstate: enabled' \u003e Staticfile\ncf push react-client --no-start --random-route\ncf set-env react-client FORCE_HTTPS true\ncf start react-client\n\n# Get the URL for the client\nclientUri=https://`app_domain react-client`\n\n# replace the client URL in the server\nsed -i -e \"s|http://localhost:3000|$clientUri|g\" $r/server/src/main/java/com/example/demo/DemoApplication.java\n\n# redeploy the server\ncd $r/server\nmvn package -DskipTests\ncf push -p target/*jar good-beer-server\n\n# cleanup changed files\ngit checkout $r/client\ngit checkout $r/server\nrm $r/client/src/BeerList.tsx-e\nrm $r/server/src/main/java/com/example/demo/DemoApplication.java-e\n\n# show apps and URLs\ncf apps\n----\n\n== Heroku\n\n**heroku-react**\n[source,bash]\n----\n#!/bin/bash\n# Warning: this script has only been tested on macOS Sierra. There's a good chance\n# it won't work on other operating systems. If you get it working on another OS,\n# please send a pull request with any changes required. Thanks!\nset -e\n\ncd `dirname $0`\nr=`pwd`\necho $r\n\nif [ -z \"$(which heroku)\" ]; then\n  echo \"You must install the Heroku CLI first!\"\n  echo \"https://devcenter.heroku.com/articles/heroku-cli\"\n  exit 1\nfi\n\nif ! echo \"$(heroku plugins)\" | grep -q heroku-cli-deploy; then\n  heroku plugins:install heroku-cli-deploy\nfi\n\nif ! echo \"$(git remote -v)\" | grep -q good-beer-server-; then\n  server_app=good-beer-server-$RANDOM\n  heroku create -r server $server_app\nelse\n  server_app=$(heroku apps:info -r server --json | python -c 'import json,sys;print json.load(sys.stdin)[\"app\"][\"name\"]')\nfi\nserverUri=\"https://$server_app.herokuapp.com\"\n\nif ! echo \"$(git remote -v)\" | grep -q react-client-; then\n  client_app=react-client-$RANDOM\n  heroku create -r client $client_app\nelse\n  client_app=$(heroku apps:info -r client --json | python -c 'import json,sys;print json.load(sys.stdin)[\"app\"][\"name\"]')\nfi\nclientUri=\"https://$client_app.herokuapp.com\"\n\n# replace the client URL in the server\nsed -i -e \"s|http://localhost:3000|$clientUri|g\" $r/server/src/main/java/com/example/demo/DemoApplication.java\n\n# Deploy the server\ncd $r/server\nmvn clean package -DskipTests\n\nheroku deploy:jar target/*jar -r server -o \"--server.port=\\$PORT\"\nheroku config:set -r server FORCE_HTTPS=\"true\"\n\n# Deploy the client\ncd $r/client\nrm -rf build\n# replace the server URL in the client\nsed -i -e \"s|http://localhost:8080|$serverUri|g\" $r/client/src/BeerList.tsx\nyarn \u0026\u0026 yarn build\ncd build\n\ncat \u003c\u003c EOF \u003e static.json\n{\n  \"https_only\": true,\n  \"root\": \".\",\n  \"routes\": {\n    \"/**\": \"index.html\"\n  }\n}\nEOF\n\nrm -f ../dist.tgz\ntar -zcvf ../dist.tgz .\n\n# TODO replace this with the heroku-cli-static command `heroku static:deploy`\nsource=$(curl -n -X POST https://api.heroku.com/apps/$client_app/sources -H 'Accept: application/vnd.heroku+json; version=3')\nget_url=$(echo \"$source\" | python -c 'import json,sys;print json.load(sys.stdin)[\"source_blob\"][\"get_url\"]')\nput_url=$(echo \"$source\" | python -c 'import json,sys;print json.load(sys.stdin)[\"source_blob\"][\"put_url\"]')\ncurl \"$put_url\" -X PUT -H 'Content-Type:' --data-binary @../dist.tgz\ncat \u003c\u003c EOF \u003e build.json\n{\n  \"buildpacks\": [{ \"url\": \"https://github.com/heroku/heroku-buildpack-static\" }],\n  \"source_blob\": { \"url\" : \"$get_url\" }\n}\nEOF\nbuild_out=$(curl -n -s -X POST https://api.heroku.com/apps/$client_app/builds \\\n  -d \"$(cat build.json)\" \\\n  -H 'Accept: application/vnd.heroku+json; version=3' \\\n  -H \"Content-Type: application/json\")\noutput_stream_url=$(echo \"$build_out\" | python -c 'import json,sys;print json.load(sys.stdin)[\"output_stream_url\"]')\ncurl -s -L \"$output_stream_url\"\n\nrm build.json\nrm ../dist.tgz\n\n# cleanup changed files\ngit checkout $r/client\ngit checkout $r/server\nrm $r/client/src/BeerList.tsx-e\nrm $r/server/src/main/java/com/example/demo/DemoApplication.java-e\n\n# show apps and URLs\nheroku open -r client\n----\n\n== JHipster\n\n**jh-findBy**\n[source,java]\n----\nfindByBlogUserLoginOrderByDateDesc(\n            org.jhipster.blog.security.SecurityUtils.getCurrentUserLogin().orElse(null), pageable);\n----\n\n**jh-get**\n[source,ts]\n----\nif (blog.isPresent() \u0026\u0026 blog.get().getUser() != null \u0026\u0026\n    !blog.get().getUser().getLogin().equals(org.jhipster.blog.security.SecurityUtils.getCurrentUserLogin().orElse(\"\"))) {\n    return new org.springframework.http.ResponseEntity\u003c\u003e(\"Unauthorized\", org.springframework.http.HttpStatus.UNAUTHORIZED);\n}\n----\n\n**jh-entries**\n[source,html]\n----\n\u003cdiv class=\"table-responsive\" *ngIf=\"entries\"\u003e\n    \u003cdiv infinite-scroll (scrolled)=\"loadPage(page + 1)\" [infiniteScrollDisabled]=\"page \u003e= links['last']\" [infiniteScrollDistance]=\"0\"\u003e\n        \u003cdiv *ngFor=\"let entry of entries; trackBy: trackId\"\u003e\n            \u003ch2\u003e{{entry.title}}\u003c/h2\u003e\n            \u003csmall\u003ePosted on {{entry.date | date: 'short'}} by {{entry.blog.user.login}}\u003c/small\u003e\n            \u003cdiv [innerHTML]=\"entry.content\"\u003e\u003c/div\u003e\n            \u003cdiv class=\"btn-group mb-2 mt-1\"\u003e\n                \u003cbutton type=\"submit\"\n                        [routerLink]=\"['/entry', entry.id, 'edit']\"\n                        class=\"btn btn-primary btn-sm\"\u003e\n                    \u003cfa-icon [icon]=\"'pencil-alt'\"\u003e\u003c/fa-icon\u003e\n                    \u003cspan class=\"d-none d-md-inline\" jhiTranslate=\"entity.action.edit\"\u003eEdit\u003c/span\u003e\n                \u003c/button\u003e\n                \u003cbutton type=\"submit\"\n                        [routerLink]=\"['/', { outlets: { popup: 'entry/'+ entry.id + '/delete'} }]\"\n                        replaceUrl=\"true\"\n                        queryParamsHandling=\"merge\"\n                        class=\"btn btn-danger btn-sm\"\u003e\n                    \u003cfa-icon [icon]=\"'times'\"\u003e\u003c/fa-icon\u003e\n                    \u003cspan class=\"d-none d-md-inline\" jhiTranslate=\"entity.action.delete\"\u003eDelete\u003c/span\u003e\n                \u003c/button\u003e\n            \u003c/div\u003e\n        \u003c/div\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n----\n\n== React\n\n**okta-react-config**\n[source,ts]\n----\nconst config = {\n  issuer: 'https://$yourOktaDomain$/oauth2/default',\n  redirectUri: window.location.origin + '/implicit/callback',\n  clientId: '$clientId$'\n};\n\nexport interface Auth {\n  login(): {};\n  logout(): {};\n  isAuthenticated(): boolean;\n  getAccessToken(): string;\n}\n----\n\n**okta-react-render**\n[source,ts]\n----\nrender() {\n  return (\n    \u003cRouter\u003e\n      \u003cSecurity\n        issuer={config.issuer}\n        client_id={config.clientId}\n        redirect_uri={config.redirectUri}\n      \u003e\n        \u003cRoute path=\"/\" exact={true} component={Home}/\u003e\n        \u003cRoute path=\"/implicit/callback\" component={ImplicitCallback}/\u003e\n      \u003c/Security\u003e\n    \u003c/Router\u003e\n  );\n}\n----\n\n**okta-react-home**\n[source,ts]\n----\nimport * as React from 'react';\nimport './App.css';\nimport BeerList from './BeerList';\nimport { withAuth } from '@okta/okta-react';\nimport { Auth } from './App';\n\nconst logo = require('./logo.svg');\n\ninterface HomeProps {\n  auth: Auth;\n}\n\ninterface HomeState {\n  authenticated: boolean;\n}\n\nexport default withAuth(class Home extends React.Component\u003cHomeProps, HomeState\u003e {\n  constructor(props: HomeProps) {\n    super(props);\n    this.state = {authenticated: false};\n    this.checkAuthentication = this.checkAuthentication.bind(this);\n    this.checkAuthentication();\n  }\n\n  async checkAuthentication() {\n    const isAuthenticated = await this.props.auth.isAuthenticated();\n    const {authenticated} = this.state;\n    if (isAuthenticated !== authenticated) {\n      this.setState({authenticated: isAuthenticated});\n    }\n  }\n\n  componentDidUpdate() {\n    this.checkAuthentication();\n  }\n\n  render() {\n    const {authenticated} = this.state;\n    let body = null;\n    if (authenticated) {\n      body = (\n        \u003cdiv className=\"Buttons\"\u003e\n          \u003cbutton onClick={this.props.auth.logout}\u003eLogout\u003c/button\u003e\n          \u003cBeerList auth={this.props.auth}/\u003e\n        \u003c/div\u003e\n      );\n    } else {\n      body = (\n        \u003cdiv className=\"Buttons\"\u003e\n          \u003cbutton onClick={this.props.auth.login}\u003eLogin\u003c/button\u003e\n        \u003c/div\u003e\n      );\n    }\n\n    return (\n      \u003cdiv className=\"App\"\u003e\n        \u003cdiv className=\"App-header\"\u003e\n          \u003cimg src={logo} className=\"App-logo\" alt=\"logo\"/\u003e\n          \u003ch2\u003eWelcome to React\u003c/h2\u003e\n        \u003c/div\u003e\n        {body}\n      \u003c/div\u003e\n    );\n  }\n});\n----\n\n**okta-react-token**\n[source,ts]\n----\nasync componentDidMount() {\n  this.setState({isLoading: true});\n\n  const response = await fetch('http://localhost:8080/good-beers', {\n    headers: {\n      Authorization: 'Bearer ' + await this.props.auth.getAccessToken()\n    }\n  });\n  const data = await response.json();\n  this.setState({beers: data, isLoading: false});\n}\n----\n\n== Contributing\n\nWant to add more? Have you figured out how to import live templates? Send a pull request!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmraible%2Fidea-live-templates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmraible%2Fidea-live-templates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmraible%2Fidea-live-templates/lists"}