Make customisations (and general file overrides) easier to specify (#21189)
Intended for customisation endpoints - see included docs.pull/21217/head
parent
a2b0cf9248
commit
95de708f4e
|
@ -16,24 +16,30 @@ the React SDK, you can still override it from the Element Web layer:
|
|||
`element-web/src/customisations/YourNameSecurity.ts`
|
||||
2. Edit customisations points and make sure export the ones you actually want to
|
||||
activate
|
||||
3. Tweak the Element build process to use the customised module instead of the
|
||||
default by adding this to the `additionalPlugins` array in `webpack.config.js`:
|
||||
3. Create/add an entry to `customisations.json` next to the webpack config:
|
||||
|
||||
```js
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/src[\/\\]customisations[\/\\]Security\.ts/,
|
||||
path.resolve(__dirname, 'src/customisations/YourNameSecurity.ts'),
|
||||
),
|
||||
```json
|
||||
{
|
||||
"src/customisations/Security.ts": "src/customisations/YourNameSecurity.ts"
|
||||
}
|
||||
```
|
||||
|
||||
If we add more customisation modules in the future, we'll likely improve these
|
||||
steps to remove the need for build changes like the above.
|
||||
|
||||
By isolating customisations to their own module, this approach should remove the
|
||||
chance of merge conflicts when updating your fork, and thus simplify ongoing
|
||||
maintenance.
|
||||
|
||||
**Note**: The project deliberately does not exclude `customisations.json` from Git.
|
||||
This is to ensure that in shared projects it's possible to have a common config. By
|
||||
default, Element Web does *not* ship with this file to prevent conflicts.
|
||||
|
||||
### Custom components
|
||||
|
||||
Instead of implementing skinning from the react-sdk, maintainers can use the above system to override components
|
||||
if they wish. Maintenance and API surface compatibility are left as a responsibility for the project - the layering
|
||||
in Element Web (including the react-sdk) do not make guarantees that properties/state machines won't change.
|
||||
|
||||
### Component visibility customisation
|
||||
|
||||
UI for some actions can be hidden via the ComponentVisibility customisation:
|
||||
- inviting users to rooms and spaces,
|
||||
- creating rooms,
|
||||
|
@ -41,21 +47,22 @@ UI for some actions can be hidden via the ComponentVisibility customisation:
|
|||
|
||||
To customise visibility create a customisation module from [ComponentVisibility](https://github.com/matrix-org/matrix-react-sdk/blob/master/src/customisations/ComponentVisibility.ts) following the instructions above.
|
||||
|
||||
`shouldShowComponent` determines whether or not the active MatrixClient user should be able to use
|
||||
`shouldShowComponent` determines whether the active MatrixClient user should be able to use
|
||||
the given UI component. When `shouldShowComponent` returns falsy all UI components for that feature will be hidden.
|
||||
If shown, the user might still not be able to use the
|
||||
component depending on their contextual permissions. For example, invite options
|
||||
might be shown to the user but they won't have permission to invite users to
|
||||
might be shown to the user, but they won't have permission to invite users to
|
||||
the current room: the button will appear disabled.
|
||||
|
||||
For example, to only allow users who meet a certain condition to create spaces:
|
||||
```
|
||||
```typescript
|
||||
function shouldShowComponent(component: UIComponent): boolean {
|
||||
if (component === UIComponent.CreateSpaces) {
|
||||
const userMeetsCondition = <<check your custom condition here>>
|
||||
return userMeetsCondition;
|
||||
}
|
||||
return true;
|
||||
if (component === UIComponent.CreateSpaces) {
|
||||
// customConditionCheck() is a function of your own creation
|
||||
const userMeetsCondition = customConditionCheck(MatrixClientPeg.get().getUserId());
|
||||
return userMeetsCondition;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
In this example, all UI related to creating a space will be hidden unless the users meets a custom condition.
|
||||
In this example, all UI related to creating a space will be hidden unless the users meets the custom condition.
|
||||
|
|
|
@ -39,6 +39,26 @@ function getActiveThemes() {
|
|||
return themes;
|
||||
}
|
||||
|
||||
// See docs/customisations.md
|
||||
let fileOverrides = {/* {[file: string]: string} */};
|
||||
try {
|
||||
fileOverrides = require('./customisations.json');
|
||||
|
||||
// stringify the output so it appears in logs correctly, as large files can sometimes get
|
||||
// represented as `<Object>` which is less than helpful.
|
||||
console.log("Using customisations.json : " + JSON.stringify(fileOverrides, null, 4));
|
||||
} catch (e) {
|
||||
// ignore - not important
|
||||
}
|
||||
const moduleReplacementPlugins = Object.entries(fileOverrides).map(([oldPath, newPath]) => {
|
||||
return new webpack.NormalModuleReplacementPlugin(
|
||||
// because the input is effectively defined by the person running the build, we don't
|
||||
// need to do anything special to protect against regex overrunning, etc.
|
||||
new RegExp(oldPath.replace(/\//g, '[\\/\\\\]').replace(/\./g, '\\.')),
|
||||
path.resolve(__dirname, newPath),
|
||||
);
|
||||
});
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
// Establish settings based on the environment and args.
|
||||
//
|
||||
|
@ -475,6 +495,8 @@ module.exports = (env, argv) => {
|
|||
},
|
||||
|
||||
plugins: [
|
||||
...moduleReplacementPlugins,
|
||||
|
||||
// This exports our CSS using the splitChunks and loaders above.
|
||||
new MiniCssExtractPlugin({
|
||||
filename: useHMR ? "bundles/[name].css" : "bundles/[hash]/[name].css",
|
||||
|
|
Loading…
Reference in New Issue