Skip to content

Commit

Permalink
Fix/server web implement config (#3368)
Browse files Browse the repository at this point in the history
* fix: server web default setting

* fix: handle dynamic gauzy api host from desktop config

* fix: setup server web

* fix: remove unecessary code

* fix: miss spell word

* fix: clean code

* fix: handle error on create tray menu

* fix: build standalone for desktop
  • Loading branch information
syns2191 authored Nov 28, 2024
1 parent a3ec43d commit 936b835
Show file tree
Hide file tree
Showing 29 changed files with 510 additions and 215 deletions.
77 changes: 77 additions & 0 deletions .scripts/configure.electron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as fs from 'fs';
import * as path from 'path';
import { hideBin } from 'yargs/helpers';
import yargs from 'yargs';

interface Arguments {
type: 'server' | 'constant'
}
const argv = yargs(hideBin(process.argv))
.options({
type: {
type: 'string',
choices: ['server', 'constant'],
demandOption: true,
description: 'Type of configuration to modify'
}
})
.parseSync() as Arguments;

function modifiedNextServer() {
const filePath = path.resolve(__dirname, '../apps/server-web/release/app/dist/standalone/apps/web/server.js');
try {
let fileContent = fs.readFileSync(filePath, 'utf8');
const searchString = 'process.env.__NEXT_PRIVATE_STANDALONE_CONFIG';
const codeToInsert = `
nextConfig.serverRuntimeConfig = {
"GAUZY_API_SERVER_URL": process.env.GAUZY_API_SERVER_URL,
"NEXT_PUBLIC_GAUZY_API_SERVER_URL": process.env.NEXT_PUBLIC_GAUZY_API_SERVER_URL
}
`;

let lines = fileContent.split('\n');
const index = lines.findIndex((line) => line.includes(searchString));

if (index !== -1) {
lines.splice(index - 1, 0, codeToInsert);

fileContent = lines.join('\n');
fs.writeFileSync(filePath, fileContent, 'utf8');
console.log('Line of code successfully inserted.');
} else {
console.log(`The string "${searchString}" was not found in the file.`);
}
} catch (error) {
console.error('Failed to change static server configuration');
}
}

function updateWebConstant(setDesktopApp) {
const filePath = path.resolve(__dirname, '../apps/web/app/constants.ts');
try {
let fileContent = fs.readFileSync(filePath, 'utf8');
const envCheck = `export const IS_DESKTOP_APP = process.env.IS_DESKTOP_APP === 'true';`;
const hardcoded = `export const IS_DESKTOP_APP = true;`;

const [from, to] = setDesktopApp ? [envCheck, hardcoded] : [hardcoded, envCheck];

if (!fileContent.includes(from)) {
throw new Error(`Expected content not found in ${filePath}`);
}

fileContent = fileContent.replace(from, to);
fs.writeFileSync(filePath, fileContent, 'utf8');
console.log(`Successfully ${setDesktopApp ? 'set' : 'reverted'} IS_DESKTOP_APP`);
} catch (error) {
console.error('Failed to update constants:', error);
process.exit(1);
}
}


if (argv.type === 'server') {
modifiedNextServer();
updateWebConstant(false);
} else if (argv.type === 'constant') {
updateWebConstant(true);
}
34 changes: 34 additions & 0 deletions .scripts/copy-web-build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { copy } from 'fs-extra';
import { join } from 'path';

async function copyWebBuild() {
const webDir = join(process.cwd(), 'apps/web');
const distDir = join(process.cwd(), 'apps/server-web/release/app/dist');

try {
// Copy standalone build
await copy(
join(webDir, '.next/standalone'),
join(distDir, 'standalone')
);

// Copy static files
await copy(
join(webDir, '.next/static'),
join(distDir, 'standalone/apps/web/.next/static')
);

// Copy public files
await copy(
join(webDir, 'public'),
join(distDir, 'standalone/apps/web/public')
);

console.log('Build files copied successfully');
} catch (error) {
console.error('Failed to copy build files:', error);
process.exit(1);
}
}

copyWebBuild();
24 changes: 12 additions & 12 deletions apps/server-web/src/locales/i18n/bg/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
"SERVER_WINDOW": "Прозорец на сървъра"
},
"MENU_APP": {
"ABOUT": "Относно",
"QUIT": "Изход",
"WINDOW": "Прозорец",
"SUBMENU": {
"SETTING": "Настройки",
"SERVER_WINDOW": "Сървърен прозорец",
"LEARN_MORE": "Научете повече",
"DOC": "Документация",
"SETTING_DEV": "Настройки за разработчици",
"SERVER_DEV": "Сървър за разработчици"
"APP_ABOUT": "Относно",
"APP_QUIT": "Изход",
"APP_WINDOW": "Прозорец",
"APP_SUBMENU": {
"APP_SETTING": "Настройки",
"APP_SERVER_WINDOW": "Сървърен прозорец",
"APP_LEARN_MORE": "Научете повече",
"APP_DOC": "Документация",
"APP_SETTING_DEV": "Настройки за разработчици",
"APP_SERVER_DEV": "Сървър за разработчици"
},
"DEV": "Разработчик",
"HELP": "Помощ"
"APP_DEV": "Разработчик",
"APP_HELP": "Помощ"
},
"FORM": {
"FIELDS": {
Expand Down
24 changes: 12 additions & 12 deletions apps/server-web/src/locales/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
"SERVER_WINDOW": "Server Window"
},
"MENU_APP": {
"ABOUT": "About",
"QUIT": "Quit",
"WINDOW": "Window",
"SUBMENU": {
"SETTING": "Setting",
"SERVER_WINDOW": "Server Window",
"LEARN_MORE": "Learn More",
"DOC": "Documentation",
"SETTING_DEV": "Setting Dev.",
"SERVER_DEV": "Server Dev."
"APP_ABOUT": "About",
"APP_QUIT": "Quit",
"APP_WINDOW": "Window",
"APP_SUBMENU": {
"APP_SETTING": "Setting",
"APP_SERVER_WINDOW": "Server Window",
"APP_LEARN_MORE": "Learn More",
"APP_DOC": "Documentation",
"APP_SETTING_DEV": "Setting Dev.",
"APP_SERVER_DEV": "Server Dev."
},
"DEV": "Developer",
"HELP": "Help"
"APP_DEV": "Developer",
"APP_HELP": "Help"
},
"FORM": {
"FIELDS": {
Expand Down
4 changes: 3 additions & 1 deletion apps/server-web/src/main/helpers/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const EventLists = {
SERVER_WINDOW: 'SERVER_WINDOW',
RESTART_SERVER: 'RESTART_SERVER',
CHANGE_THEME: 'CHANGE_THEME',
SETUP_WINDOW: 'SETUP_WINDOW'
SETUP_WINDOW: 'SETUP_WINDOW',
SETTING_WINDOW_DEV: 'SETTING_WINDOW_DEV',
SERVER_WINDOW_DEV: 'SERVER_WINDOW_DEV'
}

export const SettingPageTypeMessage = {
Expand Down
2 changes: 1 addition & 1 deletion apps/server-web/src/main/helpers/interfaces/i-constant.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type Channels = 'setting-page' | 'ipc-renderer' | 'language-set' | 'updater-page' | 'server-page' | 'theme-change' | 'current-theme';
export type Channels = 'setting-page' | 'ipc-renderer' | 'language-set' | 'updater-page' | 'server-page' | 'theme-change' | 'current-theme' | 'current-language';
15 changes: 15 additions & 0 deletions apps/server-web/src/main/helpers/interfaces/i-menu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MenuItemConstructorOptions } from 'electron';
export interface AppMenu {
id?: string;
label: string; // Menu label
submenu?: (AppMenu | ElectronMenuItem)[]; // Nested menus or Electron menu items
role?: 'appMenu' | 'fileMenu' | 'editMenu' | 'viewMenu' | 'windowMenu' | 'help'; // Predefined menu roles
type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio'; // Menu item type
click?: () => void; // Click handler for the menu item
accelerator?: string; // Keyboard shortcut
enabled?: boolean; // Whether the item is enabled
visible?: boolean; // Whether the item is visible
checked?: boolean; // For 'checkbox' or 'radio' type
}

export type ElectronMenuItem = MenuItemConstructorOptions;
6 changes: 3 additions & 3 deletions apps/server-web/src/main/helpers/interfaces/i-server.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
interface GeneralConfig {
export interface GeneralConfig {
lang?: string
autoUpdate?: boolean
updateCheckPeriode?: string
updateCheckPeriod?: string
theme?: string
setup?: boolean
[key: string]: any
}

interface ServerConfig {
export interface ServerConfig {
PORT: number;
NEXT_PUBLIC_GAUZY_API_SERVER_URL: string;
GAUZY_API_SERVER_URL: string;
Expand Down
1 change: 1 addition & 0 deletions apps/server-web/src/main/helpers/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './i-server';
export * from './i-desktop-dialog';
export * from './i-constant';
export * from './i-menu';
24 changes: 24 additions & 0 deletions apps/server-web/src/main/helpers/replace-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,27 @@ export const replaceConfig = async (folderPath: string, envOptions: EnvOptions)
console.log('error on replacing file', error);
}
}

export const clearDesktopConfig = async (folderPath: string): Promise<Boolean> => {
if (!folderPath || typeof folderPath !== 'string') {
throw new Error('Invalid folder path provided');
}
const DESKTOP_CONFIG_FILES = ['desktop-server.body', 'desktop-server.meta'] as const;
try {
// remove cached desktop server config
await Promise.all(
DESKTOP_CONFIG_FILES.map(async (file) => {
const filePath = path.join(folderPath, file);
try {
await fs.promises.unlink(filePath)
} catch (error: any) {
console.log('error unlink static web file', error.message)
}
})
)
return true;
} catch (error) {
console.log('Failed to clear static config');
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class DesktopServerFactory {
if (!this.apiInstance && !!env) {
this.apiInstance = new WebService(path, env, win, signal, eventEmitter);
}
this.apiInstance.updateEnv(env)
return this.apiInstance;
}
}
50 changes: 37 additions & 13 deletions apps/server-web/src/main/helpers/services/libs/desktop-store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Store from 'electron-store';
import { WebServer } from '../../interfaces';
import { WebServer, ServerConfig } from '../../interfaces';
const store = new Store();
const DEFAULT_CONFIG:any = {
const DEFAULT_CONFIG:WebServer = {
server: {
PORT: 3002,
GAUZY_API_SERVER_URL: 'http://localhost:3000',
Expand All @@ -11,7 +11,7 @@ const DEFAULT_CONFIG:any = {
general: {
lang: 'en',
autoUpdate: true,
updateCheckPeriode: '1140'
updateCheckPeriod: '1140' // Time in minutes
}
}
export const LocalStore = {
Expand All @@ -35,17 +35,41 @@ export const LocalStore = {
});
},

deepMerge<T>(target: T, source: Partial<T>): T {
const result: T = { ...target };
Object.keys(source).forEach(key => {
const value = source[key as keyof T];
if (value && typeof value === 'object') {
result[key as keyof T] = this.deepMerge(
target[key as keyof T],
value as any
);
} else if (value !== undefined) {
result[key as keyof T] = value as any;
}
});
return result;
},

setDefaultServerConfig: () => {
const defaultConfig: WebServer | any = store.get('config') || {};
Object.keys(DEFAULT_CONFIG).forEach((key) => {
Object.keys(DEFAULT_CONFIG[key]).forEach((keySub) => {
defaultConfig[key] = defaultConfig[key] || {};
defaultConfig[key][keySub] = defaultConfig[key][keySub] || DEFAULT_CONFIG[key][keySub];
})
})
store.set({
config: defaultConfig
validateConfig(config: WebServer): void {
const required = ['PORT', 'GAUZY_API_SERVER_URL'];
required.forEach(field => {
if (!config || !config.server || !config?.server[field as keyof ServerConfig]) {
throw new Error(`Missing required field: ${field}`);
}
});
},

setDefaultServerConfig() {
try {
const storedConfig = store.get('config') as Partial<WebServer> || {};
const mergedConfig = this.deepMerge<WebServer>(DEFAULT_CONFIG, storedConfig)
this.validateConfig(mergedConfig || {});

store.set({ config: mergedConfig });
} catch (error) {
console.error('Failed to set default configuration:', error);
store.set({ config: DEFAULT_CONFIG });
}
}
};
16 changes: 8 additions & 8 deletions apps/server-web/src/main/helpers/services/web-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EventEmitter } from 'stream';
export class WebService extends ServerTask {
constructor(
readonly path: string,
readonly env: any,
private env: any,
readonly window: BrowserWindow,
readonly signal: AbortSignal,
readonly eventEmitter: EventEmitter
Expand Down Expand Up @@ -38,11 +38,11 @@ export class WebService extends ServerTask {
}
}

private setApiConfig(): void {
// Object.assign(this.args, {
// API_HOST: '0.0.0.0',
// API_PORT: this.config.setting.PORT,
// API_BASE_URL: this.config.apiUrl
// });
public setApiConfig(): void {
Object.assign(this.args, {...this.env});
}
}

public updateEnv(env: any): void {
this.env = {...env};
}
}
Loading

0 comments on commit 936b835

Please sign in to comment.