Skip to content

Commit

Permalink
refactor: Consolidate root directory selection into settings modal (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
praveenjuge authored Mar 3, 2025
1 parent d95b197 commit ad59130
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 177 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-garlics-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"specif-ai": patch
---

refactor: Consolidate root directory selection into settings modal
34 changes: 9 additions & 25 deletions ui/src/app/components/layout/header/header.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,15 @@ <h1 class="text-2xl text-secondary-50">
</a>
</div>

<div class="flex items-center gap-4">
<div
class="flex justify-center items-center h-8 w-8 rounded-full bg-transparent text-slate-400 hover:text-slate-600 hover:bg-slate-200 cursor-pointer"
role="button"
tabindex="0"
(click)="openSelectRootDirectoryModal()"
(keydown.enter)="openSelectRootDirectoryModal()"
(keydown.space)="
openSelectRootDirectoryModal(); $event.preventDefault()
"
matTooltip="Choose Destination Folder"
>
<ng-icon name="heroFolder" />
</div>

<button
(click)="openSettingsModal()"
(keydown.enter)="openSettingsModal()"
(keydown.space)="openSettingsModal(); $event.preventDefault()"
class="flex items-center justify-center font-medium opacity-100 transition-colors duration-300 px-3 py-2 gap-2 text-xs rounded-lg border border-slate-700 bg-transparent text-white hover:bg-slate-900"
>
<ng-icon name="heroCog8Tooth" strokeWidth="2" size="16" />
Settings
</button>
</div>
<button
(click)="openSettingsModal()"
(keydown.enter)="openSettingsModal()"
(keydown.space)="openSettingsModal(); $event.preventDefault()"
class="flex items-center justify-center font-medium opacity-100 transition-colors duration-300 px-3 py-2 gap-2 text-xs rounded-lg border border-slate-700 bg-transparent text-white hover:bg-slate-900"
>
<ng-icon name="heroCog8Tooth" strokeWidth="2" size="16" />
Settings
</button>
</div>
</div>
<div class="w-full px-8 py-3 flex items-center justify-start">
Expand Down
56 changes: 3 additions & 53 deletions ui/src/app/components/layout/header/header.component.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { Component, inject } from '@angular/core';
import { APP_CONSTANTS } from '../../../constants/app.constants';
import { SelectRootDirectoryComponent } from '../../select-root-directory/select-root-directory.component';
import { MatDialog } from '@angular/material/dialog';
import { ElectronService } from '../../../services/electron/electron.service';
import { NGXLogger } from 'ngx-logger';
import { Router, RouterLink } from '@angular/router';
import { RouterLink } from '@angular/router';
import { SettingsComponent } from '../../settings/settings.component';
import { AuthService } from '../../../services/auth/auth.service';
import { environment } from '../../../../environments/environment';
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { BreadcrumbsComponent } from '../../core/breadcrumbs/breadcrumbs.component';
import { AsyncPipe, NgIf } from '@angular/common';
import { MatTooltipModule } from '@angular/material/tooltip';
import {
heroArrowRightOnRectangle,
heroCog8Tooth,
heroFolder,
} from '@ng-icons/heroicons/outline';
import { heroCog8Tooth } from '@ng-icons/heroicons/outline';

@Component({
selector: 'app-header',
Expand All @@ -31,55 +23,13 @@ import {
AsyncPipe,
MatTooltipModule,
],
viewProviders: [
provideIcons({ heroCog8Tooth, heroFolder, heroArrowRightOnRectangle }),
],
viewProviders: [provideIcons({ heroCog8Tooth })],
})
export class HeaderComponent {
protected themeConfiguration = environment.ThemeConfiguration;

authService = inject(AuthService);
electronService = inject(ElectronService);
logger = inject(NGXLogger);
dialog = inject(MatDialog);
router = inject(Router);

/**
* Prompts the user to select a root directory, saves the selected directory to local storage,
* and navigates to the '/apps' route or reloads the current page based on the current URL.
*
* @return {Promise<void>} A promise that resolves when the directory selection and navigation are complete.
*/
async selectRootDirectory(): Promise<void> {
const response = await this.electronService.openDirectory();
this.logger.debug(response);
if (response.length > 0) {
localStorage.setItem(APP_CONSTANTS.WORKING_DIR, response[0]);
const currentConfig =
(await this.electronService.getStoreValue('APP_CONFIG')) || {};
const updatedConfig = { ...currentConfig, directoryPath: response[0] };
await this.electronService.setStoreValue('APP_CONFIG', updatedConfig);

this.logger.debug('===>', this.router.url);
if (this.router.url === '/apps') {
await this.electronService.reloadApp();
} else {
await this.router.navigate(['/apps']);
}
}
}

openSelectRootDirectoryModal() {
const modalRef = this.dialog.open(SelectRootDirectoryComponent, {
disableClose: true,
});

modalRef.afterClosed().subscribe((res) => {
if (res === true) {
this.selectRootDirectory().then();
}
});
}

openSettingsModal() {
this.dialog.open(SettingsComponent, {
Expand Down

This file was deleted.

Empty file.

This file was deleted.

This file was deleted.

28 changes: 26 additions & 2 deletions ui/src/app/components/settings/settings.component.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<div class="modal-wrapper w-[32rem] max-w-lg text-sm font-medium">
<div class="modal-wrapper w-[30rem] max-w-lg text-sm font-medium">
<div class="modal-header flex items-center justify-between px-4 pt-4">
<h4 class="font-medium text-base">Settings</h4>
<button
type="button"
class="text-slate-400 bg-transparent hover:bg-slate-200 hover:text-slate-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center focus:outline-none focus:ring-0"
class="text-slate-400 bg-transparent hover:bg-slate-200 hover:text-slate-900 rounded-lg p-1 ml-auto inline-flex items-center focus:outline-none focus:ring-0"
data-dismiss="modal"
aria-label="Close"
(click)="closeModal()"
Expand Down Expand Up @@ -94,6 +94,30 @@ <h4 class="font-medium text-base">Settings</h4>
</div>
</div>

<!-- Destination Folder -->
<div class="space-y-1">
<label for="workingDir" class="block text-slate-500">
Folder to store the requirements generated by {{ appName }}
</label>
<div class="flex w-full">
<input
type="text"
[value]="workingDir"
placeholder="Choose Destination Folder"
disabled
id="workingDir"
class="bg-gray-100 border border-gray-300 text-gray-400 text-sm rounded-l-lg block w-full p-2"
/>
<app-button
[buttonContent]="'Browse'"
[theme]="'primary'"
[rounded]="'none'"
[roundedRight]="'lg'"
(click)="openFolderSelector()"
></app-button>
</div>
</div>

<!-- Save and Cancel Buttons -->
<div
*ngIf="hasChanges"
Expand Down
47 changes: 45 additions & 2 deletions ui/src/app/components/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ import { AuthService } from '../../services/auth/auth.service';
import { ToasterService } from '../../services/toaster/toaster.service';
import { ButtonComponent } from '../core/button/button.component';
import { ConfirmationDialogComponent } from '../../components/confirmation-dialog/confirmation-dialog.component';
import { CONFIRMATION_DIALOG } from '../../constants/app.constants';
import {
APP_CONSTANTS,
CONFIRMATION_DIALOG,
} from '../../constants/app.constants';
import { environment } from 'src/environments/environment';
import { ElectronService } from 'src/app/services/electron/electron.service';
import { NGXLogger } from 'ngx-logger';
import { Router } from '@angular/router';

@Component({
selector: 'app-settings',
Expand All @@ -52,11 +58,16 @@ export class SettingsComponent implements OnInit, OnDestroy {
selectedProvider: FormControl = new FormControl();
errorMessage: string = '';
hasChanges: boolean = false;
workingDir: string | null;
appName = environment.ThemeConfiguration.appName;
private subscriptions: Subscription = new Subscription();
private initialModel: string = '';
private initialProvider: string = '';
protected themeConfiguration = environment.ThemeConfiguration;

electronService = inject(ElectronService);
logger = inject(NGXLogger);
router = inject(Router);
dialog = inject(MatDialog);
version: string = environment.APP_VERSION;
currentYear = new Date().getFullYear();
Expand All @@ -67,7 +78,39 @@ export class SettingsComponent implements OnInit, OnDestroy {
private authService: AuthService,
private toasterService: ToasterService,
private cdr: ChangeDetectorRef,
) {}
) {
this.workingDir = localStorage.getItem(APP_CONSTANTS.WORKING_DIR);
}

/**
* Prompts the user to select a root directory, saves the selected directory to local storage,
* and navigates to the '/apps' route or reloads the current page based on the current URL.
*
* @return {Promise<void>} A promise that resolves when the directory selection and navigation are complete.
*/
async selectRootDirectory(): Promise<void> {
const response = await this.electronService.openDirectory();
this.logger.debug(response);
if (response.length > 0) {
localStorage.setItem(APP_CONSTANTS.WORKING_DIR, response[0]);
const currentConfig =
(await this.electronService.getStoreValue('APP_CONFIG')) || {};
const updatedConfig = { ...currentConfig, directoryPath: response[0] };
await this.electronService.setStoreValue('APP_CONFIG', updatedConfig);

this.logger.debug('===>', this.router.url);
if (this.router.url === '/apps') {
await this.electronService.reloadApp();
} else {
await this.router.navigate(['/apps']);
}
}
}

openFolderSelector() {
this.selectRootDirectory().then();
this.modalRef.close(true);
}

ngOnInit(): void {
this.subscriptions.add(
Expand Down
9 changes: 2 additions & 7 deletions ui/src/app/pages/create-solution/create-solution.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { NGXLogger } from 'ngx-logger';
import { AppSystemService } from '../../services/app-system/app-system.service';
import { ElectronService } from '../../services/electron/electron.service';
import { ToasterService } from '../../services/toaster/toaster.service';
import { SelectRootDirectoryComponent } from '../../components/select-root-directory/select-root-directory.component';
import { NgIf } from '@angular/common';
import { NgxLoadingModule } from 'ngx-loading';
import { ButtonComponent } from '../../components/core/button/button.component';
Expand All @@ -27,6 +26,7 @@ import {
import { InputFieldComponent } from '../../components/core/input-field/input-field.component';
import { TextareaFieldComponent } from '../../components/core/textarea-field/textarea-field.component';
import { ToggleComponent } from '../../components/toggle/toggle.component';
import { SettingsComponent } from 'src/app/components/settings/settings.component';

@Component({
selector: 'app-create-solution',
Expand Down Expand Up @@ -116,14 +116,9 @@ export class CreateSolutionComponent implements OnInit {
}

openSelectRootDirectoryModal() {
const modalRef = this.dialog.open(SelectRootDirectoryComponent, {
this.dialog.open(SettingsComponent, {
disableClose: true,
});
modalRef.afterClosed().subscribe((res) => {
if (res === true) {
this.selectRootDirectory().then();
}
});
}

async selectRootDirectory(): Promise<void> {
Expand Down

0 comments on commit ad59130

Please sign in to comment.