Skip to content

Commit

Permalink
Merge pull request #3389 from ever-co/develop
Browse files Browse the repository at this point in the history
Stage
  • Loading branch information
evereq authored Dec 4, 2024
2 parents 64454a6 + 88fc30c commit ecd5a95
Show file tree
Hide file tree
Showing 49 changed files with 1,860 additions and 111 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/desktop-server-api.apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:

strategy:
matrix:
os: [macos-12]
os: [macos-latest]

steps:
- name: Check out Git repository
Expand All @@ -118,7 +118,7 @@ jobs:
cache: 'yarn'

- name: Fix node-gyp and Python
run: python3 -m pip install packaging setuptools
run: python3 -m pip install --break-system-packages packaging setuptools

- name: Install latest version of NPM
run: 'sudo npm install -g npm@9'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/desktop-server-web.apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:

strategy:
matrix:
os: [macos-12]
os: [macos-latest]

steps:
- name: Check out Git repository
Expand All @@ -115,7 +115,7 @@ jobs:
cache: 'yarn'

- name: Fix node-gyp and Python
run: python3 -m pip install packaging setuptools
run: python3 -m pip install --break-system-packages packaging setuptools

- name: Install latest version of NPM
run: 'sudo npm install -g npm@9'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/desktop.apps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ jobs:

strategy:
matrix:
os: [macos-12]
os: [macos-latest]

steps:
- name: Check out Git repository
Expand All @@ -118,7 +118,7 @@ jobs:
cache: 'yarn'

- name: Fix node-gyp and Python
run: python3 -m pip install packaging setuptools
run: python3 -m pip install --break-system-packages packaging setuptools

- name: Install latest version of NPM
run: 'sudo npm install -g npm@9'
Expand Down
9 changes: 4 additions & 5 deletions apps/server-web/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,7 @@ const createWindow = async (type: 'SETTING_WINDOW' | 'LOG_WINDOW' | 'SETUP_WINDO
url = resolveHtmlPath('index.html', 'setup');
setupWindow?.loadURL(url);
mainBindings(ipcMain, setupWindow, fs);
if (process.platform === 'darwin') {
Menu.setApplicationMenu(Menu.buildFromTemplate([]));
} else {
setupWindow.removeMenu();
}
Menu.setApplicationMenu(appMenu.buildDefaultTemplate(appMenu.initialMenu(), i18nextMainBackend));
setupWindow.on('closed', () => {
setupWindow = null;
})
Expand Down Expand Up @@ -270,6 +266,8 @@ const onInitApplication = () => {
trayMenuItems = trayMenuItems.length ? trayMenuItems : defaultTrayMenuItem(eventEmitter);
updateTrayMenu('none', {}, eventEmitter, tray, trayMenuItems, i18nextMainBackend);
Menu.setApplicationMenu(appMenu.buildDefaultTemplate(appMenuItems, i18nextMainBackend))
} else {
Menu.setApplicationMenu(appMenu.buildDefaultTemplate(appMenu.initialMenu(), i18nextMainBackend))
}
}, 250));

Expand Down Expand Up @@ -378,6 +376,7 @@ const onInitApplication = () => {
})
logWindow?.webContents.send('themeSignal', { type: SettingPageTypeMessage.themeChange, data });
settingWindow?.webContents.send('themeSignal', { type: SettingPageTypeMessage.themeChange, data });
setupWindow?.webContents.send('themeSignal', { type: SettingPageTypeMessage.themeChange, data });
})

eventEmitter.on(EventLists.gotoAbout, async () => {
Expand Down
25 changes: 24 additions & 1 deletion apps/server-web/src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class MenuBuilder {
this.eventEmitter = eventEmitter
}

defaultMenu(): AppMenu[] {
initialMenu(): AppMenu[] {
const isDarwin = process.platform === 'darwin';
return [
{
Expand All @@ -41,6 +41,25 @@ export default class MenuBuilder {
},
],
},
{
id: 'MENU_APP_EDIT',
label: 'MENU_APP.APP_EDIT',
submenu: [
{ label: 'MENU_APP.APP_SUBMENU.APP_UNDO', accelerator: "CmdOrCtrl+Z", role: "undo" },
{ label: "MENU_APP.APP_SUBMENU.APP_REDO", accelerator: "Shift+CmdOrCtrl+Z", role: "redo" },
{ type: "separator" },
{ label: "MENU_APP.APP_SUBMENU.APP_CUT", accelerator: "CmdOrCtrl+X", role: "cut" },
{ label: "MENU_APP.APP_SUBMENU.APP_COPY", accelerator: "CmdOrCtrl+C", role: "copy" },
{ label: "MENU_APP.APP_SUBMENU.APP_PASTE", accelerator: "CmdOrCtrl+V", role: "paste" },
{ label: "MENU_APP.APP_SUBMENU.APP_SELECT_ALL", accelerator: "CmdOrCtrl+A", role: "selectAll" }
]
}
]
}

defaultMenu(): AppMenu[] {
return [
...this.initialMenu(),
{
id: 'MENU_APP_WINDOW',
label: 'MENU_APP.APP_WINDOW',
Expand Down Expand Up @@ -110,6 +129,10 @@ export default class MenuBuilder {
return Menu.buildFromTemplate(this.translateAppMenu(i18nextMainBackend, menuItems));
}

buildInitialTemplate(menuItems: any, i18nextMainBackend: typeof i18n) {
return Menu.buildFromTemplate(this.translateAppMenu(i18nextMainBackend, menuItems));
}

updateAppMenu(menuItem: string, context: { label?: string, enabled?: boolean}, contextMenuItems: any, i18nextMainBackend: typeof i18n) {
const menuIdx:number = contextMenuItems.findIndex((item: any) => item.id === menuItem);
if (menuIdx > -1) {
Expand Down
2 changes: 1 addition & 1 deletion apps/server-web/src/renderer/components/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const SelectComponent = ({
onValueChange={onValueChange}
>
<Select.Trigger
className="inline-flex items-center justify-center rounded-lg px-[15px] text-[13px] leading-none h-[35px] gap-[5px] bg-white dark:bg-[#25272D] text-violet11 dark:text-white shadow-[0_2px_10px] shadow-black/10 hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black data-[placeholder]:text-violet9 outline-none"
className="inline-flex items-center justify-center rounded-lg px-[15px] text-[13px] leading-none h-[35px] gap-[5px] bg-white dark:bg-[#25272D] text-black dark:text-white shadow-[0_2px_10px] shadow-black/10 hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black data-[placeholder]:text-violet9 outline-none"
aria-label="Food"
>
<Select.Value placeholder={title} />
Expand Down
4 changes: 2 additions & 2 deletions apps/server-web/src/renderer/components/Updater.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const UpdaterComponent = (props: IUpdaterComponent) => {
setToastShow(false);
};

const onSelectPeriode = (value: string) => {
const onSelectPeriod = (value: string) => {
props.changeAutoUpdate({
autoUpdate: props.data.autoUpdate,
updateCheckPeriod: value,
Expand Down Expand Up @@ -152,7 +152,7 @@ export const UpdaterComponent = (props: IUpdaterComponent) => {
value={props.data.updateCheckPeriod}
defaultValue={props.data.updateCheckPeriod}
disabled={!props.data.autoUpdate}
onValueChange={onSelectPeriode}
onValueChange={onSelectPeriod}
/>
</div>
</div>
Expand Down
14 changes: 12 additions & 2 deletions apps/server-web/src/renderer/pages/setup/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { config } from '../../../configs/config';
import { useTranslation } from 'react-i18next';
import LanguageSelector from '../../components/LanguageSelector';
import { useEffect, useState } from 'react';
import { ThemeToggler } from '../../components/Toggler';
type props = {
nextAction: () => void;
};
Expand All @@ -25,8 +26,17 @@ const Landing = (props: props) => {
}, []);
return (
<div className="w-full">
<div className="mb-6 ml-10">
<LanguageSelector lang={defaultLang} />
<div className="flex w-full mb-6 ml-10">
<div className="flex flex-col w-6/12">
<div>
<LanguageSelector lang={defaultLang} />
</div>
</div>
<div className="flex w-6/12 flex-row-reverse mr-10">
<div className="flex flex-col w-2/8">
<ThemeToggler />
</div>
</div>
</div>

<div className="mb-8 w-full text-center">
Expand Down
186 changes: 186 additions & 0 deletions apps/web/app/[locale]/reports/weekly-limit/components/data-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
'use client';

import * as React from 'react';
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable
} from '@tanstack/react-table';

import { Checkbox } from '@/components/ui/checkbox';

import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useTranslations } from 'next-intl';
import { formatIntegerToHour, formatTimeString } from '@/app/helpers';
import { ProgressBar } from '@/lib/components';

export type WeeklyLimitTableDataType = {
member: string;
timeSpent: number;
limit: number;
percentageUsed: number;
remaining: number;
};

/**
* Renders a data table displaying weekly time limits and usage for team members.
*
* @component
* @param {Object} props - The component props.
* @param {WeeklyLimitTableDataType[]} props.data - Array of data objects containing weekly time usage information.
*
* @returns {JSX.Element} A table showing member-wise weekly time limits, usage, and remaining time.
*
*/

export function DataTableWeeklyLimits(props: { data: WeeklyLimitTableDataType[] }) {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const t = useTranslations();

const columns: ColumnDef<WeeklyLimitTableDataType>[] = [
{
id: 'select',
header: ({ table }) => (
<div className="">
<Checkbox
checked={
table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')
}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
/>
</div>
),
cell: ({ row }) => (
<div className="">
<Checkbox checked={row.getIsSelected()} onCheckedChange={(value) => row.toggleSelected(!!value)} />
</div>
),
enableSorting: false,
enableHiding: false
},
{
accessorKey: 'member',
header: () => <div className="">{t('common.MEMBER')}</div>,
cell: ({ row }) => <div className="capitalize">{row.getValue('member')}</div>
},
{
accessorKey: 'timeSpent',
header: () => <div className="">{t('pages.timeLimitReport.TIME_SPENT')}</div>,
cell: ({ row }) => (
<div className="lowercase">
{formatTimeString(formatIntegerToHour(Number(row.getValue('timeSpent')) / 3600))}
</div>
)
},
{
accessorKey: 'limit',
header: () => <div className="">{t('pages.timeLimitReport.LIMIT')}</div>,
cell: ({ row }) => (
<div className="lowercase">
{formatTimeString(formatIntegerToHour(Number(row.getValue('limit')) / 3600))}
</div>
)
},
{
accessorKey: 'percentageUsed',
header: () => <div className="">{t('pages.timeLimitReport.PERCENTAGE_USED')}</div>,
cell: ({ row }) => (
<div className="lowercase flex gap-2 items-center">
<ProgressBar
width={'10rem'}
progress={`${Number(row.getValue('percentageUsed')) < 100 ? Number(row.getValue('percentageUsed')).toFixed(2) : 100}%`}
/>{' '}
<span>{`${Number(row.getValue('percentageUsed')).toFixed(2)}%`}</span>
</div>
)
},
{
accessorKey: 'remaining',
header: () => <div className="">{t('pages.timeLimitReport.REMAINING')}</div>,
cell: ({ row }) => (
<div className="lowercase">
{Number(row.getValue('percentageUsed')) > 100 && '-'}
{formatTimeString(formatIntegerToHour(Number(row.getValue('remaining')) / 3600))}
</div>
)
}
];

const table = useReactTable({
data: props.data,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection
}
});

return (
<div className="w-full">
{table?.getRowModel()?.rows.length ? (
<div className="rounded-md">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table?.getRowModel()?.rows.length ? (
table?.getRowModel().rows.map((row) => (
<TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
{t('common.NO_RESULT')}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
) : (
<div className="w-full h-12 flex items-center justify-center">
<span>{t('common.NO_RESULT')}</span>
</div>
)}
</div>
);
}
Loading

0 comments on commit ecd5a95

Please sign in to comment.