add mass updates to time entry aggregate rows, make package actions run on manual dispatch

This commit is contained in:
Gregor Vostrak
2024-08-22 19:14:56 +02:00
parent 0c05ad240d
commit 33d139e3aa
6 changed files with 48 additions and 31 deletions

View File

@@ -1,6 +1,5 @@
name: Publish API package to NPM name: Publish API package to NPM
on: on: workflow_dispatch
push:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -1,6 +1,5 @@
name: Publish UI package to NPM name: Publish UI package to NPM
on: on: workflow_dispatch
push:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -32,10 +32,8 @@ const { timeEntries, allTimeEntriesLoaded } = storeToRefs(timeEntriesStore);
const { updateTimeEntry, fetchTimeEntries, createTimeEntry } = const { updateTimeEntry, fetchTimeEntries, createTimeEntry } =
useTimeEntriesStore(); useTimeEntriesStore();
function updateTimeEntries(timeEntries: TimeEntry[]) { function updateTimeEntries(ids: string[], changes: Partial<TimeEntry>) {
timeEntries.forEach((entry) => { useTimeEntriesStore().updateTimeEntries(ids, changes);
useTimeEntriesStore().updateTimeEntry(entry);
});
fetchTimeEntries(); fetchTimeEntries();
} }

View File

@@ -34,45 +34,37 @@ const props = defineProps<{
createProject: (project: CreateProjectBody) => Promise<Project | undefined>; createProject: (project: CreateProjectBody) => Promise<Project | undefined>;
createClient: (client: CreateClientBody) => Promise<Client | undefined>; createClient: (client: CreateClientBody) => Promise<Client | undefined>;
onStartStopClick: (timeEntry: TimeEntry) => void; onStartStopClick: (timeEntry: TimeEntry) => void;
updateTimeEntries: (timeEntries: TimeEntry[]) => void; updateTimeEntries: (ids: string[], changes: Partial<TimeEntry>) => void;
deleteTimeEntries: (timeEntries: TimeEntry[]) => void; deleteTimeEntries: (timeEntries: TimeEntry[]) => void;
currency: string; currency: string;
}>(); }>();
function updateTimeEntryDescription(description: string) { function updateTimeEntryDescription(description: string) {
const updatedTimeEntries = props.timeEntry.timeEntries.map( props.updateTimeEntries(
(entry: TimeEntry) => { props.timeEntry.timeEntries.map((timeEntry: TimeEntry) => timeEntry.id),
return { ...entry, description }; { description: description }
}
); );
props.updateTimeEntries(updatedTimeEntries);
} }
function updateTimeEntryTags(tags: string[]) { function updateTimeEntryTags(tags: string[]) {
const updatedTimeEntries = props.timeEntry.timeEntries.map( props.updateTimeEntries(
(entry: TimeEntry) => { props.timeEntry.timeEntries.map((timeEntry: TimeEntry) => timeEntry.id),
return { ...entry, tags }; { tags: tags }
}
); );
props.updateTimeEntries(updatedTimeEntries);
} }
function updateTimeEntryBillable(billable: boolean) { function updateTimeEntryBillable(billable: boolean) {
const updatedTimeEntries = props.timeEntry.timeEntries.map( props.updateTimeEntries(
(entry: TimeEntry) => { props.timeEntry.timeEntries.map((timeEntry: TimeEntry) => timeEntry.id),
return { ...entry, billable }; { billable: billable }
}
); );
props.updateTimeEntries(updatedTimeEntries);
} }
function updateProjectAndTask(projectId: string, taskId: string) { function updateProjectAndTask(projectId: string, taskId: string) {
const updatedTimeEntries = props.timeEntry.timeEntries.map( props.updateTimeEntries(
(entry: TimeEntry) => { props.timeEntry.timeEntries.map((timeEntry: TimeEntry) => timeEntry.id),
return { ...entry, project_id: projectId, task_id: taskId }; { project_id: projectId, task_id: taskId }
}
); );
props.updateTimeEntries(updatedTimeEntries);
} }
const expanded = ref(false); const expanded = ref(false);
@@ -163,7 +155,10 @@ const expanded = ref(false);
:createProject :createProject
:tags="tags" :tags="tags"
indent indent
:updateTimeEntry="(arg: TimeEntry) => updateTimeEntries([arg])" :updateTimeEntry="
(timeEntry: TimeEntry) =>
updateTimeEntries([timeEntry.id], { ...timeEntry })
"
:onStartStopClick="() => onStartStopClick(subEntry)" :onStartStopClick="() => onStartStopClick(subEntry)"
:deleteTimeEntry="() => deleteTimeEntries([subEntry])" :deleteTimeEntry="() => deleteTimeEntries([subEntry])"
:currency="currency" :currency="currency"

View File

@@ -28,7 +28,7 @@ const props = defineProps<{
clients: Client[]; clients: Client[];
createTag: (name: string) => Promise<Tag | undefined>; createTag: (name: string) => Promise<Tag | undefined>;
updateTimeEntry: (entry: TimeEntry) => void; updateTimeEntry: (entry: TimeEntry) => void;
updateTimeEntries: (entries: TimeEntry[]) => void; updateTimeEntries: (ids: string[], changes: Partial<TimeEntry>) => void;
deleteTimeEntries: (entries: TimeEntry[]) => void; deleteTimeEntries: (entries: TimeEntry[]) => void;
createTimeEntry: (entry: Omit<CreateTimeEntryBody, 'member_id'>) => void; createTimeEntry: (entry: Omit<CreateTimeEntryBody, 'member_id'>) => void;
createProject: (project: CreateProjectBody) => Promise<Project | undefined>; createProject: (project: CreateProjectBody) => Promise<Project | undefined>;

View File

@@ -77,6 +77,31 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
} }
} }
async function updateTimeEntries(
ids: string[],
changes: Partial<TimeEntry>
) {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
await handleApiRequestNotifications(
() =>
api.updateMultipleTimeEntries(
{
ids: ids,
changes: changes,
},
{
params: {
organization: organizationId,
},
}
),
'Time entries updated successfully',
'Failed to update time entries'
);
}
}
async function updateTimeEntry(timeEntry: TimeEntry) { async function updateTimeEntry(timeEntry: TimeEntry) {
const organizationId = getCurrentOrganizationId(); const organizationId = getCurrentOrganizationId();
if (organizationId) { if (organizationId) {
@@ -147,5 +172,6 @@ export const useTimeEntriesStore = defineStore('timeEntries', () => {
deleteTimeEntry, deleteTimeEntry,
fetchMoreTimeEntries, fetchMoreTimeEntries,
allTimeEntriesLoaded, allTimeEntriesLoaded,
updateTimeEntries,
}; };
}); });