Skip to content

Commit d880014

Browse files
committed
fix: Use correct Semantic Color Variables for Profile Tab (#9112)
1 parent ec7de9c commit d880014

4 files changed

Lines changed: 252 additions & 87 deletions

File tree

apps/devindex/neo-config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"environment": "development",
55
"mainPath" : "./Main.mjs",
66
"themes" : ["neo-theme-neo-dark", "neo-theme-neo-light"],
7+
"useAiClient": true,
78

89
"mainThreadAddons": [
910
"DragDrop",

apps/devindex/view/home/MainContainerController.mjs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,22 @@ class MainContainerController extends Controller {
2222
// Setup Grid Listeners
2323
let grid = me.getReference('grid');
2424
if (grid) {
25-
grid.on('select', me.onGridSelect, me);
25+
grid.body.on('select', me.onGridSelect, me);
26+
}
27+
28+
// Setup Tab Listeners
29+
let tabContainer = me.getReference('controls')?.down({reference: 'controls-tab-container'});
30+
// Note: Using down() here because controls-tab-container might not be registered if controls has no controller?
31+
// Wait, I fixed that assumption. references bubble.
32+
// But controls-tab-container is inside controls items.
33+
// Let's rely on getReference('controls-tab-container') which should work if bubble is true.
34+
// But to be safe and consistent with previous discovery:
35+
// me.getReference('controls-tab-container') should be available if I trust my previous fix.
36+
// Let's use getReference().
37+
38+
let tabs = me.getReference('controls-tab-container');
39+
if (tabs) {
40+
tabs.on('activeIndexChange', me.onControlsTabChange, me);
2641
}
2742

2843
Neo.Main.getByPath({
@@ -45,26 +60,30 @@ class MainContainerController extends Controller {
4560
})
4661
}
4762

63+
/**
64+
* @param {Object} data
65+
*/
66+
onControlsTabChange(data) {
67+
let me = this;
68+
69+
if (data.value === 1 && me.selectedRecord) { // 1 = Profile Tab
70+
me.getReference('profile-container')?.updateRecord(me.selectedRecord)
71+
}
72+
}
73+
4874
/**
4975
* @param {Object} data
5076
*/
5177
onGridSelect(data) {
5278
let me = this,
5379
record = data.record,
54-
controls = me.getReference('controls'),
55-
profile = controls?.down({reference: 'profile-container'}),
56-
tabContainer = controls?.down({reference: 'controls-tab-container'});
80+
profile = me.getReference('profile-container'),
81+
tabContainer = me.getReference('controls-tab-container');
5782

58-
if (record && profile) {
59-
profile.updateRecord(record);
83+
me.selectedRecord = record;
6084

61-
if (tabContainer) {
62-
tabContainer.activeIndex = 1; // Switch to Profile Tab
63-
}
64-
65-
if (controls && !controls.cls.includes('neo-expanded')) {
66-
controls.addCls('neo-expanded');
67-
}
85+
if (record && profile && tabContainer?.activeIndex === 1) {
86+
profile.updateRecord(record)
6887
}
6988
}
7089
}

apps/devindex/view/home/ProfileContainer.mjs

Lines changed: 123 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Container from '../../../../src/container/Base.mjs';
22
import Image from '../../../../src/component/Image.mjs';
3-
import Label from '../../../../src/component/Label.mjs';
3+
import VDomUtil from '../../../../src/util/VDom.mjs';
44

55
/**
66
* @class DevIndex.view.home.ProfileContainer
@@ -13,113 +13,162 @@ class ProfileContainer extends Container {
1313
* @protected
1414
*/
1515
className: 'DevIndex.view.home.ProfileContainer',
16+
/**
17+
* @member {String[]} cls=['devindex-profile-container']
18+
*/
19+
cls: ['devindex-profile-container'],
1620
/**
1721
* @member {Object} layout={ntype:'vbox',align:'stretch'}
1822
*/
1923
layout: {ntype: 'vbox', align: 'stretch'},
24+
/**
25+
* @member {Object} itemDefaults={flex:'none'}
26+
*/
27+
itemDefaults: {flex: 'none'},
2028
/**
2129
* @member {Object[]} items
2230
*/
2331
items: [{
24-
ntype : 'component',
25-
cls : ['profile-header'],
26-
height: 100,
27-
style : {marginBottom: '1em'},
28-
vdom : {
29-
cn: [{
30-
tag: 'div', cls: ['profile-avatar-wrapper'], cn: [
31-
{tag: 'img', cls: ['profile-avatar'], flag: 'avatar'}
32-
]
33-
}, {
34-
tag: 'div', cls: ['profile-names'], cn: [
35-
{tag: 'div', cls: ['profile-name'], flag: 'name'},
36-
{tag: 'div', cls: ['profile-login'], flag: 'login'}
37-
]
38-
}]
39-
}
40-
}, {
41-
module : Label,
42-
cls : ['profile-bio'],
43-
reference: 'profile-bio',
44-
style : {
45-
fontStyle : 'italic',
46-
lineHeight: '1.4',
47-
whiteSpace: 'normal'
48-
},
49-
text: ''
32+
ntype : 'component',
33+
tag : 'div',
34+
reference: 'placeholder',
35+
text : 'Select a user to view details',
36+
cls : ['profile-placeholder']
5037
}, {
51-
ntype : 'container',
52-
layout: 'vbox',
53-
style : {marginTop: '1em'},
54-
items : [{
55-
ntype: 'label',
56-
style: {fontWeight: 'bold'},
38+
ntype : 'container',
39+
reference: 'details-wrapper',
40+
cls : ['profile-details-wrapper'],
41+
hidden : true,
42+
layout : {ntype: 'vbox', align: 'stretch'},
43+
itemDefaults: {flex: 'none'},
44+
items : [{
45+
ntype : 'component',
46+
reference: 'profile-header',
47+
cls : ['profile-header'],
48+
vdom : {
49+
cn: [{
50+
tag: 'div', cls: ['profile-avatar-wrapper'], cn: [
51+
{tag: 'img', cls: ['profile-avatar'], flag: 'avatar'}
52+
]
53+
}, {
54+
tag: 'div', cls: ['profile-names'], cn: [
55+
{tag: 'div', cls: ['profile-name'], flag: 'name'},
56+
{tag: 'div', cls: ['profile-login'], flag: 'login'}
57+
]
58+
}]
59+
}
60+
}, {
61+
ntype : 'component',
62+
tag : 'div',
63+
cls : ['profile-bio'],
64+
reference: 'profile-bio',
65+
text : ''
66+
}, {
67+
ntype: 'component',
68+
tag : 'div',
69+
cls : ['profile-details-label'],
5770
text : 'Details'
5871
}, {
59-
ntype : 'label',
72+
ntype : 'component',
73+
tag : 'div',
74+
cls : ['profile-detail'],
6075
reference: 'profile-location',
6176
text : ''
6277
}, {
63-
ntype : 'label',
78+
ntype : 'component',
79+
tag : 'div',
80+
cls : ['profile-detail'],
6481
reference: 'profile-company',
6582
text : ''
83+
}, {
84+
ntype : 'container',
85+
reference: 'profile-orgs',
86+
layout : {ntype: 'hbox', wrap: 'wrap'},
87+
cls : ['profile-orgs'],
88+
items : []
6689
}]
67-
}, {
68-
ntype : 'container',
69-
reference: 'profile-orgs',
70-
layout : {ntype: 'hbox', wrap: true},
71-
style : {gap: '5px', marginTop: '1em'},
72-
items : []
7390
}]
7491
}
7592

93+
/**
94+
* @param {String} src
95+
* @param {Number} size
96+
* @returns {String}
97+
*/
98+
getAvatarUrl(src, size) {
99+
if (src) {
100+
try {
101+
let url = new URL(src);
102+
url.searchParams.set('s', size);
103+
return url.toString()
104+
} catch (e) {
105+
console.error('Invalid Avatar URL', src)
106+
}
107+
}
108+
109+
return src || ''
110+
}
111+
76112
/**
77113
* @param {Object} record
78114
*/
79115
updateRecord(record) {
80-
let me = this,
81-
vdom = me.items[0].vdom,
82-
bio = me.getReference('profile-bio'),
83-
loc = me.getReference('profile-location'),
84-
comp = me.getReference('profile-company'),
85-
orgs = me.getReference('profile-orgs'),
116+
let me = this,
117+
wrapper = me.getReference('details-wrapper'),
118+
holder = me.getReference('placeholder'),
119+
header = me.getReference('profile-header'),
120+
bio = me.getReference('profile-bio'),
121+
loc = me.getReference('profile-location'),
122+
comp = me.getReference('profile-company'),
123+
orgs = me.getReference('profile-orgs'),
124+
vdom = header.vdom,
86125
avatar, name, login;
87126

88-
avatar = me.getVdomChild(vdom, 'avatar');
89-
name = me.getVdomChild(vdom, 'name');
90-
login = me.getVdomChild(vdom, 'login');
127+
if (!record) {
128+
wrapper.hidden = true;
129+
holder.hidden = false;
130+
return
131+
}
132+
133+
wrapper.hidden = false;
134+
holder.hidden = true;
91135

92-
avatar.src = record.avatar_url || '';
93-
name.html = record.name || '';
94-
login.html = `@${record.login}`;
136+
avatar = VDomUtil.getByFlag(vdom, 'avatar');
137+
name = VDomUtil.getByFlag(vdom, 'name');
138+
login = VDomUtil.getByFlag(vdom, 'login');
95139

96-
me.items[0].vdom = vdom;
97-
me.items[0].update();
140+
if (avatar) {
141+
avatar.src = me.getAvatarUrl(record.avatar_url, 128)
142+
}
143+
if (name) {
144+
name.text = record.name || '';
145+
}
146+
if (login) {
147+
login.text = `@${record.login}`;
148+
}
149+
150+
header.update();
98151

99152
bio.text = record.bio || 'No bio available.';
100153
loc.text = record.location ? `📍 ${record.location}` : '';
101154
comp.text = record.company ? `🏢 ${record.company}` : '';
102155

103156
// Update Orgs
104-
if (record.organizations && Array.isArray(record.organizations)) {
105-
orgs.removeAll();
106-
if (record.organizations.length > 0) {
107-
orgs.add({ntype: 'label', text: 'Organizations:', width: '100%', style: {fontWeight: 'bold', marginBottom: '5px'}});
108-
109-
record.organizations.forEach(org => {
110-
orgs.add({
111-
module: Image,
112-
alt : org.login,
113-
height: 32,
114-
src : org.avatar_url,
115-
title : org.login,
116-
width : 32,
117-
style : {borderRadius: '4px'}
118-
})
119-
});
120-
}
121-
} else {
122-
orgs.removeAll();
157+
orgs.removeAll();
158+
159+
if (record.organizations && Array.isArray(record.organizations) && record.organizations.length > 0) {
160+
orgs.add({ntype: 'component', tag: 'div', cls: ['org-label'], text: 'Organizations:'});
161+
162+
record.organizations.forEach(org => {
163+
orgs.add({
164+
module: Image,
165+
alt : org.login,
166+
height: 32,
167+
src : me.getAvatarUrl(org.avatar_url, 64),
168+
title : org.login,
169+
width : 32
170+
})
171+
});
123172
}
124173
}
125174
}

0 commit comments

Comments
 (0)