base structure

This commit is contained in:
ctengiz
2024-04-15 10:00:31 +03:00
parent 19d9d24530
commit 61f5f8fe04
21 changed files with 846 additions and 55 deletions

162
svc/api/acompany.go Normal file
View 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)
}

View File

@@ -13,6 +13,6 @@ func login(w http.ResponseWriter, r *http.Request) {
return return
} }
clientResp := authResp.GetEndUserReponse() clientResp := authResp.GetEndUserResponse()
mhttp.ResponseSuccess(w, clientResp) mhttp.ResponseSuccess(w, clientResp)
} }

View File

@@ -62,7 +62,12 @@ func HttpHandler(re enums.TRunEnv) http.Handler {
// Handle valid / invalid tokens. // Handle valid / invalid tokens.
r.Use(nauth.CheckTokenValidity) 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)
}) })
}) })

View File

@@ -1,6 +1,6 @@
module bordro-esleme module bordro-esleme
go 1.22.1 go 1.22.2
toolchain go1.22.2 toolchain go1.22.2
@@ -9,5 +9,6 @@ require (
git.notitek.com.tr/common/notgo v0.0.0-20240408194744-d12ce3096580 // indirect 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/chi/v5 v5.0.12 // indirect
github.com/go-chi/cors v1.2.1 // 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 github.com/segmentio/ksuid v1.0.4 // indirect
) )

View 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)
}

View File

@@ -13,12 +13,14 @@
"build": "quasar build" "build": "quasar build"
}, },
"dependencies": { "dependencies": {
"@intlify/vite-plugin-vue-i18n": "^7.0.0",
"@quasar/extras": "^1.16.4", "@quasar/extras": "^1.16.4",
"axios": "^1.2.1", "axios": "^1.2.1",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"pinia": "^2.0.11", "pinia": "^2.0.11",
"quasar": "^2.8.0", "quasar": "^2.8.0",
"vue": "^3.4.18", "vue": "^3.4.18",
"vue-i18n": "^9.9.0",
"vue-router": "^4.0.12" "vue-router": "^4.0.12"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -8,9 +8,8 @@
// Configuration for your app // Configuration for your app
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js // 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) { module.exports = configure(function (ctx) {
return { return {
@@ -23,12 +22,14 @@ module.exports = configure(function (ctx) {
boot: [ boot: [
'axios', 'axios',
'version', 'version',
'i18n',
'pinia', 'pinia',
'bus',
], ],
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
css: [ css: [
'app.scss' 'app.scss',
], ],
// https://github.com/quasarframework/quasar/tree/dev/extras // 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 // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
build: { build: {
target: { target: {
browser: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ], browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
node: 'node20' node: 'node20',
}, },
vueRouterMode: 'history', // available values: 'hash', 'history' vueRouterMode: 'history', // available values: 'hash', 'history'
@@ -98,19 +99,34 @@ module.exports = configure(function (ctx) {
// viteVuePluginOptions: {}, // viteVuePluginOptions: {},
vitePlugins: [ vitePlugins: [
['vite-plugin-checker', { [
'vite-plugin-checker', {
eslint: { eslint: {
lintCommand: 'eslint "./**/*.{js,mjs,cjs,vue}"' lintCommand: 'eslint "./**/*.{js,mjs,cjs,vue}"',
} },
}, { server: false }] }, { 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/**'),
}
],
],
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
devServer: { devServer: {
// https: true // https: true
port:9400, port: 9403,
open: true // opens browser window automatically open: true, // opens browser window automatically
}, },
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
@@ -132,8 +148,8 @@ module.exports = configure(function (ctx) {
'Notify', 'Notify',
'Loading', 'Loading',
'Dialog', 'Dialog',
'Meta' 'Meta',
] ],
}, },
// animations: 'all', // --- includes all animations // animations: 'all', // --- includes all animations
@@ -155,7 +171,7 @@ module.exports = configure(function (ctx) {
// https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr // https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr
ssr: { ssr: {
// ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name! // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
// will mess up SSR // will mess up SSR
// extendSSRWebserverConf (esbuildConf) {}, // extendSSRWebserverConf (esbuildConf) {},
// extendPackageJson (json) {}, // extendPackageJson (json) {},
@@ -169,8 +185,8 @@ module.exports = configure(function (ctx) {
// (gets superseded if process.env.PORT is specified at runtime) // (gets superseded if process.env.PORT is specified at runtime)
middlewares: [ middlewares: [
'render' // keep this as last one 'render', // keep this as last one
] ],
}, },
// https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa // 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 // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
capacitor: { capacitor: {
hideSplashscreen: true hideSplashscreen: true,
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron // 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: { builder: {
// https://www.electron.build/configuration/configuration // 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 // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
bex: { bex: {
contentScripts: [ contentScripts: [
'my-content-script' 'my-content-script',
], ],
// extendBexScriptsConf (esbuildConf) {} // extendBexScriptsConf (esbuildConf) {}
// extendBexManifestJson (json) {} // extendBexManifestJson (json) {}
} },
} }
}); })

14
ui/src/boot/bus.js Normal file
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,10 @@
import base from "src/libjs/i18n/tr"
const prjI18n = {
menu: {
app: 'Uygulamalar'
},
Usr: {},
}
export default {...base, ...prjI18n}

View File

@@ -1,26 +1,53 @@
<template> <template>
<q-layout view="lHh Lpr lFf" style="background-color: #f8fafc;"> <q-layout view="lHh Lpr lFf" style="background-color: #f8fafc;">
<q-header class="bg-white q-py-sm" bordered> <q-drawer
<q-toolbar> 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> <template v-for="m in ld.menu" :key="m.grantKey">
<q-img src="logo.png" width="120px" fit="contain"/> <q-item :to="m.to" v-if="!m.children">
</q-toolbar-title> <q-item-section avatar v-if="m.icon">
<q-icon :name="m.icon"/>
<q-btn </q-item-section>
round <q-item-section>
flat <q-item-label>{{ m.label }}</q-item-label>
class="on-right" </q-item-section>
icon="logout" </q-item>
color="pcolor3" <q-expansion-item
@click="logout" 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-list>
</q-toolbar> </q-scroll-area>
</q-header> </q-drawer>
<q-page-container> <q-page-container>
<router-view/> <router-view/>
@@ -29,11 +56,23 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { $VERSION } from 'boot/version'
import { inject, reactive } from 'vue'
import { useLoginStore } from 'stores/login' import { useLoginStore } from 'stores/login'
import { menu } from 'src/lib/menu'
const loginStore = useLoginStore() 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 () { const logout = function () {
loginStore.logout() loginStore.logout()
} }

123
ui/src/lib/menu.js Normal file
View 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
View 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
View 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>

View 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>

View File

@@ -1,14 +1,15 @@
<template> <template>
<q-page class="flex flex-center"> <q-page padding>
<img <m-edit-header
alt="Quasar logo" show-company-select
src="~assets/quasar-logo-vertical.svg" :show-lang-selector="false"
style="width: 200px; height: 200px" />
>
</q-page> </q-page>
</template> </template>
<script setup> <script setup>
import MEditHeader from 'src/libjs/comp/MEditHeader.vue'
defineOptions({ defineOptions({
name: 'IndexPage' name: 'IndexPage'
}); });

View File

@@ -41,8 +41,7 @@ Router.beforeEach(
// instead of having to check every route record with // instead of having to check every route record with
// to.matched.some(record => record.meta.requiresAuth) // to.matched.some(record => record.meta.requiresAuth)
if (to.meta.requiresAuth && !isLoggedIn && if (to.meta.requiresAuth && !isLoggedIn && to.path !== 'login') {
((to.path !== '/') || (to.path !== 'login'))) {
// this route requires auth, check if logged in // this route requires auth, check if logged in
// if not, redirect to login page. // 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 { return {
path: '/', path: '/',
query: '', query: '',

View File

@@ -9,6 +9,11 @@ const routes = [
children: [ children: [
{ path: '', component: () => import('pages/index.vue') }, { path: '', component: () => import('pages/index.vue') },
{ path: '/panel', 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') },
] ]
}, },

View File

@@ -8,6 +8,7 @@ export const sessionName = 'bresSession'
const defaultState = { const defaultState = {
LoggedIn: false, LoggedIn: false,
IsAdmin: false,
Token: '', Token: '',
UsrKSUID: '', UsrKSUID: '',
UsrEmail: '', UsrEmail: '',