base structure
This commit is contained in:
162
svc/api/acompany.go
Normal file
162
svc/api/acompany.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bordro-esleme/model/company"
|
||||
"git.makki.io/makki/libgo/cmn"
|
||||
"git.makki.io/makki/libgo/dbu"
|
||||
"git.makki.io/makki/libgo/mhttp"
|
||||
"git.makki.io/makki/libgo/nauth"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func companyGet(w http.ResponseWriter, r *http.Request) {
|
||||
/*
|
||||
tc := auth.TokenDataFromRequest(r)
|
||||
rbac, err := tc.RBAC(r.Context(), auth.MdCompany)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
if !rbac.IsGrantedOp(auth.OpRead) && !tc.IsAdmin() {
|
||||
mhttp.Forbidden(w)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
id := cmn.StrToInt64(chi.URLParam(r, "id"))
|
||||
data, err := company.DbRead(r.Context(), id)
|
||||
if err != nil {
|
||||
if dbu.IsNoRowsErr(err) {
|
||||
mhttp.NotFound(w)
|
||||
return
|
||||
} else {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
mhttp.ResponseSuccess(w, data)
|
||||
}
|
||||
|
||||
func companyCreate(w http.ResponseWriter, r *http.Request) {
|
||||
tc := nauth.TokenPayloadFromRequest(r)
|
||||
/*
|
||||
rbac, err := tc.RBAC(r.Context(), auth.MdCompany)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
if !rbac.IsGrantedOp(auth.OpCreate) && !tc.IsAdmin() {
|
||||
mhttp.Forbidden(w)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
data := company.New()
|
||||
err := cmn.BodyToJsonReq(r, &data)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = data.DbCreate(r.Context(), true, tc.UsrID())
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
mhttp.ResponseSuccess(w, data.ID)
|
||||
}
|
||||
|
||||
func companyUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
tc := nauth.TokenPayloadFromRequest(r)
|
||||
/*
|
||||
rbac, err := tc.RBAC(r.Context(), auth.MdCompany)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
if !rbac.IsGrantedOp(auth.OpUpdate) && !tc.IsAdmin() {
|
||||
mhttp.Forbidden(w)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
data := company.New()
|
||||
err := cmn.BodyToJsonReq(r, &data)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = data.DbUpdate(r.Context(), true, tc.UsrID())
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
mhttp.ResponseSuccess(w, true)
|
||||
}
|
||||
|
||||
func companyDelete(w http.ResponseWriter, r *http.Request) {
|
||||
tc := nauth.TokenPayloadFromRequest(r)
|
||||
/*
|
||||
rbac, err := tc.RBAC(r.Context(), auth.MdCompany)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
if !rbac.IsGrantedOp(auth.OpDelete) && !tc.IsAdmin() {
|
||||
mhttp.Forbidden(w)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
id := cmn.StrToInt64(chi.URLParam(r, "id"))
|
||||
|
||||
err := company.DbDelete(r.Context(), id, true, tc.UsrID())
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
mhttp.ResponseSuccess(w, true)
|
||||
}
|
||||
|
||||
func companyList(w http.ResponseWriter, r *http.Request) {
|
||||
/*
|
||||
tc := auth.TokenDataFromRequest(r)
|
||||
rbac, err := tc.RBAC(r.Context(), auth.MdCompany)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
if !rbac.IsGrantedOp(auth.OpRead) && !tc.IsAdmin() {
|
||||
mhttp.Forbidden(w)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
var data []company.Company
|
||||
|
||||
tr, err := dbu.NewTableRequestFromRequest(r)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
rp, err := dbu.NewRepoWithFile(r.Context(), "company", nil)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
respData, err := rp.MList(tr, &data)
|
||||
if err != nil {
|
||||
mhttp.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
mhttp.ResponseSuccess(w, respData)
|
||||
}
|
||||
@@ -13,6 +13,6 @@ func login(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
clientResp := authResp.GetEndUserReponse()
|
||||
clientResp := authResp.GetEndUserResponse()
|
||||
mhttp.ResponseSuccess(w, clientResp)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,12 @@ func HttpHandler(re enums.TRunEnv) http.Handler {
|
||||
// Handle valid / invalid tokens.
|
||||
r.Use(nauth.CheckTokenValidity)
|
||||
|
||||
r.Get("/sy/companies", napi.CompanyList)
|
||||
// company routes
|
||||
r.Get("/company/{id:[0-9]+}", companyGet)
|
||||
r.Get("/company", companyList)
|
||||
r.Put("/company", companyUpdate)
|
||||
r.Post("/company", companyCreate)
|
||||
r.Delete("/company/{id:[0-9]+}", companyDelete)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module bordro-esleme
|
||||
|
||||
go 1.22.1
|
||||
go 1.22.2
|
||||
|
||||
toolchain go1.22.2
|
||||
|
||||
@@ -9,5 +9,6 @@ require (
|
||||
git.notitek.com.tr/common/notgo v0.0.0-20240408194744-d12ce3096580 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.12 // indirect
|
||||
github.com/go-chi/cors v1.2.1 // indirect
|
||||
github.com/guregu/null/v5 v5.0.0 // indirect
|
||||
github.com/segmentio/ksuid v1.0.4 // indirect
|
||||
)
|
||||
|
||||
134
svc/model/company/company.go
Normal file
134
svc/model/company/company.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package company
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.makki.io/makki/libgo/dbu"
|
||||
"github.com/guregu/null/v5"
|
||||
"log/slog"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type Company struct {
|
||||
Clid int64 `db:"clid" json:"-"`
|
||||
ID int64 `db:"id"`
|
||||
Code string `db:"code"`
|
||||
Title null.String `db:"title"`
|
||||
IsActive bool `db:"is_active"`
|
||||
Notes null.String `db:"notes"`
|
||||
|
||||
Tmpl null.String `db:"tmpl"`
|
||||
}
|
||||
|
||||
func New() *Company {
|
||||
m := &Company{
|
||||
IsActive: true,
|
||||
}
|
||||
|
||||
// m.__DetailStruct__ = dbu.NewDetailData[*__DetailStruct__]("__sql_filename__", "__sql_masterlink_field__", "__struct_master_field_link__", true)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func DbRead(ctx context.Context, id int64) (*Company, error) {
|
||||
rp, err := dbu.NewRepoWithFile(ctx, "company", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := New()
|
||||
//rp.AddDetail(data.Auths)
|
||||
err = rp.Read(id, data)
|
||||
return data, err
|
||||
}
|
||||
|
||||
func (m *Company) GetIDVal() int64 {
|
||||
return m.ID
|
||||
}
|
||||
|
||||
func (m *Company) SetMasterLinkVal(masterField string, val int64) {
|
||||
reflect.ValueOf(m).Elem().FieldByName(masterField).SetInt(val)
|
||||
}
|
||||
|
||||
func DbDelete(ctx context.Context, id int64, log bool, usrID *int64) error {
|
||||
tx, err := dbu.DB.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
rp, err := dbu.NewRepoWithFile(ctx, "company", tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if log {
|
||||
var oldData *Company
|
||||
oldData, err = DbRead(ctx, id)
|
||||
if err != nil {
|
||||
return dbu.ParsedErrSuppressNoRows(err)
|
||||
}
|
||||
err = dbu.DB.LogDMLTx("d", "company", oldData.ID, usrID, "", oldData, nil, tx)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = rp.Delete(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
||||
func (m *Company) DbCreate(ctx context.Context, log bool, usrID *int64) error {
|
||||
rp, err := dbu.NewRepoWithFile(ctx, "company", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = rp.Create(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if log {
|
||||
err = dbu.DB.LogDMLTx("c", "company", m.ID, usrID, "", nil, m, nil)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Company) DbUpdate(ctx context.Context, log bool, usrID *int64) error {
|
||||
tx, err := dbu.DB.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
rp, err := dbu.NewRepoWithFile(ctx, "company", tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if log {
|
||||
var oldData *Company
|
||||
oldData, err = DbRead(ctx, m.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dbu.DB.LogDMLTx("u", "company", oldData.ID, usrID, "", oldData, m, tx)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = rp.Update(m.ID, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
@@ -13,12 +13,14 @@
|
||||
"build": "quasar build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@intlify/vite-plugin-vue-i18n": "^7.0.0",
|
||||
"@quasar/extras": "^1.16.4",
|
||||
"axios": "^1.2.1",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"pinia": "^2.0.11",
|
||||
"quasar": "^2.8.0",
|
||||
"vue": "^3.4.18",
|
||||
"vue-i18n": "^9.9.0",
|
||||
"vue-router": "^4.0.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
// Configuration for your app
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
|
||||
|
||||
|
||||
const { configure } = require('quasar/wrappers');
|
||||
|
||||
const { configure } = require('quasar/wrappers')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = configure(function (ctx) {
|
||||
return {
|
||||
@@ -23,12 +22,14 @@ module.exports = configure(function (ctx) {
|
||||
boot: [
|
||||
'axios',
|
||||
'version',
|
||||
'i18n',
|
||||
'pinia',
|
||||
'bus',
|
||||
],
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
|
||||
css: [
|
||||
'app.scss'
|
||||
'app.scss',
|
||||
],
|
||||
|
||||
// https://github.com/quasarframework/quasar/tree/dev/extras
|
||||
@@ -48,8 +49,8 @@ module.exports = configure(function (ctx) {
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
|
||||
build: {
|
||||
target: {
|
||||
browser: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
|
||||
node: 'node20'
|
||||
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||
node: 'node20',
|
||||
},
|
||||
|
||||
vueRouterMode: 'history', // available values: 'hash', 'history'
|
||||
@@ -98,19 +99,34 @@ module.exports = configure(function (ctx) {
|
||||
// viteVuePluginOptions: {},
|
||||
|
||||
vitePlugins: [
|
||||
['vite-plugin-checker', {
|
||||
[
|
||||
'vite-plugin-checker', {
|
||||
eslint: {
|
||||
lintCommand: 'eslint "./**/*.{js,mjs,cjs,vue}"'
|
||||
lintCommand: 'eslint "./**/*.{js,mjs,cjs,vue}"',
|
||||
},
|
||||
}, { server: false },
|
||||
],
|
||||
[
|
||||
'@intlify/vite-plugin-vue-i18n', {
|
||||
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
|
||||
// compositionOnly: false,
|
||||
|
||||
// if you want to use named tokens in your Vue I18n messages, such as 'Hello {name}',
|
||||
// you need to set `runtimeOnly: false`
|
||||
// runtimeOnly: false,
|
||||
|
||||
// you need to set i18n resource including paths !
|
||||
include: path.resolve(__dirname, './src/i18n/**'),
|
||||
}
|
||||
}, { server: false }]
|
||||
]
|
||||
],
|
||||
],
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
|
||||
devServer: {
|
||||
// https: true
|
||||
port:9400,
|
||||
open: true // opens browser window automatically
|
||||
port: 9403,
|
||||
open: true, // opens browser window automatically
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
|
||||
@@ -132,8 +148,8 @@ module.exports = configure(function (ctx) {
|
||||
'Notify',
|
||||
'Loading',
|
||||
'Dialog',
|
||||
'Meta'
|
||||
]
|
||||
'Meta',
|
||||
],
|
||||
},
|
||||
|
||||
// animations: 'all', // --- includes all animations
|
||||
@@ -169,8 +185,8 @@ module.exports = configure(function (ctx) {
|
||||
// (gets superseded if process.env.PORT is specified at runtime)
|
||||
|
||||
middlewares: [
|
||||
'render' // keep this as last one
|
||||
]
|
||||
'render', // keep this as last one
|
||||
],
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa
|
||||
@@ -194,7 +210,7 @@ module.exports = configure(function (ctx) {
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
|
||||
capacitor: {
|
||||
hideSplashscreen: true
|
||||
hideSplashscreen: true,
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron
|
||||
@@ -223,18 +239,18 @@ module.exports = configure(function (ctx) {
|
||||
builder: {
|
||||
// https://www.electron.build/configuration/configuration
|
||||
|
||||
appId: 'tr.com.notitek.bres'
|
||||
}
|
||||
appId: 'tr.com.notitek.bres',
|
||||
},
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
|
||||
bex: {
|
||||
contentScripts: [
|
||||
'my-content-script'
|
||||
'my-content-script',
|
||||
],
|
||||
|
||||
// extendBexScriptsConf (esbuildConf) {}
|
||||
// extendBexManifestJson (json) {}
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
14
ui/src/boot/bus.js
Normal file
14
ui/src/boot/bus.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// a Quasar CLI boot file (let's say /src/boot/bus.js)
|
||||
|
||||
import { EventBus } from 'quasar'
|
||||
import { boot } from 'quasar/wrappers'
|
||||
|
||||
export default boot(({ app }) => {
|
||||
const bus = new EventBus()
|
||||
|
||||
// for Options API
|
||||
app.config.globalProperties.$bus = bus
|
||||
|
||||
// for Composition API
|
||||
app.provide('bus', bus)
|
||||
})
|
||||
16
ui/src/boot/i18n.js
Normal file
16
ui/src/boot/i18n.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { boot } from 'quasar/wrappers'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import messages from 'src/i18n'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'tr',
|
||||
globalInjection: true,
|
||||
messages
|
||||
})
|
||||
|
||||
export default boot(({ app }) => {
|
||||
// Set i18n instance on app
|
||||
app.use(i18n)
|
||||
})
|
||||
|
||||
export { i18n }
|
||||
9
ui/src/i18n/en.js
Normal file
9
ui/src/i18n/en.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import base from "src/libjs/i18n/en"
|
||||
|
||||
const prjI18n = {
|
||||
menu: {
|
||||
app: 'Applications'
|
||||
},
|
||||
}
|
||||
|
||||
export default {...base, ...prjI18n}
|
||||
8
ui/src/i18n/index.js
Normal file
8
ui/src/i18n/index.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import enUS from './en'
|
||||
import trTR from './tr'
|
||||
|
||||
export default {
|
||||
'tr': trTR,
|
||||
'en-US': enUS,
|
||||
'en-GB': enUS,
|
||||
}
|
||||
10
ui/src/i18n/tr.js
Normal file
10
ui/src/i18n/tr.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import base from "src/libjs/i18n/tr"
|
||||
|
||||
const prjI18n = {
|
||||
menu: {
|
||||
app: 'Uygulamalar'
|
||||
},
|
||||
Usr: {},
|
||||
}
|
||||
|
||||
export default {...base, ...prjI18n}
|
||||
@@ -1,26 +1,53 @@
|
||||
<template>
|
||||
<q-layout view="lHh Lpr lFf" style="background-color: #f8fafc;">
|
||||
<q-header class="bg-white q-py-sm" bordered>
|
||||
<q-toolbar>
|
||||
<q-drawer
|
||||
v-model="ld.leftDrawerOpen"
|
||||
show-if-above
|
||||
bordered
|
||||
content-class="bg-grey-1"
|
||||
>
|
||||
<q-scroll-area class="fit">
|
||||
<q-list>
|
||||
<q-item-label header>
|
||||
<q-img src="notitek.png" width="120px" class="q-mb-lg"/>
|
||||
<br/>
|
||||
Bordro Eşleme
|
||||
<br/>
|
||||
{{ $VERSION.version }}
|
||||
<span style="font-size:0.7rem;">
|
||||
{{ $VERSION.build }}
|
||||
</span>
|
||||
</q-item-label>
|
||||
|
||||
<q-toolbar-title>
|
||||
<q-img src="logo.png" width="120px" fit="contain"/>
|
||||
</q-toolbar-title>
|
||||
|
||||
<q-btn
|
||||
round
|
||||
flat
|
||||
class="on-right"
|
||||
icon="logout"
|
||||
color="pcolor3"
|
||||
@click="logout"
|
||||
/>
|
||||
<template v-for="m in ld.menu" :key="m.grantKey">
|
||||
<q-item :to="m.to" v-if="!m.children">
|
||||
<q-item-section avatar v-if="m.icon">
|
||||
<q-icon :name="m.icon"/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ m.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-expansion-item
|
||||
v-else
|
||||
:icon="m.icon"
|
||||
:label="m.label"
|
||||
>
|
||||
<q-item v-for="c in m.children" :key="c.grantKey" :to="c.to" exact :inset-level=".5">
|
||||
<q-item-section avatar v-if="c.icon">
|
||||
<q-icon :name="c.icon"/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ c.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-expansion-item>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
|
||||
</q-list>
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
|
||||
<q-page-container>
|
||||
<router-view/>
|
||||
@@ -29,11 +56,23 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { $VERSION } from 'boot/version'
|
||||
import { inject, reactive } from 'vue'
|
||||
import { useLoginStore } from 'stores/login'
|
||||
import { menu } from 'src/lib/menu'
|
||||
|
||||
const loginStore = useLoginStore()
|
||||
|
||||
const ld = reactive({
|
||||
leftDrawerOpen: true,
|
||||
menu: menu(),
|
||||
})
|
||||
|
||||
const bus = inject('bus') // inside setup()
|
||||
bus.on('toggleLeftDrawerOpen', () => {
|
||||
ld.leftDrawerOpen = !ld.leftDrawerOpen
|
||||
})
|
||||
|
||||
const logout = function () {
|
||||
loginStore.logout()
|
||||
}
|
||||
|
||||
123
ui/src/lib/menu.js
Normal file
123
ui/src/lib/menu.js
Normal file
@@ -0,0 +1,123 @@
|
||||
import { useLoginStore } from 'stores/login'
|
||||
const store = useLoginStore()
|
||||
|
||||
|
||||
const tmenu = [
|
||||
{
|
||||
label: 'Şirket Tanımları',
|
||||
icon: 'business',
|
||||
grantKey: 'Company',
|
||||
to: '/company'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
label:'menu.masterData',
|
||||
icon: 'mdi-database-edit',
|
||||
grantKey: 'Data',
|
||||
to: null,
|
||||
children: [
|
||||
{
|
||||
label: 'menu.fiCrn',
|
||||
icon: 'mdi-server-network',
|
||||
grantKey: 'fiCrn',
|
||||
to: '/ficrn'
|
||||
},
|
||||
{
|
||||
label: 'menu.dfGeo',
|
||||
icon: 'mdi-server-network',
|
||||
grantKey: 'defGeo',
|
||||
to: '/dfgeo'
|
||||
},
|
||||
{
|
||||
label: 'menu.region',
|
||||
icon: 'mdi-server-network',
|
||||
grantKey: 'defGeo',
|
||||
to: '/region'
|
||||
},
|
||||
|
||||
{
|
||||
label: 'menu.translations',
|
||||
icon: 'mdi-translate',
|
||||
grantKey: 'Locale',
|
||||
to: '/locale'
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
label: 'menu.systemManagement',
|
||||
icon: 'build_circle',
|
||||
grantKey: 'System',
|
||||
to: null,
|
||||
children: [
|
||||
{
|
||||
label: 'menu.syusr',
|
||||
icon: 'mdi-badge-account-horizontal',
|
||||
grantKey: 'syUsr',
|
||||
to: '/syusr'
|
||||
},
|
||||
{
|
||||
label: 'menu.syunit',
|
||||
icon: 'mdi-account-group',
|
||||
grantKey: 'syUnit',
|
||||
to: '/syunit'
|
||||
},
|
||||
{
|
||||
label: 'menu.systemParams',
|
||||
icon: 'settings_applications',
|
||||
grantKey: 'syParams',
|
||||
to: '/syparams'
|
||||
},
|
||||
{
|
||||
label: 'Log Auth',
|
||||
icon: 'receipt',
|
||||
grantKey: 'LogAuth',
|
||||
to: '/logauth'
|
||||
},
|
||||
{
|
||||
label: 'Log DML',
|
||||
icon: 'receipt',
|
||||
grantKey: 'LogDML',
|
||||
to: '/logdml'
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
export const menu = function () {
|
||||
const m = tmenu.filter(m => {
|
||||
return checkGrant(m.grantKey)
|
||||
})
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
|
||||
const checkGrant = function (typ) {
|
||||
//todo:
|
||||
return true
|
||||
|
||||
if (store.IsAdmin) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (store.grantHasKey(typ)) {
|
||||
const o = store.Grants[typ]
|
||||
for (let [key, value] of Object.entries(o)) {
|
||||
if (value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const checkRprGrant = function (typ) {
|
||||
if (this.$store.IsAdmin) {
|
||||
return true
|
||||
}
|
||||
|
||||
return store.Grants.Rpr[typ]
|
||||
}
|
||||
103
ui/src/model/company.js
Normal file
103
ui/src/model/company.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { Model } from 'src/libjs/lib/model'
|
||||
import { i18n } from 'boot/i18n'
|
||||
const t = i18n.global.t
|
||||
|
||||
class Company extends Model {
|
||||
ID = null
|
||||
Code = ''
|
||||
Title = ''
|
||||
IsActive = true
|
||||
Notes = ''
|
||||
|
||||
|
||||
Tmpl = ''
|
||||
|
||||
|
||||
_colOptions = {
|
||||
ID: {
|
||||
label: t('Company.ID'),
|
||||
visible: true,
|
||||
dataType: 'text', //numeric, text, date, bool, datetime, time, inet
|
||||
sortable: true,
|
||||
showFilter: true,
|
||||
|
||||
//filterOptions: {},
|
||||
//render: (val, row) => {}
|
||||
//alias: '' //--> backend için, joinli tablolarda alias kullanımı. tableRequest'te fixFieldName cehennemine son vermek için
|
||||
|
||||
},
|
||||
|
||||
Code: {
|
||||
label: t('Company.Code'),
|
||||
visible: true,
|
||||
dataType: 'text', //numeric, text, date, bool, datetime, time, inet
|
||||
sortable: true,
|
||||
showFilter: true,
|
||||
|
||||
//filterOptions: {},
|
||||
//render: (val, row) => {}
|
||||
//alias: '' //--> backend için, joinli tablolarda alias kullanımı. tableRequest'te fixFieldName cehennemine son vermek için
|
||||
|
||||
},
|
||||
|
||||
Title: {
|
||||
label: t('Company.Title'),
|
||||
visible: true,
|
||||
dataType: 'text', //numeric, text, date, bool, datetime, time, inet
|
||||
sortable: true,
|
||||
showFilter: true,
|
||||
|
||||
//filterOptions: {},
|
||||
//render: (val, row) => {}
|
||||
//alias: '' //--> backend için, joinli tablolarda alias kullanımı. tableRequest'te fixFieldName cehennemine son vermek için
|
||||
|
||||
},
|
||||
|
||||
IsActive: {
|
||||
label: t('Company.IsActive'),
|
||||
visible: true,
|
||||
dataType: 'text', //numeric, text, date, bool, datetime, time, inet
|
||||
sortable: true,
|
||||
showFilter: true,
|
||||
|
||||
//filterOptions: {},
|
||||
//render: (val, row) => {}
|
||||
//alias: '' //--> backend için, joinli tablolarda alias kullanımı. tableRequest'te fixFieldName cehennemine son vermek için
|
||||
|
||||
},
|
||||
|
||||
Notes: {
|
||||
label: t('Company.Notes'),
|
||||
visible: true,
|
||||
dataType: 'text', //numeric, text, date, bool, datetime, time, inet
|
||||
sortable: true,
|
||||
showFilter: true,
|
||||
|
||||
//filterOptions: {},
|
||||
//render: (val, row) => {}
|
||||
//alias: '' //--> backend için, joinli tablolarda alias kullanımı. tableRequest'te fixFieldName cehennemine son vermek için
|
||||
|
||||
},
|
||||
|
||||
Tmpl: {
|
||||
label: t('Company.Tmpl'),
|
||||
visible: true,
|
||||
dataType: 'text', //numeric, text, date, bool, datetime, time, inet
|
||||
sortable: true,
|
||||
showFilter: true,
|
||||
|
||||
//filterOptions: {},
|
||||
//render: (val, row) => {}
|
||||
//alias: '' //--> backend için, joinli tablolarda alias kullanımı. tableRequest'te fixFieldName cehennemine son vermek için
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
constructor (endPoint) {
|
||||
super(endPoint)
|
||||
this._ignoredFieldsOnPost = ['GrpCode', 'ClsCode', 'SpeCode']
|
||||
}
|
||||
}
|
||||
|
||||
export default Company
|
||||
113
ui/src/pages/company.vue
Normal file
113
ui/src/pages/company.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<q-page padding>
|
||||
<m-edit-header
|
||||
title="Company Kayıtları"
|
||||
:id="model.ID"
|
||||
:show-save-cancel="true"
|
||||
@save="save"
|
||||
@cancel="cancel"
|
||||
/>
|
||||
<q-form ref="frmMain" greedy autofocus>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-md">
|
||||
|
||||
|
||||
<q-input class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl"
|
||||
v-model="model.Code"
|
||||
:label="t('Company.Code')"
|
||||
bottom-slots
|
||||
:rules="[]"
|
||||
/>
|
||||
|
||||
<q-input class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl"
|
||||
v-model="model.Title"
|
||||
:label="t('Company.Title')"
|
||||
bottom-slots
|
||||
:rules="[]"
|
||||
/>
|
||||
|
||||
<q-input class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl"
|
||||
v-model="model.IsActive"
|
||||
:label="t('Company.IsActive')"
|
||||
bottom-slots
|
||||
:rules="[]"
|
||||
/>
|
||||
|
||||
<q-input class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl"
|
||||
v-model="model.Notes"
|
||||
:label="t('Company.Notes')"
|
||||
bottom-slots
|
||||
:rules="[]"
|
||||
/>
|
||||
|
||||
<q-input class="col-xs-12 col-sm-6 col-md-4 col-lg-3 col-xl"
|
||||
v-model="model.Tmpl"
|
||||
:label="t('Company.Tmpl')"
|
||||
bottom-slots
|
||||
:rules="[]"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
|
||||
|
||||
</q-form>
|
||||
|
||||
</q-page>
|
||||
</template>
|
||||
<script setup>
|
||||
import MEditHeader from 'src/libjs/comp/MEditHeader.vue'
|
||||
import { onBeforeMount, reactive, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useLoginStore } from 'stores/login'
|
||||
import Company from 'src/model/company'
|
||||
import { rules } from 'src/libjs/lib/validation'
|
||||
import { i18n } from 'boot/i18n'
|
||||
const t = i18n.global.t
|
||||
|
||||
const frmMain = ref(null)
|
||||
|
||||
const endPoint = ref('/company')
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const store = useLoginStore()
|
||||
const model = reactive(new Company(endPoint.value))
|
||||
|
||||
const ld = reactive({
|
||||
})
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (route.params.id) {
|
||||
load()
|
||||
}
|
||||
})
|
||||
|
||||
const load = function () {
|
||||
const id = route.params.id
|
||||
if (!id) {
|
||||
return
|
||||
}
|
||||
model.read(id).then(() => {
|
||||
// do some other stuff
|
||||
})
|
||||
}
|
||||
|
||||
const save = function () {
|
||||
frmMain.value.validate().then(success => {
|
||||
if (success) {
|
||||
model.save(false)
|
||||
} else {
|
||||
// oh no, user has filled in
|
||||
// at least one invalid value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const cancel = function () {
|
||||
router.push(endPoint.value)
|
||||
}
|
||||
|
||||
</script>
|
||||
30
ui/src/pages/companyList.vue
Normal file
30
ui/src/pages/companyList.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<q-page padding>
|
||||
<m-edit-header title="Company Kayıtları"/>
|
||||
<m-list
|
||||
:url="ld.endPoint"
|
||||
:model="model"
|
||||
>
|
||||
</m-list>
|
||||
</q-page>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Company from 'src/model/company'
|
||||
import { reactive, ref } from 'vue'
|
||||
import { useQuasar } from 'quasar'
|
||||
import useLoginStore from 'stores/login'
|
||||
import MEditHeader from 'src/libjs/comp/MEditHeader.vue'
|
||||
import MList from 'src/libjs/comp/MList.vue'
|
||||
|
||||
const $q = useQuasar()
|
||||
|
||||
const store = useLoginStore()
|
||||
|
||||
const ld = reactive({
|
||||
endPoint: '/company'
|
||||
})
|
||||
|
||||
const model = ref(new Company(ld.endPoint))
|
||||
</script>
|
||||
@@ -1,14 +1,15 @@
|
||||
<template>
|
||||
<q-page class="flex flex-center">
|
||||
<img
|
||||
alt="Quasar logo"
|
||||
src="~assets/quasar-logo-vertical.svg"
|
||||
style="width: 200px; height: 200px"
|
||||
>
|
||||
<q-page padding>
|
||||
<m-edit-header
|
||||
show-company-select
|
||||
:show-lang-selector="false"
|
||||
/>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import MEditHeader from 'src/libjs/comp/MEditHeader.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'IndexPage'
|
||||
});
|
||||
|
||||
@@ -41,8 +41,7 @@ Router.beforeEach(
|
||||
// instead of having to check every route record with
|
||||
// to.matched.some(record => record.meta.requiresAuth)
|
||||
|
||||
if (to.meta.requiresAuth && !isLoggedIn &&
|
||||
((to.path !== '/') || (to.path !== 'login'))) {
|
||||
if (to.meta.requiresAuth && !isLoggedIn && to.path !== 'login') {
|
||||
// this route requires auth, check if logged in
|
||||
// if not, redirect to login page.
|
||||
|
||||
@@ -53,7 +52,7 @@ Router.beforeEach(
|
||||
}
|
||||
}
|
||||
|
||||
if ((isLoggedIn) && ((to.path === '/') || (to.path === 'login'))) {
|
||||
if (isLoggedIn && to.path === 'login') {
|
||||
return {
|
||||
path: '/',
|
||||
query: '',
|
||||
|
||||
@@ -9,6 +9,11 @@ const routes = [
|
||||
children: [
|
||||
{ path: '', component: () => import('pages/index.vue') },
|
||||
{ path: '/panel', component: () => import('pages/index.vue') },
|
||||
|
||||
{ path: '/company', component: () => import('pages/companyList.vue') },
|
||||
{ path: '/company/edit/:id', component: () => import('pages/company.vue') },
|
||||
{ path: '/company/new', component: () => import('pages/company.vue') },
|
||||
// { path: '/company/:id', component: () => import('pages/companyView.vue') },
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ export const sessionName = 'bresSession'
|
||||
|
||||
const defaultState = {
|
||||
LoggedIn: false,
|
||||
IsAdmin: false,
|
||||
Token: '',
|
||||
UsrKSUID: '',
|
||||
UsrEmail: '',
|
||||
|
||||
Reference in New Issue
Block a user