Skip to content

Commit

Permalink
Add pinia for vue 3
Browse files Browse the repository at this point in the history
  • Loading branch information
seraphinandrieux committed Mar 29, 2022
1 parent 953a03b commit d8be43b
Show file tree
Hide file tree
Showing 22 changed files with 18,661 additions and 20 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
},
"dependencies": {
"axios": "0.26.1",
"pinia": "2.0.12",
"pinia-plugin-persist": "^1.0.0",
"vue": "3.2.31",
"vue-router": "4.0.14"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public void addVue(Project project) {
vueService.addVue(project);
}

public void addPinia(Project project) {
vueService.addPinia(project);
}

public void addStyledVue(Project project) {
vueService.addStyledVue(project);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,66 @@
package tech.jhipster.lite.generator.client.vue.core.domain;

import java.util.Collection;
import java.util.List;

public class Vue {

public static final String ROUTER_IMPORT = "import router from \'./router/router\';";
public static final String ROUTER_PROVIDER = "app.use(router);";
public static final Collection<String> PINIA_IMPORTS = List.of(
"import {createPinia} from \"pinia\";",
"import piniaPersist from 'pinia-plugin-persist'"
);
public static final Collection<String> PINIA_PROVIDERS = List.of(
"const pinia = createPinia();",
"pinia.use(piniaPersist);",
"app.use(pinia);"
);

private Vue() {}

public static List<String> dependencies() {
return List.of("vue");
}

public static List<String> piniaDependencies() {
return List.of("pinia", "pinia-plugin-persist");
}

public static List<String> piniaDevDependencies() {
return List.of("@pinia/testing");
}

public static List<String> buttonForStoreExampleFiles() {
return List.of("Button.component.ts", "Button.html", "Button.vue", "index.ts");
}

public static List<String> buttonForStoreExampleTestFiles() {
return List.of("Button.spec.ts");
}

public static List<String> storeExampleRoutes() {
return List.of("""
{
path: '/button',
name: 'Button',
component: ButtonVue,
},
""");
}

public static List<String> storeExampleImports() {
return List.of("import { ButtonVue } from '@/common/primary/button';");
}

public static List<String> storeFilesExample() {
return List.of("CounterStore.ts");
}

public static List<String> storeTestFilesExample() {
return List.of("CounterStore.spec.ts");
}

public static List<String> routerDependencies() {
return List.of("vue-router");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ public class VueDomainService implements VueService {
public static final String SOURCE = "client/vue";
public static final String NEEDLE_IMPORT = "// jhipster-needle-main-ts-import";
public static final String NEEDLE_PROVIDER = "// jhipster-needle-main-ts-provider";
public static final String SOURCE_PRIMARY = getPath(SOURCE, "webapp/app/common/primary/app");
public static final String DESTINATION_PRIMARY = "src/main/webapp/app/common/primary/app";
public static final String NEEDLE_ROUTE = "// jhipster-needle-router-route";
public static final String NEEDLE_ROUTE_IMPORT = "// jhipster-needle-router-import";
public static final String SOURCE_PRIMARY = getPath(SOURCE, "webapp/app/common/primary");
public static final String SOURCE_TEST_PRIMARY = getPath(SOURCE, "test/spec/common/primary");
public static final String SOURCE_PRIMARY_APP = getPath(SOURCE_PRIMARY, "app");
public static final String DESTINATION_PRIMARY = "src/main/webapp/app/common/primary";
public static final String DESTINATION_PRIMARY_APP = DESTINATION_PRIMARY + "/app";
public static final String DESTINATION_PRIMARY_TEST = "src/test/javascript/spec/common/primary";
public static final String DESTINATION_PRIMARY_ROUTER = DESTINATION_PRIMARY + "/app";
public static final String DESTINATION_APP = "src/main/webapp/app";
public static final String DESTINATION_ROUTER = DESTINATION_APP + "/router";

private final ProjectRepository projectRepository;
private final NpmService npmService;
Expand All @@ -42,6 +50,49 @@ public void addStyledVue(Project project) {
addAppFilesWithCss(project);
}

@Override
public void addPinia(Project project) {
Assert.notNull("project", project);

addPiniaDependencies(project);
addPiniaMainConfiguration(project);
addStoreExample(project);
}

private void addStoreExample(Project project) {
addStoreExampleFiles(project);
addStoreExampleTestFiles(project);
addStoreExampleRouteIntoRouter(project);
}

public void addStoreExampleRouteIntoRouter(Project project) {
Vue
.storeExampleImports()
.forEach(importLine -> addNewNeedleLineToFile(project, importLine, DESTINATION_ROUTER, ROUTER_TYPESCRIPT, NEEDLE_ROUTE_IMPORT));
Vue.storeExampleRoutes().forEach(route -> addNewNeedleLineToFile(project, route, DESTINATION_ROUTER, ROUTER_TYPESCRIPT, NEEDLE_ROUTE));
}

public void addStoreExampleFiles(Project project) {
Vue
.buttonForStoreExampleFiles()
.forEach(file -> projectRepository.template(project, getPath(SOURCE_PRIMARY, "button"), file, DESTINATION_PRIMARY + "/button"));
Vue
.storeFilesExample()
.forEach(file -> projectRepository.template(project, getPath(SOURCE_PRIMARY, "store"), file, DESTINATION_PRIMARY + "/store"));
}

public void addStoreExampleTestFiles(Project project) {
Vue
.buttonForStoreExampleTestFiles()
.forEach(file ->
projectRepository.template(project, getPath(SOURCE_TEST_PRIMARY, "button"), file, DESTINATION_PRIMARY_TEST + "/button")
);
Vue
.storeTestFilesExample()
.forEach(file -> projectRepository.template(project, getPath(SOURCE_TEST_PRIMARY, "store"), file, DESTINATION_PRIMARY_TEST + "/store")
);
}

private void addCommonVue(Project project) {
Assert.notNull("project", project);
addDependencies(project);
Expand All @@ -58,6 +109,18 @@ public void addDependencies(Project project) {
Vue.dependencies().forEach(dependency -> addDependency(project, dependency));
}

public void addPiniaDependencies(Project project) {
Vue.piniaDependencies().forEach(dependency -> addDependency(project, dependency));
Vue.piniaDevDependencies().forEach(devDependency -> addDevDependency(project, devDependency));
}

private void addPiniaMainConfiguration(Project project) {
Vue.PINIA_IMPORTS.forEach(importLine -> addNewNeedleLineToFile(project, importLine, DESTINATION_APP, MAIN_TYPESCRIPT, NEEDLE_IMPORT));
Vue.PINIA_PROVIDERS.forEach(providerLine ->
addNewNeedleLineToFile(project, providerLine, DESTINATION_APP, MAIN_TYPESCRIPT, NEEDLE_PROVIDER)
);
}

public void addDevDependencies(Project project) {
Vue.devDependencies().forEach(devDependency -> addDevDependency(project, devDependency));
}
Expand Down Expand Up @@ -126,7 +189,7 @@ private void addRouterFiles(Project project) {
}

private void addRouterConfigAndTestFiles(Project project) {
projectRepository.template(project, getPath(SOURCE, "webapp/app/router"), "router.ts", "src/main/webapp/app/router");
projectRepository.template(project, getPath(SOURCE, "webapp/app/router"), ROUTER_TYPESCRIPT, "src/main/webapp/app/router");
projectRepository.template(project, getPath(SOURCE, "test/spec/router"), "Router.spec.ts", "src/test/javascript/spec/router");
}

Expand All @@ -143,29 +206,24 @@ private void addNewNeedleLineToFile(Project project, String importLine, String f
public void addAppFiles(Project project) {
project.addDefaultConfig(BASE_NAME);

projectRepository.template(project, SOURCE_PRIMARY, "App.component.ts", DESTINATION_PRIMARY);
projectRepository.template(project, SOURCE_PRIMARY, "index.ts", DESTINATION_PRIMARY);
projectRepository.template(project, SOURCE_PRIMARY_APP, "App.component.ts", DESTINATION_PRIMARY_APP);
projectRepository.template(project, SOURCE_PRIMARY_APP, "index.ts", DESTINATION_PRIMARY_APP);

projectRepository.template(
project,
getPath(SOURCE, "test/spec/common/primary/app"),
"App.spec.ts",
"src/test/javascript/spec/common/primary/app"
);
projectRepository.template(project, getPath(SOURCE_TEST_PRIMARY, "app"), "App.spec.ts", DESTINATION_PRIMARY_TEST + "/app");
}

public void addAppFilesWithoutCss(Project project) {
project.addDefaultConfig(BASE_NAME);

projectRepository.template(project, SOURCE_PRIMARY, "App.html", DESTINATION_PRIMARY);
projectRepository.template(project, SOURCE_PRIMARY, "App.vue", DESTINATION_PRIMARY);
projectRepository.template(project, SOURCE_PRIMARY_APP, "App.html", DESTINATION_PRIMARY_APP);
projectRepository.template(project, SOURCE_PRIMARY_APP, "App.vue", DESTINATION_PRIMARY_APP);
}

public void addAppFilesWithCss(Project project) {
project.addDefaultConfig(BASE_NAME);

projectRepository.template(project, SOURCE_PRIMARY, "StyledApp.html", DESTINATION_PRIMARY, "App.html");
projectRepository.template(project, SOURCE_PRIMARY, "StyledApp.vue", DESTINATION_PRIMARY, "App.vue");
projectRepository.template(project, SOURCE_PRIMARY_APP, "StyledApp.html", DESTINATION_PRIMARY_APP, "App.html");
projectRepository.template(project, SOURCE_PRIMARY_APP, "StyledApp.vue", DESTINATION_PRIMARY_APP, "App.vue");

projectRepository.add(
project,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ public interface VueService {
void addVue(Project project);

void addStyledVue(Project project);

void addPinia(Project project);
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,13 @@ public void addStyledVue(@RequestBody ProjectDTO projectDTO) {
Project project = ProjectDTO.toProject(projectDTO);
vueApplicationService.addStyledVue(project);
}

@Operation(summary = "Add Pinia", description = "Add pinia for state management")
@ApiResponse(responseCode = "500", description = "An error occurred while adding Pinia")
@PostMapping("/pinia")
@GeneratorStep(id = "vue-pinia")
public void addPinia(@RequestBody ProjectDTO projectDTO) {
Project project = ProjectDTO.toProject(projectDTO);
vueApplicationService.addPinia(project);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ private Constants() {}
public static final String DOCKERFILE = "Dockerfile";
public static final String INTEGRATION_TEST = "IntegrationTest.java";
public static final String MAIN_TYPESCRIPT = "main.ts";
public static final String ROUTER_TYPESCRIPT = "router.ts";

public static final String COMMENT_PROPERTIES_PREFIX = "#";
public static final String KEY_VALUE_PROPERTIES_SEPARATOR = "=";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {shallowMount, VueWrapper} from "@vue/test-utils";
import {ButtonVue} from "@/common/primary/button";
import {createTestingPinia} from "@pinia/testing";
import {useCounterStore} from "@/common/primary/store/CounterStore";

let wrapper: VueWrapper;
const wrap = () => {
wrapper = shallowMount(ButtonVue,{
global:{
plugins:[createTestingPinia()]
}
});
};

describe('Button',()=>{
it('should exist', () => {
wrap();
expect(wrapper.exists()).toBeTruthy();
});

it('should get counter value from store', async () => {
await wrap();
const store = useCounterStore();
expect(wrapper.text()).toEqual("Store Button 0");
const button = wrapper.find('button');
await button.trigger('click');
expect(store.increment).toHaveBeenCalledTimes(1);
});
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {createPinia, setActivePinia} from "pinia";
import {useCounterStore} from "@/common/primary/store/CounterStore";

describe("Counter store",()=>{
beforeEach(() => {
setActivePinia(createPinia())
})

it('Should initialize counter store to 0', () => {
const counter = useCounterStore()
expect(counter.count).toBe(0)
})

it('Should increment counter', () => {
const counter = useCounterStore()
counter.increment();
expect(counter.count).toBe(1)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {useCounterStore} from "@/common/primary/store/CounterStore";

export default {
name: 'Button',
setup: () => {
const counter = useCounterStore();
const increment = (): void => {
counter.increment();
}

const counterValue = (): number =>{
return counter.count;
}

return {
increment,
counterValue
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
<button id="counter" @click.prevent="increment">
Store Button {{=<% %>=}}{{ counterValue() }}<%={{ }}=%>
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template src="./Button.html"></template>

<script lang="ts" src="./Button.component.ts"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import ButtonComponent from './Button.component';
import ButtonVue from './Button.vue';

export { ButtonComponent, ButtonVue };
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {defineStore} from "pinia";

export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++
},
},
persist: {
enabled: true
}
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AppVue } from '@/common/primary/app';
import { createRouter, createWebHistory } from 'vue-router';
// jhipster-needle-router-import

const routes = [
{
Expand All @@ -11,6 +12,7 @@ const routes = [
name: 'App',
component: AppVue,
},
// jhipster-needle-router-route
];

const router = createRouter({
Expand Down
Loading

0 comments on commit d8be43b

Please sign in to comment.