ContextPath added to dynamic urls and services

This commit is contained in:
Bahadır Sofuoğlu
2022-11-29 13:46:18 +03:00
parent 93ec659282
commit bbcebb99c5
21 changed files with 115 additions and 226 deletions

View File

@@ -2,12 +2,11 @@
import { useLayout } from '@/layout/composables/layout'; import { useLayout } from '@/layout/composables/layout';
import { computed } from 'vue'; import { computed } from 'vue';
const { layoutConfig } = useLayout(); const { layoutConfig, contextPath } = useLayout();
const logoUrl = computed(() => { const logoUrl = computed(() => {
return `layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`; return `${contextPath}layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`;
}); });
</script> </script>
<template> <template>

View File

@@ -3,7 +3,7 @@ import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
import { useLayout } from '@/layout/composables/layout'; import { useLayout } from '@/layout/composables/layout';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
const { layoutConfig, onMenuToggle } = useLayout(); const { layoutConfig, onMenuToggle, contextPath } = useLayout();
const outsideClickListener = ref(null); const outsideClickListener = ref(null);
const topbarMenuActive = ref(false); const topbarMenuActive = ref(false);
@@ -18,7 +18,7 @@ onBeforeUnmount(() => {
}); });
const logoUrl = computed(() => { const logoUrl = computed(() => {
return `layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`; return `${contextPath}layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`;
}); });
const onTopBarMenuButton = () => { const onTopBarMenuButton = () => {

View File

@@ -1,5 +1,7 @@
import { toRefs, reactive, computed } from 'vue'; import { toRefs, reactive, computed } from 'vue';
const contextPath = import.meta.env.BASE_URL;
const layoutConfig = reactive({ const layoutConfig = reactive({
ripple: false, ripple: false,
darkTheme: false, darkTheme: false,
@@ -19,17 +21,17 @@ const layoutState = reactive({
menuHoverActive: false menuHoverActive: false
}); });
export function useLayout () { export function useLayout() {
const changeThemeSettings = (theme, darkTheme) => { const changeThemeSettings = (theme, darkTheme) => {
layoutConfig.darkTheme = darkTheme; layoutConfig.darkTheme = darkTheme;
layoutConfig.theme = theme; layoutConfig.theme = theme;
}; };
const setScale = scale => { const setScale = (scale) => {
layoutConfig.scale = scale; layoutConfig.scale = scale;
}; };
const setActiveMenuItem = item => { const setActiveMenuItem = (item) => {
layoutConfig.activeMenuItem = item.value || item; layoutConfig.activeMenuItem = item.value || item;
}; };
@@ -49,5 +51,5 @@ export function useLayout () {
const isDarkTheme = computed(() => layoutConfig.darkTheme); const isDarkTheme = computed(() => layoutConfig.darkTheme);
return { layoutConfig: toRefs(layoutConfig), layoutState: toRefs(layoutState), changeThemeSettings, setScale, onMenuToggle, isSidebarActive, isDarkTheme, setActiveMenuItem }; return { contextPath, layoutConfig: toRefs(layoutConfig), layoutState: toRefs(layoutState), changeThemeSettings, setScale, onMenuToggle, isSidebarActive, isDarkTheme, setActiveMenuItem };
} }

View File

@@ -1,7 +1,8 @@
const contextPath = import.meta.env.BASE_URL;
export default class CountryService { export default class CountryService {
getCountries () { getCountries() {
return fetch('/demo/data/countries.json') return fetch(contextPath + 'demo/data/countries.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
} }

View File

@@ -1,32 +1,33 @@
const contextPath = import.meta.env.BASE_URL;
export default class CustomerService { export default class CustomerService {
getCustomersSmall () { getCustomersSmall() {
return fetch('/demo/data/customers-small.json') return fetch(contextPath + 'demo/data/customers-small.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
getCustomersMedium () { getCustomersMedium() {
return fetch('/demo/data/customers-medium.json') return fetch(contextPath + 'demo/data/customers-medium.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
getCustomersLarge () { getCustomersLarge() {
return fetch('/demo/data/customers-large.json') return fetch(contextPath + 'demo/data/customers-large.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
getCustomersXLarge () { getCustomersXLarge() {
return fetch('/demo/data/customers-xlarge.json') return fetch(contextPath + 'demo/data/customers-xlarge.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
getCustomers (params) { getCustomers(params) {
const queryParams = Object.keys(params) const queryParams = Object.keys(params)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])) .map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
.join('&'); .join('&');
return fetch('https://www.primefaces.org//demo/data/customers?' + queryParams).then(res => res.json()); return fetch('https://www.primefaces.org//demo/data/customers?' + queryParams).then((res) => res.json());
} }
} }

View File

@@ -1,13 +1,14 @@
const contextPath = import.meta.env.BASE_URL;
export default class NodeService { export default class NodeService {
getTreeTableNodes () { getTreeTableNodes() {
return fetch('/demo/data/treetablenodes.json') return fetch(contextPath + 'demo/data/treetablenodes.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.root); .then((d) => d.root);
} }
getTreeNodes () { getTreeNodes() {
return fetch('/demo/data/treenodes.json') return fetch(contextPath + 'demo/data/treenodes.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.root); .then((d) => d.root);
} }
} }

View File

@@ -1,7 +1,8 @@
const contextPath = import.meta.env.BASE_URL;
export default class PhotoService { export default class PhotoService {
getImages () { getImages() {
return fetch('/demo/data/photos.json') return fetch(contextPath + 'demo/data/photos.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
} }

View File

@@ -1,19 +1,21 @@
const contextPath = import.meta.env.BASE_URL;
export default class ProductService { export default class ProductService {
getProductsSmall () { getProductsSmall() {
return fetch('/demo/data/products-small.json') return fetch(contextPath + 'demo/data/products-small.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
getProducts () { getProducts() {
return fetch('/demo/data/products.json') return fetch(contextPath + 'demo/data/products.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
getProductsWithOrdersSmall () { getProductsWithOrdersSmall() {
return fetch('/demo/data/products-orders-small.json') return fetch(contextPath + 'demo/data/products-orders-small.json')
.then(res => res.json()) .then((res) => res.json())
.then(d => d.data); .then((d) => d.data);
} }
} }

View File

@@ -1,8 +1,8 @@
import { createRouter, createWebHistory } from 'vue-router'; import { createRouter, createWebHashHistory } from 'vue-router';
import AppLayout from '@/layout/AppLayout.vue'; import AppLayout from '@/layout/AppLayout.vue';
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHashHistory(),
routes: [ routes: [
{ {
path: '/', path: '/',

View File

@@ -3,7 +3,7 @@ import { onMounted, reactive, ref, watch } from 'vue';
import ProductService from '@/layout/service/ProductService'; import ProductService from '@/layout/service/ProductService';
import { useLayout } from '@/layout/composables/layout'; import { useLayout } from '@/layout/composables/layout';
const { isDarkTheme } = useLayout(); const { isDarkTheme, contextPath } = useLayout();
const products = ref(null); const products = ref(null);
const lineData = reactive({ const lineData = reactive({
@@ -184,7 +184,7 @@ watch(
<Column style="width: 15%"> <Column style="width: 15%">
<template #header> Image </template> <template #header> Image </template>
<template #body="slotProps"> <template #body="slotProps">
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" width="50" class="shadow-2" /> <img :src="contextPath + 'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" width="50" class="shadow-2" />
</template> </template>
</Column> </Column>
<Column field="name" header="Name" :sortable="true" style="width: 35%"></Column> <Column field="name" header="Name" :sortable="true" style="width: 35%"></Column>

View File

@@ -3,8 +3,10 @@ import { FilterMatchMode } from 'primevue/api';
import { ref, onMounted, onBeforeMount } from 'vue'; import { ref, onMounted, onBeforeMount } from 'vue';
import ProductService from '@/layout/service/ProductService'; import ProductService from '@/layout/service/ProductService';
import { useToast } from 'primevue/usetoast'; import { useToast } from 'primevue/usetoast';
import { useLayout } from '@/layout/composables/layout';
const toast = useToast(); const toast = useToast();
const { contextPath } = useLayout();
const products = ref(null); const products = ref(null);
const productDialog = ref(false); const productDialog = ref(false);
@@ -181,7 +183,7 @@ const initFilters = () => {
<Column header="Image" headerStyle="width:14%; min-width:10rem;"> <Column header="Image" headerStyle="width:14%; min-width:10rem;">
<template #body="slotProps"> <template #body="slotProps">
<span class="p-column-title">Image</span> <span class="p-column-title">Image</span>
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="shadow-2" width="100" /> <img :src="contextPath + 'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="shadow-2" width="100" />
</template> </template>
</Column> </Column>
<Column field="price" header="Price" :sortable="true" headerStyle="width:14%; min-width:8rem;"> <Column field="price" header="Price" :sortable="true" headerStyle="width:14%; min-width:8rem;">
@@ -217,7 +219,7 @@ const initFilters = () => {
</DataTable> </DataTable>
<Dialog v-model:visible="productDialog" :style="{ width: '450px' }" header="Product Details" :modal="true" class="p-fluid"> <Dialog v-model:visible="productDialog" :style="{ width: '450px' }" header="Product Details" :modal="true" class="p-fluid">
<img :src="'/demo/images/product/' + product.image" :alt="product.image" v-if="product.image" width="150" class="mt-0 mx-auto mb-5 block shadow-2" /> <img :src="contextPath + 'demo/images/product/' + product.image" :alt="product.image" v-if="product.image" width="150" class="mt-0 mx-auto mb-5 block shadow-2" />
<div class="field"> <div class="field">
<label for="name">Name</label> <label for="name">Name</label>
<InputText id="name" v-model.trim="product.name" required="true" autofocus :class="{ 'p-invalid': submitted && !product.name }" /> <InputText id="name" v-model.trim="product.name" required="true" autofocus :class="{ 'p-invalid': submitted && !product.name }" />

View File

@@ -3,7 +3,7 @@ import { useLayout } from '@/layout/composables/layout';
import { computed } from 'vue'; import { computed } from 'vue';
import AppConfig from '@/layout/AppConfig.vue'; import AppConfig from '@/layout/AppConfig.vue';
const { layoutConfig } = useLayout(); const { layoutConfig, contextPath } = useLayout();
const smoothScroll = (id) => { const smoothScroll = (id) => {
document.querySelector(id).scrollIntoView({ document.querySelector(id).scrollIntoView({
@@ -12,7 +12,7 @@ const smoothScroll = (id) => {
}; };
const logoUrl = computed(() => { const logoUrl = computed(() => {
return `layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`; return `${contextPath}layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`;
}); });
</script> </script>

View File

@@ -1,5 +1,8 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { useLayout } from '@/layout/composables/layout';
const { contextPath } = useLayout();
const customEvents = ref([ const customEvents = ref([
{ {
@@ -95,7 +98,7 @@ const horizontalEvents = ref(['2020', '2021', '2022', '2023']);
{{ slotProps.item.date }} {{ slotProps.item.date }}
</template> </template>
<template #content> <template #content>
<img v-if="slotProps.item.image" :src="'/demo/images/product/' + slotProps.item.image" :alt="slotProps.item.name" width="200" class="shadow-2 mb-3" /> <img v-if="slotProps.item.image" :src="contextPath + 'demo/images/product/' + slotProps.item.image" :alt="slotProps.item.name" width="200" class="shadow-2 mb-3" />
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore sed consequuntur error repudiandae numquam deserunt quisquam repellat libero asperiores earum nam nobis, culpa ratione quam perferendis esse, cupiditate Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore sed consequuntur error repudiandae numquam deserunt quisquam repellat libero asperiores earum nam nobis, culpa ratione quam perferendis esse, cupiditate
neque quas! neque quas!

View File

@@ -3,13 +3,13 @@ import { useLayout } from '@/layout/composables/layout';
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import AppConfig from '@/layout/AppConfig.vue'; import AppConfig from '@/layout/AppConfig.vue';
const { layoutConfig } = useLayout(); const { layoutConfig, contextPath } = useLayout();
const email = ref(''); const email = ref('');
const password = ref(''); const password = ref('');
const checked = ref(false); const checked = ref(false);
const logoUrl = computed(() => { const logoUrl = computed(() => {
return `layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`; return `${contextPath}layout/images/${layoutConfig.darkTheme.value ? 'logo-white' : 'logo-dark'}.svg`;
}); });
</script> </script>

View File

@@ -1,141 +0,0 @@
<script setup>
import { ref, onMounted, computed } from 'vue';
const icons = ref(null);
const filter = ref(null);
onMounted(() => {
fetch('/demo/data/icons.json', { headers: { 'Cache-Control': 'no-cache' } })
.then((res) => res.json())
.then((d) => {
let icons = d.icons;
let data = icons.filter((value) => {
return value.icon.tags.indexOf('deprecate') === -1;
});
data.sort((icon1, icon2) => {
if (icon1.properties.name < icon2.properties.name) return -1;
else if (icon1.properties.name > icon2.properties.name) return 1;
else return 0;
});
icons.value = data;
});
});
const filteredIcons = computed(() => {
if (filter.value) {
return icons.value.filter((icon) => {
return icon.properties.name.toLowerCase().indexOf(filter.value.toLowerCase()) > -1;
});
} else {
return icons.value;
}
});
</script>
<template>
<div>
<div class="card">
<h3>Icons</h3>
<p>PrimeVue components internally use <a href="https://github.com/primefaces/primeicons" class="font-medium">PrimeIcons</a> library, the official icons suite from <a href="https://www.primetek.com.tr" class="font-medium">PrimeTek</a>.</p>
<h5>Download</h5>
<p>PrimeIcons is available at npm, run the following command to download it to your project.</p>
<pre v-code><code>
npm install primeicons --save
</code></pre>
<h5>Getting Started</h5>
<p>PrimeIcons use the <strong>pi pi-&#123;icon&#125;</strong> syntax such as <strong>pi pi-check</strong>. A standalone icon can be displayed using an element like <i>i</i> or <i>span</i></p>
<pre v-code><code>
&lt;i class="pi pi-check"&gt;&lt;/i&gt;
&lt;i class="pi pi-times"&gt;&lt;/i&gt;
</code></pre>
<i class="pi pi-check" style="margin-right: 0.5rem"></i>
<i class="pi pi-times"></i>
<h5>Size</h5>
<p>Size of the icons can easily be changed using font-size property.</p>
<pre v-code><code>
&lt;i class="pi pi-check"&gt;&lt;/i&gt;
</code></pre>
<i class="pi pi-check"></i>
<pre v-code><code>
&lt;i class="pi pi-check" style="font-size: 2rem"&gt;&lt;/i&gt;
</code></pre>
<i class="pi pi-check" style="font-size: 2rem"></i>
<h5>Spinning Animation</h5>
<p>Special pi-spin class applies continuous rotation to an icon.</p>
<pre v-code><code>
&lt;i class="pi pi-spin pi-spinner" style="font-size: 2rem"&gt;&lt;/i&gt;
</code></pre>
<i class="pi pi-spin pi-spinner" style="font-size: 2rem"></i>
<h5>Constants</h5>
<p>PrimeIcons constants API is provided to easily choose an icon with typescript e.g. when defining a menu model.</p>
<pre v-code><code>
&lt;Menu :model="items" /&gt;
</code></pre>
<pre v-code.script><code>
import {PrimeIcons} from 'primevue/api';
export default {
data() {
return {
items: [
{
label: 'Update',
icon: PrimeIcons.REFRESH,
to: '/update'
},
{
label: 'Delete',
icon: PrimeIcons.TIMES,
to: '/delete'
}
]
}
}
}
</code></pre>
<h5>List of Icons</h5>
<p>Here is the current list of PrimeIcons, more icons are added periodically. You may also <a href="https://github.com/primefaces/primeicons/issues" class="font-medium">request new icons</a> at the issue tracker.</p>
<InputText v-model="filter" class="w-full p-3 mt-3 mb-5" placeholder="Search an icon" />
<div class="grid icons-list text-center">
<div class="col-6 sm:col-4 lg:col-3 xl:col-2 pb-5" v-for="icon of filteredIcons" :key="icon.properties.name">
<i :class="'text-2xl mb-2 pi pi-' + icon.properties.name"></i>
<div>pi-{{ icon.properties.name }}</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
@import '@/assets/demo/styles/documentation.scss';
.icons-list {
i {
color: var(--text-color-secondary);
}
}
</style>

View File

@@ -1,6 +1,9 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import ProductService from '@/layout/service/ProductService'; import ProductService from '@/layout/service/ProductService';
import { useLayout } from '@/layout/composables/layout';
const { contextPath } = useLayout();
const picklistValue = ref([ const picklistValue = ref([
[ [
@@ -76,7 +79,7 @@ const onSortChange = (event) => {
<template #list="slotProps"> <template #list="slotProps">
<div class="col-12"> <div class="col-12">
<div class="flex flex-column md:flex-row align-items-center p-3 w-full"> <div class="flex flex-column md:flex-row align-items-center p-3 w-full">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="my-4 md:my-0 w-9 md:w-10rem shadow-2 mr-5" /> <img :src="contextPath + 'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="my-4 md:my-0 w-9 md:w-10rem shadow-2 mr-5" />
<div class="flex-1 text-center md:text-left"> <div class="flex-1 text-center md:text-left">
<div class="font-bold text-2xl">{{ slotProps.data.name }}</div> <div class="font-bold text-2xl">{{ slotProps.data.name }}</div>
<div class="mb-3">{{ slotProps.data.description }}</div> <div class="mb-3">{{ slotProps.data.description }}</div>
@@ -106,7 +109,7 @@ const onSortChange = (event) => {
<span :class="'product-badge status-' + slotProps.data.inventoryStatus.toLowerCase()">{{ slotProps.data.inventoryStatus }}</span> <span :class="'product-badge status-' + slotProps.data.inventoryStatus.toLowerCase()">{{ slotProps.data.inventoryStatus }}</span>
</div> </div>
<div class="text-center"> <div class="text-center">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="w-9 shadow-2 my-3 mx-0" /> <img :src="contextPath + 'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="w-9 shadow-2 my-3 mx-0" />
<div class="text-2xl font-bold">{{ slotProps.data.name }}</div> <div class="text-2xl font-bold">{{ slotProps.data.name }}</div>
<div class="mb-3">{{ slotProps.data.description }}</div> <div class="mb-3">{{ slotProps.data.description }}</div>
<Rating :modelValue="slotProps.data.rating" :readonly="true" :cancel="false"></Rating> <Rating :modelValue="slotProps.data.rating" :readonly="true" :cancel="false"></Rating>

View File

@@ -2,6 +2,9 @@
import ProductService from '@/layout/service/ProductService'; import ProductService from '@/layout/service/ProductService';
import PhotoService from '@/layout/service/PhotoService'; import PhotoService from '@/layout/service/PhotoService';
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { useLayout } from '@/layout/composables/layout';
const { contextPath } = useLayout();
const products = ref([]); const products = ref([]);
const images = ref([]); const images = ref([]);
@@ -60,7 +63,7 @@ onMounted(() => {
<div class="product-item"> <div class="product-item">
<div class="product-item-content"> <div class="product-item-content">
<div class="mb-3"> <div class="mb-3">
<img :src="'/demo/images/product/' + product.data.image" :alt="product.data.name" class="product-image" /> <img :src="contextPath + 'demo/images/product/' + product.data.image" :alt="product.data.name" class="product-image" />
</div> </div>
<div> <div>
<h4 class="mb-1"> <h4 class="mb-1">
@@ -86,10 +89,10 @@ onMounted(() => {
<h5>Galleria</h5> <h5>Galleria</h5>
<Galleria :value="images" :responsiveOptions="galleriaResponsiveOptions" :numVisible="7" :circular="true" containerStyle="max-width: 800px; margin: auto"> <Galleria :value="images" :responsiveOptions="galleriaResponsiveOptions" :numVisible="7" :circular="true" containerStyle="max-width: 800px; margin: auto">
<template #item="slotProps"> <template #item="slotProps">
<img :src="'/' + slotProps.item.itemImageSrc" :alt="slotProps.item.alt" style="width: 100%; display: block" /> <img :src="contextPath + slotProps.item.itemImageSrc" :alt="slotProps.item.alt" style="width: 100%; display: block" />
</template> </template>
<template #thumbnail="slotProps"> <template #thumbnail="slotProps">
<img :src="'/' + slotProps.item.thumbnailImageSrc" :alt="slotProps.item.alt" tyle="width: 100%; display: block;" /> <img :src="contextPath + slotProps.item.thumbnailImageSrc" :alt="slotProps.item.alt" tyle="width: 100%; display: block;" />
</template> </template>
</Galleria> </Galleria>
</div> </div>

View File

@@ -3,6 +3,9 @@ import ProductService from '@/layout/service/ProductService';
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { useToast } from 'primevue/usetoast'; import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm'; import { useConfirm } from 'primevue/useconfirm';
import { useLayout } from '@/layout/composables/layout';
const { contextPath } = useLayout();
const display = ref(false); const display = ref(false);
const displayConfirmation = ref(false); const displayConfirmation = ref(false);
@@ -105,7 +108,7 @@ const confirm = (event) => {
<Column field="name" header="Name" :sortable="true" headerStyle="min-width:10rem;"></Column> <Column field="name" header="Name" :sortable="true" headerStyle="min-width:10rem;"></Column>
<Column header="Image" headerStyle="min-width:10rem;"> <Column header="Image" headerStyle="min-width:10rem;">
<template #body="slotProps"> <template #body="slotProps">
<img :src="'/images/product/' + slotProps.data.image" :alt="slotProps.data.image" width="100" class="shadow-2" /> <img :src="contextPath + 'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" width="100" class="shadow-2" />
</template> </template>
</Column> </Column>
<Column field="price" header="Price" :sortable="true" headerStyle="min-width:8rem;"> <Column field="price" header="Price" :sortable="true" headerStyle="min-width:8rem;">

View File

@@ -3,6 +3,9 @@ import { FilterMatchMode, FilterOperator } from 'primevue/api';
import CustomerService from '@/layout/service/CustomerService'; import CustomerService from '@/layout/service/CustomerService';
import ProductService from '@/layout/service/ProductService'; import ProductService from '@/layout/service/ProductService';
import { ref, onBeforeMount } from 'vue'; import { ref, onBeforeMount } from 'vue';
import { useLayout } from '@/layout/composables/layout';
const { contextPath } = useLayout();
const customer1 = ref(null); const customer1 = ref(null);
const customer2 = ref(null); const customer2 = ref(null);
@@ -147,7 +150,7 @@ const calculateCustomerTotal = (name) => {
</Column> </Column>
<Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem"> <Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
<template #body="{ data }"> <template #body="{ data }">
<img :alt="data.representative.name" :src="'/demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" /> <img :alt="data.representative.name" :src="contextPath + 'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span style="margin-left: 0.5em; vertical-align: middle" class="image-text">{{ data.representative.name }}</span> <span style="margin-left: 0.5em; vertical-align: middle" class="image-text">{{ data.representative.name }}</span>
</template> </template>
<template #filter="{ filterModel }"> <template #filter="{ filterModel }">
@@ -155,7 +158,7 @@ const calculateCustomerTotal = (name) => {
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter"> <MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
<template #option="slotProps"> <template #option="slotProps">
<div class="p-multiselect-representative-option"> <div class="p-multiselect-representative-option">
<img :alt="slotProps.option.name" :src="'/demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" /> <img :alt="slotProps.option.name" :src="contextPath + 'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<span style="margin-left: 0.5em; vertical-align: middle" class="image-text">{{ slotProps.option.name }}</span> <span style="margin-left: 0.5em; vertical-align: middle" class="image-text">{{ slotProps.option.name }}</span>
</div> </div>
</template> </template>
@@ -242,7 +245,7 @@ const calculateCustomerTotal = (name) => {
<Column field="activity" header="Activity" :style="{ width: '200px' }"></Column> <Column field="activity" header="Activity" :style="{ width: '200px' }"></Column>
<Column field="representative.name" header="Representative" :style="{ width: '200px' }"> <Column field="representative.name" header="Representative" :style="{ width: '200px' }">
<template #body="{ data }"> <template #body="{ data }">
<img :alt="data.representative.name" :src="'/demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" /> <img :alt="data.representative.name" :src="contextPath + 'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span style="margin-left: 0.5em; vertical-align: middle" class="image-text">{{ data.representative.name }}</span> <span style="margin-left: 0.5em; vertical-align: middle" class="image-text">{{ data.representative.name }}</span>
</template> </template>
</Column> </Column>
@@ -273,7 +276,7 @@ const calculateCustomerTotal = (name) => {
</Column> </Column>
<Column header="Image"> <Column header="Image">
<template #body="slotProps"> <template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="shadow-2" width="100" /> <img :src="contextPath + 'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="shadow-2" width="100" />
</template> </template>
</Column> </Column>
<Column field="price" header="Price" :sortable="true"> <Column field="price" header="Price" :sortable="true">
@@ -357,7 +360,7 @@ const calculateCustomerTotal = (name) => {
</Column> </Column>
<Column field="date" header="Date" style="min-width: 200px"></Column> <Column field="date" header="Date" style="min-width: 200px"></Column>
<template #groupheader="slotProps"> <template #groupheader="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" /> <img :alt="slotProps.data.representative.name" :src="contextPath + 'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text font-bold ml-2">{{ slotProps.data.representative.name }}</span> <span class="image-text font-bold ml-2">{{ slotProps.data.representative.name }}</span>
</template> </template>
<template #groupfooter="slotProps"> <template #groupfooter="slotProps">

View File

@@ -1,5 +1,8 @@
<script setup> <script setup>
import { ref, onMounted, computed } from 'vue'; import { ref, onMounted, computed } from 'vue';
import { useLayout } from '@/layout/composables/layout';
const { contextPath } = useLayout();
const icons = ref(null); const icons = ref(null);
const filter = ref(null); const filter = ref(null);
@@ -10,7 +13,7 @@ const filteredIcons = computed(() => {
}); });
onMounted(() => { onMounted(() => {
fetch('data/icons.json', { headers: { 'Cache-Control': 'no-cache' } }) fetch(contextPath + 'data/icons.json', { headers: { 'Cache-Control': 'no-cache' } })
.then((res) => res.json()) .then((res) => res.json())
.then((d) => { .then((d) => {
let icons = d.icons; let icons = d.icons;

View File

@@ -4,11 +4,14 @@ import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig(({ command }) => {
plugins: [vue()], return {
resolve: { plugins: [vue()],
alias: { base: command === 'serve' ? '' : '/sakai-vue/',
'@': fileURLToPath(new URL('./src', import.meta.url)) resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
} }
} };
}); });