diff --git a/src/components/Common/DetailViewLayout/DetailViewLayout.stories.tsx b/src/components/Common/DetailViewLayout/DetailViewLayout.stories.tsx index 362b11803..96b11187e 100644 --- a/src/components/Common/DetailViewLayout/DetailViewLayout.stories.tsx +++ b/src/components/Common/DetailViewLayout/DetailViewLayout.stories.tsx @@ -42,7 +42,7 @@ function EmployeesTabContent() { ) } -function PolicyActions() { +function usePolicyActions() { const Components = useComponentContext() return ( @@ -59,6 +59,7 @@ function PolicyActions() { export const Default = () => { const [selectedTabId, setSelectedTabId] = useState('details') + const actions = usePolicyActions() const tabs = [ { id: 'details', label: 'Details', content: }, @@ -71,7 +72,7 @@ export const Default = () => { subtitle="Paid time off policy" onBack={() => {}} backLabel="Time off policies" - actions={} + actions={actions} tabs={tabs} selectedTabId={selectedTabId} onTabChange={setSelectedTabId} @@ -81,6 +82,7 @@ export const Default = () => { export const WithoutBackButton = () => { const [selectedTabId, setSelectedTabId] = useState('details') + const actions = usePolicyActions() const tabs = [ { id: 'details', label: 'Details', content: }, @@ -91,7 +93,7 @@ export const WithoutBackButton = () => { } + actions={actions} tabs={tabs} selectedTabId={selectedTabId} onTabChange={setSelectedTabId} diff --git a/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetail.stories.tsx b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetail.stories.tsx new file mode 100644 index 000000000..9335a00d6 --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetail.stories.tsx @@ -0,0 +1,323 @@ +import { Suspense, useState } from 'react' +import { fn } from 'storybook/test' +import type { HolidayItem } from '../HolidaySelectionForm/HolidaySelectionFormTypes' +import { HolidayPolicyDetailPresentation } from './HolidayPolicyDetailPresentation' +import type { HolidayPolicyDetailEmployee } from './HolidayPolicyDetailTypes' +import { HamburgerMenu } from '@/components/Common/HamburgerMenu' +import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +import PlusCircleIcon from '@/assets/icons/plus-circle.svg?react' +import EditIcon from '@/assets/icons/edit-02.svg?react' +import TrashCanSvg from '@/assets/icons/trashcan.svg?react' + +export default { + title: 'Domain/TimeOff/HolidayPolicyDetail', + decorators: [ + (Story: React.ComponentType) => ( + Loading translations...}> + + + ), + ], +} + +const mockHolidays: HolidayItem[] = [ + { + uuid: 'newYearsDay', + name: "New Year's Day", + observedDate: 'January 1', + nextObservation: 'January 1, 2027', + }, + { + uuid: 'mlkDay', + name: 'Martin Luther King, Jr. Day', + observedDate: 'Third Monday in January', + nextObservation: 'January 18, 2027', + }, + { + uuid: 'presidentsDay', + name: "Presidents' Day", + observedDate: 'Third Monday in February', + nextObservation: 'February 15, 2027', + }, + { + uuid: 'memorialDay', + name: 'Memorial Day', + observedDate: 'Last Monday in May', + nextObservation: 'May 31, 2027', + }, + { + uuid: 'juneteenth', + name: 'Juneteenth', + observedDate: 'June 19', + nextObservation: 'June 19, 2026', + }, + { + uuid: 'independenceDay', + name: 'Independence Day', + observedDate: 'July 4', + nextObservation: 'July 4, 2026', + }, + { + uuid: 'laborDay', + name: 'Labor Day', + observedDate: 'First Monday in September', + nextObservation: 'September 7, 2026', + }, + { + uuid: 'columbusDay', + name: "Columbus Day (Indigenous Peoples' Day)", + observedDate: 'Second Monday in October', + nextObservation: 'October 12, 2026', + }, + { + uuid: 'veteransDay', + name: 'Veterans Day', + observedDate: 'November 11', + nextObservation: 'November 11, 2026', + }, + { + uuid: 'thanksgiving', + name: 'Thanksgiving', + observedDate: 'Fourth Thursday in November', + nextObservation: 'November 26, 2026', + }, + { + uuid: 'christmasDay', + name: 'Christmas Day', + observedDate: 'December 25', + nextObservation: 'December 25, 2026', + }, +] + +const mockEmployees: HolidayPolicyDetailEmployee[] = [ + { uuid: '1', firstName: 'Alejandro', lastName: 'Kuhic', jobTitle: 'Marketing Director' }, + { uuid: '2', firstName: 'Alexander', lastName: 'Hamilton', jobTitle: 'Engineer' }, + { uuid: '3', firstName: 'Arthur', lastName: 'Schopenhauer', jobTitle: 'Engineer' }, + { uuid: '4', firstName: 'Friedrich', lastName: 'Nietzsche', jobTitle: 'Engineer' }, + { uuid: '5', firstName: 'Hannah', lastName: 'Arendt', jobTitle: 'Account Manager' }, + { uuid: '6', firstName: 'Immanuel', lastName: 'Kant', jobTitle: 'Client Support Manager' }, +] + +const onBack = fn().mockName('onBack') +const onTabChange = fn().mockName('onTabChange') +const onDismissAlert = fn().mockName('onDismissAlert') +const onRemoveConfirm = fn().mockName('onRemoveConfirm') +const onRemoveClose = fn().mockName('onRemoveClose') + +function useSearchState() { + const [searchValue, setSearchValue] = useState('') + return { + searchValue, + onSearchChange: setSearchValue, + onSearchClear: () => { + setSearchValue('') + }, + } +} + +function usePolicyActions() { + const { Button } = useComponentContext() + + return [ + , + , + ] +} + +const closedRemoveDialog = { + isOpen: false, + employeeName: '', + onConfirm: onRemoveConfirm, + onClose: onRemoveClose, + isPending: false, +} + +export const HolidaysTab = () => { + const [selectedTabId, setSelectedTabId] = useState('holidays') + const search = useSearchState() + const actions = usePolicyActions() + + return ( + { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={closedRemoveDialog} + /> + ) +} + +export const EmployeesTab = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + const actions = usePolicyActions() + + return ( + { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={closedRemoveDialog} + /> + ) +} + +export const WithSuccessAlert = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + const actions = usePolicyActions() + + return ( + { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={closedRemoveDialog} + successAlert="Alejandro Kuhic has been removed from the policy." + onDismissAlert={onDismissAlert} + /> + ) +} + +export const RemoveDialogOpen = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + const actions = usePolicyActions() + + return ( + { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={{ + isOpen: true, + employeeName: 'Alejandro Kuhic', + onConfirm: onRemoveConfirm, + onClose: onRemoveClose, + isPending: false, + }} + /> + ) +} + +export const EmptyEmployees = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + const actions = usePolicyActions() + + return ( + { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: [], + ...search, + }} + removeDialog={closedRemoveDialog} + /> + ) +} diff --git a/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetailPresentation.tsx b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetailPresentation.tsx new file mode 100644 index 000000000..6240c39ed --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetailPresentation.tsx @@ -0,0 +1,85 @@ +import { useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import type { HolidayItem } from '../HolidaySelectionForm/HolidaySelectionFormTypes' +import { PolicyDetailLayout } from '../shared/PolicyDetailLayout' +import type { HolidayPolicyDetailPresentationProps } from './HolidayPolicyDetailTypes' +import { DataView, useDataView } from '@/components/Common' +import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +import { useI18n } from '@/i18n' + +const HOLIDAYS_TAB_ID = 'holidays' + +export function HolidayPolicyDetailPresentation({ + title, + subtitle, + onBack, + backLabel, + actions, + holidays, + selectedTabId, + onTabChange, + employees, + removeDialog, + successAlert, + onDismissAlert, +}: HolidayPolicyDetailPresentationProps) { + useI18n('Company.TimeOff.HolidayPolicy') + const { t } = useTranslation('Company.TimeOff.HolidayPolicy') + + const holidaysTabContent = + + return ( + + ) +} + +function HolidaysTab({ holidays }: { holidays: HolidayItem[] }) { + useI18n('Company.TimeOff.HolidayPolicy') + const { t } = useTranslation('Company.TimeOff.HolidayPolicy') + const { Text } = useComponentContext() + + const columns = useMemo( + () => [ + { + key: 'name' as keyof HolidayItem, + title: t('tableHeaders.holidayName'), + render: (item: HolidayItem) => {item.name}, + }, + { + key: 'observedDate' as keyof HolidayItem, + title: t('tableHeaders.observedDate'), + render: (item: HolidayItem) => {item.observedDate}, + }, + { + key: 'nextObservation' as keyof HolidayItem, + title: t('tableHeaders.nextObservation'), + render: (item: HolidayItem) => {item.nextObservation}, + }, + ], + [t, Text], + ) + + const dataViewProps = useDataView({ + data: holidays, + columns, + }) + + return +} diff --git a/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetailTypes.ts b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetailTypes.ts new file mode 100644 index 000000000..53dd11228 --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/HolidayPolicyDetailTypes.ts @@ -0,0 +1,41 @@ +import type { ReactNode } from 'react' +import type { HolidayItem } from '../HolidaySelectionForm/HolidaySelectionFormTypes' +import type { + EmployeeTableItem, + EmployeeTableProps, +} from '../shared/EmployeeTable/EmployeeTableTypes' +import type { RemoveDialogState } from '../shared/PolicyDetailLayout/PolicyDetailLayoutTypes' + +export interface HolidayPolicyDetailEmployee extends EmployeeTableItem { + uuid: string +} + +export interface HolidayPolicyDetailPresentationProps { + title: string + subtitle?: string + onBack: () => void + backLabel: string + actions?: ReactNode[] + + holidays: HolidayItem[] + + selectedTabId: string + onTabChange: (id: string) => void + + employees: Pick< + EmployeeTableProps, + | 'data' + | 'searchValue' + | 'onSearchChange' + | 'onSearchClear' + | 'searchPlaceholder' + | 'itemMenu' + | 'pagination' + | 'isFetching' + | 'emptyState' + > + + removeDialog: RemoveDialogState + successAlert?: string + onDismissAlert?: () => void +} diff --git a/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/index.ts b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/index.ts new file mode 100644 index 000000000..8570410ad --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/HolidayPolicyDetail/index.ts @@ -0,0 +1,5 @@ +export { HolidayPolicyDetailPresentation } from './HolidayPolicyDetailPresentation' +export type { + HolidayPolicyDetailPresentationProps, + HolidayPolicyDetailEmployee, +} from './HolidayPolicyDetailTypes' diff --git a/src/components/UNSTABLE_TimeOff/index.ts b/src/components/UNSTABLE_TimeOff/index.ts index d4c62394c..a9456015d 100644 --- a/src/components/UNSTABLE_TimeOff/index.ts +++ b/src/components/UNSTABLE_TimeOff/index.ts @@ -20,5 +20,10 @@ export { ViewHolidayEmployees } from './ViewHolidayEmployees/ViewHolidayEmployee export type { ViewHolidayEmployeesProps } from './ViewHolidayEmployees/ViewHolidayEmployees' export { ViewHolidaySchedule } from './ViewHolidaySchedule/ViewHolidaySchedule' export type { ViewHolidayScheduleProps } from './ViewHolidaySchedule/ViewHolidaySchedule' +export { HolidayPolicyDetailPresentation as HolidayPolicyDetail } from './HolidayPolicyDetail' +export type { + HolidayPolicyDetailPresentationProps as HolidayPolicyDetailProps, + HolidayPolicyDetailEmployee, +} from './HolidayPolicyDetail' export { TimeOffFlow } from './TimeOffFlow/TimeOffFlow' export type { TimeOffFlowProps } from './TimeOffFlow/TimeOffFlowComponents' diff --git a/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.stories.tsx b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.stories.tsx new file mode 100644 index 000000000..1f2e465db --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.stories.tsx @@ -0,0 +1,233 @@ +import { Suspense, useState } from 'react' +import { fn } from 'storybook/test' +import type { EmployeeTableItem } from '../EmployeeTable/EmployeeTableTypes' +import { PolicyDetailLayout } from './PolicyDetailLayout' +import { HamburgerMenu } from '@/components/Common/HamburgerMenu' +import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +import TrashCanSvg from '@/assets/icons/trashcan.svg?react' + +export default { + title: 'Domain/TimeOff/PolicyDetailLayout', + decorators: [ + (Story: React.ComponentType) => ( + Loading translations...}> + + + ), + ], +} + +interface StoryEmployee extends EmployeeTableItem { + uuid: string +} + +const mockEmployees: StoryEmployee[] = [ + { uuid: '1', firstName: 'Alejandro', lastName: 'Kuhic', jobTitle: 'Marketing Director' }, + { uuid: '2', firstName: 'Alexander', lastName: 'Hamilton', jobTitle: 'Engineer' }, + { uuid: '3', firstName: 'Arthur', lastName: 'Schopenhauer', jobTitle: 'Engineer' }, + { uuid: '4', firstName: 'Friedrich', lastName: 'Nietzsche', jobTitle: 'Engineer' }, + { uuid: '5', firstName: 'Hannah', lastName: 'Arendt', jobTitle: 'Account Manager' }, +] + +const onBack = fn().mockName('onBack') +const onTabChange = fn().mockName('onTabChange') + +function useSearchState() { + const [searchValue, setSearchValue] = useState('') + return { + searchValue, + onSearchChange: setSearchValue, + onSearchClear: () => { + setSearchValue('') + }, + } +} + +function PlaceholderTabContent() { + const { Text } = useComponentContext() + return ( + + This is the domain-specific first tab content (e.g. holidays table, policy settings). + + ) +} + +const closedRemoveDialog = { + isOpen: false, + employeeName: '', + onConfirm: fn().mockName('onRemoveConfirm'), + onClose: fn().mockName('onRemoveClose'), + isPending: false, +} + +export const FirstTabSelected = () => { + const [selectedTabId, setSelectedTabId] = useState('details') + const search = useSearchState() + + return ( + + title="Company PTO" + subtitle="Paid time off policy" + onBack={onBack} + backLabel="Back to policies" + firstTab={{ + id: 'details', + label: 'Details', + content: , + }} + selectedTabId={selectedTabId} + onTabChange={id => { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={closedRemoveDialog} + /> + ) +} + +export const EmployeesTabSelected = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + + return ( + + title="Company PTO" + subtitle="Paid time off policy" + onBack={onBack} + backLabel="Back to policies" + firstTab={{ + id: 'details', + label: 'Details', + content: , + }} + selectedTabId={selectedTabId} + onTabChange={id => { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={closedRemoveDialog} + /> + ) +} + +export const WithSuccessAlert = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + + return ( + + title="Company PTO" + subtitle="Paid time off policy" + onBack={onBack} + backLabel="Back to policies" + firstTab={{ + id: 'details', + label: 'Details', + content: , + }} + selectedTabId={selectedTabId} + onTabChange={id => { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={closedRemoveDialog} + successAlert="Friedrich Nietzsche has been removed from the policy." + onDismissAlert={fn().mockName('onDismissAlert')} + /> + ) +} + +export const RemoveDialogOpen = () => { + const [selectedTabId, setSelectedTabId] = useState('employees') + const search = useSearchState() + + return ( + + title="Company PTO" + subtitle="Paid time off policy" + onBack={onBack} + backLabel="Back to policies" + firstTab={{ + id: 'details', + label: 'Details', + content: , + }} + selectedTabId={selectedTabId} + onTabChange={id => { + setSelectedTabId(id) + onTabChange(id) + }} + employees={{ + data: mockEmployees, + ...search, + itemMenu: employee => ( + , + onClick: fn().mockName(`remove-${employee.firstName}`), + }, + ]} + triggerLabel={`Actions for ${employee.firstName} ${employee.lastName}`} + /> + ), + }} + removeDialog={{ + isOpen: true, + employeeName: 'Friedrich Nietzsche', + onConfirm: fn().mockName('onRemoveConfirm'), + onClose: fn().mockName('onRemoveClose'), + isPending: false, + }} + /> + ) +} diff --git a/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.tsx b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.tsx new file mode 100644 index 000000000..9d1925d35 --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayout.tsx @@ -0,0 +1,84 @@ +import { useTranslation } from 'react-i18next' +import type { EmployeeTableItem } from '../EmployeeTable/EmployeeTableTypes' +import { EmployeeTable } from '../EmployeeTable/EmployeeTable' +import type { PolicyDetailLayoutProps } from './PolicyDetailLayoutTypes' +import { DetailViewLayout } from '@/components/Common' +import { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext' +import { useI18n } from '@/i18n' + +const EMPLOYEES_TAB_ID = 'employees' + +export function PolicyDetailLayout({ + title, + subtitle, + onBack, + backLabel, + actions, + firstTab, + selectedTabId, + onTabChange, + employees, + removeDialog, + successAlert, + onDismissAlert, +}: PolicyDetailLayoutProps) { + useI18n('Company.TimeOff.PolicyDetail') + const { t } = useTranslation('Company.TimeOff.PolicyDetail') + const { Alert, Dialog } = useComponentContext() + + const tabs = [ + { + id: firstTab.id, + label: firstTab.label, + content: firstTab.content, + }, + { + id: EMPLOYEES_TAB_ID, + label: t('tabs.employees'), + content: ( + + data={employees.data} + searchValue={employees.searchValue} + onSearchChange={employees.onSearchChange} + onSearchClear={employees.onSearchClear} + searchPlaceholder={employees.searchPlaceholder} + itemMenu={employees.itemMenu} + pagination={employees.pagination} + isFetching={employees.isFetching} + emptyState={employees.emptyState} + additionalColumns={employees.additionalColumns} + /> + ), + }, + ] + + return ( + <> + {successAlert && } + + + + + {t('removeEmployeeDialog.description', { name: removeDialog.employeeName })} + + + ) +} diff --git a/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayoutTypes.ts b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayoutTypes.ts new file mode 100644 index 000000000..a5db78f1d --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/PolicyDetailLayoutTypes.ts @@ -0,0 +1,44 @@ +import type { ReactNode } from 'react' +import type { EmployeeTableItem, EmployeeTableProps } from '../EmployeeTable/EmployeeTableTypes' + +export interface RemoveDialogState { + isOpen: boolean + employeeName: string + onConfirm: () => void + onClose: () => void + isPending: boolean +} + +export interface PolicyDetailLayoutProps { + title: string + subtitle?: string + onBack: () => void + backLabel: string + actions?: ReactNode[] + + firstTab: { + id: string + label: string + content: ReactNode + } + selectedTabId: string + onTabChange: (id: string) => void + + employees: Pick< + EmployeeTableProps, + | 'data' + | 'searchValue' + | 'onSearchChange' + | 'onSearchClear' + | 'searchPlaceholder' + | 'itemMenu' + | 'pagination' + | 'isFetching' + | 'emptyState' + | 'additionalColumns' + > + + removeDialog: RemoveDialogState + successAlert?: string + onDismissAlert?: () => void +} diff --git a/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/index.ts b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/index.ts new file mode 100644 index 000000000..751a6fb98 --- /dev/null +++ b/src/components/UNSTABLE_TimeOff/shared/PolicyDetailLayout/index.ts @@ -0,0 +1,2 @@ +export { PolicyDetailLayout } from './PolicyDetailLayout' +export type { PolicyDetailLayoutProps, RemoveDialogState } from './PolicyDetailLayoutTypes' diff --git a/src/i18n/en/Company.TimeOff.HolidayPolicy.json b/src/i18n/en/Company.TimeOff.HolidayPolicy.json index 873461b79..02aab69c8 100644 --- a/src/i18n/en/Company.TimeOff.HolidayPolicy.json +++ b/src/i18n/en/Company.TimeOff.HolidayPolicy.json @@ -14,7 +14,12 @@ }, "show": { "title": "Holiday pay policy", - "holidaySchedule": "Holiday schedule" + "holidaySchedule": "Holiday schedule", + "addEmployeesCta": "Add employees", + "editPolicyCta": "Edit policy" + }, + "tabs": { + "holidays": "Holidays" }, "holidayScheduleTable": { "title": "Holiday schedule", diff --git a/src/i18n/en/Company.TimeOff.PolicyDetail.json b/src/i18n/en/Company.TimeOff.PolicyDetail.json new file mode 100644 index 000000000..78bf6312b --- /dev/null +++ b/src/i18n/en/Company.TimeOff.PolicyDetail.json @@ -0,0 +1,12 @@ +{ + "tabs": { + "employees": "Employees" + }, + "backLabel": "Back to policies", + "removeEmployeeDialog": { + "title": "Remove {{name}}", + "description": "Are you sure you want to remove {{name}} from this policy?", + "confirmCta": "Remove", + "cancelCta": "Cancel" + } +} diff --git a/src/types/i18next.d.ts b/src/types/i18next.d.ts index 906fbcdc5..587e19a9d 100644 --- a/src/types/i18next.d.ts +++ b/src/types/i18next.d.ts @@ -489,6 +489,11 @@ export interface CompanyTimeOffHolidayPolicy{ "show":{ "title":string; "holidaySchedule":string; +"addEmployeesCta":string; +"editPolicyCta":string; +}; +"tabs":{ +"holidays":string; }; "holidayScheduleTable":{ "title":string; @@ -549,6 +554,18 @@ export interface CompanyTimeOffHolidayPolicy{ "employeesRemoved_other":string; }; }; +export interface CompanyTimeOffPolicyDetail{ +"tabs":{ +"employees":string; +}; +"backLabel":string; +"removeEmployeeDialog":{ +"title":string; +"description":string; +"confirmCta":string; +"cancelCta":string; +}; +}; export interface CompanyTimeOffSelectEmployees{ "title":string; "description":string; @@ -3379,6 +3396,6 @@ export interface common{ interface CustomTypeOptions { defaultNS: 'common'; - resources: { 'Company.Addresses': CompanyAddresses, 'Company.AssignSignatory': CompanyAssignSignatory, 'Company.BankAccount': CompanyBankAccount, 'Company.DocumentList': CompanyDocumentList, 'Company.FederalTaxes': CompanyFederalTaxes, 'Company.Industry': CompanyIndustry, 'Company.Locations': CompanyLocations, 'Company.OnboardingOverview': CompanyOnboardingOverview, 'Company.PaySchedule': CompanyPaySchedule, 'Company.SignatureForm': CompanySignatureForm, 'Company.StateTaxes': CompanyStateTaxes, 'Company.TimeOff.CreateTimeOffPolicy': CompanyTimeOffCreateTimeOffPolicy, 'Company.TimeOff.EmployeeTable': CompanyTimeOffEmployeeTable, 'Company.TimeOff.HolidayPolicy': CompanyTimeOffHolidayPolicy, 'Company.TimeOff.SelectEmployees': CompanyTimeOffSelectEmployees, 'Company.TimeOff.SelectPolicyType': CompanyTimeOffSelectPolicyType, 'Company.TimeOff.TimeOffPolicies': CompanyTimeOffTimeOffPolicies, 'Company.TimeOff.TimeOffPolicyDetails': CompanyTimeOffTimeOffPolicyDetails, 'Company.TimeOff.TimeOffRequests': CompanyTimeOffTimeOffRequests, 'Contractor.Address': ContractorAddress, 'Contractor.ContractorList': ContractorContractorList, 'Contractor.NewHireReport': ContractorNewHireReport, 'Contractor.PaymentMethod': ContractorPaymentMethod, 'Contractor.Payments.CreatePayment': ContractorPaymentsCreatePayment, 'Contractor.Payments.PaymentHistory': ContractorPaymentsPaymentHistory, 'Contractor.Payments.PaymentStatement': ContractorPaymentsPaymentStatement, 'Contractor.Payments.PaymentSummary': ContractorPaymentsPaymentSummary, 'Contractor.Payments.PaymentsList': ContractorPaymentsPaymentsList, 'Contractor.Profile': ContractorProfile, 'Contractor.Submit': ContractorSubmit, 'Employee.BankAccount': EmployeeBankAccount, 'Employee.Compensation': EmployeeCompensation, 'Employee.Dashboard': EmployeeDashboard, 'Employee.Deductions': EmployeeDeductions, 'Employee.DocumentSigner': EmployeeDocumentSigner, 'Employee.EmployeeDocuments': EmployeeEmployeeDocuments, 'Employee.EmployeeList': EmployeeEmployeeList, 'Employee.EmploymentEligibility': EmployeeEmploymentEligibility, 'Employee.FederalTaxes': EmployeeFederalTaxes, 'Employee.HomeAddress.Management': EmployeeHomeAddressManagement, 'Employee.HomeAddress': EmployeeHomeAddress, 'Employee.I9SignatureForm': EmployeeI9SignatureForm, 'Employee.Landing': EmployeeLanding, 'Employee.ManagementEmployeeList': EmployeeManagementEmployeeList, 'Employee.OnboardingSummary': EmployeeOnboardingSummary, 'Employee.PaySchedules': EmployeePaySchedules, 'Employee.PaymentMethod': EmployeePaymentMethod, 'Employee.Profile': EmployeeProfile, 'Employee.SplitPaycheck': EmployeeSplitPaycheck, 'Employee.StateTaxes': EmployeeStateTaxes, 'Employee.Taxes': EmployeeTaxes, 'Employee.Terminations.TerminateEmployee': EmployeeTerminationsTerminateEmployee, 'Employee.Terminations.TerminationFlow': EmployeeTerminationsTerminationFlow, 'Employee.Terminations.TerminationSummary': EmployeeTerminationsTerminationSummary, 'Employee.WorkAddress.Management': EmployeeWorkAddressManagement, 'InformationRequests.InformationRequestForm': InformationRequestsInformationRequestForm, 'InformationRequests.InformationRequestList': InformationRequestsInformationRequestList, 'InformationRequests': InformationRequests, 'Payroll.Common': PayrollCommon, 'Payroll.ConfirmWireDetailsBanner': PayrollConfirmWireDetailsBanner, 'Payroll.ConfirmWireDetailsForm': PayrollConfirmWireDetailsForm, 'Payroll.Dismissal': PayrollDismissal, 'Payroll.EmployeeSelection': PayrollEmployeeSelection, 'Payroll.GrossUpModal': PayrollGrossUpModal, 'Payroll.OffCycle': PayrollOffCycle, 'Payroll.OffCycleCreation': PayrollOffCycleCreation, 'Payroll.OffCycleDeductionsSetting': PayrollOffCycleDeductionsSetting, 'Payroll.OffCyclePayPeriodDateForm': PayrollOffCyclePayPeriodDateForm, 'Payroll.OffCycleReasonSelection': PayrollOffCycleReasonSelection, 'Payroll.OffCycleTaxWithholding': PayrollOffCycleTaxWithholding, 'Payroll.PayrollBlocker': PayrollPayrollBlocker, 'Payroll.PayrollConfiguration': PayrollPayrollConfiguration, 'Payroll.PayrollEditEmployee': PayrollPayrollEditEmployee, 'Payroll.PayrollFlow': PayrollPayrollFlow, 'Payroll.PayrollHistory': PayrollPayrollHistory, 'Payroll.PayrollLanding': PayrollPayrollLanding, 'Payroll.PayrollList': PayrollPayrollList, 'Payroll.PayrollOverview': PayrollPayrollOverview, 'Payroll.PayrollReceipts': PayrollPayrollReceipts, 'Payroll.RecoveryCasesList': PayrollRecoveryCasesList, 'Payroll.RecoveryCasesResubmit': PayrollRecoveryCasesResubmit, 'Payroll.Transition': PayrollTransition, 'Payroll.TransitionCreation': PayrollTransitionCreation, 'Payroll.TransitionPayrollAlert': PayrollTransitionPayrollAlert, 'Payroll.WireInstructions': PayrollWireInstructions, 'common': common, } + resources: { 'Company.Addresses': CompanyAddresses, 'Company.AssignSignatory': CompanyAssignSignatory, 'Company.BankAccount': CompanyBankAccount, 'Company.DocumentList': CompanyDocumentList, 'Company.FederalTaxes': CompanyFederalTaxes, 'Company.Industry': CompanyIndustry, 'Company.Locations': CompanyLocations, 'Company.OnboardingOverview': CompanyOnboardingOverview, 'Company.PaySchedule': CompanyPaySchedule, 'Company.SignatureForm': CompanySignatureForm, 'Company.StateTaxes': CompanyStateTaxes, 'Company.TimeOff.CreateTimeOffPolicy': CompanyTimeOffCreateTimeOffPolicy, 'Company.TimeOff.EmployeeTable': CompanyTimeOffEmployeeTable, 'Company.TimeOff.HolidayPolicy': CompanyTimeOffHolidayPolicy, 'Company.TimeOff.PolicyDetail': CompanyTimeOffPolicyDetail, 'Company.TimeOff.SelectEmployees': CompanyTimeOffSelectEmployees, 'Company.TimeOff.SelectPolicyType': CompanyTimeOffSelectPolicyType, 'Company.TimeOff.TimeOffPolicies': CompanyTimeOffTimeOffPolicies, 'Company.TimeOff.TimeOffPolicyDetails': CompanyTimeOffTimeOffPolicyDetails, 'Company.TimeOff.TimeOffRequests': CompanyTimeOffTimeOffRequests, 'Contractor.Address': ContractorAddress, 'Contractor.ContractorList': ContractorContractorList, 'Contractor.NewHireReport': ContractorNewHireReport, 'Contractor.PaymentMethod': ContractorPaymentMethod, 'Contractor.Payments.CreatePayment': ContractorPaymentsCreatePayment, 'Contractor.Payments.PaymentHistory': ContractorPaymentsPaymentHistory, 'Contractor.Payments.PaymentStatement': ContractorPaymentsPaymentStatement, 'Contractor.Payments.PaymentSummary': ContractorPaymentsPaymentSummary, 'Contractor.Payments.PaymentsList': ContractorPaymentsPaymentsList, 'Contractor.Profile': ContractorProfile, 'Contractor.Submit': ContractorSubmit, 'Employee.BankAccount': EmployeeBankAccount, 'Employee.Compensation': EmployeeCompensation, 'Employee.Dashboard': EmployeeDashboard, 'Employee.Deductions': EmployeeDeductions, 'Employee.DocumentSigner': EmployeeDocumentSigner, 'Employee.EmployeeDocuments': EmployeeEmployeeDocuments, 'Employee.EmployeeList': EmployeeEmployeeList, 'Employee.EmploymentEligibility': EmployeeEmploymentEligibility, 'Employee.FederalTaxes': EmployeeFederalTaxes, 'Employee.HomeAddress.Management': EmployeeHomeAddressManagement, 'Employee.HomeAddress': EmployeeHomeAddress, 'Employee.I9SignatureForm': EmployeeI9SignatureForm, 'Employee.Landing': EmployeeLanding, 'Employee.ManagementEmployeeList': EmployeeManagementEmployeeList, 'Employee.OnboardingSummary': EmployeeOnboardingSummary, 'Employee.PaySchedules': EmployeePaySchedules, 'Employee.PaymentMethod': EmployeePaymentMethod, 'Employee.Profile': EmployeeProfile, 'Employee.SplitPaycheck': EmployeeSplitPaycheck, 'Employee.StateTaxes': EmployeeStateTaxes, 'Employee.Taxes': EmployeeTaxes, 'Employee.Terminations.TerminateEmployee': EmployeeTerminationsTerminateEmployee, 'Employee.Terminations.TerminationFlow': EmployeeTerminationsTerminationFlow, 'Employee.Terminations.TerminationSummary': EmployeeTerminationsTerminationSummary, 'Employee.WorkAddress.Management': EmployeeWorkAddressManagement, 'InformationRequests.InformationRequestForm': InformationRequestsInformationRequestForm, 'InformationRequests.InformationRequestList': InformationRequestsInformationRequestList, 'InformationRequests': InformationRequests, 'Payroll.Common': PayrollCommon, 'Payroll.ConfirmWireDetailsBanner': PayrollConfirmWireDetailsBanner, 'Payroll.ConfirmWireDetailsForm': PayrollConfirmWireDetailsForm, 'Payroll.Dismissal': PayrollDismissal, 'Payroll.EmployeeSelection': PayrollEmployeeSelection, 'Payroll.GrossUpModal': PayrollGrossUpModal, 'Payroll.OffCycle': PayrollOffCycle, 'Payroll.OffCycleCreation': PayrollOffCycleCreation, 'Payroll.OffCycleDeductionsSetting': PayrollOffCycleDeductionsSetting, 'Payroll.OffCyclePayPeriodDateForm': PayrollOffCyclePayPeriodDateForm, 'Payroll.OffCycleReasonSelection': PayrollOffCycleReasonSelection, 'Payroll.OffCycleTaxWithholding': PayrollOffCycleTaxWithholding, 'Payroll.PayrollBlocker': PayrollPayrollBlocker, 'Payroll.PayrollConfiguration': PayrollPayrollConfiguration, 'Payroll.PayrollEditEmployee': PayrollPayrollEditEmployee, 'Payroll.PayrollFlow': PayrollPayrollFlow, 'Payroll.PayrollHistory': PayrollPayrollHistory, 'Payroll.PayrollLanding': PayrollPayrollLanding, 'Payroll.PayrollList': PayrollPayrollList, 'Payroll.PayrollOverview': PayrollPayrollOverview, 'Payroll.PayrollReceipts': PayrollPayrollReceipts, 'Payroll.RecoveryCasesList': PayrollRecoveryCasesList, 'Payroll.RecoveryCasesResubmit': PayrollRecoveryCasesResubmit, 'Payroll.Transition': PayrollTransition, 'Payroll.TransitionCreation': PayrollTransitionCreation, 'Payroll.TransitionPayrollAlert': PayrollTransitionPayrollAlert, 'Payroll.WireInstructions': PayrollWireInstructions, 'common': common, } }; } \ No newline at end of file