Skip to content

Commit 4fcdba3

Browse files
committed
initial generic Lines
1 parent 3d4cb33 commit 4fcdba3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1131
-991
lines changed

Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequestLogic.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public static ResetPasswordRequestEntity ResetPasswordRequest(UserEntity user)
163163

164164
return new ResetPasswordRequestEntity
165165
{
166-
Code = MyRandom.Current.NextString(32),
166+
Code = Random.Shared.NextString(32),
167167
User = user,
168168
RequestDate = Clock.Now,
169169
}.Save();

Extensions/Signum.Authorization/AuthAdminClient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ export function queryIsFindable(queryKey: string, fullScreen: boolean) {
225225
return allowed == "Allow" || allowed == "EmbeddedOnly" && !fullScreen;
226226
}
227227

228-
export function taskAuthorizeProperties(lineBase: LineBaseController<LineBaseProps>, state: LineBaseProps) {
228+
export function taskAuthorizeProperties(lineBase: LineBaseController<LineBaseProps, unknown>, state: LineBaseProps) {
229229
if (state.ctx.propertyRoute &&
230230
state.ctx.propertyRoute.propertyRouteType == "Field") {
231231

Extensions/Signum.Files/Components/FileImageLine.tsx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,18 @@ import { FormGroup } from '@framework/Lines/FormGroup'
55
import * as Services from '@framework/Services'
66
import { ModifiableEntity, Lite, Entity, isLite, isEntity } from '@framework/Signum.Entities'
77
import { IFile, FileTypeSymbol } from '../Signum.Files'
8-
import { EntityBaseProps, EntityBaseController } from '@framework/Lines/EntityBase'
8+
import { EntityBaseProps, EntityBaseController, Aprox, AsEntity } from '@framework/Lines/EntityBase'
99
import { FileDownloaderConfiguration } from './FileDownloader'
1010
import { FileUploader } from './FileUploader'
1111
import { FileImage } from './FileImage';
1212
import "./Files.css"
1313
import { FetchAndRemember } from '@framework/Lines'
14-
import { useController } from '@framework/Lines/LineBase'
14+
import { genericForwardRef, useController } from '@framework/Lines/LineBase'
1515
import { ImageModal } from './ImageModal'
1616

1717
export { FileTypeSymbol };
1818

19-
export interface FileImageLineProps extends EntityBaseProps {
20-
ctx: TypeContext<ModifiableEntity & IFile | Lite<IFile & Entity> | undefined | null>;
19+
export interface FileImageLineProps<V extends ModifiableEntity & IFile | Lite<IFile & Entity> | null> extends EntityBaseProps<V> {
2120
dragAndDrop?: boolean;
2221
dragAndDropMessage?: string;
2322
fileType?: FileTypeSymbol;
@@ -29,9 +28,9 @@ export interface FileImageLineProps extends EntityBaseProps {
2928
}
3029

3130

32-
export class FileImageLineController extends EntityBaseController<FileImageLineProps> {
31+
export class FileImageLineController<V extends ModifiableEntity & IFile | Lite<IFile & Entity> | null> extends EntityBaseController<FileImageLineProps<V>, V>{
3332

34-
getDefaultProps(state: FileImageLineProps) {
33+
getDefaultProps(state: FileImageLineProps<V>) {
3534

3635
super.getDefaultProps(state);
3736

@@ -49,13 +48,13 @@ export class FileImageLineController extends EntityBaseController<FileImageLineP
4948
}
5049
}
5150

52-
handleFileLoaded = (file: IFile & ModifiableEntity) =>{
53-
this.convert(file)
51+
handleFileLoaded = (file: IFile & ModifiableEntity) => {
52+
this.convert(file as Aprox<V>)
5453
.then(f => this.setValue(f));
5554
}
5655
}
5756

58-
export const FileImageLine = React.forwardRef(function FileImageLine(props: FileImageLineProps, ref: React.Ref<FileImageLineController>) {
57+
export const FileImageLine = genericForwardRef(function FileImageLine<V extends ModifiableEntity & IFile | Lite<IFile & Entity> | null>(props: FileImageLineProps<V>, ref: React.Ref<FileImageLineController<V>>) {
5958
const c = useController(FileImageLineController, props, ref);
6059
const p = c.props;
6160

@@ -94,7 +93,7 @@ export const FileImageLine = React.forwardRef(function FileImageLine(props: File
9493
<FetchAndRemember lite={val! as Lite<IFile & Entity>}>{file => <FileImage file={file} style={{ maxWidth: "100px" }} onClick={e => ImageModal.show(file as IFile & ModifiableEntity, e)} {...p.imageHtmlAttributes} />}</FetchAndRemember> :
9594
<FileImage file={val as IFile & ModifiableEntity} style={{ maxWidth: "100px" }} onClick={e => ImageModal.show(val as IFile & ModifiableEntity, e)} {...p.imageHtmlAttributes} ajaxOptions={p.ajaxOptions} />;
9695

97-
const removeButton = c.renderRemoveButton(true, val);
96+
const removeButton = c.renderRemoveButton(true);
9897

9998
if (removeButton == null)
10099
return content;
@@ -108,8 +107,8 @@ export const FileImageLine = React.forwardRef(function FileImageLine(props: File
108107
}
109108
});
110109

111-
FileImageLine.defaultProps = {
110+
(FileImageLine as any).defaultProps = {
112111
accept: "image/*",
113112
dragAndDrop: true
114-
};
113+
} as FileImageLineProps<any>;
115114

Extensions/Signum.Files/Components/FileLine.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
import * as React from 'react'
22
import { classes } from '@framework/Globals'
33
import { TypeContext } from '@framework/TypeContext'
4-
import { getSymbol } from '@framework/Reflection'
4+
import { Type, getSymbol } from '@framework/Reflection'
55
import { FormGroup } from '@framework/Lines/FormGroup'
66
import { ModifiableEntity, Lite, Entity, getToString, } from '@framework/Signum.Entities'
77
import { IFile, FileTypeSymbol } from '../Signum.Files'
8-
import { EntityBaseProps, EntityBaseController } from '@framework/Lines/EntityBase'
8+
import { EntityBaseProps, EntityBaseController, AsEntity, Aprox } from '@framework/Lines/EntityBase'
99
import { FileDownloader, FileDownloaderConfiguration, DownloadBehaviour } from './FileDownloader'
1010
import { FileUploader } from './FileUploader'
1111

1212
import "./Files.css"
13-
import { useController } from '@framework/Lines/LineBase'
13+
import { genericForwardRef, useController } from '@framework/Lines/LineBase'
1414

1515
export { FileTypeSymbol };
1616

17-
export interface FileLineProps extends EntityBaseProps {
18-
ctx: TypeContext<ModifiableEntity & IFile | Lite<IFile & Entity> | undefined | null>;
17+
export interface FileLineProps<V extends ModifiableEntity & IFile | Lite<IFile & Entity> | null> extends EntityBaseProps<V> {
1918
download?: DownloadBehaviour;
2019
showFileIcon?: boolean;
2120
dragAndDrop?: boolean;
2221
dragAndDropMessage?: string;
2322
fileType?: FileTypeSymbol;
2423
accept?: string;
25-
configuration?: FileDownloaderConfiguration<IFile>;
24+
configuration?: FileDownloaderConfiguration<AsEntity<V>>;
2625
maxSizeInBytes?: number;
2726
}
2827

2928

30-
export class FileLineController extends EntityBaseController<FileLineProps>{
29+
export class FileLineController<V extends ModifiableEntity & IFile | Lite<IFile & Entity> | null> extends EntityBaseController<FileLineProps<V>, V>{
3130

32-
getDefaultProps(state: FileLineProps) {
31+
getDefaultProps(state: FileLineProps<V>) {
3332

3433
super.getDefaultProps(state);
3534

@@ -50,12 +49,12 @@ export class FileLineController extends EntityBaseController<FileLineProps>{
5049

5150
handleFileLoaded = (file: IFile & ModifiableEntity) => {
5251

53-
this.convert(file)
52+
this.convert(file as Aprox<V>)
5453
.then(f => this.setValue(f));
5554
}
5655
}
5756

58-
export const FileLine = React.memo(React.forwardRef(function FileLine(props: FileLineProps, ref: React.Ref<FileLineController>) {
57+
export const FileLine = React.memo(genericForwardRef(function FileLine<V extends ModifiableEntity & IFile | Lite<IFile & Entity> | null>(props: FileLineProps<V>, ref: React.Ref<FileLineController<V>>) {
5958
const c = useController(FileLineController, props, ref);
6059
const p = c.props;
6160

@@ -95,7 +94,7 @@ export const FileLine = React.memo(React.forwardRef(function FileLine(props: Fil
9594
const content = p.download == "None" ?
9695
<span className={classes(ctx.formControlClass, "file-control")} > {getToString(val)}</span > :
9796
<FileDownloader
98-
configuration={p.configuration}
97+
configuration={p.configuration as FileDownloaderConfiguration<IFile>}
9998
download={p.download}
10099
showFileIcon={p.showFileIcon}
101100
entityOrLite={val}
@@ -104,7 +103,7 @@ export const FileLine = React.memo(React.forwardRef(function FileLine(props: Fil
104103
const buttons =
105104
<>
106105
{c.props.extraButtonsBefore && c.props.extraButtonsBefore(c)}
107-
{c.renderRemoveButton(true, val)}
106+
{c.renderRemoveButton(true)}
108107
{c.props.extraButtons && c.props.extraButtons(c)}
109108
</>;
110109

@@ -124,4 +123,4 @@ export const FileLine = React.memo(React.forwardRef(function FileLine(props: Fil
124123
download: "ViewOrSave",
125124
dragAndDrop: true,
126125
showFileIcon: true
127-
} as FileLineProps;
126+
} as FileLineProps<any>;

Extensions/Signum.Files/Components/MultiFileImageLine.tsx

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react'
22
import { classes } from '@framework/Globals'
33
import * as Constructor from '@framework/Constructor'
44
import { TypeContext } from '@framework/TypeContext'
5-
import { getSymbol } from '@framework/Reflection'
5+
import { Type, getSymbol } from '@framework/Reflection'
66
import { FormGroup } from '@framework/Lines/FormGroup'
77
import { ModifiableEntity, Lite, Entity, MList, SearchMessage, EmbeddedEntity, EntityControlMessage, getToString } from '@framework/Signum.Entities'
88
import { IFile, FileTypeSymbol } from '../Signum.Files'
@@ -14,13 +14,13 @@ import "./Files.css"
1414
import { EntityListBaseController, EntityListBaseProps } from '@framework/Lines/EntityListBase'
1515
import { FetchAndRemember } from '@framework/Lines'
1616
import { FileImage } from './FileImage';
17-
import { useController } from '@framework/Lines/LineBase'
17+
import { genericForwardRef, useController } from '@framework/Lines/LineBase'
1818
import { ImageModal } from './ImageModal'
19+
import { Aprox, AsEntity } from '@framework/Lines/EntityBase'
1920

2021
export { FileTypeSymbol };
2122

22-
interface MultiFileImageLineProps extends EntityListBaseProps {
23-
ctx: TypeContext<MList<ModifiableEntity & IFile | Lite<IFile & Entity> | EmbeddedEntity>>;
23+
interface MultiFileImageLineProps<V extends ModifiableEntity/* & IFile*/ | Lite</*IFile & */Entity>> extends EntityListBaseProps<V> {
2424
download?: DownloadBehaviour;
2525
dragAndDrop?: boolean;
2626
dragAndDropMessage?: string;
@@ -29,13 +29,13 @@ interface MultiFileImageLineProps extends EntityListBaseProps {
2929
configuration?: FileDownloaderConfiguration<IFile>;
3030
imageHtmlAttributes?: React.ImgHTMLAttributes<HTMLImageElement>;
3131
maxSizeInBytes?: number;
32-
getFile?: (ectx: EmbeddedEntity) => ModifiableEntity & IFile | Lite<IFile & Entity>;
33-
createEmbedded?: (file: ModifiableEntity & IFile) => Promise<EmbeddedEntity>;
32+
getFile?: (ectx: V) => ModifiableEntity & IFile | Lite<IFile & Entity>;
33+
createEmbedded?: (file: ModifiableEntity & IFile | Lite<IFile & Entity>) => Promise<V>;
3434
}
3535

36-
export class MultiFileImageLineController extends EntityListBaseController<MultiFileImageLineProps> {
36+
export class MultiFileImageLineController<V extends ModifiableEntity /*& IFile*/ | Lite</*IFile & */Entity>> extends EntityListBaseController<MultiFileImageLineProps<V>, V> {
3737

38-
overrideProps(p: MultiFileImageLineProps, overridenProps: MultiFileImageLineProps) {
38+
overrideProps(p: MultiFileImageLineProps<V>, overridenProps: MultiFileImageLineProps<V>) {
3939
super.overrideProps(p, overridenProps);
4040

4141
let pr = p.ctx.propertyRoute;
@@ -68,18 +68,14 @@ export class MultiFileImageLineController extends EntityListBaseController<Multi
6868
this.props.createEmbedded(file)
6969
.then(em => em && this.addElement(em));
7070
else
71-
this.convert(file)
71+
this.convert(file as unknown as Aprox<V>)
7272
.then(f => this.addElement(f));
7373
}
74-
75-
defaultCreate() {
76-
return Constructor.construct(this.props.type!.name);
77-
}
7874
}
7975

80-
export const MultiFileImageLine = React.forwardRef(function MultiFileLine(props: MultiFileImageLineProps, ref: React.Ref<MultiFileImageLineController>) {
76+
export const MultiFileImageLine = genericForwardRef(function MultiFileLine<V extends ModifiableEntity /*& IFile*/ | Lite</*IFile &*/ Entity>>(props: MultiFileImageLineProps<V>, ref: React.Ref<MultiFileImageLineController<V>>) {
8177

82-
const c = useController(MultiFileImageLineController, props, ref);
78+
const c = useController(MultiFileImageLineController<V>, props, ref);
8379
const p = c.props;
8480

8581
if (c.isHidden)
@@ -95,9 +91,9 @@ export const MultiFileImageLine = React.forwardRef(function MultiFileLine(props:
9591
{
9692
c.getMListItemContext(p.ctx.subCtx({ formGroupStyle: "None" })).map(mlec =>
9793
<div className="sf-file-image-container m-2" key={mlec.index}>
98-
{p.getComponent ? p.getComponent(mlec) :
94+
{p.getComponent ? p.getComponent(mlec as TypeContext<AsEntity<V>>) :
9995
p.download == "None" ? <span className={classes(mlec.formControlClass, "file-control")} > {getToString(mlec.value)}</span > :
100-
renderFile(p.getFile ? (mlec as TypeContext<EmbeddedEntity>).subCtx(p.getFile) : mlec as TypeContext<ModifiableEntity & IFile | Lite<IFile & Entity> | undefined | null>)}
96+
renderFile(p.getFile ? mlec.subCtx(p.getFile) : mlec as unknown as TypeContext<ModifiableEntity & IFile | Lite<IFile & Entity>>)}
10197
{!p.ctx.readOnly &&
10298
<a href="#" title={EntityControlMessage.Remove.niceToString()}
10399
className="sf-line-button sf-remove"
@@ -129,20 +125,19 @@ export const MultiFileImageLine = React.forwardRef(function MultiFileLine(props:
129125
);
130126

131127

132-
function renderFile(ctx: TypeContext<ModifiableEntity & IFile | Lite<IFile & Entity> | undefined | null>) {
128+
function renderFile(ctx: TypeContext<ModifiableEntity & IFile | Lite<IFile & Entity>>) {
133129
const val = ctx.value!;
134130

135131
return ctx.propertyRoute!.typeReference().isLite ?
136132
<FetchAndRemember lite={val! as Lite<IFile & Entity>}>{file => <FileImage file={file} {...p.imageHtmlAttributes} style={{ maxWidth: "100px" }} />}</FetchAndRemember> :
137133
<FileImage file={val as IFile & ModifiableEntity} {...p.imageHtmlAttributes} style={{ maxWidth: "100px" }} onClick={e => ImageModal.show(val as IFile & ModifiableEntity, e)} />;
138134
}
139-
140135
});
141136

142137
(MultiFileImageLine as any).defaultProps = {
143138
download: "SaveAs",
144139
dragAndDrop: true
145-
} as MultiFileImageLineProps;
140+
} as MultiFileImageLineProps<any>;
146141

147142

148143

Extensions/Signum.Files/Components/MultiFileLine.tsx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react'
22
import { classes } from '@framework/Globals'
33
import * as Constructor from '@framework/Constructor'
44
import { ButtonBarElement, TypeContext } from '@framework/TypeContext'
5-
import { getSymbol } from '@framework/Reflection'
5+
import { Type, getSymbol } from '@framework/Reflection'
66
import { FormGroup } from '@framework/Lines/FormGroup'
77
import { ModifiableEntity, Lite, Entity, MList, SearchMessage, EntityControlMessage, EmbeddedEntity, MListElement, getToString } from '@framework/Signum.Entities'
88
import { IFile, FileTypeSymbol } from '../Signum.Files'
@@ -11,13 +11,13 @@ import { FileUploader } from './FileUploader'
1111
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
1212
import "./Files.css"
1313
import { EntityListBaseController, EntityListBaseProps } from '@framework/Lines/EntityListBase'
14-
import { useController } from '@framework/Lines/LineBase'
14+
import { genericForwardRef, useController } from '@framework/Lines/LineBase'
1515
import { EntityBaseController } from '@framework/Lines'
16+
import { Aprox, AsEntity } from '@framework/Lines/EntityBase'
1617

1718
export { FileTypeSymbol };
1819

19-
interface MultiFileLineProps extends EntityListBaseProps {
20-
ctx: TypeContext<MList<ModifiableEntity & IFile | Lite<IFile & Entity> | ModifiableEntity /*implement getFile create Embedded*/>>;
20+
interface MultiFileLineProps<V extends ModifiableEntity/* & IFile*/ | Lite</*IFile & */Entity>> extends EntityListBaseProps<V> {
2121
download?: DownloadBehaviour;
2222
showFileIcon?: boolean;
2323
dragAndDrop?: boolean;
@@ -26,13 +26,13 @@ interface MultiFileLineProps extends EntityListBaseProps {
2626
accept?: string;
2727
configuration?: FileDownloaderConfiguration<IFile>;
2828
maxSizeInBytes?: number;
29-
getFileFromElement?: (e: any /*ModifiableEntity*/) => ModifiableEntity & IFile | Lite<IFile & Entity>;
30-
createElementFromFile?: (file: ModifiableEntity & IFile) => Promise<ModifiableEntity | undefined>;
29+
getFileFromElement?: (ectx: V) => ModifiableEntity & IFile | Lite<IFile & Entity>;
30+
createElementFromFile?: (file: ModifiableEntity & IFile) => Promise<V>;
3131
}
3232

33-
export class MultiFileLineController extends EntityListBaseController<MultiFileLineProps> {
33+
export class MultiFileLineController<V extends ModifiableEntity /*& IFile*/ | Lite</*IFile & */Entity>> extends EntityListBaseController<MultiFileLineProps<V>, V> {
3434

35-
overrideProps(p: MultiFileLineProps, overridenProps: MultiFileLineProps) {
35+
overrideProps(p: MultiFileLineProps<V>, overridenProps: MultiFileLineProps<V>) {
3636

3737
p.view = EntityBaseController.defaultIsViewable(p.type!, false) && overridenProps.getFileFromElement != null;
3838

@@ -70,15 +70,11 @@ export class MultiFileLineController extends EntityListBaseController<MultiFileL
7070
this.props.createElementFromFile(file)
7171
.then(em => em && this.addElement(em));
7272
else
73-
this.convert(file)
73+
this.convert(file as unknown as Aprox<V>)
7474
.then(f => this.addElement(f));
7575
}
7676

77-
defaultCreate() {
78-
return Constructor.construct(this.props.type!.name);
79-
}
80-
81-
renderElementViewButton(btn: boolean, entity: ModifiableEntity | Lite<Entity>, index: number) {
77+
renderElementViewButton(btn: boolean, entity: V, index: number) {
8278

8379
if (!this.canView(entity))
8480
return undefined;
@@ -94,7 +90,7 @@ export class MultiFileLineController extends EntityListBaseController<MultiFileL
9490
}
9591
}
9692

97-
export const MultiFileLine = React.forwardRef(function MultiFileLine(props: MultiFileLineProps, ref: React.Ref<MultiFileLineController>) {
93+
export const MultiFileLine = genericForwardRef(function MultiFileLine<V extends ModifiableEntity /*& IFile*/ | Lite</*IFile &*/ Entity>>(props: MultiFileLineProps<V>, ref: React.Ref<MultiFileLineController<V>>) {
9894
const c = useController(MultiFileLineController, props, ref);
9995
const p = c.props;
10096

@@ -120,7 +116,7 @@ export const MultiFileLine = React.forwardRef(function MultiFileLine(props: Mult
120116
</a>}
121117
</td>
122118
<td style={{ width: "100%" }}>
123-
{p.getComponent ? p.getComponent(mlec) :
119+
{p.getComponent ? p.getComponent(mlec as TypeContext<AsEntity<V>>) :
124120
p.download == "None" ?
125121
<span className={classes(mlec.formControlClass, "file-control")} >
126122
{getToString(p.getFileFromElement ? p.getFileFromElement(mlec.value) : mlec.value)}
@@ -130,7 +126,7 @@ export const MultiFileLine = React.forwardRef(function MultiFileLine(props: Mult
130126
showFileIcon={p.showFileIcon}
131127
download={p.download}
132128
containerEntity={p.getFileFromElement ? mlec.value as ModifiableEntity : undefined}
133-
entityOrLite={p.getFileFromElement ? p.getFileFromElement(mlec.value as ModifiableEntity) : mlec.value as ModifiableEntity & IFile | Lite<IFile & Entity>}
129+
entityOrLite={p.getFileFromElement ? p.getFileFromElement(mlec.value) : mlec.value as ModifiableEntity & IFile | Lite<IFile & Entity>}
134130
htmlAttributes={{ className: classes(mlec.formControlClass, "file-control") }} />
135131
}
136132
</td>
@@ -165,4 +161,4 @@ export const MultiFileLine = React.forwardRef(function MultiFileLine(props: Mult
165161
download: "ViewOrSave",
166162
showFileIcon: true,
167163
dragAndDrop: true
168-
} as MultiFileLineProps;
164+
} as MultiFileLineProps<any>;

0 commit comments

Comments
 (0)