feat: update app version in ngsw-config.json; refactor service worker integration and UI components for improved functionality

This commit is contained in:
2026-05-16 21:43:47 +03:30
parent 5098c26c96
commit 938baa5833
5 changed files with 37 additions and 41 deletions
+3 -3
View File
@@ -1,9 +1,9 @@
{ {
"$schema": "./node_modules/@angular/service-worker/config/schema.json", "$schema": "./node_modules/@angular/service-worker/config/schema.json",
"appData": { "appData": {
"appVersion": "0.0.22", "appVersion": "0.0.23",
"buildDate": "2026-05-16T16:59:05.769Z", "buildDate": "2026-05-16T17:49:14.877Z",
"buildNumber": 22 "buildNumber": 23
}, },
"assetGroups": [ "assetGroups": [
{ {
@@ -2,11 +2,9 @@ import { ToastService } from '@/core/services/toast.service';
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog'; import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
import { Component, computed, inject } from '@angular/core'; import { Component, computed, inject } from '@angular/core';
import { RouterLink } from '@angular/router'; import { RouterLink } from '@angular/router';
import { SwUpdate, VersionReadyEvent } from '@angular/service-worker';
import { Button } from 'primeng/button'; import { Button } from 'primeng/button';
import { Drawer } from 'primeng/drawer'; import { Drawer } from 'primeng/drawer';
import { Ripple } from 'primeng/ripple'; import { Ripple } from 'primeng/ripple';
import { filter } from 'rxjs';
import config from 'src/config'; import config from 'src/config';
import { posAboutNamedRoutes } from '../../modules/about/constants'; import { posAboutNamedRoutes } from '../../modules/about/constants';
import { posConfigNamedRoutes } from '../../modules/configs/constants'; import { posConfigNamedRoutes } from '../../modules/configs/constants';
@@ -21,7 +19,7 @@ import { PosInfoStore } from '../../store';
}) })
export class PosMainMenuSidebarComponent extends AbstractDialog { export class PosMainMenuSidebarComponent extends AbstractDialog {
private readonly posInfoStore = inject(PosInfoStore); private readonly posInfoStore = inject(PosInfoStore);
private readonly swUpdate = inject(SwUpdate); // private readonly swUpdate = inject(SwUpdate);
private readonly toastService = inject(ToastService); private readonly toastService = inject(ToastService);
readonly posInfo = computed(() => this.posInfoStore.entity()); readonly posInfo = computed(() => this.posInfoStore.entity());
@@ -65,7 +63,7 @@ export class PosMainMenuSidebarComponent extends AbstractDialog {
]; ];
ngOnInit() { ngOnInit() {
this.isPwaBuild = this.swUpdate.isEnabled; // this.isPwaBuild = this.swUpdate.isEnabled;
if (!this.isPwaBuild) return; if (!this.isPwaBuild) return;
@@ -79,13 +77,13 @@ export class PosMainMenuSidebarComponent extends AbstractDialog {
console.log('err', err); console.log('err', err);
}); });
this.swUpdate.versionUpdates // this.swUpdate.versionUpdates
.pipe(filter((event): event is VersionReadyEvent => event.type === 'VERSION_READY')) // .pipe(filter((event): event is VersionReadyEvent => event.type === 'VERSION_READY'))
.subscribe((event) => { // .subscribe((event) => {
const appData = event.latestVersion.appData as { appVersion?: string } | undefined; // const appData = event.latestVersion.appData as { appVersion?: string } | undefined;
this.appVersion = appData?.appVersion || this.appVersion; // this.appVersion = appData?.appVersion || this.appVersion;
}); // });
this.swUpdate.checkForUpdate().catch(() => {}); // this.swUpdate.checkForUpdate().catch(() => {});
} }
} }
@@ -34,7 +34,7 @@
</article> </article>
</div> </div>
<div class="mx-4 mb-4 rounded-xl border border-surface-200 bg-surface-50 p-4 md:mx-6"> <!-- <div class="mx-4 mb-4 rounded-xl border border-surface-200 bg-surface-50 p-4 md:mx-6">
<div class="flex flex-wrap items-center justify-between gap-3"> <div class="flex flex-wrap items-center justify-between gap-3">
<div class="text-sm text-surface-700"> <div class="text-sm text-surface-700">
نسخه برنامه: نسخه برنامه:
@@ -50,7 +50,7 @@
{{ updateCtaLabel() }} {{ updateCtaLabel() }}
</button> </button>
</div> </div>
</div> </div> -->
<div class="border-t border-surface-200 bg-surface-50 px-4 py-4 md:px-6"> <div class="border-t border-surface-200 bg-surface-50 px-4 py-4 md:px-6">
<p class="text-xs leading-6 text-surface-600 md:text-sm"> <p class="text-xs leading-6 text-surface-600 md:text-sm">
@@ -1,8 +1,6 @@
import { brandingConfig } from '@/branding/branding.config'; import { brandingConfig } from '@/branding/branding.config';
import { Component, computed, inject, signal } from '@angular/core'; import { Component, computed, signal } from '@angular/core';
import { SwUpdate, VersionReadyEvent } from '@angular/service-worker';
import { ButtonDirective } from 'primeng/button'; import { ButtonDirective } from 'primeng/button';
import { filter } from 'rxjs';
@Component({ @Component({
selector: 'pos-about-page', selector: 'pos-about-page',
@@ -10,17 +8,17 @@ import { filter } from 'rxjs';
imports: [ButtonDirective], imports: [ButtonDirective],
}) })
export class PosAboutPageComponent { export class PosAboutPageComponent {
private readonly swUpdate = inject(SwUpdate); // private readonly swUpdate = inject(SwUpdate);
brandingInfo = brandingConfig; brandingInfo = brandingConfig;
appVersion = signal('0.0.0'); appVersion = signal('0.0.0');
isPwaBuild = this.swUpdate.isEnabled; // isPwaBuild = this.swUpdate.isEnabled;
isCheckingUpdate = signal(false); isCheckingUpdate = signal(false);
hasUpdate = signal(false); hasUpdate = signal(false);
isUpdated = signal(false); isUpdated = signal(false);
updateCtaLabel = computed(() => { updateCtaLabel = computed(() => {
if (!this.isPwaBuild) return 'به روزرسانی فقط در نسخه PWA'; // if (!this.isPwaBuild) return 'به روزرسانی فقط در نسخه PWA';
if (this.isUpdated()) return 'به روز است'; if (this.isUpdated()) return 'به روز است';
if (this.hasUpdate()) return 'به روزرسانی برنامه'; if (this.hasUpdate()) return 'به روزرسانی برنامه';
if (this.isCheckingUpdate()) return 'در حال بررسی...'; if (this.isCheckingUpdate()) return 'در حال بررسی...';
@@ -28,21 +26,21 @@ export class PosAboutPageComponent {
}); });
ngOnInit() { ngOnInit() {
if (!this.isPwaBuild) return; // if (!this.isPwaBuild) return;
this.loadVersion(); this.loadVersion();
this.swUpdate.versionUpdates // this.swUpdate.versionUpdates
.pipe(filter((event): event is VersionReadyEvent => event.type === 'VERSION_READY')) // .pipe(filter((event): event is VersionReadyEvent => event.type === 'VERSION_READY'))
.subscribe((event) => { // .subscribe((event) => {
const appData = event.latestVersion.appData as { appVersion?: string } | undefined; // const appData = event.latestVersion.appData as { appVersion?: string } | undefined;
this.appVersion.set(appData?.appVersion || this.appVersion()); // this.appVersion.set(appData?.appVersion || this.appVersion());
this.hasUpdate.set(true); // this.hasUpdate.set(true);
this.isUpdated.set(false); // this.isUpdated.set(false);
}); // });
} }
async onUpdateCtaClick() { async onUpdateCtaClick() {
if (!this.isPwaBuild || this.isCheckingUpdate()) return; // if (!this.isPwaBuild || this.isCheckingUpdate()) return;
if (this.hasUpdate()) { if (this.hasUpdate()) {
await this.applyUpdate(); await this.applyUpdate();
@@ -56,9 +54,9 @@ export class PosAboutPageComponent {
this.isCheckingUpdate.set(true); this.isCheckingUpdate.set(true);
this.isUpdated.set(false); this.isUpdated.set(false);
try { try {
const hasUpdate = await this.swUpdate.checkForUpdate(); // const hasUpdate = await this.swUpdate.checkForUpdate();
this.hasUpdate.set(hasUpdate); // this.hasUpdate.set(hasUpdate);
this.isUpdated.set(!hasUpdate); // this.isUpdated.set(!hasUpdate);
} finally { } finally {
this.isCheckingUpdate.set(false); this.isCheckingUpdate.set(false);
} }
@@ -67,7 +65,7 @@ export class PosAboutPageComponent {
private async applyUpdate() { private async applyUpdate() {
this.isCheckingUpdate.set(true); this.isCheckingUpdate.set(true);
try { try {
await this.swUpdate.activateUpdate(); // await this.swUpdate.activateUpdate();
this.isUpdated.set(true); this.isUpdated.set(true);
this.hasUpdate.set(false); this.hasUpdate.set(false);
window.location.reload(); window.location.reload();
@@ -7,21 +7,21 @@
} }
} @else { } @else {
@for (good of visibleGoods(); track good.id) { @for (good of visibleGoods(); track good.id) {
<div class="flex-1 bg-surface-card rounded-lg p-1 shadow-xs" (click)="addProduct(good)"> <div class="flex-1 bg-surface-card rounded-lg p-1 shadow-xs flex flex-col" (click)="addProduct(good)">
<img <img
[src]="good.image_url || goodPlaceholder" [src]="good.image_url || goodPlaceholder"
loading="lazy" loading="lazy"
decoding="async" decoding="async"
class="w-full aspect-[1.3] object-cover rounded-md" class="w-full aspect-[1.3] object-cover rounded-md shrink-0"
/> />
<div class="mt-2 text-center"> <div class="mt-2 text-center grow flex flex-col justify-between">
<span class="text-lg font-bold text-center"> <span class="text-lg font-bold text-center grow flex items-center justify-center w-full">
{{ good.name }} {{ good.name }}
@if (!good.is_default_guild_good) { @if (!good.is_default_guild_good) {
<small class="text-xs text-muted-color">*</small> <small class="text-xs text-muted-color">*</small>
} }
</span> </span>
<div class="flex items-center justify-between mt-1 w-full px-2 my-2"> <div class="flex items-center justify-between mt-1 w-full px-2 my-2 shrink-0">
<!-- <span [appPriceMask]="good.salePrice" class="text-base font-bold"></span> --> <!-- <span [appPriceMask]="good.salePrice" class="text-base font-bold"></span> -->
<button pButton type="button" icon="pi pi-plus" class="w-full!">انتخاب</button> <button pButton type="button" icon="pi pi-plus" class="w-full!">انتخاب</button>
</div> </div>