Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-05-12 11:54:12 +03:00
parent a4f7d5b071
commit f9a035d11d
6 changed files with 122 additions and 181 deletions

View File

@@ -1,135 +0,0 @@
/* eslint-disable */
/**
* THIS FILE IS GENERATED AUTOMATICALLY.
* 1. DO NOT edit this file directly as it won't do anything.
* 2. EDIT the original quasar.config file INSTEAD.
* 3. DO NOT git commit this file. It should be ignored.
*
* This file is still here because there was an error in
* the original quasar.config file and this allows you to
* investigate the Node.js stack error.
*
* After you fix the original file, this file will be
* deleted automatically.
**/
// quasar.config.js
import { defineConfig } from "@quasar/app-webpack/wrappers";
var quasar_config_default = defineConfig(() => {
const apiBaseUrl = (process.env.VITE_API_BASE_URL || "/api").trim();
return {
/* =====================================================
APP INFO
===================================================== */
productName: "Baggi BSS",
productDescription: "Baggi Tekstil Business Support System",
/* =====================================================
BOOT FILES
===================================================== */
boot: ["dayjs", "locale", "resizeObserverGuard"],
/* =====================================================
GLOBAL CSS
===================================================== */
css: ["app.css"],
/* =====================================================
ICONS / FONTS
===================================================== */
extras: [
"roboto-font",
"material-icons"
],
/* =====================================================
BUILD (PRODUCTION)
===================================================== */
build: {
vueRouterMode: "hash",
env: {
VITE_API_BASE_URL: apiBaseUrl
},
esbuildTarget: {
browser: ["es2022", "firefox115", "chrome115", "safari14"],
node: "node20"
},
// Cache & performance
gzip: true,
preloadChunks: true
},
/* =====================================================
DEV SERVER (LOCAL)
===================================================== */
devServer: {
server: { type: "http" },
port: 9e3,
open: true,
client: {
overlay: {
errors: true,
warnings: false,
runtimeErrors: false
}
},
// DEV proxy (CORS'suz)
proxy: [
{
context: ["/api"],
target: "http://localhost:8080",
changeOrigin: true,
secure: false,
ws: true,
timeout: 0,
proxyTimeout: 0
}
]
},
/* =====================================================
QUASAR FRAMEWORK
===================================================== */
framework: {
config: {
notify: {
position: "top",
timeout: 2500
}
},
lang: "tr",
plugins: [
"Loading",
"Dialog",
"Notify"
]
},
animations: [],
/* =====================================================
SSR / PWA (DISABLED)
===================================================== */
ssr: {
prodPort: 3e3,
middlewares: ["render"],
pwa: false
},
pwa: {
workboxMode: "GenerateSW"
},
/* =====================================================
MOBILE / DESKTOP
===================================================== */
capacitor: {
hideSplashscreen: true
},
electron: {
preloadScripts: ["electron-preload"],
inspectPort: 5858,
bundler: "packager",
builder: {
appId: "baggisowtfaresystem"
}
},
bex: {
extraScripts: []
}
};
});
export {
quasar_config_default as default
};

View File

@@ -173,6 +173,7 @@ import { usePermissionStore } from 'stores/permissionStore'
import { useI18n } from 'src/composables/useI18n'
import { UI_LANGUAGE_OPTIONS } from 'src/i18n/languages'
import { useLocaleStore } from 'src/stores/localeStore'
import { activityLogsMenuItem, getAuthUserId } from 'src/modules/activityLogs'
/* ================= STORES ================= */
@@ -365,18 +366,6 @@ const menuItems = [
permission: 'system:update'
},
{
label: 'Loglar',
to: '/app/activity-logs',
permission: 'system:read'
},
{
label: 'Test Mail',
to: '/app/test-mail',
permission: 'system:update'
},
{
label: 'Piyasa Mail Eşleştirme',
to: '/app/market-mail-mapping',
@@ -385,6 +374,27 @@ const menuItems = [
]
},
{
label: 'SüperAdmin',
icon: 'admin_panel_settings',
onlyUserIds: activityLogsMenuItem.onlyUserIds,
children: [
{
label: 'Log İzleme',
to: activityLogsMenuItem.to,
permission: activityLogsMenuItem.permission,
onlyUserIds: activityLogsMenuItem.onlyUserIds
},
{
label: 'Test Mail',
to: '/app/test-mail',
permission: 'system:update',
onlyUserIds: activityLogsMenuItem.onlyUserIds
}
]
},
{
label: 'Dil Çeviri',
icon: 'translate',
@@ -416,6 +426,16 @@ const menuItems = [
/* ================= FILTERED MENU ================= */
function isAllowedForUser (item) {
const only = item?.onlyUserIds
if (!Array.isArray(only) || only.length === 0) return true
const id = getAuthUserId(auth.user)
if (id == null) return false
return only.includes(id)
}
const filteredMenu = computed(() => {
if (!perm.loaded) return []
@@ -424,9 +444,10 @@ const filteredMenu = computed(() => {
.map(item => {
if (item.children) {
if (!isAllowedForUser(item)) return null
const children = item.children.filter(c =>
perm.hasApiPermission(c.permission)
isAllowedForUser(c) && perm.hasApiPermission(c.permission)
)
if (!children.length) return null
@@ -437,6 +458,10 @@ const filteredMenu = computed(() => {
}
}
if (!isAllowedForUser(item)) {
return null
}
if (!perm.hasApiPermission(item.permission)) {
return null
}

View File

@@ -1,5 +1,5 @@
<template>
<q-page v-if="canReadUser" class="act-page with-bg">
<q-page v-if="isAllowed" class="act-page with-bg">
<!-- =======================================================
🔍 FILTER BAR
@@ -218,14 +218,14 @@
<script setup>
import { ref,onMounted, watch } from 'vue'
import { ref, computed, onMounted, watch } from 'vue'
import { date } from 'quasar'
import { useActivityLogStore } from 'src/stores/activityLogStore'
import { useAuthStore } from 'stores/authStore.js'
import { usePermission } from 'src/composables/usePermission'
import { isActivityLogsAllowedUser } from 'src/modules/activityLogs'
const { canRead, canUpdate } = usePermission()
const canReadUser = canRead('user')
const { canUpdate } = usePermission()
const canUpdateUser = canUpdate('user')
const diffDialog = ref(false)
@@ -236,6 +236,7 @@ const selectedDiff = ref({
})
const store = useActivityLogStore()
const auth = useAuthStore()
const isAllowed = computed(() => isActivityLogsAllowedUser(auth.user))
const categoryOptions = [
{ label: 'Auth', value: 'auth' },

View File

@@ -1,27 +1,30 @@
<template>
<q-page v-if="canReadOrder" class="pcmm-page q-pa-md">
<div class="pcmm-header row items-center q-col-gutter-md">
<div class="col">
<div class="text-h6">Maliyet Parca Eslestirme</div>
<div class="text-caption text-grey-7">
V3 Urun Ilk Grubu (42. ozellik) + Urun Ana/Alt Grup + URETIM Parca Bolum + Hammadde Turleri eslestirmesi (URETIM mk_ tablolarinda tutulur)
<div class="pcmm-top">
<div class="pcmm-header row items-center q-col-gutter-md">
<div class="col">
<div class="text-h6">Maliyet Parca Eslestirme</div>
<div class="text-caption text-grey-7">
V3 Urun Ilk Grubu (42. ozellik) + Urun Ana/Alt Grup + URETIM Parca Bolum + Hammadde Turleri eslestirmesi (URETIM mk_ tablolarinda tutulur)
</div>
</div>
<div class="col-auto">
<q-btn
color="primary"
icon="refresh"
label="Yenile"
:loading="loading"
@click="refreshAll"
/>
</div>
</div>
<div class="col-auto">
<q-btn
color="primary"
icon="refresh"
label="Yenile"
:loading="loading"
@click="refreshAll"
/>
</div>
<q-separator class="q-my-md" />
</div>
<q-separator class="q-my-md" />
<q-table
<div class="pcmm-table-wrap">
<q-table
class="ol-table pcmm-table"
flat
bordered
@@ -34,6 +37,7 @@
no-data-label="Kayit bulunamadi"
:rows-per-page-options="[0]"
hide-bottom
sticky-header
>
<template #header-cell="props">
<q-th :props="props">
@@ -279,7 +283,8 @@
</q-select>
</q-td>
</template>
</q-table>
</q-table>
</div>
</q-page>
<q-page v-else class="q-pa-md flex flex-center">
@@ -862,6 +867,11 @@ onMounted(async () => {
<style scoped>
.pcmm-page {
background: #fafafa;
/* Prevent page scroll; table body will scroll inside .pcmm-table-wrap */
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
}
.pcmm-header {
@@ -869,6 +879,16 @@ onMounted(async () => {
margin: 0 auto;
}
.pcmm-top {
flex: 0 0 auto;
}
.pcmm-table-wrap {
flex: 1 1 auto;
min-height: 0; /* important for flex overflow scrolling */
overflow: auto;
}
.pcmm-form {
max-width: 1200px;
margin: 0 auto;
@@ -905,6 +925,14 @@ onMounted(async () => {
line-height: 1.15;
}
/* Keep q-table top controls visible while scrolling (like sticky headers). */
.pcmm-table :deep(.q-table__top) {
position: sticky;
top: 0;
z-index: 3;
background: #fafafa;
}
.pcmm-header-cell {
display: flex;
align-items: flex-start;

View File

@@ -5,6 +5,7 @@ import routes from 'src/router/routes.js'
import { useAuthStore } from 'stores/authStore'
import { usePermissionStore } from 'stores/permissionStore'
import { getAuthUserId } from 'src/modules/activityLogs'
export default route(function () {
@@ -54,6 +55,16 @@ export default route(function () {
return next('/first-password-change')
}
/* ================= USER ID RESTRICTIONS ================= */
const onlyUserIds = to.meta?.onlyUserIds
if (Array.isArray(onlyUserIds) && onlyUserIds.length > 0) {
const id = getAuthUserId(auth.user)
if (id == null || !onlyUserIds.includes(id)) {
return next('/unauthorized')
}
}
/* ================= ADMIN ================= */

View File

@@ -1,3 +1,5 @@
import { activityLogsRoute } from 'src/modules/activityLogs'
// src/router/routes.js
const routes = [
@@ -53,6 +55,21 @@ const routes = [
]
},
/* ==========================================================
🚫 UNAUTHORIZED
========================================================== */
{
path: '/unauthorized',
component: () => import('layouts/EmptyLayout.vue'),
children: [
{
path: '',
name: 'unauthorized',
component: () => import('pages/Unauthorized.vue')
}
]
},
/* ==========================================================
🏠 MAIN APP
@@ -110,6 +127,10 @@ const routes = [
meta: { permission: 'system:update' }
},
/* ================= ACTIVITY LOGS ================= */
activityLogsRoute,
/* ================= FINANCE ================= */
@@ -203,23 +224,13 @@ const routes = [
},
/* ================= LOGS ================= */
{
path: 'activity-logs',
name: 'activity-logs',
component: () => import('pages/ActivityLogs.vue'),
meta: { permission: 'system:read' }
},
/* ================= TEST MAIL ================= */
{
path: 'test-mail',
name: 'test-mail',
component: () => import('pages/TestMail.vue'),
meta: { permission: 'system:update' }
meta: { permission: 'system:update', onlyUserIds: [5] }
},
{