tsondb 0.7.7 → 0.7.8
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/src/node/server/api/git.js +156 -24
- package/dist/src/node/server/index.js +4 -0
- package/dist/src/node/utils/instanceOperations.d.ts +1 -1
- package/dist/src/node/utils/instanceOperations.js +2 -2
- package/dist/src/shared/api.d.ts +17 -1
- package/dist/src/shared/utils/git.d.ts +4 -0
- package/dist/src/shared/utils/git.js +6 -1
- package/dist/src/shared/utils/markdown.d.ts +36 -17
- package/dist/src/shared/utils/markdown.js +79 -23
- package/dist/src/shared/utils/object.d.ts +1 -0
- package/dist/src/shared/utils/object.js +1 -0
- package/dist/src/web/api/git.d.ts +5 -1
- package/dist/src/web/api/git.js +6 -2
- package/dist/src/web/components/ContextProviderWrapper.d.ts +7 -0
- package/dist/src/web/components/ContextProviderWrapper.js +5 -0
- package/dist/src/web/components/InstanceRouteSkeleton.d.ts +1 -0
- package/dist/src/web/components/InstanceRouteSkeleton.js +8 -4
- package/dist/src/web/components/LoadingOverlay.d.ts +1 -0
- package/dist/src/web/components/LoadingOverlay.js +3 -0
- package/dist/src/web/components/ModalDialog.js +4 -3
- package/dist/src/web/components/git/Git.js +47 -0
- package/dist/src/web/components/git/GitBranchManager.d.ts +7 -0
- package/dist/src/web/components/git/GitBranchManager.js +17 -0
- package/dist/src/web/components/git/GitFileList.d.ts +17 -0
- package/dist/src/web/components/git/GitFileList.js +11 -0
- package/dist/src/web/components/git/GitFileManager.d.ts +8 -0
- package/dist/src/web/components/git/GitFileManager.js +34 -0
- package/dist/src/web/components/git/GitStatusIndicator.d.ts +7 -0
- package/dist/src/web/components/git/GitStatusIndicator.js +6 -0
- package/dist/src/web/components/typeInputs/StringTypeInput.js +1 -1
- package/dist/src/web/context/entities.d.ts +6 -5
- package/dist/src/web/context/git.d.ts +2 -1
- package/dist/src/web/context/gitClient.d.ts +2 -0
- package/dist/src/web/context/gitClient.js +2 -0
- package/dist/src/web/hooks/useGitClient.d.ts +37 -0
- package/dist/src/web/hooks/useGitClient.js +313 -0
- package/dist/src/web/index.js +6 -2
- package/dist/src/web/routes/CreateInstance.js +2 -1
- package/dist/src/web/routes/Entity.js +10 -4
- package/dist/src/web/routes/Instance.js +2 -1
- package/dist/src/web/signals/loading.d.ts +2 -0
- package/dist/src/web/signals/loading.js +11 -0
- package/dist/src/web/utils/BlockMarkdown.js +1 -1
- package/dist/src/web/utils/debug.d.ts +1 -0
- package/dist/src/web/utils/debug.js +4 -0
- package/package.json +3 -3
- package/public/css/styles.css +132 -70
- package/dist/src/web/components/Git.js +0 -164
- /package/dist/src/web/components/{Git.d.ts → git/Git.d.ts} +0 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { useCallback, useContext, useEffect, useMemo, useState } from "preact/hooks";
|
|
2
|
+
import { isSerializedEntityDecl, isSerializedEntityDeclWithParentReference, } from "../../shared/schema/declarations/EntityDecl.js";
|
|
3
|
+
import { isChangedInIndex, isChangedInWorkingDir, splitBranchName, } from "../../shared/utils/git.js";
|
|
4
|
+
import { deleteInstanceByEntityNameAndId } from "../api/declarations.js";
|
|
5
|
+
import * as GitApi from "../api/git.js";
|
|
6
|
+
import { EntitiesContext } from "../context/entities.js";
|
|
7
|
+
import { runWithLoading } from "../signals/loading.js";
|
|
8
|
+
import { logAndAlertError } from "../utils/debug.js";
|
|
9
|
+
import { useSetting } from "./useSettings.js";
|
|
10
|
+
const filterFilesForDisplay = (predicate, entities, data) => Object.entries(data.instances)
|
|
11
|
+
.map(([entityName, instances]) => [
|
|
12
|
+
entityName,
|
|
13
|
+
entities.find(entity => entity.declaration.name === entityName)?.declaration.namePlural ??
|
|
14
|
+
entityName,
|
|
15
|
+
instances
|
|
16
|
+
.filter(instance => instance.gitStatus !== undefined && predicate(instance.gitStatus))
|
|
17
|
+
.sort((a, b) => a.displayName.localeCompare(b.displayName, undefined, { numeric: true })),
|
|
18
|
+
])
|
|
19
|
+
.filter(([_1, _2, instances]) => instances.length > 0)
|
|
20
|
+
.sort((a, b) => a[1].localeCompare(b[1]));
|
|
21
|
+
export const useGitClient = () => {
|
|
22
|
+
const [locales] = useSetting("displayedLocales");
|
|
23
|
+
const { entities } = useContext(EntitiesContext);
|
|
24
|
+
const [isRepo, setIsRepo] = useState(false);
|
|
25
|
+
const [commitsAhead, setCommitsAhead] = useState(0);
|
|
26
|
+
const [commitsBehind, setCommitsBehind] = useState(0);
|
|
27
|
+
const [indexFiles, setIndexFiles] = useState([]);
|
|
28
|
+
const [workingTreeFiles, setWorkingTreeFiles] = useState([]);
|
|
29
|
+
const [allBranches, setAllBranches] = useState([]);
|
|
30
|
+
const [currentBranch, setCurrentBranch] = useState("");
|
|
31
|
+
const [branches, setBranches] = useState({});
|
|
32
|
+
const [isDetached, setIsDetached] = useState(false);
|
|
33
|
+
const updateGitStatus = useCallback(async () => {
|
|
34
|
+
const { isRepo } = await GitApi.isRepo(locales);
|
|
35
|
+
setIsRepo(isRepo);
|
|
36
|
+
if (isRepo && entities.length > 0) {
|
|
37
|
+
try {
|
|
38
|
+
const [statusData, branchesData] = await Promise.all([
|
|
39
|
+
GitApi.getStatus(locales),
|
|
40
|
+
GitApi.getBranches(locales),
|
|
41
|
+
]);
|
|
42
|
+
setIndexFiles(filterFilesForDisplay(isChangedInIndex, entities, statusData));
|
|
43
|
+
setWorkingTreeFiles(filterFilesForDisplay(isChangedInWorkingDir, entities, statusData));
|
|
44
|
+
setCommitsAhead(statusData.commitsAhead);
|
|
45
|
+
setCommitsBehind(statusData.commitsBehind);
|
|
46
|
+
setAllBranches(branchesData.allBranches);
|
|
47
|
+
setCurrentBranch(branchesData.currentBranch);
|
|
48
|
+
setBranches(Object.fromEntries(Object.entries(branchesData.branches).map(([branch, branchSummary]) => {
|
|
49
|
+
const { remote, name } = splitBranchName(branch);
|
|
50
|
+
return [
|
|
51
|
+
branch,
|
|
52
|
+
{
|
|
53
|
+
...branchSummary,
|
|
54
|
+
remote,
|
|
55
|
+
name,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
})));
|
|
59
|
+
setIsDetached(branchesData.isDetached);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
logAndAlertError(error, "Error updating git status: ");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, [entities, locales]);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
void updateGitStatus();
|
|
68
|
+
}, [updateGitStatus]);
|
|
69
|
+
const getGitStatusOfInstance = useCallback((entityName, instanceId) => {
|
|
70
|
+
const entity = indexFiles.find(([name]) => name === entityName);
|
|
71
|
+
const instanceInIndex = entity?.[2].find(instance => instance.id === instanceId);
|
|
72
|
+
if (instanceInIndex?.gitStatus !== undefined) {
|
|
73
|
+
return instanceInIndex.gitStatus;
|
|
74
|
+
}
|
|
75
|
+
const workingTreeEntity = workingTreeFiles.find(([name]) => name === entityName);
|
|
76
|
+
const instanceInWorkingTree = workingTreeEntity?.[2].find(instance => instance.id === instanceId);
|
|
77
|
+
return instanceInWorkingTree?.gitStatus;
|
|
78
|
+
}, [indexFiles, workingTreeFiles]);
|
|
79
|
+
const fetch = useCallback(async () => {
|
|
80
|
+
await runWithLoading(async () => {
|
|
81
|
+
try {
|
|
82
|
+
await GitApi.fetch(locales);
|
|
83
|
+
await updateGitStatus();
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logAndAlertError(error, "Error fetching from remote: ");
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}, [locales, updateGitStatus]);
|
|
90
|
+
const stage = useCallback(async (entityName, instance) => {
|
|
91
|
+
await runWithLoading(async () => {
|
|
92
|
+
try {
|
|
93
|
+
await GitApi.stageFileOfEntity(locales, entityName, instance.id);
|
|
94
|
+
await updateGitStatus();
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
logAndAlertError(error, "Error staging instance: ");
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}, [locales, updateGitStatus]);
|
|
101
|
+
const stageAll = useCallback(async (entityName) => {
|
|
102
|
+
await runWithLoading(async () => {
|
|
103
|
+
try {
|
|
104
|
+
if (entityName) {
|
|
105
|
+
await GitApi.stageAllFilesOfEntity(locales, entityName);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
await GitApi.stageAllFiles(locales);
|
|
109
|
+
}
|
|
110
|
+
await updateGitStatus();
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
logAndAlertError(error, "Error staging all instances: ");
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}, [locales, updateGitStatus]);
|
|
117
|
+
const unstage = useCallback(async (entityName, instance) => {
|
|
118
|
+
await runWithLoading(async () => {
|
|
119
|
+
try {
|
|
120
|
+
await GitApi.unstageFileOfEntity(locales, entityName, instance.id);
|
|
121
|
+
await updateGitStatus();
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
logAndAlertError(error, "Error unstaging instance: ");
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}, [locales, updateGitStatus]);
|
|
128
|
+
const unstageAll = useCallback(async (entityName) => {
|
|
129
|
+
await runWithLoading(async () => {
|
|
130
|
+
try {
|
|
131
|
+
if (entityName) {
|
|
132
|
+
await GitApi.unstageAllFilesOfEntity(locales, entityName);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
await GitApi.unstageAllFiles(locales);
|
|
136
|
+
}
|
|
137
|
+
await updateGitStatus();
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
logAndAlertError(error, "Error unstaging all instances: ");
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}, [locales, updateGitStatus]);
|
|
144
|
+
const reset = useCallback(async (entityName, instance) => {
|
|
145
|
+
await runWithLoading(async () => {
|
|
146
|
+
if (!confirm(`Are you sure you want to reset instance "${instance.displayName}" (${instance.id})?`)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const entity = entities.find(e => e.declaration.name === entityName)?.declaration;
|
|
150
|
+
if (instance.gitStatus?.workingDir === "D" &&
|
|
151
|
+
entity &&
|
|
152
|
+
isSerializedEntityDecl(entity) &&
|
|
153
|
+
isSerializedEntityDeclWithParentReference(entity) &&
|
|
154
|
+
!confirm(`If you deleted the parent of "${instance.displayName}" (${instance.id}) before, make sure to restore it as well. Continue?`)) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
if (instance.gitStatus?.workingDir === "?") {
|
|
159
|
+
await deleteInstanceByEntityNameAndId(locales, entityName, instance.id);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
await GitApi.resetFileOfEntity(locales, entityName, instance.id);
|
|
163
|
+
}
|
|
164
|
+
await updateGitStatus();
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
logAndAlertError(error, "Error resetting instance: ");
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}, [entities, locales, updateGitStatus]);
|
|
171
|
+
const commit = useCallback(async (commitMessage) => {
|
|
172
|
+
await runWithLoading(async () => {
|
|
173
|
+
if (commitMessage.length > 0 &&
|
|
174
|
+
indexFiles.length > 0 &&
|
|
175
|
+
confirm("Do you want to commit all staged files?")) {
|
|
176
|
+
try {
|
|
177
|
+
await GitApi.commitStagedFiles(locales, commitMessage);
|
|
178
|
+
await updateGitStatus();
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
logAndAlertError(error, "Error committing instances: ");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}, [indexFiles.length, locales, updateGitStatus]);
|
|
186
|
+
const push = useCallback(async () => {
|
|
187
|
+
await runWithLoading(async () => {
|
|
188
|
+
try {
|
|
189
|
+
await GitApi.pushCommits(locales);
|
|
190
|
+
alert("Pushed commits successfully");
|
|
191
|
+
await updateGitStatus();
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
logAndAlertError(error, "Error pushing commits: ");
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}, [locales, updateGitStatus]);
|
|
198
|
+
const pull = useCallback(async () => {
|
|
199
|
+
await runWithLoading(async () => {
|
|
200
|
+
try {
|
|
201
|
+
await GitApi.pullCommits(locales);
|
|
202
|
+
alert("Pulled commits successfully");
|
|
203
|
+
await updateGitStatus();
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
logAndAlertError(error, "Error pulling commits: ");
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}, [locales, updateGitStatus]);
|
|
210
|
+
const createBranch = useCallback(async (newBranchName) => {
|
|
211
|
+
await runWithLoading(async () => {
|
|
212
|
+
if (newBranchName.length === 0) {
|
|
213
|
+
alert("Branch name cannot be empty");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (allBranches.includes(newBranchName)) {
|
|
217
|
+
alert("Branch name already exists");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
await GitApi.createBranch(locales, newBranchName);
|
|
222
|
+
alert(`Created branch "${newBranchName}" successfully`);
|
|
223
|
+
await updateGitStatus();
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
logAndAlertError(error, "Error creating branch: ");
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}, [allBranches, locales, updateGitStatus]);
|
|
230
|
+
const switchBranch = useCallback(async (targetBranch) => {
|
|
231
|
+
await runWithLoading(async () => {
|
|
232
|
+
try {
|
|
233
|
+
await GitApi.switchBranch(locales, targetBranch);
|
|
234
|
+
await updateGitStatus();
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
logAndAlertError(error, "Error switching branch: ");
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}, [locales, updateGitStatus]);
|
|
241
|
+
const deleteBranch = useCallback(async (targetBranch) => {
|
|
242
|
+
await runWithLoading(async () => {
|
|
243
|
+
if (targetBranch === currentBranch) {
|
|
244
|
+
alert("Cannot delete the current branch");
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!allBranches.includes(targetBranch)) {
|
|
248
|
+
alert(`Branch "${targetBranch}" does not exist`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (!confirm(`Are you sure you want to delete branch "${targetBranch}"?`)) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
await GitApi.deleteBranch(locales, targetBranch);
|
|
256
|
+
alert(`Deleted branch "${targetBranch}" successfully`);
|
|
257
|
+
await updateGitStatus();
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
logAndAlertError(error, "Error deleting branch: ");
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}, [allBranches, currentBranch, locales, updateGitStatus]);
|
|
264
|
+
return useMemo(() => ({
|
|
265
|
+
isRepo,
|
|
266
|
+
commitsAhead,
|
|
267
|
+
commitsBehind,
|
|
268
|
+
indexFiles,
|
|
269
|
+
workingTreeFiles,
|
|
270
|
+
allBranches,
|
|
271
|
+
currentBranch,
|
|
272
|
+
branches,
|
|
273
|
+
isDetached,
|
|
274
|
+
getGitStatusOfInstance,
|
|
275
|
+
updateLocalState: updateGitStatus,
|
|
276
|
+
fetch,
|
|
277
|
+
stage,
|
|
278
|
+
stageAll,
|
|
279
|
+
unstage,
|
|
280
|
+
unstageAll,
|
|
281
|
+
reset,
|
|
282
|
+
commit,
|
|
283
|
+
push,
|
|
284
|
+
pull,
|
|
285
|
+
createBranch,
|
|
286
|
+
switchBranch,
|
|
287
|
+
deleteBranch,
|
|
288
|
+
}), [
|
|
289
|
+
allBranches,
|
|
290
|
+
branches,
|
|
291
|
+
commit,
|
|
292
|
+
commitsAhead,
|
|
293
|
+
commitsBehind,
|
|
294
|
+
createBranch,
|
|
295
|
+
currentBranch,
|
|
296
|
+
deleteBranch,
|
|
297
|
+
fetch,
|
|
298
|
+
getGitStatusOfInstance,
|
|
299
|
+
indexFiles,
|
|
300
|
+
isDetached,
|
|
301
|
+
isRepo,
|
|
302
|
+
pull,
|
|
303
|
+
push,
|
|
304
|
+
reset,
|
|
305
|
+
stage,
|
|
306
|
+
stageAll,
|
|
307
|
+
switchBranch,
|
|
308
|
+
unstage,
|
|
309
|
+
unstageAll,
|
|
310
|
+
updateGitStatus,
|
|
311
|
+
workingTreeFiles,
|
|
312
|
+
]);
|
|
313
|
+
};
|
package/dist/src/web/index.js
CHANGED
|
@@ -4,11 +4,15 @@ import { LocationProvider, Route, Router, useLocation } from "preact-iso";
|
|
|
4
4
|
import { useEffect, useState } from "preact/hooks";
|
|
5
5
|
import { getAllEntities } from "./api/declarations.js";
|
|
6
6
|
import { getWebConfig } from "./api/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { ContextProviderWrapper } from "./components/ContextProviderWrapper.js";
|
|
8
|
+
import { Git } from "./components/git/Git.js";
|
|
9
|
+
import { LoadingOverlay } from "./components/LoadingOverlay.js";
|
|
8
10
|
import { ConfigContext } from "./context/config.js";
|
|
9
11
|
import { EntitiesContext } from "./context/entities.js";
|
|
10
12
|
import { GitContext } from "./context/git.js";
|
|
13
|
+
import { GitClientContext } from "./context/gitClient.js";
|
|
11
14
|
import { SettingsContext } from "./context/settings.js";
|
|
15
|
+
import { useGitClient } from "./hooks/useGitClient.js";
|
|
12
16
|
import { useMappedAPIResource } from "./hooks/useMappedAPIResource.js";
|
|
13
17
|
import { useSettings } from "./hooks/useSettings.js";
|
|
14
18
|
import { CreateInstance } from "./routes/CreateInstance.js";
|
|
@@ -29,7 +33,7 @@ const App = ({ config }) => {
|
|
|
29
33
|
alert("Error reloading entities: " + String(error));
|
|
30
34
|
});
|
|
31
35
|
}, [location.path, reloadEntities]);
|
|
32
|
-
return (_jsx(ConfigContext.Provider, { value: config, children: _jsx(SettingsContext.Provider, { value: settingsContext, children: _jsx(GitContext.Provider, { value: [isGitOpen, setIsGitOpen], children: _jsx(LocationProvider, { children:
|
|
36
|
+
return (_jsx(ConfigContext.Provider, { value: config, children: _jsx(SettingsContext.Provider, { value: settingsContext, children: _jsx(GitContext.Provider, { value: [isGitOpen, setIsGitOpen], children: _jsx(LocationProvider, { children: _jsx(EntitiesContext.Provider, { value: { entities: entities ?? [], reloadEntities }, children: _jsxs(ContextProviderWrapper, { context: GitClientContext, useValue: useGitClient, children: [_jsx(LoadingOverlay, {}), _jsxs(Router, { children: [_jsx(Route, { path: "/", component: Home }), _jsx(Route, { path: "/entities/:name", component: Entity }), _jsx(Route, { path: "/entities/:name/instances/create", component: CreateInstance }), _jsx(Route, { path: "/entities/:name/instances/:id", component: Instance }), _jsx(Route, { default: true, component: NotFound })] }), _jsx(Git, {})] }) }) }) }) }) }));
|
|
33
37
|
};
|
|
34
38
|
const config = await getWebConfig();
|
|
35
39
|
const root = document.getElementById("app");
|
|
@@ -11,7 +11,7 @@ const titleBuilder = ({ entity }) => {
|
|
|
11
11
|
const entityName = entity.name;
|
|
12
12
|
return "New " + toTitleCase(entityName) + " — TSONDB";
|
|
13
13
|
};
|
|
14
|
-
const onSubmit = async ({ locales, entity, buttonName, instanceContent, isLocaleEntity, customId, childInstances, setInstanceContent, setCustomId, route, getDeclFromDeclName, }) => {
|
|
14
|
+
const onSubmit = async ({ locales, entity, buttonName, instanceContent, isLocaleEntity, customId, childInstances, setInstanceContent, setCustomId, route, getDeclFromDeclName, updateLocalGitState, }) => {
|
|
15
15
|
try {
|
|
16
16
|
if (buttonName) {
|
|
17
17
|
const createdInstance = await createInstanceByEntityNameAndId(locales, entity.name, {
|
|
@@ -20,6 +20,7 @@ const onSubmit = async ({ locales, entity, buttonName, instanceContent, isLocale
|
|
|
20
20
|
content: instanceContent,
|
|
21
21
|
id: undefined,
|
|
22
22
|
}, isLocaleEntity ? customId : undefined);
|
|
23
|
+
await updateLocalGitState?.();
|
|
23
24
|
switch (buttonName) {
|
|
24
25
|
case "saveandcontinue": {
|
|
25
26
|
route(`/entities/${entity.name}/instances/${createdInstance.instance.id}`);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { useRoute } from "preact-iso";
|
|
3
3
|
import { useContext, useEffect, useState } from "preact/hooks";
|
|
4
|
-
import { getGitStatusForDisplay
|
|
4
|
+
import { getGitStatusForDisplay } from "../../shared/utils/git.js";
|
|
5
5
|
import { toTitleCase } from "../../shared/utils/string.js";
|
|
6
6
|
import { deleteInstanceByEntityNameAndId, getInstancesByEntityName, getLocaleInstances, } from "../api/declarations.js";
|
|
7
|
+
import { GitStatusIndicator } from "../components/git/GitStatusIndicator.js";
|
|
7
8
|
import { Layout } from "../components/Layout.js";
|
|
8
9
|
import { ConfigContext } from "../context/config.js";
|
|
9
10
|
import { EntitiesContext } from "../context/entities.js";
|
|
11
|
+
import { GitClientContext } from "../context/gitClient.js";
|
|
10
12
|
import { useEntityFromRoute } from "../hooks/useEntityFromRoute.js";
|
|
11
13
|
import { useMappedAPIResource } from "../hooks/useMappedAPIResource.js";
|
|
12
14
|
import { useSetting } from "../hooks/useSettings.js";
|
|
@@ -21,6 +23,7 @@ export const Entity = () => {
|
|
|
21
23
|
const [searchText, setSearchText] = useState("");
|
|
22
24
|
const entityFromRoute = useEntityFromRoute();
|
|
23
25
|
const config = useContext(ConfigContext);
|
|
26
|
+
const gitClient = useContext(GitClientContext);
|
|
24
27
|
const { reloadEntities } = useContext(EntitiesContext);
|
|
25
28
|
const { declaration: entity, isLocaleEntity } = entityFromRoute ?? {};
|
|
26
29
|
const [instances, reloadInstances] = useMappedAPIResource(getInstancesByEntityName, mapInstances, locales, name ?? "");
|
|
@@ -43,10 +46,13 @@ export const Entity = () => {
|
|
|
43
46
|
return (_jsxs(Layout, { breadcrumbs: [{ url: "/", label: homeTitle }], children: [_jsxs("div", { class: "header-with-btns", children: [_jsx("h1", { children: toTitleCase(entity?.namePlural ?? name) }), _jsx("a", { class: "btn btn--primary", "aria-disabled": true, children: "Add" })] }), _jsx("p", { class: "loading", children: "Loading \u2026" })] }));
|
|
44
47
|
}
|
|
45
48
|
const lowerSearchText = searchText.toLowerCase();
|
|
46
|
-
const filteredInstances = searchText.length === 0
|
|
49
|
+
const filteredInstances = (searchText.length === 0
|
|
47
50
|
? instances
|
|
48
51
|
: instances.filter(instance => instance.id.includes(searchText) ||
|
|
49
|
-
instance.displayName.toLowerCase().includes(lowerSearchText))
|
|
52
|
+
instance.displayName.toLowerCase().includes(lowerSearchText))).map(instance => ({
|
|
53
|
+
...instance,
|
|
54
|
+
gitStatus: gitClient?.getGitStatusOfInstance(entity.name, instance.id),
|
|
55
|
+
}));
|
|
50
56
|
const instancesByLocale = Object.groupBy(filteredInstances, instance => instance.displayNameLocaleId ?? "undefined");
|
|
51
57
|
const groupedInstances = [...locales, "undefined"]
|
|
52
58
|
.map(key => ({
|
|
@@ -59,7 +65,7 @@ export const Entity = () => {
|
|
|
59
65
|
.filter(group => group.instances.length > 0);
|
|
60
66
|
const instanceMapper = (instance) => {
|
|
61
67
|
const gitStatusForDisplay = getGitStatusForDisplay(instance.gitStatus);
|
|
62
|
-
return (_jsxs("li", { id: `instance-${instance.id}`, class: `entries-item ${created === instance.id ? "entries-item--created" : ""} ${gitStatusForDisplay === undefined ? "" : `git-status--${gitStatusForDisplay}`}`, children: [_jsx("h2", { class: "entries-item__title", children: instance.displayName }), _jsx("p", { "aria-hidden": true, class: "entries-item__subtitle entries-item__subtitle--id", children: instance.id }), _jsxs("div", { class: "entries-item__side", children: [
|
|
68
|
+
return (_jsxs("li", { id: `instance-${instance.id}`, class: `entries-item ${created === instance.id ? "entries-item--created" : ""} ${gitStatusForDisplay === undefined ? "" : `git-status--${gitStatusForDisplay}`}`, children: [_jsx("h2", { class: "entries-item__title", children: instance.displayName }), _jsx("p", { "aria-hidden": true, class: "entries-item__subtitle entries-item__subtitle--id", children: instance.id }), _jsxs("div", { class: "entries-item__side", children: [_jsx(GitStatusIndicator, { status: instance.gitStatus }), _jsxs("div", { class: "btns", children: [_jsx("a", { href: `/entities/${entity.name}/instances/${instance.id}`, class: "btn", children: "Edit" }), _jsx("button", { class: "destructive", onClick: () => {
|
|
63
69
|
if (confirm("Are you sure you want to delete this instance?")) {
|
|
64
70
|
deleteInstanceByEntityNameAndId(locales, entity.name, instance.id)
|
|
65
71
|
.then(() => reloadInstances())
|
|
@@ -21,7 +21,7 @@ const titleBuilder = ({ locales, entity, instanceId, instanceContent, }) => {
|
|
|
21
21
|
}
|
|
22
22
|
return undefined;
|
|
23
23
|
};
|
|
24
|
-
const onSubmit = async ({ locales, entity, instanceId, instanceContent, buttonName, childInstances, route, }) => {
|
|
24
|
+
const onSubmit = async ({ locales, entity, instanceId, instanceContent, buttonName, childInstances, route, updateLocalGitState, }) => {
|
|
25
25
|
try {
|
|
26
26
|
if (instanceId && buttonName) {
|
|
27
27
|
await updateInstanceByEntityNameAndId(locales, entity.name, instanceId, {
|
|
@@ -30,6 +30,7 @@ const onSubmit = async ({ locales, entity, instanceId, instanceContent, buttonNa
|
|
|
30
30
|
content: instanceContent,
|
|
31
31
|
id: instanceId,
|
|
32
32
|
});
|
|
33
|
+
await updateLocalGitState?.();
|
|
33
34
|
switch (buttonName) {
|
|
34
35
|
case "saveandcontinue": {
|
|
35
36
|
break;
|
|
@@ -15,7 +15,7 @@ export const BlockMarkdown = ({ node, outerHeadingLevel = 0 }) => {
|
|
|
15
15
|
return (_jsx("ul", { children: node.content.map((item, ii) => (_jsx("li", { children: item.content.map((inline, iii) => (_jsx(InlineMarkdown, { node: inline }, iii))) }, ii))) }));
|
|
16
16
|
}
|
|
17
17
|
case "table":
|
|
18
|
-
return (_jsxs("table", { children: [_jsx("thead", { children: _jsx("tr", { children: node.header.map((th, hi) => (_jsx("th", { children: th.map((inline, hii) => (_jsx(InlineMarkdown, { node: inline }, hii))) }, hi))) }) }), _jsx("tbody", { children: node.rows.map((tr, ri) => (_jsx("tr", { children: tr.map((tc, ci) => (_jsx("td", { children: tc.map((inline, cii) => (_jsx(InlineMarkdown, { node: inline }, cii))) }, ci))) }, ri))) })] }));
|
|
18
|
+
return (_jsxs("table", { children: [node.caption !== undefined && (_jsx("caption", { children: node.caption.map((inline, ci) => (_jsx(InlineMarkdown, { node: inline }, ci))) })), _jsx("thead", { children: _jsx("tr", { children: node.header.map((th, hi) => (_jsx("th", { children: th.map((inline, hii) => (_jsx(InlineMarkdown, { node: inline }, hii))) }, hi))) }) }), _jsx("tbody", { children: node.rows.map((tr, ri) => (_jsx("tr", { children: tr.map((tc, ci) => (_jsx("td", { children: tc.map((inline, cii) => (_jsx(InlineMarkdown, { node: inline }, cii))) }, ci))) }, ri))) })] }));
|
|
19
19
|
default:
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
@@ -3,3 +3,7 @@ export const printJson = (data) => JSON.stringify(data, undefined, 2)
|
|
|
3
3
|
.replace(/((?:^|\n *)[{[])\n +/g, "$1 ")
|
|
4
4
|
.replace(/"(.+?)":/g, '<span style="color: darkorange">$1</span>:')
|
|
5
5
|
.replace(/ "(.*?)"([ ,])/g, ' <span style="color: darkgreen">"$1"</span>$2');
|
|
6
|
+
export const logAndAlertError = (error, prependedMessage) => {
|
|
7
|
+
console.error(error);
|
|
8
|
+
alert((prependedMessage ?? "") + (error instanceof Error ? error.toString() : String(error)));
|
|
9
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsondb",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "Lukas Obermann",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"typescript-eslint": "^8.45.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
+
"@preact/signals": "^2.3.2",
|
|
50
51
|
"debug": "^4.4.3",
|
|
51
52
|
"express": "^5.1.0",
|
|
52
53
|
"preact": "^10.27.2",
|
|
53
54
|
"preact-iso": "^2.11.0",
|
|
54
55
|
"simple-cli-args": "^0.1.3",
|
|
55
|
-
"simple-git": "^3.28.0"
|
|
56
|
-
"uuid": "^13.0.0"
|
|
56
|
+
"simple-git": "^3.28.0"
|
|
57
57
|
},
|
|
58
58
|
"repository": "github:elyukai/tsondb",
|
|
59
59
|
"bugs": {
|