A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/signumsoftware/framework/commit/3ba48fae1456207992abadf74075bb05502507f5 below:

add EntityAccordion.tsx · signumsoftware/framework@3ba48fa · GitHub

1 +

import * as React from 'react'

2 +

import { classes } from '../Globals'

3 +

import * as Navigator from '../Navigator'

4 +

import { TypeContext } from '../TypeContext'

5 +

import { ModifiableEntity, Lite, Entity, EntityControlMessage, getToString, isLite } from '../Signum.Entities'

6 +

import { EntityBaseController } from './EntityBase'

7 +

import { EntityListBaseController, EntityListBaseProps, DragConfig, MoveConfig } from './EntityListBase'

8 +

import { RenderEntity } from './RenderEntity'

9 +

import { newMListElement } from '../Signum.Entities';

10 +

import { tryGetTypeInfos, getTypeInfo } from '../Reflection';

11 +

import { useController } from './LineBase'

12 +

import { TypeBadge } from './AutoCompleteConfig'

13 +

import { Accordion } from 'react-bootstrap'

14 +

import { useForceUpdate } from '../Hooks'

15 +

import { AccordionEventKey } from 'react-bootstrap/esm/AccordionContext'

16 + 17 +

export interface EntityAccordionProps extends EntityListBaseProps {

18 +

createAsLink?: boolean | ((er: EntityAccordionController) => React.ReactElement<any>);

19 +

avoidFieldSet?: boolean;

20 +

createMessage?: string;

21 +

getTitle?: (ctx: TypeContext<any /*T*/>) => React.ReactChild;

22 +

itemExtraButtons?: (er: EntityListBaseController<EntityListBaseProps>, index: number) => React.ReactElement<any>;

23 +

initialSelectedIndex?: number | null;

24 +

selectedIndex?: number | null;

25 +

onSelectTab?: (newIndex: number | null) => void;

26 +

}

27 + 28 +

function isControlled(p: EntityAccordionProps) {

29 + 30 +

if ((p.selectedIndex !== undefined) != (p.onSelectTab !== undefined))

31 +

throw new Error("selectedIndex and onSelectTab should be set together");

32 + 33 +

return p.selectedIndex != null;

34 +

}

35 + 36 +

export class EntityAccordionController extends EntityListBaseController<EntityAccordionProps> {

37 + 38 +

selectedIndex!: number | null;

39 +

setSelectedIndex!: (index: number | null) => void;

40 +

initialIsControlled!: boolean;

41 + 42 +

init(p: EntityAccordionProps) {

43 +

super.init(p);

44 + 45 +

this.initialIsControlled = React.useMemo(() => isControlled(p), []);

46 +

const currentIsControlled = isControlled(p);

47 +

if (currentIsControlled != this.initialIsControlled)

48 +

throw new Error(`selectedIndex was isControlled=${this.initialIsControlled} but now is ${currentIsControlled}`);

49 + 50 +

if (!this.initialIsControlled) {

51 +

[this.selectedIndex, this.setSelectedIndex] = React.useState<number | null>(p.initialSelectedIndex ?? null);

52 +

} else {

53 +

this.selectedIndex = p.selectedIndex!;

54 +

this.setSelectedIndex = p.onSelectTab!;

55 +

}

56 +

}

57 + 58 +

getDefaultProps(p: EntityAccordionProps) {

59 +

super.getDefaultProps(p);

60 +

p.viewOnCreate = false;

61 +

p.createAsLink = true;

62 +

}

63 + 64 +

addElement(entityOrLite: Lite<Entity> | ModifiableEntity) {

65 + 66 +

if (isLite(entityOrLite) != (this.props.type!.isLite || false))

67 +

throw new Error("entityOrLite should be already converted");

68 + 69 +

const list = this.props.ctx.value!;

70 +

list.push(newMListElement(entityOrLite));

71 +

this.setSelectedIndex(list.length - 1);

72 +

this.setValue(list);

73 +

}

74 +

}

75 + 76 + 77 +

export const EntityAccordion = React.forwardRef(function EntityAccordion(props: EntityAccordionProps, ref: React.Ref<EntityAccordionController>) {

78 +

var c = useController(EntityAccordionController, props, ref);

79 +

var p = c.props;

80 + 81 +

if (c.isHidden)

82 +

return null;

83 + 84 +

let ctx = p.ctx;

85 + 86 +

if (p.avoidFieldSet == true)

87 +

return (

88 +

<div className={classes("sf-accordion-field sf-control-container", ctx.errorClassBorder)}

89 +

{...{ ...c.baseHtmlAttributes(), ...p.formGroupHtmlAttributes, ...ctx.errorAttributes() }}>

90 +

{renderButtons()}

91 +

{renderAccordion()}

92 +

</div>

93 +

);

94 + 95 +

return (

96 +

<fieldset className={classes("sf-accordion-field sf-control-container", ctx.errorClass)}

97 +

{...{ ...c.baseHtmlAttributes(), ...c.props.formGroupHtmlAttributes, ...ctx.errorAttributes() }}>

98 +

<legend>

99 +

<div>

100 +

<span>{p.labelText}</span>

101 +

{renderButtons()}

102 +

</div>

103 +

</legend>

104 +

{renderAccordion()}

105 +

</fieldset>

106 +

);

107 + 108 + 109 +

function renderButtons() {

110 +

const buttons = (

111 +

<span className="float-end">

112 +

{p.extraButtonsBefore && p.extraButtonsBefore(c)}

113 +

{p.createAsLink == false && c.renderCreateButton(false, p.createMessage)}

114 +

{c.renderFindButton(false)}

115 +

{p.extraButtonsAfter && p.extraButtonsAfter(c)}

116 +

</span>

117 +

);

118 + 119 +

return EntityBaseController.hasChildrens(buttons) ? buttons : undefined;

120 +

}

121 + 122 +

function handleSelectTab(eventKey: AccordionEventKey | null) {

123 +

var num = eventKey == null ? null: parseInt(eventKey as string);

124 +

c.setSelectedIndex(num);

125 +

}

126 + 127 +

function renderAccordion() {

128 +

const readOnly = ctx.readOnly;

129 +

const showType = tryGetTypeInfos(ctx.propertyRoute!.typeReference().name).length > 1;

130 +

return (

131 +

<Accordion className="sf-accordion-elements" activeKey={c.selectedIndex?.toString()} onSelect={handleSelectTab}>

132 +

{

133 +

c.getMListItemContext(ctx).map((mlec, i) => (

134 +

<EntityAccordionElement key={c.keyGenerator.getKey(mlec.value)}

135 +

onRemove={c.canRemove(mlec.value) && !readOnly ? e => c.handleRemoveElementClick(e, mlec.index!) : undefined}

136 +

ctx={mlec}

137 +

move={c.canMove(mlec.value) && p.moveMode == "MoveIcons" && !readOnly ? c.getMoveConfig(false, mlec.index!, "v") : undefined}

138 +

drag={c.canMove(mlec.value) && p.moveMode == "DragIcon" && !readOnly ? c.getDragConfig(mlec.index!, "v") : undefined}

139 +

itemExtraButtons={p.itemExtraButtons ? (() => p.itemExtraButtons!(c, mlec.index!)) : undefined}

140 +

getComponent={p.getComponent}

141 +

getViewPromise={p.getViewPromise}

142 +

getTitle={p.getTitle}

143 +

title={showType ? <TypeBadge entity={mlec.value} /> : undefined} />))

144 +

}

145 +

{

146 +

p.createAsLink && p.create && !readOnly &&

147 +

(typeof p.createAsLink == "function" ? p.createAsLink(c) :

148 +

<a href="#" title={ctx.titleLabels ? EntityControlMessage.Create.niceToString() : undefined}

149 +

className="sf-line-button sf-create"

150 +

onClick={c.handleCreateClick}>

151 +

{EntityBaseController.createIcon}&nbsp;{p.createMessage ?? EntityControlMessage.Create.niceToString()}

152 +

</a>)

153 +

}

154 +

</Accordion>

155 +

);

156 +

}

157 +

});

158 + 159 + 160 +

export interface EntityAccordionElementProps {

161 +

ctx: TypeContext<Lite<Entity> | ModifiableEntity>;

162 +

getComponent?: (ctx: TypeContext<ModifiableEntity>) => React.ReactElement<any>;

163 +

getViewPromise?: (entity: ModifiableEntity) => undefined | string | Navigator.ViewPromise<ModifiableEntity>;

164 +

getTitle?: (ctx: TypeContext<any /*T*/>) => React.ReactChild;

165 +

onRemove?: (event: React.MouseEvent<any>) => void;

166 +

move?: MoveConfig;

167 +

drag?: DragConfig;

168 +

title?: React.ReactElement<any>;

169 +

itemExtraButtons?: () => React.ReactElement<any>;

170 +

}

171 + 172 +

export function EntityAccordionElement({ ctx, getComponent, getViewPromise, onRemove, move, drag, itemExtraButtons, title, getTitle }: EntityAccordionElementProps)

173 +

{

174 + 175 +

const forceUpdate = useForceUpdate();

176 + 177 +

return (

178 +

<Accordion.Item className={classes(drag?.dropClass, "sf-accordion-element")} eventKey={ctx.index!.toString()}

179 +

onDragEnter={drag?.onDragOver}

180 +

onDragOver={drag?.onDragOver}

181 +

onDrop={drag?.onDrop}>

182 + 183 +

<Accordion.Header {...EntityListBaseController.entityHtmlAttributes(ctx.value)}>

184 +

<div className="d-flex align-items-center flex-grow-1">

185 +

{onRemove && <a href="#" className={classes("sf-line-button", "sf-remove")}

186 +

onClick={onRemove}

187 +

title={ctx.titleLabels ? EntityControlMessage.Remove.niceToString() : undefined}>

188 +

{EntityListBaseController.removeIcon}

189 +

</a>}

190 +

&nbsp;

191 +

{move?.renderMoveUp()}

192 +

{move?.renderMoveDown()}

193 +

{drag && <a href="#" className={classes("sf-line-button", "sf-move")}

194 +

draggable={true}

195 +

onDragStart={drag.onDragStart}

196 +

onDragEnd={drag.onDragEnd}

197 +

onKeyDown={drag.onKeyDown}

198 +

title={drag.title}>

199 +

{EntityListBaseController.moveIcon}

200 +

</a>}

201 +

{itemExtraButtons && itemExtraButtons()}

202 +

{'\xa0'}

203 +

{getTitle ? getTitle(ctx) : getToString(ctx.value)}

204 +

</div>

205 +

</Accordion.Header>

206 +

<Accordion.Body>

207 +

<RenderEntity ctx={ctx} getComponent={getComponent} getViewPromise={getViewPromise} onRefresh={forceUpdate} />

208 +

</Accordion.Body>

209 +

</Accordion.Item>

210 +

);

211 +

}


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4