diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index 826b721e8f..ab8fc582e9 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -2,9 +2,9 @@ name: 'PR Flow'
on:
push:
- branches: [feat/*, fix/*, custom/*]
+ branches: [feat/*, fix/*, custom/*, refactor/*]
pull_request:
- branches: [feat/*, fix/*, custom/*]
+ branches: [feat/*, fix/*, custom/*, refactor/*]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
diff --git a/apps/assistant-panel/src/app/app.component.ts b/apps/assistant-panel/src/app/app.component.ts
new file mode 100644
index 0000000000..be7ad09471
--- /dev/null
+++ b/apps/assistant-panel/src/app/app.component.ts
@@ -0,0 +1,39 @@
+import { Component, inject, OnInit } from '@angular/core';
+import { PlaceOS_Service } from '@placeos/common';
+
+@Component({
+ selector: 'app-root',
+ template: `
+
- {{ time | date: 'shortTime' }} + {{ time() | date: 'shortTime' }}
@if (!hide_qr && checkin) { @@ -124,7 +131,7 @@ import { PanelStateService } from './panel-state.service'; [class.w-56]="show_qr" >{{ 'APP.CONCIERGE.ASSETS_ITEM_LOADING' | translate }}
@@ -434,7 +448,7 @@ import { AssetManagerStateService } from './asset-manager-state.service';{{ 'APP.CONCIERGE.ASSETS_ITEM_DELETE_MSG' | translate }} @@ -463,7 +477,7 @@ import { AssetManagerStateService } from './asset-manager-state.service';
@@ -483,7 +497,18 @@ import { AssetManagerStateService } from './asset-manager-state.service';
}
`,
],
- standalone: false,
+ imports: [
+ CommonModule,
+ RouterModule,
+ MatProgressSpinnerModule,
+ TranslatePipe,
+ MatRippleModule,
+ SimpleTableComponent,
+ MatTabsModule,
+ MatTooltipModule,
+ ImageCarouselComponent,
+ IconComponent,
+ ],
})
export class AssetViewComponent extends AsyncHandler {
private _route = inject(ActivatedRoute);
@@ -492,8 +517,8 @@ export class AssetViewComponent extends AsyncHandler {
private _dialog = inject(MatDialog);
private _org = inject(OrganisationService);
- public loading = false;
- public deleting = false;
+ public readonly loading = signal(false);
+ public readonly deleting = signal(false);
public readonly item = this._state.active_product;
public readonly asset_list = combineLatest([
this.item,
@@ -523,9 +548,9 @@ export class AssetViewComponent extends AsyncHandler {
public readonly _tooltip_el = viewChild(CustomTooltipComponent);
public async deleteAsset() {
- this.deleting = true;
+ this.deleting.set(true);
await this._state.deleteActiveProduct();
- this.deleting = false;
+ this.deleting.set(false);
this._router.navigate([this._state.base_route, 'list', 'items']);
this.closeTooltip();
}
@@ -547,7 +572,7 @@ export class AssetViewComponent extends AsyncHandler {
}
public ngOnInit() {
- this.loading = true;
+ this.loading.set(true);
this.subscription(
'route.params',
this._route.paramMap.subscribe((params) => {
@@ -563,7 +588,7 @@ export class AssetViewComponent extends AsyncHandler {
);
this._state.active_product.pipe(first((_) => !!_)).subscribe(() => {
this.clearTimeout('no_asset');
- this.loading = false;
+ this.loading.set(false);
});
}
@@ -579,9 +604,11 @@ export class AssetViewComponent extends AsyncHandler {
);
if (resp.reason !== 'done') return;
resp.loading('Deleting asset...');
- await deleteAsset(asset.id).toPromise();
+ await lastValueFrom(deleteAsset(asset.id));
await removeAssetRequests(asset.id);
- const item = await this._state.active_product.pipe(first()).toPromise();
+ const item = await lastValueFrom(
+ this._state.active_product.pipe(first()),
+ );
this._state.setOptions({ active_item: '' });
setTimeout(
() => this._state.setOptions({ active_item: item.id }),
@@ -602,8 +629,10 @@ export class AssetViewComponent extends AsyncHandler {
);
if (resp.reason !== 'done') return;
resp.loading('Deleting purchase order...');
- await deleteAssetPurchaseOrder(asset.id).toPromise();
- const item = await this._state.active_product.pipe(first()).toPromise();
+ await lastValueFrom(deleteAssetPurchaseOrder(asset.id));
+ const item = await lastValueFrom(
+ this._state.active_product.pipe(first()),
+ );
this._state.setOptions({ active_item: '' });
setTimeout(
() => this._state.setOptions({ active_item: item.id }),
diff --git a/apps/concierge/src/app/asset-manager/duration.pipe.ts b/apps/concierge/src/app/asset-manager/duration.pipe.ts
index 25ec5b144b..7ecefb475f 100644
--- a/apps/concierge/src/app/asset-manager/duration.pipe.ts
+++ b/apps/concierge/src/app/asset-manager/duration.pipe.ts
@@ -3,7 +3,6 @@ import { formatDuration } from '@placeos/common';
@Pipe({
name: 'duration',
- standalone: false,
})
export class DurationFormatPipe implements PipeTransform {
public transform(value: number, short = true): string {
diff --git a/apps/concierge/src/app/asset-manager/split-join.pipe.ts b/apps/concierge/src/app/asset-manager/split-join.pipe.ts
index 20b410d1e8..1338c68ada 100644
--- a/apps/concierge/src/app/asset-manager/split-join.pipe.ts
+++ b/apps/concierge/src/app/asset-manager/split-join.pipe.ts
@@ -2,7 +2,6 @@ import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'splitjoin',
- standalone: false,
})
export class SplitJoinPipe implements PipeTransform {
public transform(value: string, split = '_', join = ' '): string {
diff --git a/apps/concierge/src/app/building-manager/auto-release-settings-modal.component.ts b/apps/concierge/src/app/building-manager/auto-release-settings-modal.component.ts
index cd596ff7f7..00f6cfc9f0 100644
--- a/apps/concierge/src/app/building-manager/auto-release-settings-modal.component.ts
+++ b/apps/concierge/src/app/building-manager/auto-release-settings-modal.component.ts
@@ -2,10 +2,12 @@ import { Component, OnInit, inject, signal } from '@angular/core';
import {
MAT_DIALOG_DATA,
MatDialog,
+ MatDialogModule,
MatDialogRef,
} from '@angular/material/dialog';
import {
SettingsService,
+ WorktimePreference,
i18n,
nextValueFrom,
notifyError,
@@ -20,7 +22,6 @@ import {
updateMetadata,
updateSettings,
} from '@placeos/ts-client';
-import { WorktimePreference } from '@placeos/users';
import {
set,
setDay,
@@ -29,11 +30,24 @@ import {
startOfDay,
startOfMinute,
} from 'date-fns';
-import * as yaml from 'js-yaml';
-import { WFHSettingsModalComponent } from 'libs/users/src/lib/wfh-settings-modal.component';
import { lastValueFrom } from 'rxjs';
import { map } from 'rxjs/operators';
+import { WFHSettingsModalComponent } from '@placeos/users';
+
+import { FormsModule } from '@angular/forms';
+import { MatRippleModule } from '@angular/material/core';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
+import { MatSelectModule } from '@angular/material/select';
+import { SettingsToggleComponent, TranslatePipe } from '@placeos/components';
+import {
+ DurationFieldComponent,
+ TimeFieldComponent,
+} from '@placeos/form-fields';
+
+import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
+
@Component({
selector: 'auto-release-modal',
template: `
@@ -236,7 +250,18 @@ import { map } from 'rxjs/operators';
}
`,
styles: [``],
- standalone: false,
+ imports: [
+ DurationFieldComponent,
+ MatProgressSpinnerModule,
+ MatRippleModule,
+ SettingsToggleComponent,
+ MatFormFieldModule,
+ MatSelectModule,
+ TimeFieldComponent,
+ FormsModule,
+ MatDialogModule,
+ TranslatePipe,
+ ],
})
export class AutoReleaseSettingsModalComponent implements OnInit {
private _id = inject(MAT_DIALOG_DATA);
@@ -342,7 +367,7 @@ export class AutoReleaseSettingsModalComponent implements OnInit {
if (!unencrypted) return;
try {
this.settings =
- yaml.load(unencrypted.settings_string)?.auto_release || {};
+ parseYaml(unencrypted.settings_string)?.auto_release || {};
} catch {}
if (!this.settings.custom) this.settings.custom = [];
for (const name of this.types) {
@@ -356,9 +381,9 @@ export class AutoReleaseSettingsModalComponent implements OnInit {
public async save() {
this.loading.set(i18n('APP.CONCIERGE.AUTO_RELEASE_SAVING'));
- const settings = await querySettings({ parent_id: this.id })
- .pipe(map((_) => _.data))
- .toPromise();
+ const settings = await lastValueFrom(
+ querySettings({ parent_id: this.id }).pipe(map((_) => _.data)),
+ );
let unencrypted = settings.find(
(_) => _.encryption_level === EncryptionLevel.None,
);
@@ -373,9 +398,9 @@ export class AutoReleaseSettingsModalComponent implements OnInit {
delete new_settings.custom;
let old_settings = {};
try {
- old_settings = yaml.load(unencrypted.settings_string) || {};
+ old_settings = parseYaml(unencrypted.settings_string) || {};
} catch {}
- (unencrypted as any).settings_string = yaml.dump({
+ (unencrypted as any).settings_string = stringifyYaml({
...old_settings,
auto_release: new_settings,
});
diff --git a/apps/concierge/src/app/building-manager/building-form.component.ts b/apps/concierge/src/app/building-manager/building-form.component.ts
index efb199202b..1edba9b74e 100644
--- a/apps/concierge/src/app/building-manager/building-form.component.ts
+++ b/apps/concierge/src/app/building-manager/building-form.component.ts
@@ -1,3 +1,4 @@
+import { CommonModule } from '@angular/common';
import {
Component,
OnChanges,
@@ -8,16 +9,27 @@ import {
model,
output,
} from '@angular/core';
-import { FormControl, FormGroup, Validators } from '@angular/forms';
+import {
+ FormControl,
+ FormGroup,
+ ReactiveFormsModule,
+ Validators,
+} from '@angular/forms';
+import { MatAutocompleteModule } from '@angular/material/autocomplete';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { MatSelectModule } from '@angular/material/select';
import {
AsyncHandler,
+ Building,
+ OrganisationService,
TIMEZONES_IANA,
getInvalidFields,
i18n,
notifyError,
notifySuccess,
} from '@placeos/common';
-import { Building, OrganisationService } from '@placeos/organisation';
+import { IconComponent, TranslatePipe } from '@placeos/components';
import { addZone, authority, updateZone } from '@placeos/ts-client';
@Component({
@@ -107,7 +119,16 @@ import { addZone, authority, updateZone } from '@placeos/ts-client';
}
`,
styles: [``],
- standalone: false,
+ imports: [
+ CommonModule,
+ TranslatePipe,
+ IconComponent,
+ ReactiveFormsModule,
+ MatFormFieldModule,
+ MatAutocompleteModule,
+ MatSelectModule,
+ MatInputModule,
+ ],
})
export class BuildingFormComponent
extends AsyncHandler
diff --git a/apps/concierge/src/app/building-manager/building-list.component.ts b/apps/concierge/src/app/building-manager/building-list.component.ts
index 6e17b29292..a0d31c1f6c 100644
--- a/apps/concierge/src/app/building-manager/building-list.component.ts
+++ b/apps/concierge/src/app/building-manager/building-list.component.ts
@@ -4,6 +4,13 @@ import { MatDialog } from '@angular/material/dialog';
import { i18n, notifySuccess } from '@placeos/common';
import { BuildingManagementService } from './building-management.service';
+import { MatMenuModule } from '@angular/material/menu';
+import {
+ AuthenticatedImageDirective,
+ IconComponent,
+ SimpleTableComponent,
+ TranslatePipe,
+} from '@placeos/components';
import { BookingPanelSettingsModalComponent } from '../ui/app-settings/booking-panel-settings-modal.component';
import { ConciergeSettingsFormModalComponent } from '../ui/app-settings/concierge-settings-form-modal.component';
import { VisitorKioskSettingsFormModalComponent } from '../ui/app-settings/visitor-kiosk-settings-form-modal.component';
@@ -239,7 +246,13 @@ import { WorkplaceSettingsFormModalComponent } from '../ui/app-settings/workplac
`,
styles: [``],
- standalone: false,
+ imports: [
+ SimpleTableComponent,
+ AuthenticatedImageDirective,
+ MatMenuModule,
+ TranslatePipe,
+ IconComponent,
+ ],
})
export class BuildingListComponent {
private _manager = inject(BuildingManagementService);
diff --git a/apps/concierge/src/app/building-manager/building-management.service.ts b/apps/concierge/src/app/building-manager/building-management.service.ts
index 0cc3d23a19..ba44786b0f 100644
--- a/apps/concierge/src/app/building-manager/building-management.service.ts
+++ b/apps/concierge/src/app/building-manager/building-management.service.ts
@@ -1,9 +1,14 @@
import { Injectable, inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
-import { i18n, notifyError, notifySuccess } from '@placeos/common';
-import { Building, OrganisationService } from '@placeos/organisation';
+import {
+ Building,
+ OrganisationService,
+ i18n,
+ notifyError,
+ notifySuccess,
+} from '@placeos/common';
+import { openConfirmModal } from '@placeos/components';
import { PlaceZone, removeZone } from '@placeos/ts-client';
-import { openConfirmModal } from 'libs/components/src/lib/confirm-modal.component';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { AppSettingsModalComponent } from '../ui/app-settings-modal.component';
diff --git a/apps/concierge/src/app/building-manager/building-manager.component.ts b/apps/concierge/src/app/building-manager/building-manager.component.ts
index a85cd205d7..41180d8758 100644
--- a/apps/concierge/src/app/building-manager/building-manager.component.ts
+++ b/apps/concierge/src/app/building-manager/building-manager.component.ts
@@ -1,4 +1,9 @@
import { Component, inject } from '@angular/core';
+import { MatRippleModule } from '@angular/material/core';
+import { TranslatePipe } from '@placeos/components';
+import { ApplicationSidebarComponent } from '../ui/app-sidebar.component';
+import { ApplicationTopbarComponent } from '../ui/app-topbar.component';
+import { BuildingListComponent } from './building-list.component';
import { BuildingManagementService } from './building-management.service';
@Component({
@@ -47,7 +52,13 @@ import { BuildingManagementService } from './building-management.service';
}
`,
],
- standalone: false,
+ imports: [
+ BuildingListComponent,
+ ApplicationTopbarComponent,
+ ApplicationSidebarComponent,
+ MatRippleModule,
+ TranslatePipe,
+ ],
})
export class BuildingManagerComponent {
private _state = inject(BuildingManagementService);
diff --git a/apps/concierge/src/app/building-manager/building-manager.module.ts b/apps/concierge/src/app/building-manager/building-manager.module.ts
index 58cb1cc562..0b6df9c8ac 100644
--- a/apps/concierge/src/app/building-manager/building-manager.module.ts
+++ b/apps/concierge/src/app/building-manager/building-manager.module.ts
@@ -1,40 +1,12 @@
-import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
import { Route, RouterModule } from '@angular/router';
-import { UIModule } from '../ui/ui.module';
-
-import { SharedUsersModule } from '@placeos/users';
-
-import { MatChipsModule } from '@angular/material/chips';
-import { AutoReleaseSettingsModalComponent } from './auto-release-settings-modal.component';
-import { BuildingFormComponent } from './building-form.component';
-import { BuildingListComponent } from './building-list.component';
import { BuildingManagerComponent } from './building-manager.component';
-import { BuildingModalComponent } from './building-modal.component';
-import { InductionSettingsModalComponent } from './induction-settings-modal.component';
-import { ItemListModalComponent } from './item-list-modal.component';
const ROUTES: Route[] = [{ path: '', component: BuildingManagerComponent }];
@NgModule({
- declarations: [
- BuildingManagerComponent,
- BuildingListComponent,
- BuildingFormComponent,
- BuildingModalComponent,
- AutoReleaseSettingsModalComponent,
- InductionSettingsModalComponent,
- ItemListModalComponent,
- ],
- imports: [
- CommonModule,
- FormsModule,
- UIModule,
- SharedUsersModule,
- MatChipsModule,
- RouterModule.forChild(ROUTES),
- ],
+ declarations: [],
+ imports: [BuildingManagerComponent, RouterModule.forChild(ROUTES)],
})
export class BuildingManagerModule {}
diff --git a/apps/concierge/src/app/building-manager/building-modal.component.ts b/apps/concierge/src/app/building-manager/building-modal.component.ts
index 077285ae7e..0fc237ef9e 100644
--- a/apps/concierge/src/app/building-manager/building-modal.component.ts
+++ b/apps/concierge/src/app/building-manager/building-modal.component.ts
@@ -1,6 +1,10 @@
+import { CommonModule } from '@angular/common';
import { Component, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
-import { Building } from '@placeos/organisation';
+import { Building } from '@placeos/common';
+import { TranslatePipe } from '@placeos/components';
+import { FullscreenModalShellComponent } from 'libs/components/src/lib/fullscreen-modal-shell.component';
+import { BuildingFormComponent } from './building-form.component';
@Component({
selector: 'building-modal',
@@ -28,7 +32,12 @@ import { Building } from '@placeos/organisation';
`,
styles: [``],
- standalone: false,
+ imports: [
+ CommonModule,
+ FullscreenModalShellComponent,
+ BuildingFormComponent,
+ TranslatePipe,
+ ],
})
export class BuildingModalComponent {
private _data = inject
No spaces
+{{ loading | async }}
+{{ 'APP.WORKPLACE.PARKING_SUCCESS_MSG' @@ -37,7 +47,7 @@ import { OrganisationService } from '@placeos/organisation'; } }}
-{{ message() }}
+{{ raw_description }}
- @if (!raw_description.trim()) { +{{ raw_description() }}
+ @if (!raw_description().trim()) {{{ 'CALENDAR_EVENT.GROUP_NO_DESCRIPTION' @@ -61,12 +73,12 @@ import { GroupEventDetailsModalComponent } from './group-event-details-modal.com