diff --git a/ui/dev-dist/sw.js b/ui/dev-dist/sw.js index 9ebb4717..63b68ed5 100644 --- a/ui/dev-dist/sw.js +++ b/ui/dev-dist/sw.js @@ -67,7 +67,7 @@ if (!self.define) { }); }; } -define(['./workbox-a959eb95'], (function (workbox) { 'use strict'; +define(['./workbox-54d0af47'], (function (workbox) { 'use strict'; self.skipWaiting(); workbox.clientsClaim(); @@ -82,28 +82,12 @@ define(['./workbox-a959eb95'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "/index.html", - "revision": "0.jq60tbu0hgg" + "revision": "0.0b2biv3ob58" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), { allowlist: [/^\/$/], denylist: [/^\/api\//] })); - workbox.registerRoute(/\.(?:js|css|html|json)$/, new workbox.NetworkFirst({ - "cacheName": "static-resources", - plugins: [new workbox.ExpirationPlugin({ - maxEntries: 50, - maxAgeSeconds: 86400 - }), new workbox.CacheableResponsePlugin({ - statuses: [0, 200] - })] - }), 'GET'); - workbox.registerRoute(/\.(?:png|jpg|jpeg|svg|gif|webp|ico)$/, new workbox.CacheFirst({ - "cacheName": "images", - plugins: [new workbox.ExpirationPlugin({ - maxEntries: 100, - maxAgeSeconds: 2592000 - })] - }), 'GET'); })); diff --git a/ui/public/version.json b/ui/public/version.json new file mode 100644 index 00000000..b60c9c82 --- /dev/null +++ b/ui/public/version.json @@ -0,0 +1,112 @@ +{ + "releases": [ + { + "version": "1.0.14", + "buildDate": "2025-09-22", + "commit": "1c4ab4f8232b4cd2a39fa66f8101664840113ce5", + "changeLog": [ + "Yeni versiyon çıktı uyarı gelecek şekilde düzenlendi.", + "Sağ alt kısımda mesaj çıkacak ve yenile butonu ile uygulama yeni versiyona geçecektir." + ] + }, + { + "version": "1.0.13", + "buildDate": "2025-09-22", + "commit": "c5f3a65304bc3c04d89ddf2f01d02563c656b911", + "changeLog": [ + "nginx ayarları ve versiyon yenileme hakkında düzeltme" + ] + }, + { + "version": "1.0.12", + "buildDate": "2025-09-22", + "commit": "f55b777a171ec2072999e204b8e1e818fd91d8a3", + "changeLog": [ + "Versiyon yenileme sistemi güncellemesi" + ] + }, + { + "version": "1.0.11", + "buildDate": "2025-09-22", + "commit": "b2e489d7051ca47a82561cbf2674ec49dc30ed92", + "changeLog": [ + "Liste formlarda Layout görünümü düzenlemesi" + ] + }, + { + "version": "1.0.10", + "buildDate": "2025-09-22", + "commit": "b75158bc018b4d5076e0208796d68f16975e77d8", + "changeLog": [ + "EditorOptions içerisine DataSource özelliği eklendi" + ] + }, + { + "version": "1.0.9", + "buildDate": "2025-09-21", + "commit": "e14d6930c21d2b1c108f16ce675dd05474a95d9e", + "changeLog": [ + "Form komponentinin SelectBox -> lookup bilgisi varsa verileri dolduruyor" + ] + }, + { + "version": "1.0.8", + "buildDate": "2025-09-21", + "commit": "3f69cc54e94cf40db87fb23ba4cf7b311cc1f77c", + "changeLog": [ + "Listelere Grid ve Card görünümleri eklendi." + ] + }, + { + "version": "1.0.7", + "buildDate": "2025-09-20", + "commit": "8754fc65c1a855b9b625db93a4f8d39f92fa5ab8", + "changeLog": [ + "Versiyon güncellemesi için geçiş uyarı sistemi" + ] + }, + { + "version": "1.0.6", + "buildDate": "2025-09-19", + "commit": "9e85780623d940f43155474b66f2820d997abe3a", + "changeLog": [ + "Versiyon güncelleme sistemi", + "Vite.Config dosyasında hızlandırma adına güncellemeler" + ] + }, + { + "version": "1.0.5", + "buildDate": "2025-09-19", + "commit": "c947fb2a1c0979df3d7fd4dab47af7a2d370f622", + "changeLog": [ + "Form ekranındaki Butonlar güncellemeleri yapıldı", + "Edit Form ekranındaki Info butonu eklendi.", + "New Form ekranındaki Geri butonu eklendi." + ] + }, + { + "version": "1.0.4", + "buildDate": "2025-09-19", + "commit": "6766d1129d345e165282fc3ec198a168f188ab00", + "changeLog": [ + "Subformlar üzerinde extra filters ve Widget çalışmaları yapıldı." + ] + }, + { + "version": "1.0.3", + "buildDate": "2025-09-19", + "commit": "656d1626179733f8da56aa2268b852a79efe26d8", + "changeLog": [ + "Manage Grid üzerinde Extra filtre tanımlaması yapıldı." + ] + }, + { + "version": "1.0.2", + "buildDate": "2025-09-16", + "commit": "c6d2fbf30acae9c96502dfdd3846cbfbaf8af614", + "changeLog": [ + "Genel Static olan Url bilgileri kaldırıldı." + ] + } + ] +} diff --git a/ui/src/main.tsx b/ui/src/main.tsx index 0249132e..fed41ad2 100644 --- a/ui/src/main.tsx +++ b/ui/src/main.tsx @@ -11,6 +11,24 @@ import 'devextreme-react/html-editor' // // Lisansı uygulama başlamadan önce kaydediyoruz // config({ licenseKey }) +import { store } from '@/store' + +async function initVersion() { + try { + const res = await fetch('/version.json?ts=' + Date.now()) + const data = await res.json() + const latest = data?.releases?.[0]?.version + if (latest) { + store.getActions().locale.setUiVersion(latest) + } + } catch (e) { + console.warn('Versiyon okunamadı', e) + } +} + +// uygulama başlamadan bir defa çağır +initVersion() + ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render() UiEvalService.Init() diff --git a/ui/src/views/version/swRegistration.ts b/ui/src/views/version/swRegistration.ts index e683e07a..e346ed4b 100644 --- a/ui/src/views/version/swRegistration.ts +++ b/ui/src/views/version/swRegistration.ts @@ -1,23 +1,10 @@ import { registerSW } from 'virtual:pwa-register' -import { store } from '@/store' export const registerServiceWorker = () => { registerSW({ immediate: true, - async onNeedRefresh() { - try { - const res = await fetch('/version.json?ts=' + Date.now()) - const data = await res.json() - const latest = data?.releases?.[0]?.version - if (latest) { - // ✅ direkt store.dispatch ile versiyonu güncelle - store.getActions().locale.setUiVersion(latest) - } - } catch { - console.warn('Yeni versiyon bilgisi alınamadı') - } - - // ✅ yeni SW aktif olduğunda uygulamayı yenile + onNeedRefresh() { + console.log('🔔 New content available, please refresh.') window.location.reload() }, onOfflineReady() { diff --git a/ui/vite.config.ts b/ui/vite.config.ts index 99d39a56..464f3032 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -19,100 +19,98 @@ export default defineConfig(async ({ mode }) => { return { plugins: [ react(), - mode === 'production' - ? VitePWA({ - // Deploy'dan sonra otomatik güncelle - registerType: 'autoUpdate', - // Kayıt kodunu otomatik enjekte et (virtual:pwa-register yazmadan da çalışır) - injectRegister: 'auto', - // Dev ortamında SW'yi aç, prod'da kapalı tut (build edilmiş SW prod'da zaten aktif olur) - devOptions: { - enabled: mode !== 'production', - type: 'module', // Modern module worker kullan - }, + VitePWA({ + // Deploy'dan sonra otomatik güncelle + registerType: 'autoUpdate', + // Kayıt kodunu otomatik enjekte et (virtual:pwa-register yazmadan da çalışır) + injectRegister: 'auto', + // Dev ortamında SW'yi aç, prod'da kapalı tut (build edilmiş SW prod'da zaten aktif olur) + devOptions: { + enabled: mode !== 'production', + type: 'module', // Modern module worker kullan + }, - workbox: { - // Büyük asset'leri de cache'leyebil - maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, + workbox: { + // Büyük asset'leri de cache'leyebil + maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, - // EN KRİTİK: yeni SW beklemeden kontrolü alsın - clientsClaim: true, - skipWaiting: true, + // EN KRİTİK: yeni SW beklemeden kontrolü alsın + clientsClaim: true, + skipWaiting: true, - // Eski workbox cache'lerini temizle - cleanupOutdatedCaches: true, + // Eski workbox cache'lerini temizle + cleanupOutdatedCaches: true, - // SPA fallback'i API çağrılarına uygulama - navigateFallbackDenylist: [/^\/api\//], + // SPA fallback'i API çağrılarına uygulama + navigateFallbackDenylist: [/^\/api\//], - // ⭐⭐ BU KISMI EKLEYİN: Cache sorununu çözecek runtime caching - runtimeCaching: - mode === 'production' - ? [ - { - urlPattern: /\.(?:js|css|html|json)$/, - handler: 'NetworkFirst', - options: { - cacheName: 'static-resources', - expiration: { - maxEntries: 50, - maxAgeSeconds: 24 * 60 * 60, // 24 saat - }, - cacheableResponse: { - statuses: [0, 200], - }, - }, + // ⭐⭐ BU KISMI EKLEYİN: Cache sorununu çözecek runtime caching + runtimeCaching: + mode === 'production' + ? [ + { + urlPattern: /\.(?:js|css|html|json)$/, + handler: 'NetworkFirst', + options: { + cacheName: 'static-resources', + expiration: { + maxEntries: 50, + maxAgeSeconds: 24 * 60 * 60, // 24 saat }, - { - urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp|ico)$/, - handler: 'CacheFirst', - options: { - cacheName: 'images', - expiration: { - maxEntries: 100, - maxAgeSeconds: 30 * 24 * 60 * 60, // 30 gün - }, - }, + cacheableResponse: { + statuses: [0, 200], }, - ] - : [], + }, + }, + { + urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp|ico)$/, + handler: 'CacheFirst', + options: { + cacheName: 'images', + expiration: { + maxEntries: 100, + maxAgeSeconds: 30 * 24 * 60 * 60, // 30 gün + }, + }, + }, + ] + : [], - // ⭐ YENİ EKLENEN: Additional navigation route for SPA - navigateFallback: '/index.html', - navigateFallbackAllowlist: [/^(?!\/__).*/], - }, + // ⭐ YENİ EKLENEN: Additional navigation route for SPA + navigateFallback: '/index.html', + navigateFallbackAllowlist: [/^(?!\/__).*/], + }, - manifest: { - name: 'Sözsoft Kurs Platform', - short_name: 'Sözsoft Kurs Platform', - theme_color: '#FF99C8', - background_color: '#f0e7db', - display: 'standalone', - icons: [ - { - src: '/img/logo/logo-400.png', - sizes: '400x400', - type: 'image/png', - purpose: 'any maskable', - }, - { - src: '/img/logo/logo-192.png', - sizes: '192x192', - type: 'image/png', - purpose: 'any maskable', - }, - { - src: '/img/logo/logo-512.png', - sizes: '512x512', - type: 'image/png', - purpose: 'any maskable', - }, - ], - categories: ['business', 'productivity'], - description: 'Sözsoft Kurs Platform Application', + manifest: { + name: 'Sözsoft Kurs Platform', + short_name: 'Sözsoft Kurs Platform', + theme_color: '#FF99C8', + background_color: '#f0e7db', + display: 'standalone', + icons: [ + { + src: '/img/logo/logo-400.png', + sizes: '400x400', + type: 'image/png', + purpose: 'any maskable', }, - }) - : null, + { + src: '/img/logo/logo-192.png', + sizes: '192x192', + type: 'image/png', + purpose: 'any maskable', + }, + { + src: '/img/logo/logo-512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any maskable', + }, + ], + categories: ['business', 'productivity'], + description: 'Sözsoft Kurs Platform Application', + }, + }), ], server: {