Website improvements 4 (#3182)

* Add contributor individual page

* Improve mobile menu

* Fix

* Remove yarn.lock from twenty-website

* Add yarn to gitingore

* Fix linter
This commit is contained in:
Félix Malfait
2023-12-31 10:41:53 +01:00
committed by GitHub
parent 97f83b55b0
commit 858c294f14
60 changed files with 571 additions and 9797 deletions

View File

@ -6,12 +6,12 @@ import { isNonEmptyString } from '@sniptt/guards';
import debounce from 'lodash.debounce';
import { Activity } from '@/activities/types/Activity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { BlockEditor } from '@/ui/input/editor/components/BlockEditor';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { FileFolder, useUploadFileMutation } from '~/generated/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledBlockNoteStyledContainer = styled.div`
width: 100%;

View File

@ -7,6 +7,7 @@ import { Comment } from '@/activities/comment/Comment';
import { Activity } from '@/activities/types/Activity';
import { Comment as CommentType } from '@/activities/types/Comment';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import {
@ -14,7 +15,6 @@ import {
AutosizeTextInputVariant,
} from '@/ui/input/components/AutosizeTextInput';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledThreadItemListContainer = styled.div`
align-items: flex-start;

View File

@ -6,6 +6,7 @@ import { AttachmentDropdown } from '@/activities/files/components/AttachmentDrop
import { AttachmentIcon } from '@/activities/files/components/AttachmentIcon';
import { Attachment } from '@/activities/files/types/Attachment';
import { downloadFile } from '@/activities/files/utils/downloadFile';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import {
FieldContext,
GenericFieldContextType,
@ -14,7 +15,6 @@ import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { IconCalendar } from '@/ui/display/icon';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { formatToHumanReadableDate } from '~/utils';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledRow = styled.div`
align-items: center;

View File

@ -8,11 +8,11 @@ import { Attachment } from '@/activities/files/types/Attachment';
import { getFileType } from '@/activities/files/utils/getFileType';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { IconPlus } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button';
import { FileFolder, useUploadFileMutation } from '~/generated/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledTaskGroupEmptyContainer = styled.div`
align-items: center;

View File

@ -1,8 +1,8 @@
import { Attachment } from '@/activities/files/types/Attachment';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { ActivityTargetableEntity } from '../../types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
// do we need to test this?
export const useAttachments = (entity: ActivityTargetableEntity) => {

View File

@ -5,6 +5,7 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { Activity, ActivityType } from '@/activities/types/Activity';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
@ -15,7 +16,6 @@ import { activityTargetableEntityArrayState } from '../states/activityTargetable
import { viewableActivityIdState } from '../states/viewableActivityIdState';
import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity';
import { getTargetableEntitiesWithParents } from '../utils/getTargetableEntitiesWithParents';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useOpenCreateActivityDrawer = () => {
const { openRightDrawer } = useRightDrawer();

View File

@ -6,12 +6,12 @@ import { useHandleCheckableActivityTargetChange } from '@/activities/hooks/useHa
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/activities/utils/flatMapAndSortEntityForSelectArrayByName';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlineCell';
import { MultipleEntitySelect } from '@/object-record/relation-picker/components/MultipleEntitySelect';
import { useRelationPicker } from '@/object-record/relation-picker/hooks/useRelationPicker';
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
import { assertNotNull } from '~/utils/assert';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
type ActivityTargetInlineCellEditModeProps = {
activityId: string;

View File

@ -1,9 +1,9 @@
import { Note } from '@/activities/types/Note';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { OrderByField } from '@/object-metadata/types/OrderByField';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { ActivityTargetableEntity } from '../../types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useNotes = (entity: ActivityTargetableEntity) => {
const { records: activityTargets } = useFindManyRecords({

View File

@ -1,10 +1,10 @@
import { useRecoilState } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { IconTrash } from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
type ActivityActionBarProps = {
activityId: string;

View File

@ -4,11 +4,11 @@ import { useRecoilState } from 'recoil';
import { ActivityEditor } from '@/activities/components/ActivityEditor';
import { Activity } from '@/activities/types/Activity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import '@blocknote/core/style.css';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledContainer = styled.div`
box-sizing: border-box;

View File

@ -6,6 +6,7 @@ import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRi
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { GraphQLActivity } from '@/activities/types/GraphQLActivity';
import { getActivitySummary } from '@/activities/utils/getActivitySummary';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { IconCalendar, IconComment } from '@/ui/display/icon';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
@ -13,7 +14,6 @@ import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils';
import { useCompleteTask } from '../hooks/useCompleteTask';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledContainer = styled.div`
align-items: center;

View File

@ -1,8 +1,8 @@
import { useCallback } from 'react';
import { Activity } from '@/activities/types/Activity';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
type Task = Pick<Activity, 'id' | 'completedAt'>;

View File

@ -2,9 +2,9 @@ import { DateTime } from 'luxon';
import { useRecoilValue } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { parseDate } from '~/utils/date-utils';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useCurrentUserTaskCount = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);

View File

@ -3,11 +3,11 @@ import { DateTime } from 'luxon';
import { Activity } from '@/activities/types/Activity';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { parseDate } from '~/utils/date-utils';
import { isDefined } from '~/utils/isDefined';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
type UseTasksProps = {
filterDropdownId?: string;

View File

@ -5,11 +5,11 @@ import { ActivityCreateButton } from '@/activities/components/ActivityCreateButt
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
import { Activity } from '@/activities/types/Activity';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { TimelineItemsContainer } from './TimelineItemsContainer';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledMainContainer = styled.div`
align-items: flex-start;

View File

@ -6,6 +6,7 @@ import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRi
import { Activity } from '@/activities/types/Activity';
import { Company } from '@/companies/types/Company';
import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { Person } from '@/people/types/Person';
import { IconNotes } from '@/ui/display/icon';
@ -26,7 +27,6 @@ import { Command, CommandType } from '../types/Command';
import { CommandGroup } from './CommandGroup';
import { CommandMenuItem } from './CommandMenuItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const StyledDialog = styled.div`
background: ${({ theme }) => theme.background.secondary};

View File

@ -6,6 +6,7 @@ import { flip, offset, useFloating } from '@floating-ui/react';
import { v4 } from 'uuid';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { FieldDoubleText } from '@/object-record/field/types/FieldDoubleText';
import { RelationPicker } from '@/object-record/relation-picker/components/RelationPicker';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
@ -16,7 +17,6 @@ import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledContainer = styled.div`
position: static;

View File

@ -2,6 +2,7 @@ import { ReactNode, useContext } from 'react';
import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import {
FieldContext,
RecordUpdateHook,
@ -24,7 +25,6 @@ import { getLogoUrlFromDomainName } from '~/utils';
import { companyProgressesFamilyState } from '../states/companyProgressesFamilyState';
import { CompanyChip } from './CompanyChip';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledBoardCard = styled.div<{ selected: boolean }>`
background-color: ${({ theme, selected }) =>

View File

@ -4,11 +4,11 @@ import { isNonEmptyArray } from '@sniptt/guards';
import { Company } from '@/companies/types/Company';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { mapPaginatedRecordsToRecords } from '@/object-record/utils/mapPaginatedRecordsToRecords';
import { PeopleCard } from '@/people/components/PeopleCard';
import { AddPersonToCompany } from './AddPersonToCompany';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export type CompanyTeamProps = {
company: Pick<Company, 'id'>;

View File

@ -3,6 +3,7 @@ import { useRecoilValue } from 'recoil';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
import { availableRecordBoardCardFieldsScopedState } from '@/object-record/record-board/states/availableRecordBoardCardFieldsScopedState';
import { recordBoardCardFieldsScopedState } from '@/object-record/record-board/states/recordBoardCardFieldsScopedState';
@ -14,7 +15,6 @@ import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'
import { useViewBar } from '@/views/hooks/useViewBar';
import { ViewType } from '@/views/types/ViewType';
import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
type HooksCompanyBoardEffectProps = {
viewBarId: string;

View File

@ -2,6 +2,7 @@ import { useCallback, useContext, useState } from 'react';
import { useQuery } from '@apollo/client';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { NewButton } from '@/object-record/record-board/components/NewButton';
import { BoardColumnContext } from '@/object-record/record-board/contexts/BoardColumnContext';
import { useCreateOpportunity } from '@/object-record/record-board/hooks/internal/useCreateOpportunity';
@ -11,7 +12,6 @@ import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const NewOpportunityButton = () => {
const [isCreatingCard, setIsCreatingCard] = useState(false);

View File

@ -3,6 +3,7 @@ import { useQuery } from '@apollo/client';
import { useRecoilValue } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { SingleEntitySelectBase } from '@/object-record/relation-picker/components/SingleEntitySelectBase';
import { useEntitySelectSearch } from '@/object-record/relation-picker/hooks/useEntitySelectSearch';
import { useRelationPicker } from '@/object-record/relation-picker/hooks/useRelationPicker';
@ -17,7 +18,6 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export type OpportunityPickerProps = {
companyId: string | null;

View File

@ -1,11 +1,11 @@
import { Company } from '@/companies/types/Company';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords';
import { useSpreadsheetImport } from '@/spreadsheet-import/hooks/useSpreadsheetImport';
import { SpreadsheetOptions } from '@/spreadsheet-import/types';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { fieldsForCompany } from '../utils/fieldsForCompany';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export type FieldCompanyMapping = (typeof fieldsForCompany)[number]['key'];

View File

@ -9,12 +9,12 @@ import { Favorite } from '@/favorites/types/Favorite';
import { mapFavorites } from '@/favorites/utils/mapFavorites';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { PaginatedRecordTypeResults } from '@/object-record/types/PaginatedRecordTypeResults';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { favoritesState } from '../states/favoritesState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useFavorites = ({
objectNamePlural,

View File

@ -3,6 +3,7 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { Company } from '@/companies/types/Company';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
import { turnObjectDropdownFilterIntoQueryFilter } from '@/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter';
@ -11,7 +12,6 @@ import { Opportunity } from '@/pipeline/types/Opportunity';
import { PipelineStep } from '@/pipeline/types/PipelineStep';
import { useFindManyRecords } from './useFindManyRecords';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useObjectRecordBoard = () => {
const objectNameSingular = 'opportunity';

View File

@ -3,6 +3,7 @@ import styled from '@emotion/styled';
import { DragDropContext, OnDragEndResponder } from '@hello-pangea/dnd'; // Atlassian dnd does not support StrictMode from RN 18, so we use a fork @hello-pangea/dnd https://github.com/atlassian/react-beautiful-dnd/issues/2350
import { useRecoilValue } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { RecordBoardActionBar } from '@/object-record/record-board/action-bar/components/RecordBoardActionBar';
import { RecordBoardInternalEffect } from '@/object-record/record-board/components/RecordBoardInternalEffect';
@ -22,7 +23,6 @@ import { BoardColumnDefinition } from '../types/BoardColumnDefinition';
import { BoardOptions } from '../types/BoardOptions';
import { RecordBoardColumn } from './RecordBoardColumn';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export type RecordBoardProps = {
recordBoardId: string;

View File

@ -1,10 +1,10 @@
import { useRecoilCallback } from 'recoil';
import { v4 } from 'uuid';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { recordBoardCardIdsByColumnIdFamilyState } from '@/object-record/record-board/states/recordBoardCardIdsByColumnIdFamilyState';
import { Opportunity } from '@/pipeline/types/Opportunity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useCreateOpportunity = () => {
const { createOneRecord: createOneOpportunity } =

View File

@ -1,12 +1,12 @@
import { useApolloClient } from '@apollo/client';
import { useRecoilCallback } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
import { Opportunity } from '@/pipeline/types/Opportunity';
import { useRemoveRecordBoardCardIdsInternal } from './useRemoveRecordBoardCardIdsInternal';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useDeleteSelectedRecordBoardCardsInternal = () => {
const removeCardIds = useRemoveRecordBoardCardIdsInternal();

View File

@ -1,12 +1,12 @@
import { useRecoilState } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
import { PipelineStep } from '@/pipeline/types/PipelineStep';
import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
import { BoardColumnDefinition } from '../../types/BoardColumnDefinition';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useBoardColumnsInternal = () => {
const { boardColumnsState } = useRecordBoardScopedStates();

View File

@ -6,6 +6,7 @@ import styled from '@emotion/styled';
import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { Person } from '@/people/types/Person';
import { IconDotsVertical, IconLinkOff, IconTrash } from '@/ui/display/icon';
import { FloatingIconButton } from '@/ui/input/button/components/FloatingIconButton';
@ -14,7 +15,6 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { Avatar } from '@/users/components/Avatar';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export type PeopleCardProps = {
person: Pick<Person, 'id' | 'avatarUrl' | 'name' | 'jobTitle'>;

View File

@ -1,5 +1,6 @@
import { v4 } from 'uuid';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords';
import { Person } from '@/people/types/Person';
import { useSpreadsheetImport } from '@/spreadsheet-import/hooks/useSpreadsheetImport';
@ -7,7 +8,6 @@ import { SpreadsheetOptions } from '@/spreadsheet-import/types';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { fieldsForPerson } from '../utils/fieldsForPerson';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export type FieldPersonMapping = (typeof fieldsForPerson)[number]['key'];

View File

@ -1,11 +1,11 @@
import { useRecoilCallback } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { BoardColumnDefinition } from '@/object-record/record-board/types/BoardColumnDefinition';
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
import { PipelineStep } from '@/pipeline/types/PipelineStep';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const usePipelineSteps = () => {
const { createOneRecord: createOnePipelineStep } =

View File

@ -17,7 +17,9 @@ export const useRelationFieldPreviewValue = ({
: undefined;
const { records: relationObjects } = useFindManyRecords({
objectNameSingular: relationObjectMetadataItem?.nameSingular ?? CoreObjectNameSingular.Company, // TODO fix this hack
objectNameSingular:
relationObjectMetadataItem?.nameSingular ??
CoreObjectNameSingular.Company, // TODO fix this hack
skip: skip || !relationObjectMetadataItem,
});

View File

@ -5,10 +5,10 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { TextInput } from '@/ui/input/components/TextInput';
import { logError } from '~/utils/logError';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledComboInputContainer = styled.div`
display: flex;

View File

@ -2,11 +2,11 @@ import { useState } from 'react';
import { useRecoilState } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { ImageInput } from '@/ui/input/components/ImageInput';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { useUploadProfilePictureMutation } from '~/generated/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const ProfilePictureUploader = () => {
const [uploadPicture, { loading: isUploading }] =

View File

@ -2,9 +2,9 @@ import { useCallback } from 'react';
import { useRecoilState } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useColorScheme = () => {
const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState(

View File

@ -2,13 +2,13 @@ import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { useViewBar } from '@/views/hooks/useViewBar';
import { GraphQLView } from '@/views/types/GraphQLView';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const ViewBarEffect = () => {
const {

View File

@ -2,10 +2,10 @@ import { useApolloClient } from '@apollo/client';
import { useRecoilCallback } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { ViewField } from '@/views/types/ViewField';
import { getViewScopedStatesFromSnapshot } from '@/views/utils/getViewScopedStatesFromSnapshot';
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useViewFields = (viewScopeId: string) => {
const { updateOneRecordMutation, createOneRecordMutation } =

View File

@ -3,13 +3,13 @@ import { produce } from 'immer';
import { useRecoilCallback } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { savedViewFiltersScopedFamilyState } from '@/views/states/savedViewFiltersScopedFamilyState';
import { ViewFilter } from '@/views/types/ViewFilter';
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
import { useViewScopedStates } from './useViewScopedStates';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useViewFilters = (viewScopeId: string) => {
const {

View File

@ -3,13 +3,13 @@ import { produce } from 'immer';
import { useRecoilCallback } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
import { savedViewSortsScopedFamilyState } from '@/views/states/savedViewSortsScopedFamilyState';
import { ViewSort } from '@/views/types/ViewSort';
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
import { useViewScopedStates } from './useViewScopedStates';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useViewSorts = (viewScopeId: string) => {
const {

View File

@ -2,9 +2,9 @@ import { useApolloClient } from '@apollo/client';
import { useRecoilCallback } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { GraphQLView } from '@/views/types/GraphQLView';
import { getViewScopedStateValuesFromSnapshot } from '@/views/utils/getViewScopedStateValuesFromSnapshot';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const useViews = (scopeId: string) => {
const {

View File

@ -12,6 +12,7 @@ import { Title } from '@/auth/components/Title';
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
@ -21,7 +22,6 @@ import { MainButton } from '@/ui/input/button/components/MainButton';
import { TextInput } from '@/ui/input/components/TextInput';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledContentContainer = styled.div`
width: 100%;

View File

@ -1,6 +1,7 @@
import styled from '@emotion/styled';
import { CompanyBoard } from '@/companies/board/components/CompanyBoard';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { PipelineAddButton } from '@/pipeline/components/PipelineAddButton';
import { usePipelineSteps } from '@/pipeline/hooks/usePipelineSteps';
@ -9,7 +10,6 @@ import { IconTargetArrow } from '@/ui/display/icon';
import { PageBody } from '@/ui/layout/page/PageBody';
import { PageContainer } from '@/ui/layout/page/PageContainer';
import { PageHeader } from '@/ui/layout/page/PageHeader';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledBoardContainer = styled.div`
display: flex;

View File

@ -3,6 +3,7 @@ import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
@ -16,7 +17,6 @@ import { Section } from '@/ui/layout/section/components/Section';
import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink';
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledH1Title = styled(H1Title)`
margin-bottom: 0;

View File

@ -5,6 +5,7 @@ import { useCreateOneRelationMetadataItem } from '@/object-metadata/hooks/useCre
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { PaginatedRecordTypeResults } from '@/object-record/types/PaginatedRecordTypeResults';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
@ -22,7 +23,6 @@ import { View } from '@/views/types/View';
import { ViewType } from '@/views/types/ViewType';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const SettingsObjectNewFieldStep2 = () => {
const navigate = useNavigate();

View File

@ -5,6 +5,7 @@ import { DateTime } from 'luxon';
import { useRecoilState } from 'recoil';
import { useOptimisticEvict } from '@/apollo/optimistic-effect/hooks/useOptimisticEvict';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
@ -24,7 +25,6 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
import { Section } from '@/ui/layout/section/components/Section';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledInfo = styled.span`
color: ${({ theme }) => theme.font.color.light};

View File

@ -2,6 +2,7 @@ import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import styled from '@emotion/styled';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { objectSettingsWidth } from '@/settings/data-model/constants/objectSettings';
import { SettingsApiKeysFieldItemTableRow } from '@/settings/developers/components/SettingsApiKeysFieldItemTableRow';
@ -15,7 +16,6 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
import { Table } from '@/ui/layout/table/components/Table';
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
const StyledContainer = styled.div`
height: fit-content;

View File

@ -2,6 +2,7 @@ import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { DateTime } from 'luxon';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
@ -17,7 +18,6 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
import { Section } from '@/ui/layout/section/components/Section';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
export const SettingsDevelopersApiKeysNew = () => {
const [generateOneApiKeyToken] = useGenerateApiKeyTokenMutation();

View File

@ -12,6 +12,8 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@jsdevtools/rehype-toc": "^3.0.2",
"@nivo/calendar": "^0.84.0",
"@nivo/core": "^0.84.0",
"@stoplight/elements": "^7.16.2",
"@tabler/icons-react": "^2.44.0",
"better-sqlite3": "^9.2.2",

View File

@ -1,6 +1,7 @@
'use client'
import styled from '@emotion/styled';
import Link from 'next/link';
export interface User {
login: string;
@ -50,10 +51,12 @@ const AvatarGrid = ({ users }: { users: User[] }) => {
return (
<AvatarGridContainer>
{users.map(user => (
<AvatarItem key={user.login}>
<img src={user.avatarUrl} alt={user.login} />
<span className="username">{user.login}</span>
</AvatarItem>
<Link href={`/developers/contributors/${user.login}`} key={`l_${user.login}`}>
<AvatarItem key={user.login}>
<img src={user.avatarUrl} alt={user.login} />
<span className="username">{user.login}</span>
</AvatarItem>
</Link>
))}
</AvatarGridContainer>
);

View File

@ -33,6 +33,7 @@ const Nav = styled.nav`
const LinkList = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
`;
const ListItem = styled.a`
@ -164,6 +165,13 @@ const HamburgerLine2 = styled.div`
const NavOpen = styled.div`
flex-direction: column;
align-items: center;
position: fixed;
inset: 0px;
top: 63px;
background-color: #fff;
gap: 33px;
padding-top: 32px;
z-index: 100;
`;
const MobileMenu = styled.div`

View File

@ -0,0 +1,9 @@
'use client'
import { ResponsiveTimeRange } from '@nivo/calendar'
export const ActivityLog = ({ data }: { data: { value: number, day: string }[] }) => {
return <ResponsiveTimeRange
data={data}
/>;
}

View File

@ -0,0 +1,100 @@
import Image from 'next/image';
import Database from 'better-sqlite3';
import AvatarGrid from '@/app/components/AvatarGrid';
import { ResponsiveTimeRange } from '@nivo/calendar'
import { ActivityLog } from './components/ActivityLog';
import { Metadata } from 'next';
interface Contributor {
login: string;
avatarUrl: string;
pullRequestCount: number;
}
export function generateMetadata({ params }: { params: { slug: string } }): Metadata {
return {
title: params.slug + ' | Contributors',
};
}
export default async function (
{ params }: { params: { slug: string } }) {
const db = new Database('db.sqlite', { readonly: true });
const contributor = db.prepare(`
SELECT
u.login,
u.avatarUrl,
(SELECT COUNT(*) FROM pullRequests WHERE authorId = u.id) AS pullRequestCount,
(SELECT COUNT(*) FROM issues WHERE authorId = u.id) AS issuesCount
FROM
users u
WHERE
u.login = :user_id
`).get({'user_id' : params.slug}) as Contributor;
const pullRequestActivity = db.prepare(`
SELECT
COUNT(*) as value,
DATE(createdAt) as day
FROM
pullRequests
WHERE
authorId = (SELECT id FROM users WHERE login = :user_id)
GROUP BY
DATE(createdAt)
ORDER BY
DATE(createdAt)
`).all({'user_id': params.slug}) as { value: number, day: string }[];
const pullRequestList = db.prepare(`
SELECT
id,
title,
body,
url,
createdAt,
updatedAt,
closedAt,
mergedAt
FROM
pullRequests
WHERE
authorId = (SELECT id FROM users WHERE login = :user_id)
ORDER BY
DATE(createdAt) DESC
`).all({'user_id': params.slug}) as { title: string, createdAt: string, url: string }[];
db.close();
return (
<div style={{maxWidth: '900px', display: 'flex', padding: '40px', gap: '24px'}}>
<div style={{ flexDirection: 'column', width: '240px'}}>
<Image src={contributor.avatarUrl} alt={contributor.login} width={240} height={240} />
<h1>{contributor.login}</h1>
</div>
<div style={{flexDirection: 'column'}}>
<div style={{width: '450px', height: '200px'}}>
<ActivityLog
data={pullRequestActivity}
/>
</div>
<div style={{width: '450px'}}>
{pullRequestList.map(pr => (
<div>
<a href={pr.url}>{pr.title}</a>
</div>
))}
</div>
</div>
</div>
);
};

View File

@ -7,7 +7,7 @@ export async function GET(
{ params }: { params: { slug: string } }) {
const db = new Database('db.sqlite', { readonly: true });
if(params.slug !== 'users' && params.slug !== 'labels' && params.slug !== 'pullRequests') {
if(params.slug !== 'users' && params.slug !== 'labels' && params.slug !== 'pullRequests' && params.slug !== 'issues') {
return Response.json({ error: 'Invalid table name' }, { status: 400 });
}

View File

@ -21,6 +21,7 @@ interface PullRequestNode {
id: string;
title: string;
body: string;
url: string;
createdAt: string;
updatedAt: string;
closedAt: string;
@ -35,6 +36,7 @@ interface IssueNode {
id: string;
title: string;
body: string;
url: string;
createdAt: string;
updatedAt: string;
closedAt: string;
@ -90,6 +92,7 @@ async function fetchData(cursor: string | null = null, isIssues: boolean = false
id
title
body
url
createdAt
updatedAt
closedAt
@ -119,6 +122,7 @@ async function fetchData(cursor: string | null = null, isIssues: boolean = false
id
title
body
url
createdAt
updatedAt
closedAt
@ -178,6 +182,7 @@ const initDb = () => {
id TEXT PRIMARY KEY,
title TEXT,
body TEXT,
url TEXT,
createdAt TEXT,
updatedAt TEXT,
closedAt TEXT,
@ -192,7 +197,8 @@ const initDb = () => {
id TEXT PRIMARY KEY,
title TEXT,
body TEXT,
createdAt TEXT,
url TEXT,
createdAt TEXT,
updatedAt TEXT,
closedAt TEXT,
authorId TEXT,
@ -249,10 +255,10 @@ export async function GET() {
const assignableUsers = await fetchAssignableUsers();
const prs = await fetchData(lastPRCursor) as Array<PullRequestNode>;
const issues = await fetchData(lastIssueCursor) as Array<IssueNode>;
const issues = await fetchData(lastIssueCursor, true) as Array<IssueNode>;
const insertPR = db.prepare('INSERT INTO pullRequests (id, title, body, createdAt, updatedAt, closedAt, mergedAt, authorId) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO NOTHING');
const insertIssue = db.prepare('INSERT INTO issues (id, title, body, createdAt, updatedAt, closedAt, authorId) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO NOTHING');
const insertPR = db.prepare('INSERT INTO pullRequests (id, title, body, url, createdAt, updatedAt, closedAt, mergedAt, authorId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO NOTHING');
const insertIssue = db.prepare('INSERT INTO issues (id, title, body, url, createdAt, updatedAt, closedAt, authorId) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO NOTHING');
const insertUser = db.prepare('INSERT INTO users (id, login, avatarUrl, url, isEmployee) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO NOTHING');
const insertLabel = db.prepare('INSERT INTO labels (id, name, color, description) VALUES (?, ?, ?, ?) ON CONFLICT(id) DO NOTHING');
const insertPullRequestLabel = db.prepare('INSERT INTO pullRequestLabels (pullRequestId, labelId) VALUES (?, ?)');
@ -262,7 +268,7 @@ export async function GET() {
console.log(pr);
if(pr.author == null) { continue; }
insertUser.run(pr.author.resourcePath, pr.author.login, pr.author.avatarUrl, pr.author.url, assignableUsers.has(pr.author.login) ? 1 : 0);
insertPR.run(pr.id, pr.title, pr.body, pr.createdAt, pr.updatedAt, pr.closedAt, pr.mergedAt, pr.author.resourcePath);
insertPR.run(pr.id, pr.title, pr.body, pr.url, pr.createdAt, pr.updatedAt, pr.closedAt, pr.mergedAt, pr.author.resourcePath);
for (const label of pr.labels.nodes) {
insertLabel.run(label.id, label.name, label.color, label.description);
@ -274,7 +280,7 @@ export async function GET() {
if(issue.author == null) { continue; }
insertUser.run(issue.author.resourcePath, issue.author.login, issue.author.avatarUrl, issue.author.url, assignableUsers.has(issue.author.login) ? 1 : 0);
insertIssue.run(issue.id, issue.title, issue.body, issue.createdAt, issue.updatedAt, issue.closedAt, issue.author.resourcePath);
insertIssue.run(issue.id, issue.title, issue.body, issue.url, issue.createdAt, issue.updatedAt, issue.closedAt, issue.author.resourcePath);
for (const label of issue.labels.nodes) {
insertLabel.run(label.id, label.name, label.color, label.description);

View File

@ -26,12 +26,12 @@ const Contributors = async () => {
ORDER BY
pullRequestCount DESC;
`).all() as Contributor[];
db.close();
return (
<div>
<h1>Top Contributors</h1>
<AvatarGrid users={contributors} />
</div>
);

View File

@ -7,8 +7,8 @@ import { HeaderMobile } from '@/app/components/HeaderMobile';
import './layout.css';
export const metadata: Metadata = {
title: 'Twenty.dev',
description: 'Twenty for Developer',
title: 'Twenty.com',
description: 'Open Source CRM',
icons: '/images/core/logo.svg',
};

File diff suppressed because it is too large Load Diff