feat(guilds): a third place on the guild page, and where that page lives #13
@@ -202,6 +202,13 @@ registry.declareModuleSlot(ID, 'uo.guild.detail')
|
|||||||
// empty.
|
// empty.
|
||||||
registry.declareModuleSlot(ID, 'uo.guild.forum')
|
registry.declareModuleSlot(ID, 'uo.guild.forum')
|
||||||
|
|
||||||
|
// And a THIRD, at the top of the same page, for core's per-Team notification
|
||||||
|
// control (TEAMS.md §6.3). Same reasoning as the other two and a different place:
|
||||||
|
// muting a guild is an action ON this page, so it sits with the page's heading
|
||||||
|
// rather than after its content. Core resolves whether this viewer is in the
|
||||||
|
// Team at all — this module neither knows nor asks.
|
||||||
|
registry.declareModuleSlot(ID, 'uo.guild.header')
|
||||||
|
|
||||||
// `module.json`'s `coreApi` range is checked by the loader before this file is
|
// `module.json`'s `coreApi` range is checked by the loader before this file is
|
||||||
// ever served, so there is nothing to re-check here. It is logged because a
|
// ever served, so there is nothing to re-check here. It is logged because a
|
||||||
// mismatch between the core that validated the manifest and the core that
|
// mismatch between the core that validated the manifest and the core that
|
||||||
|
|||||||
@@ -75,6 +75,13 @@ export default function Guild() {
|
|||||||
{data.alliance && ` · ${data.alliance}`}
|
{data.alliance && ` · ${data.alliance}`}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
{/* A third place for core, up here rather than below the roster: core
|
||||||
|
puts this guild's notification control in it, and a control that
|
||||||
|
acts on the page belongs beside the page's title and not after its
|
||||||
|
content. Empty for a visitor with no membership, and on a core
|
||||||
|
that fills nothing. */}
|
||||||
|
<Slot name="uo.guild.header" externalId={String(id)} moduleId="uo" />
|
||||||
|
|
||||||
{roster.length > 0 && (
|
{roster.length > 0 && (
|
||||||
<div style={{ overflowX: 'auto', marginTop: 18 }}>
|
<div style={{ overflowX: 'auto', marginTop: 18 }}>
|
||||||
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
|
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
|
||||||
|
|||||||
@@ -214,10 +214,16 @@ it('declares its own guild slots, for core to fill', () => {
|
|||||||
// core page: core owns the activity feed and the forum, this module owns the
|
// core page: core owns the activity feed and the forum, this module owns the
|
||||||
// word "guild", so this module declares the places and core puts them in.
|
// word "guild", so this module declares the places and core puts them in.
|
||||||
//
|
//
|
||||||
// TWO slots rather than one because a slot holds one component: stacking the
|
// THREE slots rather than one because a slot holds one component: stacking the
|
||||||
// feed and the forum into a single fill would take away this module's ability
|
// feed, the forum and the notification control into a single fill would take
|
||||||
// to place them separately on its own page.
|
// away this module's ability to place them separately on its own page — and it
|
||||||
assert.deepEqual([...registered.declaredSlots], ['uo.guild.detail', 'uo.guild.forum'])
|
// does place them separately, the control above the roster and the other two
|
||||||
|
// below it.
|
||||||
|
assert.deepEqual([...registered.declaredSlots], [
|
||||||
|
'uo.guild.detail',
|
||||||
|
'uo.guild.forum',
|
||||||
|
'uo.guild.header',
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('every declared slot is rendered by the page that owns it', () => {
|
it('every declared slot is rendered by the page that owns it', () => {
|
||||||
|
|||||||
@@ -317,4 +317,18 @@ async function projectRoster(externalId, members, viewer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getTeams, getTeamMembers, getTeamLeaders, projectRoster, boardIsCurrent }
|
// Where core should point a link at a guild (MODULE_API 1.6.0, TEAMS.md §6.4).
|
||||||
|
//
|
||||||
|
// **Core cannot work this out for itself, and it is not supposed to.** Teams are
|
||||||
|
// a contract primitive with no core surface — this module owns the guild page,
|
||||||
|
// because core does not own the word "guild" — so the one thing core needs back
|
||||||
|
// is where the page it does not own actually lives. A notification email that
|
||||||
|
// cannot link to the thread it is about is most of the way to useless.
|
||||||
|
//
|
||||||
|
// A relative path with `{externalId}` substituted, matching `Guild.jsx`'s route
|
||||||
|
// (`/uo/guilds/:id`). Core does the substitution and nothing else with it; a
|
||||||
|
// template naming its own host is refused at registration, which is why this is
|
||||||
|
// data and not a callback.
|
||||||
|
const pageUrlTemplate = '/uo/guilds/{externalId}'
|
||||||
|
|
||||||
|
module.exports = { getTeams, getTeamMembers, getTeamLeaders, projectRoster, boardIsCurrent, pageUrlTemplate }
|
||||||
|
|||||||
Reference in New Issue
Block a user