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

14 PR Merges #1

Merged
merged 43 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
696cb19
feat: add opengraph tags to website
SethFalco Jul 23, 2022
69793bb
docs: noteable > notable in contribution guide
SethFalco Jul 23, 2022
ffd8233
display confirmation if there is any content
Mar 2, 2023
dee123a
moved isCardEmpty into utils
Mar 3, 2023
b8386b2
changed the function into a redux selector
Mar 3, 2023
80d2bac
fix tests
Mar 3, 2023
8799eb1
changed selector into hook, to use existing selectors
Mar 5, 2023
293b62a
created fullCalendarCard
Mar 5, 2023
4d14413
removed the event prop as it was unnecesary
Mar 7, 2023
13d8859
added unit tests for FullCalendarCard component
Mar 7, 2023
77b5086
Fix indentation for tsconfix.json
availchet Mar 11, 2023
193d8dd
Merge branch 'mattermost:main' into patch-1
availchet Mar 11, 2023
ef31f87
Merge branch 'main' into GH-4476-No-card-delete-confirmation-status
mattermost-build Mar 29, 2023
347a49f
4621 Added color property to react-select singleValue
Apr 9, 2023
f7b8dda
Max width for tooltip is disabled ...
Apr 9, 2023
05ae50c
Overflow of table selector is changed from...
Apr 10, 2023
a550108
Merge branch 'main' into assignee-not-visible-in-dark-mode
mattermost-build May 1, 2023
7d99f7d
fixed Bug:After deleting a board, using the undo feature would redire…
V1nnncJune Sep 9, 2023
c40df74
Merge branch 'main' into fix-board_deletion_not_found_error
mattermost-build Sep 27, 2023
65e796e
Replace a non-semantic JSX child in one of the test files with an emp…
Andarist Oct 8, 2023
6b5a3b2
Merge branch 'main' into fix-board_deletion_not_found_error
mattermost-build Oct 17, 2023
8071eb8
prevent ModifiedBy overwrite
omggga Oct 18, 2023
60b2e2a
Update win-wpf app to persist user settings (issue #314)
baong12 Oct 27, 2023
cd5233c
Add import csv feature
Jneville0815 Oct 31, 2023
302e134
Standalone PWA
BhasherBEL Oct 31, 2023
2186710
Update blocks.go
alemon0 Dec 7, 2023
c8b0f75
MM-52722: Fixed error when accessing property on undefined
srisri332 Dec 18, 2023
05509b7
Merge pull request #1 from BhasherBEL/main
Kuuchuu May 9, 2024
56f3761
Merge pull request #2 from srisri332/MM-52722
Kuuchuu May 9, 2024
62eef79
Merge pull request #3 from alemon0/main
Kuuchuu May 9, 2024
0510d30
Merge pull request #4 from radiusmethod/feature/import_csv
Kuuchuu May 9, 2024
d593c8b
Merge pull request #5 from baong12/feature/win-settings
Kuuchuu May 9, 2024
da9260e
Merge pull request #6 from omggga/read_userid_from_jsonl
Kuuchuu May 9, 2024
daee5c1
Merge pull request #7 from Andarist/fix/invalid-jsx-children
Kuuchuu May 9, 2024
43cc621
Merge pull request #8 from V1nnncJune/fix-board_deletion_not_found_error
Kuuchuu May 9, 2024
af44fe9
Merge pull request #9 from barisunsalhn/template-selector-horizontall…
Kuuchuu May 9, 2024
7281b63
Merge pull request #10 from barisunsalhn/tooltip-on-attachment-not-fu…
Kuuchuu May 9, 2024
836566a
Merge pull request #11 from barisunsalhn/assignee-not-visible-in-dark…
Kuuchuu May 9, 2024
50970aa
Merge pull request #12 from availchet/patch-1
Kuuchuu May 9, 2024
a10abae
Merge pull request #13 from JesusMurguia/GH-4476-No-card-delete-confi…
Kuuchuu May 9, 2024
c4bcfe8
Revert "docs: noteable > notable in contribution guide"
Kuuchuu May 9, 2024
3e72d2f
Merge pull request #17 from Ports-Exposed/feat/add-opengraph
Kuuchuu May 9, 2024
798a5fe
Version Bump | 7.13.0
Kuuchuu May 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions import/csv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
16 changes: 16 additions & 0 deletions import/csv/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# CSV importer

This node app converts a CSV into a Focalboard archive. To use:
1. Run `npm install` from within `focalboard/webapp`
2. Run `npm install` from within `focalboard/import/csv`
3. Run `npx ts-node importCsv.ts -i <path to csv> -o archive.boardarchive`
- If the csv was exported by testrails, pass `-t true` into the command line arguments
4. In Focalboard, click `Settings`, then `Import archive` and select `archive.boardarchive`

## Import scope

Currently, the script imports all cards from a single board, including their properties and markdown content.

The script currently imports all card properties as a Select type. You can change the type after importing into Focalboard.

[Contribute code](https://mattermost.github.io/focalboard/) to expand this.
171 changes: 171 additions & 0 deletions import/csv/importCsv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import csv from 'csvtojson'
import * as fs from 'fs'
import minimist from 'minimist'
import path from 'path'
import {exit} from 'process'
import {ArchiveUtils} from '../util/archive'
import {Block} from '../../webapp/src/blocks/block'
import {Board} from '../../webapp/src/blocks/board'
import {IPropertyTemplate, createBoard} from '../../webapp/src/blocks/board'
import {createBoardView} from '../../webapp/src/blocks/boardView'
import {createCard} from '../../webapp/src/blocks/card'
import {createTextBlock} from '../../webapp/src/blocks/textBlock'
import {Utils} from './utils'

(global.window as any) = {}

const optionColors = [
'propColorGray',
'propColorBrown',
'propColorOrange',
'propColorYellow',
'propColorGreen',
'propColorBlue',
'propColorPurple',
'propColorPink',
'propColorRed',
]
let optionColorIndex = 0

async function main() {
const args: minimist.ParsedArgs = minimist(process.argv.slice(2))

const inputFile = args['i']
const outputFile = args['o'] || 'test/archive.boardarchive'
const testrailFormat = (args['t'] === 'true') || false

if (!inputFile) {
showHelp()
}

if (!fs.existsSync(inputFile)){
console.log(`File not found: ${inputFile}`)
exit(2)
}

console.log(`InputFile: ${inputFile}`)
const input = await csv().fromFile(inputFile)
console.log(`Read ${input.length} rows.`)
console.log(input)

const title = path.basename(inputFile, '.csv')
console.log(`Title: ${title}`)

const [boards, blocks] = convert(input, title, testrailFormat)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)

fs.writeFileSync(outputFile, outputData)
console.log(`Exported to ${outputFile}`)
}

function convert(input: any[], title: string, testrailFormat: boolean): [Board[], Block[]] {
const boards: Board[] = []
const blocks: Block[] = []

// Board
const board = createBoard()
console.log(`Board: ${title}`)
board.title = title

// Each column is a card property
const columns = getColumns(input)
columns.forEach(column => {
if(column === "Steps" && testrailFormat) {
return
} else {
const cardProperty: IPropertyTemplate = {
id: Utils.createGuid(),
name: column,
type: 'select',
options: []
}
board.cardProperties.push(cardProperty)
}
})

// Set all column types to select
// TODO: Detect column type
boards.push(board)

// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.boardId = board.id
view.parentId = board.id
blocks.push(view)

// Cards
input.forEach(row => {
const keys = Object.keys(row)
console.log(keys)
if (keys.length < 1) {
console.error(`Expected at least one column`)
return blocks
}
const titleKey = keys[0]
const title = row[titleKey]

console.log(`Card: ${title}`)

const outCard = createCard()
outCard.title = title
outCard.boardId = board.id
outCard.parentId = board.id

// Card properties, skip first key which is the title
for (const key of keys.slice(1)) {
const value = row[key]
if(key === "Steps" && testrailFormat) {
const block = createTextBlock()
block.title = value
block.boardId = board.id
block.parentId = outCard.id
blocks.push(block)

outCard.fields.contentOrder = [block.id]
continue
}
if (!value) {
// Skip empty values
continue
}

const cardProperty = board.cardProperties.find((o) => o.name === key)!
let option = cardProperty.options.find((o) => o.value === value)
if (!option) {
const color = optionColors[optionColorIndex % optionColors.length]
optionColorIndex += 1
option = {
id: Utils.createGuid(),
value,
color: color,
}
cardProperty.options.push(option)
}

outCard.fields.properties[cardProperty.id] = option.id
}

blocks.push(outCard)
})

console.log('')
console.log(`Found ${input.length} card(s).`)

return [boards, blocks]
}

function getColumns(input: any[]) {
const row = input[0]
const keys = Object.keys(row)
// The first key (column) is the card title
return keys.slice(1)
}

function showHelp() {
console.log('import -i <input.csv> -o [output.boardarchive]')
exit(1)
}

main()
Loading
Loading