Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrades to SASS and Bootstrap 5 #2524

Merged
merged 7 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion docs/_data/version.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
current: 13.7
current: 14.0
10 changes: 10 additions & 0 deletions docs/sections/dev/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ title: Best practices
- [PSR 12](https://www.php-fig.org/psr/psr-12/)
- [Symfony coding standards](http://symfony.com/doc/current/contributing/code/standards.html)
- [JavaScript code conventions](https://www.crockford.com/code.html)

## Styles

- Use [Margin](https://getbootstrap.com/docs/5.3/utilities/spacing/#margin-and-padding) utilities to manage spacing between components
- Use size `3` for standard spacing

- Limit page content size with `.content-sm`, `.content-md`, `.content-lg` :
- `.content-md` : Forms and Details view
- `.content-lg` : Two columns views
- Full width : List views, Custom views (like Agenda or Home)
2 changes: 1 addition & 1 deletion docs/sections/user-interface/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ Tools styles are stored in `MY_PLUGIN/Resources/styles`.
// MY_PLUGIN/Resources/styles/my-tool.less

// Claroline & bootstrap variables
@import "/src/main/app/Resources/styles/variables";
@import "src/main/app/Resources/styles/variables";

// Your custom styles are defined here

Expand Down
21,164 changes: 8,027 additions & 13,137 deletions package-lock.json

Large diffs are not rendered by default.

39 changes: 19 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "GPL-3.0",
"repository": "/~https://github.com/claroline/Claroline",
"engines": {
"node": ">=12",
"node": ">=18",
"npm": ">=8"
},
"scripts": {
Expand All @@ -20,44 +20,42 @@
"@babel/preset-react": "^7.10.1",
"@fortawesome/fontawesome-free": "^6",
"assets-webpack-plugin": "3.9.7",
"autoprefixer": "^8.5.0",
"autoprefixer": "^10.4.0",
"babel-loader": "^8.0.0",
"bootstrap": "^3.4.1",
"classnames": "^2.2.5",
"core-js": "^3.26.1",
"cssnano": "^4.1",
"d3": "^4.4.0",
"bootstrap": "^5.3.0",
"classnames": "^2.3.2",
"core-js": "^3.31.0",
"cssnano": "^6.0.1",
"d3": "^7.8.5",
"html-react-parser": "^0.9.1",
"html2pdf.js": "^0.9.1",
"invariant": "^2.2.4",
"jquery": "2.2.4",
"jsplumb": "^2.2.11",
"less": "^4.1",
"lodash": "^4.17.21",
"mathjax": "2.7.4",
"moment": "^2.24.0",
"pdfjs-dist": "^2.12",
"postcss-cli": "^2.5.0",
"prop-types": "^15.7.2",
"pdfjs-dist": "^3.8.162",
"postcss": "^8.4.24",
"prop-types": "^15.8.1",
"react": "^16.7.0",
"react-bootstrap": "^0.31.2",
"react-bootstrap": "^2.7",
"react-dnd": "^7.7.0",
"react-dnd-html5-backend": "^7.0.2",
"react-dnd-touch-backend": "^0.5.2",
"react-dom": "^16.7.0",
"react-helmet": "5.2.1",
"react-helmet": "^6.1.0",
"react-redux": "^7.0.3",
"react-router-dom": "^5.0.0",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"shelljs": "^0.5.3",
"swagger-ui-react": "3.51.2",
"tinycolor2": "^1.4.1",
"reselect": "^4.1.8",
"sass": "^1.62.1",
"swagger-ui-react": "^5.1.0",
"tinycolor2": "^1.6.0",
"tinymce": "^6.3",
"@tinymce/tinymce-react": "^4.2",
"uuid": "^9.0.0",
"video.js": "7.7.4",
"video.js": "^8.3.0",
"wavesurfer.js": "2.2.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
Expand All @@ -71,5 +69,6 @@
"eslint-plugin-react": "^7.21.5",
"redux-freeze": "^0.1.7",
"webpack-dev-server": "^4.11.1"
}
},
"browserslist": ["last 2 versions"]
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {PropTypes as T} from 'prop-types'
import {schemeCategory20c} from 'd3-scale'
import {schemeCategory20c} from '#/main/theme/color/utils'

import {trans} from '#/main/app/intl/translation'
import {ContentCounter} from '#/main/app/content/components/counter'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ const BBBServers = (props) =>
<TableRow key={i}>
<TableCell>
{server.disabled &&
<span className="label label-danger">{trans('disabled')}</span>
<span className="badge rounded-pill text-bg-danger">{trans('disabled')}</span>
}

{!server.disabled && server.limit && server.participants >= server.limit &&
<span className="label label-warning">{trans('full')}</span>
<span className="badge rounded-pill text-bg-warning">{trans('full')}</span>
}

{!server.disabled && (!server.limit || server.participants < server.limit) &&
<span className="label label-success">{trans('available')}</span>
<span className="badge rounded-pill text-bg-success">{trans('available')}</span>
}
</TableCell>
<TableCell>{server.url}</TableCell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class Player extends Component {
return (
<Fragment>
{this.props.bbb.newTab && this.props.bbb.welcomeMessage &&
<div className="panel panel-default" style={{marginTop: 20}}>
<ContentHtml className="panel-body">
<div className="card mb-3" style={{marginTop: 20}}>
<ContentHtml className="card-body">
{this.props.bbb.welcomeMessage}
</ContentHtml>
</div>
Expand Down Expand Up @@ -99,8 +99,9 @@ class Player extends Component {

<Button
type={CALLBACK_BUTTON}
className="btn btn-block btn-emphasis component-container"
icon="fa fa-fw fa-sign-in-alt"
className="w-100 mb-3"
variant="btn"
size="lg"
label={trans('join', {}, 'bbb')}
callback={() => this.openTab()}
disabled={!this.state.ready}
Expand All @@ -113,20 +114,21 @@ class Player extends Component {
{(this.isClosed() || !isEmpty(this.props.joinStatus)) && this.props.allowRecords && this.props.bbb.record && get(this.props.lastRecording, 'media.presentation') && this.props.bbb.newTab &&
<Button
type={URL_BUTTON}
className="btn btn-block btn-emphasis"
icon="fa fa-fw fa-video"
className="w-100"
variant="btn"
label={trans('show-last-record', {}, 'actions')}
target={this.props.lastRecording.media.presentation}
primary={true}
size="lg"
open="_blank"
/>
}

{this.props.bbb.newTab && this.props.allowRecords && this.props.bbb.record && !isEmpty(this.props.lastRecording) &&
<Button
type={LINK_BUTTON}
className="btn btn-block"
icon="fa fa-fw fa-list"
className="w-100"
variant="btn"
label={trans('show-records', {}, 'actions')}
target={`${this.props.path}/records`}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "/src/main/app/Resources/styles/variables";
@import "src/main/app/Resources/styles/variables";

.youtube-player-container {
& > iframe#youtube-player {
Expand Down
2 changes: 1 addition & 1 deletion src/integration/youtube/assets.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"styles": {
"entry": {
"youtube": "youtube.less"
"youtube": "youtube.scss"
}
}
}
9 changes: 5 additions & 4 deletions src/main/app/Controller/AbstractCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public function setObjectManager(ObjectManager $om)
* )
*
* @param string $class
*
* @deprecated. use the get or list endpoints
*/
public function findAction(Request $request, $class): JsonResponse
{
Expand Down Expand Up @@ -119,7 +121,6 @@ public function getAction(string $field, $id, $class): JsonResponse
*
* @param string $class
* @param string $field
* @param mixed $value
*/
public function existAction($class, $field, $value): JsonResponse
{
Expand Down Expand Up @@ -213,7 +214,7 @@ public function updateAction($id, Request $request, $class): JsonResponse
return new JsonResponse($object, 422);
}

//just in case so we really returns the proper object
// just in case so we really returns the proper object
$this->om->refresh($object);

return new JsonResponse(
Expand Down Expand Up @@ -280,8 +281,8 @@ public static function getOptions(): array
public function getRequirements(): array
{
return [
'get' => ['id' => '^(?!.*(copy|find|\/)).*'],
'update' => ['id' => '^(?!.*(find|\/)).*'],
'get' => ['id' => '^(?!.*(copy|find|exists\/)).*'],
'update' => ['id' => '^(?!.*(find|exist\/)).*'],
'exist' => [],
];
}
Expand Down
7 changes: 3 additions & 4 deletions src/main/app/Entity/Meta/Creator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ trait Creator
* The user who created the entity.
*
* @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\User")
* @ORM\JoinColumn(onDelete="SET NULL")
*
* @var User
* @ORM\JoinColumn(onDelete="SET NULL")
*/
protected $creator;
protected ?User $creator = null;

/**
* Returns the entity creator.
Expand All @@ -28,7 +27,7 @@ public function getCreator(): ?User
/**
* Sets the entity creator.
*/
public function setCreator(?User $creator = null): void
public function setCreator(User $creator = null): void
{
$this->creator = $creator;
}
Expand Down
11 changes: 6 additions & 5 deletions src/main/app/Resources/modules/action/components/button.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {Component, cloneElement} from 'react'
import React, {Component, cloneElement, createElement, forwardRef} from 'react'
import classes from 'classnames'
import invariant from 'invariant'
import merge from 'lodash/merge'
import omit from 'lodash/omit'

import {PropTypes as T, implementPropTypes} from '#/main/app/prop-types'
Expand All @@ -10,21 +11,21 @@ import {TooltipOverlay} from '#/main/app/overlays/tooltip/components/overlay'
import {Action as ActionTypes} from '#/main/app/action/prop-types'
import {createActionDefinition} from '#/main/app/action/utils'

const ButtonComponent = props => {
const ButtonComponent = forwardRef((props, ref) => {
const button = buttonRegistry.get(props.type)

invariant(undefined !== button, `You have requested a non existent button "${props.type}".`)

return React.createElement(button, omit(props, 'type', 'icon', 'label', 'hideLabel', 'subscript'), [
return createElement(button, merge(omit(props, 'type', 'icon', 'label', 'hideLabel', 'subscript'), {ref: ref}), [
(props.icon && typeof props.icon === 'string') &&
<span key="button-icon" className={classes('action-icon', props.icon, !props.hideLabel && 'icon-with-text-right')} aria-hidden={true} />,
(props.icon && typeof props.icon !== 'string') && cloneElement(props.icon, {key: 'button-icon'}),
props.hideLabel ? <span key="button-label" className="action-label sr-only">{props.label}</span> : props.label,
props.children,
props.subscript &&
<span key="button-subscript" className={classes('action-subscript', `${props.subscript.type} ${props.subscript.type}-${props.subscript.status || 'primary'}`)}>{props.subscript.value}</span>
<span key="button-subscript" className={classes('action-subscript badge rounded-pill', `text-bg-${props.subscript.status || 'primary'}`)}>{props.subscript.value}</span>
])
}
})

implementPropTypes(ButtonComponent, ActionTypes, {
hideLabel: T.bool
Expand Down
15 changes: 8 additions & 7 deletions src/main/app/Resources/modules/action/components/toolbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {buildToolbar} from '#/main/app/action/utils'
/**
* Creates a toolbar of actions.
*/
const StaticToolbar = props => {
const StaticToolbar = (props) => {
const toolbar = buildToolbar(props.toolbar, props.actions, props.scope)

return (0 !== toolbar.length &&
Expand All @@ -26,17 +26,18 @@ const StaticToolbar = props => {
0 !== groupIndex &&
<span
key={`separator-${groupIndex}`}
className={`${props.className}-separator`}
className={`${props.name || props.className}-separator`}
/>,
...group.map((action) =>
<Button
{...omit(action, 'name', 'className')}
id={`${props.id || props.name || ''}${action.id || action.name}`}
key={action.id || action.name}
disabled={props.disabled || action.disabled}
className={classes(`${props.name || props.className}-btn`, props.buttonName, action.className)}
className={classes(props.name ? `${props.name}-btn` : null, props.buttonName, action.className)}
tooltip={undefined !== action.tooltip ? action.tooltip : props.tooltip}
size={props.size}
size={action.size || props.size}
variant={props.variant}
onClick={action.onClick ? () => {
action.onClick()
if (props.onClick) {
Expand All @@ -59,12 +60,12 @@ implementPropTypes(StaticToolbar, ToolbarTypes, {
actions: []
})

const PromisedToolbar = props =>
const PromisedToolbar = (props) =>
<Await
for={props.actions}
placeholder={
<div className={props.className}>
<span className={classes(`${props.className}-btn`, props.buttonName, 'default')}>
<span className={classes(props.name ? `${props.name}-btn` : null, props.buttonName, 'default')}>
<span className="fa fa-fw fa-spinner fa-spin" />
</span>
</div>
Expand All @@ -81,7 +82,7 @@ implementPropTypes(PromisedToolbar, ToolbarTypes, {
)
})

const Toolbar = props => props.actions instanceof Promise ?
const Toolbar = (props) => props.actions instanceof Promise ?
<PromisedToolbar {...props} /> :
<StaticToolbar {...props} />

Expand Down
4 changes: 2 additions & 2 deletions src/main/app/Resources/modules/action/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ const ACTIONS = {
icon: 'fa fa-save'
},
[ACTION_DELETE]: {
icon: 'fa fa-trash',
dangerous: true
icon: 'fa fa-trash'/*,
dangerous: true*/
},
[ACTION_SEND]: {
icon: 'fa fa-paper-plane'
Expand Down
2 changes: 1 addition & 1 deletion src/main/app/Resources/modules/action/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function createActionDefinition(action) {
question: action.confirm.message,
dangerous: action.dangerous,

// forward original action to the confirm modal
// forward original action to the confirmation modal
confirmAction: Object.assign({}, omit(action, 'confirm'), {
id: actionDef.id ? `${actionDef.id}-confirm` : undefined,
label: action.confirm.button || action.label
Expand Down
Loading