This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import React from 'react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { mergeLayouts, normalizeLayouts } from '@/lib/ui/patch';
|
||||
import { API_BASE_URL, base44 } from '@/api/base44Client';
|
||||
import { request } from '@/api/httpClient';
|
||||
import { generateJobDescription, screenCandidate, matchTalentForJob } from './krowAi';
|
||||
import { recalcProfilePatch } from './krowScore';
|
||||
import { logActivity } from './userTracking';
|
||||
@@ -62,6 +65,52 @@ export function useUpdatePreferences() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A person's own UI layout changes, per page.
|
||||
*
|
||||
* Stored beside `customSkills` in the account's preferences, which is a store
|
||||
* that already exists, is already per-user, and already reaches Postgres
|
||||
* through `PATCH /api/v1/me/preferences`. No new endpoint, no new table, and
|
||||
* nothing to deploy — which is the whole point: a layout change is a runtime
|
||||
* change, and a runtime change that needed a release would not be one.
|
||||
*
|
||||
* What is written is the **operation list** the UI engine validated, never a
|
||||
* copy of the rendered tree and never Markdown. A stored tree would be a
|
||||
* photograph of the page on the day it was saved; an operation still means what
|
||||
* it said after a release moves the built-ins around it.
|
||||
*
|
||||
* The whole `uiLayouts` object is sent on every write, because the endpoint
|
||||
* shallow-merges its top-level keys: sending one page would replace the map and
|
||||
* silently drop every other page's layout.
|
||||
*/
|
||||
export function useUiLayouts() {
|
||||
const preferences = usePreferences();
|
||||
const update = useUpdatePreferences();
|
||||
|
||||
const layouts = React.useMemo(
|
||||
() => normalizeLayouts(preferences.uiLayouts).layouts,
|
||||
[preferences.uiLayouts]
|
||||
);
|
||||
|
||||
/**
|
||||
* Store one page's patch.
|
||||
*
|
||||
* A patch with no operations is removed rather than stored empty — that is
|
||||
* the same state as never having customised the page, and keeping the key
|
||||
* would grow the blob with a record of every page somebody once opened.
|
||||
*/
|
||||
const save = React.useCallback(async (page, patch) => {
|
||||
const key = String(page || '').trim();
|
||||
if (!key) return null;
|
||||
/* Only `uiLayouts` is sent. Every other preference — `customSkills` above
|
||||
all — is left for the endpoint's shallow merge to preserve, so a layout
|
||||
change can never disturb an authored skill. */
|
||||
return update.mutateAsync({ uiLayouts: mergeLayouts(layouts, key, patch) });
|
||||
}, [layouts, update]);
|
||||
|
||||
return { layouts, save, saving: update.isPending };
|
||||
}
|
||||
|
||||
export function useJobPostings() {
|
||||
return useQuery({
|
||||
queryKey: ['jobPostings'],
|
||||
@@ -326,6 +375,29 @@ export function useCreateJobPosting() {
|
||||
* organization now has one more worker offering that role and what is worth
|
||||
* asking has changed with it.
|
||||
*/
|
||||
/**
|
||||
* Record a NEW employee and their first declared role, in one transaction.
|
||||
*
|
||||
* One request, not two. Creating the worker and then the role as separate calls
|
||||
* leaves a worker nobody meant to create when the second fails — indistinguishable
|
||||
* from a real one and with nothing to say why it is there. The endpoint writes
|
||||
* both inside a transaction and rolls the worker back if the role cannot be
|
||||
* written, so a refused create leaves the database exactly as it was.
|
||||
*/
|
||||
export function useCreateWorkerWithRole() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: /** @param {any} data */ (data) => request('POST', '/worker-profiles/with-role', { body: data }),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['employeeRoles'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['workerProfiles'] });
|
||||
queryClient.invalidateQueries({ queryKey: owliverContextKey });
|
||||
logActivity('create_employee_role');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** Record another role for somebody already on file. A different request. */
|
||||
export function useCreateEmployeeRole() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
|
||||
Reference in New Issue
Block a user