Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue Route in demo App #183

Merged
merged 11 commits into from
Sep 11, 2024
Merged
7 changes: 6 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,12 @@ export default tseslint.config(
'vue/html-indent': ['error', 'tab'],
// should be based on the printWidth
'vue/max-attributes-per-line': 'off',
'vue/no-undef-components': 'error',
'vue/no-undef-components': [
'error',
{
ignorePatterns: ['RouterView', 'RouterLink'],
},
],
'vue/html-comment-indent': ['error', 'tab'],
'vue/script-indent': ['error', 'tab'],
'vue/no-empty-component-block': 'error',
Expand Down
13 changes: 11 additions & 2 deletions packages/web-forms/e2e/vue.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { faker } from '@faker-js/faker';
import { expect, test } from '@playwright/test';
import { expect, Page, test } from '@playwright/test';

const expandAllCategories = async (page: Page) => {
await page.evaluate(() => {
document.querySelectorAll('ul.category-list > li').forEach((c) => c.classList.add('expanded'));
});
};
test('All forms are rendered and there is no console error', async ({ page, browserName }) => {
let consoleErrors = 0;

Expand All @@ -15,7 +20,10 @@ test('All forms are rendered and there is no console error', async ({ page, brow
// this ensures that Vue application is loaded before proceeding forward.
await expect(page.getByText('Demo Forms')).toBeVisible();

const forms = await page.locator('ul.form-list li').all();
// Let's expand all categories, so that Form list is visible
await expandAllCategories(page);

const forms = await page.locator('ul.form-list li a').all();

expect(forms.length).toBeGreaterThan(0);

Expand Down Expand Up @@ -81,6 +89,7 @@ test('All forms are rendered and there is no console error', async ({ page, brow
}

await page.goBack();
await expandAllCategories(page);
}

expect(consoleErrors).toBe(0);
Expand Down
2 changes: 1 addition & 1 deletion packages/web-forms/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/demo.ts"></script>
<script type="module" src="/src/demo/demo.ts"></script>
</body>
</html>
3 changes: 2 additions & 1 deletion packages/web-forms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
"vite": "^5.4.3",
"vite-plugin-css-injected-by-js": "^3.5.1",
"vitest": "^2.0.5",
"vue": "3.3.4"
"vue": "3.3.4",
"vue-router": "^4.4.3"
},
"peerDependencies": {
"vue": "^3.3.4"
Expand Down
90 changes: 0 additions & 90 deletions packages/web-forms/src/OdkWebFormDemo.vue

This file was deleted.

131 changes: 131 additions & 0 deletions packages/web-forms/src/demo/FormList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { RouterLink } from 'vue-router';

const formFixtureGlobImports = import.meta.glob<true, 'raw', string>('../../../ui-solid/fixtures/xforms/**/*.xml', {
query: '?raw'
});

type CategoryType = Record<string, string[]>;

const categories = Object.keys(formFixtureGlobImports)
.map(f => f.replace('../../../ui-solid/fixtures/xforms/', '').replace('.xml', ''))
.reduce((result: CategoryType, f:string) => {
const parts = f.split('/');
const category = parts.length == 2 ? parts[0] : 'Other';
if(!result[category]){
result[category] = [];
}
result[category].push(parts.length == 2 ? parts[1]: parts[0])
return result;
}, {});

const expandedCategories = ref(new Set());

const toggleCategory = (category:string) => {
if(expandedCategories.value.has(category)) {
expandedCategories.value.delete(category);
}
else {
expandedCategories.value.add(category);
}
}

</script>

<template>
<div class="component-root">
<h1>Demo Forms</h1>
<ul class="category-list">
<li
v-for="(category,categoryName) in categories"
:key="categoryName"
:class="{ 'expanded': expandedCategories.has(categoryName) }"
@click="toggleCategory(categoryName)"
>
{{ categoryName }}
<ul class="form-list">
<li v-for="form in category" :key="form">
<RouterLink :to="`/form/${categoryName}/${form}`">
{{ form }}
</RouterLink>
</li>
</ul>
</li>
</ul>
</div>
</template>

<style scoped>
.component-root {
background: white;
height: 100vh;
margin-top: -25px;
}

h1 {
margin-left: 10px;
padding-top: 20px;
}
.category-list {
padding: 0;

> li {
list-style: none;
cursor: pointer;
margin: 10px;
text-transform: capitalize;
font-size: 20px;
padding: 10px;

&:hover {
background-color: var(--gray-100);
}

&::before {
content: '▶︎';
margin-right: 10px;
}

ul.form-list {
display: none;
padding: 0 0 0 20px;

li {
list-style: none;
margin: 10px;
border: 1px solid var(--primary-500);
border-radius: 10px;
cursor: pointer;
background-color: var(--surface-0);
font-size: 16px;

a {
display: block;
padding: 10px;
text-decoration: none;
color: var(--gray-900);

&:visited {
color: var(--gray-900)
}
}
}

li:hover {
background-color: var(--primary-50);
}
}

&.expanded {
&::before {
content: '▼';
}
ul.form-list {
display: block;
}
}
}
}

</style>
38 changes: 38 additions & 0 deletions packages/web-forms/src/demo/FormPreview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useRoute } from 'vue-router';
import OdkWebForm from '../components/OdkWebForm.vue';

const route = useRoute()

const formFixtureGlobImports = import.meta.glob<false, 'raw', string>('../../../ui-solid/fixtures/xforms/**/*.xml', {
query: '?raw',
import: 'default',
eager: false,
});

const categoryParam = route.params.category as string;
const formParam = route.params.form as string;
const formPath = '../../../ui-solid/fixtures/xforms/' + (route.params.category != 'Other' ? `${categoryParam}/${formParam}` : formParam) + '.xml';

const form = ref();
formFixtureGlobImports[formPath]()
.then((xml:string) => {
form.value = xml;
})
.catch(() => {
alert('Failed to load the Form XML');
});

const handleSubmit = () => {
alert(`Submit button was pressed`);
}

</script>

<template>
<OdkWebForm v-if="form" :form-xml="form" @submit="handleSubmit" />
<div v-else>
Loading...
</div>
</template>
3 changes: 3 additions & 0 deletions packages/web-forms/src/demo/OdkWebFormDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<RouterView />
</template>
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import type { Component } from 'vue';
import { createApp } from 'vue';

import { webFormsPlugin } from '../WebFormsPlugin';
import OdkWebFormDemo from './OdkWebFormDemo.vue';
import { webFormsPlugin } from './WebFormsPlugin';

import roboto from '@fontsource/roboto/300.css?inline';
import icomoon from './assets/css/icomoon.css?inline';
import theme from './themes/2024-light/theme.scss?inline';
import icomoon from '../assets/css/icomoon.css?inline';
import theme from '../themes/2024-light/theme.scss?inline';
// TODO/sk: Purge it - postcss-purgecss
import primeflex from 'primeflex/primeflex.css?inline';

import demoStyles from './assets/css/style.scss?inline';
import demoStyles from '../assets/css/style.scss?inline';
import router from './router';

const styles = [roboto, icomoon, theme, primeflex, demoStyles].join('\n\n');
const stylesheet = new CSSStyleSheet();
Expand All @@ -21,4 +22,5 @@ document.adoptedStyleSheets.push(stylesheet);

const app = createApp(OdkWebFormDemo as Component);
app.use(webFormsPlugin);
app.use(router);
app.mount('#app');
16 changes: 16 additions & 0 deletions packages/web-forms/src/demo/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Component } from 'vue';
import { createRouter, createWebHashHistory } from 'vue-router';
import FormList from './FormList.vue';
import FormPreview from './FormPreview.vue';

const routes = [
{ path: '/', component: FormList as Component },
{ path: '/form/:category/:form', component: FormPreview as Component },
];

const router = createRouter({
history: createWebHashHistory(),
routes,
});

export default router;
Loading
Loading