Merge pull request #5307 from Sandeep-FED/update-modern-carousel
This commit is contained in:
commit
d54365558e
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "SPFx 1.18.2",
|
"name": "SPFx 1.20.2",
|
||||||
"image": "docker.io/m365pnp/spfx:1.18.2",
|
"image": "docker.io/m365pnp/spfx:1.20.2",
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
"nodeVersion": "18.18.2",
|
"nodeVersion": "18.18.2",
|
||||||
"sdksVersions": {
|
"sdksVersions": {
|
||||||
"@microsoft/microsoft-graph-client": "3.0.2",
|
"@microsoft/microsoft-graph-client": "3.0.2",
|
||||||
"@microsoft/teams-js": "2.12.0"
|
"@microsoft/teams-js": "2.24.0"
|
||||||
},
|
},
|
||||||
"version": "1.18.2",
|
"version": "1.20.0",
|
||||||
"libraryName": "award-recognition",
|
"libraryName": "award-recognition",
|
||||||
"libraryId": "45e061b8-13f5-423f-bedb-12fc2a44fa89",
|
"libraryId": "45e061b8-13f5-423f-bedb-12fc2a44fa89",
|
||||||
"environment": "spo",
|
"environment": "spo",
|
||||||
|
|
|
@ -9,21 +9,21 @@ This SharePoint Framework (SPFx) web part introduces a contemporary carousel com
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
| :warning: Important |
|
| :warning: Important |
|
||||||
|:---------------------------|
|
| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Every SPFx version is optimally compatible with specific versions of Node.js. In order to be able to build this sample, you need to ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node.|
|
| Every SPFx version is optimally compatible with specific versions of Node.js. In order to be able to build this sample, you need to ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node. |
|
||||||
|Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
|
| Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
![version](https://img.shields.io/badge/version-1.18.2-green.svg)
|
![version](https://img.shields.io/badge/version-1.20.0-green.svg)
|
||||||
|
|
||||||
This sample is optimally compatible with the following environment configuration:
|
This sample is optimally compatible with the following environment configuration:
|
||||||
|
|
||||||
![SPFx 1.18.2](https://img.shields.io/badge/SPFx-1.18.2-green.svg)
|
![SPFx 1.20.0](https://img.shields.io/badge/SPFx-1.20.0-green.svg)
|
||||||
![Node.js v18 | v16](https://img.shields.io/badge/Node.js-v18%20%7C%20v16-green.svg)
|
![Node.js v18 | v16](https://img.shields.io/badge/Node.js-v18%20%7C%20v16-green.svg)
|
||||||
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||||
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
![Does not work with SharePoint 2019](https://img.shields.io/badge/SharePoint%20Server%202019-Incompatible-red.svg "SharePoint Server 2019 requires SPFx 1.4.1 or lower")
|
||||||
![Does not work with SharePoint 2016 (Feature Pack 2)](https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
![Does not work with SharePoint 2016 (Feature Pack 2)](<https://img.shields.io/badge/SharePoint%20Server%202016%20(Feature%20Pack%202)-Incompatible-red.svg> "SharePoint Server 2016 Feature Pack 2 requires SPFx 1.1")
|
||||||
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||||
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-red.svg)
|
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-red.svg)
|
||||||
![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-red.svg)
|
![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-red.svg)
|
||||||
|
@ -40,7 +40,7 @@ This sample is optimally compatible with the following environment configuration
|
||||||
Create a SharePoint custom list `Award Recognition` in the SPO site with below columns
|
Create a SharePoint custom list `Award Recognition` in the SPO site with below columns
|
||||||
|
|
||||||
| Column Name | Type |
|
| Column Name | Type |
|
||||||
| ------- | --------------- |
|
| ----------- | ----- |
|
||||||
| Title | OOTB |
|
| Title | OOTB |
|
||||||
| Designation | Text |
|
| Designation | Text |
|
||||||
| UserImage | Image |
|
| UserImage | Image |
|
||||||
|
@ -48,8 +48,8 @@ Create a SharePoint custom list `Award Recognition` in the SPO site with below c
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
| Solution | Author(s) |
|
| Solution | Author(s) |
|
||||||
| ----------- | ------------------------------------------------------- |
|
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| react-modern-carousel| Sandeep P S ( [LinkedIn](https://www.linkedin.com/in/sandeepps1299/) ) / Quadrasystems.net ( [Twitter](https://www.linkedin.com/company/quadrasystems.net-india-pvt-ltd) / [LinkedIn](https://www.linkedin.com/company/quadrasystems.net-india-pvt-ltd) ) |
|
| react-modern-carousel | Sandeep P S ( [LinkedIn](https://www.linkedin.com/in/sandeepps1299/) ) / Quadrasystems.net ( [Twitter](https://www.linkedin.com/company/quadrasystems.net-india-pvt-ltd) / [LinkedIn](https://www.linkedin.com/company/quadrasystems.net-india-pvt-ltd) ) |
|
||||||
|
|
||||||
## Contributors🧑💻
|
## Contributors🧑💻
|
||||||
|
|
||||||
|
@ -58,8 +58,9 @@ Create a SharePoint custom list `Award Recognition` in the SPO site with below c
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
| Version | Date | Comments |
|
| Version | Date | Comments |
|
||||||
| ------- | ---------------- | --------------- |
|
| ------- | ---------------- | ----------------------------------- |
|
||||||
| 1.0 | March 16, 2024 | Initial release |
|
| 1.0 | March 16, 2024 | Initial release |
|
||||||
|
| 1.1 | October 19, 2024 | Upgrade to SPFx 1.20 & misc changes |
|
||||||
|
|
||||||
## Minimal Path to Awesome⚡
|
## Minimal Path to Awesome⚡
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"This SharePoint Framework (SPFx) web part introduces a contemporary carousel component leveraging Swiper, facilitating seamless traversal through content housed within a SharePoint site. This innovative feature enhances user experience by providing fluid navigation through various pieces of content, thereby adding a touch of elegance and sophistication to the SharePoint environment."
|
"This SharePoint Framework (SPFx) web part introduces a contemporary carousel component leveraging Swiper, facilitating seamless traversal through content housed within a SharePoint site. This innovative feature enhances user experience by providing fluid navigation through various pieces of content, thereby adding a touch of elegance and sophistication to the SharePoint environment."
|
||||||
],
|
],
|
||||||
"creationDateTime": "2024-03-16",
|
"creationDateTime": "2024-03-16",
|
||||||
"updateDateTime": "2024-03-16",
|
"updateDateTime": "2024-10-10",
|
||||||
"products": [
|
"products": [
|
||||||
"SharePoint"
|
"SharePoint"
|
||||||
],
|
],
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "SPFX-VERSION",
|
"key": "SPFX-VERSION",
|
||||||
"value": "1.18.2"
|
"value": "1.20.2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"thumbnails": [
|
"thumbnails": [
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
"solution": {
|
"solution": {
|
||||||
"name": "award-recognition-client-side-solution",
|
"name": "award-recognition-client-side-solution",
|
||||||
"id": "45e061b8-13f5-423f-bedb-12fc2a44fa89",
|
"id": "45e061b8-13f5-423f-bedb-12fc2a44fa89",
|
||||||
"version": "1.0.0.0",
|
"version": "1.1.0.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true,
|
"skipFeatureDeployment": true,
|
||||||
"isDomainIsolated": false,
|
"isDomainIsolated": false,
|
||||||
"developer": {
|
"developer": {
|
||||||
"name": "",
|
"name": "Sandeep P S",
|
||||||
"websiteUrl": "",
|
"websiteUrl": "",
|
||||||
"privacyUrl": "",
|
"privacyUrl": "",
|
||||||
"termsOfUseUrl": "",
|
"termsOfUseUrl": "",
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
"title": "award-recognition Feature",
|
"title": "award-recognition Feature",
|
||||||
"description": "The feature that activates elements of the award-recognition solution.",
|
"description": "The feature that activates elements of the award-recognition solution.",
|
||||||
"id": "475edc5c-974e-43d2-874b-0262da790739",
|
"id": "475edc5c-974e-43d2-874b-0262da790739",
|
||||||
"version": "1.0.0.0"
|
"version": "1.1.0.0"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "award-recognition",
|
"name": "award-recognition",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.13.0 <17.0.0 || >=18.17.1 <19.0.0"
|
"node": ">=16.13.0 <17.0.0 || >=18.17.1 <19.0.0"
|
||||||
|
@ -13,14 +13,14 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluentui/react": "8.106.4",
|
"@fluentui/react": "8.106.4",
|
||||||
"@fluentui/react-components": "^9.40.0",
|
"@fluentui/react-components": "^9.55.1",
|
||||||
"@microsoft/sp-adaptive-card-extension-base": "1.18.2",
|
"@microsoft/sp-adaptive-card-extension-base": "1.18.2",
|
||||||
"@microsoft/sp-core-library": "1.18.2",
|
"@microsoft/sp-core-library": "1.20.0",
|
||||||
"@microsoft/sp-lodash-subset": "1.18.2",
|
"@microsoft/sp-lodash-subset": "1.20.0",
|
||||||
"@microsoft/sp-office-ui-fabric-core": "1.18.2",
|
"@microsoft/sp-office-ui-fabric-core": "1.20.0",
|
||||||
"@microsoft/sp-property-pane": "1.18.2",
|
"@microsoft/sp-property-pane": "1.20.0",
|
||||||
"@microsoft/sp-webpart-base": "1.18.2",
|
"@microsoft/sp-webpart-base": "1.20.0",
|
||||||
"@pnp/sp": "^3.20.0",
|
"@pnp/sp": "^3.26.0",
|
||||||
"pnp-react-hooks": "^1.3.0",
|
"pnp-react-hooks": "^1.3.0",
|
||||||
"react": "17.0.1",
|
"react": "17.0.1",
|
||||||
"react-dom": "17.0.1",
|
"react-dom": "17.0.1",
|
||||||
|
@ -28,18 +28,17 @@
|
||||||
"tslib": "2.3.1"
|
"tslib": "2.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@microsoft/eslint-config-spfx": "1.18.2",
|
"@microsoft/eslint-config-spfx": "1.20.2",
|
||||||
"@microsoft/eslint-plugin-spfx": "1.18.2",
|
"@microsoft/eslint-plugin-spfx": "1.18.2",
|
||||||
"@microsoft/rush-stack-compiler-4.5": "0.2.2",
|
|
||||||
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
|
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
|
||||||
"@microsoft/sp-build-web": "1.18.2",
|
"@microsoft/sp-build-web": "1.18.2",
|
||||||
"@microsoft/sp-module-interfaces": "1.18.2",
|
"@microsoft/sp-module-interfaces": "1.20.2",
|
||||||
"@rushstack/eslint-config": "2.5.1",
|
"@rushstack/eslint-config": "4.0.1",
|
||||||
"@types/react": "17.0.45",
|
"@types/react": "17.0.45",
|
||||||
"@types/react-dom": "17.0.17",
|
"@types/react-dom": "17.0.17",
|
||||||
"@types/webpack-env": "~1.15.2",
|
"@types/webpack-env": "~1.15.2",
|
||||||
"ajv": "^6.12.5",
|
"ajv": "^6.12.5",
|
||||||
"eslint": "8.7.0",
|
"eslint": "8.57.0",
|
||||||
"eslint-plugin-react-hooks": "4.3.0",
|
"eslint-plugin-react-hooks": "4.3.0",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"typescript": "4.7.4"
|
"typescript": "4.7.4"
|
||||||
|
|
|
@ -1,54 +1,54 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Swiper, SwiperSlide } from "swiper/react";
|
import { Swiper, SwiperSlide } from "swiper/react";
|
||||||
import { EffectCoverflow } from "swiper";
|
import { EffectCoverflow } from "swiper";
|
||||||
import { Card, CardPreview } from "@fluentui/react-components"
|
import { Card, CardPreview } from "@fluentui/react-components";
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect, useState } from "react";
|
||||||
import { useListItems } from "pnp-react-hooks/hooks/sp/useListItems"
|
import { useListItems } from "pnp-react-hooks/hooks/sp/useListItems";
|
||||||
import { ListOptions } from "pnp-react-hooks/types/options/ListOptions"
|
import { ListOptions } from "pnp-react-hooks/types/options/ListOptions";
|
||||||
import { useSite } from "pnp-react-hooks/hooks/sp/useSite"
|
import { useSite } from "pnp-react-hooks/hooks/sp/useSite";
|
||||||
|
|
||||||
// Import Swiper styles
|
// Import Swiper styles
|
||||||
import "swiper/swiper.min.css"
|
import "swiper/swiper.min.css";
|
||||||
import "swiper/modules/navigation/navigation.min.css"
|
import "swiper/modules/navigation/navigation.min.css";
|
||||||
import "swiper/modules/pagination/pagination.min.css"
|
import "swiper/modules/pagination/pagination.min.css";
|
||||||
import "swiper/modules/effect-coverflow/effect-coverflow.min.css"
|
import "swiper/modules/effect-coverflow/effect-coverflow.min.css";
|
||||||
|
|
||||||
import { AwardItems } from "../types/AwardItems"
|
import { AwardItems } from "../types/AwardItems";
|
||||||
import styles from "../webparts/awardRecognition/components/AwardRecognition.module.scss"
|
import styles from "../webparts/awardRecognition/components/AwardRecognition.module.scss";
|
||||||
import { Content } from "./Content"
|
import { Content } from "./Content";
|
||||||
|
|
||||||
export const Carousel = (): JSX.Element => {
|
export const Carousel = (): JSX.Element => {
|
||||||
const [awardList, setAwardList] = useState<AwardItems[]>([])
|
const [awardList, setAwardList] = useState<AwardItems[]>([]);
|
||||||
const [selectedUser, setSelectedUser] = useState<AwardItems | null>(null)
|
const [selectedUser, setSelectedUser] = useState<AwardItems | null>(null);
|
||||||
|
|
||||||
const listItems = useListItems<AwardItems>("Award Recognition", {
|
const listItems = useListItems<AwardItems>("Award Recognition", {
|
||||||
query: {
|
query: {
|
||||||
select: ["ID", "Title", "Designation", "UserImage"],
|
select: ["ID", "Title", "Designation", "UserImage"],
|
||||||
},
|
},
|
||||||
mode: ListOptions.All,
|
mode: ListOptions.All,
|
||||||
})
|
});
|
||||||
|
|
||||||
const siteInfo = useSite()
|
const siteInfo = useSite();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (listItems && listItems.length > 0) {
|
if (listItems && listItems.length > 0) {
|
||||||
const parsedData = listItems.map((item) => {
|
const parsedData = listItems.map((item) => {
|
||||||
const AppImageUrl = JSON.parse(item.UserImage)
|
const AppImageUrl = JSON.parse(item.UserImage);
|
||||||
const ImageUrl = `${siteInfo.Url}/Lists/Award%20Recognition/Attachments/${item.ID}/${AppImageUrl.fileName}`
|
const ImageUrl = `${siteInfo.Url}/Lists/Award%20Recognition/Attachments/${item.ID}/${AppImageUrl.fileName}`;
|
||||||
return { ...item, ImageUrl }
|
return { ...item, ImageUrl };
|
||||||
})
|
});
|
||||||
setAwardList(parsedData)
|
setAwardList(parsedData);
|
||||||
if (selectedUser === null) {
|
if (selectedUser === null) {
|
||||||
setSelectedUser(parsedData[0])
|
setSelectedUser(parsedData[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [listItems, selectedUser, siteInfo])
|
}, [listItems, selectedUser, siteInfo]);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const handleSlideChange = (swiper: any): void => {
|
const handleSlideChange = (swiper: any): void => {
|
||||||
const activeIndex = swiper.activeIndex
|
const activeIndex = swiper.activeIndex;
|
||||||
setSelectedUser(awardList[activeIndex])
|
setSelectedUser(awardList[activeIndex]);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
|
@ -56,8 +56,10 @@ export const Carousel = (): JSX.Element => {
|
||||||
<Content user={selectedUser} />
|
<Content user={selectedUser} />
|
||||||
</aside>
|
</aside>
|
||||||
<aside className={styles.carouselWrapper}>
|
<aside className={styles.carouselWrapper}>
|
||||||
|
<div className={styles.fade_left}></div>
|
||||||
|
<div className={styles.fade_right}></div>
|
||||||
<Swiper
|
<Swiper
|
||||||
effect='coverflow'
|
effect="coverflow"
|
||||||
grabCursor={true}
|
grabCursor={true}
|
||||||
coverflowEffect={{
|
coverflowEffect={{
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
|
@ -93,8 +95,8 @@ export const Carousel = (): JSX.Element => {
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CardPreview>
|
<CardPreview style={{ height: "inherit" }}>
|
||||||
<img src={user.ImageUrl} alt={user.Title}/>
|
<img src={user.ImageUrl} alt={user.Title} />
|
||||||
</CardPreview>
|
</CardPreview>
|
||||||
</Card>
|
</Card>
|
||||||
</SwiperSlide>
|
</SwiperSlide>
|
||||||
|
@ -102,5 +104,5 @@ export const Carousel = (): JSX.Element => {
|
||||||
</Swiper>
|
</Swiper>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
|
@ -26,6 +26,7 @@ $primaryColor: "[theme: themePrimary, default: #0078d7]";
|
||||||
}
|
}
|
||||||
.carouselWrapper {
|
.carouselWrapper {
|
||||||
width: 70%;
|
width: 70%;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.contentDescriptionWrapper {
|
.contentDescriptionWrapper {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -36,3 +37,26 @@ $primaryColor: "[theme: themePrimary, default: #0078d7]";
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.2rem;
|
gap: 0.2rem;
|
||||||
}
|
}
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade
|
||||||
|
.fade_left,
|
||||||
|
.fade_right {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 4rem; /* Equivalent to w-16 in Tailwind */
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade_left {
|
||||||
|
left: 0;
|
||||||
|
background: linear-gradient(to right, white, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade_right {
|
||||||
|
right: 0;
|
||||||
|
background: linear-gradient(to left, white, transparent);
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
define([], function () {
|
define([], function () {
|
||||||
return {
|
return {
|
||||||
PropertyPaneDescription: "Description",
|
PropertyPaneDescription: "Configure this webpart",
|
||||||
BasicGroupName: "Configure this webpart",
|
BasicGroupName: "Basic Settings",
|
||||||
WebpartFieldLabel: "Webpart Title",
|
WebpartFieldLabel: "Header",
|
||||||
ContentTitleFieldLabel: "Content Title",
|
ContentTitleFieldLabel: "Sub heading",
|
||||||
ContentDescriptionFieldLabel: "Content Description",
|
ContentDescriptionFieldLabel: "Sub heading description",
|
||||||
AppLocalEnvironmentSharePoint:
|
AppLocalEnvironmentSharePoint:
|
||||||
"The app is running on your local environment as SharePoint web part",
|
"The app is running on your local environment as SharePoint web part",
|
||||||
AppLocalEnvironmentTeams:
|
AppLocalEnvironmentTeams:
|
||||||
|
|
Loading…
Reference in New Issue