@elevasis/ui 2.67.0 → 2.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.js +3 -3
- package/dist/app/index.d.ts +575 -370
- package/dist/app/index.js +17 -23
- package/dist/auth/index.css +149 -149
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.js +11 -13
- package/dist/charts/index.css +208 -208
- package/dist/charts/index.js +11 -13
- package/dist/{chunk-M535KHLW.js → chunk-26BTE3Z4.js} +1 -1
- package/dist/chunk-3KMDHCAR.js +52 -0
- package/dist/chunk-3MEXPLWT.js +265 -0
- package/dist/chunk-4JHLS234.js +39 -0
- package/dist/chunk-6PZFOHJK.js +1764 -0
- package/dist/chunk-7WJEPTE7.js +194 -0
- package/dist/chunk-AH52XQB7.js +1 -0
- package/dist/{chunk-UFTM5SZZ.js → chunk-AKANHRQ5.js} +9 -3
- package/dist/chunk-BZZCNLT6.js +12 -0
- package/dist/chunk-C75XWBYZ.js +383 -0
- package/dist/chunk-DLR4SDZW.js +51 -0
- package/dist/{chunk-4OEVLV66.js → chunk-FLECOYUS.js} +113 -148
- package/dist/chunk-IRV6KJPV.js +425 -0
- package/dist/chunk-IT7GTJCB.js +10 -0
- package/dist/chunk-LGKLC5MG.js +44 -0
- package/dist/chunk-MFLM7BVC.js +85 -0
- package/dist/chunk-MRVGQLWN.js +1595 -0
- package/dist/{chunk-4DV4ECMG.js → chunk-N7U24M2J.js} +4 -0
- package/dist/{chunk-I7BZVVVU.js → chunk-NM4A63KJ.js} +104 -415
- package/dist/chunk-NU3NBXHP.js +1194 -0
- package/dist/chunk-PDHTXPSF.js +12 -0
- package/dist/chunk-RW64UJWT.js +1934 -0
- package/dist/{chunk-JFBZ6XDW.js → chunk-SNZDFCOQ.js} +3 -49
- package/dist/chunk-TUMSNGTX.js +35 -0
- package/dist/chunk-UD657ICS.js +589 -0
- package/dist/{chunk-XNW3O6QW.js → chunk-VDX6DL7Z.js} +1 -1
- package/dist/chunk-WXHAHKKI.js +16411 -0
- package/dist/chunk-XAZR3T6Y.js +2162 -0
- package/dist/chunk-XQ3ILKYN.js +37 -0
- package/dist/chunk-YCRINA2D.js +67 -0
- package/dist/chunk-YGCMMOY4.js +1484 -0
- package/dist/chunk-YNRYIXUT.js +10945 -0
- package/dist/chunk-ZD6LM53O.js +4528 -0
- package/dist/chunk-ZPTEGGKU.js +631 -0
- package/dist/components/chat/index.js +2 -1
- package/dist/components/index.css +208 -208
- package/dist/components/index.d.ts +1634 -264
- package/dist/components/index.js +2774 -14
- package/dist/components/navigation/index.css +149 -149
- package/dist/components/navigation/index.js +12 -13
- package/dist/features/auth/index.css +149 -149
- package/dist/features/auth/index.d.ts +457 -167
- package/dist/features/auth/index.js +13 -14
- package/dist/features/clients/index.css +208 -208
- package/dist/features/clients/index.d.ts +39 -1
- package/dist/features/clients/index.js +16 -13
- package/dist/features/content/index.d.ts +1788 -0
- package/dist/features/content/index.js +2180 -0
- package/dist/features/crm/index.d.ts +1802 -231
- package/dist/features/crm/index.js +16 -13
- package/dist/features/dashboard/index.d.ts +1 -8
- package/dist/features/dashboard/index.js +17 -13
- package/dist/features/delivery/index.d.ts +457 -167
- package/dist/features/delivery/index.js +16 -13
- package/dist/features/knowledge/index.css +149 -149
- package/dist/features/knowledge/index.js +11 -13
- package/dist/features/lead-gen/index.d.ts +53 -104
- package/dist/features/lead-gen/index.js +17 -13
- package/dist/features/monitoring/index.js +16 -13
- package/dist/features/monitoring/requests/index.js +15 -20
- package/dist/features/operations/index.d.ts +1 -86
- package/dist/features/operations/index.js +22 -12
- package/dist/features/public-agent-chat/index.js +2 -1
- package/dist/features/seo/index.js +2 -1
- package/dist/features/settings/index.d.ts +457 -167
- package/dist/features/settings/index.js +15 -13
- package/dist/hooks/access/index.css +149 -149
- package/dist/hooks/access/index.d.ts +5 -0
- package/dist/hooks/access/index.js +11 -13
- package/dist/hooks/delivery/index.d.ts +457 -167
- package/dist/hooks/delivery/index.js +2 -23
- package/dist/hooks/index.d.ts +2203 -244
- package/dist/hooks/index.js +11 -13
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +1 -8
- package/dist/hooks/published.d.ts +2203 -244
- package/dist/hooks/published.js +11 -13
- package/dist/initialization/index.d.ts +465 -169
- package/dist/knowledge/index.css +149 -149
- package/dist/knowledge/index.d.ts +5 -90
- package/dist/knowledge/index.js +3215 -3203
- package/dist/{knowledge-search-index-6EZNBNSR.js → knowledge-search-index-LP2WVSQX.js} +689 -695
- package/dist/layout/index.css +149 -149
- package/dist/layout/index.js +15 -13
- package/dist/organization/index.d.ts +10 -4
- package/dist/organization/index.js +1 -21
- package/dist/profile/index.d.ts +457 -167
- package/dist/provider/index.d.ts +576 -372
- package/dist/provider/index.js +11 -13
- package/dist/provider/published.css +149 -149
- package/dist/provider/published.d.ts +576 -372
- package/dist/provider/published.js +11 -13
- package/dist/supabase/index.d.ts +906 -347
- package/dist/test-utils/index.d.ts +15 -2
- package/dist/test-utils/index.js +41 -12
- package/dist/test-utils/setup-integration.js +1 -1
- package/dist/test-utils/setup.js +1 -1
- package/dist/theme/index.js +3 -2
- package/dist/theme/presets/index.js +1 -1
- package/dist/typeform/index.js +2049 -1
- package/dist/types/index.d.ts +477 -177
- package/dist/utils/index.d.ts +1 -8
- package/dist/utils/index.js +1 -1
- package/dist/vite/index.js +2 -2
- package/dist/vite-plugin-knowledge/index.js +1 -1
- package/package.json +7 -3
- package/src/features/README.md +28 -28
- package/dist/chunk-5TERYXOO.js +0 -51390
- package/dist/chunk-AUDNF2Q7.js +0 -2050
- package/dist/index.d.ts +0 -17888
- package/dist/index.js +0 -30
- package/dist/{chunk-GMXGDO3I.js → chunk-MISHPEJX.js} +1 -1
- package/dist/{chunk-RBGVNPA6.js → chunk-XQBURFKM.js} +0 -0
- package/dist/{index.css → features/content/index.css} +149 -149
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { getLeadGenStageCatalog } from './chunk-WXHAHKKI.js';
|
|
2
|
+
import { SYSTEM_INTERFACE_PROFILES, formatOntologyId, registerBuiltInReadinessProfile, registerReadinessInterfaceMarker, requireContractReadiness, computeInterfaceReadiness, addReadinessIssue, formatInterfaceIdentity, resourceBindingIds, requireCatalogReadiness, requireScopedBinding } from './chunk-NM4A63KJ.js';
|
|
3
|
+
|
|
4
|
+
// ../core/src/business/acquisition/ontology-validation.ts
|
|
5
|
+
var LEAD_GEN_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[0];
|
|
6
|
+
var CRM_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[1];
|
|
7
|
+
var LEAD_GEN_CRM_HANDOFF_INTERFACE = SYSTEM_INTERFACE_PROFILES[2];
|
|
8
|
+
LEAD_GEN_API_INTERFACE.readinessProfile;
|
|
9
|
+
CRM_API_INTERFACE.readinessProfile;
|
|
10
|
+
LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile;
|
|
11
|
+
var LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID = formatOntologyId({
|
|
12
|
+
scope: "sales.lead-gen",
|
|
13
|
+
kind: "object",
|
|
14
|
+
localId: "list"
|
|
15
|
+
});
|
|
16
|
+
var LEAD_GEN_COMPANY_OBJECT_ONTOLOGY_ID = formatOntologyId({
|
|
17
|
+
scope: "sales.lead-gen",
|
|
18
|
+
kind: "object",
|
|
19
|
+
localId: "company"
|
|
20
|
+
});
|
|
21
|
+
var LEAD_GEN_CONTACT_OBJECT_ONTOLOGY_ID = formatOntologyId({
|
|
22
|
+
scope: "sales.lead-gen",
|
|
23
|
+
kind: "object",
|
|
24
|
+
localId: "contact"
|
|
25
|
+
});
|
|
26
|
+
var LEAD_GEN_BUILD_TEMPLATE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
27
|
+
scope: "sales.lead-gen",
|
|
28
|
+
kind: "catalog",
|
|
29
|
+
localId: "build-template"
|
|
30
|
+
});
|
|
31
|
+
var LEAD_GEN_COMPANY_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
32
|
+
scope: "sales.lead-gen",
|
|
33
|
+
kind: "catalog",
|
|
34
|
+
localId: "company-stage"
|
|
35
|
+
});
|
|
36
|
+
var LEAD_GEN_CONTACT_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
37
|
+
scope: "sales.lead-gen",
|
|
38
|
+
kind: "catalog",
|
|
39
|
+
localId: "contact-stage"
|
|
40
|
+
});
|
|
41
|
+
var CRM_PIPELINE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
42
|
+
scope: "sales.crm",
|
|
43
|
+
kind: "catalog",
|
|
44
|
+
localId: "crm.pipeline"
|
|
45
|
+
});
|
|
46
|
+
var LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
47
|
+
scope: "sales.lead-gen",
|
|
48
|
+
kind: "catalog",
|
|
49
|
+
localId: "lead-gen.stage-catalog"
|
|
50
|
+
});
|
|
51
|
+
var LEAD_GEN_API_READINESS_CONTRACT = {
|
|
52
|
+
requiredObjects: [
|
|
53
|
+
LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID,
|
|
54
|
+
LEAD_GEN_COMPANY_OBJECT_ONTOLOGY_ID,
|
|
55
|
+
LEAD_GEN_CONTACT_OBJECT_ONTOLOGY_ID
|
|
56
|
+
],
|
|
57
|
+
requiredCatalogs: [
|
|
58
|
+
LEAD_GEN_BUILD_TEMPLATE_CATALOG_ONTOLOGY_ID,
|
|
59
|
+
LEAD_GEN_COMPANY_STAGE_CATALOG_ONTOLOGY_ID,
|
|
60
|
+
LEAD_GEN_CONTACT_STAGE_CATALOG_ONTOLOGY_ID
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
var CRM_API_READINESS_CONTRACT = {
|
|
64
|
+
requiredObjects: [],
|
|
65
|
+
requiredCatalogs: [CRM_PIPELINE_CATALOG_ONTOLOGY_ID]
|
|
66
|
+
};
|
|
67
|
+
function isPlainRecord(value) {
|
|
68
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
69
|
+
}
|
|
70
|
+
function createLeadGenStageCatalog(model) {
|
|
71
|
+
return {
|
|
72
|
+
id: LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID,
|
|
73
|
+
label: "Lead Gen Processing Stages",
|
|
74
|
+
ownerSystemId: "sales.lead-gen",
|
|
75
|
+
kind: "processing-stage-catalog",
|
|
76
|
+
entries: Object.fromEntries(
|
|
77
|
+
Object.entries(getLeadGenStageCatalog(model)).map(([key, entry]) => [
|
|
78
|
+
key,
|
|
79
|
+
{
|
|
80
|
+
...entry
|
|
81
|
+
}
|
|
82
|
+
])
|
|
83
|
+
),
|
|
84
|
+
legacyCatalogKey: "LEAD_GEN_STAGE_CATALOG"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function requireLeadGenSupplementalReadiness(issues, index, resources, context) {
|
|
88
|
+
const catalogs = resourceBindingIds(resources, "usesCatalogs");
|
|
89
|
+
const templateStepCatalog = findLeadGenTemplateStepCatalog(index);
|
|
90
|
+
if (templateStepCatalog === void 0) {
|
|
91
|
+
addReadinessIssue(
|
|
92
|
+
issues,
|
|
93
|
+
"SYSTEM_INTERFACE_NOT_READY",
|
|
94
|
+
"missing-template-step-catalog",
|
|
95
|
+
`System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" is missing a lead-gen template-step catalog.`
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
requireCatalogReadiness(issues, index, templateStepCatalog.id, context);
|
|
99
|
+
requireScopedBinding(issues, catalogs, "usesCatalogs", templateStepCatalog.id, context);
|
|
100
|
+
}
|
|
101
|
+
requireCatalogReadiness(issues, index, LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID, context);
|
|
102
|
+
}
|
|
103
|
+
function requireLeadGenInterfaceReadiness(issues, index, resources, context) {
|
|
104
|
+
requireContractReadiness(issues, index, resources, LEAD_GEN_API_READINESS_CONTRACT, context);
|
|
105
|
+
requireLeadGenSupplementalReadiness(issues, index, resources, context);
|
|
106
|
+
}
|
|
107
|
+
function requireCrmInterfaceReadiness(issues, index, resources, context) {
|
|
108
|
+
requireContractReadiness(issues, index, resources, CRM_API_READINESS_CONTRACT, context);
|
|
109
|
+
}
|
|
110
|
+
function findSystemInterfaceGrant(model, consumer, provider) {
|
|
111
|
+
return Object.values(model.topology?.relationships ?? {}).find((relationship) => {
|
|
112
|
+
const grant = relationship.metadata?.["systemInterfaceGrant"];
|
|
113
|
+
if (!isPlainRecord(grant) || !isPlainRecord(grant.consumer) || !isPlainRecord(grant.provider)) return false;
|
|
114
|
+
return grant.consumer.systemPath === consumer.systemPath && grant.consumer.interfaceKey === consumer.interfaceKey && grant.provider.systemPath === provider.systemPath && grant.provider.interfaceKey === provider.interfaceKey;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function requireHandoffBridgeReadiness(issues, model, context) {
|
|
118
|
+
const crmResult = computeInterfaceReadiness(model, CRM_API_INTERFACE);
|
|
119
|
+
if (!crmResult.ready) {
|
|
120
|
+
for (const issue of crmResult.issues) {
|
|
121
|
+
addReadinessIssue(
|
|
122
|
+
issues,
|
|
123
|
+
"SYSTEM_BRIDGE_NOT_READY",
|
|
124
|
+
issue.code,
|
|
125
|
+
`Provider interface ${formatInterfaceIdentity(CRM_API_INTERFACE.systemPath, CRM_API_INTERFACE.interfaceKey)} is not ready: ${issue.message}`,
|
|
126
|
+
{ path: issue.path, ref: issue.ref }
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const bridgeGrant = findSystemInterfaceGrant(model, context, CRM_API_INTERFACE);
|
|
131
|
+
if (bridgeGrant === void 0) {
|
|
132
|
+
addReadinessIssue(
|
|
133
|
+
issues,
|
|
134
|
+
"SYSTEM_BRIDGE_NOT_READY",
|
|
135
|
+
"missing-topology-grant",
|
|
136
|
+
`System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" requires a scoped topology grant to "${formatInterfaceIdentity(CRM_API_INTERFACE.systemPath, CRM_API_INTERFACE.interfaceKey)}".`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return bridgeGrant;
|
|
140
|
+
}
|
|
141
|
+
function getLeadGenCrmHandoffResourceIds(model) {
|
|
142
|
+
return Object.values(model.resources ?? {}).filter(
|
|
143
|
+
(resource) => resource.systemPath === LEAD_GEN_CRM_HANDOFF_INTERFACE.systemPath && resource.ontology?.usesCatalogs?.includes(CRM_PIPELINE_CATALOG_ONTOLOGY_ID) === true
|
|
144
|
+
).map((resource) => resource.id);
|
|
145
|
+
}
|
|
146
|
+
function mergeLeadGenDerivedCatalogs(model) {
|
|
147
|
+
const baseCatalogTypes = model.ontology?.catalogTypes ?? {};
|
|
148
|
+
const derivedCatalogTypes = {};
|
|
149
|
+
if (baseCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] === void 0) {
|
|
150
|
+
derivedCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] = createLeadGenStageCatalog(model);
|
|
151
|
+
}
|
|
152
|
+
if (Object.keys(derivedCatalogTypes).length === 0) return model;
|
|
153
|
+
return {
|
|
154
|
+
...model,
|
|
155
|
+
ontology: {
|
|
156
|
+
...model.ontology ?? {},
|
|
157
|
+
catalogTypes: {
|
|
158
|
+
...baseCatalogTypes,
|
|
159
|
+
...derivedCatalogTypes
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
registerBuiltInReadinessProfile(LEAD_GEN_API_INTERFACE.readinessProfile, {
|
|
165
|
+
validate: (issues, index, resources, _model, context) => requireLeadGenInterfaceReadiness(issues, index, resources, context),
|
|
166
|
+
prepareModel: mergeLeadGenDerivedCatalogs
|
|
167
|
+
});
|
|
168
|
+
registerBuiltInReadinessProfile(CRM_API_INTERFACE.readinessProfile, {
|
|
169
|
+
validate: (issues, index, resources, _model, context) => requireCrmInterfaceReadiness(issues, index, resources, context)
|
|
170
|
+
});
|
|
171
|
+
registerBuiltInReadinessProfile(LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile, {
|
|
172
|
+
validate: (issues, index, resources, model, context) => {
|
|
173
|
+
requireLeadGenInterfaceReadiness(issues, index, resources, context);
|
|
174
|
+
requireCrmInterfaceReadiness(issues, index, resources, { ...context, allowForeignOwner: true });
|
|
175
|
+
requireHandoffBridgeReadiness(issues, model, context);
|
|
176
|
+
},
|
|
177
|
+
prepareModel: mergeLeadGenDerivedCatalogs
|
|
178
|
+
});
|
|
179
|
+
registerReadinessInterfaceMarker(
|
|
180
|
+
LEAD_GEN_CRM_HANDOFF_INTERFACE.systemPath,
|
|
181
|
+
LEAD_GEN_CRM_HANDOFF_INTERFACE.interfaceKey,
|
|
182
|
+
(model) => ({
|
|
183
|
+
lifecycle: "active",
|
|
184
|
+
readinessProfile: LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile,
|
|
185
|
+
resourceIds: getLeadGenCrmHandoffResourceIds(model)
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
function findLeadGenTemplateStepCatalog(index) {
|
|
189
|
+
return Object.values(index.ontology.catalogTypes).find(
|
|
190
|
+
(catalog) => catalog.ownerSystemId === "sales.lead-gen" && catalog.kind === "template-step" && catalog.appliesTo === LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export { CRM_API_INTERFACE, LEAD_GEN_API_INTERFACE };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -25,11 +25,17 @@ function detectLayout(viteRoot) {
|
|
|
25
25
|
return {
|
|
26
26
|
mode: "monorepo",
|
|
27
27
|
projectRoot,
|
|
28
|
-
omSourcePath: resolve(projectRoot, "packages/elevasis
|
|
28
|
+
omSourcePath: resolve(projectRoot, "packages/elevasis/core/config/organization-model.ts"),
|
|
29
29
|
// monorepo mode does not consume mdxNodesDir; field kept for type uniformity
|
|
30
|
-
mdxNodesDir: resolve(projectRoot, "packages/elevasis
|
|
30
|
+
mdxNodesDir: resolve(projectRoot, "packages/elevasis/core/knowledge-nodes-unused"),
|
|
31
31
|
generatedDir: resolve(projectRoot, "packages/ui/src/knowledge/_generated"),
|
|
32
|
-
|
|
32
|
+
// Both, and the knowledge dir is the load-bearing one: monorepo runCodegen
|
|
33
|
+
// regenerates from the MDX bodies, so watching only the OM meant a node edit
|
|
34
|
+
// never hot-regenerated. Pre-dates the move — the paths changed, the gap did not.
|
|
35
|
+
watchPaths: [
|
|
36
|
+
resolve(projectRoot, "packages/elevasis/core/config/organization-model"),
|
|
37
|
+
resolve(projectRoot, "packages/elevasis/core/config/knowledge/nodes")
|
|
38
|
+
]
|
|
33
39
|
};
|
|
34
40
|
}
|
|
35
41
|
const parent = resolve(dir, "..");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Container, Stack } from '@mantine/core';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/layout/shell/PageContainer.tsx
|
|
5
|
+
var PageContainer = ({ children }) => {
|
|
6
|
+
return (
|
|
7
|
+
// Add padding to the top of the container to adjust for the topbar height
|
|
8
|
+
/* @__PURE__ */ jsx(Container, { size: "xl", p: 0, w: "100%", children: /* @__PURE__ */ jsx(Stack, { gap: "lg", children }) })
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { PageContainer };
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { getErrorInfo, formatErrorMessage, getErrorTitle } from './chunk-NM4A63KJ.js';
|
|
2
|
+
import { useElevasisServices } from './chunk-BI5VDO2K.js';
|
|
3
|
+
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
|
|
4
|
+
import { notifications } from '@mantine/notifications';
|
|
5
|
+
|
|
6
|
+
var showInfoNotification = (message) => {
|
|
7
|
+
notifications.show({
|
|
8
|
+
title: "Info",
|
|
9
|
+
message,
|
|
10
|
+
autoClose: 5e3,
|
|
11
|
+
color: "blue",
|
|
12
|
+
position: "top-right"
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
var showSuccessNotification = (message) => {
|
|
16
|
+
notifications.show({
|
|
17
|
+
title: "Action Successful",
|
|
18
|
+
message,
|
|
19
|
+
autoClose: 5e3,
|
|
20
|
+
color: "green",
|
|
21
|
+
position: "top-right"
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
var showErrorNotification = (error) => {
|
|
25
|
+
if (error instanceof Error) {
|
|
26
|
+
error = error.message;
|
|
27
|
+
}
|
|
28
|
+
notifications.show({
|
|
29
|
+
title: "Action Failed",
|
|
30
|
+
message: error,
|
|
31
|
+
autoClose: 5e3,
|
|
32
|
+
color: "red",
|
|
33
|
+
position: "top-right"
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
var showWarningNotification = (message) => {
|
|
37
|
+
notifications.show({
|
|
38
|
+
title: "Warning",
|
|
39
|
+
message,
|
|
40
|
+
autoClose: 5e3,
|
|
41
|
+
color: "orange",
|
|
42
|
+
position: "top-right"
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
var showApiErrorNotification = (error) => {
|
|
46
|
+
const { message, code, requestId, fields, retryAfter } = getErrorInfo(error);
|
|
47
|
+
notifications.show({
|
|
48
|
+
title: getErrorTitle(code),
|
|
49
|
+
message: formatErrorMessage(message, requestId, fields, retryAfter),
|
|
50
|
+
autoClose: retryAfter ? retryAfter * 1e3 : 5e3,
|
|
51
|
+
color: "red",
|
|
52
|
+
position: "top-right"
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
var milestoneKeys = {
|
|
56
|
+
all: ["project-milestones"],
|
|
57
|
+
lists: () => [...milestoneKeys.all, "list"],
|
|
58
|
+
list: (orgId, filters) => [...milestoneKeys.all, "list", orgId, filters],
|
|
59
|
+
details: () => [...milestoneKeys.all, "detail"],
|
|
60
|
+
detail: (id) => [...milestoneKeys.all, "detail", id]
|
|
61
|
+
};
|
|
62
|
+
function useMilestones(filters = {}) {
|
|
63
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
64
|
+
return useQuery({
|
|
65
|
+
queryKey: milestoneKeys.list(workOSOrganizationId, filters),
|
|
66
|
+
queryFn: async () => {
|
|
67
|
+
const res = await apiRequest(`/projects/${filters.projectId}/milestones`);
|
|
68
|
+
return res.milestones;
|
|
69
|
+
},
|
|
70
|
+
enabled: isReady && !!filters.projectId
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function useCreateMilestone() {
|
|
74
|
+
const { apiRequest } = useElevasisServices();
|
|
75
|
+
const queryClient = useQueryClient();
|
|
76
|
+
return useMutation({
|
|
77
|
+
mutationFn: async (params) => {
|
|
78
|
+
const { project_id, ...body } = params;
|
|
79
|
+
if (!project_id) throw new Error("project_id is required to create a milestone");
|
|
80
|
+
const res = await apiRequest(`/projects/${project_id}/milestones`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
body: JSON.stringify(body)
|
|
83
|
+
});
|
|
84
|
+
return res.milestone;
|
|
85
|
+
},
|
|
86
|
+
onSuccess: (data) => {
|
|
87
|
+
queryClient.invalidateQueries({ queryKey: milestoneKeys.all });
|
|
88
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
89
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(data.project_id) });
|
|
90
|
+
},
|
|
91
|
+
onError: (error) => {
|
|
92
|
+
showApiErrorNotification(error);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function useUpdateMilestone() {
|
|
97
|
+
const { apiRequest } = useElevasisServices();
|
|
98
|
+
const queryClient = useQueryClient();
|
|
99
|
+
return useMutation({
|
|
100
|
+
mutationFn: async (params) => {
|
|
101
|
+
const res = await apiRequest(`/milestones/${params.id}`, {
|
|
102
|
+
method: "PATCH",
|
|
103
|
+
body: JSON.stringify(params.updates)
|
|
104
|
+
});
|
|
105
|
+
return res.milestone;
|
|
106
|
+
},
|
|
107
|
+
onSuccess: (data) => {
|
|
108
|
+
queryClient.invalidateQueries({ queryKey: milestoneKeys.all });
|
|
109
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
110
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(data.project_id) });
|
|
111
|
+
},
|
|
112
|
+
onError: (error) => {
|
|
113
|
+
showApiErrorNotification(error);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function useDeleteMilestone() {
|
|
118
|
+
const { apiRequest } = useElevasisServices();
|
|
119
|
+
const queryClient = useQueryClient();
|
|
120
|
+
return useMutation({
|
|
121
|
+
mutationFn: async (params) => {
|
|
122
|
+
await apiRequest(`/milestones/${params.id}`, {
|
|
123
|
+
method: "DELETE"
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
onSuccess: (_, params) => {
|
|
127
|
+
queryClient.invalidateQueries({ queryKey: milestoneKeys.all });
|
|
128
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
129
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(params.projectId) });
|
|
130
|
+
},
|
|
131
|
+
onError: (error) => {
|
|
132
|
+
showApiErrorNotification(error);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
var taskKeys = {
|
|
137
|
+
all: ["project-tasks"],
|
|
138
|
+
lists: () => [...taskKeys.all, "list"],
|
|
139
|
+
list: (orgId, filters) => [...taskKeys.all, "list", orgId, filters],
|
|
140
|
+
details: () => [...taskKeys.all, "detail"],
|
|
141
|
+
detail: (id) => [...taskKeys.all, "detail", id]
|
|
142
|
+
};
|
|
143
|
+
function useTasks(filters = {}) {
|
|
144
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
145
|
+
return useQuery({
|
|
146
|
+
queryKey: taskKeys.list(workOSOrganizationId, filters),
|
|
147
|
+
queryFn: async () => {
|
|
148
|
+
const params = new URLSearchParams();
|
|
149
|
+
if (filters.status) params.set("status", filters.status);
|
|
150
|
+
if (filters.milestoneId) params.set("milestone_id", filters.milestoneId);
|
|
151
|
+
const qs = params.toString();
|
|
152
|
+
const base = `/projects/${filters.projectId}/tasks`;
|
|
153
|
+
const path = qs ? `${base}?${qs}` : base;
|
|
154
|
+
const res = await apiRequest(path);
|
|
155
|
+
return res.tasks;
|
|
156
|
+
},
|
|
157
|
+
enabled: isReady && !!filters.projectId
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function useCreateTask() {
|
|
161
|
+
const { apiRequest } = useElevasisServices();
|
|
162
|
+
const queryClient = useQueryClient();
|
|
163
|
+
return useMutation({
|
|
164
|
+
mutationFn: async (params) => {
|
|
165
|
+
const res = await apiRequest("/project-tasks", {
|
|
166
|
+
method: "POST",
|
|
167
|
+
body: JSON.stringify(params)
|
|
168
|
+
});
|
|
169
|
+
return res.task;
|
|
170
|
+
},
|
|
171
|
+
onSuccess: (data) => {
|
|
172
|
+
queryClient.invalidateQueries({ queryKey: taskKeys.all });
|
|
173
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
174
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(data.project_id) });
|
|
175
|
+
},
|
|
176
|
+
onError: (error) => {
|
|
177
|
+
showApiErrorNotification(error);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function useUpdateTask() {
|
|
182
|
+
const { apiRequest } = useElevasisServices();
|
|
183
|
+
const queryClient = useQueryClient();
|
|
184
|
+
return useMutation({
|
|
185
|
+
mutationFn: async (params) => {
|
|
186
|
+
const res = await apiRequest(`/project-tasks/${params.id}`, {
|
|
187
|
+
method: "PATCH",
|
|
188
|
+
body: JSON.stringify(params.updates)
|
|
189
|
+
});
|
|
190
|
+
return res.task;
|
|
191
|
+
},
|
|
192
|
+
onSuccess: (data) => {
|
|
193
|
+
queryClient.invalidateQueries({ queryKey: taskKeys.all });
|
|
194
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
195
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(data.project_id) });
|
|
196
|
+
},
|
|
197
|
+
onError: (error) => {
|
|
198
|
+
showApiErrorNotification(error);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
function useDeleteTask() {
|
|
203
|
+
const { apiRequest } = useElevasisServices();
|
|
204
|
+
const queryClient = useQueryClient();
|
|
205
|
+
return useMutation({
|
|
206
|
+
mutationFn: async (params) => {
|
|
207
|
+
await apiRequest(`/project-tasks/${params.id}`, {
|
|
208
|
+
method: "DELETE"
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
onSuccess: (_, params) => {
|
|
212
|
+
queryClient.invalidateQueries({ queryKey: taskKeys.all });
|
|
213
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
214
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(params.projectId) });
|
|
215
|
+
},
|
|
216
|
+
onError: (error) => {
|
|
217
|
+
showApiErrorNotification(error);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
var noteKeys = {
|
|
222
|
+
all: ["project-notes"],
|
|
223
|
+
lists: () => [...noteKeys.all, "list"],
|
|
224
|
+
list: (orgId, filters) => [...noteKeys.all, "list", orgId, filters],
|
|
225
|
+
details: () => [...noteKeys.all, "detail"],
|
|
226
|
+
detail: (id) => [...noteKeys.all, "detail", id]
|
|
227
|
+
};
|
|
228
|
+
function useProjectNotes(filters = {}) {
|
|
229
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
230
|
+
return useQuery({
|
|
231
|
+
queryKey: noteKeys.list(workOSOrganizationId, filters),
|
|
232
|
+
queryFn: async () => {
|
|
233
|
+
const res = await apiRequest(`/projects/${filters.projectId}/notes`);
|
|
234
|
+
return res.notes;
|
|
235
|
+
},
|
|
236
|
+
enabled: isReady && !!filters.projectId
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function useCreateNote() {
|
|
240
|
+
const { apiRequest } = useElevasisServices();
|
|
241
|
+
const queryClient = useQueryClient();
|
|
242
|
+
return useMutation({
|
|
243
|
+
mutationFn: async (params) => {
|
|
244
|
+
const res = await apiRequest("/project-notes", {
|
|
245
|
+
method: "POST",
|
|
246
|
+
body: JSON.stringify(params)
|
|
247
|
+
});
|
|
248
|
+
return res.note;
|
|
249
|
+
},
|
|
250
|
+
onSuccess: (data) => {
|
|
251
|
+
queryClient.invalidateQueries({ queryKey: noteKeys.all });
|
|
252
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
253
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(data.project_id) });
|
|
254
|
+
},
|
|
255
|
+
onError: (error) => {
|
|
256
|
+
showApiErrorNotification(error);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/hooks/delivery/useProjects.ts
|
|
262
|
+
var projectKeys = {
|
|
263
|
+
all: ["projects"],
|
|
264
|
+
lists: () => [...projectKeys.all, "list"],
|
|
265
|
+
list: (orgId, filters) => [...projectKeys.all, "list", orgId, filters],
|
|
266
|
+
details: () => [...projectKeys.all, "detail"],
|
|
267
|
+
detail: (id) => [...projectKeys.all, "detail", id],
|
|
268
|
+
milestones: (id) => [...projectKeys.all, id, "milestones"],
|
|
269
|
+
tasks: (id) => [...projectKeys.all, id, "tasks"]
|
|
270
|
+
};
|
|
271
|
+
function useProjects(filters = {}) {
|
|
272
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
273
|
+
return useQuery({
|
|
274
|
+
queryKey: projectKeys.list(workOSOrganizationId, filters),
|
|
275
|
+
queryFn: async () => {
|
|
276
|
+
const params = new URLSearchParams();
|
|
277
|
+
if (filters.kind) params.set("kind", filters.kind);
|
|
278
|
+
const qs = params.toString();
|
|
279
|
+
const path = qs ? `/projects?${qs}` : "/projects";
|
|
280
|
+
const res = await apiRequest(path);
|
|
281
|
+
return res.projects;
|
|
282
|
+
},
|
|
283
|
+
enabled: isReady
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function useProject(id) {
|
|
287
|
+
const { apiRequest, isReady, workOSOrganizationId } = useElevasisServices();
|
|
288
|
+
return useQuery({
|
|
289
|
+
queryKey: [...projectKeys.detail(id), workOSOrganizationId],
|
|
290
|
+
queryFn: async () => {
|
|
291
|
+
try {
|
|
292
|
+
const res = await apiRequest(`/projects/${id}`);
|
|
293
|
+
return res.project;
|
|
294
|
+
} catch (err) {
|
|
295
|
+
if (err && typeof err === "object" && "statusCode" in err && err.statusCode === 404) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
throw err;
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
enabled: isReady && !!id
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function useProjectMilestones(projectId) {
|
|
305
|
+
const { apiRequest, isReady } = useElevasisServices();
|
|
306
|
+
return useQuery({
|
|
307
|
+
queryKey: projectKeys.milestones(projectId),
|
|
308
|
+
queryFn: async () => {
|
|
309
|
+
const res = await apiRequest(`/projects/${projectId}/milestones`);
|
|
310
|
+
return res.milestones;
|
|
311
|
+
},
|
|
312
|
+
enabled: isReady && !!projectId
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function useProjectTasks(projectId) {
|
|
316
|
+
const { apiRequest, isReady } = useElevasisServices();
|
|
317
|
+
return useQuery({
|
|
318
|
+
queryKey: projectKeys.tasks(projectId),
|
|
319
|
+
queryFn: async () => {
|
|
320
|
+
const res = await apiRequest(`/projects/${projectId}/tasks`);
|
|
321
|
+
return res.tasks;
|
|
322
|
+
},
|
|
323
|
+
enabled: isReady && !!projectId
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
function useCreateProject() {
|
|
327
|
+
const { apiRequest } = useElevasisServices();
|
|
328
|
+
const queryClient = useQueryClient();
|
|
329
|
+
return useMutation({
|
|
330
|
+
mutationFn: async (params) => {
|
|
331
|
+
const res = await apiRequest("/projects", {
|
|
332
|
+
method: "POST",
|
|
333
|
+
body: JSON.stringify(params)
|
|
334
|
+
});
|
|
335
|
+
return res.project;
|
|
336
|
+
},
|
|
337
|
+
onSuccess: () => {
|
|
338
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
339
|
+
},
|
|
340
|
+
onError: (error) => {
|
|
341
|
+
showApiErrorNotification(error);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
function useUpdateProject() {
|
|
346
|
+
const { apiRequest } = useElevasisServices();
|
|
347
|
+
const queryClient = useQueryClient();
|
|
348
|
+
return useMutation({
|
|
349
|
+
mutationFn: async (params) => {
|
|
350
|
+
const res = await apiRequest(`/projects/${params.id}`, {
|
|
351
|
+
method: "PATCH",
|
|
352
|
+
body: JSON.stringify(params.updates)
|
|
353
|
+
});
|
|
354
|
+
return res.project;
|
|
355
|
+
},
|
|
356
|
+
onSuccess: (data) => {
|
|
357
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
358
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.detail(data.id) });
|
|
359
|
+
},
|
|
360
|
+
onError: (error) => {
|
|
361
|
+
showApiErrorNotification(error);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
function useDeleteProject() {
|
|
366
|
+
const { apiRequest } = useElevasisServices();
|
|
367
|
+
const queryClient = useQueryClient();
|
|
368
|
+
return useMutation({
|
|
369
|
+
mutationFn: async (id) => {
|
|
370
|
+
await apiRequest(`/projects/${id}`, {
|
|
371
|
+
method: "DELETE"
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
onSuccess: () => {
|
|
375
|
+
queryClient.invalidateQueries({ queryKey: projectKeys.all });
|
|
376
|
+
},
|
|
377
|
+
onError: (error) => {
|
|
378
|
+
showApiErrorNotification(error);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export { milestoneKeys, noteKeys, projectKeys, showApiErrorNotification, showErrorNotification, showInfoNotification, showSuccessNotification, showWarningNotification, taskKeys, useCreateMilestone, useCreateNote, useCreateProject, useCreateTask, useDeleteMilestone, useDeleteProject, useDeleteTask, useMilestones, useProject, useProjectMilestones, useProjectNotes, useProjectTasks, useProjects, useTasks, useUpdateMilestone, useUpdateProject, useUpdateTask };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/features/delivery/_shared.ts
|
|
2
|
+
var projectStatusColors = {
|
|
3
|
+
active: "blue",
|
|
4
|
+
on_track: "green",
|
|
5
|
+
at_risk: "yellow",
|
|
6
|
+
blocked: "red",
|
|
7
|
+
completed: "teal",
|
|
8
|
+
paused: "gray"
|
|
9
|
+
};
|
|
10
|
+
var milestoneStatusColors = {
|
|
11
|
+
upcoming: "gray",
|
|
12
|
+
in_progress: "blue",
|
|
13
|
+
completed: "green",
|
|
14
|
+
overdue: "red",
|
|
15
|
+
blocked: "orange"
|
|
16
|
+
};
|
|
17
|
+
var taskStatusColors = {
|
|
18
|
+
pending: "gray",
|
|
19
|
+
planned: "gray",
|
|
20
|
+
in_progress: "blue",
|
|
21
|
+
blocked: "red",
|
|
22
|
+
completed: "green",
|
|
23
|
+
cancelled: "gray",
|
|
24
|
+
submitted: "yellow",
|
|
25
|
+
approved: "green",
|
|
26
|
+
rejected: "red",
|
|
27
|
+
revision_requested: "orange"
|
|
28
|
+
};
|
|
29
|
+
var taskTypeColors = {
|
|
30
|
+
documentation: "blue",
|
|
31
|
+
code: "violet",
|
|
32
|
+
report: "cyan",
|
|
33
|
+
design: "pink",
|
|
34
|
+
other: "gray"
|
|
35
|
+
};
|
|
36
|
+
var noteTypeColors = {
|
|
37
|
+
call_note: "blue",
|
|
38
|
+
status_update: "green",
|
|
39
|
+
issue: "yellow",
|
|
40
|
+
blocker: "red",
|
|
41
|
+
agent_learning: "grape"
|
|
42
|
+
};
|
|
43
|
+
function formatStatusLabel(status) {
|
|
44
|
+
return status.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
45
|
+
}
|
|
46
|
+
function calculateProgress(completed, total) {
|
|
47
|
+
if (total === 0) return 0;
|
|
48
|
+
return Math.round(completed / total * 100);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { calculateProgress, formatStatusLabel, milestoneStatusColors, noteTypeColors, projectStatusColors, taskStatusColors, taskTypeColors };
|