Compare commits

...

10 Commits

Author SHA1 Message Date
sockenklaus
cd7784e04f working on UserCreate form... 2023-07-12 00:44:19 +02:00
Sockenklaus
3a85d2c196 working on userform 2023-07-11 22:28:58 +02:00
Sockenklaus
428ab06fcc Started with user edit form 2023-07-11 01:03:03 +02:00
Sockenklaus
3534b9fb8d reverted back from vue typescript to javascript to fix bad performance... 2023-07-10 23:05:49 +02:00
Sockenklaus
7f33499459 tinkering with performance 2023-07-10 22:38:24 +02:00
Sockenklaus
fdb7eae847 removed unplugin. Working on better performance in dev mode... 2023-07-10 17:16:27 +02:00
Sockenklaus
360fa51607 fixed problems with tailwind overwriting naive ui styles
implemented user datatable
2023-07-09 22:37:43 +02:00
Sockenklaus
bda4b0489b first datatable 2023-07-09 18:04:40 +02:00
Sockenklaus
decf693f4f show user first impl. 2023-07-08 22:17:39 +02:00
Sockenklaus
39a28cbd14 Revert "added ssr?????"
This reverts commit 5371f784fb.
2023-07-08 18:38:18 +02:00
31 changed files with 2404 additions and 15835 deletions

View File

@@ -1,32 +1,82 @@
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
import Database from '@ioc:Adonis/Lucid/Database'
import { schema, rules } from '@ioc:Adonis/Core/Validator'
export default class UsersController {
public async index({ inertia, bouncer }: HttpContextContract) {
await bouncer.with('UserPolicy').authorize('index')
const users = await Database
const users = await Database
.from('users')
.select('id', 'username', 'is_admin')
return inertia.render('Users/Index', { users })
}
public async create({ auth, inertia }: HttpContextContract) {
if(auth.user?.isAdmin) {
inertia.render('Users/Create')
} else {
public async create({ inertia, bouncer }: HttpContextContract) {
await bouncer
.with('UserPolicy')
.authorize('create')
return inertia.render('Users/Create')
}
public async store({ bouncer, inertia, request }: HttpContextContract) {
await bouncer
.with('UserPolicy')
.authorize('store')
const newUserSchema = schema.create({
username: schema.string(
{ trim: true },
[
rules.unique({ table: 'users', column: 'username' })
]
),
is_admin: schema.boolean(),
password: schema.string([
rules.confirmed("passwordRepeat")
]),
password_repeat: schema.string(),
})
console.log(request.body())
const payload = await request.validate({ schema: newUserSchema })
console.log(payload)
if(request.qs().validate) {
console.log("darf ich jetzt einen user erstellen?")
await User.create({
username: payload.username,
isAdmin: payload.is_admin,
password: payload.password,
})
return inertia.render('Users')
}
}
public async store({}: HttpContextContract) {}
public async show({ bouncer, params, inertia }: HttpContextContract) {
const queriedUser: User = await User.findByOrFail('id', params.id)
await bouncer
.with('UserPolicy')
.authorize('show', queriedUser)
public async show({}: HttpContextContract) {}
return inertia.render('Users/Show', { user: queriedUser })
}
public async edit({}: HttpContextContract) {}
public async edit({ bouncer, params, inertia }: HttpContextContract) {
const queriedUser: User = await User.findByOrFail('id', params.id)
await bouncer
.with("UserPolicy")
.authorize('edit', queriedUser)
return inertia.render("Users/Edit", { user: queriedUser })
}
public async update({}: HttpContextContract) {}

View File

@@ -5,10 +5,18 @@ export default class UserPolicy extends BasePolicy {
public async index(user: User) {
return user.isAdmin
}
public async create(user: User) {
return user.isAdmin
}
public async show(user: User, query: User) {
return user.isAdmin || user.id === query.id
}
public async edit(user: User, query: User) {
return user.isAdmin || user.id === query.id
}
public async update(user: User, query: User) {
return user.isAdmin || user.id === query.id

3
components.d.ts vendored
View File

@@ -8,10 +8,13 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
NButton: typeof import('naive-ui')['NButton']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NDataTable: typeof import('naive-ui')['NDataTable']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NInput: typeof import('naive-ui')['NInput']
NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NText: typeof import('naive-ui')['NText']
}
}

View File

@@ -15,7 +15,6 @@ import { InertiaConfig } from '@ioc:EidelLev/Inertia';
export const inertia: InertiaConfig = {
view: 'app',
ssr: {
enabled: true,
autoreload: process.env.NODE_ENV === 'development',
enabled: false,
},
};

View File

@@ -1,9 +0,0 @@
{
"entrypoints": {
"ssr": {
"js": [
"auto/ssr.js"
]
}
}
}

View File

@@ -1,3 +0,0 @@
{
"ssr/ssr.js": "autossr.js"
}

File diff suppressed because one or more lines are too long

15713
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,7 @@
"@japa/preset-adonis": "^1.2.0",
"@japa/runner": "^2.5.1",
"@symfony/webpack-encore": "^4.1.1",
"@types/node": "^20.4.1",
"@types/proxy-addr": "^2.0.0",
"@types/source-map-support": "^0.5.6",
"@vicons/material": "^0.12.0",
@@ -77,15 +78,11 @@
"@eidellev/inertia-adonisjs": "^8.0.1",
"@inertiajs/vue3": "^1.0.9",
"@vue/compiler-sfc": "^3.3.4",
"@vue/server-renderer": "^3.3.4",
"@vue/tsconfig": "^0.1.3",
"luxon": "^3.3.0",
"proxy-addr": "^2.0.7",
"reflect-metadata": "^0.1.13",
"source-map-support": "^0.5.21",
"sqlite3": "^5.1.6",
"ts-loader": "^9.4.4",
"vue": "^3.3.4",
"webpack-node-externals": "^3.0.0"
"vue": "^3.3.4"
}
}

View File

@@ -1,5 +1,5 @@
<template>
<LoginLayout>
<LoginLayout class="w-3/5 h-3/4">
<MainNav />
<slot></slot>
@@ -7,7 +7,7 @@
</template>
<script setup>
import LoginLayout from '@/layouts/LoginLayout'
import MainNav from '@/components/MainNav'
import LoginLayout from '@/layouts/LoginLayout.vue'
import MainNav from '@/components/MainNav.vue'
</script>

View File

@@ -1,10 +1,13 @@
<template>
<main class="bg-slate-100 flex justify-center h-screen">
<div class="m-auto bg-white p-4 border rounded space-y-4 drop-shadow">
<div class="m-auto bg-white p-4 border rounded drop-shadow" :class="class">
<slot></slot>
</div>
</main>
</template>
<script setup lang="ts">
<script setup>
defineProps(['class'])
</script>

View File

@@ -1,7 +1,6 @@
import '../css/app.css'
import { createApp, h } from "vue";
import { createInertiaApp, Link } from "@inertiajs/vue3";
import '../css/app.css'
createInertiaApp({
resolve: (name) => require(`./pages/${name}`),

View File

@@ -1,6 +1,6 @@
<template>
</template>
<script setup lang="ts">
<script setup>
import { useMessage } from 'naive-ui'
import { onUpdated, onMounted } from 'vue'
@@ -15,13 +15,13 @@
displayNewMessages(props.messages)
})
function displayNewMessages(messages: any) {
function displayNewMessages(messages) {
let output: Array<Object> = []
let output = []
output = flattenObject(removeValidationErrors(messages))
output?.forEach((item: any) => {
output?.forEach((item) => {
for (let key in item) {
switch (key){
case 'error':
@@ -52,24 +52,24 @@
})
}
function removeValidationErrors(input: any) {
function removeValidationErrors(input) {
if(input === null || !input.hasOwnProperty("errors")) return input
const { errors: _, ...output } = (input as any)
const { errors: _, ...output } = (input)
return output
}
function flattenObject(input: Object) {
function flattenObject(input) {
if (input === null) return input
return Object.values(input).map((value) => Object.entries(value)).flat().reduce((acc: Array<Object>, [key, value]) => {
return Object.values(input).map((value) => Object.entries(value)).flat().reduce((acc, [key, value]) => {
acc.push({[key]: value});
return acc;
}, []);
}
function translateError(errorMsg: string) {
function translateError(errorMsg) {
switch(errorMsg.split(":")[0]) {
case 'E_INVALID_AUTH_PASSWORD':
return "Falsches Passwort eingegeben."

View File

@@ -1,41 +1,46 @@
<template>
<n-menu
<div class="flex justify-center">
<n-menu
v-model:value="activeKey"
mode="horizontal"
:options="menuOptions"
class="-mx-4"
/>
/>
</div>
</template>
<script setup lang="ts">
import type { MenuOption } from 'naive-ui'
<script setup>
import { renderIcon } from '@/util'
import { NIcon } from 'naive-ui'
import { Link, usePage } from '@inertiajs/vue3'
import { h, ref } from 'vue';
import { NIcon } from 'naive-ui'
import {
GroupsFilled as Users,
EventNoteFilled as Events,
LogOutFilled as Logout
LogOutFilled as Logout,
SettingsRound as Settings,
PersonRound as Profile,
} from '@vicons/material'
const isAdmin: boolean = (usePage().props.isAdmin as boolean)
const activeKey = ref<string>((usePage().props.request as any)?.url)
const activeKey= ref(usePage().props.request?.url)
const user = usePage().props.user
const menuOptions = []
const menuOptions: MenuOption[] = []
menuOptions.push({
label: () =>
h(
Link, {
href: "/events",
methode: "get"
method: "get"
},
() => "Veranstaltungen"
),
key: '/events',
icon: renderIcon(Events)
icon: () => { return renderIcon(Events) }
})
if(isAdmin) menuOptions.push({
if(user.is_admin) menuOptions.push({
label: () =>
h(
Link, {
@@ -45,12 +50,28 @@
() => "Benutzer"
),
key: '/users',
icon: renderIcon(Users)
icon: () => { return renderIcon(Users) }
})
menuOptions.push({
label: () =>
h(
label: "Einstellungen",
key: "einstellungen",
icon: () => { return renderIcon(Settings) },
children: [{
label: () => h(
Link, {
href: "/users/"+user.id,
method: "get",
as: "button"
},
() => "Mein Profil"
),
key: 'profile',
icon: () => { return renderIcon(Profile) }
},
{
label: () => h(
Link, {
href: "/logout",
method: "post",
@@ -59,14 +80,15 @@
() => "Abmelden"
),
key: '/logout',
icon: renderIcon(Logout)
icon: () => { return renderIcon(Logout) }
}]
})
function renderIcon(icon: any) {
/*function renderIcon(icon) {
return () => h(NIcon, null, { default: () => h(icon) })
}
}*/
</script>

View File

@@ -0,0 +1,110 @@
<template>
<n-form
:model="userModel"
:rules="rules"
label-placement="left"
require-mark-placement="right-hanging"
label-width="auto"
@submit.prevent="$emit('submit')"
>
<n-form-item label="Benutzername" path="username">
<n-input
v-model:value="userModel.username"
/>
</n-form-item>
<n-form-item label="Ist Admin?" path="is_admin">
<n-checkbox v-model:checked="userModel.is_admin" />
</n-form-item>
<n-form-item label="Passwort" path="password">
<n-input
type="password"
show-password-on="mouseclick"
placeholder="Passwort"
v-model:value="userModel.password"
@input="handlePasswordInput"
/>
</n-form-item>
<n-form-item label="Password wiederholen" path="password_repeat" ref="passwordRepeatRef">
<n-input
type="password"
:disabled="!userModel.password"
show-password-on="mouseclick"
placeholder="Passwort wiederholen"
v-model:value="userModel.password_repeat"
/>
</n-form-item>
</n-form>
<n-button
@click="validate"
>
validate
</n-button>
<div>
{{ userModel }}
</div>
</template>
<script setup>
import { router } from '@inertiajs/vue3';
import { reactive, ref } from 'vue'
const props = defineProps(['userModel'])
const emit = defineEmits(['validateUsername'])
const passwordRepeatRef = ref(null)
const rules = {
username: [{
required: true,
message: "Benutzername ist erforderlich",
}],
password: [{
required: true,
message: "Passwort ist erforderlich",
}],
password_repeat: [{
required: true,
message: "Wiederholtes Passwort ist erforderlich",
trigger: ["input", "blur"],
},{
validator: passwordStartsWith,
message: "Passwörter stimmen nicht überein",
trigger: "input",
},{
validator: passwordSame,
message: "Passwörter stimmen nicht überein",
trigger: ["blur", "password-input"],
}]
}
function passwordStartsWith(rule, value) {
return !!props.userModel.password && props.userModel.password.startsWith(value) && props.userModel.password.length >= value.length;
}
function passwordSame(rule, value) {
return value === props.userModel.password;
}
function usernameUnique(rule, value) {
}
function validate() {
console.log("vue validate")
router.post('/users?validate=true', {
username: props.userModel.username,
is_admin: props.userModel.is_admin,
password: props.userModel.password,
password_repeat: props.userModel.password_repeat,
} )
}
function handlePasswordInput() {
if(props.userModel.password_repeat) {
passwordRepeatRef.value?.validate({ trigger: "password-input" })
}
}
</script>

View File

@@ -0,0 +1,29 @@
<template>
<div class="flex justify-between mb-4">
<n-button
:renderIcon="() => { return renderIcon(Back)}"
@click="$emit('clickBack')"
>
Zurück
</n-button>
<n-button
secondary
type="primary"
:renderIcon="() => { return renderIcon(Save) }"
@click="$emit('clickSave')"
>
Speichern
</n-button>
</div>
</template>
<script setup>
import { renderIcon } from '@/util'
import {
ArrowBackRound as Back,
SaveRound as Save,
} from '@vicons/material'
</script>

View File

@@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="ts">
<script setup>
import BELayout from '@/layouts/BELayout.vue'
import FlashMessages from '@/components/FlashMessages.vue'
@@ -17,9 +17,7 @@ defineOptions({
layout: BELayout
})
const props = defineProps({
flashMessages: Object
})
const props = defineProps(['flashMessages'])
</script>

View File

@@ -12,15 +12,12 @@
</div>
</template>
<script setup lang="ts">
<script setup>
import { ref } from 'vue'
import FlashMessages from '@/components/FlashMessages.vue'
const props = defineProps({
test: String,
flashMessages: Object
})
const props = defineProps(['test', 'flashMessages'])
const helloWorld = ref<String>("helloWorld")
const helloWorld = ref("helloWorld")
</script>

View File

@@ -37,7 +37,6 @@
<div class="flex justify-center">
<n-button
class="bg-[#18A058]"
type="success"
@click="onClickLogin"
:disabled="!form.password || !form.username"
@@ -46,10 +45,9 @@
</n-form>
</template>
<script setup lang="ts">
<script setup>
import { ref } from 'vue'
import { router } from '@inertiajs/vue3'
import type { FormInst } from 'naive-ui'
import LoginLayout from '@/layouts/LoginLayout.vue'
import FlashMessages from '@/components/FlashMessages.vue'
@@ -61,7 +59,7 @@
password: '',
})
const formRef = ref<FormInst | null>(null)
const formRef = ref(null)
const rules = ref({
username: {

View File

@@ -1,3 +1,33 @@
<template>
<UserNav
@clickBack="() => { router.get('/users') }"
/>
<UserForm
:userModel="form"
/>
</template>
</template>
<script setup>
import BELayout from '@/layouts/BELayout.vue'
import UserForm from '@/components/Users/UserForm.vue'
import UserNav from '@/components/Users/UserNav.vue'
import { router, useForm } from '@inertiajs/vue3'
import { renderIcon } from '@/util'
import {
ArrowBackRound as Back,
SaveRound as Save
} from '@vicons/material'
defineOptions({ layout: BELayout })
const form = useForm({
username: null,
password: null,
is_admin: false,
password_repeat: null,
})
</script>

View File

@@ -0,0 +1,68 @@
<template>
<UserNav
@clickBack="() => { router.get('/users') }"
/>
<n-form
:model="userModel"
label-placement="left"
require-mark-placement="right-hanging"
label-width="auto"
>
<n-form-item label="ID" path="id">
<n-text>{{ userModel.id }}</n-text>
</n-form-item>
<n-form-item label="Benutzername" path="username">
<n-input
class="align-middle"
v-model:value="userModel.username"
/>
</n-form-item>
<n-form-item label="Ist Admin?" path="is_admin">
<n-checkbox v-model:checked="userModel.is_admin"/>
</n-form-item>
<n-form-item label="Passwort" path="password">
<n-input
type="password"
show-password-on="mouseclick"
placeholder="Passwort"
v-model:value="userModel.password"
/>
</n-form-item>
<n-form-item label="Passwort wiederholen" path="password_repeat">
<n-input
type="password"
show-password-on="mouseclick"
placeholder="Passwort wiederholen"
v-model:value="userModel.password_repeat"
/>
</n-form-item>
</n-form>
{{ userModel }}
</template>
<script setup>
import BELayout from '@/layouts/BELayout.vue'
import UserNav from '@/components/Users/UserNav.vue'
import { router } from '@inertiajs/vue3'
import { renderIcon } from '@/util'
import { h, reactive } from 'vue'
import { NIcon } from 'naive-ui'
import {
ArrowBackFilled as Back
} from '@vicons/material'
defineOptions({
layout: BELayout
})
const props = defineProps(['user'])
const userModel = reactive(props.user)
</script>

View File

@@ -3,25 +3,99 @@
<FlashMessages
:messages="props.flashMessages"
/>
</n-message-provider>
<div>
Bin in Users
</div>
<div>
{{ users }}
</div>
</n-message-provider>
<div class="flex flex-row-reverse mb-2">
<n-button
class="items-end"
secondary
type="primary"
:renderIcon="() => { return renderIcon(Plus) }"
:onClick="() => { router.get('/users/create') }"
>
Neuer Benutzer</n-button>
</div>
<n-data-table
:columns="columns"
:data="users"
row-class-name="group"
/>
</template>
<script setup lang="ts">
<script setup>
import { h } from 'vue'
import BELayout from '@/layouts/BELayout.vue'
import FlashMessages from '@/components/FlashMessages.vue'
import { NIcon, NButton } from 'naive-ui'
import { router } from '@inertiajs/vue3'
import {
AdminPanelSettingsFilled as Admin,
EditRound as Edit,
DeleteRound as Delete,
PlusRound as Plus,
} from '@vicons/material'
defineOptions({ layout: BELayout })
const props = defineProps({
users: Object,
flashMessages: Object
})
const props = defineProps(['users', 'flashMessages'])
const columns = [
{
title: "Admin",
key: "is_admin",
align: "center",
render (row) {
if(row.is_admin) {
return renderIcon(Admin, "align-middle")
}
}
},
{
title: "Benutzername",
key: "username",
},
{
title: "Aktionen",
key: "actions",
className: "space-x-4",
render(row) {
let arr = []
arr[0] = h(
NButton,
{
class: "invisible group-hover:visible align-middle",
circle: true,
onClick: () => { clickEdit(row.id) },
renderIcon: () => { return renderIcon(Edit) },
},
)
arr[1] = h(
NButton,
{
class: "invisible group-hover:visible align-middle",
secondary: true,
circle: true,
type: "error",
onClick: () => { clickDelete(row.id) },
renderIcon: () => { return renderIcon(Delete) },
},
)
return arr
}
}
]
function clickEdit(id){
router.get('users/'+id+'/edit')
}
function clickDelete(id){
console.log("Delete clicked: "+id)
}
function renderIcon(icon, className = "") {
return h(NIcon, { component: icon, class: className, size: 20 })
}
</script>

View File

@@ -0,0 +1,11 @@
<template>
</template>
<script setup>
import BELayout from '@/layouts/BELayout.vue'
defineOptions({ layout: BELayout })
</script>

View File

@@ -1,16 +0,0 @@
import { createSSRApp, h } from 'vue';
import { renderToString } from '@vue/server-renderer';
import { createInertiaApp } from '@inertiajs/vue3';
export default function render(page) {
return createInertiaApp({
page,
render: renderToString,
resolve: (name) => require(`./pages/${name}`),
setup({ app, props, plugin }) {
return createSSRApp({
render: () => h(app, props),
}).use(plugin);
},
});
}

View File

@@ -0,0 +1,6 @@
import { h } from "vue"
import { NIcon } from 'naive-ui'
export function renderIcon(icon, className = "", size = 20) {
return h(NIcon, { component: icon, class: className, size: size })
}

View File

@@ -9,7 +9,7 @@
@entryPointScripts('app')
<title>enzos-events</title>
@inertiaHead
<meta name="naive-ui-style" />
</head>
<body>
@inertia

View File

@@ -8,11 +8,11 @@
|
*/
import Inertia from '@ioc:EidelLev/Inertia';
import Inertia from '@ioc:EidelLev/Inertia'
Inertia.share({
errors: ({ session }) => session.flashMessages.get('errors'),
request: ({ request }) => request,
isAdmin: ({ auth }) => auth.user?.isAdmin,
user: ({ auth }) => auth.user,
flashMessages: ({ session }) => session.flashMessages.all(),
}).version(() => Inertia.manifestFile('public/assets/manifest.json'));
}).version(() => Inertia.manifestFile('public/assets/manifest.json'))

View File

@@ -9,6 +9,7 @@
],
"compilerOptions": {
"outDir": "build",
"allowJs": true,
"rootDir": "./",
"sourceMap": true,
"paths": {
@@ -35,7 +36,8 @@
"@eidellev/inertia-adonisjs",
"@adonisjs/lucid",
"@adonisjs/auth",
"@adonisjs/bouncer"
"@adonisjs/bouncer",
"node"
]
}
}

View File

@@ -1,13 +0,0 @@
{
// tsconfig.vue.json
"extends": "@vue/tsconfig/tsconfig.json",
"include": [
"./resources/js/**/*"
],
"compilerOptions": {
"paths": {
"@/*": ["./resources/js/"]
}
}
}

View File

@@ -1,4 +1,4 @@
const { join } = require('path')
const { join, resolve } = require('path')
const Encore = require('@symfony/webpack-encore')
const Components = require('unplugin-vue-components/webpack')
const { NaiveUiResolver } = require('unplugin-vue-components/resolvers')
@@ -47,7 +47,7 @@ Encore.setPublicPath('/assets')
| entrypoints.
|
*/
Encore.addEntry('app', './resources/js/app.ts')
Encore.addEntry('app', './resources/js/app.js')
/*
|--------------------------------------------------------------------------
@@ -187,10 +187,8 @@ Encore.enableVueLoader(() => {}, {
version: 3,
runtimeCompilerBuild: false,
useJsx: false
}).enableTypeScriptLoader(config => {
config.configFile = 'tsconfig.vue.json'
}).addAliases({
'@': join(__dirname, 'resources/js')
'@': join(__dirname, 'resources/js'),
}).configureDefinePlugin(options => {
options['__VUE_OPTIONS_API__'] = true
options['__VUE_PROD_DEVTOOLS__'] = false

View File

@@ -1,208 +0,0 @@
const { join } = require('path')
const Encore = require('@symfony/webpack-encore')
const Components = require('unplugin-vue-components/webpack')
const { NaiveUiResolver } = require('unplugin-vue-components/resolvers')
const nodeExternals = require('webpack-node-externals')
/*
|--------------------------------------------------------------------------
| Encore runtime environment
|--------------------------------------------------------------------------
*/
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev')
}
/*
|--------------------------------------------------------------------------
| Output path
|--------------------------------------------------------------------------
|
| The output path for writing the compiled files. It should always
| be inside the public directory, so that AdonisJS can serve it.
|
*/
Encore.setOutputPath('./inertia/ssr')
/*
|--------------------------------------------------------------------------
| Public URI
|--------------------------------------------------------------------------
|
| The public URI to access the static files. It should always be
| relative from the "public" directory.
|
*/
Encore.setPublicPath('/ssr')
/*
|--------------------------------------------------------------------------
| Entrypoints
|--------------------------------------------------------------------------
|
| Entrypoints are script files that boots your frontend application. Ideally
| a single entrypoint is used by majority of applications. However, feel
| free to add more (if required).
|
| Also, make sure to read the docs on "Assets bundler" to learn more about
| entrypoints.
|
*/
Encore.addEntry('ssr', './resources/js/ssr.js')
/*
|--------------------------------------------------------------------------
| Isolated entrypoints
|--------------------------------------------------------------------------
|
| Treat each entry point and its dependencies as its own isolated module.
|
*/
Encore.disableSingleRuntimeChunk()
/*
|--------------------------------------------------------------------------
| Cleanup output folder
|--------------------------------------------------------------------------
|
| It is always nice to cleanup the build output before creating a build. It
| will ensure that all unused files from the previous build are removed.
|
*/
Encore.cleanupOutputBeforeBuild()
/*
|--------------------------------------------------------------------------
| Assets versioning
|--------------------------------------------------------------------------
|
| Enable assets versioning to leverage lifetime browser and CDN cache
|
*/
Encore.enableVersioning(Encore.isProduction())
/*
|--------------------------------------------------------------------------
| Configure dev server
|--------------------------------------------------------------------------
|
| Here we configure the dev server to enable live reloading for edge templates.
| Remember edge templates are not processed by Webpack and hence we need
| to watch them explicitly and livereload the browser.
|
*/
Encore.configureDevServerOptions((options) => {
/**
* Normalize "options.static" property to an array
*/
if (!options.static) {
options.static = []
} else if (!Array.isArray(options.static)) {
options.static = [options.static]
}
/**
* Enable live reload and add views directory
*/
options.liveReload = true
options.static.push({
directory: join(__dirname, './resources/views'),
watch: true,
})
})
/*
|--------------------------------------------------------------------------
| CSS precompilers support
|--------------------------------------------------------------------------
|
| Uncomment one of the following lines of code to enable support for your
| favorite CSS precompiler
|
*/
// Encore.enableSassLoader()
// Encore.enableLessLoader()
// Encore.enableStylusLoader()
/*
|--------------------------------------------------------------------------
| CSS loaders
|--------------------------------------------------------------------------
|
| Uncomment one of the following line of code to enable support for
| PostCSS or CSS.
|
*/
Encore.enablePostCssLoader()
// Encore.configureCssLoader(() => {})
/*
|--------------------------------------------------------------------------
| Enable Vue loader
|--------------------------------------------------------------------------
|
| Uncomment the following lines of code to enable support for vue. Also make
| sure to install the required dependencies.
|
*/
Encore.enableVueLoader(() => {}, {
version: 3,
runtimeCompilerBuild: false,
useJsx: false,
}).enableTypeScriptLoader(config => {
config.configFile = 'tsconfig.vue.json'
}).addAliases({
'@': join(__dirname, 'resources/js')
}).configureDefinePlugin(options => {
options['__VUE_OPTIONS_API__'] = true
options['__VUE_PROD_DEVTOOLS__'] = false
}).addPlugin( Components({
resolvers: [NaiveUiResolver()]
}))
/*
|--------------------------------------------------------------------------
| Configure logging
|--------------------------------------------------------------------------
|
| To keep the terminal clean from unnecessary info statements , we only
| log warnings and errors. If you want all the logs, you can change
| the level to "info".
|
*/
const config = Encore.getWebpackConfig()
config.infrastructureLogging = {
level: 'warn',
}
config.stats = 'errors-warnings'
/*
|--------------------------------------------------------------------------
| SSR Config
|--------------------------------------------------------------------------
|
*/
//config.externals = [require('webpack-node-externals')()]
config.externals = [
nodeExternals({
allowlist: ['@inertiajs/core', '@inertiajs/vue3'],
}),
]
config.externalsPresets = { node: true }
config.output = {
libraryTarget: 'commonjs2',
filename: 'ssr.js',
path: join(__dirname, './inertia/ssr'),
}
config.experiments = { outputModule: true }
/*
|--------------------------------------------------------------------------
| Export config
|--------------------------------------------------------------------------
|
| Export config for webpack to do its job
|
*/
module.exports = config