5htp-core 0.4.7-2 → 0.4.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.4.7-2",
4
+ "version": "0.4.8",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -3,7 +3,7 @@ h2,
3
3
  h3 {
4
4
 
5
5
  font-weight: 600;
6
- text-align: inherit;
6
+ text-align: left; // Align all titles to the left by default
7
7
  color: var(--cTxtImportant);
8
8
 
9
9
  /*.img & {
@@ -57,7 +57,10 @@
57
57
  justify-content: flex-start;
58
58
  }
59
59
 
60
- &.sep-1 > * + * { border-left: solid 1px var(--cLine); }
60
+ &.sep-1 {
61
+ gap: 0;
62
+ > * + * { border-left: solid 1px var(--cLine); }
63
+ }
61
64
 
62
65
  &.menu {
63
66
 
@@ -146,7 +149,10 @@
146
149
  &.al-right { align-items: flex-end; }
147
150
  &, &.al-fill { align-items: stretch; }
148
151
 
149
- &.sep-1 > * + * { border-top: solid 1px var(--cLine); }
152
+ &.sep-1 {
153
+ gap: 0;
154
+ > * + * { border-top: solid 1px var(--cLine); }
155
+ }
150
156
 
151
157
  > .col-1 { align-self: stretch; }
152
158
 
@@ -27,7 +27,11 @@ type TParams = { [cle: string]: unknown }
27
27
 
28
28
  type ComposantToast = React.FunctionComponent<{ close?: any }> & { data?: object };
29
29
 
30
- type TOptsToast = (CardInfos & { content?: ComponentChild })
30
+ type TOptsToast = (CardInfos & {
31
+ content?: ComponentChild,
32
+ data?: {},
33
+ className?: string,
34
+ })
31
35
 
32
36
  type TOnCloseCallback<TReturnType extends any> = (returnedValue: TReturnType) => void
33
37
 
@@ -43,16 +47,25 @@ export type TDialogControls = {
43
47
  then: (cb: TOnCloseCallback<any>) => any
44
48
  }
45
49
 
50
+ type TDialogContentArg = ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast;
51
+
52
+ type TDialogShowArgs = [
53
+ // On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
54
+ Content: TDialogContentArg,
55
+ paramsInit?: TParams
56
+ ] | [
57
+ title: string,
58
+ // On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
59
+ Content: TDialogContentArg,
60
+ paramsInit?: TParams
61
+ ]
62
+
46
63
  type DialogActions = {
47
64
 
48
65
  setToasts: ( setter: (old: ComponentChild[]) => ComponentChild[]) => void,
49
66
  setModals: ( setter: (old: ComponentChild[]) => ComponentChild[]) => void,
50
67
 
51
- show: (
52
- // On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
53
- Content: ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast,
54
- paramsInit?: TParams
55
- ) => TDialogControls,
68
+ show: (...args: TDialogShowArgs ) => TDialogControls,
56
69
 
57
70
  confirm: (title: string, content: string | ComponentChild, defaultBtn: 'Yes'|'No') => TDialogControls,
58
71
 
@@ -73,26 +86,33 @@ type DialogActions = {
73
86
  let idA: number = 0;
74
87
  export const createDialog = (app: Application, isToast: boolean): DialogActions => {
75
88
 
76
- const show = <TReturnType extends any = true>(
77
- // On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
78
- Content: ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast,
79
- paramsInit?: TParams
80
- ): TDialogControls => {
89
+ const show = <TReturnType extends any = true>( ...args: TDialogShowArgs ): TDialogControls => {
81
90
 
82
91
  let onClose: TOnCloseCallback<TReturnType>;
83
92
  const id = idA++;
84
93
 
94
+ // Parse args
95
+ let title: string | undefined;
96
+ let Content: TDialogContentArg;
97
+ let paramsInit: TParams = {};
98
+ if (typeof args[0] === 'string') {
99
+ [title, Content, paramsInit] = args;
100
+ } else {
101
+ [Content, paramsInit] = args;
102
+ }
103
+
104
+ // Set instance management function
85
105
  const setDialog = isToast
86
106
  ? instance.setToasts
87
107
  : instance.setModals;
88
108
 
109
+ // Close function
89
110
  const close = (retour: TReturnType) => {
90
111
 
91
112
  setDialog(q => q.filter(m => m.id !== id))
92
113
 
93
114
  if (onClose !== undefined)
94
115
  onClose(retour);
95
-
96
116
  };
97
117
 
98
118
  const promise = new Promise(async (resolve: TOnCloseCallback<TReturnType>) => {
@@ -101,33 +121,49 @@ export const createDialog = (app: Application, isToast: boolean): DialogActions
101
121
  let render: ComponentChild;
102
122
  let propsRendu: CardInfos = {
103
123
  ...paramsInit,
104
- close: close,
105
- data: {}
106
- };
124
+ close: close
125
+ };
126
+
127
+ // modal.show( import('./modalSupprimer') )
128
+ // -> Fetch component
129
+ if (Content.constructor === Promise)
130
+ Content = (await Content).default;
131
+
132
+ // modal.show('Supprimer', import('./modalSupprimer'))
133
+ // -> Shortcut for modal.show({ title: 'Suoorimer', content: <Component> })
134
+ if (title !== undefined) {
135
+ Content = {
136
+ title: title,
137
+ content: Content
138
+ }
139
+ }
107
140
 
108
- // toast.show({ title: 'supprimer', content: <>...</> })
141
+ // modal.show({ title: 'supprimer', content: <>...</> })
109
142
  if (Content.constructor === Object) {
110
143
 
111
- const { content, ...propsToast } = Content as TOptsToast;
144
+ const { content: CardContent, data = {}, ...propsToast } = Content as TOptsToast;
145
+
146
+ let cardContent: ComponentChild;
147
+ if (typeof CardContent === 'function') {
148
+ cardContent = <CardContent {...propsRendu} {...data} />
149
+ propsToast.boutons = null; // Component content = advanced content = should include buttons
150
+ } else {
151
+ cardContent = CardContent;
152
+ }
153
+
112
154
  render = (
113
- <Card {...propsRendu} children={content} {...propsToast} isToast={isToast} />
155
+ <Card {...propsRendu} {...propsToast} isToast={isToast}>
156
+ {cardContent}
157
+ </Card>
114
158
  )
115
159
 
116
- // toast.show( import('./modalSupprimer') )
117
- // toast.show( ToastSupprimer )
160
+ // modal.show( ToastSupprimer )
161
+ // -> Content is a component rendering a Card
118
162
  } else {
119
163
 
120
- let DialogCard;
121
- if (Content.constructor === Promise) {
122
- DialogCard = (await Content).default;
123
- } else {
124
- DialogCard = Content as typeof Card;
125
- }
126
-
127
164
  render = (
128
- <DialogCard {...propsRendu} isToast={isToast} />
165
+ <Content {...propsRendu} isToast={isToast} />
129
166
  )
130
-
131
167
  }
132
168
 
133
169
  // Chargeur de données
@@ -27,6 +27,7 @@ export type Props = {
27
27
  cover?: string,
28
28
  icon?: ComponentChild,
29
29
  title?: string | ComponentChild,
30
+ className?: string,
30
31
 
31
32
  children?: ComponentChild,
32
33
  isToast?: boolean,
@@ -49,6 +50,7 @@ export default ({
49
50
  cover,
50
51
  icon,
51
52
  title,
53
+ className = '',
52
54
 
53
55
  children,
54
56
  isToast,
@@ -149,7 +151,7 @@ export default ({
149
151
 
150
152
  </div>
151
153
  ) : (
152
- <div class={"card pd-2 col al-top"} style={width === undefined
154
+ <div class={"card pd-2 col al-top " + className} style={width === undefined
153
155
  ? {}
154
156
  : { minWidth: width + "px", maxWidth: width + "px" }
155
157
  }>
@@ -78,9 +78,8 @@
78
78
  > .card {
79
79
 
80
80
  position: relative;
81
- max-height: 80vh;
82
81
  min-width: 300px;
83
- max-height: 100vh;
82
+ max-height: 90vh;
84
83
  box-shadow: none;
85
84
  overflow-y: auto;
86
85
 
@@ -39,6 +39,7 @@ export type Props = (
39
39
  enableSearch?: boolean,
40
40
  required?: boolean,
41
41
  noneSelection?: false | string,
42
+ addNew?: (search?: string) => Promise<Choice>
42
43
  }
43
44
 
44
45
  type SelectorProps = Props & {
@@ -69,6 +69,7 @@ export default (props: Props) => {
69
69
  onChange: onChangeCallback,
70
70
  multiple,
71
71
  dropdown,
72
+ addNew,
72
73
  ...otherProps
73
74
  } = props;
74
75
 
@@ -148,6 +149,17 @@ export default (props: Props) => {
148
149
  }
149
150
  }
150
151
 
152
+ const clickAddNew = () => addNew(search.keywords).then( newItem => {
153
+
154
+ if (!newItem)
155
+ return;
156
+
157
+ onChange( current => multiple
158
+ ? [...(current || []), newItem]
159
+ : newItem
160
+ )
161
+ })
162
+
151
163
  /*----------------------------------
152
164
  - RENDER
153
165
  ----------------------------------*/
@@ -156,10 +168,13 @@ export default (props: Props) => {
156
168
 
157
169
  const Search = enableSearch && (
158
170
  <Input
171
+ icon="search"
159
172
  placeholder="Type your search here"
160
173
  value={search.keywords}
161
174
  onChange={keywords => setSearch(s => ({ ...s, loading: true, keywords }))}
162
175
  inputRef={refInputSearch}
176
+ wrapper={false}
177
+ className="bg white"
163
178
  />
164
179
  )
165
180
 
@@ -167,13 +182,15 @@ export default (props: Props) => {
167
182
  <InputWrapper {...props}>
168
183
  {dropdown ? (
169
184
  <Popover {...(dropdown === true ? {
170
- width: '200px'
185
+ width: '200px',
171
186
  } : dropdown)} content={(
172
- <div class="card bg white col al-top">
187
+ <div class="bg white col al-top">
173
188
 
174
- {Search}
189
+ <div class="bb-1" style={{ position: 'sticky', top: 0, zIndex: 5 }}>
190
+ {Search}
191
+ </div>
175
192
 
176
- {selectedItems.length !== 0 && (
193
+ {(multiple && selectedItems.length !== 0) && (
177
194
  <ul class="row al-left wrap sp-05">
178
195
  {selectedItems.map( choice => (
179
196
  <ChoiceElement format='badge' choice={choice}
@@ -191,7 +208,7 @@ export default (props: Props) => {
191
208
  <i src="spin" />
192
209
  </div>
193
210
  ) : (
194
- <ul class="menu col">
211
+ <ul class="menu col">
195
212
  {choices.map( choice => (
196
213
  <ChoiceElement format='list' choice={choice}
197
214
  currentList={currentList}
@@ -202,6 +219,14 @@ export default (props: Props) => {
202
219
  ))}
203
220
  </ul>
204
221
  )}
222
+
223
+ {addNew && (
224
+ <div class="col" style={{ position: 'sticky', bottom: '0px', zIndex: 5 }}>
225
+ <Button type="primary" icon="plus" onClick={clickAddNew}>
226
+ Add new
227
+ </Button>
228
+ </div>
229
+ )}
205
230
  </div>
206
231
  )} state={popoverState}>
207
232
  <Button type="secondary" icon={icon} iconR="chevron-down" {...otherProps}>
@@ -116,16 +116,16 @@ export default (props: Props & InputBaseProps<{}>) => {
116
116
  contentEditable={
117
117
  <ContentEditable
118
118
  className="editor-input"
119
- aria-placeholder={title}
119
+ aria-placeholder={"Type text here ..."}
120
120
  placeholder={
121
- <div className="editor-placeholder">{title}</div>
121
+ <div className="editor-placeholder">Type text here ...</div>
122
122
  }
123
123
  />
124
124
  }
125
125
  ErrorBoundary={LexicalErrorBoundary}
126
126
  />
127
127
  <HistoryPlugin />
128
- <AutoFocusPlugin />
128
+ {/* <AutoFocusPlugin /> */}
129
129
  <OnChangePlugin onChange={onChange} />
130
130
  <ValueControlPlugin props={props} value={value} />
131
131
  </div>
@@ -51,7 +51,7 @@ export default (props: Props & InputBaseProps<string> & TInputElementProps) => {
51
51
 
52
52
  let {
53
53
  // Decoration
54
- icon, prefix, suffix, iconR, required, size, className = '',
54
+ icon, prefix, suffix, iconR, placeholder, size, className = '',
55
55
  // State
56
56
  inputRef, errors,
57
57
  // Behavior
@@ -181,7 +181,7 @@ export default (props: Props & InputBaseProps<string> & TInputElementProps) => {
181
181
 
182
182
  <Tag {...fieldProps}
183
183
 
184
- placeholder={props.title}
184
+ placeholder={placeholder || props.title}
185
185
 
186
186
  // @ts-ignore: Property 'ref' does not exist on type 'IntrinsicAttributes'
187
187
  ref={refInput}
@@ -225,8 +225,6 @@ export default abstract class AuthService<
225
225
 
226
226
  this.config.debug && console.warn(LogPrefix, `Check auth, role = ${role}. Current user =`, user?.name);
227
227
 
228
- console.log({ entity, role, motivation });
229
-
230
228
  if (user === undefined) {
231
229
 
232
230
  throw new Error(`request.user has not been decoded.`);
@@ -256,7 +256,7 @@ export default class SQL extends Service<Config, Hooks, Application, Services> {
256
256
  }
257
257
 
258
258
  public equalities = (data: TObjetDonnees, keys = Object.keys(data)) =>
259
- keys.map(k => '' + k + ' = ' + mysql.escape( data[k] ))
259
+ keys.map(k => '' + k + ' = ' + this.esc( data[k] ))
260
260
 
261
261
  /*----------------------------------
262
262
  - OPERATIONS: LOW LEVELf