Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""Types of values in related tables.""" 

2 

3from bson.objectid import ObjectId 

4 

5from config import Config as C, Names as N 

6from control.utils import pick as G, E 

7from control.html import HtmlElements as H 

8from control.typ.base import TypeBase 

9 

10 

11CT = C.tables 

12CW = C.web 

13 

14Qq = H.icon(CW.unknown[N.generic], asChar=True) 

15QQ = H.icon(CW.unknown[N.generic]) 

16 

17ACTUAL_TABLES = set(CT.actualTables) 

18 

19 

20def castObjectId(value): 

21 """Try to cast the value as an ObjectId. 

22 Paramaters 

23 ---------- 

24 value:string 

25 The value to cast, normally a string representation of a BSON object id. 

26 

27 Returns 

28 ------- 

29 objectId | None 

30 The corresponding BSON object id if the input is a valid representation of 

31 such an id, otherwise `None`. 

32 """ 

33 

34 try: 

35 oValue = ObjectId(value) 

36 except Exception: 

37 oValue = None 

38 return oValue 

39 

40 

41class Related(TypeBase): 

42 """Base class for types with values in other tables.""" 

43 

44 needsContext = True 

45 

46 def __init__(self, context): 

47 """## Initialization 

48 

49 Parameters 

50 ---------- 

51 context: object 

52 See below. 

53 """ 

54 

55 self.context = context 

56 """*object* A `control.context.Context` singleton. 

57 """ 

58 

59 def normalize(self, strVal): 

60 return strVal 

61 

62 def toDisplay(self, val, markup=True): 

63 result = self.title(eid=val, markup=markup) 

64 return result[1] if markup else result 

65 

66 def titleStr(self, record, markup=True, **kwargs): 

67 valBare = ( 

68 G(record, N.title) or G(record, N.rep) or (E if markup is None else Qq) 

69 ) 

70 return valBare if markup is None else H.he(valBare) 

71 

72 def titleHint(self, record): 

73 return None 

74 

75 def title(self, record=None, eid=None, markup=False, active=None, **kwargs): 

76 """Generate a title for a related record. 

77 

78 Parameters 

79 ---------- 

80 record: dict, optional `None` 

81 The record for which to generate a title. 

82 eid: ObjectId, optional `None` 

83 If `record` is not passed, use this to retrieve the full record. 

84 markup: boolean 

85 If true, generate the title in HTML markup, otherwise as a plain string. 

86 active: ObjectId, optional `None` 

87 If passed, is is the id of the currently *active* record, the one 

88 that the current user is interacting with. 

89 

90 Returns 

91 ------- 

92 string(html) 

93 """ 

94 

95 if record is None and eid is None: 95 ↛ 96line 95 didn't jump to line 96, because the condition on line 95 was never true

96 return None if markup is None else (QQ, QQ) if markup else Qq 

97 

98 table = self.name 

99 

100 if record is None: 

101 context = self.context 

102 record = context.getItem(table, eid) 

103 

104 titleStr = self.titleStr(record, markup=markup, **kwargs) 

105 titleHint = self.titleHint(record) 

106 

107 if markup: 

108 if eid is None: 108 ↛ 109line 108 didn't jump to line 109, because the condition on line 108 was never true

109 eid = G(record, N._id) 

110 

111 inActualCls = self.inActualCls(record) 

112 atts = dict(cls=f"tag medium {inActualCls}") 

113 if titleHint: 113 ↛ 114line 113 didn't jump to line 114, because the condition on line 113 was never true

114 atts[N.title] = titleHint 

115 

116 href = f"""/{table}/item/{eid}""" 

117 titleFormatted = H.a(titleStr, href, target=N._blank, **atts) 

118 return (titleStr, titleFormatted) 

119 else: 

120 return titleStr 

121 

122 def inActualCls(self, record): 

123 """Get a CSS class name for a record based on whether it is *actual*. 

124 

125 Actual records belong to the current `package`, a record that specifies 

126 which contribution types, and criteria are currently part of the workflow. 

127 

128 Parameters 

129 ---------- 

130 record: dict 

131 

132 Returns 

133 ------- 

134 string 

135 `inactual` if the record is not actual, else the empty string. 

136 """ 

137 

138 table = self.name 

139 

140 isActual = ( 

141 table not in ACTUAL_TABLES 

142 or not record 

143 or G(record, N.actual, default=False) 

144 ) 

145 return E if isActual else "inactual"