├── .dockerignore ├── src ├── main │ ├── resources │ │ ├── META-INF │ │ │ └── resources │ │ │ │ ├── robots.txt │ │ │ │ ├── assets │ │ │ │ ├── index.js │ │ │ │ └── logo.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── favicon.png │ │ │ │ ├── e90b6873f455f0560c2a2eeae2dbc955.png │ │ │ │ ├── css │ │ │ │ ├── README.md │ │ │ │ ├── spinner.css │ │ │ │ ├── base.css │ │ │ │ └── index.css │ │ │ │ ├── manifest.json │ │ │ │ ├── index.html │ │ │ │ ├── 0.bundle.js.map │ │ │ │ ├── 1.bundle.js.map │ │ │ │ ├── 2.bundle.js.map │ │ │ │ ├── 0.bundle.js │ │ │ │ ├── 1.bundle.js │ │ │ │ └── 2.bundle.js │ │ └── application.properties.template │ ├── docker │ │ ├── Dockerfile.native │ │ └── Dockerfile.jvm │ └── java │ │ └── com │ │ └── sestevez │ │ ├── cql │ │ └── AstraDemoCQL.java │ │ └── todo │ │ ├── api │ │ └── Todo.java │ │ └── AstraTODO.java └── test │ └── java │ └── com │ └── sestevez │ ├── NativeAstraDemoCQLIT.java │ └── AstraDemoCQLTest.java ├── Quarkus+Astra.pdf ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── .gitignore ├── devfile.yaml ├── README.md ├── pom.xml ├── mvnw.cmd └── mvnw /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /api 3 | 4 | -------------------------------------------------------------------------------- /Quarkus+Astra.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/demo-astra-java-quarkus/main/Quarkus+Astra.pdf -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/assets/index.js: -------------------------------------------------------------------------------- 1 | import logo from './logo.png'; 2 | export const Logo = logo; 3 | 4 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/demo-astra-java-quarkus/main/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/demo-astra-java-quarkus/main/src/main/resources/META-INF/resources/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/demo-astra-java-quarkus/main/src/main/resources/META-INF/resources/favicon.png -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/demo-astra-java-quarkus/main/src/main/resources/META-INF/resources/assets/logo.png -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/e90b6873f455f0560c2a2eeae2dbc955.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/demo-astra-java-quarkus/main/src/main/resources/META-INF/resources/e90b6873f455f0560c2a2eeae2dbc955.png -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /src/test/java/com/sestevez/NativeAstraDemoCQLIT.java: -------------------------------------------------------------------------------- 1 | package com.sestevez; 2 | 3 | import io.quarkus.test.junit.NativeImageTest; 4 | 5 | @NativeImageTest 6 | public class NativeAstraDemoCQLIT extends AstraDemoCQLTest { 7 | 8 | // Execute the same tests but in native mode. 9 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/css/README.md: -------------------------------------------------------------------------------- 1 | The following files in this directory were taken from TodoMVC project: 2 | 3 | - base.css 4 | - index.css 5 | 6 | https://github.com/tastejs/todomvc 7 | 8 | Following files are taken from http://tobiasahlin.com/spinkit/ 9 | 10 | - spinner.css 11 | -------------------------------------------------------------------------------- /src/main/resources/application.properties.template: -------------------------------------------------------------------------------- 1 | # Configuration file 2 | # key = value 3 | quarkus.cassandra.cloud.secure-connect-bundle=/home/tato/Downloads/secure-connect-serverlessdb.zip 4 | # Authentication 5 | quarkus.cassandra.auth.username=token 6 | quarkus.cassandra.auth.password=AstraCS:REPLACE_ME:REPLACE_ME 7 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Sample App", 3 | "name": "Sample app", 4 | "icons": [ 5 | { 6 | "src": "favicon.png", 7 | "type": "image/png" 8 | } 9 | ], 10 | "start_url": "./index.html", 11 | "display": "standalone", 12 | "theme_color": "#000000", 13 | "background_color": "#ffffff" 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .project 3 | .classpath 4 | .settings/ 5 | bin/ 6 | 7 | # IntelliJ 8 | .idea 9 | *.ipr 10 | *.iml 11 | *.iws 12 | 13 | # NetBeans 14 | nb-configuration.xml 15 | 16 | # Visual Studio Code 17 | .vscode 18 | .factorypath 19 | 20 | # OSX 21 | .DS_Store 22 | 23 | # Vim 24 | *.swp 25 | *.swo 26 | 27 | # patch 28 | *.orig 29 | *.rej 30 | 31 | # Maven 32 | target/ 33 | pom.xml.tag 34 | pom.xml.releaseBackup 35 | pom.xml.versionsBackup 36 | release.properties 37 | 38 | application.properties 39 | -------------------------------------------------------------------------------- /src/test/java/com/sestevez/AstraDemoCQLTest.java: -------------------------------------------------------------------------------- 1 | package com.sestevez; 2 | 3 | import io.quarkus.test.junit.QuarkusTest; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static io.restassured.RestAssured.given; 7 | import static org.hamcrest.CoreMatchers.is; 8 | 9 | @QuarkusTest 10 | public class AstraDemoCQLTest { 11 | 12 | @Test 13 | public void testHelloEndpoint() { 14 | given() 15 | .when().get("/hello") 16 | .then() 17 | .statusCode(200) 18 | .body(is("hello")); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode 3 | # 4 | # Before building the docker image run: 5 | # 6 | # mvn package -Pnative -Dquarkus.native.container-build=true 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/my-artifactId . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/my-artifactId 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1 18 | WORKDIR /work/ 19 | COPY --chown=1001:root target/*-runner /work/application 20 | 21 | EXPOSE 8080 22 | USER 1001 23 | 24 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] -------------------------------------------------------------------------------- /src/main/java/com/sestevez/cql/AstraDemoCQL.java: -------------------------------------------------------------------------------- 1 | package com.sestevez.cql; 2 | 3 | import javax.inject.Inject; 4 | import javax.ws.rs.GET; 5 | import javax.ws.rs.Path; 6 | import javax.ws.rs.Produces; 7 | import javax.ws.rs.core.MediaType; 8 | 9 | import com.datastax.oss.driver.api.core.cql.ResultSet; 10 | import com.datastax.oss.driver.api.core.cql.Row; 11 | import com.datastax.oss.quarkus.runtime.api.session.QuarkusCqlSession; 12 | import io.smallrye.common.annotation.Blocking; 13 | 14 | @Path("/hello") 15 | public class AstraDemoCQL { 16 | @Inject 17 | QuarkusCqlSession cqlSession; 18 | 19 | @GET 20 | @Produces(MediaType.TEXT_PLAIN) 21 | @Blocking 22 | public String hello() { 23 | ResultSet rs = this.cqlSession 24 | .execute("SELECT data_center FROM system.local"); 25 | 26 | Row row = rs.one(); 27 | String version = row.getFormattedContents(); 28 | return "hello " + version; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/sestevez/todo/api/Todo.java: -------------------------------------------------------------------------------- 1 | package com.sestevez.todo.api; 2 | 3 | import io.quarkus.runtime.annotations.RegisterForReflection; 4 | 5 | @RegisterForReflection 6 | public class Todo { 7 | private String id; 8 | private String title; 9 | private boolean completed; 10 | 11 | public Todo() { 12 | } 13 | 14 | public Todo(String id, String title, boolean completed) { 15 | this.id = id; 16 | this.title = title; 17 | this.completed = completed; 18 | } 19 | 20 | public String getId() { 21 | return this.id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getTitle() { 29 | return this.title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title; 34 | } 35 | 36 | public boolean isCompleted() { 37 | return this.completed; 38 | } 39 | 40 | public void setCompleted(boolean completed) { 41 | this.completed = completed; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/css/spinner.css: -------------------------------------------------------------------------------- 1 | .spinner { 2 | width: 30px; 3 | height: 30px; 4 | background-color: red; 5 | 6 | margin: 100px auto; 7 | -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out; 8 | animation: sk-rotateplane 1.2s infinite ease-in-out; 9 | } 10 | 11 | @-webkit-keyframes sk-rotateplane { 12 | 0% { -webkit-transform: perspective(120px) } 13 | 50% { -webkit-transform: perspective(120px) rotateY(180deg) } 14 | 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } 15 | } 16 | 17 | @keyframes sk-rotateplane { 18 | 0% { 19 | transform: perspective(120px) rotateX(0deg) rotateY(0deg); 20 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg) 21 | } 50% { 22 | transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); 23 | -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg) 24 | } 100% { 25 | transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 26 | -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 27 | } 28 | } -------------------------------------------------------------------------------- /devfile.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: 1.0.0 2 | metadata: 3 | name: quarkus-astra-demos 4 | projects: 5 | - name: quarkus-astra-demos 6 | source: 7 | location: 'https://github.com/phact/quarkus-astra-demos' 8 | type: git 9 | branch: main 10 | components: 11 | - id: redhat/quarkus-java11/latest 12 | type: chePlugin 13 | - mountSources: true 14 | endpoints: 15 | - name: quarkus-astra-todo 16 | port: 8080 17 | memoryLimit: 1024Mi 18 | type: dockerimage 19 | volumes: 20 | - name: m2 21 | containerPath: /home/jboss/.m2 22 | alias: quarkus-astra-todo 23 | image: 'registry.redhat.io/codeready-workspaces/plugin-java11-rhel8:latest' 24 | env: 25 | - value: '-XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Djava.security.egd=file:/dev/./urandom -Duser.home=/home/jboss' 26 | name: JAVA_OPTS 27 | - value: $(JAVA_OPTS) 28 | name: MAVEN_OPTS 29 | commands: 30 | - name: Quarkus Live Coding 31 | actions: 32 | - workdir: '${CHE_PROJECTS_ROOT}/quarkus-astra-demos' 33 | type: exec 34 | command: './mvnw quarkus:dev -Dquarkus.http.host=0.0.0.0' 35 | component: quarkus-astra-todo 36 | - name: Build native image 37 | actions: 38 | - workdir: '${CHE_PROJECTS_ROOT}/quarkus-astra-demos' 39 | type: exec 40 | command: './mvnw clean package -Pnative -DskipTests' 41 | component: quarkus-astra-todo 42 | - name: Attach remote debugger 43 | actions: 44 | - referenceContent: | 45 | { 46 | "version": "0.2.0", 47 | "configurations": [ 48 | { 49 | "type": "java", 50 | "request": "attach", 51 | "name": "Attach to Remote App", 52 | "hostName": "localhost", 53 | "port": 5005 54 | } 55 | ] 56 | } 57 | type: vscode-launch 58 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Astra • ReactJS • Serverless • Todo Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
{{thing}}
22 | 28 | 29 | Fork me on GitHub 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/docker/Dockerfile.jvm: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode 3 | # 4 | # Before building the docker image run: 5 | # 6 | # mvn package 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.jvm -t quarkus/my-artifactId-jvm . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/my-artifactId-jvm 15 | # 16 | # If you want to include the debug port into your docker image 17 | # you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050 18 | # 19 | # Then run the container using : 20 | # 21 | # docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/my-artifactId-jvm 22 | # 23 | ### 24 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1 25 | 26 | ARG JAVA_PACKAGE=java-11-openjdk-headless 27 | ARG RUN_JAVA_VERSION=1.3.8 28 | 29 | ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' 30 | 31 | # Install java and the run-java script 32 | # Also set up permissions for user `1001` 33 | RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ 34 | && microdnf update \ 35 | && microdnf clean all \ 36 | && mkdir /deployments \ 37 | && chown 1001 /deployments \ 38 | && chmod "g+rwX" /deployments \ 39 | && chown 1001:root /deployments \ 40 | && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ 41 | && chown 1001 /deployments/run-java.sh \ 42 | && chmod 540 /deployments/run-java.sh \ 43 | && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security 44 | 45 | # Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. 46 | ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" 47 | 48 | COPY target/lib/* /deployments/lib/ 49 | COPY target/*-runner.jar /deployments/app.jar 50 | 51 | EXPOSE 8080 52 | USER 1001 53 | 54 | ENTRYPOINT [ "/deployments/run-java.sh" ] -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/css/base.css: -------------------------------------------------------------------------------- 1 | hr { 2 | margin: 20px 0; 3 | border: 0; 4 | border-top: 1px dashed #c5c5c5; 5 | border-bottom: 1px dashed #f7f7f7; 6 | } 7 | 8 | .learn a { 9 | font-weight: normal; 10 | text-decoration: none; 11 | color: #b83f45; 12 | } 13 | 14 | .learn a:hover { 15 | text-decoration: underline; 16 | color: #787e7e; 17 | } 18 | 19 | .learn h3, 20 | .learn h4, 21 | .learn h5 { 22 | margin: 10px 0; 23 | font-weight: 500; 24 | line-height: 1.2; 25 | color: #000; 26 | } 27 | 28 | .learn h3 { 29 | font-size: 24px; 30 | } 31 | 32 | .learn h4 { 33 | font-size: 18px; 34 | } 35 | 36 | .learn h5 { 37 | margin-bottom: 0; 38 | font-size: 14px; 39 | } 40 | 41 | .learn ul { 42 | padding: 0; 43 | margin: 0 0 30px 25px; 44 | } 45 | 46 | .learn li { 47 | line-height: 20px; 48 | } 49 | 50 | .learn p { 51 | font-size: 15px; 52 | font-weight: 300; 53 | line-height: 1.3; 54 | margin-top: 0; 55 | margin-bottom: 0; 56 | } 57 | 58 | #issue-count { 59 | display: none; 60 | } 61 | 62 | .quote { 63 | border: none; 64 | margin: 20px 0 60px 0; 65 | } 66 | 67 | .quote p { 68 | font-style: italic; 69 | } 70 | 71 | .quote p:before { 72 | content: '“'; 73 | font-size: 50px; 74 | opacity: .15; 75 | position: absolute; 76 | top: -20px; 77 | left: 3px; 78 | } 79 | 80 | .quote p:after { 81 | content: '”'; 82 | font-size: 50px; 83 | opacity: .15; 84 | position: absolute; 85 | bottom: -42px; 86 | right: 3px; 87 | } 88 | 89 | .quote footer { 90 | position: absolute; 91 | bottom: -40px; 92 | right: 0; 93 | } 94 | 95 | .quote footer img { 96 | border-radius: 3px; 97 | } 98 | 99 | .quote footer a { 100 | margin-left: 5px; 101 | vertical-align: middle; 102 | } 103 | 104 | .speech-bubble { 105 | position: relative; 106 | padding: 10px; 107 | background: rgba(0, 0, 0, .04); 108 | border-radius: 5px; 109 | } 110 | 111 | .speech-bubble:after { 112 | content: ''; 113 | position: absolute; 114 | top: 100%; 115 | right: 30px; 116 | border: 13px solid transparent; 117 | border-top-color: rgba(0, 0, 0, .04); 118 | } 119 | 120 | .learn-bar > .learn { 121 | position: absolute; 122 | width: 272px; 123 | top: 8px; 124 | left: -300px; 125 | padding: 10px; 126 | border-radius: 5px; 127 | background-color: rgba(255, 255, 255, .6); 128 | transition-property: left; 129 | transition-duration: 500ms; 130 | } 131 | 132 | @media (min-width: 899px) { 133 | .learn-bar { 134 | width: auto; 135 | padding-left: 300px; 136 | } 137 | 138 | .learn-bar > .learn { 139 | left: 8px; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/com/sestevez/todo/AstraTODO.java: -------------------------------------------------------------------------------- 1 | package com.sestevez.todo; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import javax.enterprise.context.ApplicationScoped; 7 | import javax.enterprise.event.Observes; 8 | import javax.inject.Inject; 9 | import javax.ws.rs.*; 10 | import javax.ws.rs.core.MediaType; 11 | import javax.ws.rs.core.Response; 12 | 13 | import com.datastax.oss.driver.api.core.cql.BoundStatement; 14 | import com.datastax.oss.driver.api.core.cql.PreparedStatement; 15 | import com.datastax.oss.driver.api.core.cql.ResultSet; 16 | import com.datastax.oss.driver.api.core.cql.Row; 17 | import com.datastax.oss.quarkus.runtime.api.session.QuarkusCqlSession; 18 | import com.sestevez.todo.api.Todo; 19 | import io.quarkus.runtime.StartupEvent; 20 | import io.smallrye.common.annotation.Blocking; 21 | 22 | @ApplicationScoped 23 | @Path("/api") 24 | public class AstraTODO { 25 | @Inject 26 | QuarkusCqlSession cqlSession; 27 | 28 | private String keyspaceName = "free"; 29 | private String tableName = "todolist"; 30 | 31 | public boolean onStart(@Observes StartupEvent ev){ 32 | ResultSet rs = this.cqlSession.execute("CREATE TABLE IF NOT EXISTS " + this.keyspaceName+"." + this.tableName + "(list_id text, id text, title text, completed boolean, PRIMARY KEY(list_id, id));"); 33 | System.out.println("**** Table created " + rs.wasApplied() + "****"); 34 | return rs.wasApplied(); 35 | } 36 | 37 | @GET 38 | @Produces(MediaType.APPLICATION_JSON) 39 | @Path("/todo/{list_id}") 40 | @Blocking 41 | public List getTodos(@PathParam("list_id") String list_id) { 42 | ResultSet rs = this.cqlSession 43 | .execute("SELECT * FROM " + this.keyspaceName + "." + this.tableName + " where list_id =?", list_id); 44 | 45 | List rows = rs.all(); 46 | return rows.stream() 47 | .map(x -> new Todo(x.getString("id"), x.getString("title"), x.getBoolean("completed"))) 48 | .collect(Collectors.toList()); 49 | } 50 | 51 | @POST 52 | @Produces(MediaType.APPLICATION_JSON) 53 | @Consumes(MediaType.APPLICATION_JSON) 54 | @Path("/todo/{list_id}") 55 | @Blocking 56 | public Response setTodo(@PathParam("list_id") String list_id, Todo todo) { 57 | ResultSet rs = this.cqlSession 58 | .execute("INSERT INTO " + this.keyspaceName + "." + this.tableName + 59 | "(list_id, id, title, completed) VALUES (?,?,?,?)", 60 | list_id, todo.getId(), todo.getTitle(), todo.isCompleted()); 61 | 62 | boolean successful = rs.wasApplied(); 63 | if (successful) { 64 | return Response.ok().build(); 65 | }else{ 66 | return Response.serverError().build(); 67 | } 68 | 69 | } 70 | 71 | @DELETE 72 | @Produces(MediaType.APPLICATION_JSON) 73 | @Path("/todo/{list_id}/{id}") 74 | @Blocking 75 | public boolean getTodos(@PathParam("list_id") String list_id, @PathParam("id") String id){ 76 | ResultSet rs = this.cqlSession.execute("DELETE FROM " + this.keyspaceName + "." + 77 | this.tableName + " WHERE list_id = ? AND id = ?",list_id, id); 78 | 79 | return rs.wasApplied(); 80 | } 81 | 82 | @POST 83 | @Produces(MediaType.APPLICATION_JSON) 84 | @Path("/todo/{list_id}/{id}") 85 | @Blocking 86 | public boolean completeTodo(@PathParam("list_id") String list_id, @PathParam("id") String id) { 87 | 88 | ResultSet rs = this.cqlSession.execute("INSERT INTO " + this.keyspaceName + 89 | "." + this.tableName + " (id, list_id, completed) VALUES (?, ?, ?)", id, list_id, true); 90 | 91 | return rs.wasApplied(); 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # quarkus-astra-demo 2 | 3 | **`ASTRA`** is the simplest way to run Cassandra with zero operations at all - just push the button and get your cluster. No credit card required, $25.00 USD credit every month, roughly 5M writes, 30M reads, 40GB storage monthly - sufficient to run small production workloads. 4 | 5 | To use this project: 6 | 7 | ✅ Clone the repo 8 | 9 | ✅ Register (if needed) and Sign In to Astra [https://astra.datastax.com](https://dtsx.io/workshop): You can use your `Github`, `Google` accounts or register with an `email`. 10 | 11 | _Make sure to chose a password with minimum 8 characters, containing upper and lowercase letters, at least one number and special character_ 12 | 13 | ✅ Create a "pay as you go" plan 14 | 15 | Follow this [guide](https://docs.datastax.com/en/astra/docs/creating-your-astra-database.html), to set up a pay as you go database with a free $25 monthly credit. 16 | 17 | - **Select the pay as you go option**: Includes $25 monthly credit - no credit card needed to set up. 18 | 19 | You will find below which values to enter for each field. 20 | 21 | - **For the database name** - `free_db.` While Astra allows you to fill in these fields with values of your own choosing, please follow our recommendations to ensure the application runs properly. 22 | 23 | - **For the keyspace name** - `free`. It's really important that you use the name "free" for the code to work. 24 | 25 | _You can technically use whatever you want and update the code to reflect the keyspace. This is really to get you on a happy path for the first run._ 26 | 27 | - **For provider and region**: Choose and provider (either GCP or AWS). Region is where your database will reside physically (choose one close to you or your users). 28 | 29 | - **Create the database**. Review all the fields to make sure they are as shown, and click the `Create Database` button. 30 | 31 | You will see your new database `pending` in the Dashboard. 32 | 33 | ![my-pic](https://github.com/datastaxdevs/shared-assets/blob/master/astra/dashboard-pending-1000-update.png?raw=true) 34 | 35 | The status will change to `Active` when the database is ready, this will only take 2-3 minutes. You will also receive an email when it is ready. 36 | 37 | ✅ [Download your secure connect bundle](https://docs.datastax.com/en/astra/docs/obtaining-database-credentials.html) from the connect screen 38 | 39 | ✅ [Create a token for your app](https://docs.datastax.com/en/astra/docs/manage-application-tokens.html) to use in the settings screen 40 | 41 | ✅ Create and populate your application.properties file: 42 | 43 | cp ./src/main/resources/application.properties.template ./src/main/resources/application.properties 44 | 45 | ✅ Replace the following lines to point at your scb and with your token: 46 | 47 | quarkus.cassandra.cloud.secure-connect-bundle=<> 48 | quarkus.cassandra.auth.password=AstraCS:<> 49 | 50 | If you prefer to stub out the code yourself, pull the `puzzle` branch instead and give it a try. This `main` branch has the required endpoints stubbed out. 51 | 52 | This project uses Quarkus, the Supersonic Subatomic Java Framework. 53 | 54 | If you want to learn more about Quarkus, please visit the website: https://quarkus.io/ 55 | 56 | ## Running the application in dev mode 57 | 58 | You can run your application in dev mode that enables live coding using: 59 | ``` 60 | ./mvnw clean quarkus:dev 61 | ``` 62 | 63 | 📗 **Expected output** 64 | ![quarkus dev output](https://user-images.githubusercontent.com/23346205/110409249-f9b61500-8054-11eb-8f73-b366a5a0e045.png) 65 | 66 | 67 | Once the application is running navigate to [http://localhost:8080](http://localhost:8080). 68 | 69 | ![localhost 8080](https://user-images.githubusercontent.com/23346205/110409508-64ffe700-8055-11eb-93bd-cd4b78d03f95.png) 70 | 71 | 72 | ## Packaging and running the application 73 | 74 | The application can be packaged using `./mvnw package`. 75 | It produces the `quarkus-run.jar` file in the `/target/quarkus-app` directory. 76 | Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib` directory. 77 | 78 | The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`. 79 | 80 | ## Creating a native executable 81 | 82 | You can create a native executable using: `./mvnw package -Pnative`. 83 | 84 | Or, if you don't have GraalVM installed, you can run the native executable build in a container using: `./mvnw package -Pnative -Dquarkus.native.container-build=true`. 85 | 86 | > Make sure you have a container runtime (docker/podman/etc) installed 87 | 88 | You can then execute your native executable with: `./target/quarkus-astra-demo-0.01-runner` 89 | 90 | If you want to learn more about building native executables, please consult https://quarkus.io/guides/building-native-image. 91 | 92 | ## Running on Red Hat Developer Sandbox 93 | Run this application on the free [Red Hat Developer Sandbox](https://developers.redhat.com/developer-sandbox). All you need to do is create an account and then [click here](https://workspaces.openshift.com/f?url=https://github.com/phact/quarkus-astra-demos/tree/todo) to load the workspace! 94 | -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | quarkus-astra-demo 6 | quarkus-astra-demo 7 | 0.01 8 | 9 | 3.8.1 10 | true 11 | 11 12 | 11 13 | UTF-8 14 | UTF-8 15 | 1.12.1.Final 16 | quarkus-universe-bom 17 | io.quarkus 18 | 1.12.1.Final 19 | 3.0.0-M5 20 | 21 | 22 | 23 | 24 | ${quarkus.platform.group-id} 25 | ${quarkus.platform.artifact-id} 26 | ${quarkus.platform.version} 27 | pom 28 | import 29 | 30 | 31 | 32 | 33 | 34 | io.quarkus 35 | quarkus-resteasy-reactive 36 | 37 | 38 | io.quarkus 39 | quarkus-resteasy-reactive-jackson 40 | 41 | 42 | com.datastax.oss.quarkus 43 | cassandra-quarkus-client 44 | 45 | 46 | com.datastax.oss 47 | java-driver-mapper-runtime 48 | 4.7.2 49 | 50 | 51 | io.quarkus 52 | quarkus-micrometer 53 | 54 | 55 | io.quarkus 56 | quarkus-micrometer-registry-prometheus 57 | 58 | 59 | io.quarkus 60 | quarkus-smallrye-openapi 61 | 62 | 63 | io.quarkus 64 | quarkus-smallrye-health 65 | 66 | 67 | io.quarkus 68 | quarkus-junit5 69 | test 70 | 71 | 72 | io.rest-assured 73 | rest-assured 74 | test 75 | 76 | 77 | 78 | 79 | 80 | io.quarkus 81 | quarkus-maven-plugin 82 | ${quarkus-plugin.version} 83 | true 84 | 85 | 86 | 87 | build 88 | generate-code 89 | generate-code-tests 90 | 91 | 92 | 93 | 94 | 95 | maven-compiler-plugin 96 | ${compiler-plugin.version} 97 | 98 | 99 | 100 | com.datastax.oss 101 | java-driver-mapper-processor 102 | 4.7.2 103 | 104 | 105 | 106 | 107 | 108 | maven-surefire-plugin 109 | ${surefire-plugin.version} 110 | 111 | 112 | org.jboss.logmanager.LogManager 113 | ${maven.home} 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | native 122 | 123 | 124 | native 125 | 126 | 127 | 128 | 129 | 130 | maven-failsafe-plugin 131 | ${surefire-plugin.version} 132 | 133 | 134 | 135 | integration-test 136 | verify 137 | 138 | 139 | 140 | ${project.build.directory}/${project.build.finalName}-runner 141 | org.jboss.logmanager.LogManager 142 | ${maven.home} 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | native 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/0.bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/all-todos.jsx","webpack:///./src/todoItem.jsx","webpack:///./src/todoList.jsx"],"names":["AllTodos","props","ESCAPE_KEY","ENTER_KEY","TodoItem","state","editText","todo","title","handleEdit","bind","handleSubmit","handleKeyDown","handleChange","nextProps","nextState","editing","prevProps","node","ReactDOM","findDOMNode","refs","editField","focus","setSelectionRange","value","length","val","trim","onSave","setState","onDestroy","onEdit","event","which","onCancel","target","classNames","completed","onToggle","React","Component","TodoList","todoItems","todos","map","id","text"],"mappings":"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","file":"0.bundle.js","sourcesContent":["import React from 'react';\nimport TodoList from './todoList';\n\nexport default function AllTodos(props) {\n return ;\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport classNames from 'classnames';\n\nconst ESCAPE_KEY = 27;\nconst ENTER_KEY = 13;\n\nexport default class TodoItem extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n editText: props.todo.title,\n };\n this.handleEdit = this.handleEdit.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n\n /**\n * This is a completely optional performance enhancement that you can\n * implement on any React component. If you were to delete this method\n * the app would still work correctly (and still be very performant!), we\n * just use it as an example of how little code it takes to get an order\n * of magnitude performance improvement.\n */\n shouldComponentUpdate(nextProps, nextState) {\n return (\n nextProps.todo !== this.props.todo ||\n nextProps.editing !== this.props.editing ||\n nextState.editText !== this.state.editText\n );\n }\n\n /**\n * Safely manipulate the DOM after updating the state when invoking\n * `this.props.onEdit()` in the `handleEdit` method above.\n * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate\n * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate\n */\n componentDidUpdate(prevProps) {\n if (!prevProps.editing && this.props.editing) {\n const node = ReactDOM.findDOMNode(this.refs.editField);\n node.focus();\n node.setSelectionRange(node.value.length, node.value.length);\n }\n }\n\n handleSubmit() {\n const val = this.state.editText.trim();\n if (val) {\n this.props.onSave(val);\n this.setState({ editText: val });\n } else {\n this.props.onDestroy();\n }\n }\n\n handleEdit() {\n this.props.onEdit();\n this.setState({ editText: this.props.todo.title });\n }\n\n handleKeyDown(event) {\n if (event.which === ESCAPE_KEY) {\n this.setState({ editText: this.props.todo.title });\n this.props.onCancel(event);\n } else if (event.which === ENTER_KEY) {\n this.handleSubmit(event);\n }\n }\n\n handleChange(event) {\n if (this.props.editing) {\n this.setState({ editText: event.target.value });\n }\n }\n\n render() {\n return (\n
  • \n
    \n \n \n
    \n \n
  • \n );\n }\n}\n","import React from 'react';\nimport TodoItem from './todoItem';\n\nexport default function TodoList(props) {\n const todoItems = props.todos.map(todo => (\n { props.onToggle(todo); }}\n onDestroy={() => { props.onDestroy(todo); }}\n onEdit={() => { props.onEdit(todo); }}\n editing={props.editing(todo)}\n onSave={(text) => { props.onSave(todo, text); }}\n onCancel={() => { props.onCancel(); }}\n />\n ));\n\n return (\n
    \n {todoItems}\n
    \n );\n}\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/1.bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/active-todos.jsx","webpack:///./src/todoItem.jsx","webpack:///./src/todoList.jsx"],"names":["ActiveTodos","todos","props","filteredTodos","filter","todo","completed","ESCAPE_KEY","ENTER_KEY","TodoItem","state","editText","title","handleEdit","bind","handleSubmit","handleKeyDown","handleChange","nextProps","nextState","editing","prevProps","node","ReactDOM","findDOMNode","refs","editField","focus","setSelectionRange","value","length","val","trim","onSave","setState","onDestroy","onEdit","event","which","onCancel","target","classNames","onToggle","React","Component","TodoList","todoItems","map","id","text"],"mappings":"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","file":"1.bundle.js","sourcesContent":["import React from 'react';\nimport TodoList from './todoList';\n\nexport default function ActiveTodos({ todos, ...props }) {\n const filteredTodos = todos.filter(todo => !todo.completed);\n return ;\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport classNames from 'classnames';\n\nconst ESCAPE_KEY = 27;\nconst ENTER_KEY = 13;\n\nexport default class TodoItem extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n editText: props.todo.title,\n };\n this.handleEdit = this.handleEdit.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n\n /**\n * This is a completely optional performance enhancement that you can\n * implement on any React component. If you were to delete this method\n * the app would still work correctly (and still be very performant!), we\n * just use it as an example of how little code it takes to get an order\n * of magnitude performance improvement.\n */\n shouldComponentUpdate(nextProps, nextState) {\n return (\n nextProps.todo !== this.props.todo ||\n nextProps.editing !== this.props.editing ||\n nextState.editText !== this.state.editText\n );\n }\n\n /**\n * Safely manipulate the DOM after updating the state when invoking\n * `this.props.onEdit()` in the `handleEdit` method above.\n * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate\n * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate\n */\n componentDidUpdate(prevProps) {\n if (!prevProps.editing && this.props.editing) {\n const node = ReactDOM.findDOMNode(this.refs.editField);\n node.focus();\n node.setSelectionRange(node.value.length, node.value.length);\n }\n }\n\n handleSubmit() {\n const val = this.state.editText.trim();\n if (val) {\n this.props.onSave(val);\n this.setState({ editText: val });\n } else {\n this.props.onDestroy();\n }\n }\n\n handleEdit() {\n this.props.onEdit();\n this.setState({ editText: this.props.todo.title });\n }\n\n handleKeyDown(event) {\n if (event.which === ESCAPE_KEY) {\n this.setState({ editText: this.props.todo.title });\n this.props.onCancel(event);\n } else if (event.which === ENTER_KEY) {\n this.handleSubmit(event);\n }\n }\n\n handleChange(event) {\n if (this.props.editing) {\n this.setState({ editText: event.target.value });\n }\n }\n\n render() {\n return (\n
  • \n
    \n \n \n
    \n \n
  • \n );\n }\n}\n","import React from 'react';\nimport TodoItem from './todoItem';\n\nexport default function TodoList(props) {\n const todoItems = props.todos.map(todo => (\n { props.onToggle(todo); }}\n onDestroy={() => { props.onDestroy(todo); }}\n onEdit={() => { props.onEdit(todo); }}\n editing={props.editing(todo)}\n onSave={(text) => { props.onSave(todo, text); }}\n onCancel={() => { props.onCancel(); }}\n />\n ));\n\n return (\n
    \n {todoItems}\n
    \n );\n}\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/2.bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/completed-todos.jsx","webpack:///./src/todoItem.jsx","webpack:///./src/todoList.jsx"],"names":["ActiveTodos","todos","props","filteredTodos","filter","todo","completed","ESCAPE_KEY","ENTER_KEY","TodoItem","state","editText","title","handleEdit","bind","handleSubmit","handleKeyDown","handleChange","nextProps","nextState","editing","prevProps","node","ReactDOM","findDOMNode","refs","editField","focus","setSelectionRange","value","length","val","trim","onSave","setState","onDestroy","onEdit","event","which","onCancel","target","classNames","onToggle","React","Component","TodoList","todoItems","map","id","text"],"mappings":"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","file":"2.bundle.js","sourcesContent":["import React from 'react';\nimport TodoList from './todoList';\n\nexport default function ActiveTodos({ todos, ...props }) {\n const filteredTodos = todos.filter(todo => todo.completed);\n return ;\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport classNames from 'classnames';\n\nconst ESCAPE_KEY = 27;\nconst ENTER_KEY = 13;\n\nexport default class TodoItem extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n editText: props.todo.title,\n };\n this.handleEdit = this.handleEdit.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n\n /**\n * This is a completely optional performance enhancement that you can\n * implement on any React component. If you were to delete this method\n * the app would still work correctly (and still be very performant!), we\n * just use it as an example of how little code it takes to get an order\n * of magnitude performance improvement.\n */\n shouldComponentUpdate(nextProps, nextState) {\n return (\n nextProps.todo !== this.props.todo ||\n nextProps.editing !== this.props.editing ||\n nextState.editText !== this.state.editText\n );\n }\n\n /**\n * Safely manipulate the DOM after updating the state when invoking\n * `this.props.onEdit()` in the `handleEdit` method above.\n * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate\n * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate\n */\n componentDidUpdate(prevProps) {\n if (!prevProps.editing && this.props.editing) {\n const node = ReactDOM.findDOMNode(this.refs.editField);\n node.focus();\n node.setSelectionRange(node.value.length, node.value.length);\n }\n }\n\n handleSubmit() {\n const val = this.state.editText.trim();\n if (val) {\n this.props.onSave(val);\n this.setState({ editText: val });\n } else {\n this.props.onDestroy();\n }\n }\n\n handleEdit() {\n this.props.onEdit();\n this.setState({ editText: this.props.todo.title });\n }\n\n handleKeyDown(event) {\n if (event.which === ESCAPE_KEY) {\n this.setState({ editText: this.props.todo.title });\n this.props.onCancel(event);\n } else if (event.which === ENTER_KEY) {\n this.handleSubmit(event);\n }\n }\n\n handleChange(event) {\n if (this.props.editing) {\n this.setState({ editText: event.target.value });\n }\n }\n\n render() {\n return (\n
  • \n
    \n \n \n
    \n \n
  • \n );\n }\n}\n","import React from 'react';\nimport TodoItem from './todoItem';\n\nexport default function TodoList(props) {\n const todoItems = props.todos.map(todo => (\n { props.onToggle(todo); }}\n onDestroy={() => { props.onDestroy(todo); }}\n onEdit={() => { props.onEdit(todo); }}\n editing={props.editing(todo)}\n onSave={(text) => { props.onSave(todo, text); }}\n onCancel={() => { props.onCancel(); }}\n />\n ));\n\n return (\n
    \n {todoItems}\n
    \n );\n}\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/css/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | button { 8 | margin: 0; 9 | padding: 0; 10 | border: 0; 11 | background: none; 12 | font-size: 100%; 13 | vertical-align: baseline; 14 | font-family: inherit; 15 | font-weight: inherit; 16 | color: inherit; 17 | -webkit-appearance: none; 18 | appearance: none; 19 | -webkit-font-smoothing: antialiased; 20 | -moz-font-smoothing: antialiased; 21 | font-smoothing: antialiased; 22 | } 23 | 24 | body { 25 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; 26 | line-height: 1.4em; 27 | background: #f5f5f5; 28 | color: #4d4d4d; 29 | min-width: 230px; 30 | max-width: 550px; 31 | margin: 0 auto; 32 | -webkit-font-smoothing: antialiased; 33 | -moz-font-smoothing: antialiased; 34 | font-smoothing: antialiased; 35 | font-weight: 300; 36 | } 37 | 38 | button, 39 | input[type="checkbox"] { 40 | outline: none; 41 | } 42 | 43 | .hidden { 44 | display: none; 45 | } 46 | 47 | .todoapp { 48 | background: #fff; 49 | margin: 130px 0 40px 0; 50 | position: relative; 51 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 52 | 0 25px 50px 0 rgba(0, 0, 0, 0.1); 53 | } 54 | 55 | .todoapp input::-webkit-input-placeholder { 56 | font-style: italic; 57 | font-weight: 300; 58 | color: #e6e6e6; 59 | } 60 | 61 | .todoapp input::-moz-placeholder { 62 | font-style: italic; 63 | font-weight: 300; 64 | color: #e6e6e6; 65 | } 66 | 67 | .todoapp input::input-placeholder { 68 | font-style: italic; 69 | font-weight: 300; 70 | color: #e6e6e6; 71 | } 72 | 73 | .todoapp h1 { 74 | position: absolute; 75 | top: -185px; 76 | width: 100%; 77 | font-size: 80px; 78 | font-weight: 100; 79 | text-align: center; 80 | color: rgba(175, 47, 47, 0.15); 81 | -webkit-text-rendering: optimizeLegibility; 82 | -moz-text-rendering: optimizeLegibility; 83 | text-rendering: optimizeLegibility; 84 | } 85 | 86 | .todoapp h1:before { 87 | font-size: 0.3em; 88 | color: #606060; 89 | content: "serverless"; 90 | position: absolute; 91 | top: 0em; 92 | right: 2em; 93 | } 94 | 95 | .new-todo, 96 | .edit { 97 | position: relative; 98 | margin: 0; 99 | width: 100%; 100 | font-size: 24px; 101 | font-family: inherit; 102 | font-weight: inherit; 103 | line-height: 1.4em; 104 | border: 0; 105 | outline: none; 106 | color: inherit; 107 | padding: 6px; 108 | border: 1px solid #999; 109 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); 110 | box-sizing: border-box; 111 | -webkit-font-smoothing: antialiased; 112 | -moz-font-smoothing: antialiased; 113 | font-smoothing: antialiased; 114 | } 115 | 116 | .new-todo { 117 | padding: 16px 16px 16px 60px; 118 | border: none; 119 | background: rgba(0, 0, 0, 0.003); 120 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); 121 | } 122 | 123 | .main { 124 | position: relative; 125 | z-index: 2; 126 | border-top: 1px solid #e6e6e6; 127 | } 128 | 129 | label[for='toggle-all'] { 130 | display: none; 131 | } 132 | 133 | .toggle-all { 134 | position: absolute; 135 | top: -55px; 136 | left: -12px; 137 | width: 60px; 138 | height: 34px; 139 | text-align: center; 140 | border: none; /* Mobile Safari */ 141 | } 142 | 143 | .toggle-all:before { 144 | content: '❯'; 145 | font-size: 22px; 146 | color: #e6e6e6; 147 | padding: 10px 27px 10px 27px; 148 | } 149 | 150 | .toggle-all:checked:before { 151 | color: #737373; 152 | } 153 | 154 | .todo-list { 155 | margin: 0; 156 | padding: 0; 157 | list-style: none; 158 | } 159 | 160 | .todo-list li { 161 | position: relative; 162 | font-size: 24px; 163 | border-bottom: 1px solid #ededed; 164 | } 165 | 166 | .todo-list li:last-child { 167 | border-bottom: none; 168 | } 169 | 170 | .todo-list li.editing { 171 | border-bottom: none; 172 | padding: 0; 173 | } 174 | 175 | .todo-list li.editing .edit { 176 | display: block; 177 | width: 506px; 178 | padding: 13px 17px 12px 17px; 179 | margin: 0 0 0 43px; 180 | } 181 | 182 | .todo-list li.editing .view { 183 | display: none; 184 | } 185 | 186 | .todo-list li .toggle { 187 | text-align: center; 188 | width: 40px; 189 | /* auto, since non-WebKit browsers doesn't support input styling */ 190 | height: auto; 191 | position: absolute; 192 | top: 0; 193 | bottom: 0; 194 | margin: auto 0; 195 | border: none; /* Mobile Safari */ 196 | -webkit-appearance: none; 197 | appearance: none; 198 | } 199 | 200 | .todo-list li .toggle:after { 201 | content: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); 202 | } 203 | 204 | .todo-list li .toggle:checked:after { 205 | content: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); 206 | } 207 | 208 | .todo-list li label { 209 | white-space: pre-line; 210 | word-break: break-all; 211 | padding: 15px 60px 15px 15px; 212 | margin-left: 45px; 213 | display: block; 214 | line-height: 1.2; 215 | transition: color 0.4s; 216 | } 217 | 218 | .todo-list li.completed label { 219 | color: #d9d9d9; 220 | text-decoration: line-through; 221 | } 222 | 223 | .todo-list li .destroy { 224 | display: none; 225 | position: absolute; 226 | top: 0; 227 | right: 10px; 228 | bottom: 0; 229 | width: 40px; 230 | height: 40px; 231 | margin: auto 0; 232 | font-size: 30px; 233 | color: #cc9a9a; 234 | margin-bottom: 11px; 235 | transition: color 0.2s ease-out; 236 | } 237 | 238 | .todo-list li .destroy:hover { 239 | color: #af5b5e; 240 | } 241 | 242 | .todo-list li .destroy:after { 243 | content: '×'; 244 | } 245 | 246 | .todo-list li:hover .destroy { 247 | display: block; 248 | } 249 | 250 | .todo-list li .edit { 251 | display: none; 252 | } 253 | 254 | .todo-list li.editing:last-child { 255 | margin-bottom: -1px; 256 | } 257 | 258 | .footer { 259 | color: #777; 260 | padding: 10px 15px; 261 | height: 20px; 262 | text-align: center; 263 | border-top: 1px solid #e6e6e6; 264 | } 265 | 266 | .footer:before { 267 | content: ''; 268 | position: absolute; 269 | right: 0; 270 | bottom: 0; 271 | left: 0; 272 | height: 50px; 273 | overflow: hidden; 274 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 275 | 0 8px 0 -3px #f6f6f6, 276 | 0 9px 1px -3px rgba(0, 0, 0, 0.2), 277 | 0 16px 0 -6px #f6f6f6, 278 | 0 17px 2px -6px rgba(0, 0, 0, 0.2); 279 | } 280 | 281 | 282 | .session { 283 | margin: 65px auto 0; 284 | color: #bfbfbf; 285 | font-size: 18px; 286 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); 287 | text-align: center; 288 | } 289 | 290 | .session a { 291 | color: rgba(175, 47, 47, 0.90); 292 | text-decoration: none; 293 | font-weight: 400; 294 | } 295 | 296 | .session a:hover { 297 | text-decoration: underline; 298 | } 299 | 300 | 301 | .todo-count { 302 | float: left; 303 | text-align: left; 304 | } 305 | 306 | .todo-count strong { 307 | font-weight: 300; 308 | } 309 | 310 | .filters { 311 | margin: 0; 312 | padding: 0; 313 | list-style: none; 314 | position: absolute; 315 | right: 0; 316 | left: 0; 317 | } 318 | 319 | .filters li { 320 | display: inline; 321 | } 322 | 323 | .filters li a { 324 | color: inherit; 325 | margin: 3px; 326 | padding: 3px 7px; 327 | text-decoration: none; 328 | border: 1px solid transparent; 329 | border-radius: 3px; 330 | } 331 | 332 | .filters li a.selected, 333 | .filters li a:hover { 334 | border-color: rgba(175, 47, 47, 0.1); 335 | } 336 | 337 | .filters li a.selected { 338 | border-color: rgba(175, 47, 47, 0.2); 339 | } 340 | 341 | .clear-completed, 342 | html .clear-completed:active { 343 | float: right; 344 | position: relative; 345 | line-height: 20px; 346 | text-decoration: none; 347 | cursor: pointer; 348 | position: relative; 349 | } 350 | 351 | .clear-completed:hover { 352 | text-decoration: underline; 353 | } 354 | 355 | .info { 356 | margin: 65px auto 0; 357 | color: #bfbfbf; 358 | font-size: 10px; 359 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); 360 | text-align: center; 361 | } 362 | 363 | .info p { 364 | line-height: 1; 365 | } 366 | 367 | .info a { 368 | color: inherit; 369 | text-decoration: none; 370 | font-weight: 400; 371 | } 372 | 373 | .info a:hover { 374 | text-decoration: underline; 375 | } 376 | 377 | /* 378 | Hack to remove background from Mobile Safari. 379 | Can't use it globally since it destroys checkboxes in Firefox 380 | */ 381 | @media screen and (-webkit-min-device-pixel-ratio:0) { 382 | .toggle-all, 383 | .todo-list li .toggle { 384 | background: none; 385 | } 386 | 387 | .todo-list li .toggle { 388 | height: 40px; 389 | } 390 | 391 | .toggle-all { 392 | -webkit-transform: rotate(90deg); 393 | transform: rotate(90deg); 394 | -webkit-appearance: none; 395 | appearance: none; 396 | } 397 | } 398 | 399 | @media (max-width: 430px) { 400 | .footer { 401 | height: 50px; 402 | } 403 | 404 | .filters { 405 | bottom: 10px; 406 | } 407 | } 408 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/0.bundle.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{ 2 | 3 | /***/ "./src/all-todos.jsx": 4 | /*!***************************!*\ 5 | !*** ./src/all-todos.jsx ***! 6 | \***************************/ 7 | /*! exports provided: default */ 8 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 9 | 10 | "use strict"; 11 | __webpack_require__.r(__webpack_exports__); 12 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AllTodos; }); 13 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 14 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 15 | /* harmony import */ var _todoList__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./todoList */ "./src/todoList.jsx"); 16 | 17 | 18 | function AllTodos(props) { 19 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_todoList__WEBPACK_IMPORTED_MODULE_1__["default"], props); 20 | } 21 | 22 | /***/ }), 23 | 24 | /***/ "./src/todoItem.jsx": 25 | /*!**************************!*\ 26 | !*** ./src/todoItem.jsx ***! 27 | \**************************/ 28 | /*! exports provided: default */ 29 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 30 | 31 | "use strict"; 32 | __webpack_require__.r(__webpack_exports__); 33 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TodoItem; }); 34 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 35 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 36 | /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js"); 37 | /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__); 38 | /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! classnames */ "./node_modules/classnames/index.js"); 39 | /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(classnames__WEBPACK_IMPORTED_MODULE_2__); 40 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 41 | 42 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 43 | 44 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 45 | 46 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 47 | 48 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 49 | 50 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 51 | 52 | function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 53 | 54 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 55 | 56 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 57 | 58 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 59 | 60 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 61 | 62 | 63 | 64 | 65 | var ESCAPE_KEY = 27; 66 | var ENTER_KEY = 13; 67 | 68 | var TodoItem = /*#__PURE__*/function (_React$Component) { 69 | _inherits(TodoItem, _React$Component); 70 | 71 | var _super = _createSuper(TodoItem); 72 | 73 | function TodoItem(props) { 74 | var _this; 75 | 76 | _classCallCheck(this, TodoItem); 77 | 78 | _this = _super.call(this, props); 79 | _this.state = { 80 | editText: props.todo.title 81 | }; 82 | _this.handleEdit = _this.handleEdit.bind(_assertThisInitialized(_this)); 83 | _this.handleSubmit = _this.handleSubmit.bind(_assertThisInitialized(_this)); 84 | _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this)); 85 | _this.handleChange = _this.handleChange.bind(_assertThisInitialized(_this)); 86 | return _this; 87 | } 88 | /** 89 | * This is a completely optional performance enhancement that you can 90 | * implement on any React component. If you were to delete this method 91 | * the app would still work correctly (and still be very performant!), we 92 | * just use it as an example of how little code it takes to get an order 93 | * of magnitude performance improvement. 94 | */ 95 | 96 | 97 | _createClass(TodoItem, [{ 98 | key: "shouldComponentUpdate", 99 | value: function shouldComponentUpdate(nextProps, nextState) { 100 | return nextProps.todo !== this.props.todo || nextProps.editing !== this.props.editing || nextState.editText !== this.state.editText; 101 | } 102 | /** 103 | * Safely manipulate the DOM after updating the state when invoking 104 | * `this.props.onEdit()` in the `handleEdit` method above. 105 | * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate 106 | * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate 107 | */ 108 | 109 | }, { 110 | key: "componentDidUpdate", 111 | value: function componentDidUpdate(prevProps) { 112 | if (!prevProps.editing && this.props.editing) { 113 | var node = react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.findDOMNode(this.refs.editField); 114 | node.focus(); 115 | node.setSelectionRange(node.value.length, node.value.length); 116 | } 117 | } 118 | }, { 119 | key: "handleSubmit", 120 | value: function handleSubmit() { 121 | var val = this.state.editText.trim(); 122 | 123 | if (val) { 124 | this.props.onSave(val); 125 | this.setState({ 126 | editText: val 127 | }); 128 | } else { 129 | this.props.onDestroy(); 130 | } 131 | } 132 | }, { 133 | key: "handleEdit", 134 | value: function handleEdit() { 135 | this.props.onEdit(); 136 | this.setState({ 137 | editText: this.props.todo.title 138 | }); 139 | } 140 | }, { 141 | key: "handleKeyDown", 142 | value: function handleKeyDown(event) { 143 | if (event.which === ESCAPE_KEY) { 144 | this.setState({ 145 | editText: this.props.todo.title 146 | }); 147 | this.props.onCancel(event); 148 | } else if (event.which === ENTER_KEY) { 149 | this.handleSubmit(event); 150 | } 151 | } 152 | }, { 153 | key: "handleChange", 154 | value: function handleChange(event) { 155 | if (this.props.editing) { 156 | this.setState({ 157 | editText: event.target.value 158 | }); 159 | } 160 | } 161 | }, { 162 | key: "render", 163 | value: function render() { 164 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", { 165 | className: classnames__WEBPACK_IMPORTED_MODULE_2___default()({ 166 | completed: this.props.todo.completed, 167 | editing: this.props.editing 168 | }) 169 | }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { 170 | className: "view" 171 | }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", { 172 | className: "toggle", 173 | type: "checkbox", 174 | checked: this.props.todo.completed, 175 | onChange: this.props.onToggle 176 | }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("label", { 177 | onDoubleClick: this.handleEdit 178 | }, this.props.todo.title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", { 179 | className: "destroy", 180 | onClick: this.props.onDestroy 181 | })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", { 182 | ref: "editField", 183 | className: "edit", 184 | value: this.state.editText, 185 | onBlur: this.handleSubmit, 186 | onChange: this.handleChange, 187 | onKeyDown: this.handleKeyDown 188 | })); 189 | } 190 | }]); 191 | 192 | return TodoItem; 193 | }(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component); 194 | 195 | 196 | 197 | /***/ }), 198 | 199 | /***/ "./src/todoList.jsx": 200 | /*!**************************!*\ 201 | !*** ./src/todoList.jsx ***! 202 | \**************************/ 203 | /*! exports provided: default */ 204 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 205 | 206 | "use strict"; 207 | __webpack_require__.r(__webpack_exports__); 208 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TodoList; }); 209 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 210 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 211 | /* harmony import */ var _todoItem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./todoItem */ "./src/todoItem.jsx"); 212 | 213 | 214 | function TodoList(props) { 215 | var todoItems = props.todos.map(function (todo) { 216 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_todoItem__WEBPACK_IMPORTED_MODULE_1__["default"], { 217 | key: todo.id, 218 | todo: todo, 219 | onToggle: function onToggle() { 220 | props.onToggle(todo); 221 | }, 222 | onDestroy: function onDestroy() { 223 | props.onDestroy(todo); 224 | }, 225 | onEdit: function onEdit() { 226 | props.onEdit(todo); 227 | }, 228 | editing: props.editing(todo), 229 | onSave: function onSave(text) { 230 | props.onSave(todo, text); 231 | }, 232 | onCancel: function onCancel() { 233 | props.onCancel(); 234 | } 235 | }); 236 | }); 237 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, todoItems); 238 | } 239 | 240 | /***/ }) 241 | 242 | }]); 243 | //# sourceMappingURL=0.bundle.js.map -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/1.bundle.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],{ 2 | 3 | /***/ "./src/active-todos.jsx": 4 | /*!******************************!*\ 5 | !*** ./src/active-todos.jsx ***! 6 | \******************************/ 7 | /*! exports provided: default */ 8 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 9 | 10 | "use strict"; 11 | __webpack_require__.r(__webpack_exports__); 12 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ActiveTodos; }); 13 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 14 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 15 | /* harmony import */ var _todoList__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./todoList */ "./src/todoList.jsx"); 16 | function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } 17 | 18 | function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } 19 | 20 | function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } 21 | 22 | 23 | 24 | function ActiveTodos(_ref) { 25 | var todos = _ref.todos, 26 | props = _objectWithoutProperties(_ref, ["todos"]); 27 | 28 | var filteredTodos = todos.filter(function (todo) { 29 | return !todo.completed; 30 | }); 31 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_todoList__WEBPACK_IMPORTED_MODULE_1__["default"], _extends({ 32 | todos: filteredTodos 33 | }, props)); 34 | } 35 | 36 | /***/ }), 37 | 38 | /***/ "./src/todoItem.jsx": 39 | /*!**************************!*\ 40 | !*** ./src/todoItem.jsx ***! 41 | \**************************/ 42 | /*! exports provided: default */ 43 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 44 | 45 | "use strict"; 46 | __webpack_require__.r(__webpack_exports__); 47 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TodoItem; }); 48 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 49 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 50 | /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js"); 51 | /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__); 52 | /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! classnames */ "./node_modules/classnames/index.js"); 53 | /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(classnames__WEBPACK_IMPORTED_MODULE_2__); 54 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 55 | 56 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 57 | 58 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 59 | 60 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 61 | 62 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 63 | 64 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 65 | 66 | function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 67 | 68 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 69 | 70 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 71 | 72 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 73 | 74 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 75 | 76 | 77 | 78 | 79 | var ESCAPE_KEY = 27; 80 | var ENTER_KEY = 13; 81 | 82 | var TodoItem = /*#__PURE__*/function (_React$Component) { 83 | _inherits(TodoItem, _React$Component); 84 | 85 | var _super = _createSuper(TodoItem); 86 | 87 | function TodoItem(props) { 88 | var _this; 89 | 90 | _classCallCheck(this, TodoItem); 91 | 92 | _this = _super.call(this, props); 93 | _this.state = { 94 | editText: props.todo.title 95 | }; 96 | _this.handleEdit = _this.handleEdit.bind(_assertThisInitialized(_this)); 97 | _this.handleSubmit = _this.handleSubmit.bind(_assertThisInitialized(_this)); 98 | _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this)); 99 | _this.handleChange = _this.handleChange.bind(_assertThisInitialized(_this)); 100 | return _this; 101 | } 102 | /** 103 | * This is a completely optional performance enhancement that you can 104 | * implement on any React component. If you were to delete this method 105 | * the app would still work correctly (and still be very performant!), we 106 | * just use it as an example of how little code it takes to get an order 107 | * of magnitude performance improvement. 108 | */ 109 | 110 | 111 | _createClass(TodoItem, [{ 112 | key: "shouldComponentUpdate", 113 | value: function shouldComponentUpdate(nextProps, nextState) { 114 | return nextProps.todo !== this.props.todo || nextProps.editing !== this.props.editing || nextState.editText !== this.state.editText; 115 | } 116 | /** 117 | * Safely manipulate the DOM after updating the state when invoking 118 | * `this.props.onEdit()` in the `handleEdit` method above. 119 | * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate 120 | * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate 121 | */ 122 | 123 | }, { 124 | key: "componentDidUpdate", 125 | value: function componentDidUpdate(prevProps) { 126 | if (!prevProps.editing && this.props.editing) { 127 | var node = react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.findDOMNode(this.refs.editField); 128 | node.focus(); 129 | node.setSelectionRange(node.value.length, node.value.length); 130 | } 131 | } 132 | }, { 133 | key: "handleSubmit", 134 | value: function handleSubmit() { 135 | var val = this.state.editText.trim(); 136 | 137 | if (val) { 138 | this.props.onSave(val); 139 | this.setState({ 140 | editText: val 141 | }); 142 | } else { 143 | this.props.onDestroy(); 144 | } 145 | } 146 | }, { 147 | key: "handleEdit", 148 | value: function handleEdit() { 149 | this.props.onEdit(); 150 | this.setState({ 151 | editText: this.props.todo.title 152 | }); 153 | } 154 | }, { 155 | key: "handleKeyDown", 156 | value: function handleKeyDown(event) { 157 | if (event.which === ESCAPE_KEY) { 158 | this.setState({ 159 | editText: this.props.todo.title 160 | }); 161 | this.props.onCancel(event); 162 | } else if (event.which === ENTER_KEY) { 163 | this.handleSubmit(event); 164 | } 165 | } 166 | }, { 167 | key: "handleChange", 168 | value: function handleChange(event) { 169 | if (this.props.editing) { 170 | this.setState({ 171 | editText: event.target.value 172 | }); 173 | } 174 | } 175 | }, { 176 | key: "render", 177 | value: function render() { 178 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", { 179 | className: classnames__WEBPACK_IMPORTED_MODULE_2___default()({ 180 | completed: this.props.todo.completed, 181 | editing: this.props.editing 182 | }) 183 | }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { 184 | className: "view" 185 | }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", { 186 | className: "toggle", 187 | type: "checkbox", 188 | checked: this.props.todo.completed, 189 | onChange: this.props.onToggle 190 | }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("label", { 191 | onDoubleClick: this.handleEdit 192 | }, this.props.todo.title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", { 193 | className: "destroy", 194 | onClick: this.props.onDestroy 195 | })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", { 196 | ref: "editField", 197 | className: "edit", 198 | value: this.state.editText, 199 | onBlur: this.handleSubmit, 200 | onChange: this.handleChange, 201 | onKeyDown: this.handleKeyDown 202 | })); 203 | } 204 | }]); 205 | 206 | return TodoItem; 207 | }(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component); 208 | 209 | 210 | 211 | /***/ }), 212 | 213 | /***/ "./src/todoList.jsx": 214 | /*!**************************!*\ 215 | !*** ./src/todoList.jsx ***! 216 | \**************************/ 217 | /*! exports provided: default */ 218 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 219 | 220 | "use strict"; 221 | __webpack_require__.r(__webpack_exports__); 222 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TodoList; }); 223 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 224 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 225 | /* harmony import */ var _todoItem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./todoItem */ "./src/todoItem.jsx"); 226 | 227 | 228 | function TodoList(props) { 229 | var todoItems = props.todos.map(function (todo) { 230 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_todoItem__WEBPACK_IMPORTED_MODULE_1__["default"], { 231 | key: todo.id, 232 | todo: todo, 233 | onToggle: function onToggle() { 234 | props.onToggle(todo); 235 | }, 236 | onDestroy: function onDestroy() { 237 | props.onDestroy(todo); 238 | }, 239 | onEdit: function onEdit() { 240 | props.onEdit(todo); 241 | }, 242 | editing: props.editing(todo), 243 | onSave: function onSave(text) { 244 | props.onSave(todo, text); 245 | }, 246 | onCancel: function onCancel() { 247 | props.onCancel(); 248 | } 249 | }); 250 | }); 251 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, todoItems); 252 | } 253 | 254 | /***/ }) 255 | 256 | }]); 257 | //# sourceMappingURL=1.bundle.js.map -------------------------------------------------------------------------------- /src/main/resources/META-INF/resources/2.bundle.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{ 2 | 3 | /***/ "./src/completed-todos.jsx": 4 | /*!*********************************!*\ 5 | !*** ./src/completed-todos.jsx ***! 6 | \*********************************/ 7 | /*! exports provided: default */ 8 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 9 | 10 | "use strict"; 11 | __webpack_require__.r(__webpack_exports__); 12 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ActiveTodos; }); 13 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 14 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 15 | /* harmony import */ var _todoList__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./todoList */ "./src/todoList.jsx"); 16 | function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } 17 | 18 | function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } 19 | 20 | function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } 21 | 22 | 23 | 24 | function ActiveTodos(_ref) { 25 | var todos = _ref.todos, 26 | props = _objectWithoutProperties(_ref, ["todos"]); 27 | 28 | var filteredTodos = todos.filter(function (todo) { 29 | return todo.completed; 30 | }); 31 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_todoList__WEBPACK_IMPORTED_MODULE_1__["default"], _extends({ 32 | todos: filteredTodos 33 | }, props)); 34 | } 35 | 36 | /***/ }), 37 | 38 | /***/ "./src/todoItem.jsx": 39 | /*!**************************!*\ 40 | !*** ./src/todoItem.jsx ***! 41 | \**************************/ 42 | /*! exports provided: default */ 43 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 44 | 45 | "use strict"; 46 | __webpack_require__.r(__webpack_exports__); 47 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TodoItem; }); 48 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 49 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 50 | /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js"); 51 | /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__); 52 | /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! classnames */ "./node_modules/classnames/index.js"); 53 | /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(classnames__WEBPACK_IMPORTED_MODULE_2__); 54 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 55 | 56 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 57 | 58 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 59 | 60 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 61 | 62 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 63 | 64 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 65 | 66 | function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 67 | 68 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 69 | 70 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 71 | 72 | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } 73 | 74 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 75 | 76 | 77 | 78 | 79 | var ESCAPE_KEY = 27; 80 | var ENTER_KEY = 13; 81 | 82 | var TodoItem = /*#__PURE__*/function (_React$Component) { 83 | _inherits(TodoItem, _React$Component); 84 | 85 | var _super = _createSuper(TodoItem); 86 | 87 | function TodoItem(props) { 88 | var _this; 89 | 90 | _classCallCheck(this, TodoItem); 91 | 92 | _this = _super.call(this, props); 93 | _this.state = { 94 | editText: props.todo.title 95 | }; 96 | _this.handleEdit = _this.handleEdit.bind(_assertThisInitialized(_this)); 97 | _this.handleSubmit = _this.handleSubmit.bind(_assertThisInitialized(_this)); 98 | _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this)); 99 | _this.handleChange = _this.handleChange.bind(_assertThisInitialized(_this)); 100 | return _this; 101 | } 102 | /** 103 | * This is a completely optional performance enhancement that you can 104 | * implement on any React component. If you were to delete this method 105 | * the app would still work correctly (and still be very performant!), we 106 | * just use it as an example of how little code it takes to get an order 107 | * of magnitude performance improvement. 108 | */ 109 | 110 | 111 | _createClass(TodoItem, [{ 112 | key: "shouldComponentUpdate", 113 | value: function shouldComponentUpdate(nextProps, nextState) { 114 | return nextProps.todo !== this.props.todo || nextProps.editing !== this.props.editing || nextState.editText !== this.state.editText; 115 | } 116 | /** 117 | * Safely manipulate the DOM after updating the state when invoking 118 | * `this.props.onEdit()` in the `handleEdit` method above. 119 | * For more info refer to notes at https://facebook.github.io/react/docs/component-api.html#setstate 120 | * and https://facebook.github.io/react/docs/component-specs.html#updating-componentdidupdate 121 | */ 122 | 123 | }, { 124 | key: "componentDidUpdate", 125 | value: function componentDidUpdate(prevProps) { 126 | if (!prevProps.editing && this.props.editing) { 127 | var node = react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.findDOMNode(this.refs.editField); 128 | node.focus(); 129 | node.setSelectionRange(node.value.length, node.value.length); 130 | } 131 | } 132 | }, { 133 | key: "handleSubmit", 134 | value: function handleSubmit() { 135 | var val = this.state.editText.trim(); 136 | 137 | if (val) { 138 | this.props.onSave(val); 139 | this.setState({ 140 | editText: val 141 | }); 142 | } else { 143 | this.props.onDestroy(); 144 | } 145 | } 146 | }, { 147 | key: "handleEdit", 148 | value: function handleEdit() { 149 | this.props.onEdit(); 150 | this.setState({ 151 | editText: this.props.todo.title 152 | }); 153 | } 154 | }, { 155 | key: "handleKeyDown", 156 | value: function handleKeyDown(event) { 157 | if (event.which === ESCAPE_KEY) { 158 | this.setState({ 159 | editText: this.props.todo.title 160 | }); 161 | this.props.onCancel(event); 162 | } else if (event.which === ENTER_KEY) { 163 | this.handleSubmit(event); 164 | } 165 | } 166 | }, { 167 | key: "handleChange", 168 | value: function handleChange(event) { 169 | if (this.props.editing) { 170 | this.setState({ 171 | editText: event.target.value 172 | }); 173 | } 174 | } 175 | }, { 176 | key: "render", 177 | value: function render() { 178 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", { 179 | className: classnames__WEBPACK_IMPORTED_MODULE_2___default()({ 180 | completed: this.props.todo.completed, 181 | editing: this.props.editing 182 | }) 183 | }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { 184 | className: "view" 185 | }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", { 186 | className: "toggle", 187 | type: "checkbox", 188 | checked: this.props.todo.completed, 189 | onChange: this.props.onToggle 190 | }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("label", { 191 | onDoubleClick: this.handleEdit 192 | }, this.props.todo.title), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", { 193 | className: "destroy", 194 | onClick: this.props.onDestroy 195 | })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("input", { 196 | ref: "editField", 197 | className: "edit", 198 | value: this.state.editText, 199 | onBlur: this.handleSubmit, 200 | onChange: this.handleChange, 201 | onKeyDown: this.handleKeyDown 202 | })); 203 | } 204 | }]); 205 | 206 | return TodoItem; 207 | }(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component); 208 | 209 | 210 | 211 | /***/ }), 212 | 213 | /***/ "./src/todoList.jsx": 214 | /*!**************************!*\ 215 | !*** ./src/todoList.jsx ***! 216 | \**************************/ 217 | /*! exports provided: default */ 218 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 219 | 220 | "use strict"; 221 | __webpack_require__.r(__webpack_exports__); 222 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TodoList; }); 223 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); 224 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 225 | /* harmony import */ var _todoItem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./todoItem */ "./src/todoItem.jsx"); 226 | 227 | 228 | function TodoList(props) { 229 | var todoItems = props.todos.map(function (todo) { 230 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_todoItem__WEBPACK_IMPORTED_MODULE_1__["default"], { 231 | key: todo.id, 232 | todo: todo, 233 | onToggle: function onToggle() { 234 | props.onToggle(todo); 235 | }, 236 | onDestroy: function onDestroy() { 237 | props.onDestroy(todo); 238 | }, 239 | onEdit: function onEdit() { 240 | props.onEdit(todo); 241 | }, 242 | editing: props.editing(todo), 243 | onSave: function onSave(text) { 244 | props.onSave(todo, text); 245 | }, 246 | onCancel: function onCancel() { 247 | props.onCancel(); 248 | } 249 | }); 250 | }); 251 | return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, todoItems); 252 | } 253 | 254 | /***/ }) 255 | 256 | }]); 257 | //# sourceMappingURL=2.bundle.js.map --------------------------------------------------------------------------------