Projenizdeki tüm eklentiler registerPlugins() metodu ile main.js dosyanızdan çağırılırlar.
src/main.js
// Components
import App from "./App.vue";
// Composables
import { createApp } from "vue";
// Plugins
import { registerPlugins } from "@/plugins";
const app = createApp(App);
registerPlugins(app);
app.mount("#app");
Admin eklentisi Olobase Admin ana kütüphanesinin projenize dahil edilmesini ve projenizdeki temel fonksiyonların konfigüre edilmesini ve çalışmasını sağlar. Takip eden örnekte admin eklentisine ait bir örnek gösteriliyor:
src/plugins/admin.js
import OlobaseAdmin from "olobase-admin";
import router from "@/router";
import i18n from "../i18n";
import store from "@/store";
import config from "@/_config";
import routes from "@/router/admin";
import PageNotFound from "@/views/Error404.vue";
import {
jsonServerDataProvider,
jwtAuthProvider,
} from "olobase-admin/src/providers";
import { en, tr } from "olobase-admin/src/locales";
let admin = new OlobaseAdmin(import.meta.env);
/**
* Install admin plugin
*/
export default {
install: (app, http, resources) => {
admin.setOptions({
app,
router,
resources,
store,
i18n,
dashboard: "dashboard",
downloadUrl: "/files/findOneById/",
readFileUrl: "/files/readOneById/",
title: "demo",
routes,
locales: { en, tr },
dataProvider: jsonServerDataProvider(http),
authProvider: jwtAuthProvider(http),
http,
canAction: null,
// canAction: ({ resource, action, can }) => {
// if (can(["admin"])) {
// return true;
// }
// // any other custom actions on given resource and action...
// },
config: config,
});
admin.init();
OlobaseAdmin.install(app); // install layouts & components
app.provide("i18n", i18n);
app.provide("router", router);
app.provide("admin", admin); // make injectable
app.component("PageNotFound", PageNotFound);
},
};
Admin eklentisinin temel görevleri aşağıdaki gibidir:
OlobaseAdmin nesnesi konfigurasyon için uygulamanız tarafında bulunan src/_config.js nesnesine ihtiyaç duyar.
export default {
//
// va-form component global settings
//
form: {
disableExitWithoutSave: false,
},
dateFormat: "shortFormat",
//
// va-list provider global settings
//
list: {
disableGlobalSearch: false,
disableItemsPerPage: true,
itemsPerPage: 10,
itemsPerPageOptions: [100],
},
/*
...
*/
}
OlobaseAdmin constructor metodunun çalışması için aşağıda listelenen parametrelerin tümüne ihtiyacı vardır:
Anahtar | Tür | Açıklama |
---|---|---|
router | VueRouter | Tüm genel özel rotalarınızı içerebilen Vue Router örneği. |
store | Vuex.Store | Otomatik kaynak API modülleri köprü kaydı için tüm özel modüllerinizi içerebilen Vue Store örneği. |
i18n | VueI18n | Tam yerelleştirme desteği için tüm özel yerelleştirilmiş etiketlerinizi içerebilen Vue I18n örneği. |
dashboard | string | Uygulamanızın giriş sayfasına ait rotasını belirler. Giriş sayfanızın rotasını farklılaştırmak istiyrosanız bu değere mevcut bir rota adı vermelisiniz. |
downloadUrl | string | Dosya indirme api rotasını belirler. |
readFileUrl | string | Dosya okuma api rotasını belirler. |
title | string | Uygulamanızın başlığı, uygulama çubuğu başlığında ve belge başlığında sayfa başlığından sonra gösterilecektir |
routes | object | Yönetici düzeninden devralınması gereken, kimliği doğrulanmış rotaların listesi. Tüm kaynak rotalarının CRUD sayfaları burada alt öğe olarak kaydedilecek |
locales | object | En az bir Olobase Admin yerel ayarı sağlanmalıdır; yalnızca en ve tr dilleri %100 desteklenir. |
authProvider | object | Kimlik doğrulama sözleşmesini uygulaması gereken kimlik doğrulama sağlayıcısı. |
dataProvider | object | Veri sözleşmesini uygulaması gereken veri sağlayıcı. |
resources | array | Yönetilecek tüm kaynakları içeren kaynaklar dizisi. |
http | object | İsteğe bağlı olarak eklenen özel HTTP istemcisi, this.admin.http aracılığıyla kullanılabilir. |
config | object | Alanlar veya girişler için bazı genel seçenekler ve bazı ayarlar için kullanılır. |
canAction | null|function | Herhangi bir kaynağın her eylemi için özelleştirilebilir yetki fonksiyonu. |
Olobase Admin akış şeması.
Ana VueRouter yalnızca genel sayfalara (veya vuetify-admin ile ilgili olmayan tüm diğer sayfalara) sahip olmalıdır. Bu sayfalarda herhangi bir Admin Düzeni tamamen yoktur, dolayısıyla kendi düzeninizi kullanabilirsiniz. Olobase Admin, oluşturduğu CRUD kaynak rotalarını VueRouter.addRoute() aracılığıyla eklemek için Vue Router'a ihtiyaç duyacaktır.
src/router/index.js
import { createRouter, createWebHistory } from "vue-router";
import i18n from "../i18n";
import Member from "@/layouts/Member.vue";
import Login from "@/views/Login.vue";
import ForgotPassword from "@/views/ForgotPassword";
import ResetPassword from "@/views/ResetPassword";
const routes = [
{
path: "/",
redirect: "/login",
component: Member,
children: [
{
path: "/login",
name: "login",
component: Login,
meta: {
title: i18n.global.t("routes.login"),
},
},
{
path: "/forgotPassword",
name: "forgotPassword",
component: ForgotPassword,
meta: {
title: i18n.global.t("routes.forgotPassword"),
},
},
{
path: "/resetPassword",
name: "resetPassword",
component: ResetPassword,
meta: {
title: i18n.global.t("routes.resetPassword"),
},
},
],
}
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
Varsayılan olarak yukarıdaki gibi herhangi bir kayıt veya şifre sıfırlamanın da dahil olabileceği bir giriş sayfanız olmalıdır.
Tüm özel store modüllerinizi buraya koyabilirsiniz. İster özel sayfalarınızda ister kaynak sayfalarınızda olsun, bunları istediğiniz yerde kullanmakta özgürsünüz. Olobase Admin, oluşturduğu API kaynakları modüllerini RegisterModule() aracılığıyla kaydettirmek için tam olarak örneklenmiş Vuex'e ihtiyaç duyacaktır.
İşte temel bir örnek:
src/store/index.js
import { createStore } from "vuex";
import axios from 'axios';
const store = createStore({
state: {
locale: "en",
showDialog: false,
confirm: false,
resolve: null,
reject: null,
},
actions: {
setLocale({ commit }, locale) {
commit("SET_LOCALE", locale);
},
openDialog({ commit, state }) {
commit("TOGGLE_DIALOG", true);
return new Promise((resolve, reject) => {
state.resolve = resolve;
state.reject = reject;
});
},
},
getters: {
dialog(state) {
return state.showDialog;
},
getLocale(state) {
return state.locale
}
},
mutations: {
SET_LOCALE(state, locale) {
state.locale = locale;
axios.defaults.headers.common['Client-Locale'] = locale;
},
TOGGLE_DIALOG(state, bool) {
state.showDialog = bool;
},
TOGGLE_DIALOG(state, bool) {
state.showDialog = bool;
},
TOGGLE_AGREE(state) {
state.resolve(true);
state.showDialog = false;
},
TOGGLE_CANCEL(state) {
state.resolve(false);
state.showDialog = false;
},
},
modules: {},
});
export default store;
Olobase Admin'in, alt öğeler olarak kimliği doğrulanmış tüm rotaları içerecek, yukarıdaki genel rotalardan ayrı bir temel rota formatı nesnesine ihtiyacı vardır. Bu ayrılmanın temel nedeni Vue Router alt kayıt sınırlamasından kaynaklanmaktadır. Bu nedenle en azından şimdilik OlobaseAdmin yapıcısına manuel olarak enjekte edilmesi gerekiyor. Burası, kimliği doğrulanmış tüm özel sayfalarınızı kontrol paneli, profil sayfası vb. olarak yerleştirebileceğiniz yerdir.
src/router/admin.js
import AdminLayout from "@/layouts/Admin";
import Dashboard from "@/views/Dashboard";
import Account from "@/views/Account";
import Password from "@/views/Password";
import Error404 from "@/views/Error404";
import i18n from "../i18n";
export default {
path: "",
component: AdminLayout,
meta: {
title: i18n.global.t("routes.home"),
},
children: [
{
path: "/dashboard",
name: "dashboard",
component: Dashboard,
meta: {
title: i18n.global.t("routes.dashboard"),
},
},
{
path: "/account",
name: "account",
component: Account,
meta: {
title: i18n.global.t("routes.account"),
},
},
{
path: "/password",
name: "password",
component: Password,
meta: {
title: i18n.global.t("routes.password"),
},
},
{
path: "*",
component: Error404,
meta: {
title: i18n.global.t("routes.notFound"),
},
},
],
};
Olobase Admin tarafından çözülemeyen sayfa istekleri src/views/Error404.vue bileşenine yönlendirilir. Varsayılan 404 sayfası olarak kullanılır ve özelleştirilebilir.
Loader eklentisi adından anlaşılacağı gibi temel yükleme görevlerini içerir. Aşağıda bu görevler listelenmiştir.küütüphanelerinizi .
import "./vuetify";
import Trix from "trix";
import "trix/dist/trix.css";
import "@mdi/font/css/materialdesignicons.css";
import PortalVue from "portal-vue";
import Modal from "../components/Modal";
import camelCase from "lodash/camelCase";
import upperFirst from "lodash/upperFirst";
/**
* Autoload resources
*/
const modules = import.meta.glob('@/resources/*/*.vue', { eager: true })
/**
* Dynamic vuetify components
*/
import {
VAutocomplete,
VCombobox,
} from "vuetify/components";
export default {
install: (app) => {
/**
* Register portal-vue
*/
app.use(PortalVue);
/**
* Register global modal
*/
app.component('modal', Modal);
/**
* Explicit registering of this components because dynamic
*/
app.component("VAutocomplete", VAutocomplete);
app.component("VCombobox", VCombobox);
/**
* Register application resources automatically
*/
for (let fileName in modules) {
const componentConfig = modules[fileName];
fileName = fileName
.replace(/^\.\//, "")
.replace(/\//, "")
.replace(/\.\w+$/, "");
const pathArray = fileName.split("/").slice(-2);
const componentName = upperFirst(camelCase(pathArray[0].toLowerCase() + pathArray[1]));
// register component
app.component(
componentName,
componentConfig.default || componentConfig
);
}
// end app resources
},
};
useHttp(axios) metodu bir axios örneğinden admin client elde etmek için kullanılır. Yani useHttp() metodu devreden çıkarıldığından aşağıdaki uygulamanızda aşağıdaki fonksiyonlar çalışmayacaktır.
Açıkça anlatmak gerekirse useHttp() metodu uygulamaya özgü axios interceptörler i axios örneğine atamış olur.
Uygulamaya ait birincil axios örneği plugins/index.js dosyası içerisinde yaratılır ve useHttp() metodu burada çalıştırılır.
src/plugins/index.js
import { useHttp } from "../plugins/useHttp";
import axios from "axios";
/**
* Set default global http configuration
*/
axios.defaults.timeout = 10000;
axios.defaults.baseURL = import.meta.env.VITE_API_URL;
axios.defaults.headers.common['Content-Type'] = "application/json";
axios.defaults.headers.common['Client-Locale'] = i18n.global.locale.value;
axios.interceptors.request.use(
function (config) {
let token = localStorage.getItem("token");
if (typeof token == "undefined" || token == "undefined" || token == "") {
return config;
}
config.headers["Authorization"] = "Bearer " + token;
return config;
},
function (error) {
return Promise.reject(error);
}
);
useHttp(axios);
src/plugins/useHttp.js
import i18n from "../i18n";
import store from "@/store";
import eventBus from "vuetify-admin/src/utils/eventBus";
let isRefreshing = false;
let failedQueue = [];
//
// https://github.com/Godofbrowser/axios-refresh-multiple-request/tree/master
//
const processQueue = (error, token = null) => {
failedQueue.forEach(prom => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
/**
* Http global response settings
*/
const useHttp = function (axios) {
let axiosInstance = axios;
axiosInstance.interceptors.response.use(
(response) => {
const statusOk = (response && response["status"] && response.status === 200) ? true : false;
const configUrlSegments = response.config.url.split('/');
if (
(statusOk && configUrlSegments.includes("create")) ||
(statusOk && configUrlSegments.includes("update"))
) {
eventBus.emit("last-dialog", false) // close edit modal window if it's opened
store.commit("messages/show", { type: 'success', message: i18n.global.t("form.saved") });
}
if (statusOk &&
cookies.get(cookieKey.token) &&
response.config.url == "/auth/session") {
let config = response.config;
config._retry = false; // retry value every must be false
const delayRetryRequest = new Promise((resolve) => {
setTimeout(() => {
resolve();
}, import.meta.env.VITE_SESSION_UPDATE_TIME * 60 * 1000); // every x minutes
});
return delayRetryRequest.then(() => axiosInstance(config));
}
return response;
},
/* etc .... */
}
//
// This is an example and this part of the coding has been deleted
// so it doesn't take up much space.
//
/**
* Export useHttp method
*/
export { useHttp };
Vuetify eklentisi, VuetifyJs kütüphanesine özgü konfigürasyonlarınızı içerir.
// Styles
import "vuetify/styles";
// Translations provided by Vuetify
import { en, tr } from "vuetify/locale";
import Trans from "@/i18n/translation";
const defaultLang = Trans.guessDefaultLocale();
// Composables
import { createVuetify } from "vuetify";
const defaultTheme = {
dark: false,
colors: {
background: "#FFFFFF",
surface: "#FFFFFF",
primary: localStorage.getItem("themeColor")
? localStorage.getItem("themeColor")
: "#0a7248",
secondary: "#eeeeee",
error: "#ed0505",
info: "#00CAE3",
// success: '#4CAF50',
// warning: '#FB8C00',
},
};
// Vuetify
export default createVuetify({
locale: {
locale: Trans.supportedLocales.includes(defaultLang) ? defaultLang : import.meta.env.VITE_DEFAULT_LOCALE,
fallback: "en",
messages: { tr, en },
},
theme: {
defaultTheme: "defaultTheme",
themes: {
defaultTheme,
},
},
});