diff --git a/.changeset/fresh-news-push.md b/.changeset/fresh-news-push.md new file mode 100644 index 0000000000..a77b7a256b --- /dev/null +++ b/.changeset/fresh-news-push.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-bazaar': patch +--- + +`HomePageBazaarInfoCard` is now displaying `title` instead of `name`. Title is a string that doesn't have to be URL friendly. +The BazaarOverviewCard have the new property `fullHeight`. Link in `BazaarOverviewCard`is moved to header in card. diff --git a/.changeset/pretty-eagles-matter.md b/.changeset/pretty-eagles-matter.md new file mode 100644 index 0000000000..64eabd9ce6 --- /dev/null +++ b/.changeset/pretty-eagles-matter.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-bazaar-backend': patch +--- + +Column `title` has replaced column `name` for `BazaarProject` in database diff --git a/plugins/bazaar-backend/knexfile.js b/plugins/bazaar-backend/knexfile.js new file mode 100644 index 0000000000..c05af246c5 --- /dev/null +++ b/plugins/bazaar-backend/knexfile.js @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Update with your config settings. + +// This file makes it possible to run "yarn knex migrate:make some_file_name" +// to assist in making new migrations +module.exports = { + client: 'better-sqlite3', + connection: ':memory:', + useNullAsDefault: true, + migrations: { + directory: './migrations', + }, +}; diff --git a/plugins/bazaar-backend/migrations/20221121120212_rename_col_to_title.js b/plugins/bazaar-backend/migrations/20221121120212_rename_col_to_title.js new file mode 100644 index 0000000000..9974c9eb20 --- /dev/null +++ b/plugins/bazaar-backend/migrations/20221121120212_rename_col_to_title.js @@ -0,0 +1,35 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('metadata', table => { + table.renameColumn('name', 'title'); + }); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('metadata', table => { + table.renameColumn('title', 'name'); + }); +}; diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts index 371d20ff13..be4f82f580 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts @@ -19,7 +19,7 @@ import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { Knex as KnexType } from 'knex'; const bazaarProject: any = { - name: 'n1', + title: 'n1', entityRef: 'ref1', community: '', status: 'proposed', @@ -64,7 +64,7 @@ describe('DatabaseHandler', () => { await knex('metadata').insert({ entity_ref: bazaarProject.entityRef, - name: bazaarProject.name, + title: bazaarProject.title, description: bazaarProject.description, community: bazaarProject.community, status: bazaarProject.status, diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.ts index 8fbe985a10..f75ea8b782 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.ts @@ -52,7 +52,7 @@ export class DatabaseHandler { private columns = [ 'metadata.id', 'metadata.entity_ref', - 'metadata.name', + 'metadata.title', 'metadata.description', 'metadata.status', 'metadata.updated_at', @@ -116,7 +116,7 @@ export class DatabaseHandler { async insertMetadata(bazaarProject: any) { const { - name, + title, entityRef, community, description, @@ -129,7 +129,7 @@ export class DatabaseHandler { await this.client .insert({ - name, + title, entity_ref: entityRef, community, description, @@ -145,7 +145,7 @@ export class DatabaseHandler { async updateMetadata(bazaarProject: any) { const { - name, + title, id, entityRef, community, @@ -158,7 +158,7 @@ export class DatabaseHandler { } = bazaarProject; return await this.client('metadata').where({ id: id }).update({ - name, + title, entity_ref: entityRef, description, community, diff --git a/plugins/bazaar/README.md b/plugins/bazaar/README.md index 40b2a8afbe..0798888a23 100644 --- a/plugins/bazaar/README.md +++ b/plugins/bazaar/README.md @@ -80,13 +80,13 @@ export const homePage = ( + + -+ ++ + {/* ...other homepage items */} ``` -The property `fullWidth` is optional and can be used to adjust the card to fit a grid with column width 12. +The properties `fullHeight` and `fullWidth` are optional and can be used to adjust the cards styling. ## How does the Bazaar work? @@ -106,7 +106,7 @@ To add a project to the bazaar, simply click on the `add-project` button and fil The following fields are mandatory: -- name - name of the project on URL safe format +- title - title of the project - description - present your idea and what skills you are looking for - status - whether or not the project has started - size - small, medium or large diff --git a/plugins/bazaar/api-report.md b/plugins/bazaar/api-report.md index c12c95a1f7..a17927cd77 100644 --- a/plugins/bazaar/api-report.md +++ b/plugins/bazaar/api-report.md @@ -17,6 +17,7 @@ export const BazaarOverviewCard: ( export type BazaarOverviewCardProps = { order: 'latest' | 'random'; fullWidth?: boolean; + fullHeight?: boolean; }; // @public (undocumented) diff --git a/plugins/bazaar/media/layout.png b/plugins/bazaar/media/layout.png index cc02a374a3..86c95f1e6e 100644 Binary files a/plugins/bazaar/media/layout.png and b/plugins/bazaar/media/layout.png differ diff --git a/plugins/bazaar/media/overviewCard.png b/plugins/bazaar/media/overviewCard.png index 676764f6e4..6769aa34ca 100644 Binary files a/plugins/bazaar/media/overviewCard.png and b/plugins/bazaar/media/overviewCard.png differ diff --git a/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx b/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx index 749fcf3cff..45392206d9 100644 --- a/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx +++ b/plugins/bazaar/src/components/AddProjectDialog/AddProjectDialog.tsx @@ -42,8 +42,7 @@ export const AddProjectDialog = ({ const [selectedEntity, setSelectedEntity] = useState(null); const defaultValues = { - name: '', - title: 'Add project', + title: '', community: '', description: '', status: 'proposed' as Status, @@ -65,6 +64,7 @@ export const AddProjectDialog = ({ reset: UseFormReset, ) => { const formValues = getValues(); + const response = await bazaarApi.addProject({ ...formValues, entityRef: selectedEntity ? stringifyEntityRef(selectedEntity) : null, diff --git a/plugins/bazaar/src/components/BazaarOverviewCard/BazaarOverviewCard.tsx b/plugins/bazaar/src/components/BazaarOverviewCard/BazaarOverviewCard.tsx index d64e36baeb..d30eaa3620 100644 --- a/plugins/bazaar/src/components/BazaarOverviewCard/BazaarOverviewCard.tsx +++ b/plugins/bazaar/src/components/BazaarOverviewCard/BazaarOverviewCard.tsx @@ -24,13 +24,16 @@ import type { BazaarProject } from '../../types'; import { bazaarApiRef } from '../../api'; import { fetchCatalogItems } from '../../util/fetchMethods'; import { parseBazaarProject } from '../../util/parseMethods'; -import { ErrorPanel, InfoCard } from '@backstage/core-components'; +import { ErrorPanel, InfoCard, Link } from '@backstage/core-components'; import { bazaarPlugin } from '../../plugin'; +import { IconButton } from '@material-ui/core'; +import StorefrontIcon from '@material-ui/icons/Storefront'; /** @public */ export type BazaarOverviewCardProps = { order: 'latest' | 'random'; fullWidth?: boolean; + fullHeight?: boolean; }; const getUnlinkedCatalogEntities = ( @@ -48,7 +51,7 @@ const getUnlinkedCatalogEntities = ( /** @public */ export const BazaarOverviewCard = (props: BazaarOverviewCardProps) => { - const { order, fullWidth = false } = props; + const { order, fullWidth = false, fullHeight = false } = props; const bazaarApi = useApi(bazaarApiRef); const catalogApi = useApi(catalogApiRef); const root = useRouteRef(bazaarPlugin.routes.root); @@ -127,7 +130,13 @@ export const BazaarOverviewCard = (props: BazaarOverviewCardProps) => { title={ order === 'latest' ? 'Bazaar Latest Projects' : 'Bazaar Random Projects' } - deepLink={bazaarLink} + action={ + + + + + + } > { catalogEntities={unlinkedCatalogEntities || []} useTablePagination={false} gridSize={fullWidth ? 2 : 4} + height={fullHeight ? '13rem' : '7rem'} /> ); diff --git a/plugins/bazaar/src/components/CardContentFields/CardContentFields.tsx b/plugins/bazaar/src/components/CardContentFields/CardContentFields.tsx index 641ae97f95..82ab9df89d 100644 --- a/plugins/bazaar/src/components/CardContentFields/CardContentFields.tsx +++ b/plugins/bazaar/src/components/CardContentFields/CardContentFields.tsx @@ -17,7 +17,6 @@ import React from 'react'; import { Grid, - makeStyles, Card, CardContent, Typography, @@ -31,13 +30,6 @@ import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { StatusTag } from '../StatusTag'; import { Member, BazaarProject } from '../../types'; -const useStyles = makeStyles({ - break: { - wordBreak: 'break-word', - textAlign: 'justify', - }, -}); - type Props = { bazaarProject: BazaarProject; members: Member[]; @@ -51,7 +43,6 @@ export const CardContentFields = ({ descriptionSize, membersSize, }: Props) => { - const classes = useStyles(); const catalogEntityRoute = useRouteRef(entityRouteRef); return ( @@ -64,12 +55,7 @@ export const CardContentFields = ({ {bazaarProject.description .split('\n') .map((str: string, i: number) => ( - + {str} ))} @@ -114,7 +100,6 @@ export const CardContentFields = ({ picture={member.picture} /> - {bazaarProject.name} + + {bazaarProject.title} , ' from the Bazaar?', ]} diff --git a/plugins/bazaar/src/components/EntityBazaarInfoContent/EntityBazaarInfoContent.tsx b/plugins/bazaar/src/components/EntityBazaarInfoContent/EntityBazaarInfoContent.tsx index 0c9da1ed24..a2e5fe151b 100644 --- a/plugins/bazaar/src/components/EntityBazaarInfoContent/EntityBazaarInfoContent.tsx +++ b/plugins/bazaar/src/components/EntityBazaarInfoContent/EntityBazaarInfoContent.tsx @@ -173,7 +173,7 @@ export const EntityBazaarInfoContent = ({ {parseEntityRef(bazaarProject.entityRef!).name} , ' from ', - {bazaarProject.name}, + {bazaarProject.title}, ' ?', ]} type="unlink" @@ -182,7 +182,7 @@ export const EntityBazaarInfoContent = ({ )} {bazaarProject?.name!}

} + title={

{bazaarProject?.title!}

} action={
, ' from ', - {bazaarProject.value?.name}, + {bazaarProject.value?.title}, ' ?', ]} type="unlink" @@ -257,7 +257,7 @@ export const HomePageBazaarInfoCard = ({ - {bazaarProject.value?.name || initProject.name} + {bazaarProject.value?.title || initProject.title}

} action={ diff --git a/plugins/bazaar/src/components/InputField/InputField.tsx b/plugins/bazaar/src/components/InputField/InputField.tsx index cae22a1313..a2c8ca4ac4 100644 --- a/plugins/bazaar/src/components/InputField/InputField.tsx +++ b/plugins/bazaar/src/components/InputField/InputField.tsx @@ -30,7 +30,7 @@ type Rules = { }; type Props = { - inputType: 'description' | 'community' | 'responsible' | 'name'; + inputType: 'description' | 'community' | 'responsible' | 'title'; error?: FieldError | undefined; control: Control; helperText?: string; diff --git a/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx b/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx index fcae411519..9193215804 100644 --- a/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx +++ b/plugins/bazaar/src/components/ProjectCard/ProjectCard.tsx @@ -34,7 +34,7 @@ type Props = { project: BazaarProject; fetchBazaarProjects: () => Promise; catalogEntities: Entity[]; - fullHeight?: boolean; + height?: string; }; const useStyles = makeStyles({ @@ -48,7 +48,6 @@ const useStyles = makeStyles({ WebkitLineClamp: 7, WebkitBoxOrient: 'vertical', overflow: 'hidden', - textAlign: 'justify', }, memberCount: { float: 'right', @@ -60,6 +59,7 @@ const useStyles = makeStyles({ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', + height: '5rem', }, }); @@ -67,10 +67,11 @@ export const ProjectCard = ({ project, fetchBazaarProjects, catalogEntities, + height, }: Props) => { const classes = useStyles(); const [openCard, setOpenCard] = useState(false); - const { id, name, status, updatedAt, description, membersCount } = project; + const { id, title, status, updatedAt, description, membersCount } = project; const handleClose = () => { setOpenCard(false); @@ -93,7 +94,7 @@ export const ProjectCard = ({ classes={{ root: classes.header }} title={ - {name} + {title} } subtitle={`updated ${DateTime.fromISO( @@ -102,7 +103,7 @@ export const ProjectCard = ({ base: DateTime.now(), })}`} /> - + {Number(membersCount) === Number(1) diff --git a/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx b/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx index 2f8b9e9cb9..ec7312576d 100644 --- a/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx +++ b/plugins/bazaar/src/components/ProjectDialog/ProjectDialog.tsx @@ -89,16 +89,14 @@ export const ProjectDialog = ({ - @@ -142,7 +140,7 @@ export const ProjectDialog = ({ pattern: RegExp('^(https?)://'), }} inputType="community" - helperText="please enter a link starting with http/https" + helperText="Please enter a link starting with http/https" placeholder="Community link to e.g. Teams or Discord" /> diff --git a/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx b/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx index 7dd82edf94..216cf50c2f 100644 --- a/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx +++ b/plugins/bazaar/src/components/ProjectPreview/ProjectPreview.tsx @@ -27,6 +27,7 @@ type Props = { catalogEntities: Entity[]; useTablePagination?: boolean; gridSize?: GridSize; + height: string; }; const useStyles = makeStyles({ @@ -55,6 +56,7 @@ export const ProjectPreview = ({ catalogEntities, useTablePagination = true, gridSize = 2, + height, }: Props) => { const classes = useStyles(); const [page, setPage] = useState(1); @@ -90,6 +92,7 @@ export const ProjectPreview = ({ key={i} fetchBazaarProjects={fetchBazaarProjects} catalogEntities={catalogEntities} + height={height} /> ); diff --git a/plugins/bazaar/src/components/SortView/SortView.tsx b/plugins/bazaar/src/components/SortView/SortView.tsx index 75f5bbeb34..68b63a6885 100644 --- a/plugins/bazaar/src/components/SortView/SortView.tsx +++ b/plugins/bazaar/src/components/SortView/SortView.tsx @@ -27,7 +27,7 @@ import { BazaarProject } from '../../types'; import { bazaarApiRef } from '../../api'; import { Alert } from '@material-ui/lab'; import SearchBar from 'material-ui-search-bar'; -import { sortByDate, sortByMembers, sortByName } from '../../util/sortMethods'; +import { sortByDate, sortByMembers, sortByTitle } from '../../util/sortMethods'; import { SortMethodSelector } from '../SortMethodSelector'; import { fetchCatalogItems } from '../../util/fetchMethods'; import { parseBazaarProject } from '../../util/parseMethods'; @@ -71,7 +71,7 @@ export const SortView = () => { const bazaarApi = useApi(bazaarApiRef); const catalogApi = useApi(catalogApiRef); const classes = useStyles(); - const sortMethods = [sortByDate, sortByName, sortByMembers]; + const sortMethods = [sortByDate, sortByTitle, sortByMembers]; const [sortMethodNbr, setSortMethodNbr] = useState(0); const [openAdd, setOpenAdd] = useState(false); const [searchValue, setSearchValue] = useState(''); @@ -99,7 +99,7 @@ export const SortView = () => { const getSearchResults = () => { return bazaarProjects.value - ?.filter(project => project.name.includes(searchValue)) + ?.filter(project => project.title.includes(searchValue)) .sort(sortMethods[sortMethodNbr]); }; @@ -199,6 +199,7 @@ export const SortView = () => { bazaarProjects={getSearchResults() || []} fetchBazaarProjects={fetchBazaarProjects} catalogEntities={unlinkedCatalogEntities || []} + height="13rem" /> diff --git a/plugins/bazaar/src/types.ts b/plugins/bazaar/src/types.ts index e698f21264..055ec2fcab 100644 --- a/plugins/bazaar/src/types.ts +++ b/plugins/bazaar/src/types.ts @@ -27,7 +27,7 @@ export type Status = 'ongoing' | 'proposed'; export type Size = 'small' | 'medium' | 'large'; export type BazaarProject = { - name: string; + title: string; id: number; entityRef?: string; community: string; @@ -42,7 +42,7 @@ export type BazaarProject = { }; export type FormValues = { - name: string; + title: string; description: string; community: string; status: string; diff --git a/plugins/bazaar/src/util/parseMethods.ts b/plugins/bazaar/src/util/parseMethods.ts index b32c5d42d3..b93f70c9f1 100644 --- a/plugins/bazaar/src/util/parseMethods.ts +++ b/plugins/bazaar/src/util/parseMethods.ts @@ -20,7 +20,7 @@ export const parseBazaarProject = (metadata: any): BazaarProject => { return { id: metadata.id, entityRef: metadata.entity_ref, - name: metadata.name, + title: metadata.title, community: metadata.community, description: metadata.description, status: metadata.status, diff --git a/plugins/bazaar/src/util/sortMethods.ts b/plugins/bazaar/src/util/sortMethods.ts index d75639edca..d7ef71c8de 100644 --- a/plugins/bazaar/src/util/sortMethods.ts +++ b/plugins/bazaar/src/util/sortMethods.ts @@ -26,10 +26,10 @@ export const sortByDate = (a: BazaarProject, b: BazaarProject): number => { return dateB - dateA; }; -export const sortByName = (a: BazaarProject, b: BazaarProject) => { - if (a.name < b.name) { +export const sortByTitle = (a: BazaarProject, b: BazaarProject) => { + if (a.title < b.title) { return -1; - } else if (a.name > b.name) { + } else if (a.title > b.title) { return 1; } return 0;