pict-section-login 0.0.1

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.
Files changed (25) hide show
  1. package/example_applications/custom_login/Custom-Login-Application.js +75 -0
  2. package/example_applications/custom_login/html/index.html +110 -0
  3. package/example_applications/custom_login/package.json +27 -0
  4. package/example_applications/harness_app/Harness-App-Application.js +167 -0
  5. package/example_applications/harness_app/Harness-App-Configuration.json +4 -0
  6. package/example_applications/harness_app/html/index.html +90 -0
  7. package/example_applications/harness_app/package.json +28 -0
  8. package/example_applications/harness_app/providers/PictRouter-HarnessApp.json +24 -0
  9. package/example_applications/harness_app/views/PictView-HarnessApp-Books.js +172 -0
  10. package/example_applications/harness_app/views/PictView-HarnessApp-Dashboard.js +158 -0
  11. package/example_applications/harness_app/views/PictView-HarnessApp-Layout.js +86 -0
  12. package/example_applications/harness_app/views/PictView-HarnessApp-Login.js +58 -0
  13. package/example_applications/harness_app/views/PictView-HarnessApp-TopBar.js +157 -0
  14. package/example_applications/harness_app/views/PictView-HarnessApp-Users.js +188 -0
  15. package/example_applications/oauth_login/OAuth-Login-Application.js +78 -0
  16. package/example_applications/oauth_login/html/index.html +57 -0
  17. package/example_applications/oauth_login/package.json +27 -0
  18. package/example_applications/orator_login/Orator-Login-Application.js +61 -0
  19. package/example_applications/orator_login/html/index.html +51 -0
  20. package/example_applications/orator_login/package.json +27 -0
  21. package/package.json +53 -0
  22. package/source/Pict-Section-Login-DefaultConfiguration.js +265 -0
  23. package/source/Pict-Section-Login.js +533 -0
  24. package/test/Browser_Integration_tests.js +588 -0
  25. package/test/Pict-Section-Login_tests.js +593 -0
@@ -0,0 +1,172 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "HarnessApp-Books",
6
+
7
+ DefaultRenderable: "HarnessApp-Books-Content",
8
+ DefaultDestinationAddress: "#HarnessApp-Content-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ .harnessapp-books h1
14
+ {
15
+ font-size: 1.8rem;
16
+ margin: 0 0 1rem 0;
17
+ color: #264653;
18
+ }
19
+ .harnessapp-books-table
20
+ {
21
+ width: 100%;
22
+ border-collapse: collapse;
23
+ background: #fff;
24
+ border: 1px solid #D4A373;
25
+ border-radius: 6px;
26
+ overflow: hidden;
27
+ box-shadow: 0 2px 8px rgba(38,70,83,0.08);
28
+ }
29
+ .harnessapp-books-table th
30
+ {
31
+ background: #264653;
32
+ color: #FAEDCD;
33
+ padding: 0.6rem 0.75rem;
34
+ text-align: left;
35
+ font-size: 0.8rem;
36
+ font-weight: 600;
37
+ text-transform: uppercase;
38
+ letter-spacing: 0.04em;
39
+ }
40
+ .harnessapp-books-table td
41
+ {
42
+ padding: 0.55rem 0.75rem;
43
+ border-bottom: 1px solid #E8D9C0;
44
+ font-size: 0.85rem;
45
+ color: #264653;
46
+ }
47
+ .harnessapp-books-table tr:nth-child(even) td
48
+ {
49
+ background: #FFF9F0;
50
+ }
51
+ .harnessapp-books-table tr:hover td
52
+ {
53
+ background: #FAEDCD;
54
+ }
55
+ .harnessapp-books-loading
56
+ {
57
+ padding: 2rem;
58
+ text-align: center;
59
+ color: #999;
60
+ font-size: 0.9rem;
61
+ }
62
+ `,
63
+
64
+ Templates:
65
+ [
66
+ {
67
+ Hash: "HarnessApp-Books-Template",
68
+ Template: /*html*/`
69
+ <div class="harnessapp-books">
70
+ <h1>Books</h1>
71
+ <div id="HarnessApp-Books-TableContainer">
72
+ <div class="harnessapp-books-loading">Loading books&hellip;</div>
73
+ </div>
74
+ </div>
75
+ `
76
+ }
77
+ ],
78
+
79
+ Renderables:
80
+ [
81
+ {
82
+ RenderableHash: "HarnessApp-Books-Content",
83
+ TemplateHash: "HarnessApp-Books-Template",
84
+ DestinationAddress: "#HarnessApp-Content-Container",
85
+ RenderMethod: "replace"
86
+ }
87
+ ]
88
+ };
89
+
90
+ class HarnessAppBooksView extends libPictView
91
+ {
92
+ constructor(pFable, pOptions, pServiceHash)
93
+ {
94
+ super(pFable, pOptions, pServiceHash);
95
+ }
96
+
97
+ onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
98
+ {
99
+ this._loadBooks();
100
+ return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
101
+ }
102
+
103
+ _loadBooks()
104
+ {
105
+ fetch('/1.0/Books/FilteredTo/Title~ILK~a/0/25')
106
+ .then((pResponse) =>
107
+ {
108
+ return pResponse.json();
109
+ })
110
+ .then((pData) =>
111
+ {
112
+ let tmpRecords = [];
113
+ if (Array.isArray(pData))
114
+ {
115
+ tmpRecords = pData;
116
+ }
117
+ else if (pData && Array.isArray(pData.Records))
118
+ {
119
+ tmpRecords = pData.Records;
120
+ }
121
+
122
+ this._renderTable(tmpRecords);
123
+ })
124
+ .catch((pError) =>
125
+ {
126
+ this.log.error('Failed to load books: ' + pError.message);
127
+ let tmpContainer = this.services.ContentAssignment.getElement('#HarnessApp-Books-TableContainer');
128
+ if (tmpContainer && tmpContainer.length > 0)
129
+ {
130
+ tmpContainer[0].innerHTML = '<div class="harnessapp-books-loading">Failed to load books. Is the server running?</div>';
131
+ }
132
+ });
133
+ }
134
+
135
+ _renderTable(pRecords)
136
+ {
137
+ let tmpContainer = this.services.ContentAssignment.getElement('#HarnessApp-Books-TableContainer');
138
+ if (!tmpContainer || tmpContainer.length < 1)
139
+ {
140
+ return;
141
+ }
142
+
143
+ if (pRecords.length < 1)
144
+ {
145
+ tmpContainer[0].innerHTML = '<div class="harnessapp-books-loading">No books found.</div>';
146
+ return;
147
+ }
148
+
149
+ let tmpHTML = '<table class="harnessapp-books-table">';
150
+ tmpHTML += '<thead><tr><th>ID</th><th>Title</th><th>Type</th><th>Language</th><th>Year</th></tr></thead>';
151
+ tmpHTML += '<tbody>';
152
+
153
+ for (let i = 0; i < pRecords.length; i++)
154
+ {
155
+ let tmpBook = pRecords[i];
156
+ tmpHTML += '<tr>';
157
+ tmpHTML += '<td>' + (tmpBook.IDBook || '') + '</td>';
158
+ tmpHTML += '<td>' + (tmpBook.Title || '') + '</td>';
159
+ tmpHTML += '<td>' + (tmpBook.Type || '') + '</td>';
160
+ tmpHTML += '<td>' + (tmpBook.Language || '') + '</td>';
161
+ tmpHTML += '<td>' + (tmpBook.PublishDate || '') + '</td>';
162
+ tmpHTML += '</tr>';
163
+ }
164
+
165
+ tmpHTML += '</tbody></table>';
166
+ tmpContainer[0].innerHTML = tmpHTML;
167
+ }
168
+ }
169
+
170
+ module.exports = HarnessAppBooksView;
171
+
172
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,158 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "HarnessApp-Dashboard",
6
+
7
+ DefaultRenderable: "HarnessApp-Dashboard-Content",
8
+ DefaultDestinationAddress: "#HarnessApp-Content-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ .harnessapp-dashboard h1
14
+ {
15
+ font-size: 1.8rem;
16
+ margin: 0 0 0.5rem 0;
17
+ color: #264653;
18
+ }
19
+ .harnessapp-dashboard p
20
+ {
21
+ font-size: 1rem;
22
+ line-height: 1.6;
23
+ color: #555;
24
+ max-width: 640px;
25
+ margin: 0 0 1.5rem 0;
26
+ }
27
+ .harnessapp-dashboard-cards
28
+ {
29
+ display: flex;
30
+ gap: 1.25rem;
31
+ flex-wrap: wrap;
32
+ }
33
+ .harnessapp-dashboard-card
34
+ {
35
+ flex: 1;
36
+ min-width: 220px;
37
+ background: #fff;
38
+ border: 1px solid #D4A373;
39
+ border-top: 4px solid #E76F51;
40
+ border-radius: 6px;
41
+ padding: 1.25rem;
42
+ cursor: pointer;
43
+ transition: box-shadow 0.15s, transform 0.15s;
44
+ box-shadow: 0 2px 8px rgba(38,70,83,0.08);
45
+ }
46
+ .harnessapp-dashboard-card:hover
47
+ {
48
+ box-shadow: 0 4px 16px rgba(38,70,83,0.15);
49
+ transform: translateY(-2px);
50
+ }
51
+ .harnessapp-dashboard-card h3
52
+ {
53
+ margin: 0 0 0.5rem;
54
+ color: #E76F51;
55
+ font-size: 1.05rem;
56
+ }
57
+ .harnessapp-dashboard-card p
58
+ {
59
+ margin: 0;
60
+ font-size: 0.9rem;
61
+ color: #666;
62
+ }
63
+ .harnessapp-dashboard-session-info
64
+ {
65
+ background: #264653;
66
+ color: #FAEDCD;
67
+ border-radius: 6px;
68
+ padding: 0.8rem 1rem;
69
+ font-size: 0.85rem;
70
+ margin-bottom: 1.5rem;
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 0.5rem;
74
+ }
75
+ .harnessapp-dashboard-session-info .badge
76
+ {
77
+ background: #E76F51;
78
+ color: #fff;
79
+ font-size: 0.7rem;
80
+ font-weight: 700;
81
+ padding: 0.15rem 0.5rem;
82
+ border-radius: 9999px;
83
+ }
84
+ `,
85
+
86
+ Templates:
87
+ [
88
+ {
89
+ Hash: "HarnessApp-Dashboard-Template",
90
+ Template: /*html*/`
91
+ <div class="harnessapp-dashboard">
92
+ <h1>Dashboard</h1>
93
+ <div class="harnessapp-dashboard-session-info" id="HarnessApp-Dashboard-SessionInfo"></div>
94
+ <p>
95
+ Welcome to the Bookstore Harness. This application demonstrates
96
+ <strong>pict-section-login</strong> combined with <strong>pict-router</strong>
97
+ for route-based navigation with authentication.
98
+ </p>
99
+ <div class="harnessapp-dashboard-cards">
100
+ <div class="harnessapp-dashboard-card" onclick="{~P~}.PictApplication.navigateTo('/Books')">
101
+ <h3>Books</h3>
102
+ <p>Browse the book catalog from the Meadow ORM.</p>
103
+ </div>
104
+ <div class="harnessapp-dashboard-card" onclick="{~P~}.PictApplication.navigateTo('/Users')">
105
+ <h3>Users</h3>
106
+ <p>View registered users in the system.</p>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ `
111
+ }
112
+ ],
113
+
114
+ Renderables:
115
+ [
116
+ {
117
+ RenderableHash: "HarnessApp-Dashboard-Content",
118
+ TemplateHash: "HarnessApp-Dashboard-Template",
119
+ DestinationAddress: "#HarnessApp-Content-Container",
120
+ RenderMethod: "replace"
121
+ }
122
+ ]
123
+ };
124
+
125
+ class HarnessAppDashboardView extends libPictView
126
+ {
127
+ constructor(pFable, pOptions, pServiceHash)
128
+ {
129
+ super(pFable, pOptions, pServiceHash);
130
+ }
131
+
132
+ onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
133
+ {
134
+ // Populate session info banner
135
+ let tmpSession = this.pict.AppData.Session;
136
+ let tmpInfoElements = this.services.ContentAssignment.getElement('#HarnessApp-Dashboard-SessionInfo');
137
+ if (tmpInfoElements && tmpInfoElements.length > 0 && tmpSession && tmpSession.UserRecord)
138
+ {
139
+ let tmpUser = tmpSession.UserRecord;
140
+ let tmpHTML = 'Logged in as <strong>' + (tmpUser.FullName || tmpUser.LoginID || '') + '</strong>';
141
+ if (tmpUser.IDUser)
142
+ {
143
+ tmpHTML += ' <span class="badge">ID ' + tmpUser.IDUser + '</span>';
144
+ }
145
+ if (tmpUser.Email)
146
+ {
147
+ tmpHTML += '&nbsp;&nbsp;' + tmpUser.Email;
148
+ }
149
+ tmpInfoElements[0].innerHTML = tmpHTML;
150
+ }
151
+
152
+ return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
153
+ }
154
+ }
155
+
156
+ module.exports = HarnessAppDashboardView;
157
+
158
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,86 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "HarnessApp-Layout",
6
+
7
+ DefaultRenderable: "HarnessApp-Layout-Shell",
8
+ DefaultDestinationAddress: "#HarnessApp-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ #HarnessApp-Container
14
+ {
15
+ display: flex;
16
+ flex-direction: column;
17
+ min-height: 100vh;
18
+ }
19
+ #HarnessApp-TopBar-Container
20
+ {
21
+ flex-shrink: 0;
22
+ }
23
+ #HarnessApp-Content-Container
24
+ {
25
+ flex: 1;
26
+ padding: 1.5rem;
27
+ max-width: 1100px;
28
+ width: 100%;
29
+ margin: 0 auto;
30
+ box-sizing: border-box;
31
+ }
32
+ `,
33
+
34
+ Templates:
35
+ [
36
+ {
37
+ Hash: "HarnessApp-Layout-Shell-Template",
38
+ Template: /*html*/`
39
+ <div id="HarnessApp-TopBar-Container"></div>
40
+ <div id="HarnessApp-Content-Container"></div>
41
+ `
42
+ }
43
+ ],
44
+
45
+ Renderables:
46
+ [
47
+ {
48
+ RenderableHash: "HarnessApp-Layout-Shell",
49
+ TemplateHash: "HarnessApp-Layout-Shell-Template",
50
+ DestinationAddress: "#HarnessApp-Container",
51
+ RenderMethod: "replace"
52
+ }
53
+ ]
54
+ };
55
+
56
+ class HarnessAppLayoutView extends libPictView
57
+ {
58
+ constructor(pFable, pOptions, pServiceHash)
59
+ {
60
+ super(pFable, pOptions, pServiceHash);
61
+ }
62
+
63
+ onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
64
+ {
65
+ // Render the top bar
66
+ this.pict.views['HarnessApp-TopBar'].render();
67
+
68
+ // Inject all CSS
69
+ this.pict.CSSMap.injectCSS();
70
+
71
+ // If the URL contains a deep-link hash route (e.g. #/Books from a
72
+ // pasted bookmark), navigateCurrent() will navigate to it.
73
+ // Otherwise, show Dashboard as the default content and resolve.
74
+ if (this.pict.providers.PictRouter && !this.pict.providers.PictRouter.navigateCurrent())
75
+ {
76
+ this.pict.views['HarnessApp-Dashboard'].render();
77
+ this.pict.providers.PictRouter.resolve();
78
+ }
79
+
80
+ return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
81
+ }
82
+ }
83
+
84
+ module.exports = HarnessAppLayoutView;
85
+
86
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,58 @@
1
+ const libPictSectionLogin = require('../../../source/Pict-Section-Login.js');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "HarnessApp-Login",
6
+
7
+ DefaultRenderable: "Login-Container",
8
+ DefaultDestinationAddress: "#Pict-Login-Container",
9
+ TargetElementAddress: "#HarnessApp-Login-Container",
10
+
11
+ AutoRender: false,
12
+
13
+ // The application controls when to check the session,
14
+ // so we disable the auto-check built into the section.
15
+ CheckSessionOnLoad: false,
16
+ ShowOAuthProviders: false,
17
+
18
+ // orator-authentication endpoints (defaults match, but shown for clarity)
19
+ LoginEndpoint: "/1.0/Authenticate",
20
+ LoginMethod: "POST",
21
+ LogoutEndpoint: "/1.0/Deauthenticate",
22
+ CheckSessionEndpoint: "/1.0/CheckSession",
23
+
24
+ SessionDataAddress: "AppData.Session"
25
+ };
26
+
27
+ class HarnessAppLoginView extends libPictSectionLogin
28
+ {
29
+ constructor(pFable, pOptions, pServiceHash)
30
+ {
31
+ super(pFable, pOptions, pServiceHash);
32
+ }
33
+
34
+ onLoginSuccess(pSessionData)
35
+ {
36
+ this.log.info('Login succeeded, switching to protected app.');
37
+ if (this.pict.PictApplication && typeof (this.pict.PictApplication.showProtectedApp) === 'function')
38
+ {
39
+ this.pict.PictApplication.showProtectedApp();
40
+ }
41
+ }
42
+
43
+ onSessionChecked(pSessionData)
44
+ {
45
+ if (pSessionData && pSessionData.LoggedIn)
46
+ {
47
+ this.log.info('Existing session found, switching to protected app.');
48
+ if (this.pict.PictApplication && typeof (this.pict.PictApplication.showProtectedApp) === 'function')
49
+ {
50
+ this.pict.PictApplication.showProtectedApp();
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ module.exports = HarnessAppLoginView;
57
+
58
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,157 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: "HarnessApp-TopBar",
6
+
7
+ DefaultRenderable: "HarnessApp-TopBar-Content",
8
+ DefaultDestinationAddress: "#HarnessApp-TopBar-Container",
9
+
10
+ AutoRender: false,
11
+
12
+ CSS: /*css*/`
13
+ .harnessapp-topbar
14
+ {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ background: #264653;
19
+ color: #FAEDCD;
20
+ padding: 0 1.25rem;
21
+ height: 52px;
22
+ border-bottom: 3px solid #E76F51;
23
+ }
24
+ .harnessapp-topbar-brand
25
+ {
26
+ font-size: 1.15rem;
27
+ font-weight: 700;
28
+ color: #E76F51;
29
+ text-decoration: none;
30
+ cursor: pointer;
31
+ letter-spacing: 0.02em;
32
+ }
33
+ .harnessapp-topbar-brand:hover
34
+ {
35
+ color: #F4845F;
36
+ }
37
+ .harnessapp-topbar-nav
38
+ {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 0.15rem;
42
+ }
43
+ .harnessapp-topbar-nav a
44
+ {
45
+ color: #D4A373;
46
+ text-decoration: none;
47
+ padding: 0.4rem 0.75rem;
48
+ border-radius: 4px;
49
+ font-size: 0.85rem;
50
+ cursor: pointer;
51
+ transition: background-color 0.15s, color 0.15s;
52
+ }
53
+ .harnessapp-topbar-nav a:hover
54
+ {
55
+ background: #1A3340;
56
+ color: #FAEDCD;
57
+ }
58
+ .harnessapp-topbar-session
59
+ {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: 0.5rem;
63
+ font-size: 0.8rem;
64
+ color: #D4A373;
65
+ }
66
+ .harnessapp-topbar-session .dot
67
+ {
68
+ width: 8px;
69
+ height: 8px;
70
+ border-radius: 50%;
71
+ background: #2A9D8F;
72
+ box-shadow: 0 0 4px rgba(42,157,143,0.5);
73
+ }
74
+ .harnessapp-topbar-logout
75
+ {
76
+ background: #E76F51;
77
+ color: #fff;
78
+ border: none;
79
+ padding: 0.3rem 0.8rem;
80
+ border-radius: 4px;
81
+ font-size: 0.75rem;
82
+ font-weight: 600;
83
+ cursor: pointer;
84
+ margin-left: 0.25rem;
85
+ }
86
+ .harnessapp-topbar-logout:hover
87
+ {
88
+ background: #C45A3E;
89
+ }
90
+ `,
91
+
92
+ Templates:
93
+ [
94
+ {
95
+ Hash: "HarnessApp-TopBar-Template",
96
+ Template: /*html*/`
97
+ <div class="harnessapp-topbar">
98
+ <a class="harnessapp-topbar-brand" onclick="{~P~}.PictApplication.navigateTo('/Dashboard')">Bookstore</a>
99
+ <div class="harnessapp-topbar-nav">
100
+ <a onclick="{~P~}.PictApplication.navigateTo('/Dashboard')">Dashboard</a>
101
+ <a onclick="{~P~}.PictApplication.navigateTo('/Books')">Books</a>
102
+ <a onclick="{~P~}.PictApplication.navigateTo('/Users')">Users</a>
103
+ </div>
104
+ <div class="harnessapp-topbar-session">
105
+ <span class="dot"></span>
106
+ <span id="HarnessApp-TopBar-UserName"></span>
107
+ <button class="harnessapp-topbar-logout" type="button" onclick="{~P~}.PictApplication.doLogout()">Log out</button>
108
+ </div>
109
+ </div>
110
+ `
111
+ }
112
+ ],
113
+
114
+ Renderables:
115
+ [
116
+ {
117
+ RenderableHash: "HarnessApp-TopBar-Content",
118
+ TemplateHash: "HarnessApp-TopBar-Template",
119
+ DestinationAddress: "#HarnessApp-TopBar-Container",
120
+ RenderMethod: "replace"
121
+ }
122
+ ]
123
+ };
124
+
125
+ class HarnessAppTopBarView extends libPictView
126
+ {
127
+ constructor(pFable, pOptions, pServiceHash)
128
+ {
129
+ super(pFable, pOptions, pServiceHash);
130
+ }
131
+
132
+ onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
133
+ {
134
+ // Populate the user name from session data
135
+ let tmpSession = this.pict.AppData.Session;
136
+ let tmpDisplayName = '';
137
+
138
+ if (tmpSession && tmpSession.UserRecord)
139
+ {
140
+ tmpDisplayName = tmpSession.UserRecord.FullName
141
+ || tmpSession.UserRecord.LoginID
142
+ || '';
143
+ }
144
+
145
+ let tmpUserNameElements = this.services.ContentAssignment.getElement('#HarnessApp-TopBar-UserName');
146
+ if (tmpUserNameElements && tmpUserNameElements.length > 0)
147
+ {
148
+ tmpUserNameElements[0].textContent = tmpDisplayName;
149
+ }
150
+
151
+ return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
152
+ }
153
+ }
154
+
155
+ module.exports = HarnessAppTopBarView;
156
+
157
+ module.exports.default_configuration = _ViewConfiguration;