@hrbolek/uoisfrontend-template 0.6.1 → 0.6.3
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/cjs/index.js +447 -0
- package/dist/es/index.js +11062 -0
- package/dist/umd/index.js +447 -0
- package/package.json +5 -1
- package/src/Base/Components/Link.jsx +13 -8
- package/src/Base/Mutations/General.jsx +3 -1
- package/src/Base/Mutations/Update.jsx +5 -0
- package/src/EventGQLModel/Components/A4Plan/A4Plan.jsx +363 -0
- package/src/EventGQLModel/Components/A4Plan/index.js +1 -0
- package/src/EventGQLModel/Components/CardCapsule.jsx +43 -0
- package/src/EventGQLModel/Components/Children.jsx +31 -0
- package/src/EventGQLModel/Components/ConfirmEdit.jsx +61 -0
- package/src/EventGQLModel/Components/Filter.jsx +14 -0
- package/src/EventGQLModel/Components/LargeCard.jsx +54 -0
- package/src/EventGQLModel/Components/Link.jsx +55 -0
- package/src/EventGQLModel/Components/LiveEdit.jsx +111 -0
- package/src/EventGQLModel/Components/MediumCard.jsx +39 -0
- package/src/EventGQLModel/Components/MediumContent.jsx +96 -0
- package/src/EventGQLModel/Components/MediumEditableContent.jsx +35 -0
- package/src/EventGQLModel/Components/Plan/PlanRow.jsx +470 -0
- package/src/EventGQLModel/Components/Plan/_utils.js +971 -0
- package/src/EventGQLModel/Components/Plan/calendarReducer.js +535 -0
- package/src/EventGQLModel/Components/Plan/index.js +3 -0
- package/src/EventGQLModel/Components/Table.jsx +7 -0
- package/src/EventGQLModel/Components/index.js +15 -0
- package/src/EventGQLModel/Mutations/Create.jsx +202 -0
- package/src/EventGQLModel/Mutations/Delete.jsx +173 -0
- package/src/EventGQLModel/Mutations/InteractiveMutations.jsx +30 -0
- package/src/EventGQLModel/Mutations/Update.jsx +147 -0
- package/src/EventGQLModel/Mutations/helpers.jsx +7 -0
- package/src/EventGQLModel/Pages/PageBase.jsx +56 -0
- package/src/EventGQLModel/Pages/PageCreateItem.jsx +28 -0
- package/src/EventGQLModel/Pages/PageDeleteItem.jsx +16 -0
- package/src/EventGQLModel/Pages/PageNavbar.jsx +160 -0
- package/src/EventGQLModel/Pages/PagePlan.jsx +42 -0
- package/src/EventGQLModel/Pages/PageReadItem.jsx +11 -0
- package/src/EventGQLModel/Pages/PageReadItemEx.jsx +42 -0
- package/src/EventGQLModel/Pages/PageSubevents.jsx +43 -0
- package/src/EventGQLModel/Pages/PageUpdateItem.jsx +14 -0
- package/src/EventGQLModel/Pages/PageVector.jsx +80 -0
- package/src/EventGQLModel/Pages/RouterSegment.jsx +82 -0
- package/src/EventGQLModel/Pages/index.js +2 -0
- package/src/EventGQLModel/Queries/DeleteAsyncAction.jsx +32 -0
- package/src/EventGQLModel/Queries/Fragments.jsx +123 -0
- package/src/EventGQLModel/Queries/InsertAsyncAction.jsx +40 -0
- package/src/EventGQLModel/Queries/ReadAsyncAction.jsx +44 -0
- package/src/EventGQLModel/Queries/ReadPageAsyncAction.jsx +13 -0
- package/src/EventGQLModel/Queries/ReadSubEventsAsyncAction.jsx +44 -0
- package/src/EventGQLModel/Queries/SearchAsyncAction.jsx +16 -0
- package/src/EventGQLModel/Queries/UpdateAsyncAction.jsx +40 -0
- package/src/EventGQLModel/Queries/index.js +6 -0
- package/src/EventGQLModel/Scalars/ScalarAttribute.jsx +54 -0
- package/src/EventGQLModel/Scalars/TemplateScalarAttribute.jsx +88 -0
- package/src/EventGQLModel/Scalars/index.js +1 -0
- package/src/EventGQLModel/Vectors/TemplateVectorsAttribute.jsx +326 -0
- package/src/EventGQLModel/Vectors/VectorAttribute.jsx +56 -0
- package/src/EventGQLModel/Vectors/index.js +1 -0
- package/src/EventGQLModel/WhatToDo.md +44 -0
- package/src/EventGQLModel/index.js +71 -0
- package/src/GroupGQLModel/Mutations/Create.jsx +8 -2
- package/src/GroupGQLModel/Mutations/Delete.jsx +8 -2
- package/src/GroupGQLModel/Mutations/Update.jsx +8 -8
- package/src/GroupGQLModel/Queries/Fragments.jsx +17 -1
- package/src/GroupGQLModel/Scalars/RBACObject.jsx +17 -5
- package/src/GroupGQLModel/Vectors/GroupMemberships.jsx +1 -1
- package/src/UserGQLModel/Components/MediumContent.jsx +9 -3
- package/src/UserGQLModel/Queries/Fragments.jsx +6 -0
- package/src/_Template/WhatToDo.md +1 -1
- package/index.html +0 -104
- package/vite.config.js +0 -47
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { CreateURI, MediumEditableContent, ReadItemURI } from "../Components"
|
|
2
|
+
import { InsertAsyncAction } from "../Queries"
|
|
3
|
+
import {
|
|
4
|
+
CreateBody as BaseCreateBody,
|
|
5
|
+
CreateButton as BaseCreateButton,
|
|
6
|
+
CreateDialog as BaseCreateDialog,
|
|
7
|
+
CreateLink as BaseCreateLink
|
|
8
|
+
} from "../../../../_template/src/Base/Mutations/Create"
|
|
9
|
+
|
|
10
|
+
const DefaultContent = (props) => <MediumEditableContent {...props} />
|
|
11
|
+
const MutationAsyncAction = InsertAsyncAction
|
|
12
|
+
|
|
13
|
+
const permissions = {
|
|
14
|
+
oneOfRoles: ["superadmin"],
|
|
15
|
+
mode: "absolute",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const defaultitem = { name: "Nový" };
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Wrapper nad `BaseCreateLink` (alias importu `CreateLink` z Base/Mutations/Create),
|
|
22
|
+
* který je odvozený z obecných `General*` komponent.
|
|
23
|
+
*
|
|
24
|
+
* Účel wrapperu:
|
|
25
|
+
* - nastaví výchozí `uriPattern` pro create route
|
|
26
|
+
* - aplikuje výchozí RBAC nastavení přes `permissions` (např. `oneOfRoles`, `mode`)
|
|
27
|
+
* - všechny ostatní props pouze přeposílá do Base komponenty
|
|
28
|
+
*
|
|
29
|
+
* Vizuálně vyrenderuje link pro kliknutí
|
|
30
|
+
*
|
|
31
|
+
* @param {Object} params
|
|
32
|
+
* @param {string} [params.uriPattern=CreateURI]
|
|
33
|
+
* Cílová URI/pattern pro link na create stránku nebo create akci (dle routování aplikace).
|
|
34
|
+
*
|
|
35
|
+
* @param {Object} params.props
|
|
36
|
+
* Další props přeposílané do `BaseCreateLink` (např. `children`, `className`,
|
|
37
|
+
* `preserveSearch`, `preserveHash`, atd.).
|
|
38
|
+
*
|
|
39
|
+
* @returns {JSX.Element} Vykreslí `BaseCreateLink` s přednastaveným `uriPattern` a RBAC oprávněními.
|
|
40
|
+
*/
|
|
41
|
+
export const CreateLink = ({
|
|
42
|
+
uriPattern=CreateURI,
|
|
43
|
+
...props
|
|
44
|
+
}) => (
|
|
45
|
+
<BaseCreateLink {...props} uriPattern={uriPattern} {...permissions} />
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Wrapper nad `BaseCreateButton` (alias importu `CreateButton` z Base/Mutations/Create),
|
|
50
|
+
* který je odvozený z obecných `General*` komponent.
|
|
51
|
+
*
|
|
52
|
+
* Účel wrapperu:
|
|
53
|
+
* - nastaví výchozí oprávnění (RBAC) přes `permissions` (`oneOfRoles`, `mode`)
|
|
54
|
+
* - nastaví výchozí mutaci pro vytvoření entity (`mutationAsyncAction`)
|
|
55
|
+
* - umožní vyměnit dialog a obsah formuláře (`CreateDialog`, `DefaultContent`)
|
|
56
|
+
* - určí kam se má po úspěšném vytvoření navigovat (`readItemURI`)
|
|
57
|
+
* - předá výchozí `item` pro nový záznam
|
|
58
|
+
*
|
|
59
|
+
* Zobrazí tlačítko a po jeho stisku otevře dialog, při volbě OK dochází k odeslání mutace na backend
|
|
60
|
+
*
|
|
61
|
+
* @param {Object} params
|
|
62
|
+
* @param {Function} [params.mutationAsyncAction=MutationAsyncAction]
|
|
63
|
+
* Async action (thunk) pro vytvoření entity (např. InsertAsyncAction). Používá ho Base/General logika.
|
|
64
|
+
*
|
|
65
|
+
* @param {React.ComponentType<Object>} [params.CreateDialog=CreateDialog]
|
|
66
|
+
* Komponenta dialogu použitá pro vytvoření (renderuje formulář a volá `onOk(draft)` / `onCancel()`).
|
|
67
|
+
*
|
|
68
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=DefaultContent]
|
|
69
|
+
* Komponenta, která vykreslí editable obsah formuláře (typicky MediumEditableContent).
|
|
70
|
+
*
|
|
71
|
+
* @param {string} [params.readItemURI=ReadItemURI]
|
|
72
|
+
* URI pattern pro navigaci na detail nově vytvořené entity (obvykle obsahuje `:id`).
|
|
73
|
+
*
|
|
74
|
+
* @param {Object} [params.rbacitem]
|
|
75
|
+
* RBAC item pro PermissionGate/Permission check (pokud se liší od entity, která se vytváří).
|
|
76
|
+
*
|
|
77
|
+
* @param {Object} [params.item=defaultitem]
|
|
78
|
+
* Výchozí objekt (draft) pro nový záznam. Posílá se do dialogu jako `item`.
|
|
79
|
+
*
|
|
80
|
+
* @param {Object} params.props
|
|
81
|
+
* Všechny další props jsou přeposlány přímo do `BaseCreateButton`
|
|
82
|
+
* (typicky `children`, `className`, `disabled`, `title`, atd.).
|
|
83
|
+
*
|
|
84
|
+
* @returns {JSX.Element} Vykreslí `BaseCreateButton` s přednastavenými defaulty a RBAC oprávněními.
|
|
85
|
+
*/
|
|
86
|
+
export const CreateButton = ({
|
|
87
|
+
mutationAsyncAction=MutationAsyncAction,
|
|
88
|
+
CreateDialog: CreateDialog_=CreateDialog,
|
|
89
|
+
DefaultContent:defaultContent=DefaultContent,
|
|
90
|
+
readItemURI=ReadItemURI,
|
|
91
|
+
rbacitem,
|
|
92
|
+
item=defaultitem,
|
|
93
|
+
...props
|
|
94
|
+
}) => {
|
|
95
|
+
return <BaseCreateButton
|
|
96
|
+
{...props}
|
|
97
|
+
DefaultContent={defaultContent}
|
|
98
|
+
CreateDialog={CreateDialog_}
|
|
99
|
+
readItemURI={readItemURI}
|
|
100
|
+
rbacitem={rbacitem}
|
|
101
|
+
item={item}
|
|
102
|
+
mutationAsyncAction={mutationAsyncAction}
|
|
103
|
+
{...permissions}
|
|
104
|
+
/>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Wrapper nad `BaseCreateDialog` (alias importu `CreateDialog` z Base/Mutations/Create),
|
|
109
|
+
* který je odvozený z obecných `General*` komponent.
|
|
110
|
+
*
|
|
111
|
+
* Účel wrapperu:
|
|
112
|
+
* - nastaví výchozí title, obsah formuláře a výchozí draft (`item`)
|
|
113
|
+
* - předá `readItemURI` pro případnou navigaci po vytvoření (dle implementace Base/General)
|
|
114
|
+
* - umožní přepsat `mutationAsyncAction` (pokud BaseCreateDialog mutaci používá)
|
|
115
|
+
*
|
|
116
|
+
* Mutaci provadi až tlačítko (`BaseCreateButton`) Dialog jen zobrazuje a zabezpecuje sber dat
|
|
117
|
+
* a dialog je jen “formulář”.
|
|
118
|
+
*
|
|
119
|
+
* @param {Object} params
|
|
120
|
+
* @param {string} [params.title="Nov(ý/é)"]
|
|
121
|
+
* Titulek dialogu.
|
|
122
|
+
*
|
|
123
|
+
* @param {Function} [params.mutationAsyncAction=MutationAsyncAction]
|
|
124
|
+
* Async action (thunk) pro vytvoření entity. Použije se pouze pokud ho `BaseCreateDialog` skutečně volá
|
|
125
|
+
* (záleží na Base/General implementaci).
|
|
126
|
+
*
|
|
127
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=DefaultContent]
|
|
128
|
+
* Komponenta, která vykreslí editable obsah formuláře (typicky MediumEditableContent).
|
|
129
|
+
*
|
|
130
|
+
* @param {string} [params.readItemURI=ReadItemURI]
|
|
131
|
+
* URI pattern pro navigaci na detail nově vytvořené entity (obvykle obsahuje `:id`).
|
|
132
|
+
*
|
|
133
|
+
* @param {Object} [params.item=defaultitem]
|
|
134
|
+
* Výchozí objekt (draft) pro nový záznam. Posílá se do dialogu jako `item`.
|
|
135
|
+
*
|
|
136
|
+
* @param {Object} params.props
|
|
137
|
+
* Všechny další props jsou přeposlány přímo do `BaseCreateDialog`
|
|
138
|
+
* (typicky `oklabel`, `cancellabel`, `onOk`, `onCancel`, `className`, atd.).
|
|
139
|
+
*
|
|
140
|
+
* @returns {JSX.Element} Vykreslí `BaseCreateDialog` s přednastavenými defaulty.
|
|
141
|
+
*/
|
|
142
|
+
export const CreateDialog = ({
|
|
143
|
+
title = "Nov(ý/é)",
|
|
144
|
+
// mutationAsyncAction=MutationAsyncAction,
|
|
145
|
+
DefaultContent:defaultContent=DefaultContent,
|
|
146
|
+
readItemURI=ReadItemURI,
|
|
147
|
+
item=defaultitem,
|
|
148
|
+
...props
|
|
149
|
+
}) => {
|
|
150
|
+
return <BaseCreateDialog
|
|
151
|
+
{...props}
|
|
152
|
+
title={title}
|
|
153
|
+
DefaultContent={defaultContent}
|
|
154
|
+
readItemURI={readItemURI}
|
|
155
|
+
item={item}
|
|
156
|
+
// mutationAsyncAction={mutationAsyncAction}
|
|
157
|
+
/>
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Wrapper nad `BaseCreateBody` (alias importu `CreateBody` z Base/Mutations/Create),
|
|
162
|
+
* který je odvozený z obecných `General*` komponent.
|
|
163
|
+
*
|
|
164
|
+
* `CreateBody` typicky reprezentuje “page-level” create workflow (ne jen tlačítko + modal):
|
|
165
|
+
* - vykreslí create formulář pomocí `DefaultContent`
|
|
166
|
+
* - zajistí uložení přes `mutationAsyncAction` (dle Base/General implementace)
|
|
167
|
+
* - po úspěchu může navigovat na detail vytvořené entity přes `readItemURI` (pokud Base/General takto funguje)
|
|
168
|
+
*
|
|
169
|
+
* Wrapper pouze nastavuje defaulty a přeposílá props do `BaseCreateBody`.
|
|
170
|
+
*
|
|
171
|
+
* Vizualizuje <DefaultContent />, sbira zmeny a umoznuje volani backendu pro ulozeni dat
|
|
172
|
+
*
|
|
173
|
+
* @param {Object} params
|
|
174
|
+
* @param {Function} [params.mutationAsyncAction=MutationAsyncAction]
|
|
175
|
+
* Async action (thunk) pro vytvoření entity (např. InsertAsyncAction). Používá ho Base/General logika.
|
|
176
|
+
*
|
|
177
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=DefaultContent]
|
|
178
|
+
* Komponenta, která vykreslí editable obsah formuláře (typicky MediumEditableContent).
|
|
179
|
+
*
|
|
180
|
+
* @param {string} [params.readItemURI=ReadItemURI]
|
|
181
|
+
* URI pattern pro navigaci na detail nově vytvořené entity (obvykle obsahuje `:id`).
|
|
182
|
+
*
|
|
183
|
+
* @param {Object} params.props
|
|
184
|
+
* Všechny další props jsou přeposlány přímo do `BaseCreateBody`
|
|
185
|
+
* (typicky `title`, `oklabel`, `cancellabel`, `onOk`, `onCancel`, `className`, atd.).
|
|
186
|
+
*
|
|
187
|
+
* @returns {JSX.Element} Vykreslí `BaseCreateBody` s přednastavenými defaulty.
|
|
188
|
+
*/
|
|
189
|
+
export const CreateBody = ({
|
|
190
|
+
mutationAsyncAction=MutationAsyncAction,
|
|
191
|
+
DefaultContent:defaultContent=DefaultContent,
|
|
192
|
+
readItemURI=ReadItemURI,
|
|
193
|
+
...props
|
|
194
|
+
}) => {
|
|
195
|
+
return <BaseCreateBody
|
|
196
|
+
{...props}
|
|
197
|
+
DefaultContent={defaultContent}
|
|
198
|
+
readItemURI={readItemURI}
|
|
199
|
+
mutationAsyncAction={mutationAsyncAction}
|
|
200
|
+
/>
|
|
201
|
+
};
|
|
202
|
+
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { DeleteItemURI, ListURI, MediumContent, VectorItemsURI } from "../Components";
|
|
2
|
+
import { DeleteAsyncAction } from "../Queries";
|
|
3
|
+
import {
|
|
4
|
+
DeleteBody as BaseDeleteBody,
|
|
5
|
+
DeleteButton as BaseDeleteButton,
|
|
6
|
+
DeleteDialog as BaseDeleteDialog,
|
|
7
|
+
DeleteLink as BaseDeleteLink
|
|
8
|
+
} from "../../../../_template/src/Base/Mutations/Delete";
|
|
9
|
+
|
|
10
|
+
const DefaultContent = MediumContent
|
|
11
|
+
const MutationAsyncAction = DeleteAsyncAction
|
|
12
|
+
|
|
13
|
+
const permissions = {
|
|
14
|
+
oneOfRoles: ["superadmin"],
|
|
15
|
+
mode: "absolute",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Link na delete route pro konkrétní entitu.
|
|
20
|
+
*
|
|
21
|
+
* Wrapper nad `BaseDeleteLink`. Nastavuje výchozí `uriPattern` pro delete route a aplikuje RBAC
|
|
22
|
+
* přes `permissions`. Ostatní props přeposílá do Base komponenty.
|
|
23
|
+
*
|
|
24
|
+
* @param {Object} params
|
|
25
|
+
* @param {string} [params.uriPattern=DeleteItemURI]
|
|
26
|
+
* URI pattern pro delete route (typicky obsahuje `:id` nebo odpovídá routování aplikace).
|
|
27
|
+
* @param {Object} params.props
|
|
28
|
+
* Další props přeposílané do `BaseDeleteLink` (např. `children`, `className`,
|
|
29
|
+
* `preserveSearch`, `preserveHash`, atd.).
|
|
30
|
+
*
|
|
31
|
+
* @returns {JSX.Element}
|
|
32
|
+
*/
|
|
33
|
+
export const DeleteLink = ({
|
|
34
|
+
uriPattern=DeleteItemURI,
|
|
35
|
+
...props
|
|
36
|
+
}) => {
|
|
37
|
+
return (
|
|
38
|
+
<BaseDeleteLink
|
|
39
|
+
{...props}
|
|
40
|
+
uriPattern={uriPattern}
|
|
41
|
+
{...permissions}
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Tlačítko pro smazání entity (obvykle otevře confirm dialog a spustí delete mutaci).
|
|
48
|
+
*
|
|
49
|
+
* Wrapper nad `BaseDeleteButton`. Dodává výchozí `DefaultContent`, `mutationAsyncAction`
|
|
50
|
+
* a `vectorItemsURI` (kam se naviguje po úspěšném smazání, pokud není použit `onOk`).
|
|
51
|
+
*
|
|
52
|
+
* Chování navigace / callback:
|
|
53
|
+
* - Pokud je definované `onOk`, použije se pro “feedback”, že mazání proběhlo (tj. uživatel si
|
|
54
|
+
* rozhodne, co dál).
|
|
55
|
+
* - Pokud `onOk` definované není, Base implementace typicky naviguje na `vectorItemsURI`.
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} params
|
|
58
|
+
* @param {Function} [params.mutationAsyncAction=MutationAsyncAction]
|
|
59
|
+
* Async action (thunk) pro delete operaci (např. DeleteAsyncAction).
|
|
60
|
+
*
|
|
61
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=MediumContent]
|
|
62
|
+
* Komponenta pro zobrazení mazáné entity v confirm dialogu (read-only).
|
|
63
|
+
*
|
|
64
|
+
* @param {string} [params.vectorItemsURI=ListURI]
|
|
65
|
+
* URI pro návrat po úspěšném smazání (typicky list stránka / kolekce).
|
|
66
|
+
*
|
|
67
|
+
* @param {Function} [params.onOk]
|
|
68
|
+
* Callback po úspěšném smazání. Pokud není zadán, Base implementace typicky použije navigaci na `vectorItemsURI`.
|
|
69
|
+
*
|
|
70
|
+
* @param {Object}} params.props
|
|
71
|
+
* Další props přeposílané do `BaseDeleteButton` (např. `children`, `title`, `className`,
|
|
72
|
+
* `rbacitem`, `item`, `disabled`, atd. – podle Base/General implementace).
|
|
73
|
+
*
|
|
74
|
+
* @returns {JSX.Element}
|
|
75
|
+
*/
|
|
76
|
+
export const DeleteButton = ({
|
|
77
|
+
mutationAsyncAction=MutationAsyncAction,
|
|
78
|
+
DefaultContent:DefaultContent_=DefaultContent,
|
|
79
|
+
Dialog=DeleteDialog,
|
|
80
|
+
vectorItemsURI=ListURI,
|
|
81
|
+
onOk,
|
|
82
|
+
...props
|
|
83
|
+
}) => {
|
|
84
|
+
return (
|
|
85
|
+
<BaseDeleteButton
|
|
86
|
+
{...props}
|
|
87
|
+
DefaultContent={DefaultContent_}
|
|
88
|
+
Dialog={Dialog}
|
|
89
|
+
mutationAsyncAction={mutationAsyncAction}
|
|
90
|
+
vectorItemsURI={vectorItemsURI}
|
|
91
|
+
onOk={onOk}
|
|
92
|
+
{...permissions}
|
|
93
|
+
/>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Confirm dialog pro smazání entity.
|
|
99
|
+
*
|
|
100
|
+
* Wrapper nad `BaseDeleteDialog`. Dodává výchozí `DefaultContent` (read-only zobrazení entity),
|
|
101
|
+
* `mutationAsyncAction` a `vectorItemsURI` pro návrat po úspěchu (dle Base/General implementace).
|
|
102
|
+
*
|
|
103
|
+
* @param {Object} params
|
|
104
|
+
* @param {Function} [params.mutationAsyncAction=MutationAsyncAction]
|
|
105
|
+
* Async action (thunk) pro delete operaci (např. DeleteAsyncAction).
|
|
106
|
+
*
|
|
107
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=MediumContent]
|
|
108
|
+
* Komponenta pro zobrazení mazáné entity (read-only).
|
|
109
|
+
*
|
|
110
|
+
* @param {string} [params.vectorItemsURI=ListURI]
|
|
111
|
+
* URI pro návrat po úspěšném smazání (typicky list stránka / kolekce).
|
|
112
|
+
*
|
|
113
|
+
* @param {Object}} params.props
|
|
114
|
+
* Další props přeposílané do `BaseDeleteDialog` (např. `title`, `oklabel`, `cancellabel`,
|
|
115
|
+
* `item`, `onOk`, `onCancel`, atd.).
|
|
116
|
+
*
|
|
117
|
+
* @returns {JSX.Element}
|
|
118
|
+
*/
|
|
119
|
+
export const DeleteDialog = ({
|
|
120
|
+
mutationAsyncAction=MutationAsyncAction,
|
|
121
|
+
DefaultContent:DefaultContent_=DefaultContent,
|
|
122
|
+
vectorItemsURI=ListURI,
|
|
123
|
+
...props
|
|
124
|
+
}) => {
|
|
125
|
+
return (
|
|
126
|
+
<BaseDeleteDialog
|
|
127
|
+
{...props}
|
|
128
|
+
DefaultContent={DefaultContent_}
|
|
129
|
+
mutationAsyncAction={mutationAsyncAction}
|
|
130
|
+
vectorItemsURI={vectorItemsURI}
|
|
131
|
+
{...permissions}
|
|
132
|
+
/>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* “Page-level” delete workflow (mazání na celé stránce / v těle stránky).
|
|
138
|
+
*
|
|
139
|
+
* Wrapper nad `BaseDeleteBody`. Dodává výchozí `DefaultContent`, `mutationAsyncAction`
|
|
140
|
+
* a `vectorItemsURI` a aplikuje RBAC přes `permissions`.
|
|
141
|
+
*
|
|
142
|
+
* @param {Object} params
|
|
143
|
+
* @param {Function} [params.mutationAsyncAction=MutationAsyncAction]
|
|
144
|
+
* Async action (thunk) pro delete operaci (např. DeleteAsyncAction).
|
|
145
|
+
*
|
|
146
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=MediumContent]
|
|
147
|
+
* Komponenta pro zobrazení mazáné entity (read-only).
|
|
148
|
+
*
|
|
149
|
+
* @param {string} [params.vectorItemsURI=ListURI]
|
|
150
|
+
* URI pro návrat po úspěšném smazání (typicky list stránka / kolekce).
|
|
151
|
+
*
|
|
152
|
+
* @param {Object}} params.props
|
|
153
|
+
* Další props přeposílané do `BaseDeleteBody` (např. `title`, `oklabel`, `cancellabel`,
|
|
154
|
+
* `item`, `onOk`, `onCancel`, atd.).
|
|
155
|
+
*
|
|
156
|
+
* @returns {JSX.Element}
|
|
157
|
+
*/
|
|
158
|
+
export const DeleteBody = ({
|
|
159
|
+
mutationAsyncAction=MutationAsyncAction,
|
|
160
|
+
DefaultContent:DefaultContent_=DefaultContent,
|
|
161
|
+
vectorItemsURI=ListURI,
|
|
162
|
+
...props
|
|
163
|
+
}) => {
|
|
164
|
+
return (
|
|
165
|
+
<BaseDeleteBody
|
|
166
|
+
{...props}
|
|
167
|
+
DefaultContent={DefaultContent_}
|
|
168
|
+
mutationAsyncAction={mutationAsyncAction}
|
|
169
|
+
vectorItemsURI={vectorItemsURI}
|
|
170
|
+
{...permissions}
|
|
171
|
+
/>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CardCapsule, VectorItemsURI } from "../Components"
|
|
2
|
+
import { CreateButton, CreateLink } from "./Create"
|
|
3
|
+
import { UpdateButton, UpdateLink } from "./Update"
|
|
4
|
+
import { ProxyLink } from "../../../../_template/src/Base/Components/ProxyLink"
|
|
5
|
+
import { DeleteButton } from "./Delete"
|
|
6
|
+
|
|
7
|
+
export const PageLink = ({ children, preserveHash = true, preserveSearch = true, ...props }) => {
|
|
8
|
+
return (
|
|
9
|
+
<ProxyLink
|
|
10
|
+
to={VectorItemsURI}
|
|
11
|
+
preserveHash={preserveHash}
|
|
12
|
+
preserveSearch={preserveSearch}
|
|
13
|
+
{...props}
|
|
14
|
+
>
|
|
15
|
+
{children}
|
|
16
|
+
</ProxyLink>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const InteractiveMutations = ({ item }) => {
|
|
21
|
+
return (
|
|
22
|
+
<CardCapsule item={item} title="Nástroje">
|
|
23
|
+
<PageLink className="btn btn-outline-success">Stránka</PageLink>
|
|
24
|
+
<UpdateLink className="btn btn-outline-success" item={item}>Upravit</UpdateLink>
|
|
25
|
+
<UpdateButton className="btn btn-outline-success" item={item}>Upravit Dialog</UpdateButton>
|
|
26
|
+
<CreateButton className="btn btn-outline-success" rbacitem={{}}>Vytvořit nový</CreateButton>
|
|
27
|
+
<DeleteButton className="btn btn-outline-danger" item={item}>Odstranit</DeleteButton>
|
|
28
|
+
</CardCapsule>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UpdateBody as BaseUpdateBody,
|
|
3
|
+
UpdateButton as BaseUpdateButton,
|
|
4
|
+
UpdateDialog as BaseUpdateDialog,
|
|
5
|
+
UpdateLink as BaseUpdateLink
|
|
6
|
+
} from "../../../../_template/src/Base/Mutations/Update";
|
|
7
|
+
|
|
8
|
+
import { MediumEditableContent, UpdateItemURI } from "../Components";
|
|
9
|
+
import { UpdateAsyncAction } from "../Queries";
|
|
10
|
+
|
|
11
|
+
const DefaultContent = (props) => <MediumEditableContent {...props} />
|
|
12
|
+
const mutationAsyncAction = UpdateAsyncAction
|
|
13
|
+
|
|
14
|
+
const permissions = {
|
|
15
|
+
oneOfRoles: ["superadmin"],
|
|
16
|
+
mode: "absolute",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ALTERNATIVE, CHECK GQLENDPOINT
|
|
20
|
+
// const permissions = {
|
|
21
|
+
// oneOfRoles: ["administrátor", "personalista"],
|
|
22
|
+
// mode: "item",
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Link na update stránku / update route pro konkrétní entitu.
|
|
27
|
+
*
|
|
28
|
+
* Wrapper nad `BaseUpdateLink`. Nastavuje výchozí `uriPattern` a aplikuje RBAC
|
|
29
|
+
* přes `permissions`. Vše ostatní přeposílá do Base komponenty.
|
|
30
|
+
*
|
|
31
|
+
* @param {Object} params
|
|
32
|
+
* @param {string} [params.uriPattern=UpdateItemURI]
|
|
33
|
+
* URI pattern pro update route (typicky obsahuje `:id` nebo je již konkrétní URL dle routování).
|
|
34
|
+
* @param {Object} params.props
|
|
35
|
+
* Další props přeposílané do `BaseUpdateLink` (např. `children`, `className`,
|
|
36
|
+
* `preserveSearch`, `preserveHash`, atd.).
|
|
37
|
+
* @returns {JSX.Element}
|
|
38
|
+
*/
|
|
39
|
+
export const UpdateLink = ({
|
|
40
|
+
uriPattern = UpdateItemURI,
|
|
41
|
+
...props
|
|
42
|
+
}) => {
|
|
43
|
+
return <BaseUpdateLink
|
|
44
|
+
{...props}
|
|
45
|
+
uriPattern={uriPattern}
|
|
46
|
+
{...permissions}
|
|
47
|
+
/>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Dialog pro editaci entity.
|
|
52
|
+
*
|
|
53
|
+
* Wrapper nad `BaseUpdateDialog`. Dodává výchozí editovatelný obsah (`DefaultContent`)
|
|
54
|
+
* a výchozí mutační akci (`mutationAsyncAction`) pro uložení změn. Aplikuje RBAC
|
|
55
|
+
* přes `permissions`.
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} params
|
|
58
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=DefaultContent]
|
|
59
|
+
* Komponenta, která vykreslí editovatelný obsah dialogu (typicky MediumEditableContent).
|
|
60
|
+
* @param {Function} [params.mutationAsyncAction=mutationAsyncAction]
|
|
61
|
+
* Async action (thunk) pro uložení změn (např. UpdateAsyncAction). Použije se podle Base/General implementace.
|
|
62
|
+
* @param {Object} params.props
|
|
63
|
+
* Další props přeposílané do `BaseUpdateDialog` (např. `title`, `oklabel`, `cancellabel`,
|
|
64
|
+
* `item`, `onOk`, `onCancel`, atd.).
|
|
65
|
+
* @returns {JSX.Element}
|
|
66
|
+
*/
|
|
67
|
+
export const UpdateDialog = ({
|
|
68
|
+
DefaultContent: DefaultContent_ = DefaultContent,
|
|
69
|
+
mutationAsyncAction: mutationAsyncAction_ = mutationAsyncAction,
|
|
70
|
+
...props
|
|
71
|
+
}) => {
|
|
72
|
+
return (
|
|
73
|
+
<BaseUpdateDialog
|
|
74
|
+
{...props}
|
|
75
|
+
DefaultContent={DefaultContent_}
|
|
76
|
+
mutationAsyncAction={mutationAsyncAction_}
|
|
77
|
+
{...permissions}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Tlačítko, které otevře update dialog a provede uložení.
|
|
84
|
+
*
|
|
85
|
+
* Wrapper nad `BaseUpdateButton`. Dodává výchozí `DefaultContent`, výchozí `Dialog`,
|
|
86
|
+
* a výchozí `mutationAsyncAction`. Aplikuje RBAC přes `permissions`.
|
|
87
|
+
*
|
|
88
|
+
* @param {Object} params
|
|
89
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=DefaultContent]
|
|
90
|
+
* Komponenta editovatelného obsahu (typicky MediumEditableContent).
|
|
91
|
+
* @param {React.ComponentType<Object>} [params.Dialog=UpdateDialog]
|
|
92
|
+
* Dialog komponenta použitá pro editaci (volá `onOk(draft)` / `onCancel()`).
|
|
93
|
+
* @param {Function} [params.mutationAsyncAction=mutationAsyncAction]
|
|
94
|
+
* Async action (thunk) pro uložení změn (např. UpdateAsyncAction).
|
|
95
|
+
* @param {Object} params.props
|
|
96
|
+
* Další props přeposílané do `BaseUpdateButton` (např. `children`, `className`, `title`,
|
|
97
|
+
* `item`, `uriPattern`, `onOk`, `onCancel`, atd.).
|
|
98
|
+
* @returns {JSX.Element}
|
|
99
|
+
*/
|
|
100
|
+
export const UpdateButton = ({
|
|
101
|
+
DefaultContent: DefaultContent_ = DefaultContent,
|
|
102
|
+
Dialog = UpdateDialog,
|
|
103
|
+
mutationAsyncAction: mutationAsyncAction_ = mutationAsyncAction,
|
|
104
|
+
...props
|
|
105
|
+
}) => {
|
|
106
|
+
return (
|
|
107
|
+
<BaseUpdateButton
|
|
108
|
+
{...props}
|
|
109
|
+
DefaultContent={DefaultContent_}
|
|
110
|
+
Dialog={Dialog}
|
|
111
|
+
mutationAsyncAction={mutationAsyncAction_}
|
|
112
|
+
{...permissions}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* “Page-level” update workflow (inline edit / celá stránka editace).
|
|
119
|
+
*
|
|
120
|
+
* Wrapper nad `BaseUpdateBody`. Typicky vykreslí editovatelný obsah (`DefaultContent`)
|
|
121
|
+
* a zajistí uložení přes `mutationAsyncAction` (dle Base/General implementace).
|
|
122
|
+
* Aplikuje RBAC přes `permissions`.
|
|
123
|
+
*
|
|
124
|
+
* @param {Object} params
|
|
125
|
+
* @param {React.ComponentType<Object>} [params.DefaultContent=DefaultContent]
|
|
126
|
+
* Komponenta editovatelného obsahu (typicky MediumEditableContent).
|
|
127
|
+
* @param {Function} [params.mutationAsyncAction=mutationAsyncAction]
|
|
128
|
+
* Async action (thunk) pro uložení změn (např. UpdateAsyncAction).
|
|
129
|
+
* @param {Object} params.props
|
|
130
|
+
* Další props přeposílané do `BaseUpdateBody` (např. `title`, `oklabel`, `cancellabel`,
|
|
131
|
+
* `item`, `onOk`, `onCancel`, `className`, atd.).
|
|
132
|
+
* @returns {JSX.Element}
|
|
133
|
+
*/
|
|
134
|
+
export const UpdateBody = ({
|
|
135
|
+
DefaultContent: DefaultContent_ = DefaultContent,
|
|
136
|
+
mutationAsyncAction: mutationAsyncAction_ = mutationAsyncAction,
|
|
137
|
+
...props
|
|
138
|
+
}) => {
|
|
139
|
+
return (
|
|
140
|
+
<BaseUpdateBody
|
|
141
|
+
{...props}
|
|
142
|
+
DefaultContent={DefaultContent_}
|
|
143
|
+
mutationAsyncAction={mutationAsyncAction_}
|
|
144
|
+
{...permissions}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const makeMutationURI = (linkURI, action, { withId = false } = {}) => {
|
|
2
|
+
const viewSegmentRe = /\/view(\/|$)/;
|
|
3
|
+
if (!viewSegmentRe.test(linkURI)) throw new Error(`LinkURI must contain '/view'. Got: ${linkURI}`);
|
|
4
|
+
|
|
5
|
+
const base = linkURI.replace(viewSegmentRe, `/${action}$1`).replace(/\/?$/, "/");
|
|
6
|
+
return withId ? `${base}:id` : base.replace(/\/$/, "");
|
|
7
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ReadAsyncAction } from "../Queries"
|
|
2
|
+
import { PageItemBase as PageItemBase_} from "../../../../_template/src/Base/Pages/Page"
|
|
3
|
+
import { LargeCard } from "../Components"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base wrapper pro stránky pracující s jedním entity itemem podle `:id` z routy.
|
|
8
|
+
*
|
|
9
|
+
* Komponenta:
|
|
10
|
+
* - načte `id` z URL přes `useParams()`
|
|
11
|
+
* - sestaví minimální `item` objekt `{ id }`
|
|
12
|
+
* - poskytne jej přes `AsyncActionProvider`, který zajistí načtení entity pomocí `queryAsyncAction`
|
|
13
|
+
* - vloží do stránky navbar přes `PlaceChild Component={PageNavbar}`
|
|
14
|
+
* - vyrenderuje `children` uvnitř provideru (tj. až v kontextu načtené entity)
|
|
15
|
+
*
|
|
16
|
+
* Typické použití je jako obálka routy typu `/.../:id`, kde vnořené komponenty
|
|
17
|
+
* (detail, editace, akce) používají kontext z `AsyncActionProvider`.
|
|
18
|
+
*
|
|
19
|
+
* @component
|
|
20
|
+
* @param {object} props
|
|
21
|
+
* @param {import("react").ReactNode} props.children
|
|
22
|
+
* Obsah stránky, který se má vyrenderovat uvnitř `AsyncActionProvider`.
|
|
23
|
+
* @param {Function} [props.queryAsyncAction=ReadAsyncAction]
|
|
24
|
+
* Async action (např. thunk) použitá pro načtení entity z GraphQL endpointu.
|
|
25
|
+
* Dostane `item` s `id` (a případně další parametry podle implementace provideru).
|
|
26
|
+
*
|
|
27
|
+
* @returns {import("react").JSX.Element}
|
|
28
|
+
* Provider s navigací (`PageNavbar`) a obsahem stránky (`children`).
|
|
29
|
+
*/
|
|
30
|
+
export const PageItemBase = ({
|
|
31
|
+
queryAsyncAction=ReadAsyncAction,
|
|
32
|
+
PageNavbar=()=>null,
|
|
33
|
+
ItemLayout=LargeCard,
|
|
34
|
+
SubPage=null,
|
|
35
|
+
...props
|
|
36
|
+
}) => {
|
|
37
|
+
return (
|
|
38
|
+
<PageItemBase_
|
|
39
|
+
queryAsyncAction={queryAsyncAction}
|
|
40
|
+
PageNavbar={PageNavbar}
|
|
41
|
+
ItemLayout={ItemLayout}
|
|
42
|
+
SubPage={SubPage}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
export const PageBase = ({ children, PageNavbar=()=>null }) => {
|
|
50
|
+
return (
|
|
51
|
+
<>
|
|
52
|
+
<PageNavbar />
|
|
53
|
+
{children}
|
|
54
|
+
</>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReadAsyncAction } from "../Queries"
|
|
2
|
+
import { Row } from "../../../../_template/src/Base/Components/Row";
|
|
3
|
+
import { CreateBody } from "../Mutations/Create";
|
|
4
|
+
import { LeftColumn, MiddleColumn } from "@hrbolek/uoisfrontend-shared";
|
|
5
|
+
import { PageItemBase } from "./PageBase";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
const PageBody = ({...props}) => (
|
|
10
|
+
<Row>
|
|
11
|
+
<LeftColumn />
|
|
12
|
+
<MiddleColumn>
|
|
13
|
+
<CreateBody {...props} />
|
|
14
|
+
</MiddleColumn>
|
|
15
|
+
</Row>
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
export const PageCreateItem = ({
|
|
19
|
+
SubPage=PageBody,
|
|
20
|
+
...props
|
|
21
|
+
}) => {
|
|
22
|
+
return (
|
|
23
|
+
<PageItemBase
|
|
24
|
+
SubPage={SubPage}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PageItemBase } from "./PageBase";
|
|
2
|
+
import { DeleteBody } from "../Mutations/Delete";
|
|
3
|
+
|
|
4
|
+
export const PageDeleteItem = ({
|
|
5
|
+
SubPage=DeleteBody,
|
|
6
|
+
...props
|
|
7
|
+
}) => {
|
|
8
|
+
return (
|
|
9
|
+
<PageItemBase
|
|
10
|
+
SubPage={SubPage}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|