Skip to content

Commit b39e1a8

Browse files
committed
Initial public release
0 parents  commit b39e1a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+24935
-0
lines changed

.editorconfig

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
indent_size = 2
5+
indent_style = space
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.gitignore

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
node_modules
2+
lib
3+
dist
4+
.nuxt
5+
playground/.nuxt
6+
7+
src/runtime/css/output.css
8+
9+
graphql/translations.graphql
10+
11+
npmBuild/
12+
13+
playground/translations.graphql
14+
15+
drupal/frontend_routing.settings.yml
16+
17+
.npm
18+
.idea/

.nuxtrc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
imports.autoImport=false
2+
typescript.includeWorkspace=true

.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v20

.prettierrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"proseWrap": "always",
3+
"semi": false,
4+
"singleQuote": true,
5+
"arrowParens": "always",
6+
"printWidth": 80,
7+
"trailingComma": "all"
8+
}

README.md

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# VuePal
2+
3+
VuePal provides a bridge between Drupal and Vue. It comes with a set of components and
4+
composables to make your life easier when working with Drupal.
5+
6+
## Frontend Routing
7+
8+
```ts [nuxt.config.ts]
9+
export default defineNuxtConfig({
10+
vuepal: {
11+
frontendRouting: {
12+
enabled: true,
13+
langcodes: ['de', 'fr', 'en'],
14+
outputPath: './../drupal/config/default/frontend_routing.settings.yml',
15+
},
16+
},
17+
})
18+
```
19+
20+
With this feature enabled, you can create a static frontend page in Nuxt and still use all the routing features of
21+
Drupal in your frontend application. You can define your aliases in the frontend page using `definePageMeta`. The module
22+
will automatically create a Drupal configuration file that can be imported and processed by the
23+
[Drupal frontend_routing](https://www.drupal.org/project/frontend_routing) module.
24+
25+
```ts [pages/static-page/example.vue]
26+
definePageMeta({
27+
name: 'static-page-example',
28+
drupalFrontendRoute: true,
29+
languageMapping: {
30+
de: '/de/statisch',
31+
fr: '/fr/statique',
32+
en: '/en/static',
33+
},
34+
})
35+
```
36+
37+
## Drupal Route
38+
39+
```ts [nuxt.config.ts]
40+
export default defineNuxtConfig({
41+
vuepal: {
42+
drupalRoute: {
43+
enabled: true,
44+
},
45+
},
46+
})
47+
```
48+
49+
This option enables the `useDrupalRoute()` composable.
50+
This composable provides the necessary GraphQL fragment and query to fetch the route data and metatags of a Drupal page.
51+
52+
## Admin Toolbar
53+
54+
```ts [nuxt.config.ts]
55+
export default defineNuxtConfig({
56+
vuepal: {
57+
adminToolbar: {
58+
enabled: true,
59+
},
60+
},
61+
})
62+
```
63+
64+
The admin toolbar component fetches the Drupal administration menu and displays it in your frontend application.
65+
![toolbar.png](/screenshots/toolbar.png)
66+
67+
### Usage
68+
69+
```vue
70+
71+
<template>
72+
<ClientOnly>
73+
<div v-if="drupalUser.accessToolbar && !isEditing">
74+
<VuepalAdminToolbar :key="language" />
75+
</div>
76+
</ClientOnly>
77+
</template>
78+
79+
80+
<script setup lang="ts">
81+
const route = useRoute()
82+
const drupalUser = useDrupalUser()
83+
const language = useCurrentLanguage()
84+
const isEditing = computed(
85+
() =>
86+
!!(route.query.blokkliEditing || route.query.blokkliPreview) &&
87+
drupalUser.value.accessToolbar,
88+
)
89+
</script>
90+
```
91+
92+
## LocalTasks
93+
94+
```ts [nuxt.config.ts]
95+
export default defineNuxtConfig({
96+
vuepal: {
97+
localTasks: {
98+
enabled: true,
99+
},
100+
},
101+
})
102+
```
103+
104+
The local tasks component fetches the local tasks of a Drupal page and displays them in your frontend application.
105+
![localtasks.png](/screenshots/localtasks.png)
106+
107+
```vue
108+
109+
<template>
110+
<ClientOnly>
111+
<div class="flex">
112+
<div class="mx-auto w-auto bg-white py-8 xl:min-w-[1174px]">
113+
<VuepalLocalTasks />
114+
</div>
115+
</div>
116+
</ClientOnly>
117+
</template>
118+
```
119+
120+
## Full Configuration
121+
122+
Example of a full VuePal configuration in the `nuxt.config.ts` file.
123+
124+
```ts
125+
export default defineNuxtConfig({
126+
vuepal: {
127+
adminToolbar: {
128+
enabled: true,
129+
},
130+
localTasks: {
131+
enabled: true,
132+
},
133+
drupalRoute: {
134+
enabled: true,
135+
},
136+
frontendRouting: {
137+
enabled: true,
138+
langcodes: ['de', 'fr', 'en'],
139+
outputPath: './../drupal/config/default/frontend_routing.settings.yml',
140+
},
141+
devMode: {
142+
enabled: true,
143+
url: `https://${NUXT_REQUEST_HOST}`,
144+
forceHttps: true,
145+
},
146+
},
147+
})
148+
```

app/vuepal.adapter.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { defineVuepalAdapter } from '#vuepal/types'
2+
import { computed } from '#imports'
3+
4+
export default defineVuepalAdapter(() => {
5+
return {
6+
getAdminMenu() {
7+
return Promise.resolve(undefined)
8+
},
9+
getCurrentLanguage() {
10+
return computed(() => 'de')
11+
},
12+
}
13+
})

build.config.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineBuildConfig } from 'unbuild'
2+
3+
export default defineBuildConfig({
4+
externals: [
5+
'#imports',
6+
'defu',
7+
'unplugin',
8+
'magic-string',
9+
'estree-walker',
10+
'acorn',
11+
'pathe',
12+
'webpack-sources',
13+
'webpack-virtual-modules',
14+
'@jridgewell/sourcemap-codec',
15+
],
16+
})

css/index.css

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
@import './../src/runtime/components/AdminToolbar/Palette/index.css';
2+
3+
@tailwind base;
4+
@tailwind components;
5+
@tailwind utilities;
6+
7+
.vuepal-admin-toolbar {
8+
@apply relative top-0 left-0 w-full bg-white shadow-md font-sans;
9+
z-index: 900001;
10+
background: white;
11+
font-size: 14px;
12+
--vuepal-environment-color: #ccc;
13+
border-top: 6px solid var(--vuepal-environment-color);
14+
15+
a {
16+
@apply flex px-15 py-10 text-black justify-between items-center hover:bg-slate-100 no-underline whitespace-nowrap;
17+
svg {
18+
@apply w-[14px] h-[14px];
19+
}
20+
}
21+
22+
> ul {
23+
@apply flex m-0 list-none p-0;
24+
margin-left: min(5vw, 32px);
25+
margin-right: min(5vw, 48px);
26+
ul {
27+
@apply absolute bg-white list-none p-0 min-w-[200px];
28+
box-shadow: 0 8px 14px rgba(0, 0, 0, 0.15);
29+
}
30+
31+
> li > ul {
32+
top: 100%;
33+
left: 0;
34+
35+
> li ul {
36+
left: 100%;
37+
top: 0;
38+
}
39+
}
40+
}
41+
li {
42+
position: relative;
43+
&:hover {
44+
> a {
45+
background: #eee;
46+
}
47+
}
48+
}
49+
}
50+
51+
.vuepal-admin-toolbar-icon {
52+
@apply w-18 h-18;
53+
background: currentColor;
54+
display: inline-block;
55+
margin-right: 0.5em;
56+
-webkit-mask-position: center center;
57+
mask-position: center center;
58+
-webkit-mask-size: 17px 17px;
59+
mask-size: 17px 17px;
60+
-webkit-mask-repeat: no-repeat;
61+
mask-repeat: no-repeat;
62+
}
63+
64+
.vuepal-admin-toolbar-link {
65+
@apply py-18;
66+
67+
&.vp-is-first {
68+
@apply py-20;
69+
}
70+
71+
&[data-route-name='<front>'] {
72+
@apply h-full;
73+
padding: 0;
74+
width: 54px;
75+
.vuepal-admin-toolbar-icon {
76+
width: 100%;
77+
height: 100%;
78+
-webkit-mask-size: 28px 28px;
79+
mask-size: 28px 28px;
80+
mask-position: 14px center;
81+
background: var(--vuepal-environment-color);
82+
}
83+
.vuepal-admin-toolbar-text {
84+
display: none;
85+
}
86+
}
87+
}
88+
89+
.vuepal-local-tasks > ul {
90+
@apply list-none flex gap-15;
91+
a {
92+
@apply flex items-center py-0 px-16 h-[43px] font-bold no-underline text-[15px] font-sans rounded-full;
93+
&.vp-is-active,
94+
&:hover {
95+
background: #d9e0f9;
96+
color: #043cad;
97+
}
98+
}
99+
}

eslint.config.mjs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// @ts-check
2+
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
3+
4+
// Run `npx @eslint/config-inspector` to inspect the resolved config interactively
5+
export default createConfigForNuxt({
6+
features: {
7+
// Rules for module authors
8+
tooling: true,
9+
// Rules for formatting
10+
stylistic: false,
11+
},
12+
dirs: {
13+
src: ['./playground'],
14+
},
15+
})
16+
.override('nuxt/vue/rules', {
17+
rules: {
18+
'vue/no-v-html': 0,
19+
'vue/no-v-text-v-html-on-component': 0,
20+
'vue/multi-word-component-names': 0,
21+
'vue/no-empty-component-block': 'error',
22+
'vue/padding-line-between-blocks': 'error',
23+
'vue/no-v-for-template-key': 'error',
24+
'vue/prefer-true-attribute-shorthand': 'error',
25+
'vue/component-api-style': 'error',
26+
'vue/block-lang': [
27+
'error',
28+
{
29+
script: {
30+
lang: 'ts',
31+
},
32+
},
33+
],
34+
'vue/block-order': [
35+
'error',
36+
{
37+
order: [['script', 'template'], 'style'],
38+
},
39+
],
40+
'vue/html-self-closing': [
41+
'error',
42+
{
43+
html: {
44+
void: 'always',
45+
},
46+
},
47+
],
48+
'vue/no-deprecated-slot-attribute': [
49+
'error',
50+
{
51+
ignore: [],
52+
},
53+
],
54+
},
55+
})
56+
.override('nuxt/typescript/rules', {
57+
rules: {
58+
'@typescript-eslint/no-explicit-any': 'warn',
59+
'@typescript-eslint/ban-ts-comment': 'off',
60+
'@typescript-eslint/no-empty-object-type': 'off',
61+
},
62+
})
63+
.override('nuxt/tooling/regexp', {
64+
rules: {
65+
'regexp/no-super-linear-backtracking': 'off',
66+
'regexp/optimal-quantifier-concatenation': 'off',
67+
'regexp/no-unused-capturing-group': 'off',
68+
},
69+
})

graphql/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)