1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-01-26 18:48:15 +02:00

Merge remote-tracking branch 'origin/main' into issue-2617

This commit is contained in:
Jesús Espino 2022-04-04 17:23:31 +02:00
commit 67dfb4e118
152 changed files with 1851 additions and 1026 deletions

View File

@ -15,6 +15,7 @@ jobs:
with:
go-version: 1.16
- uses: actions/checkout@v2
- run: make templates-archive
- name: server-lint
uses: golangci/golangci-lint-action@v2
with:

1
.gitignore vendored
View File

@ -45,6 +45,7 @@ __debug_bin
files
octo*.db
focalboard*.db
*.boardarchive
.eslintcache
.vscode/settings.json
# config.json is copied from app-config.json in the Makefile

View File

@ -1,4 +1,4 @@
.PHONY: prebuild clean cleanall ci server server-mac server-linux server-win server-linux-package generate watch-server webapp mac-app win-app-wpf linux-app modd-precheck
.PHONY: prebuild clean cleanall ci server server-mac server-linux server-win server-linux-package generate watch-server webapp mac-app win-app-wpf linux-app modd-precheck templates-archive
PACKAGE_FOLDER = focalboard
@ -35,25 +35,28 @@ ci: server-test
cd webapp; npm run test
cd webapp; npm run cypress:ci
server: ## Build server for local environment.
templates-archive: ## Build templates archive file
cd server/assets/build-template-archive; go run -tags '$(BUILD_TAGS)' main.go --dir="../templates-boardarchive" --out="../templates.boardarchive"
server: templates-archive ## Build server for local environment.
$(eval LDFLAGS += -X "github.com/mattermost/focalboard/server/model.Edition=dev")
cd server; go build -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' -o ../bin/focalboard-server ./main
server-mac: ## Build server for Mac.
server-mac: templates-archive ## Build server for Mac.
mkdir -p bin/mac
$(eval LDFLAGS += -X "github.com/mattermost/focalboard/server/model.Edition=mac")
cd server; env GOOS=darwin GOARCH=$(MAC_GO_ARCH) go build -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' -o ../bin/mac/focalboard-server ./main
server-linux: ## Build server for Linux.
server-linux: templates-archive ## Build server for Linux.
mkdir -p bin/linux
$(eval LDFLAGS += -X "github.com/mattermost/focalboard/server/model.Edition=linux")
cd server; env GOOS=linux GOARCH=amd64 go build -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' -o ../bin/linux/focalboard-server ./main
server-win: ## Build server for Windows.
server-win: templates-archive ## Build server for Windows.
$(eval LDFLAGS += -X "github.com/mattermost/focalboard/server/model.Edition=win")
cd server; env GOOS=windows GOARCH=amd64 go build -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' -o ../bin/win/focalboard-server.exe ./main
server-dll: ## Build server as Windows DLL.
server-dll: templates-archive ## Build server as Windows DLL.
$(eval LDFLAGS += -X "github.com/mattermost/focalboard/server/model.Edition=win")
cd server; env GOOS=windows GOARCH=amd64 go build -ldflags '$(LDFLAGS)' -tags '$(BUILD_TAGS)' -buildmode=c-shared -o ../bin/win-dll/focalboard-server.dll ./main
@ -87,7 +90,7 @@ generate: ## Install and run code generators.
cd server; go get -modfile=go.tools.mod github.com/golang/mock/mockgen
cd server; go generate ./...
server-lint: ## Run linters on server code.
server-lint: templates-archive ## Run linters on server code.
@if ! [ -x "$$(command -v golangci-lint)" ]; then \
echo "golangci-lint is not installed. Please see https://github.com/golangci/golangci-lint#install for installation instructions."; \
exit 1; \
@ -112,14 +115,14 @@ watch-server-test: modd-precheck ## Run server tests watching for changes
server-test: server-test-sqlite server-test-mysql server-test-postgres ## Run server tests
server-test-sqlite: ## Run server tests using sqlite
server-test-sqlite: templates-archive ## Run server tests using sqlite
cd server; go test -tags '$(BUILD_TAGS)' -race -v -count=1 -timeout=30m ./...
server-test-mysql: export FB_UNIT_TESTING=1
server-test-mysql: export FB_STORE_TEST_DB_TYPE=mysql
server-test-mysql: export FB_STORE_TEST_DOCKER_PORT=44445
server-test-mysql: ## Run server tests using mysql
server-test-mysql: templates-archive ## Run server tests using mysql
@echo Starting docker container for mysql
docker-compose -f ./docker-testing/docker-compose-mysql.yml down -v --remove-orphans
docker-compose -f ./docker-testing/docker-compose-mysql.yml run start_dependencies
@ -130,7 +133,7 @@ server-test-postgres: export FB_UNIT_TESTING=1
server-test-postgres: export FB_STORE_TEST_DB_TYPE=postgres
server-test-postgres: export FB_STORE_TEST_DOCKER_PORT=44446
server-test-postgres: ## Run server tests using postgres
server-test-postgres: templates-archive ## Run server tests using postgres
@echo Starting docker container for postgres
docker-compose -f ./docker-testing/docker-compose-postgres.yml down -v --remove-orphans
docker-compose -f ./docker-testing/docker-compose-postgres.yml run start_dependencies

View File

@ -5,6 +5,7 @@ import minimist from 'minimist'
import {exit} from 'process'
import {ArchiveUtils} from '../util/archive'
import {Block} from '../../webapp/src/blocks/block'
import {Board} from '../../webapp/src/blocks/board'
import {IPropertyOption, IPropertyTemplate, createBoard} from '../../webapp/src/blocks/board'
import {createBoardView} from '../../webapp/src/blocks/boardView'
import {createCard} from '../../webapp/src/blocks/card'
@ -49,11 +50,11 @@ function main() {
const input = JSON.parse(inputData) as Asana
// Convert
const blocks = convert(input)
const [boards, blocks] = convert(input)
// Save output
// TODO: Stream output
const outputData = ArchiveUtils.buildBlockArchive(blocks)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)
fs.writeFileSync(outputFile, outputData)
console.log(`Exported to ${outputFile}`)
@ -88,22 +89,22 @@ function getSections(input: Asana, projectId: string): Workspace[] {
return [...sectionMap.values()]
}
function convert(input: Asana): Block[] {
function convert(input: Asana): [Board[], Block[]] {
const projects = getProjects(input)
if (projects.length < 1) {
console.error('No projects found')
return []
return [[],[]]
}
// TODO: Handle multiple projects
const project = projects[0]
const boards: Board[] = []
const blocks: Block[] = []
// Board
const board = createBoard()
console.log(`Board: ${project.name}`)
board.rootId = board.id
board.title = project.name
// Convert sections (columns) to a Select property
@ -130,14 +131,14 @@ function convert(input: Asana): Block[] {
options
}
board.cardProperties = [cardProperty]
blocks.push(board)
boards.push(board)
// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.rootId = board.id
view.parentId = board.id
view.boardId = board.id
blocks.push(view)
// Cards
@ -146,7 +147,7 @@ function convert(input: Asana): Block[] {
const outCard = createCard()
outCard.title = card.name
outCard.rootId = board.id
outCard.boardId = board.id
outCard.parentId = board.id
// Map lists to Select property options
@ -168,8 +169,8 @@ function convert(input: Asana): Block[] {
// console.log(`\t${card.notes}`)
const text = createTextBlock()
text.title = card.notes
text.rootId = board.id
text.parentId = outCard.id
text.boardId = board.id
blocks.push(text)
outCard.fields.contentOrder = [text.id]
@ -179,7 +180,7 @@ function convert(input: Asana): Block[] {
console.log('')
console.log(`Found ${input.data.length} card(s).`)
return blocks
return [boards, blocks]
}
function showHelp() {

View File

@ -3,7 +3,7 @@
import {run} from './jiraImporter'
import * as fs from 'fs'
import {ArchiveUtils} from '../../webapp/src/blocks/archive'
import {ArchiveUtils} from '../util/archive'
const inputFile = './test/jira-export.xml'
const outputFile = './test/jira.focalboard'
@ -27,10 +27,6 @@ describe('import from Jira', () => {
expect(blocks).toEqual(
expect.arrayContaining([
expect.objectContaining({
title: 'Jira import',
type: 'board'
}),
expect.objectContaining({
title: 'Board View',
type: 'view'

View File

@ -4,6 +4,7 @@ import * as fs from 'fs'
import {exit} from 'process'
import {ArchiveUtils} from '../util/archive'
import {Block} from '../../webapp/src/blocks/block'
import {Board} from '../../webapp/src/blocks/board'
import {IPropertyOption, IPropertyTemplate, createBoard} from '../../webapp/src/blocks/board'
import {createBoardView} from '../../webapp/src/blocks/boardView'
import {Card, createCard} from '../../webapp/src/blocks/card'
@ -70,23 +71,23 @@ async function run(inputFile: string, outputFile: string): Promise<number> {
// console.dir(items);
// Convert
const blocks = convert(items)
const [boards, blocks] = convert(items)
// Save output
// TODO: Stream output
const outputData = ArchiveUtils.buildBlockArchive(blocks)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)
fs.writeFileSync(outputFile, outputData)
console.log(`Exported ${blocks.length} block(s) to ${outputFile}`)
return blocks.length
}
function convert(items: any[]) {
function convert(items: any[]): [Board[], Block[]] {
const boards: Board[] = []
const blocks: Block[] = []
// Board
const board = createBoard()
board.rootId = board.id
board.title = 'Jira import'
// Compile standard properties
@ -126,13 +127,13 @@ function convert(items: any[]) {
}
board.cardProperties.push(createdDateProperty)
blocks.push(board)
boards.push(board)
// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.rootId = board.id
view.boardId = board.id
view.parentId = board.id
blocks.push(view)
@ -145,7 +146,7 @@ function convert(items: any[]) {
const card = createCard()
card.title = item.summary
card.rootId = board.id
card.boardId = board.id
card.parentId = board.id
// Map standard properties
@ -169,7 +170,7 @@ function convert(items: any[]) {
console.log(`\t${description}`)
const text = createTextBlock()
text.title = description
text.rootId = board.id
text.boardId = board.id
text.parentId = card.id
blocks.push(text)
@ -179,7 +180,7 @@ function convert(items: any[]) {
blocks.push(card)
}
return blocks
return [boards, blocks]
}
function buildCardPropertyFromValues(propertyName: string, allValues: string[]) {

View File

@ -3,8 +3,9 @@
import * as fs from 'fs'
import minimist from 'minimist'
import {exit} from 'process'
import {ArchiveUtils} from '../../webapp/src/blocks/archive'
import {ArchiveUtils} from '../util/archive'
import {Block} from '../../webapp/src/blocks/block'
import {Board as FBBoard} from '../../webapp/src/blocks/board'
import {IPropertyOption, IPropertyTemplate, createBoard} from '../../webapp/src/blocks/board'
import {createBoardView} from '../../webapp/src/blocks/boardView'
import {createCard} from '../../webapp/src/blocks/card'
@ -69,10 +70,10 @@ async function main() {
}))
// Convert
const blocks = convert(board, stacks)
const [boards, blocks] = convert(board, stacks)
// // Save output
const outputData = ArchiveUtils.buildBlockArchive(blocks)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)
fs.writeFileSync(outputFile, outputData)
console.log(`Exported to ${outputFile}`)
@ -85,13 +86,13 @@ async function selectBoard(deckClient: NextcloudDeckClient): Promise<number> {
return readline.questionInt("Enter Board ID: ")
}
function convert(deckBoard: Board, stacks: Stack[]): Block[] {
function convert(deckBoard: Board, stacks: Stack[]): [FBBoard[], Block[]] {
const boards: FBBoard[] = []
const blocks: Block[] = []
// Board
const board = createBoard()
console.log(`Board: ${deckBoard.title}`)
board.rootId = board.id
board.title = deckBoard.title
let colorIndex = 0
@ -145,14 +146,14 @@ function convert(deckBoard: Board, stacks: Stack[]): Block[] {
options: []
}
board.fields.cardProperties = [stackProperty, labelProperty, dueDateProperty]
blocks.push(board)
board.cardProperties = [stackProperty, labelProperty, dueDateProperty]
boards.push(board)
// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.rootId = board.id
view.boardId = board.id
view.parentId = board.id
blocks.push(view)
@ -164,7 +165,7 @@ function convert(deckBoard: Board, stacks: Stack[]): Block[] {
const outCard = createCard()
outCard.title = card.title
outCard.rootId = board.id
outCard.boardId = board.id
outCard.parentId = board.id
// Map Stacks to Select property options
@ -189,7 +190,7 @@ function convert(deckBoard: Board, stacks: Stack[]): Block[] {
if (card.description) {
const text = createTextBlock()
text.title = card.description
text.rootId = board.id
text.boardId = board.id
text.parentId = outCard.id
blocks.push(text)
@ -200,7 +201,7 @@ function convert(deckBoard: Board, stacks: Stack[]): Block[] {
card.comments?.forEach(comment => {
const commentBlock = createCommentBlock()
commentBlock.title = comment.message
commentBlock.rootId = board.id
commentBlock.boardId = board.id
commentBlock.parentId = outCard.id
blocks.push(commentBlock)
})
@ -210,7 +211,7 @@ function convert(deckBoard: Board, stacks: Stack[]): Block[] {
console.log('')
console.log(`Transformed Board ${deckBoard.title} into ${blocks.length} blocks.`)
return blocks
return [boards, blocks]
}
function showHelp() {

View File

@ -5,6 +5,7 @@ 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'
@ -70,11 +71,11 @@ async function main() {
markdownFolder = path.join(inputFolder, basename)
// Convert
const blocks = convert(input, title)
const [boards, blocks] = convert(input, title)
// Save output
// TODO: Stream output
const outputData = ArchiveUtils.buildBlockArchive(blocks)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)
fs.writeFileSync(outputFile, outputData)
console.log(`Exported to ${outputFile}`)
@ -117,13 +118,13 @@ function getColumns(input: any[]) {
return keys.slice(1)
}
function convert(input: any[], title: string): Block[] {
function convert(input: any[], title: string): [Board[], Block[]] {
const boards: Board[] = []
const blocks: Block[] = []
// Board
const board = createBoard()
console.log(`Board: ${title}`)
board.rootId = board.id
board.title = title
// Each column is a card property
@ -140,13 +141,13 @@ function convert(input: any[], title: string): Block[] {
// Set all column types to select
// TODO: Detect column type
blocks.push(board)
boards.push(board)
// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.rootId = board.id
view.boardId = board.id
view.parentId = board.id
blocks.push(view)
@ -166,7 +167,7 @@ function convert(input: any[], title: string): Block[] {
const outCard = createCard()
outCard.title = title
outCard.rootId = board.id
outCard.boardId = board.id
outCard.parentId = board.id
// Card properties, skip first key which is the title
@ -201,7 +202,7 @@ function convert(input: any[], title: string): Block[] {
console.log(`Markdown: ${markdown.length} bytes`)
const text = createTextBlock()
text.title = markdown
text.rootId = board.id
text.boardId = board.id
text.parentId = outCard.id
blocks.push(text)
@ -212,7 +213,7 @@ function convert(input: any[], title: string): Block[] {
console.log('')
console.log(`Found ${input.length} card(s).`)
return blocks
return [boards, blocks]
}
function showHelp() {

View File

@ -5,6 +5,7 @@ import minimist from 'minimist'
import {exit} from 'process'
import {ArchiveUtils} from '../util/archive'
import {Block} from '../../webapp/src/blocks/block'
import {Board} from '../../webapp/src/blocks/board'
import {IPropertyOption, IPropertyTemplate, createBoard} from '../../webapp/src/blocks/board'
import {createBoardView} from '../../webapp/src/blocks/boardView'
import {createCard} from '../../webapp/src/blocks/card'
@ -56,31 +57,34 @@ function main() {
const inputData = fs.readFileSync(inputFile, 'utf-8')
const input = JSON.parse(inputData) as Todoist
const boards = [] as Board[]
const blocks = [] as Block[]
input.projects.forEach(project => {
blocks.push(...convert(input, project))
const [brds, blks] = convert(input, project)
boards.push(...brds)
blocks.push(...blks)
})
// Save output
// TODO: Stream output
const outputData = ArchiveUtils.buildBlockArchive(blocks)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)
fs.writeFileSync(outputFile, outputData)
console.log(`Exported to ${outputFile}`)
}
function convert(input: Todoist, project: Project): Block[] {
function convert(input: Todoist, project: Project): [Board[], Block[]] {
const boards: Board[] = []
const blocks: Block[] = []
if (project.name === 'Inbox') {
return blocks
return [boards, blocks]
}
// Board
const board = createBoard()
console.log(`Board: ${project.name}`)
board.rootId = board.id
board.title = project.name
board.description = project.name
@ -115,13 +119,13 @@ function convert(input: Todoist, project: Project): Block[] {
options
}
board.cardProperties = [cardProperty]
blocks.push(board)
boards.push(board)
// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.rootId = board.id
view.boardId = board.id
view.parentId = board.id
blocks.push(view)
@ -130,7 +134,7 @@ function convert(input: Todoist, project: Project): Block[] {
cards.forEach(card => {
const outCard = createCard()
outCard.title = card.content
outCard.rootId = board.id
outCard.boardId = board.id
outCard.parentId = board.id
// Map lists to Select property options
@ -148,14 +152,14 @@ function convert(input: Todoist, project: Project): Block[] {
// console.log(`\t${card.desc}`)
const text = createTextBlock()
text.title = getCardDescription(input, card).join('\n\n')
text.rootId = board.id
text.boardId = board.id
text.parentId = outCard.id
blocks.push(text)
outCard.fields.contentOrder = [text.id]
})
return blocks
return [boards, blocks]
}
function getProjectColumns(input: Todoist, project: Project): Array<Section> {

View File

@ -5,6 +5,7 @@ import minimist from 'minimist'
import {exit} from 'process'
import {ArchiveUtils} from '../util/archive'
import {Block} from '../../webapp/src/blocks/block'
import {Board} from '../../webapp/src/blocks/board'
import {IPropertyOption, IPropertyTemplate, createBoard} from '../../webapp/src/blocks/board'
import {createBoardView} from '../../webapp/src/blocks/boardView'
import {createCard} from '../../webapp/src/blocks/card'
@ -50,23 +51,23 @@ function main() {
const input = JSON.parse(inputData) as Trello
// Convert
const blocks = convert(input)
const [boards, blocks] = convert(input)
// Save output
// TODO: Stream output
const outputData = ArchiveUtils.buildBlockArchive(blocks)
const outputData = ArchiveUtils.buildBlockArchive(boards, blocks)
fs.writeFileSync(outputFile, outputData)
console.log(`Exported to ${outputFile}`)
}
function convert(input: Trello): Block[] {
function convert(input: Trello): [Board[], Block[]] {
const boards: Board[] = []
const blocks: Block[] = []
// Board
const board = createBoard()
console.log(`Board: ${input.name}`)
board.rootId = board.id
board.title = input.name
board.description = input.desc
@ -93,13 +94,13 @@ function convert(input: Trello): Block[] {
options
}
board.cardProperties = [cardProperty]
blocks.push(board)
boards.push(board)
// Board view
const view = createBoardView()
view.title = 'Board View'
view.fields.viewType = 'board'
view.rootId = board.id
view.boardId = board.id
view.parentId = board.id
blocks.push(view)
@ -109,7 +110,7 @@ function convert(input: Trello): Block[] {
const outCard = createCard()
outCard.title = card.name
outCard.rootId = board.id
outCard.boardId = board.id
outCard.parentId = board.id
// Map lists to Select property options
@ -130,7 +131,7 @@ function convert(input: Trello): Block[] {
// console.log(`\t${card.desc}`)
const text = createTextBlock()
text.title = card.desc
text.rootId = board.id
text.boardId = board.id
text.parentId = outCard.id
blocks.push(text)
@ -150,7 +151,7 @@ function convert(input: Trello): Block[] {
} else {
checkBlock.fields.value = false
}
checkBlock.rootId = outCard.rootId
checkBlock.boardId = board.id
checkBlock.parentId = outCard.id
blocks.push(checkBlock)
@ -164,7 +165,7 @@ function convert(input: Trello): Block[] {
console.log('')
console.log(`Found ${input.cards.length} card(s).`)
return blocks
return [boards, blocks]
}
function showHelp() {

View File

@ -1,25 +1,31 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Block} from '../../webapp/src/blocks/block'
import {Board} from '../../webapp/src/blocks/board'
interface ArchiveHeader {
version: number
date: number
}
// This schema allows the expansion of additional line types in the future
interface ArchiveLine {
type: string,
data: unknown,
}
// This schema allows the expansion of additional line types in the future
interface BlockArchiveLine extends ArchiveLine {
type: 'block',
data: Block
}
interface BoardArchiveLine extends ArchiveLine {
type: 'board',
data: Board
}
class ArchiveUtils {
static buildBlockArchive(blocks: readonly Block[]): string {
static buildBlockArchive(boards: readonly Board[], blocks: readonly Block[]): string {
const header: ArchiveHeader = {
version: 1,
date: Date.now(),
@ -27,6 +33,17 @@ class ArchiveUtils {
const headerString = JSON.stringify(header)
let content = headerString + '\n'
for (const board of boards) {
const line: BoardArchiveLine = {
type: 'board',
data: board,
}
const lineString = JSON.stringify(line)
content += lineString
content += '\n'
}
for (const block of blocks) {
const line: BlockArchiveLine = {
type: 'block',

View File

@ -80,9 +80,12 @@ ifneq ($(HAS_SERVER),)
golangci-lint run ./...
endif
templates-archive: ## Build templates archive file
cd ../server/assets/build-template-archive; go run -tags '$(BUILD_TAGS)' main.go --dir="../templates-boardarchive" --out="../templates.boardarchive"
## Builds the server, if it exists, for all supported architectures.
.PHONY: server
server:
server: templates-archive
ifneq ($(HAS_SERVER),)
mkdir -p server/dist;
ifeq ($(MM_DEBUG),)

View File

@ -87,14 +87,9 @@ func (a *API) RegisterRoutes(r *mux.Router) {
apiv1.HandleFunc("/boards/{boardID}/blocks/{blockID}", a.sessionRequired(a.handleDeleteBlock)).Methods("DELETE")
apiv1.HandleFunc("/boards/{boardID}/blocks/{blockID}", a.sessionRequired(a.handlePatchBlock)).Methods("PATCH")
apiv1.HandleFunc("/boards/{boardID}/blocks/{blockID}/undelete", a.sessionRequired(a.handleUndeleteBlock)).Methods("POST")
apiv1.HandleFunc("/boards/{boardID}/blocks/{blockID}/subtree", a.attachSession(a.handleGetSubTree, false)).Methods("GET")
apiv1.HandleFunc("/boards/{boardID}/blocks/{blockID}/duplicate", a.attachSession(a.handleDuplicateBlock, false)).Methods("POST")
apiv1.HandleFunc("/boards/{boardID}/metadata", a.sessionRequired(a.handleGetBoardMetadata)).Methods("GET")
// Import&Export APIs
apiv1.HandleFunc("/boards/{boardID}/blocks/export", a.sessionRequired(a.handleExport)).Methods("GET")
apiv1.HandleFunc("/boards/{boardID}/blocks/import", a.sessionRequired(a.handleImport)).Methods("POST")
// Member APIs
apiv1.HandleFunc("/boards/{boardID}/members", a.sessionRequired(a.handleGetMembersForBoard)).Methods("GET")
apiv1.HandleFunc("/boards/{boardID}/members", a.sessionRequired(a.handleAddMember)).Methods("POST")
@ -155,7 +150,7 @@ func (a *API) RegisterRoutes(r *mux.Router) {
// archives
apiv1.HandleFunc("/boards/{boardID}/archive/export", a.sessionRequired(a.handleArchiveExportBoard)).Methods("GET")
apiv1.HandleFunc("/boards/{boardID}/archive/import", a.sessionRequired(a.handleArchiveImport)).Methods("POST")
apiv1.HandleFunc("/teams/{teamID}/archive/import", a.sessionRequired(a.handleArchiveImport)).Methods("POST")
}
func (a *API) RegisterAdminRoutes(r *mux.Router) {
@ -363,23 +358,6 @@ func (a *API) handleGetBlocks(w http.ResponseWriter, r *http.Request) {
auditRec.Success()
}
func stampModificationMetadata(r *http.Request, blocks []model.Block, auditRec *audit.Record) {
userID := getUserID(r)
if userID == model.SingleUser {
userID = ""
}
now := utils.GetMillis()
for i := range blocks {
blocks[i].ModifiedBy = userID
blocks[i].UpdateAt = now
if auditRec != nil {
auditRec.AddMeta("block_"+strconv.FormatInt(int64(i), 10), blocks[i])
}
}
}
func (a *API) handleCreateCategory(w http.ResponseWriter, r *http.Request) {
requestBody, err := ioutil.ReadAll(r.Body)
if err != nil {
@ -1219,287 +1197,6 @@ func (a *API) handlePatchBlocks(w http.ResponseWriter, r *http.Request) {
auditRec.Success()
}
func (a *API) handleGetSubTree(w http.ResponseWriter, r *http.Request) {
// swagger:operation GET /api/v1/boards/{boardID}/blocks/{blockID}/subtree getSubTree
//
// Returns the blocks of a subtree
//
// ---
// produces:
// - application/json
// parameters:
// - name: boardID
// in: path
// description: Board ID
// required: true
// type: string
// - name: blockID
// in: path
// description: The ID of the root block of the subtree
// required: true
// type: string
// - name: l
// in: query
// description: The number of levels to return. 2 or 3. Defaults to 2.
// required: false
// type: integer
// minimum: 2
// maximum: 3
// security:
// - BearerAuth: []
// responses:
// '200':
// description: success
// schema:
// type: array
// items:
// "$ref": "#/definitions/Block"
// default:
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
userID := getUserID(r)
vars := mux.Vars(r)
boardID := vars["boardID"]
blockID := vars["blockID"]
if !a.hasValidReadTokenForBoard(r, boardID) && !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionViewBoard) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
query := r.URL.Query()
levels, err := strconv.ParseInt(query.Get("l"), 10, 32)
if err != nil {
levels = 2
}
if levels != 2 && levels != 3 {
a.logger.Error("Invalid levels", mlog.Int64("levels", levels))
a.errorResponse(w, r.URL.Path, http.StatusBadRequest, "invalid levels", nil)
return
}
auditRec := a.makeAuditRecord(r, "getSubTree", audit.Fail)
defer a.audit.LogRecord(audit.LevelRead, auditRec)
auditRec.AddMeta("boardID", boardID)
auditRec.AddMeta("blockID", blockID)
blocks, err := a.app.GetSubTree(boardID, blockID, int(levels), model.QuerySubtreeOptions{})
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
a.logger.Debug("GetSubTree",
mlog.Int64("levels", levels),
mlog.String("boardID", boardID),
mlog.String("blockID", blockID),
mlog.Int("block_count", len(blocks)),
)
json, err := json.Marshal(blocks)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
jsonBytesResponse(w, http.StatusOK, json)
auditRec.AddMeta("blockCount", len(blocks))
auditRec.Success()
}
func (a *API) handleExport(w http.ResponseWriter, r *http.Request) {
// swagger:operation GET /api/v1/boards/{boardID}/blocks/export exportBlocks
//
// Returns all blocks of a board
//
// ---
// produces:
// - application/json
// parameters:
// - name: boardID
// in: path
// description: Board ID
// required: true
// type: string
// security:
// - BearerAuth: []
// responses:
// '200':
// description: success
// schema:
// type: array
// items:
// "$ref": "#/definitions/Block"
// default:
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
userID := getUserID(r)
vars := mux.Vars(r)
boardID := vars["boardID"]
if !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionViewBoard) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
query := r.URL.Query()
rootID := query.Get("root_id")
auditRec := a.makeAuditRecord(r, "export", audit.Fail)
defer a.audit.LogRecord(audit.LevelRead, auditRec)
auditRec.AddMeta("boardID", boardID)
auditRec.AddMeta("rootID", rootID)
var blocks []model.Block
var err error
if rootID == "" {
blocks, err = a.app.GetBlocksForBoard(boardID)
} else {
blocks, err = a.app.GetBlocksWithBoardID(boardID)
}
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
a.logger.Debug("raw blocks", mlog.Int("block_count", len(blocks)))
auditRec.AddMeta("rawCount", len(blocks))
blocks = filterOrphanBlocks(blocks)
a.logger.Debug("EXPORT filtered blocks", mlog.Int("block_count", len(blocks)))
auditRec.AddMeta("filteredCount", len(blocks))
json, err := json.Marshal(blocks)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
jsonBytesResponse(w, http.StatusOK, json)
auditRec.Success()
}
func filterOrphanBlocks(blocks []model.Block) (ret []model.Block) {
queue := make([]model.Block, 0)
childrenOfBlockWithID := make(map[string]*[]model.Block)
// Build the trees from nodes
for _, block := range blocks {
if len(block.ParentID) == 0 {
// Queue root blocks to process first
queue = append(queue, block)
} else {
siblings := childrenOfBlockWithID[block.ParentID]
if siblings != nil {
*siblings = append(*siblings, block)
} else {
siblings := []model.Block{block}
childrenOfBlockWithID[block.ParentID] = &siblings
}
}
}
// Map the trees to an array, which skips orphaned nodes
blocks = make([]model.Block, 0)
for len(queue) > 0 {
block := queue[0]
queue = queue[1:] // dequeue
blocks = append(blocks, block)
children := childrenOfBlockWithID[block.ID]
if children != nil {
queue = append(queue, *children...)
}
}
return blocks
}
func (a *API) handleImport(w http.ResponseWriter, r *http.Request) {
// swagger:operation POST /api/v1/boards/{boardID}/blocks/import importBlocks
//
// Import blocks on a given board
//
// ---
// produces:
// - application/json
// parameters:
// - name: boardID
// in: path
// description: Board ID
// required: true
// type: string
// - name: Body
// in: body
// description: array of blocks to import
// required: true
// schema:
// type: array
// items:
// "$ref": "#/definitions/Block"
// security:
// - BearerAuth: []
// responses:
// '200':
// description: success
// default:
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
userID := getUserID(r)
vars := mux.Vars(r)
boardID := vars["boardID"]
if !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionManageBoardCards) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to make board changes"})
return
}
requestBody, err := ioutil.ReadAll(r.Body)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
var blocks []model.Block
err = json.Unmarshal(requestBody, &blocks)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
auditRec := a.makeAuditRecord(r, "import", audit.Fail)
defer a.audit.LogRecord(audit.LevelModify, auditRec)
auditRec.AddMeta("boardID", boardID)
// all blocks should now be part of the board that they're being
// imported onto
for i := range blocks {
blocks[i].BoardID = boardID
}
stampModificationMetadata(r, blocks, auditRec)
if _, err = a.app.InsertBlocks(model.GenerateBlockIDs(blocks, a.logger), userID, false); err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}
jsonStringResponse(w, http.StatusOK, "{}")
a.logger.Debug("IMPORT BlockIDs", mlog.Int("block_count", len(blocks)))
auditRec.AddMeta("blockCount", len(blocks))
auditRec.Success()
}
// Sharing
func (a *API) handleGetSharing(w http.ResponseWriter, r *http.Request) {
@ -1799,6 +1496,9 @@ func (a *API) handlePostTeamRegenerateSignupToken(w http.ResponseWriter, r *http
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
if a.MattermostAuth {
a.errorResponse(w, r.URL.Path, http.StatusNotImplemented, "not permitted in plugin mode", nil)
}
team, err := a.app.GetRootTeam()
if err != nil {
@ -1824,7 +1524,7 @@ func (a *API) handlePostTeamRegenerateSignupToken(w http.ResponseWriter, r *http
// File upload
func (a *API) handleServeFile(w http.ResponseWriter, r *http.Request) {
// swagger:operation GET /boards/{boardID}/{rootID}/{fileID} getFile
// swagger:operation GET "api/v1/files/teams/{teamID}/{boardID}/{filename} getFile
//
// Returns the contents of an uploaded file
//
@ -1835,19 +1535,19 @@ func (a *API) handleServeFile(w http.ResponseWriter, r *http.Request) {
// - image/png
// - image/gif
// parameters:
// - name: teamID
// in: path
// description: Team ID
// required: true
// type: string
// - name: boardID
// in: path
// description: Board ID
// required: true
// type: string
// - name: rootID
// - name: filename
// in: path
// description: ID of the root block
// required: true
// type: string
// - name: fileID
// in: path
// description: ID of the file
// description: name of the file
// required: true
// type: string
// security:
@ -1865,7 +1565,8 @@ func (a *API) handleServeFile(w http.ResponseWriter, r *http.Request) {
filename := vars["filename"]
userID := getUserID(r)
if !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionViewBoard) {
hasValidReadToken := a.hasValidReadTokenForBoard(r, boardID)
if !hasValidReadToken && !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionViewBoard) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
@ -2192,7 +1893,7 @@ func (a *API) handleGetTemplates(w http.ResponseWriter, r *http.Request) {
auditRec.AddMeta("teamID", teamID)
// retrieve boards list
boards, err := a.app.GetTemplateBoards(teamID)
boards, err := a.app.GetTemplateBoards(teamID, userID)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
@ -2835,8 +2536,7 @@ func (a *API) handleDuplicateBoard(w http.ResponseWriter, r *http.Request) {
return
}
hasValidReadToken := a.hasValidReadTokenForBoard(r, boardID)
if userID == "" && !hasValidReadToken {
if userID == "" {
a.errorResponse(w, r.URL.Path, http.StatusUnauthorized, "", PermissionError{"access denied to board"})
return
}
@ -2851,17 +2551,15 @@ func (a *API) handleDuplicateBoard(w http.ResponseWriter, r *http.Request) {
return
}
if !hasValidReadToken {
if board.Type == model.BoardTypePrivate {
if !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionViewBoard) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
} else {
if !a.permissions.HasPermissionToTeam(userID, board.TeamID, model.PermissionViewTeam) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
if board.Type == model.BoardTypePrivate {
if !a.permissions.HasPermissionToBoard(userID, boardID, model.PermissionViewBoard) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
} else {
if !a.permissions.HasPermissionToTeam(userID, board.TeamID, model.PermissionViewTeam) {
a.errorResponse(w, r.URL.Path, http.StatusForbidden, "", PermissionError{"access denied to board"})
return
}
}
@ -2930,8 +2628,7 @@ func (a *API) handleDuplicateBlock(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
asTemplate := query.Get("asTemplate")
hasValidReadToken := a.hasValidReadTokenForBoard(r, boardID)
if userID == "" && !hasValidReadToken {
if userID == "" {
a.errorResponse(w, r.URL.Path, http.StatusUnauthorized, "", PermissionError{"access denied to board"})
return
}

View File

@ -8,6 +8,8 @@ import (
"github.com/gorilla/mux"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/services/audit"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
const (
@ -103,6 +105,9 @@ func (a *API) handleArchiveExportTeam(w http.ResponseWriter, r *http.Request) {
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
if a.MattermostAuth {
a.errorResponse(w, r.URL.Path, http.StatusNotImplemented, "not permitted in plugin mode", nil)
}
vars := mux.Vars(r)
teamID := vars["teamID"]
@ -143,7 +148,7 @@ func (a *API) handleArchiveExportTeam(w http.ResponseWriter, r *http.Request) {
}
func (a *API) handleArchiveImport(w http.ResponseWriter, r *http.Request) {
// swagger:operation POST /api/v1/boards/{boardID}/archive/import archiveImport
// swagger:operation POST /api/v1/teams/{teamID}/archive/import archiveImport
//
// Import an archive of boards.
//
@ -153,9 +158,9 @@ func (a *API) handleArchiveImport(w http.ResponseWriter, r *http.Request) {
// consumes:
// - multipart/form-data
// parameters:
// - name: boardID
// - name: teamID
// in: path
// description: Workspace ID
// description: Team ID
// required: true
// type: string
// - name: file
@ -198,6 +203,10 @@ func (a *API) handleArchiveImport(w http.ResponseWriter, r *http.Request) {
}
if err := a.app.ImportArchive(file, opt); err != nil {
a.logger.Debug("Error importing archive",
mlog.String("team_id", teamID),
mlog.Err(err),
)
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
return
}

View File

@ -166,6 +166,9 @@ func (a *API) handleLogin(w http.ResponseWriter, r *http.Request) {
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
if a.MattermostAuth {
a.errorResponse(w, r.URL.Path, http.StatusNotImplemented, "not permitted in plugin mode", nil)
}
if len(a.singleUserToken) > 0 {
// Not permitted in single-user mode
@ -228,6 +231,9 @@ func (a *API) handleLogout(w http.ResponseWriter, r *http.Request) {
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
if a.MattermostAuth {
a.errorResponse(w, r.URL.Path, http.StatusNotImplemented, "not permitted in plugin mode", nil)
}
if len(a.singleUserToken) > 0 {
// Not permitted in single-user mode
@ -278,6 +284,9 @@ func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
if a.MattermostAuth {
a.errorResponse(w, r.URL.Path, http.StatusNotImplemented, "not permitted in plugin mode", nil)
}
if len(a.singleUserToken) > 0 {
// Not permitted in single-user mode
@ -377,6 +386,9 @@ func (a *API) handleChangePassword(w http.ResponseWriter, r *http.Request) {
// description: internal error
// schema:
// "$ref": "#/definitions/ErrorResponse"
if a.MattermostAuth {
a.errorResponse(w, r.URL.Path, http.StatusNotImplemented, "not permitted in plugin mode", nil)
}
if len(a.singleUserToken) > 0 {
// Not permitted in single-user mode
@ -458,6 +470,18 @@ func (a *API) attachSession(handler func(w http.ResponseWriter, r *http.Request)
CreateAt: now,
UpdateAt: now,
}
user, err := a.app.GetUser(userID)
if err != nil {
a.errorResponse(w, r.URL.Path, http.StatusUnauthorized, "", err)
return
}
if user.IsGuest {
a.errorResponse(w, r.URL.Path, http.StatusUnauthorized, "guests not supported", nil)
return
}
ctx := context.WithValue(r.Context(), sessionContextKey, session)
handler(w, r.WithContext(ctx))
return

View File

@ -234,15 +234,6 @@ func (a *App) CopyCardFiles(sourceBoardID string, blocks []model.Block) error {
return nil
}
func (a *App) GetSubTree(boardID, blockID string, levels int, opts model.QuerySubtreeOptions) ([]model.Block, error) {
// Only 2 or 3 levels are supported for now
if levels >= 3 {
return a.store.GetSubTree3(boardID, blockID, opts)
}
return a.store.GetSubTree2(boardID, blockID, opts)
}
func (a *App) GetBlockByID(blockID string) (*model.Block, error) {
return a.store.GetBlock(blockID)
}

View File

@ -69,6 +69,21 @@ func (a *App) GetBoardMetadata(boardID string) (*model.Board, *model.BoardMetada
return board, &boardMetadata, nil
}
// getBoardForBlock returns the board that owns the specified block.
func (a *App) getBoardForBlock(blockID string) (*model.Board, error) {
block, err := a.GetBlockByID(blockID)
if err != nil {
return nil, fmt.Errorf("cannot get block %s: %w", blockID, err)
}
board, err := a.GetBoard(block.BoardID)
if err != nil {
return nil, fmt.Errorf("cannot get board %s: %w", block.BoardID, err)
}
return board, nil
}
func (a *App) getBoardHistory(boardID string, latest bool) (*model.Board, error) {
opts := model.QueryBlockHistoryOptions{
Limit: 1,
@ -150,8 +165,8 @@ func (a *App) GetBoardsForUserAndTeam(userID, teamID string) ([]*model.Board, er
return a.store.GetBoardsForUserAndTeam(userID, teamID)
}
func (a *App) GetTemplateBoards(teamID string) ([]*model.Board, error) {
return a.store.GetTemplateBoards(teamID)
func (a *App) GetTemplateBoards(teamID, userID string) ([]*model.Board, error) {
return a.store.GetTemplateBoards(teamID, userID)
}
func (a *App) CreateBoard(board *model.Board, userID string, addMember bool) (*model.Board, error) {

View File

@ -19,9 +19,10 @@ import (
)
type TestHelper struct {
App *App
Store *mockstore.MockStore
logger *mlog.Logger
App *App
Store *mockstore.MockStore
FilesBackend *mocks.FileBackend
logger *mlog.Logger
}
func SetupTestHelper(t *testing.T) (*TestHelper, func()) {
@ -29,6 +30,7 @@ func SetupTestHelper(t *testing.T) (*TestHelper, func()) {
defer ctrl.Finish()
cfg := config.Configuration{}
store := mockstore.NewMockStore(ctrl)
filesBackend := &mocks.FileBackend{}
auth := auth.New(&cfg, store, nil)
logger := mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)
sessionToken := "TESTTOKEN"
@ -39,7 +41,7 @@ func SetupTestHelper(t *testing.T) (*TestHelper, func()) {
appServices := Services{
Auth: auth,
Store: store,
FilesBackend: &mocks.FileBackend{},
FilesBackend: filesBackend,
Webhook: webhook,
Metrics: metricsService,
Logger: logger,
@ -55,8 +57,9 @@ func SetupTestHelper(t *testing.T) (*TestHelper, func()) {
}
return &TestHelper{
App: app2,
Store: store,
logger: logger,
App: app2,
Store: store,
FilesBackend: filesBackend,
logger: logger,
}, tearDown
}

View File

@ -24,6 +24,10 @@ const (
legacyFileBegin = "{\"version\":1"
)
var (
errBlockIsNotABoard = errors.New("block is not a board")
)
// ImportArchive imports an archive containing zero or more boards, plus all
// associated content, including cards, content blocks, views, and images.
//
@ -113,13 +117,15 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (str
userID = ""
}
now := utils.GetMillis()
var boardID string
lineNum := 1
firstLine := true
for {
line, errRead := readLine(lineReader)
if len(line) != 0 {
var skip bool
if lineNum == 1 {
if firstLine {
// first line might be a header tag (old archive format)
if strings.HasPrefix(string(line), legacyFileBegin) {
skip = true
@ -131,7 +137,37 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (str
if err := json.Unmarshal(line, &archiveLine); err != nil {
return "", fmt.Errorf("error parsing archive line %d: %w", lineNum, err)
}
// first line must be a board
if firstLine && archiveLine.Type == "block" {
archiveLine.Type = "board_block"
}
switch archiveLine.Type {
case "board":
var board model.Board
if err2 := json.Unmarshal(archiveLine.Data, &board); err2 != nil {
return "", fmt.Errorf("invalid board in archive line %d: %w", lineNum, err2)
}
board.ModifiedBy = userID
board.UpdateAt = now
board.TeamID = opt.TeamID
boardsAndBlocks.Boards = append(boardsAndBlocks.Boards, &board)
boardID = board.ID
case "board_block":
// legacy archives encoded boards as blocks; we need to convert them to real boards.
var block model.Block
if err2 := json.Unmarshal(archiveLine.Data, &block); err2 != nil {
return "", fmt.Errorf("invalid board block in archive line %d: %w", lineNum, err2)
}
block.ModifiedBy = userID
block.UpdateAt = now
board, err := a.blockToBoard(&block, opt)
if err != nil {
return "", fmt.Errorf("cannot convert archive line %d to block: %w", lineNum, err)
}
boardsAndBlocks.Boards = append(boardsAndBlocks.Boards, board)
boardID = board.ID
case "block":
var block model.Block
if err2 := json.Unmarshal(archiveLine.Data, &block); err2 != nil {
@ -139,19 +175,12 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (str
}
block.ModifiedBy = userID
block.UpdateAt = now
block.BoardID = boardID
boardsAndBlocks.Blocks = append(boardsAndBlocks.Blocks, block)
case "board":
var board model.Board
if err2 := json.Unmarshal(archiveLine.Data, &board); err2 != nil {
return "", fmt.Errorf("invalid block in archive line %d: %w", lineNum, err2)
}
board.ModifiedBy = userID
board.UpdateAt = now
board.TeamID = opt.TeamID
boardsAndBlocks.Boards = append(boardsAndBlocks.Boards, &board)
default:
return "", model.NewErrUnsupportedArchiveLineType(lineNum, archiveLine.Type)
}
firstLine = false
}
}
@ -164,24 +193,12 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (str
lineNum++
}
modInfoCache := make(map[string]interface{})
modBoards := make([]*model.Board, 0, len(boardsAndBlocks.Boards))
for _, board := range boardsAndBlocks.Boards {
b := *board
if opt.BoardModifier != nil && !opt.BoardModifier(&b, modInfoCache) {
a.logger.Debug("skipping insert block per block modifier",
mlog.String("blockID", board.ID),
)
continue
}
modBoards = append(modBoards, &b)
}
boardsAndBlocks.Boards = modBoards
a.fixBoardsandBlocks(boardsAndBlocks, opt)
var err error
boardsAndBlocks, err = model.GenerateBoardsAndBlocksIDs(boardsAndBlocks, a.logger)
if err != nil {
return "", fmt.Errorf("error inserting archive blocks: %w", err)
return "", fmt.Errorf("error generating archive block IDs: %w", err)
}
boardsAndBlocks, err = a.CreateBoardsAndBlocks(boardsAndBlocks, opt.ModifiedBy, false)
@ -189,6 +206,18 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (str
return "", fmt.Errorf("error inserting archive blocks: %w", err)
}
// add user to all the new boards.
for _, board := range boardsAndBlocks.Boards {
boardMember := &model.BoardMember{
BoardID: board.ID,
UserID: opt.ModifiedBy,
SchemeAdmin: true,
}
if _, err := a.AddMemberToBoard(boardMember); err != nil {
return "", fmt.Errorf("cannot add member to board: %w", err)
}
}
// find new board id
for _, board := range boardsAndBlocks.Boards {
return board.ID, nil
@ -196,6 +225,161 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (str
return "", fmt.Errorf("missing board in archive: %w", model.ErrInvalidBoardBlock)
}
// fixBoardsandBlocks allows the caller of `ImportArchive` to modify or filters boards and blocks being
// imported via callbacks.
func (a *App) fixBoardsandBlocks(boardsAndBlocks *model.BoardsAndBlocks, opt model.ImportArchiveOptions) {
if opt.BlockModifier == nil && opt.BoardModifier == nil {
return
}
modInfoCache := make(map[string]interface{})
modBoards := make([]*model.Board, 0, len(boardsAndBlocks.Boards))
modBlocks := make([]model.Block, 0, len(boardsAndBlocks.Blocks))
for _, board := range boardsAndBlocks.Boards {
b := *board
if opt.BoardModifier != nil && !opt.BoardModifier(&b, modInfoCache) {
a.logger.Debug("skipping insert board per board modifier",
mlog.String("boardID", board.ID),
)
continue
}
modBoards = append(modBoards, &b)
}
for _, block := range boardsAndBlocks.Blocks {
b := block
if opt.BlockModifier != nil && !opt.BlockModifier(&b, modInfoCache) {
a.logger.Debug("skipping insert block per block modifier",
mlog.String("blockID", block.ID),
)
continue
}
modBlocks = append(modBlocks, b)
}
boardsAndBlocks.Boards = modBoards
boardsAndBlocks.Blocks = modBlocks
}
// blockToBoard converts a `model.Block` to `model.Board`. Legacy archive formats encode boards as blocks
// and need conversion during import.
func (a *App) blockToBoard(block *model.Block, opt model.ImportArchiveOptions) (*model.Board, error) {
if block.Type != model.TypeBoard {
return nil, errBlockIsNotABoard
}
board := &model.Board{
ID: block.ID,
TeamID: opt.TeamID,
CreatedBy: block.CreatedBy,
ModifiedBy: block.ModifiedBy,
Type: model.BoardTypePrivate,
Title: block.Title,
CreateAt: block.CreateAt,
UpdateAt: block.UpdateAt,
DeleteAt: block.DeleteAt,
Properties: make(map[string]interface{}),
CardProperties: make([]map[string]interface{}, 0),
ColumnCalculations: make(map[string]interface{}),
}
if icon, ok := stringValue(block.Fields, "icon"); ok {
board.Icon = icon
}
if description, ok := stringValue(block.Fields, "description"); ok {
board.Description = description
}
if showDescription, ok := boolValue(block.Fields, "showDescription"); ok {
board.ShowDescription = showDescription
}
if isTemplate, ok := boolValue(block.Fields, "isTemplate"); ok {
board.IsTemplate = isTemplate
}
if templateVer, ok := intValue(block.Fields, "templateVer"); ok {
board.TemplateVersion = templateVer
}
if properties, ok := mapValue(block.Fields, "properties"); ok {
board.Properties = properties
}
if cardProperties, ok := arrayMapsValue(block.Fields, "cardProperties"); ok {
board.CardProperties = cardProperties
}
if columnCalculations, ok := mapValue(block.Fields, "columnCalculations"); ok {
board.ColumnCalculations = columnCalculations
}
return board, nil
}
func stringValue(m map[string]interface{}, key string) (string, bool) {
v, ok := m[key]
if !ok {
return "", false
}
s, ok := v.(string)
if !ok {
return "", false
}
return s, true
}
func boolValue(m map[string]interface{}, key string) (bool, bool) {
v, ok := m[key]
if !ok {
return false, false
}
b, ok := v.(bool)
if !ok {
return false, false
}
return b, true
}
func intValue(m map[string]interface{}, key string) (int, bool) {
v, ok := m[key]
if !ok {
return 0, false
}
i, ok := v.(int)
if !ok {
return 0, false
}
return i, true
}
func mapValue(m map[string]interface{}, key string) (map[string]interface{}, bool) {
v, ok := m[key]
if !ok {
return nil, false
}
mm, ok := v.(map[string]interface{})
if !ok {
return nil, false
}
return mm, true
}
func arrayMapsValue(m map[string]interface{}, key string) ([]map[string]interface{}, bool) {
v, ok := m[key]
if !ok {
return nil, false
}
ai, ok := v.([]interface{})
if !ok {
return nil, false
}
arr := make([]map[string]interface{}, 0, len(ai))
for _, mi := range ai {
mm, ok := mi.(map[string]interface{})
if !ok {
return nil, false
}
arr = append(arr, mm)
}
return arr, true
}
func parseVersionFile(r io.Reader) (int, error) {
file, err := io.ReadAll(r)
if err != nil {

69
server/app/import_test.go Normal file
View File

@ -0,0 +1,69 @@
package app
import (
"bytes"
"testing"
"github.com/golang/mock/gomock"
"github.com/mattermost/focalboard/server/model"
"github.com/stretchr/testify/require"
)
func TestApp_ImportArchive(t *testing.T) {
th, tearDown := SetupTestHelper(t)
defer tearDown()
board := &model.Board{
ID: "d14b9df9-1f31-4732-8a64-92bc7162cd28",
TeamID: "test-team",
Title: "Cross-Functional Project Plan",
}
block := model.Block{
ID: "2c1873e0-1484-407d-8b2c-3c3b5a2a9f9e",
ParentID: board.ID,
Type: model.TypeView,
BoardID: board.ID,
}
babs := &model.BoardsAndBlocks{
Boards: []*model.Board{board},
Blocks: []model.Block{block},
}
boardMember := &model.BoardMember{
BoardID: board.ID,
UserID: "user",
}
t.Run("import asana archive", func(t *testing.T) {
r := bytes.NewReader([]byte(asana))
opts := model.ImportArchiveOptions{
TeamID: "test-team",
ModifiedBy: "user",
}
th.Store.EXPECT().CreateBoardsAndBlocks(gomock.AssignableToTypeOf(&model.BoardsAndBlocks{}), "user").Return(babs, nil)
th.Store.EXPECT().GetMembersForBoard(board.ID).AnyTimes().Return([]*model.BoardMember{boardMember}, nil)
th.Store.EXPECT().GetBoard(board.ID).Return(board, nil)
th.Store.EXPECT().GetMemberForBoard(board.ID, "user").Return(boardMember, nil)
err := th.App.ImportArchive(r, opts)
require.NoError(t, err, "import archive should not fail")
})
}
//nolint:lll
const asana = `{"version":1,"date":1614714686842}
{"type":"block","data":{"id":"d14b9df9-1f31-4732-8a64-92bc7162cd28","fields":{"icon":"","description":"","cardProperties":[{"id":"3bdcbaeb-bc78-4884-8531-a0323b74676a","name":"Section","type":"select","options":[{"id":"d8d94ef1-5e74-40bb-8be5-fc0eb3f47732","value":"Planning","color":"propColorGray"},{"id":"454559bb-b788-4ff6-873e-04def8491d2c","value":"Milestones","color":"propColorBrown"},{"id":"deaab476-c690-48df-828f-725b064dc476","value":"Next steps","color":"propColorOrange"},{"id":"2138305a-3157-461c-8bbe-f19ebb55846d","value":"Comms Plan","color":"propColorYellow"}]}]},"createAt":1614714686836,"updateAt":1614714686836,"deleteAt":0,"schema":1,"parentId":"","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"board","title":"Cross-Functional Project Plan"}}
{"type":"block","data":{"id":"2c1873e0-1484-407d-8b2c-3c3b5a2a9f9e","fields":{"sortOptions":[],"visiblePropertyIds":[],"visibleOptionIds":[],"hiddenOptionIds":[],"filter":{"operation":"and","filters":[]},"cardOrder":[],"columnWidths":{},"viewType":"board"},"createAt":1614714686840,"updateAt":1614714686840,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"view","title":"Board View"}}
{"type":"block","data":{"id":"520c332b-adf5-4a32-88ab-43655c8b6aa2","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"d8d94ef1-5e74-40bb-8be5-fc0eb3f47732"},"contentOrder":["deb3966c-6d56-43b1-8e95-36806877ce81"]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"[READ ME] - Instructions for using this template"}}
{"type":"block","data":{"id":"deb3966c-6d56-43b1-8e95-36806877ce81","fields":{},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"520c332b-adf5-4a32-88ab-43655c8b6aa2","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"text","title":"This project template is set up in List View with sections and Asana-created Custom Fields to help you track your team's work. We've provided some example content in this template to get you started, but you should add tasks, change task names, add more Custom Fields, and change any other info to make this project your own.\n\nSend feedback about this template: https://asa.na/templatesfeedback"}}
{"type":"block","data":{"id":"be791f66-a5e5-4408-82f6-cb1280f5bc45","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"d8d94ef1-5e74-40bb-8be5-fc0eb3f47732"},"contentOrder":["2688b31f-e7ff-4de1-87ae-d4b5570f8712"]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"Redesign the landing page of our website"}}
{"type":"block","data":{"id":"2688b31f-e7ff-4de1-87ae-d4b5570f8712","fields":{},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"be791f66-a5e5-4408-82f6-cb1280f5bc45","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"text","title":"Redesign the landing page to focus on the main persona."}}
{"type":"block","data":{"id":"98f74948-1700-4a3c-8cc2-8bb632499def","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"454559bb-b788-4ff6-873e-04def8491d2c"},"contentOrder":[]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"[EXAMPLE TASK] Consider trying a new email marketing service"}}
{"type":"block","data":{"id":"142fba5d-05e6-4865-83d9-b3f54d9de96e","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"454559bb-b788-4ff6-873e-04def8491d2c"},"contentOrder":[]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"[EXAMPLE TASK] Budget finalization"}}
{"type":"block","data":{"id":"ca6670b1-b034-4e42-8971-c659b478b9e0","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"deaab476-c690-48df-828f-725b064dc476"},"contentOrder":[]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"[EXAMPLE TASK] Find a venue for the holiday party"}}
{"type":"block","data":{"id":"db1dd596-0999-4741-8b05-72ca8e438e31","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"deaab476-c690-48df-828f-725b064dc476"},"contentOrder":[]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"[EXAMPLE TASK] Approve campaign copy"}}
{"type":"block","data":{"id":"16861c05-f31f-46af-8429-80a87b5aa93a","fields":{"icon":"","properties":{"3bdcbaeb-bc78-4884-8531-a0323b74676a":"2138305a-3157-461c-8bbe-f19ebb55846d"},"contentOrder":[]},"createAt":1614714686841,"updateAt":1614714686841,"deleteAt":0,"schema":1,"parentId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","rootId":"d14b9df9-1f31-4732-8a64-92bc7162cd28","modifiedBy":"","type":"card","title":"[EXAMPLE TASK] Send out updated attendee list"}}
`

View File

@ -9,7 +9,7 @@ import (
// initialize is called when the App is first created.
func (a *App) initialize(skipTemplateInit bool) {
if !skipTemplateInit {
if err := a.initializeTemplates(); err != nil {
if err := a.InitTemplates(); err != nil {
a.logger.Error(`InitializeTemplates failed`, mlog.Err(err))
}
}

View File

@ -46,14 +46,14 @@ func (a *App) PrepareOnboardingTour(userID string, teamID string) (string, strin
}
func (a *App) getOnboardingBoardID() (string, error) {
boards, err := a.store.GetTemplateBoards(globalTeamID)
boards, err := a.store.GetTemplateBoards(globalTeamID, "")
if err != nil {
return "", err
}
var onboardingBoardID string
for _, block := range boards {
if block.Title == WelcomeBoardTitle {
if block.Title == WelcomeBoardTitle && block.TeamID == globalTeamID {
onboardingBoardID = block.ID
break
}

View File

@ -25,7 +25,7 @@ func TestPrepareOnboardingTour(t *testing.T) {
IsTemplate: true,
}
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().DuplicateBoard(welcomeBoard.ID, userID, teamID, false).Return(&model.BoardsAndBlocks{Boards: []*model.Board{&welcomeBoard}},
nil, nil)
th.Store.EXPECT().GetMembersForBoard(welcomeBoard.ID).Return([]*model.BoardMember{}, nil)
@ -60,7 +60,7 @@ func TestCreateWelcomeBoard(t *testing.T) {
TeamID: "0",
IsTemplate: true,
}
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().DuplicateBoard(welcomeBoard.ID, userID, teamID, false).
Return(&model.BoardsAndBlocks{Boards: []*model.Board{&welcomeBoard}}, nil, nil)
th.Store.EXPECT().GetMembersForBoard(welcomeBoard.ID).Return([]*model.BoardMember{}, nil)
@ -72,7 +72,7 @@ func TestCreateWelcomeBoard(t *testing.T) {
t.Run("template doesn't contain a board", func(t *testing.T) {
teamID := testTeamID
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{}, nil)
boardID, err := th.App.createWelcomeBoard("user_id_1", teamID)
assert.Error(t, err)
assert.Empty(t, boardID)
@ -86,7 +86,7 @@ func TestCreateWelcomeBoard(t *testing.T) {
TeamID: teamID,
IsTemplate: true,
}
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{&welcomeBoard}, nil)
boardID, err := th.App.createWelcomeBoard("user_id_1", "workspace_id_1")
assert.Error(t, err)
assert.Empty(t, boardID)
@ -104,7 +104,7 @@ func TestGetOnboardingBoardID(t *testing.T) {
TeamID: "0",
IsTemplate: true,
}
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{&welcomeBoard}, nil)
onboardingBoardID, err := th.App.getOnboardingBoardID()
assert.NoError(t, err)
@ -112,7 +112,7 @@ func TestGetOnboardingBoardID(t *testing.T) {
})
t.Run("no blocks found", func(t *testing.T) {
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{}, nil)
onboardingBoardID, err := th.App.getOnboardingBoardID()
assert.Error(t, err)
@ -126,7 +126,7 @@ func TestGetOnboardingBoardID(t *testing.T) {
TeamID: "0",
IsTemplate: true,
}
th.Store.EXPECT().GetTemplateBoards("0").Return([]*model.Board{&welcomeBoard}, nil)
th.Store.EXPECT().GetTemplateBoards("0", "").Return([]*model.Board{&welcomeBoard}, nil)
onboardingBoardID, err := th.App.getOnboardingBoardID()
assert.Error(t, err)

View File

@ -3,6 +3,8 @@ package app
import (
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/utils"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
func (a *App) CreateSubscription(sub *model.Subscription) (*model.Subscription, error) {
@ -37,5 +39,15 @@ func (a *App) notifySubscriptionChanged(subscription *model.Subscription) {
if a.notifications == nil {
return
}
a.notifications.BroadcastSubscriptionChange(subscription)
board, err := a.getBoardForBlock(subscription.BlockID)
if err != nil {
a.logger.Error("Error notifying subscription change",
mlog.String("subscriber_id", subscription.SubscriberID),
mlog.String("block_id", subscription.BlockID),
mlog.Err(err),
)
}
a.notifications.BroadcastSubscriptionChange(board.TeamID, subscription)
}

View File

@ -5,8 +5,7 @@ import (
"fmt"
"strings"
_ "embed"
"github.com/mattermost/focalboard/server/assets"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
@ -17,18 +16,16 @@ const (
globalTeamID = "0"
)
//go:embed templates.boardarchive
var defTemplates []byte
func (a *App) InitTemplates() error {
return a.initializeTemplates()
_, err := a.initializeTemplates()
return err
}
// initializeTemplates imports default templates if the boards table is empty.
func (a *App) initializeTemplates() error {
boards, err := a.store.GetTemplateBoards(globalTeamID)
func (a *App) initializeTemplates() (bool, error) {
boards, err := a.store.GetTemplateBoards(globalTeamID, "")
if err != nil {
return fmt.Errorf("cannot initialize templates: %w", err)
return false, fmt.Errorf("cannot initialize templates: %w", err)
}
a.logger.Debug("Fetched template boards", mlog.Int("count", len(boards)))
@ -36,27 +33,31 @@ func (a *App) initializeTemplates() error {
isNeeded, reason := a.isInitializationNeeded(boards)
if !isNeeded {
a.logger.Debug("Template import not needed, skipping")
return nil
return false, nil
}
a.logger.Debug("Importing new default templates", mlog.String("reason", reason))
a.logger.Debug("Importing new default templates",
mlog.String("reason", reason),
mlog.Int("size", len(assets.DefaultTemplatesArchive)),
)
// Remove in case of newer Templates
if err = a.store.RemoveDefaultTemplates(boards); err != nil {
return fmt.Errorf("cannot remove old template boards: %w", err)
return false, fmt.Errorf("cannot remove old template boards: %w", err)
}
r := bytes.NewReader(defTemplates)
r := bytes.NewReader(assets.DefaultTemplatesArchive)
opt := model.ImportArchiveOptions{
TeamID: globalTeamID,
ModifiedBy: "system",
BlockModifier: fixTemplateBlock,
BoardModifier: fixTemplateBoard,
}
if err = a.ImportArchive(r, opt); err != nil {
return fmt.Errorf("cannot initialize global templates for team %s: %w", globalTeamID, err)
return false, fmt.Errorf("cannot initialize global templates for team %s: %w", globalTeamID, err)
}
return nil
return true, nil
}
// isInitializationNeeded returns true if the blocks table contains no default templates,
@ -79,17 +80,34 @@ func (a *App) isInitializationNeeded(boards []*model.Board) (bool, string) {
return false, ""
}
// fixTemplateBlock fixes a block to be inserted as part of a template.
func fixTemplateBlock(block *model.Block, cache map[string]interface{}) bool {
// cache contains ids of skipped boards. Ensure their children are skipped as well.
if _, ok := cache[block.BoardID]; ok {
cache[block.ID] = struct{}{}
return false
}
if _, ok := cache[block.ParentID]; ok {
cache[block.ID] = struct{}{}
return false
}
return true
}
// fixTemplateBoard fixes a board to be inserted as part of a template.
func fixTemplateBoard(board *model.Board, cache map[string]interface{}) bool {
// filter out template blocks; we only want the non-template
// blocks which we will turn into default template blocks.
if board.IsTemplate {
cache[board.ID] = struct{}{}
return false
}
// remove '(NEW)' from title & force template flag
board.Title = strings.ReplaceAll(board.Title, "(NEW)", "")
board.IsTemplate = true
board.TemplateVersion = defaultTemplateVersion
board.Type = model.BoardTypeOpen
return true
}

View File

@ -0,0 +1,70 @@
package app
import (
"testing"
"github.com/golang/mock/gomock"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/utils"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock"
)
func TestApp_initializeTemplates(t *testing.T) {
board := &model.Board{
ID: utils.NewID(utils.IDTypeBoard),
TeamID: globalTeamID,
Type: model.BoardTypeOpen,
Title: "test board",
IsTemplate: true,
TemplateVersion: defaultTemplateVersion,
}
block := model.Block{
ID: utils.NewID(utils.IDTypeBlock),
ParentID: board.ID,
BoardID: board.ID,
Type: model.TypeText,
Title: "test text",
}
boardsAndBlocks := &model.BoardsAndBlocks{
Boards: []*model.Board{board},
Blocks: []model.Block{block},
}
boardMember := &model.BoardMember{
BoardID: board.ID,
UserID: "test-user",
}
t.Run("Needs template init", func(t *testing.T) {
th, tearDown := SetupTestHelper(t)
defer tearDown()
th.Store.EXPECT().GetTemplateBoards(globalTeamID, "").Return([]*model.Board{}, nil)
th.Store.EXPECT().RemoveDefaultTemplates([]*model.Board{}).Return(nil)
th.Store.EXPECT().CreateBoardsAndBlocks(gomock.Any(), gomock.Any()).AnyTimes().Return(boardsAndBlocks, nil)
th.Store.EXPECT().GetMembersForBoard(board.ID).AnyTimes().Return([]*model.BoardMember{}, nil)
th.Store.EXPECT().GetBoard(board.ID).AnyTimes().Return(board, nil)
th.Store.EXPECT().GetMemberForBoard(gomock.Any(), gomock.Any()).AnyTimes().Return(boardMember, nil)
th.FilesBackend.On("WriteFile", mock.Anything, mock.Anything).Return(int64(1), nil)
done, err := th.App.initializeTemplates()
require.NoError(t, err, "initializeTemplates should not error")
require.True(t, done, "initialization was needed")
})
t.Run("Skip template init", func(t *testing.T) {
th, tearDown := SetupTestHelper(t)
defer tearDown()
th.Store.EXPECT().GetTemplateBoards(globalTeamID, "").Return([]*model.Board{board}, nil)
done, err := th.App.initializeTemplates()
require.NoError(t, err, "initializeTemplates should not error")
require.False(t, done, "initialization was not needed")
})
}

11
server/assets/assets.go Normal file
View File

@ -0,0 +1,11 @@
package assets
import (
_ "embed"
)
// DefaultTemplatesArchive is an embedded archive file containing the default
// templates to be imported to team 0.
// This archive is generated with `make templates-archive`
//go:embed templates.boardarchive
var DefaultTemplatesArchive []byte

View File

@ -0,0 +1,193 @@
package main
import (
"archive/zip"
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
)
const (
defArchiveFilename = "templates.boardarchive"
versionFilename = "version.json"
boardFilename = "board.jsonl"
minArchiveVersion = 2
maxArchiveVersion = 2
)
type archiveVersion struct {
Version int `json:"version"`
Date int64 `json:"date"`
}
type appConfig struct {
dir string
out string
verbose bool
}
func main() {
cfg := appConfig{}
flag.StringVar(&cfg.dir, "dir", "", "source directory of templates")
flag.StringVar(&cfg.out, "out", defArchiveFilename, "output filename")
flag.BoolVar(&cfg.verbose, "verbose", false, "enable verbose output")
flag.Parse()
if cfg.dir == "" {
flag.Usage()
os.Exit(-1)
}
var code int
if err := build(cfg); err != nil {
code = -1
fmt.Fprintf(os.Stderr, "error creating archive: %v\n", err)
} else if cfg.verbose {
fmt.Fprintf(os.Stdout, "archive created: %s\n", cfg.out)
}
os.Exit(code)
}
func build(cfg appConfig) (err error) {
version, err := getVersionFile(cfg)
if err != nil {
return err
}
// create the output archive zip file
archiveFile, err := os.Create(cfg.out)
if err != nil {
return fmt.Errorf("error creating %s: %w", cfg.out, err)
}
archiveZip := zip.NewWriter(archiveFile)
defer func() {
if err2 := archiveZip.Close(); err2 != nil {
if err == nil {
err = fmt.Errorf("error closing zip %s: %w", cfg.out, err2)
}
}
if err2 := archiveFile.Close(); err2 != nil {
if err == nil {
err = fmt.Errorf("error closing %s: %w", cfg.out, err2)
}
}
}()
// write the version file
v, err := archiveZip.Create(versionFilename)
if err != nil {
return fmt.Errorf("error creating %s: %w", cfg.out, err)
}
if _, err = v.Write(version); err != nil {
return fmt.Errorf("error writing %s: %w", cfg.out, err)
}
// each board is a subdirectory; write each to the archive
files, err := ioutil.ReadDir(cfg.dir)
if err != nil {
return fmt.Errorf("error reading directory %s: %w", cfg.dir, err)
}
for _, f := range files {
if !f.IsDir() {
if f.Name() != versionFilename && cfg.verbose {
fmt.Fprintf(os.Stdout, "skipping non-directory %s\n", f.Name())
}
continue
}
if err = writeBoard(archiveZip, f.Name(), cfg); err != nil {
return fmt.Errorf("error writing board %s: %w", f.Name(), err)
}
}
return nil
}
func getVersionFile(cfg appConfig) ([]byte, error) {
path := filepath.Join(cfg.dir, versionFilename)
buf, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("cannot read %s: %w", path, err)
}
var version archiveVersion
if err := json.Unmarshal(buf, &version); err != nil {
return nil, fmt.Errorf("cannot parse %s: %w", path, err)
}
if version.Version < minArchiveVersion || version.Version > maxArchiveVersion {
return nil, errUnsupportedVersion{Min: minArchiveVersion, Max: maxArchiveVersion, Got: version.Version}
}
return buf, nil
}
func writeBoard(w *zip.Writer, boardID string, cfg appConfig) error {
// copy the board's jsonl file first. BoardID is also the directory name.
srcPath := filepath.Join(cfg.dir, boardID, boardFilename)
destPath := filepath.Join(boardID, boardFilename)
if err := writeFile(w, srcPath, destPath, cfg); err != nil {
return err
}
boardPath := filepath.Join(cfg.dir, boardID)
files, err := ioutil.ReadDir(boardPath)
if err != nil {
return fmt.Errorf("error reading board directory %s: %w", cfg.dir, err)
}
for _, f := range files {
if f.IsDir() {
if cfg.verbose {
fmt.Fprintf(os.Stdout, "skipping directory %s\n", f.Name())
}
continue
}
if f.Name() == boardFilename {
continue
}
srcPath = filepath.Join(cfg.dir, boardID, f.Name())
destPath = filepath.Join(boardID, f.Name())
if err = writeFile(w, srcPath, destPath, cfg); err != nil {
return fmt.Errorf("error writing %s: %w", destPath, err)
}
}
return nil
}
func writeFile(w *zip.Writer, srcPath string, destPath string, cfg appConfig) (err error) {
inFile, err := os.Open(srcPath)
if err != nil {
return fmt.Errorf("error reading %s: %w", srcPath, err)
}
defer inFile.Close()
outFile, err := w.Create(destPath)
if err != nil {
return fmt.Errorf("error creating %s: %w", destPath, err)
}
size, err := io.Copy(outFile, inFile)
if err != nil {
return fmt.Errorf("error writing %s: %w", destPath, err)
}
if cfg.verbose {
fmt.Fprintf(os.Stdout, "%s written (%d bytes)\n", destPath, size)
}
return nil
}
type errUnsupportedVersion struct {
Min int
Max int
Got int
}
func (e errUnsupportedVersion) Error() string {
return fmt.Sprintf("unsupported archive version; require between %d and %d inclusive, got %d", e.Min, e.Max, e.Got)
}

View File

@ -0,0 +1,36 @@
{"type":"block","data":{"id":"b7wnw9awd4pnefryhq51apbzb4c","parentId":"","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"board","title":"Meeting Agenda (NEW)","fields":{"cardProperties":[{"id":"d777ba3b-8728-40d1-87a6-59406bbbbfb0","name":"Status","options":[{"color":"propColorPink","id":"34eb9c25-d5bf-49d9-859e-f74f4e0030e7","value":"To Discuss 💬"},{"color":"propColorYellow","id":"d37a61f4-f332-4db9-8b2d-5e0a91aa20ed","value":"Revisit Later ⏳"},{"color":"propColorGreen","id":"dabadd9b-adf1-4d9f-8702-805ac6cef602","value":"Done / Archived 📦"}],"type":"select"},{"id":"4cf1568d-530f-4028-8ffd-bdc65249187e","name":"Priority","options":[{"color":"propColorRed","id":"8b05c83e-a44a-4d04-831e-97f01d8e2003","value":"1. High"},{"color":"propColorYellow","id":"b1abafbf-a038-4a19-8b68-56e0fd2319f7","value":"2. Medium"},{"color":"propColorGray","id":"2491ffaa-eb55-417b-8aff-4bd7d4136613","value":"3. Low"}],"type":"select"},{"id":"aw4w63xhet79y9gueqzzeiifdoe","name":"Created by","options":[],"type":"createdBy"},{"id":"a6ux19353xcwfqg9k1inqg5sg4w","name":"Created time","options":[],"type":"createdTime"}],"columnCalculations":[],"description":"Use this template for recurring meeting agendas, like team meetings and 1:1's. To use this board:\n* Participants queue new items to discuss under \"To Discuss\"\n* Go through items during the meeting\n* Move items to Done or Revisit Later as needed","icon":"🍩","isTemplate":false,"showDescription":true},"createAt":1641497047916,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cgwagmaw6gin7xcq7nwew8rsynr","parentId":"b7wnw9awd4pnefryhq51apbzb4c","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"card","title":"Team Schedule","fields":{"contentOrder":["a4t1p1pbxbtnnu8p8e538o8369a","7b7hsbkm6sifqfqi4gstxxaz7my","aoqz1pydxbtnzdcs4ehcuys6cuc","7b3njq5m3n78hdpe4bimzr34fic","73dzfgistnbgzuekc6c8irou9wy","7z4cjur4ybbfibgmydhfct4jdke"],"icon":"⏰","isTemplate":false,"properties":{"4cf1568d-530f-4028-8ffd-bdc65249187e":"8b05c83e-a44a-4d04-831e-97f01d8e2003","d777ba3b-8728-40d1-87a6-59406bbbbfb0":"34eb9c25-d5bf-49d9-859e-f74f4e0030e7"}},"createAt":1641497048246,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"chki1tsudciyiiffrkqbcmp71rh","parentId":"b7wnw9awd4pnefryhq51apbzb4c","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"card","title":"Video production","fields":{"contentOrder":["a9ti13dqo8jfmjdmg97f5umfdyw","717fa85sx3f8f8m81f771s9hmwr","a4se5s4ozx3ry8ec57w6z6jpk7y","7n37rxrn9uffdzrfi1xajotzjey","7ifofmuwjzbdzppfxgtuai4i47h","7cfc4fkpz53gn9frciz9kui4p1c"],"icon":"📹","isTemplate":false,"properties":{"4cf1568d-530f-4028-8ffd-bdc65249187e":"b1abafbf-a038-4a19-8b68-56e0fd2319f7","d777ba3b-8728-40d1-87a6-59406bbbbfb0":"34eb9c25-d5bf-49d9-859e-f74f4e0030e7"}},"createAt":1641497048092,"updateAt":1643788318629,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cmt5usr1mw3fom886t34ekjquay","parentId":"b7wnw9awd4pnefryhq51apbzb4c","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"card","title":"Offsite plans","fields":{"contentOrder":["aw53ugkfq8pyi9fjh9j6i4kdeiw","7ni9593iz3pnb7xitoz3guwq5gh","agjkcro3x7irbxedyxrn8iuerrr","75zkot1f3sjb7ifysuzijitw91y","7is5m8apdu3g53c8f6cz6sq7bmh","7xsmzscbqn3ftudzqbb4w1q7t7e"],"icon":"🚙","isTemplate":false,"properties":{"4cf1568d-530f-4028-8ffd-bdc65249187e":"8b05c83e-a44a-4d04-831e-97f01d8e2003","d777ba3b-8728-40d1-87a6-59406bbbbfb0":"dabadd9b-adf1-4d9f-8702-805ac6cef602"}},"createAt":1641497048336,"updateAt":1643788318629,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cnqsbzg4b7brfddtyh7fc66atrw","parentId":"b7wnw9awd4pnefryhq51apbzb4c","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"card","title":"Social Media Strategy","fields":{"contentOrder":["ao57n1fbtmt8q8bfk8ieqgzqt3a","76h9y996sdj8sbrbpqjo9d8cwto","aco8iu5jp7jbyzmzegwxkeusgzr","7y6zcyofmsfrbt899ts1ixr3iey","7hudywfzcwirkpcp1p5jhsfs83r","7jzw67ngdgtns8mstsg9g614oac"],"icon":"🎉","isTemplate":false,"properties":{"4cf1568d-530f-4028-8ffd-bdc65249187e":"b1abafbf-a038-4a19-8b68-56e0fd2319f7","d777ba3b-8728-40d1-87a6-59406bbbbfb0":"d37a61f4-f332-4db9-8b2d-5e0a91aa20ed"}},"createAt":1641497048417,"updateAt":1643788318629,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vfs8sj79dt7n75bomn46fybxmfo","parentId":"b7wnw9awd4pnefryhq51apbzb4c","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"view","title":"Discussion Items","fields":{"cardOrder":["cjpkiya33qsagr4f9hrdwhgiajc"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"ch798q5ucefyobf5bymgqjt4f3h","filter":{"filters":[],"operation":"and"},"groupById":"d777ba3b-8728-40d1-87a6-59406bbbbfb0","hiddenOptionIds":[""],"kanbanCalculations":{},"sortOptions":[{"propertyId":"4cf1568d-530f-4028-8ffd-bdc65249187e","reversed":false}],"viewType":"board","visibleOptionIds":[],"visiblePropertyIds":["4cf1568d-530f-4028-8ffd-bdc65249187e"]},"createAt":1641497048501,"updateAt":1643788318629,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"73dzfgistnbgzuekc6c8irou9wy","parentId":"cgwagmaw6gin7xcq7nwew8rsynr","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586451774,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7b3njq5m3n78hdpe4bimzr34fic","parentId":"cgwagmaw6gin7xcq7nwew8rsynr","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586448934,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7b7hsbkm6sifqfqi4gstxxaz7my","parentId":"cgwagmaw6gin7xcq7nwew8rsynr","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641586358664,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7z4cjur4ybbfibgmydhfct4jdke","parentId":"cgwagmaw6gin7xcq7nwew8rsynr","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586454130,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a4t1p1pbxbtnnu8p8e538o8369a","parentId":"cgwagmaw6gin7xcq7nwew8rsynr","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Notes\n*[Add meeting notes here]*","fields":{},"createAt":1641586355777,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aoqz1pydxbtnzdcs4ehcuys6cuc","parentId":"cgwagmaw6gin7xcq7nwew8rsynr","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Action Items","fields":{},"createAt":1641586443526,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"766mkfhc4u7dxzcc36nhfpmm5fy","parentId":"ch798q5ucefyobf5bymgqjt4f3h","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641586677789,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"76w5qigi5ufgktcmmnw9ze88w5w","parentId":"ch798q5ucefyobf5bymgqjt4f3h","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641497389096,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"79wi7osb3utd3mjt9x57h7wpqfa","parentId":"ch798q5ucefyobf5bymgqjt4f3h","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641497390990,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7un1ccdg7qi8j3gxmkx5y3d9nhr","parentId":"ch798q5ucefyobf5bymgqjt4f3h","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641497382984,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"as3orhrci6tnutp5etbh6bzbgdy","parentId":"ch798q5ucefyobf5bymgqjt4f3h","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"text","title":"# Action Items","fields":{},"createAt":1641497371429,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"axyitfq8ae38qictgcw34cmwueh","parentId":"ch798q5ucefyobf5bymgqjt4f3h","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"mweioqznbife7p7aee7dr4wcxo","modifiedBy":"mweioqznbife7p7aee7dr4wcxo","schema":1,"type":"text","title":"# Notes\n*[Add meeting notes here]*","fields":{},"createAt":1641497348992,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"717fa85sx3f8f8m81f771s9hmwr","parentId":"chki1tsudciyiiffrkqbcmp71rh","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641586368705,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7cfc4fkpz53gn9frciz9kui4p1c","parentId":"chki1tsudciyiiffrkqbcmp71rh","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586479058,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7ifofmuwjzbdzppfxgtuai4i47h","parentId":"chki1tsudciyiiffrkqbcmp71rh","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586476646,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7n37rxrn9uffdzrfi1xajotzjey","parentId":"chki1tsudciyiiffrkqbcmp71rh","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586469805,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a4se5s4ozx3ry8ec57w6z6jpk7y","parentId":"chki1tsudciyiiffrkqbcmp71rh","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Action Items","fields":{},"createAt":1641586462602,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a9ti13dqo8jfmjdmg97f5umfdyw","parentId":"chki1tsudciyiiffrkqbcmp71rh","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Notes\n*[Add meeting notes here]*","fields":{},"createAt":1641586365342,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"75zkot1f3sjb7ifysuzijitw91y","parentId":"cmt5usr1mw3fom886t34ekjquay","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586514173,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7is5m8apdu3g53c8f6cz6sq7bmh","parentId":"cmt5usr1mw3fom886t34ekjquay","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586516563,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7ni9593iz3pnb7xitoz3guwq5gh","parentId":"cmt5usr1mw3fom886t34ekjquay","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641586383504,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7xsmzscbqn3ftudzqbb4w1q7t7e","parentId":"cmt5usr1mw3fom886t34ekjquay","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586518624,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"agjkcro3x7irbxedyxrn8iuerrr","parentId":"cmt5usr1mw3fom886t34ekjquay","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Action Items","fields":{},"createAt":1641586506048,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aw53ugkfq8pyi9fjh9j6i4kdeiw","parentId":"cmt5usr1mw3fom886t34ekjquay","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Notes\n*[Add meeting notes here]*","fields":{},"createAt":1641586380592,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"76h9y996sdj8sbrbpqjo9d8cwto","parentId":"cnqsbzg4b7brfddtyh7fc66atrw","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641586375619,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7hudywfzcwirkpcp1p5jhsfs83r","parentId":"cnqsbzg4b7brfddtyh7fc66atrw","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586495344,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7jzw67ngdgtns8mstsg9g614oac","parentId":"cnqsbzg4b7brfddtyh7fc66atrw","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586497433,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7y6zcyofmsfrbt899ts1ixr3iey","parentId":"cnqsbzg4b7brfddtyh7fc66atrw","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"","fields":{"value":false},"createAt":1641586492877,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aco8iu5jp7jbyzmzegwxkeusgzr","parentId":"cnqsbzg4b7brfddtyh7fc66atrw","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Action Items","fields":{},"createAt":1641586487881,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ao57n1fbtmt8q8bfk8ieqgzqt3a","parentId":"cnqsbzg4b7brfddtyh7fc66atrw","rootId":"b7wnw9awd4pnefryhq51apbzb4c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Notes\n*[Add meeting notes here]*","fields":{},"createAt":1641586373252,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

View File

@ -0,0 +1,22 @@
{"type":"block","data":{"id":"bbn1888mprfrm5fjw9f1je9x3xo","parentId":"","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"board","title":"Personal Tasks (NEW)","fields":{"cardProperties":[{"id":"a9zf59u8x1rf4ywctpcqama7tio","name":"Occurrence","options":[{"color":"propColorBlue","id":"an51dnkenmoog9cetapbc4uyt3y","value":"Daily"},{"color":"propColorOrange","id":"afpy8s7i45frggprmfsqngsocqh","value":"Weekly"},{"color":"propColorPurple","id":"aj4jyekqqssatjcq7r7chmy19ey","value":"Monthly"}],"type":"select"},{"id":"abthng7baedhhtrwsdodeuincqy","name":"Completed","options":[],"type":"checkbox"}],"columnCalculations":[],"description":"Use this template to organize your life and track your personal tasks.","icon":"✔️","isTemplate":false,"showDescription":true},"createAt":1640281433899,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c5xamko6rpibhje3bjreenon7ce","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Pay bills","fields":{"contentOrder":["7gwsf4uxtftgjt841zgwydxeere","7j6rbt87htj83bbssod76iumsja","7fjacjgfxjfrf3psxc46wwsgqdo"],"icon":"🔌","isTemplate":false,"properties":{"a9zf59u8x1rf4ywctpcqama7tio":"aj4jyekqqssatjcq7r7chmy19ey","abthng7baedhhtrwsdodeuincqy":"true"}},"createAt":1640366942078,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"co6a88h6og3dm3kkub64kyb71jw","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Buy groceries","fields":{"contentOrder":["amd9sbzwrkpdspkisato6ajmzby","7r749xjm5pfnuib18sefxwezc4o","7zhat99shridtfntr97ek5j7yho","7imjjx8fazty8fcjzkns464nupy","7cbjz6bszwprnby56gfgzqehexc","76x8gh63upjdnm8uso3nja7gjqh","7z6ho1e3dibg6mki7jug84yxpja"],"icon":"🛒","isTemplate":false,"properties":{"a9zf59u8x1rf4ywctpcqama7tio":"afpy8s7i45frggprmfsqngsocqh"}},"createAt":1640365957059,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cr7gz7sempbfqpq7sign4jaeyxc","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Go for a walk","fields":{"contentOrder":["a6b44enuiwpgszm1wt6og1mshqa","aumtoywd8wjy7udm4ntcib4ckpo","75gpszxg6difjmf1j3f5edj3w7a"],"icon":"👣","isTemplate":false,"properties":{"a9zf59u8x1rf4ywctpcqama7tio":"an51dnkenmoog9cetapbc4uyt3y"}},"createAt":1640281433950,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cx7cki81xppd3pdgnyktwbgtzer","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Feed Fluffy","fields":{"contentOrder":["as5kdrix3ibd3jrnqzz94dcqqba"],"icon":"🐱","isTemplate":false,"properties":{"a9zf59u8x1rf4ywctpcqama7tio":"an51dnkenmoog9cetapbc4uyt3y"}},"createAt":1640281433850,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"czowhma7rnpgb3eczbqo3t7fijo","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Gardening","fields":{"contentOrder":[],"icon":"🌳","isTemplate":false,"properties":{"a9zf59u8x1rf4ywctpcqama7tio":"afpy8s7i45frggprmfsqngsocqh"}},"createAt":1640281433750,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vjq4piq89kbds5x5zq39zww7joo","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"List View","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"__title":280},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["a9zf59u8x1rf4ywctpcqama7tio","abthng7baedhhtrwsdodeuincqy"]},"createAt":1641247999081,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vyeipq97iqbfjtd6fgcbxg6xbme","parentId":"bbn1888mprfrm5fjw9f1je9x3xo","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Board View","fields":{"cardOrder":["co6a88h6og3dm3kkub64kyb71jw","c5xamko6rpibhje3bjreenon7ce","cr7gz7sempbfqpq7sign4jaeyxc","cx7cki81xppd3pdgnyktwbgtzer","czowhma7rnpgb3eczbqo3t7fijo"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"cidrrzojxpfroicutox1hoyk91h","filter":{"filters":[],"operation":"and"},"groupById":"a9zf59u8x1rf4ywctpcqama7tio","hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"board","visibleOptionIds":["an51dnkenmoog9cetapbc4uyt3y","afpy8s7i45frggprmfsqngsocqh","aj4jyekqqssatjcq7r7chmy19ey",""],"visiblePropertyIds":["a9zf59u8x1rf4ywctpcqama7tio"]},"createAt":1640281433698,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7fjacjgfxjfrf3psxc46wwsgqdo","parentId":"c5xamko6rpibhje3bjreenon7ce","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Utilities","fields":{"value":true},"createAt":1640367568655,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7gwsf4uxtftgjt841zgwydxeere","parentId":"c5xamko6rpibhje3bjreenon7ce","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Mobile phone","fields":{"value":true},"createAt":1640367517692,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7j6rbt87htj83bbssod76iumsja","parentId":"c5xamko6rpibhje3bjreenon7ce","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Internet","fields":{"value":true},"createAt":1640367560684,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"76x8gh63upjdnm8uso3nja7gjqh","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Cereal","fields":{"value":false},"createAt":1640366017886,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7cbjz6bszwprnby56gfgzqehexc","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Butter","fields":{"value":false},"createAt":1640365985683,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7imjjx8fazty8fcjzkns464nupy","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Bread","fields":{"value":false},"createAt":1640365983209,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7r749xjm5pfnuib18sefxwezc4o","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Milk","fields":{"value":false},"createAt":1640365978720,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7z6ho1e3dibg6mki7jug84yxpja","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Bananas","fields":{"value":false},"createAt":1640367364568,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7zhat99shridtfntr97ek5j7yho","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Eggs","fields":{"value":false},"createAt":1640365980953,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"amd9sbzwrkpdspkisato6ajmzby","parentId":"co6a88h6og3dm3kkub64kyb71jw","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Grocery list","fields":{},"createAt":1640367228497,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"75gpszxg6difjmf1j3f5edj3w7a","parentId":"cr7gz7sempbfqpq7sign4jaeyxc","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"76fwrj36hptg6dywka4k5mt3sph.png"},"createAt":1640368278060,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a6b44enuiwpgszm1wt6og1mshqa","parentId":"cr7gz7sempbfqpq7sign4jaeyxc","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Goal\nWalk at least 10,000 steps every day.","fields":{},"createAt":1640367836067,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aumtoywd8wjy7udm4ntcib4ckpo","parentId":"cr7gz7sempbfqpq7sign4jaeyxc","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Route","fields":{},"createAt":1640368155600,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"as5kdrix3ibd3jrnqzz94dcqqba","parentId":"cx7cki81xppd3pdgnyktwbgtzer","rootId":"bbn1888mprfrm5fjw9f1je9x3xo","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"","fields":{},"createAt":1640368933239,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

View File

@ -0,0 +1,52 @@
{"type":"block","data":{"id":"bc41mwxg9ybb69pn9j5zna6d36c","parentId":"","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"board","title":"Project Tasks (NEW)","fields":{"cardProperties":[{"id":"a972dc7a-5f4c-45d2-8044-8c28c69717f1","name":"Status","options":[{"color":"propColorBlue","id":"ayz81h9f3dwp7rzzbdebesc7ute","value":"Not Started"},{"color":"propColorYellow","id":"ar6b8m3jxr3asyxhr8iucdbo6yc","value":"In Progress"},{"color":"propColorRed","id":"afi4o5nhnqc3smtzs1hs3ij34dh","value":"Blocked"},{"color":"propColorGreen","id":"adeo5xuwne3qjue83fcozekz8ko","value":"Completed 🙌"},{"color":"propColorBrown","id":"ahpyxfnnrzynsw3im1psxpkgtpe","value":"Archived"}],"type":"select"},{"id":"d3d682bf-e074-49d9-8df5-7320921c2d23","name":"Priority","options":[{"color":"propColorRed","id":"d3bfb50f-f569-4bad-8a3a-dd15c3f60101","value":"1. High 🔥"},{"color":"propColorYellow","id":"87f59784-b859-4c24-8ebe-17c766e081dd","value":"2. Medium"},{"color":"propColorGray","id":"98a57627-0f76-471d-850d-91f3ed9fd213","value":"3. Low"}],"type":"select"},{"id":"axkhqa4jxr3jcqe4k87g8bhmary","name":"Assignee","options":[],"type":"person"},{"id":"a8daz81s4xjgke1ww6cwik5w7ye","name":"Estimated Hours","options":[],"type":"number"},{"id":"a3zsw7xs8sxy7atj8b6totp3mby","name":"Due Date","options":[],"type":"date"},{"id":"a7gdnz8ff8iyuqmzddjgmgo9ery","name":"Created By","options":[],"type":"createdBy"},{"id":"2a5da320-735c-4093-8787-f56e15cdfeed","name":"Date Created","options":[],"type":"createdTime"}],"columnCalculations":{"a8daz81s4xjgke1ww6cwik5w7ye":"sum"},"description":"Use this template to stay on top of your project tasks and progress.","icon":"🎯","isTemplate":false,"showDescription":true},"createAt":1640281242611,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c68gyx34srjgjxmrs1z8pj7nbce","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Identify dependencies","fields":{"contentOrder":["akqkae666a7bnbgib4ykbexjjey","7b1h5q66pkig4mp948z635dejxy","aepujbmb347ye9j7uikbk3oajqh","76q9tmzey4byqdpimsdxeg1gx3h","79qbaadiuwjgujnz9tgqmmkaaqo","7msorzdb7r3rk3qjncmdxhpqz5o","7izro8efd1irwpepfph4uz56bgh"],"icon":"🔗","isTemplate":false,"properties":{"a8daz81s4xjgke1ww6cwik5w7ye":"16","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ayz81h9f3dwp7rzzbdebesc7ute","d3d682bf-e074-49d9-8df5-7320921c2d23":"98a57627-0f76-471d-850d-91f3ed9fd213"}},"createAt":1640364405240,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c6w7rxrootfdw7j4fsftc5gsyoo","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Define project scope","fields":{"contentOrder":["ags74nq3isiywmmkkg8h4tbxcfh","7q7rkcbuqwfffjgrk57yjkydnry","a66dncm7qppd4tjo9886d5bbsaa","7jy54jqerhbnj7r4efpuk3g4cda","716fy9hw4p38a5mf8rq5ap6txoo","7opf3hssh6pn9zyy6toh53r49iw","7g1qskptj9i8gimg1aynyqtnwka"],"icon":"🔬","isTemplate":false,"properties":{"a8daz81s4xjgke1ww6cwik5w7ye":"32","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ar6b8m3jxr3asyxhr8iucdbo6yc","d3d682bf-e074-49d9-8df5-7320921c2d23":"87f59784-b859-4c24-8ebe-17c766e081dd"}},"createAt":1640364532461,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cdwqxf4b3utbbxdrgbwtmk9y9eo","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Requirements sign-off","fields":{"contentOrder":["aags5e9sbbfnqtrtf39hoopbxme","7kriyyuos4pgg8k6t8fkcsa7bde","adw7awe3ucp8g781dfq7yw6kfur","7xk7xg6yonbn88fpkihigzn8whr","7b9uyiog56jr1zgonbutxfd7w3c","7r3ua3e7w3jrmpqdngzqs74i1go","76hsxtocpnbnrijxqcfccfkyo1e"],"icon":"🖋️","isTemplate":false,"properties":{"a8daz81s4xjgke1ww6cwik5w7ye":"8","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ayz81h9f3dwp7rzzbdebesc7ute","d3d682bf-e074-49d9-8df5-7320921c2d23":"d3bfb50f-f569-4bad-8a3a-dd15c3f60101"}},"createAt":1640281242441,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cfk8kwmuhcfd8m8qicz5aqw4mar","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Project budget approval","fields":{"contentOrder":["a9h4kfaurrprepefrw95i1raoxr","7btyuex8nji8jxn9yieaxgwoe6h","a34hy46bu8bngxcxpz9woui4afa","7ekrgkgq67fdofn9gskpe19bkrc","7ygi1kq3683ya5ydfttuc5rhasr","7qmjyww91rj8a38dsgu5b5wu7hr","7qmmpepfm4byqjqo9m16yp7m3no"],"icon":"💵","isTemplate":false,"properties":{"a8daz81s4xjgke1ww6cwik5w7ye":"16","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ayz81h9f3dwp7rzzbdebesc7ute","d3d682bf-e074-49d9-8df5-7320921c2d23":"d3bfb50f-f569-4bad-8a3a-dd15c3f60101"}},"createAt":1640281242677,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ckcntrrmcjbywpciau57gw5suoo","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Conduct market analysis","fields":{"contentOrder":["a6gowxxpgijgip8qzrsp5rmjwqy","771bq4ja3ejfwbgaq78cdpgmjih","asdoj8ffhcirh3x3iys3joeox9o","7k975b49ni7yrfn3nqg7q4x4wde","7e9aj57zouidozb8sf8e1wybywe","71dm4jiu43byubx7pukjiy19pay","719y6x4tkiigd9nwarn1e6ek7ic"],"icon":"📈","isTemplate":false,"properties":{"a8daz81s4xjgke1ww6cwik5w7ye":"40","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ar6b8m3jxr3asyxhr8iucdbo6yc","d3d682bf-e074-49d9-8df5-7320921c2d23":"87f59784-b859-4c24-8ebe-17c766e081dd"}},"createAt":1640281242851,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vcuoise4b8jn1ffzujfuacymmmr","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Project Priorities","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"groupById":"d3d682bf-e074-49d9-8df5-7320921c2d23","hiddenOptionIds":[],"kanbanCalculations":{"":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"87f59784-b859-4c24-8ebe-17c766e081dd":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"98a57627-0f76-471d-850d-91f3ed9fd213":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"d3bfb50f-f569-4bad-8a3a-dd15c3f60101":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"}},"sortOptions":[],"viewType":"board","visibleOptionIds":["d3bfb50f-f569-4bad-8a3a-dd15c3f60101","87f59784-b859-4c24-8ebe-17c766e081dd","98a57627-0f76-471d-850d-91f3ed9fd213",""],"visiblePropertyIds":["a972dc7a-5f4c-45d2-8044-8c28c69717f1","a8daz81s4xjgke1ww6cwik5w7ye"]},"createAt":1640281242551,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vey61xzc6u38ptnpjqaik6ap91e","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Progress Tracker","fields":{"cardOrder":["cfk8kwmuhcfd8m8qicz5aqw4mar","cdwqxf4b3utbbxdrgbwtmk9y9eo","c68gyx34srjgjxmrs1z8pj7nbce","ckcntrrmcjbywpciau57gw5suoo","c6w7rxrootfdw7j4fsftc5gsyoo","coxnjt3ro1in19dd1e3awdt338r"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"czw9es1e89fdpjr7cqptr1xq7qh","filter":{"filters":[],"operation":"and"},"groupById":"a972dc7a-5f4c-45d2-8044-8c28c69717f1","hiddenOptionIds":[],"kanbanCalculations":{"":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"adeo5xuwne3qjue83fcozekz8ko":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"afi4o5nhnqc3smtzs1hs3ij34dh":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"ahpyxfnnrzynsw3im1psxpkgtpe":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"ar6b8m3jxr3asyxhr8iucdbo6yc":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"},"ayz81h9f3dwp7rzzbdebesc7ute":{"calculation":"sum","propertyId":"a8daz81s4xjgke1ww6cwik5w7ye"}},"sortOptions":[],"viewType":"board","visibleOptionIds":["ayz81h9f3dwp7rzzbdebesc7ute","ar6b8m3jxr3asyxhr8iucdbo6yc","afi4o5nhnqc3smtzs1hs3ij34dh","adeo5xuwne3qjue83fcozekz8ko","ahpyxfnnrzynsw3im1psxpkgtpe",""],"visiblePropertyIds":["d3d682bf-e074-49d9-8df5-7320921c2d23","a8daz81s4xjgke1ww6cwik5w7ye"]},"createAt":1640281242788,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vfztxwjnegbdh38nfccu3bq1auc","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Task Overview","fields":{"cardOrder":["c6w7rxrootfdw7j4fsftc5gsyoo","ckcntrrmcjbywpciau57gw5suoo","c68gyx34srjgjxmrs1z8pj7nbce","cfk8kwmuhcfd8m8qicz5aqw4mar","cdwqxf4b3utbbxdrgbwtmk9y9eo","cz8p8gofakfby8kzz83j97db8ph","ce1jm5q5i54enhuu4h3kkay1hcc"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"2a5da320-735c-4093-8787-f56e15cdfeed":196,"__title":280,"a8daz81s4xjgke1ww6cwik5w7ye":139,"a972dc7a-5f4c-45d2-8044-8c28c69717f1":141,"d3d682bf-e074-49d9-8df5-7320921c2d23":110},"defaultTemplateId":"czw9es1e89fdpjr7cqptr1xq7qh","filter":{"filters":[],"operation":"and"},"groupById":"","hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["a972dc7a-5f4c-45d2-8044-8c28c69717f1","d3d682bf-e074-49d9-8df5-7320921c2d23","2a5da320-735c-4093-8787-f56e15cdfeed","a3zsw7xs8sxy7atj8b6totp3mby","axkhqa4jxr3jcqe4k87g8bhmary","a7gdnz8ff8iyuqmzddjgmgo9ery","a8daz81s4xjgke1ww6cwik5w7ye"]},"createAt":1640281242734,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vi49i1138jpnbiqhyd81beme9zy","parentId":"bc41mwxg9ybb69pn9j5zna6d36c","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Task Calendar","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"dateDisplayPropertyId":"a3zsw7xs8sxy7atj8b6totp3mby","defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"calendar","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1640361708030,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"76q9tmzey4byqdpimsdxeg1gx3h","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 1]","fields":{"value":false},"createAt":1641247437494,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"79qbaadiuwjgujnz9tgqmmkaaqo","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 2]","fields":{"value":false},"createAt":1641247440946,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7b1h5q66pkig4mp948z635dejxy","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641247334696,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7izro8efd1irwpepfph4uz56bgh","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"...","fields":{"value":false},"createAt":1641247447937,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7msorzdb7r3rk3qjncmdxhpqz5o","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 3]","fields":{"value":false},"createAt":1641247445214,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aepujbmb347ye9j7uikbk3oajqh","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Checklist","fields":{},"createAt":1641247378401,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"akqkae666a7bnbgib4ykbexjjey","parentId":"c68gyx34srjgjxmrs1z8pj7nbce","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*","fields":{},"createAt":1641247332262,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"716fy9hw4p38a5mf8rq5ap6txoo","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 2]","fields":{"value":false},"createAt":1641247170396,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7g1qskptj9i8gimg1aynyqtnwka","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"...","fields":{"value":false},"createAt":1641247182126,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7jy54jqerhbnj7r4efpuk3g4cda","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 1]","fields":{"value":false},"createAt":1641247156773,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7opf3hssh6pn9zyy6toh53r49iw","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 3]","fields":{"value":false},"createAt":1641247176917,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7q7rkcbuqwfffjgrk57yjkydnry","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641247131586,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a66dncm7qppd4tjo9886d5bbsaa","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Checklist","fields":{},"createAt":1641247135038,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ags74nq3isiywmmkkg8h4tbxcfh","parentId":"c6w7rxrootfdw7j4fsftc5gsyoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*","fields":{},"createAt":1641247112211,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"76hsxtocpnbnrijxqcfccfkyo1e","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"...","fields":{"value":false},"createAt":1641247486848,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7b9uyiog56jr1zgonbutxfd7w3c","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 2]","fields":{"value":false},"createAt":1641247480724,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7kriyyuos4pgg8k6t8fkcsa7bde","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641247352753,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7r3ua3e7w3jrmpqdngzqs74i1go","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 3]","fields":{"value":false},"createAt":1641247483695,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7xk7xg6yonbn88fpkihigzn8whr","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 1]","fields":{"value":false},"createAt":1641247478297,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aags5e9sbbfnqtrtf39hoopbxme","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*","fields":{},"createAt":1641247350239,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"adw7awe3ucp8g781dfq7yw6kfur","parentId":"cdwqxf4b3utbbxdrgbwtmk9y9eo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Checklist","fields":{},"createAt":1641247399161,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7btyuex8nji8jxn9yieaxgwoe6h","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641247342345,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7ekrgkgq67fdofn9gskpe19bkrc","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 1]","fields":{"value":false},"createAt":1641247459230,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7qmjyww91rj8a38dsgu5b5wu7hr","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 3]","fields":{"value":false},"createAt":1641247464903,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7qmmpepfm4byqjqo9m16yp7m3no","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"...","fields":{"value":false},"createAt":1641247468228,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7ygi1kq3683ya5ydfttuc5rhasr","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 2]","fields":{"value":false},"createAt":1641247461754,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a34hy46bu8bngxcxpz9woui4afa","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Checklist","fields":{},"createAt":1641247389505,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a9h4kfaurrprepefrw95i1raoxr","parentId":"cfk8kwmuhcfd8m8qicz5aqw4mar","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*","fields":{},"createAt":1641247339781,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"719y6x4tkiigd9nwarn1e6ek7ic","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"...","fields":{"value":false},"createAt":1641247428974,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"71dm4jiu43byubx7pukjiy19pay","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 3]","fields":{"value":false},"createAt":1641247425545,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"771bq4ja3ejfwbgaq78cdpgmjih","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641247327922,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7e9aj57zouidozb8sf8e1wybywe","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 2]","fields":{"value":false},"createAt":1641247421647,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7k975b49ni7yrfn3nqg7q4x4wde","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 1]","fields":{"value":false},"createAt":1641247417179,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a6gowxxpgijgip8qzrsp5rmjwqy","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*","fields":{},"createAt":1641247325247,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"asdoj8ffhcirh3x3iys3joeox9o","parentId":"ckcntrrmcjbywpciau57gw5suoo","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Checklist","fields":{},"createAt":1641247365651,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"73a715h3xkiye9jj9px3daujgpa","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 3]","fields":{"value":false},"createAt":1641247243580,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"75afimcsuqby6xxq39wiae9obme","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 2]","fields":{"value":false},"createAt":1641247239940,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7dodh1pgw73yq78pgtmk3ckc9fr","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"divider","title":"","fields":{},"createAt":1641247212754,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7ttgtruigcbfzdmxkhmzt6kp6dh","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"[Subtask 1]","fields":{"value":false},"createAt":1641247226415,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7u7mmiit57b8i8gsp6mc6x7h9he","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"...","fields":{"value":false},"createAt":1641247248372,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"adxx8y691qf8btg7w8mx6x78w9y","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*","fields":{},"createAt":1641247210152,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"afatxnq346jbcin9iisryo38grr","parentId":"czw9es1e89fdpjr7cqptr1xq7qh","rootId":"bc41mwxg9ybb69pn9j5zna6d36c","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Checklist","fields":{},"createAt":1641247215942,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

View File

@ -0,0 +1,8 @@
{"type":"block","data":{"id":"bd65qbzuqupfztpg31dgwgwm5ga","parentId":"","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"board","title":"Personal Goals (NEW)","fields":{"cardProperties":[{"id":"af6fcbb8-ca56-4b73-83eb-37437b9a667d","name":"Status","options":[{"color":"propColorRed","id":"bf52bfe6-ac4c-4948-821f-83eaa1c7b04a","value":"To Do"},{"color":"propColorYellow","id":"77c539af-309c-4db1-8329-d20ef7e9eacd","value":"Doing"},{"color":"propColorGreen","id":"98bdea27-0cce-4cde-8dc6-212add36e63a","value":"Done 🙌"}],"type":"select"},{"id":"d9725d14-d5a8-48e5-8de1-6f8c004a9680","name":"Category","options":[{"color":"propColorPurple","id":"3245a32d-f688-463b-87f4-8e7142c1b397","value":"Life Skills"},{"color":"propColorGreen","id":"80be816c-fc7a-4928-8489-8b02180f4954","value":"Finance"},{"color":"propColorOrange","id":"ffb3f951-b47f-413b-8f1d-238666728008","value":"Health"}],"type":"select"},{"id":"d6b1249b-bc18-45fc-889e-bec48fce80ef","name":"Target","options":[{"color":"propColorBlue","id":"9a090e33-b110-4268-8909-132c5002c90e","value":"Q1"},{"color":"propColorBrown","id":"0a82977f-52bf-457b-841b-e2b7f76fb525","value":"Q2"},{"color":"propColorGreen","id":"6e7139e4-5358-46bb-8c01-7b029a57b80a","value":"Q3"},{"color":"propColorPurple","id":"d5371c63-66bf-4468-8738-c4dc4bea4843","value":"Q4"}],"type":"select"},{"id":"ajy6xbebzopojaenbnmfpgtdwso","name":"Due Date","options":[],"type":"date"}],"columnCalculations":[],"description":"Use this template to set and accomplish new personal goals.","icon":"⛰️","isTemplate":false,"showDescription":true},"createAt":1641246775089,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c76haqhzin78q5dkfko7kwhbjjh","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Start a daily journal","fields":{"contentOrder":[],"icon":"✍️","isTemplate":false,"properties":{"af6fcbb8-ca56-4b73-83eb-37437b9a667d":"bf52bfe6-ac4c-4948-821f-83eaa1c7b04a","d6b1249b-bc18-45fc-889e-bec48fce80ef":"0a82977f-52bf-457b-841b-e2b7f76fb525","d9725d14-d5a8-48e5-8de1-6f8c004a9680":"3245a32d-f688-463b-87f4-8e7142c1b397"}},"createAt":1641246774828,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ca3byfg7iq3g8zjpg1t8hwa6ekh","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Run 3 times a week","fields":{"contentOrder":[],"icon":"🏃","isTemplate":false,"properties":{"af6fcbb8-ca56-4b73-83eb-37437b9a667d":"bf52bfe6-ac4c-4948-821f-83eaa1c7b04a","d6b1249b-bc18-45fc-889e-bec48fce80ef":"6e7139e4-5358-46bb-8c01-7b029a57b80a","d9725d14-d5a8-48e5-8de1-6f8c004a9680":"ffb3f951-b47f-413b-8f1d-238666728008"}},"createAt":1641246775039,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ckng5n1ag5f8m5gfdifn7ijof9y","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Learn to paint","fields":{"contentOrder":[],"icon":"🎨","isTemplate":false,"properties":{"af6fcbb8-ca56-4b73-83eb-37437b9a667d":"77c539af-309c-4db1-8329-d20ef7e9eacd","d6b1249b-bc18-45fc-889e-bec48fce80ef":"9a090e33-b110-4268-8909-132c5002c90e","d9725d14-d5a8-48e5-8de1-6f8c004a9680":"3245a32d-f688-463b-87f4-8e7142c1b397"}},"createAt":1641246774928,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cw9zofoi6dj8x7x8r6ypebpwpuc","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Open retirement account","fields":{"contentOrder":[],"icon":"🏦","isTemplate":false,"properties":{"af6fcbb8-ca56-4b73-83eb-37437b9a667d":"bf52bfe6-ac4c-4948-821f-83eaa1c7b04a","d6b1249b-bc18-45fc-889e-bec48fce80ef":"0a82977f-52bf-457b-841b-e2b7f76fb525","d9725d14-d5a8-48e5-8de1-6f8c004a9680":"80be816c-fc7a-4928-8489-8b02180f4954"}},"createAt":1641246774987,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"v9sj7oekk1jr1pemtf9rps7fate","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"By Status","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"groupById":"af6fcbb8-ca56-4b73-83eb-37437b9a667d","hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"board","visibleOptionIds":["bf52bfe6-ac4c-4948-821f-83eaa1c7b04a","77c539af-309c-4db1-8329-d20ef7e9eacd","98bdea27-0cce-4cde-8dc6-212add36e63a",""],"visiblePropertyIds":["d9725d14-d5a8-48e5-8de1-6f8c004a9680","d6b1249b-bc18-45fc-889e-bec48fce80ef"]},"createAt":1641246774878,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vrpmc8r6nj7fcmdkp18cpcekzco","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Calendar View","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"dateDisplayPropertyId":"ajy6xbebzopojaenbnmfpgtdwso","defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"calendar","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1641247726340,"updateAt":1643788318630,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vw9mbn66j97dwb8jhqiq7zuum5e","parentId":"bd65qbzuqupfztpg31dgwgwm5ga","rootId":"bd65qbzuqupfztpg31dgwgwm5ga","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"By Date","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"groupById":"d6b1249b-bc18-45fc-889e-bec48fce80ef","hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"board","visibleOptionIds":["9a090e33-b110-4268-8909-132c5002c90e","0a82977f-52bf-457b-841b-e2b7f76fb525","6e7139e4-5358-46bb-8c01-7b029a57b80a","d5371c63-66bf-4468-8738-c4dc4bea4843",""],"visiblePropertyIds":["d9725d14-d5a8-48e5-8de1-6f8c004a9680"]},"createAt":1641246775139,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -0,0 +1,18 @@
{"type":"block","data":{"id":"brs9cdimfw7fodyi7erqt747rhc","parentId":"","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"board","title":"Content Calendar (NEW)","fields":{"cardProperties":[{"id":"ae9ar615xoknd8hw8py7mbyr7zo","name":"Status","options":[{"color":"propColorGray","id":"awna1nuarjca99m9s4uiy9kwj5h","value":"Idea 💡"},{"color":"propColorOrange","id":"a9ana1e9w673o5cp8md4xjjwfto","value":"Draft"},{"color":"propColorPurple","id":"apy9dcd7zmand615p3h53zjqxjh","value":"In Review"},{"color":"propColorBlue","id":"acri4cm3bmay55f7ksztphmtnga","value":"Ready to Publish"},{"color":"propColorGreen","id":"amsowcd9a8e1kid317r7ttw6uzh","value":"Published 🎉"}],"type":"select"},{"id":"aysx3atqexotgwp5kx6h5i5ancw","name":"Type","options":[{"color":"propColorOrange","id":"aywiofmmtd3ofgzj95ysky4pjga","value":"Press Release"},{"color":"propColorGreen","id":"apqdgjrmsmx8ngmp7zst51647de","value":"Sponsored Post"},{"color":"propColorPurple","id":"a3woynbjnb7j16e74uw3pubrytw","value":"Customer Story"},{"color":"propColorRed","id":"aq36k5pkpfcypqb3idw36xdi1fh","value":"Product Release"},{"color":"propColorGray","id":"azn66pmk34adygnizjqhgiac4ia","value":"Partnership"},{"color":"propColorBlue","id":"aj8y675weso8kpb6eceqbpj4ruw","value":"Feature Announcement"},{"color":"propColorYellow","id":"a3xky7ygn14osr1mokerbfah5cy","value":"Article"}],"type":"select"},{"id":"ab6mbock6styfe6htf815ph1mhw","name":"Channel","options":[{"color":"propColorBrown","id":"a8xceonxiu4n3c43szhskqizicr","value":"Website"},{"color":"propColorGreen","id":"a3pdzi53kpbd4okzdkz6khi87zo","value":"Blog"},{"color":"propColorOrange","id":"a3d9ux4fmi3anyd11kyipfbhwde","value":"Email"},{"color":"propColorRed","id":"a8cbbfdwocx73zn3787cx6gacsh","value":"Podcast"},{"color":"propColorPink","id":"aigjtpcaxdp7d6kmctrwo1ztaia","value":"Print"},{"color":"propColorBlue","id":"af1wsn13muho59e7ghwaogxy5ey","value":"Facebook"},{"color":"propColorGray","id":"a47zajfxwhsg6q8m7ppbiqs7jge","value":"LinkedIn"},{"color":"propColorYellow","id":"az8o8pfe9hq6s7xaehoqyc3wpyc","value":"Twitter"}],"type":"multiSelect"},{"id":"ao44fz8nf6z6tuj1x31t9yyehcc","name":"Assignee","options":[],"type":"person"},{"id":"a39x5cybshwrbjpc3juaakcyj6e","name":"Due Date","options":[],"type":"date"},{"id":"agqsoiipowmnu9rdwxm57zrehtr","name":"Publication Date","options":[],"type":"date"},{"id":"ap4e7kdg7eip7j3c3oyiz39eaoc","name":"Link","options":[],"type":"url"}],"columnCalculations":[],"description":"Use this template to plan and organize your editorial content.","icon":"📅","isTemplate":false,"showDescription":true},"createAt":1641618112737,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c3pxiqf156fnhjfazwwpo79rt6w","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"New Project and Workflow Management Solutions for Developers","fields":{"contentOrder":["71qhnzuec6esdi6fnynwpze4xya","aianjmrimwfyr7jiiju1oi77kiw"],"icon":"🎯","isTemplate":false,"properties":{"a39x5cybshwrbjpc3juaakcyj6e":"{\"from\":1645790400000}","ab6mbock6styfe6htf815ph1mhw":["a8xceonxiu4n3c43szhskqizicr","a3pdzi53kpbd4okzdkz6khi87zo","a3d9ux4fmi3anyd11kyipfbhwde"],"ae9ar615xoknd8hw8py7mbyr7zo":"awna1nuarjca99m9s4uiy9kwj5h","ap4e7kdg7eip7j3c3oyiz39eaoc":"https://mattermost.com/newsroom/press-releases/mattermost-launches-new-project-and-workflow-management-solutions-for-developers/","aysx3atqexotgwp5kx6h5i5ancw":"aywiofmmtd3ofgzj95ysky4pjga"}},"createAt":1641618113009,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cemyj9s9nwtgzieowpufrd1oo5h","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"[Tweet] Mattermost v6.1 includes card @-mention notifications in Boards","fields":{"contentOrder":["7i96m7nbsdsex8n6hzuzrmdfjuy","7ed5bwp3gr8yax3mhtuwiaa9gjy","a8egmu8gsqp8dzfk9pgpq5mm4ta","awyawmyjtj3nfffu4aphaqy9bgy","abdasiyq4k7ndtfrdadrias8sjy","71ppnm4bcmbrbpn73nefjkao17r"],"icon":"🐤","isTemplate":false,"properties":{"a39x5cybshwrbjpc3juaakcyj6e":"{\"from\":1639051200000}","ab6mbock6styfe6htf815ph1mhw":["az8o8pfe9hq6s7xaehoqyc3wpyc"],"ae9ar615xoknd8hw8py7mbyr7zo":"a9ana1e9w673o5cp8md4xjjwfto","agqsoiipowmnu9rdwxm57zrehtr":"{\"from\":1637668800000}","ap4e7kdg7eip7j3c3oyiz39eaoc":"https://twitter.com/Mattermost/status/1463145633162969097?s=20","aysx3atqexotgwp5kx6h5i5ancw":"aj8y675weso8kpb6eceqbpj4ruw"}},"createAt":1641618112896,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cp963ioyx63rz98q8gs19nxxm7w","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Top 10 Must-Have DevOps Tools in 2021","fields":{"contentOrder":["7fo1utqc8x1z1z6hzg33hes1ktc","ajm6ykd3633dbxdq6j76wtthbia"],"icon":"🛠️","isTemplate":false,"properties":{"a39x5cybshwrbjpc3juaakcyj6e":"{\"from\":1636113600000}","ab6mbock6styfe6htf815ph1mhw":["a8xceonxiu4n3c43szhskqizicr"],"ae9ar615xoknd8hw8py7mbyr7zo":"a9ana1e9w673o5cp8md4xjjwfto","agqsoiipowmnu9rdwxm57zrehtr":"{\"from\":1637323200000}","ap4e7kdg7eip7j3c3oyiz39eaoc":"https://www.toolbox.com/tech/devops/articles/best-devops-tools/","aysx3atqexotgwp5kx6h5i5ancw":"a3xky7ygn14osr1mokerbfah5cy"}},"createAt":1641618112796,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"crrwzx9z4dfbsiki6suzwj3mqfw","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Unblocking Workflows: The Guide to Developer Productivity","fields":{"contentOrder":["77tz16jtz5x73ncs3dxc3fp1d7h","asmp1ztc1gjyh3k8og8yyizu5jy"],"icon":"💻","isTemplate":false,"properties":{"a39x5cybshwrbjpc3juaakcyj6e":"{\"from\":1638532800000}","ab6mbock6styfe6htf815ph1mhw":["a3pdzi53kpbd4okzdkz6khi87zo"],"ae9ar615xoknd8hw8py7mbyr7zo":"apy9dcd7zmand615p3h53zjqxjh","agqsoiipowmnu9rdwxm57zrehtr":"{\"from\":1639483200000}","ap4e7kdg7eip7j3c3oyiz39eaoc":"https://mattermost.com/newsroom/press-releases/mattermost-unveils-definitive-report-on-the-state-of-developer-productivity-unblocking-workflows-the-guide-to-developer-productivity-2022-edition/","aysx3atqexotgwp5kx6h5i5ancw":"a3xky7ygn14osr1mokerbfah5cy"}},"createAt":1641618112846,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vaiuu5bg4ofdn8j4whttdgtus4w","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"By Status","fields":{"cardOrder":[null,"cdbfkd15d6iy18rgx1tskmfsr6c","cn8yofg9rtkgmzgmb5xdi56p3ic","csgsnnywpuqzs5jgq87snk9x17e","cqwaytore5y487wdu8zffppqnea",null],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"cff1jmrxfrirgbeebhr9qd7nida","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"board","visibleOptionIds":["awna1nuarjca99m9s4uiy9kwj5h","a9ana1e9w673o5cp8md4xjjwfto","apy9dcd7zmand615p3h53zjqxjh","acri4cm3bmay55f7ksztphmtnga","amsowcd9a8e1kid317r7ttw6uzh",""],"visiblePropertyIds":["ab6mbock6styfe6htf815ph1mhw"]},"createAt":1641618113176,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vgbzazskupjrq7gnrwqqk51adsh","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Due Date Calendar","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"dateDisplayPropertyId":"a39x5cybshwrbjpc3juaakcyj6e","defaultTemplateId":"cff1jmrxfrirgbeebhr9qd7nida","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"calendar","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1641618113068,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vkk4dm1tnzb8fbmr5gxhibr63te","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Publication Calendar","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"dateDisplayPropertyId":"agqsoiipowmnu9rdwxm57zrehtr","defaultTemplateId":"cff1jmrxfrirgbeebhr9qd7nida","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"calendar","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1641618113123,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vpsefkithi7gq3rfyignqxa9cze","parentId":"brs9cdimfw7fodyi7erqt747rhc","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Content List","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"__title":322,"ab6mbock6styfe6htf815ph1mhw":229,"aysx3atqexotgwp5kx6h5i5ancw":208},"defaultTemplateId":"cff1jmrxfrirgbeebhr9qd7nida","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[{"propertyId":"a39x5cybshwrbjpc3juaakcyj6e","reversed":false}],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["ae9ar615xoknd8hw8py7mbyr7zo","aysx3atqexotgwp5kx6h5i5ancw","ab6mbock6styfe6htf815ph1mhw","ao44fz8nf6z6tuj1x31t9yyehcc","a39x5cybshwrbjpc3juaakcyj6e","agqsoiipowmnu9rdwxm57zrehtr","ap4e7kdg7eip7j3c3oyiz39eaoc"]},"createAt":1641618243042,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aianjmrimwfyr7jiiju1oi77kiw","parentId":"c3pxiqf156fnhjfazwwpo79rt6w","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n\n## Notes\n- ...\n- ...","fields":{},"createAt":1641618141074,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"71ppnm4bcmbrbpn73nefjkao17r","parentId":"cemyj9s9nwtgzieowpufrd1oo5h","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7y5kr8x8ybpnwdykjfuz57rggrh.png"},"createAt":1641618185785,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a8egmu8gsqp8dzfk9pgpq5mm4ta","parentId":"cemyj9s9nwtgzieowpufrd1oo5h","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n\n## Notes\n- ...\n- ...","fields":{},"createAt":1641618157625,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"awyawmyjtj3nfffu4aphaqy9bgy","parentId":"cemyj9s9nwtgzieowpufrd1oo5h","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Media","fields":{},"createAt":1641618160634,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a4uyug1msrtrkdfy5fwu8shf7so","parentId":"cff1jmrxfrirgbeebhr9qd7nida","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n\n## Notes\n- ...\n- ...","fields":{},"createAt":1641618338368,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"abztjcgndkffd3gybef6phr14so","parentId":"cff1jmrxfrirgbeebhr9qd7nida","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n- ...\n\n## Notes\n- ...\n- ...\n- ...","fields":{},"createAt":1641618112322,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"azczyg4pfj3ysjpxf4hjtu666ne","parentId":"cff1jmrxfrirgbeebhr9qd7nida","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n\n## Notes\n- ...\n- ...","fields":{},"createAt":1641618112527,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ajm6ykd3633dbxdq6j76wtthbia","parentId":"cp963ioyx63rz98q8gs19nxxm7w","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n\n## Notes\n- ...\n- ...","fields":{},"createAt":1641618208454,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"asmp1ztc1gjyh3k8og8yyizu5jy","parentId":"crrwzx9z4dfbsiki6suzwj3mqfw","rootId":"brs9cdimfw7fodyi7erqt747rhc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Research\n- ...\n- ...\n\n## Plan\n- ...\n- ...\n\n## Notes\n- ...\n- ...","fields":{},"createAt":1641618224780,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -0,0 +1,31 @@
{"type":"block","data":{"id":"bui5izho7dtn77xg3thkiqprc9r","parentId":"","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"board","title":"Roadmap (NEW)","fields":{"cardProperties":[{"id":"50117d52-bcc7-4750-82aa-831a351c44a0","name":"Status","options":[{"color":"propColorGray","id":"8c557f69-b0ed-46ec-83a3-8efab9d47ef5","value":"Not Started"},{"color":"propColorYellow","id":"ec6d2bc5-df2b-4f77-8479-e59ceb039946","value":"In Progress"},{"color":"propColorGreen","id":"849766ba-56a5-48d1-886f-21672f415395","value":"Complete 🙌"}],"type":"select"},{"id":"20717ad3-5741-4416-83f1-6f133fff3d11","name":"Type","options":[{"color":"propColorYellow","id":"424ea5e3-9aa1-4075-8c5c-01b44b66e634","value":"Epic ⛰"},{"color":"propColorGreen","id":"6eea96c9-4c61-4968-8554-4b7537e8f748","value":"Task 🔨"},{"color":"propColorRed","id":"1fdbb515-edd2-4af5-80fc-437ed2211a49","value":"Bug 🐞"}],"type":"select"},{"id":"60985f46-3e41-486e-8213-2b987440ea1c","name":"Sprint","options":[{"color":"propColorBrown","id":"c01676ca-babf-4534-8be5-cce2287daa6c","value":"Sprint 1"},{"color":"propColorPurple","id":"ed4a5340-460d-461b-8838-2c56e8ee59fe","value":"Sprint 2"},{"color":"propColorBlue","id":"14892380-1a32-42dd-8034-a0cea32bc7e6","value":"Sprint 3"}],"type":"select"},{"id":"f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e","name":"Priority","options":[{"color":"propColorRed","id":"cb8ecdac-38be-4d36-8712-c4d58cc8a8e9","value":"P1 🔥"},{"color":"propColorYellow","id":"e6a7f297-4440-4783-8ab3-3af5ba62ca11","value":"P2"},{"color":"propColorGray","id":"c62172ea-5da7-4dec-8186-37267d8ee9a7","value":"P3"}],"type":"select"},{"id":"aphg37f7zbpuc3bhwhp19s1ribh","name":"Assignee","options":[],"type":"person"},{"id":"a4378omyhmgj3bex13sj4wbpfiy","name":"Due Date","options":[],"type":"date"},{"id":"a36o9q1yik6nmar6ri4q4uca7ey","name":"Created Date","options":[],"type":"createdTime"},{"id":"ai7ajsdk14w7x5s8up3dwir77te","name":"Design Link","options":[],"type":"url"}],"columnCalculations":[],"description":"Use this template to plan your roadmap and manage your releases more efficiently.","icon":"🗺️","isTemplate":false,"showDescription":true},"createAt":1640363551156,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c3jawn6e4fbr3jctthy9xxkdsqe","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"App crashing","fields":{"contentOrder":["79t7rkiuspeneqi9xurou9tqzwh","a4d68ftemrbfsfykur6eh6nrogh","ae54fbyywubnbtr3s4yhgns4nye","7o9ktgofg37yc7gma9s3jd9bd3a"],"icon":"📉","isTemplate":false,"properties":{"20717ad3-5741-4416-83f1-6f133fff3d11":"1fdbb515-edd2-4af5-80fc-437ed2211a49","50117d52-bcc7-4750-82aa-831a351c44a0":"ec6d2bc5-df2b-4f77-8479-e59ceb039946","60985f46-3e41-486e-8213-2b987440ea1c":"c01676ca-babf-4534-8be5-cce2287daa6c","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e":"cb8ecdac-38be-4d36-8712-c4d58cc8a8e9"}},"createAt":1641589357560,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c5trb4319wi8n3x4r4f7f83ytdc","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Calendar view","fields":{"contentOrder":["7df11783ny67mdnognqae31ax6y","ag9rxpgbwqid1mm5hgg8b9yhf6o"],"icon":"📆","isTemplate":false,"properties":{"20717ad3-5741-4416-83f1-6f133fff3d11":"6eea96c9-4c61-4968-8554-4b7537e8f748","50117d52-bcc7-4750-82aa-831a351c44a0":"849766ba-56a5-48d1-886f-21672f415395","60985f46-3e41-486e-8213-2b987440ea1c":"c01676ca-babf-4534-8be5-cce2287daa6c","ai7ajsdk14w7x5s8up3dwir77te":"https://mattermost.com/boards/","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e":"e6a7f297-4440-4783-8ab3-3af5ba62ca11"}},"createAt":1641590072588,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c9p4bdasriifc7qgihzhjm63ugy","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Standard templates","fields":{"contentOrder":["7uonmjk41nipnrsi6tz8wau5ssh","afz66z155b7fhik9p6opysjneha"],"icon":"🗺️","isTemplate":false,"properties":{"20717ad3-5741-4416-83f1-6f133fff3d11":"6eea96c9-4c61-4968-8554-4b7537e8f748","50117d52-bcc7-4750-82aa-831a351c44a0":"ec6d2bc5-df2b-4f77-8479-e59ceb039946","60985f46-3e41-486e-8213-2b987440ea1c":"ed4a5340-460d-461b-8838-2c56e8ee59fe","ai7ajsdk14w7x5s8up3dwir77te":"https://mattermost.com/boards/","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e":"e6a7f297-4440-4783-8ab3-3af5ba62ca11"}},"createAt":1641589960934,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"chfrdo1nb3p8ofnbftyinr6949o","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Import / Export","fields":{"contentOrder":["aw66wjze7qfr1ukqs8gw53qa5qw"],"icon":"🚢","isTemplate":false,"properties":{"20717ad3-5741-4416-83f1-6f133fff3d11":"6eea96c9-4c61-4968-8554-4b7537e8f748","50117d52-bcc7-4750-82aa-831a351c44a0":"ec6d2bc5-df2b-4f77-8479-e59ceb039946","60985f46-3e41-486e-8213-2b987440ea1c":"c01676ca-babf-4534-8be5-cce2287daa6c","ai7ajsdk14w7x5s8up3dwir77te":"https://mattermost.com/boards/","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e":"e6a7f297-4440-4783-8ab3-3af5ba62ca11"}},"createAt":1640363550923,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cp1m1wrpfatdxikhwkf58oo5k3o","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Review API design","fields":{"contentOrder":["ahsamufik97nsfxjgx9cs6cmzme"],"icon":"🛣️","isTemplate":false,"properties":{"20717ad3-5741-4416-83f1-6f133fff3d11":"424ea5e3-9aa1-4075-8c5c-01b44b66e634","50117d52-bcc7-4750-82aa-831a351c44a0":"8c557f69-b0ed-46ec-83a3-8efab9d47ef5","60985f46-3e41-486e-8213-2b987440ea1c":"14892380-1a32-42dd-8034-a0cea32bc7e6","ai7ajsdk14w7x5s8up3dwir77te":"https://mattermost.com/boards/","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e":"c62172ea-5da7-4dec-8186-37267d8ee9a7"}},"createAt":1640363550754,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cqfy6g434pigk3p7j3gq55trq9o","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Icons don't display","fields":{"contentOrder":["axfkn6tuy4igubj3ka99tbymb8o","acbpep9wxdtyg8gg3fi6h1hgoro","7tedfdyq4p7g77dmkrebryh4jor"],"icon":"💻","isTemplate":false,"properties":{"20717ad3-5741-4416-83f1-6f133fff3d11":"1fdbb515-edd2-4af5-80fc-437ed2211a49","50117d52-bcc7-4750-82aa-831a351c44a0":"8c557f69-b0ed-46ec-83a3-8efab9d47ef5","60985f46-3e41-486e-8213-2b987440ea1c":"ed4a5340-460d-461b-8838-2c56e8ee59fe","ai7ajsdk14w7x5s8up3dwir77te":"https://mattermost.com/boards/","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e":"e6a7f297-4440-4783-8ab3-3af5ba62ca11"}},"createAt":1640363550868,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"v1uubwdzrw7fsxnd6pss1dyhh5e","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Calendar View","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"dateDisplayPropertyId":"a4378omyhmgj3bex13sj4wbpfiy","defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"calendar","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1640379248049,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"v7n4sc9cre7gsbq9yydsuekpg8a","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Board: Sprints","fields":{"cardOrder":["c3jawn6e4fbr3jctthy9xxkdsqe","c5trb4319wi8n3x4r4f7f83ytdc","c9p4bdasriifc7qgihzhjm63ugy","cqfy6g434pigk3p7j3gq55trq9o","chfrdo1nb3p8ofnbftyinr6949o","cp1m1wrpfatdxikhwkf58oo5k3o"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"cidz4imnqhir48brz6e8hxhfrhy","filter":{"filters":[],"operation":"and"},"groupById":"60985f46-3e41-486e-8213-2b987440ea1c","hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[{"propertyId":"f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e","reversed":false}],"viewType":"board","visibleOptionIds":["c01676ca-babf-4534-8be5-cce2287daa6c","ed4a5340-460d-461b-8838-2c56e8ee59fe","14892380-1a32-42dd-8034-a0cea32bc7e6",""],"visiblePropertyIds":["20717ad3-5741-4416-83f1-6f133fff3d11","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e"]},"createAt":1640363550811,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"v8sa3mo81d38rbmd8bz4n6dg7qc","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"List: Tasks 🔨","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"50117d52-bcc7-4750-82aa-831a351c44a0":139,"__title":280},"defaultTemplateId":"","filter":{"filters":[{"condition":"includes","propertyId":"20717ad3-5741-4416-83f1-6f133fff3d11","values":["6eea96c9-4c61-4968-8554-4b7537e8f748"]}],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[{"propertyId":"50117d52-bcc7-4750-82aa-831a351c44a0","reversed":true}],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["50117d52-bcc7-4750-82aa-831a351c44a0","20717ad3-5741-4416-83f1-6f133fff3d11","60985f46-3e41-486e-8213-2b987440ea1c","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e"]},"createAt":1640363550980,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vi43bqxsho3fmjbu1oa8qafwo4c","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Board: Status","fields":{"cardOrder":["c3jawn6e4fbr3jctthy9xxkdsqe","cm4w7cc3aac6s9jdcujbs4j8f4r","c6egh6cpnj137ixdoitsoxq17oo","cct9u78utsdyotmejbmwwg66ihr","cmft87it1q7yebbd51ij9k65xbw","c9fe77j9qcruxf4itzib7ag6f1c","coup7afjknqnzbdwghiwbsq541w","c5ex1hndz8qyc8gx6ofbfeksftc"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"cidz4imnqhir48brz6e8hxhfrhy","filter":{"filters":[],"operation":"and"},"groupById":"50117d52-bcc7-4750-82aa-831a351c44a0","hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[{"propertyId":"f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e","reversed":false}],"viewType":"board","visibleOptionIds":["8c557f69-b0ed-46ec-83a3-8efab9d47ef5","ec6d2bc5-df2b-4f77-8479-e59ceb039946","849766ba-56a5-48d1-886f-21672f415395",""],"visiblePropertyIds":["20717ad3-5741-4416-83f1-6f133fff3d11","60985f46-3e41-486e-8213-2b987440ea1c","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e"]},"createAt":1640363551099,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vod5de87tz7nxpji31oou4ine3c","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"List: Bugs 🐞","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"50117d52-bcc7-4750-82aa-831a351c44a0":145,"__title":280},"defaultTemplateId":"","filter":{"filters":[{"condition":"includes","propertyId":"20717ad3-5741-4416-83f1-6f133fff3d11","values":["1fdbb515-edd2-4af5-80fc-437ed2211a49"]}],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[{"propertyId":"f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e","reversed":false}],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["50117d52-bcc7-4750-82aa-831a351c44a0","20717ad3-5741-4416-83f1-6f133fff3d11","60985f46-3e41-486e-8213-2b987440ea1c","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e"]},"createAt":1640363550690,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vwcxq5337styqzefjsiqohdjjeh","parentId":"bui5izho7dtn77xg3thkiqprc9r","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"List: Epics ⛰","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"__title":280},"defaultTemplateId":"","filter":{"filters":[{"condition":"includes","propertyId":"20717ad3-5741-4416-83f1-6f133fff3d11","values":["424ea5e3-9aa1-4075-8c5c-01b44b66e634"]}],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[{"propertyId":"60985f46-3e41-486e-8213-2b987440ea1c","reversed":false}],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["50117d52-bcc7-4750-82aa-831a351c44a0","20717ad3-5741-4416-83f1-6f133fff3d11","60985f46-3e41-486e-8213-2b987440ea1c","f7f3ad42-b31a-4ac2-81f0-28ea80c5b34e"]},"createAt":1640363551039,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7o9ktgofg37yc7gma9s3jd9bd3a","parentId":"c3jawn6e4fbr3jctthy9xxkdsqe","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"77pe9r4ckbin438ph3f18bpatua.png"},"createAt":1641589687567,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a4d68ftemrbfsfykur6eh6nrogh","parentId":"c3jawn6e4fbr3jctthy9xxkdsqe","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Steps to reproduce the behavior\n1. Go to ...\n2. Select ...\n3. Scroll down to ...\n4. See error\n\n## Expected behavior\n*[A clear and concise description of what you expected to happen.]*\n\n## Edition and Platform\n- Edition: *[e.g. Personal Desktop / Personal Server / Mattermost plugin]*\n- Version: *[e.g. v0.9.0]*\n- Browser and OS: *[e.g. Chrome 91 on macOS, Edge 93 on Windows]*\n\n## Additional context\n*[Add any other context about the problem here.]*","fields":{},"createAt":1641589386414,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ae54fbyywubnbtr3s4yhgns4nye","parentId":"c3jawn6e4fbr3jctthy9xxkdsqe","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Screenshots\n*[If applicable, add screenshots to elaborate on the problem.]*","fields":{},"createAt":1641589472988,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ag9rxpgbwqid1mm5hgg8b9yhf6o","parentId":"c5trb4319wi8n3x4r4f7f83ytdc","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*\n\n## Requirements\n- *[Requirement 1]*\n- *[Requirement 2]*\n- ...","fields":{},"createAt":1641590081840,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"afz66z155b7fhik9p6opysjneha","parentId":"c9p4bdasriifc7qgihzhjm63ugy","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*\n\n## Requirements\n- *[Requirement 1]*\n- *[Requirement 2]*\n- ...","fields":{},"createAt":1641589969935,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"73dpuy7r9qpfymrp67c9n3krrsc","parentId":"cfefgwjke6bbxpjpig618g9bpte","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7pbp4qg415pbstc6enzeicnu3qh.png"},"createAt":1640379104209,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aabek71yr1trxmjudty7efncp3r","parentId":"cfefgwjke6bbxpjpig618g9bpte","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Screenshots\nIf applicable, add screenshots to elaborate on the problem.","fields":{},"createAt":1640379104369,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"asqzoizq31b81dpyzm1tnm8wyxc","parentId":"cfefgwjke6bbxpjpig618g9bpte","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Steps to reproduce the behavior\n\n1. Go to ...\n2. Select ...\n3. Scroll down to ...\n4. See error\n\n## Expected behavior\n\nA clear and concise description of what you expected to happen.\n\n## Edition and Platform\n\n - Edition: Personal Desktop / Personal Server / Mattermost plugin\n - Version: [e.g. v0.9.0]\n - Browser and OS: [e.g. Chrome 91 on macOS, Edge 93 on Windows]\n\n## Additional context\n\nAdd any other context about the problem here.","fields":{},"createAt":1640379104459,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"auefo9xa6sffatbeqzya56bhebo","parentId":"cfefgwjke6bbxpjpig618g9bpte","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Steps to reproduce the behavior\n\n1. Go to ...\n2. Select ...\n3. Scroll down to ...\n4. See error\n\n## Expected behavior\n\n*[A clear and concise description of what you expected to happen.]*\n\n## Screenshots\n\n*[If applicable, add screenshots to elaborate on the problem.]*\n\n## Edition and Platform\n\n - Edition: *[e.g. Personal Desktop / Personal Server / Mattermost plugin]*\n - Version: *[e.g. v0.9.0]*\n - Browser and OS: *[e.g. Chrome 91 on macOS, Edge 93 on Windows]*\n\n## Additional context\n\n*[Add any other context about the problem here.]*","fields":{},"createAt":1640379139361,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aw66wjze7qfr1ukqs8gw53qa5qw","parentId":"chfrdo1nb3p8ofnbftyinr6949o","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*\n\n## Requirements\n- *[Requirement 1]*\n- *[Requirement 2]*\n- ...","fields":{},"createAt":1640380216220,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"anppzrbx3i7b47n17b6jje6e1yc","parentId":"cidz4imnqhir48brz6e8hxhfrhy","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Description\n*[Brief description of this task]*\n\n## Requirements\n- *[Requirement 1]*\n- *[Requirement 2]*\n- ...","fields":{},"createAt":1640380239894,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"azyfnyszy6jb9iys9izfz1bhbdw","parentId":"cidz4imnqhir48brz6e8hxhfrhy","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Requirements\n- [Requirement 1]\n- [Requirement 2]\n- ...","fields":{},"createAt":1640380231316,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ahsamufik97nsfxjgx9cs6cmzme","parentId":"cp1m1wrpfatdxikhwkf58oo5k3o","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Summary\n*[Brief description of what this epic is about]*\n\n## Motivation\n*[Brief description on why this is needed]*\n\n## Acceptance Criteria\n - *[Criteron 1]*\n - *[Criteron 2]*\n - ...\n\n## Personas\n - *[Persona A]*\n - *[Persona B]*\n - ...\n\n## Reference Materials\n - *[Links to other relevant documents as needed]*\n - ...","fields":{},"createAt":1640380010492,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7tedfdyq4p7g77dmkrebryh4jor","parentId":"cqfy6g434pigk3p7j3gq55trq9o","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7pbp4qg415pbstc6enzeicnu3qh.png"},"createAt":1640379056342,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"acbpep9wxdtyg8gg3fi6h1hgoro","parentId":"cqfy6g434pigk3p7j3gq55trq9o","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Screenshots\n*[If applicable, add screenshots to elaborate on the problem.]*","fields":{},"createAt":1640378826029,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"axfkn6tuy4igubj3ka99tbymb8o","parentId":"cqfy6g434pigk3p7j3gq55trq9o","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Steps to reproduce the behavior\n1. Go to ...\n2. Select ...\n3. Scroll down to ...\n4. See error\n\n## Expected behavior\n*[A clear and concise description of what you expected to happen.]*\n\n## Edition and Platform\n- Edition: *[e.g. Personal Desktop / Personal Server / Mattermost plugin]*\n- Version: *[e.g. v0.9.0]*\n- Browser and OS: *[e.g. Chrome 91 on macOS, Edge 93 on Windows]*\n\n## Additional context\n*[Add any other context about the problem here.]*","fields":{},"createAt":1640378803642,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a58i6xsb3abdhm87oezaum6ehhc","parentId":"cwrq9ag3p5pgzzy98nfd3wwra1w","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Summary\n*[Brief description of what this epic is about]*\n## Motivation\n*[Brief description on why this is needed]*\n## Acceptance Criteria\n- *[Criteron 1]*\n- *[Criteron 2]*\n- ...\n## Personas\n- *[Persona A]*\n- *[Persona B]*\n- ...\n## Reference Materials\n- *[Links to other relevant documents as needed]*\n- ...","fields":{},"createAt":1640380125209,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a799597ibbjb17yxy1c3zjias1w","parentId":"cwrq9ag3p5pgzzy98nfd3wwra1w","rootId":"bui5izho7dtn77xg3thkiqprc9r","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"## Summary\n[Brief description of what this epic is about]\n\n## Motivation\n[Brief description on why this is needed]\n\n## Acceptance Criteria\n - [Criteron 1]\n - [Criteron 2]\n - ...\n\n## Personas\n - [Persona A]\n - [Persona B]\n - ...\n\n## Reference Materials\n - [Links to other relevant documents as needed]\n - ...","fields":{},"createAt":1640380118322,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 KiB

View File

@ -0,0 +1,47 @@
{"type":"block","data":{"id":"buixxjic3xjfkieees4iafdrznc","parentId":"","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"board","title":"Welcome to Boards!","fields":{"cardProperties":[{"id":"a972dc7a-5f4c-45d2-8044-8c28c69717f1","name":"Status","options":[{"color":"propColorRed","id":"amm6wfhnbuxojwssyftgs9dipqe","value":"To do 🔥"},{"color":"propColorYellow","id":"af3p8ztcyxgn8wd9z4az7o9tjeh","value":"Next up"},{"color":"propColorPurple","id":"ajurey3xkocs1nwx8di5zx6oe7o","value":"Later"},{"color":"propColorGreen","id":"agkinkjy5983wsk6kppsujajxqw","value":"Completed 🙌"}],"type":"select"},{"id":"acypkejeb5yfujhj9te57p9kaxw","name":"Priority","options":[{"color":"propColorOrange","id":"aanaehcw3m13jytujsjk5hpf6ry","value":"1. High"},{"color":"propColorBrown","id":"ascd7nm9r491ayot8i86g1gmgqw","value":"2. Medium"},{"color":"propColorGray","id":"aq6ukoiciyfctgwyhwzpfss8ghe","value":"3. Low"}],"type":"select"},{"id":"aqh13jabwexjkzr3jqsz1i1syew","name":"Assignee","options":[],"type":"person"},{"id":"acmg7mz1rr1eykfug4hcdpb1y1o","name":"Due Date","options":[],"type":"date"},{"id":"amewjwfjrtpu8ha73xsrdmxazxr","name":"Reviewed","options":[],"type":"checkbox"},{"id":"attzzboqaz6m1sdti5xa7gjnk1e","name":"Last updated time","options":[],"type":"updatedTime"},{"id":"a4nfnb5xr3txr5xq7y9ho7kyz6c","name":"Reference","options":[],"type":"url"},{"id":"a9gzwi3dt5n55nddej6zcbhxaeh","name":"Created by","options":[],"type":"createdBy"}],"columnCalculations":[],"description":"Mattermost Boards is an open source project management tool that helps you organize, track, and manage work across teams. Select a card to learn more.","icon":"👋","isTemplate":false,"showDescription":true},"createAt":1640034759040,"updateAt":1643788318628,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c5ay4q3t1hf8cdcschejip7ybpc","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Drag cards","fields":{"contentOrder":["apktbgtee5jb8xrnqy3ibiujxew","aefratgmk6j8nzj5fngfrf4k8hw"],"icon":"🤏","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/working-with-boards.html#dragging-cards","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ajurey3xkocs1nwx8di5zx6oe7o","acypkejeb5yfujhj9te57p9kaxw":"aq6ukoiciyfctgwyhwzpfss8ghe","aqh13jabwexjkzr3jqsz1i1syew":"Bob"}},"createAt":1640034759400,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"c9h4wpgh1ajyzfdqoyotohtj6oy","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Manage tasks with cards","fields":{"contentOrder":["a778mcixrm7byzb4mxrixjtrwwa","7mgy47rzyxpdm5c5eod9x5nypea","7tuw1my7b7fnxd8sfyzpz6dd1sc","784uu3ufcgb878ky7hyugmf6xcw","77msur4yswfn65d8qycdyfpfawe","7dh4oncxngj8jb8n59sefmsynac","7nkegq1zimifpmxcrq8ntyothoe","7nb8y7jyoetro8cd36qcju53z8c","7exhjmek1ctbexxt95w5cy1cuwo","7peuyuzgkc3fmzczfjuzseg9ksa","76nwb9tqfsid5jx46yw34itqima","7dy3mcgzgybf1ifa3emgewkzj7e","a5ca6tii33bfw8ba36y1rswq3he","7876od6xhffr6fy69zeogag7eyw","7x7bq9awkatbm5x4docbh5gaw4y","7ghpx9qff43dgtke1rwidmge1ho","7nb8y7jyoetro8cd36qcju53z8c","7hdyxemhbytfm3m83g88djq9nhr","7pgnejxokubbe9kdrxj6g9qa41e","7hw9z6qtx8jyizkmm9g5yq3gxcy","7gk6ooz6npbb8by5rgp9aig7tua","7ayruwskq4b8rte64fiwz493kjo"],"icon":"☑️","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/work-with-cards.html","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"amm6wfhnbuxojwssyftgs9dipqe","acypkejeb5yfujhj9te57p9kaxw":"aanaehcw3m13jytujsjk5hpf6ry"}},"createAt":1640034759460,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cfkikng8egbr878ryaztmpkno4w","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Create your own board","fields":{"contentOrder":["apedf7fbrspgt3cg8e5worq1gqa","as7511u6t1pdc7fe7zrbzdfg51y","7r9my1yuddbn45dojrfht3neg8c","7eir5gdjxgjbsxpbyp3df4npcze","7cux9rwr1b3rjmxakbipeoxky6h"],"icon":"📋","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/working-with-boards.html#adding-new-boards","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"amm6wfhnbuxojwssyftgs9dipqe","acypkejeb5yfujhj9te57p9kaxw":"aanaehcw3m13jytujsjk5hpf6ry"}},"createAt":1640034759557,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cm8yz355wbtfd7rtpgs655wbr4e","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Share a board","fields":{"contentOrder":["a5z5po5apabfibkgmkq53dxe9dw","ag791jfbc47gobroeo9ie1afcdo","7r7asyew8d7fyunf4sow8e5iyoc","ad8j3n8tp77bppee3ipjt6odgpe","7w935usqt6pby8qz9x5pxaj7iow","7ogbs8h6q4j8z7ngy1m7eag63nw","7z1jau5qy3jfcxdp5cgq3duk6ne","7hkn59merfbf38gzxf7sabewuma"],"icon":"📤","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/sharing-boards.html","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ajurey3xkocs1nwx8di5zx6oe7o","acypkejeb5yfujhj9te57p9kaxw":"aq6ukoiciyfctgwyhwzpfss8ghe","aqh13jabwexjkzr3jqsz1i1syew":"Gene"}},"createAt":1640034759139,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cmjtfip8a738nbr33shzmgk559o","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Create a new card","fields":{"contentOrder":["aykjshfjrxpd9zngqruenqn5s7h","adhsx4h5ss7rqdcjt8xyam6xtqc","auow16g4f4tf4z89qrxbg3btxba","7me9p46gbqiyfmfnapi7dyxb5br","76bqrrm8dobr37kttya6jhznjih"],"icon":"📝","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/working-with-boards.html#adding-cards","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"amm6wfhnbuxojwssyftgs9dipqe","acypkejeb5yfujhj9te57p9kaxw":"aanaehcw3m13jytujsjk5hpf6ry","aqh13jabwexjkzr3jqsz1i1syew":"Linda"}},"createAt":1640034759755,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cq1gmiwhx4jgd7q9ad9c1icasqr","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Share cards on Channels","fields":{"contentOrder":["arpj7spx9op8jumm6yfdsxwpeuw","a4z7htb6catgaue5npinux4tmrc","a3qa1n69wc7d1u8krumz9ogcidy","7y5hxcb9zzprzzrqeu675rtnpae"],"icon":"📮","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/work-with-cards.html#share-card-previews","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"af3p8ztcyxgn8wd9z4az7o9tjeh","acypkejeb5yfujhj9te57p9kaxw":"ascd7nm9r491ayot8i86g1gmgqw"}},"createAt":1641487149480,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cse6a9d81tfyd7e34cbmfttbgte","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Filter and sort cards","fields":{"contentOrder":["a4fz9kcfs9ibj8puk9mux7ac94c","ad9fecctco7ggjjeo9usfpwkfpa","78i8aqjmqtibr7x4okhz6uqquqr","7oz9pp3bkopgfpycph3oqgze8uw"],"icon":"🎛️","isTemplate":false,"properties":{"a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ajurey3xkocs1nwx8di5zx6oe7o","acypkejeb5yfujhj9te57p9kaxw":"aq6ukoiciyfctgwyhwzpfss8ghe","aqh13jabwexjkzr3jqsz1i1syew":"Linda"}},"createAt":1640034759298,"updateAt":1643788318631,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cstm8jadnmbds9kooz4tr8sy5wr","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Create a new view","fields":{"contentOrder":["aozbezukpgif3jpbsq7tahmmp5e","a538fji6kcp89fyhmgaoko7wk6c","7owai1ux3h3gtf8byynfk6hyx1c","7n8jq1dizyfgotby3o91arf1hxh","77y4wffj1ctg7xmm9bx45qn6q6o","7te5jcsrym3by7yxq4um8usj7ao"],"icon":"👓","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/working-with-boards.html#adding-new-views","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"af3p8ztcyxgn8wd9z4az7o9tjeh","acypkejeb5yfujhj9te57p9kaxw":"ascd7nm9r491ayot8i86g1gmgqw","aqh13jabwexjkzr3jqsz1i1syew":"Louise"}},"createAt":1640034759508,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cut8jasi4etbd7mpqpn36fna9ba","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"Add new properties","fields":{"contentOrder":["afb3pntrwgtrwidfeo1f1dsonqy","ayhk11qsuz789fk8bqae4oz8mro","7gc3z8cf8rirgfyutwoke9nn6jy","76cinqnb6k3dzmfbm9fnc8eofny","79yggmhcyhbgdiej5w4re3k4ssy"],"icon":"🏷️","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/work-with-cards.html#add-and-manage-properties","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"af3p8ztcyxgn8wd9z4az7o9tjeh","acypkejeb5yfujhj9te57p9kaxw":"ascd7nm9r491ayot8i86g1gmgqw","aqh13jabwexjkzr3jqsz1i1syew":"Linda"}},"createAt":1640034759239,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"cwf9xw6d6zbgfbbgd6atr336uco","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"card","title":"@mention teammates","fields":{"contentOrder":["akbz4abecginpjgz1etweynd7io","ab6ygnyg757bc9cpm9bkp8aam8e","7mbw9t71hjbrydgzgkqqaoh8usr","78mzk7qpof7ybxpfjn9j9an9gkh"],"icon":"🔔","isTemplate":false,"properties":{"a4nfnb5xr3txr5xq7y9ho7kyz6c":"https://docs.mattermost.com/boards/work-with-cards.html#mention-people","a972dc7a-5f4c-45d2-8044-8c28c69717f1":"ajurey3xkocs1nwx8di5zx6oe7o","acypkejeb5yfujhj9te57p9kaxw":"aq6ukoiciyfctgwyhwzpfss8ghe","aqh13jabwexjkzr3jqsz1i1syew":"Bob"}},"createAt":1640034759348,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vkm63rwrg5p8q5mrrk6ghzk3q1r","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Preview: Table View","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{"__title":280,"a972dc7a-5f4c-45d2-8044-8c28c69717f1":100,"acypkejeb5yfujhj9te57p9kaxw":169},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"table","visibleOptionIds":[],"visiblePropertyIds":["a972dc7a-5f4c-45d2-8044-8c28c69717f1","aqh13jabwexjkzr3jqsz1i1syew","acmg7mz1rr1eykfug4hcdpb1y1o","acypkejeb5yfujhj9te57p9kaxw"]},"createAt":1640034759909,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vmu9ebyngpjb1mkc887m3pfocfa","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Preview: Calendar View","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"dateDisplayPropertyId":"acmg7mz1rr1eykfug4hcdpb1y1o","defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"calendar","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1641796830370,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vssisypn6sfbctxy8si7oj3y9io","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Preview: Gallery View","fields":{"cardOrder":[],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"hiddenOptionIds":[],"kanbanCalculations":{},"sortOptions":[],"viewType":"gallery","visibleOptionIds":[],"visiblePropertyIds":["__title"]},"createAt":1641791749185,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"vzou1dc41ntn73mkyymka9yrese","parentId":"buixxjic3xjfkieees4iafdrznc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"view","title":"Onboarding","fields":{"cardOrder":["cmjtfip8a738nbr33shzmgk559o","c9h4wpgh1ajyzfdqoyotohtj6oy","cfkikng8egbr878ryaztmpkno4w","cq1gmiwhx4jgd7q9ad9c1icasqr","cut8jasi4etbd7mpqpn36fna9ba","cstm8jadnmbds9kooz4tr8sy5wr","cwf9xw6d6zbgfbbgd6atr336uco","c5ay4q3t1hf8cdcschejip7ybpc","cm8yz355wbtfd7rtpgs655wbr4e","cse6a9d81tfyd7e34cbmfttbgte"],"collapsedOptionIds":[],"columnCalculations":{},"columnWidths":{},"defaultTemplateId":"","filter":{"filters":[],"operation":"and"},"groupById":"a972dc7a-5f4c-45d2-8044-8c28c69717f1","hiddenOptionIds":[""],"kanbanCalculations":{},"sortOptions":[],"viewType":"board","visibleOptionIds":["aqb5x3pt87dcc9stbk4ofodrpoy","a1mtm777bkagq3iuu7xo9b13qfr","auxbwzptiqzkii5r61uz3ndsy1r","aj9386k1bx8qwmepeuxg3b7z4pw"],"visiblePropertyIds":[]},"createAt":1640034759964,"updateAt":1643788318632,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aefratgmk6j8nzj5fngfrf4k8hw","parentId":"c5ay4q3t1hf8cdcschejip7ybpc","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Mattermost Boards makes it easy for you to update certain properties on cards through our drag and drop functionality. Simply drag this card from the **Later** column to the **Completed** column to automatically update the status and mark this task as complete.","fields":{},"createAt":1640035135582,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"77msur4yswfn65d8qycdyfpfawe","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Assign tasks to teammates","fields":{"value":false},"createAt":1641787609114,"updateAt":1643788318633,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7ayruwskq4b8rte64fiwz493kjo","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Create and manage checklists, like this one... :)","fields":{"value":false},"createAt":1641788123369,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7dh4oncxngj8jb8n59sefmsynac","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Add and update descriptions with Markdown","fields":{"value":false},"createAt":1641793564533,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7exhjmek1ctbexxt95w5cy1cuwo","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Follow cards to get notified on the latest updates","fields":{"value":false},"createAt":1641787466530,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7mgy47rzyxpdm5c5eod9x5nypea","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Set priorities and update statuses","fields":{"value":false},"createAt":1641787424191,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7nkegq1zimifpmxcrq8ntyothoe","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Provide feedback and ask questions via comments","fields":{"value":false},"createAt":1642012664514,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7peuyuzgkc3fmzczfjuzseg9ksa","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"@mention teammates so they can follow, and collaborate on, comments and descriptions","fields":{"value":false},"createAt":1641787459538,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7tuw1my7b7fnxd8sfyzpz6dd1sc","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"checkbox","title":"Manage deadlines and milestones","fields":{"value":false},"createAt":1641787583043,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a778mcixrm7byzb4mxrixjtrwwa","parentId":"c9h4wpgh1ajyzfdqoyotohtj6oy","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Cards allow your entire team to manage and collaborate on a task in one place. Within a card, your team can:","fields":{},"createAt":1641786489535,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7cux9rwr1b3rjmxakbipeoxky6h","parentId":"cfkikng8egbr878ryaztmpkno4w","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"74uia99m9btr8peydw7oexn37tw.gif"},"createAt":1643638662994,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"apedf7fbrspgt3cg8e5worq1gqa","parentId":"cfkikng8egbr878ryaztmpkno4w","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"A board helps you manage your project, organize tasks, and collaborate with your team all in one place.","fields":{},"createAt":1641797295263,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"as7511u6t1pdc7fe7zrbzdfg51y","parentId":"cfkikng8egbr878ryaztmpkno4w","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"To create your own board, select the \"+\" on the top of the left hand sidebar. Choose from one of our standard templates and see how they can help you get started with your next project:\n\n- **Project Tasks**: Stay on top of your project tasks, track progress, and set priorities. \n- **Meeting Agenda**: Set your meeting agendas for recurring team meetings and 1:1s.\n- **Roadmap**: Plan your roadmap and manage your releases more efficiently.\n- **Personal Tasks**: Organize your life and track your personal tasks.\n- **Content Calendar**: Plan your editorial content, assign work, and track deadlines.\n- **Personal Goals**: Set and accomplish new personal goals and milestones.","fields":{},"createAt":1641788827589,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7hkn59merfbf38gzxf7sabewuma","parentId":"cm8yz355wbtfd7rtpgs655wbr4e","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7knxbyuiedtdafcgmropgkrtybr.gif"},"createAt":1643638846658,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a5z5po5apabfibkgmkq53dxe9dw","parentId":"cm8yz355wbtfd7rtpgs655wbr4e","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Keep stakeholders and customers up-to-date on project progress by sharing your board.","fields":{},"createAt":1642198459390,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ag791jfbc47gobroeo9ie1afcdo","parentId":"cm8yz355wbtfd7rtpgs655wbr4e","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"To share a board, select **Share** at the top right of the Board view. Copy the link to share the board internally with your team or generate public link that can be accessed by anyone externally.","fields":{},"createAt":1642199464341,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"76bqrrm8dobr37kttya6jhznjih","parentId":"cmjtfip8a738nbr33shzmgk559o","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7iw4rxx7jj7bypmdotd9z469cyh.png"},"createAt":1643143198631,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"auow16g4f4tf4z89qrxbg3btxba","parentId":"cmjtfip8a738nbr33shzmgk559o","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"To create a new card, simply do any of the following:\n- Select \"**New**\" on the top right header\n- Select \"**+ New**\" below any column\n- Select \"**+**\" to the right of any columnn header","fields":{},"createAt":1640034820888,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"aykjshfjrxpd9zngqruenqn5s7h","parentId":"cmjtfip8a738nbr33shzmgk559o","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Mattermost Boards helps you manage and track all your project tasks with **Cards**.","fields":{},"createAt":1641504858080,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7y5hxcb9zzprzzrqeu675rtnpae","parentId":"cq1gmiwhx4jgd7q9ad9c1icasqr","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7ek6wbpp19jfoujs1goh6kttbby.gif"},"createAt":1643638818402,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a3qa1n69wc7d1u8krumz9ogcidy","parentId":"cq1gmiwhx4jgd7q9ad9c1icasqr","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"After you've copied the link, paste it into any channel or Direct Message to share the card. A preview of the card will display within the channel with a link back to the card on Boards.","fields":{},"createAt":1642195798726,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a4z7htb6catgaue5npinux4tmrc","parentId":"cq1gmiwhx4jgd7q9ad9c1icasqr","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"To share a card, you'll need to copy the card link first. You can:\n\n- Open a card and select the options menu button at the top right of the card.\n- Open the board view and hover your mouse over any card to access the options menu button.","fields":{},"createAt":1642193170054,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"arpj7spx9op8jumm6yfdsxwpeuw","parentId":"cq1gmiwhx4jgd7q9ad9c1icasqr","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Cards can be linked and shared with teammates directly on Channels. Card previews are displayed when shared on Channels, so your team can discuss work items and get the relevant context without having to switch over to Boards.","fields":{},"createAt":1642193162587,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7oz9pp3bkopgfpycph3oqgze8uw","parentId":"cse6a9d81tfyd7e34cbmfttbgte","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7dybb6t8fj3nrdft7nerhuf784y.png"},"createAt":1643142381491,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ad9fecctco7ggjjeo9usfpwkfpa","parentId":"cse6a9d81tfyd7e34cbmfttbgte","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Organize and find the cards you're looking for with our filter, sort, and grouping options. From the Board header, you can quickly toggle on different properties, change the group display, set filters, and change how the cards are sorted.","fields":{},"createAt":1640034870185,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"7te5jcsrym3by7yxq4um8usj7ao","parentId":"cstm8jadnmbds9kooz4tr8sy5wr","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"78jws5m1myf8pufewzkaa6i11sc.gif"},"createAt":1643638721400,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"a538fji6kcp89fyhmgaoko7wk6c","parentId":"cstm8jadnmbds9kooz4tr8sy5wr","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Views allow your team to visualize the same cards and data from different perspectives, so they can stay up-to-date in the way that works best for them. To add a new view, go to **Add a new view** from the view drop-down, then select from any of the following views:\n\n- **Board**: Adds a Kanban board, similar to this one, that allows your team to organize cards in swimlanes grouped by any property of your choosing. This view helps you visualize your project progress.\n- **Table**: Displays cards in a table format with rows and columns. Use this view to get an overview of all your project tasks. Easily view and compare the state of all properties across all cards without needing to open individual cards.\n- **Gallery**: Displays cards in a gallery format, so you can manage and organize cards with image attachments.\n- **Calendar**: Adds a calendar view to easily visualize your cards by dates and keep track of deadlines.","fields":{},"createAt":1640035911505,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"79yggmhcyhbgdiej5w4re3k4ssy","parentId":"cut8jasi4etbd7mpqpn36fna9ba","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"7d6hrtig3zt8f9cnbo1um5oxx3y.gif"},"createAt":1643638613909,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"afb3pntrwgtrwidfeo1f1dsonqy","parentId":"cut8jasi4etbd7mpqpn36fna9ba","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Customize cards to fit your needs and track the information most important to you. Boards supports a wide range of fully customizable property types. For example, you can:\n- Use the **Date** property for things like deadlines or milestones.\n- Assign owners to tasks with the **Person** property.\n- Define statuses and priorities with the **Select** property.\n- Create tags with the **Multi Select** property.\n- Link cards to webpages with the **URL** property.","fields":{},"createAt":1641611832288,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"78mzk7qpof7ybxpfjn9j9an9gkh","parentId":"cwf9xw6d6zbgfbbgd6atr336uco","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"image","title":"","fields":{"fileId":"74nt9eqzea3ydjjpgjtsxcjgrxc.gif"},"createAt":1643638766210,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"ab6ygnyg757bc9cpm9bkp8aam8e","parentId":"cwf9xw6d6zbgfbbgd6atr336uco","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"To mention a teammate use the **@ symbol with their username** in the comments or description section. They'll get a Direct Message notification via Channels and also be added as a [follower](https://docs.mattermost.com/boards/work-with-cards.html#receive-updates) to the card. \n\nWhenever any changes are made to the card, they'll automatically get notified on Channels.","fields":{},"createAt":1642177456022,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}
{"type":"block","data":{"id":"akbz4abecginpjgz1etweynd7io","parentId":"cwf9xw6d6zbgfbbgd6atr336uco","rootId":"buixxjic3xjfkieees4iafdrznc","createdBy":"edrkkih4cinzf8ueeszh6rmfoo","modifiedBy":"edrkkih4cinzf8ueeszh6rmfoo","schema":1,"type":"text","title":"Collaborate with teammates directly on each card using @mentions and have all the relevant context in one place.","fields":{},"createAt":1642177002644,"updateAt":1643788318634,"deleteAt":0,"workspaceId":"855b3j34ojn5p8f36yhu8336fe"}}

View File

@ -0,0 +1 @@
{"version":2,"date":1643788318636}

View File

@ -42,7 +42,7 @@ func setupTestHelper(t *testing.T) *TestHelper {
newAuth := New(&cfg, mockStore, localpermissions.New(mockPermissions, logger))
// called during default template setup for every test
mockStore.EXPECT().GetTemplateBoards(gomock.Any()).AnyTimes()
mockStore.EXPECT().GetTemplateBoards("0", "").AnyTimes()
mockStore.EXPECT().RemoveDefaultTemplates(gomock.Any()).AnyTimes()
mockStore.EXPECT().InsertBlock(gomock.Any(), gomock.Any()).AnyTimes()

View File

@ -164,10 +164,6 @@ func (c *Client) GetBlockRoute(boardID, blockID string) string {
return fmt.Sprintf("%s/%s", c.GetBlocksRoute(boardID), blockID)
}
func (c *Client) GetSubtreeRoute(boardID, blockID string) string {
return fmt.Sprintf("%s/subtree", c.GetBlockRoute(boardID, blockID))
}
func (c *Client) GetBoardsRoute() string {
return "/boards"
}
@ -297,16 +293,6 @@ func (c *Client) DeleteBlock(boardID, blockID string) (bool, *Response) {
return true, BuildResponse(r)
}
func (c *Client) GetSubtree(boardID, blockID string) ([]model.Block, *Response) {
r, err := c.DoAPIGet(c.GetSubtreeRoute(boardID, blockID), "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
defer closeBody(r)
return model.BlocksFromJSON(r.Body), BuildResponse(r)
}
// Boards and blocks.
func (c *Client) CreateBoardsAndBlocks(bab *model.BoardsAndBlocks) (*model.BoardsAndBlocks, *Response) {
r, err := c.DoAPIPost(c.GetBoardsAndBlocksRoute(), toJSON(bab))

View File

@ -429,18 +429,4 @@ func TestGetSubtree(t *testing.T) {
}
require.Contains(t, blockIDs, parentBlockID)
})
t.Run("Get subtree for parent ID", func(t *testing.T) {
blocks, resp := th.Client.GetSubtree(board.ID, parentBlockID)
require.NoError(t, resp.Error)
require.Len(t, blocks, 3)
blockIDs := make([]string, len(blocks))
for i, b := range blocks {
blockIDs[i] = b.ID
}
require.Contains(t, blockIDs, parentBlockID)
require.Contains(t, blockIDs, childBlockID1)
require.Contains(t, blockIDs, childBlockID2)
})
}

View File

@ -112,6 +112,12 @@ type BlockPatchBatch struct {
// Return true to import the block or false to skip import.
type BoardModifier func(board *Board, cache map[string]interface{}) bool
// BlockModifier is a callback that can modify each block during an import.
// A cache of arbitrary data will be passed for each call and any changes
// to the cache will be preserved for the next call.
// Return true to import the block or false to skip import.
type BlockModifier func(block *Block, cache map[string]interface{}) bool
func BlocksFromJSON(data io.Reader) []Block {
var blocks []Block
_ = json.NewDecoder(data).Decode(&blocks)

View File

@ -45,6 +45,7 @@ type ImportArchiveOptions struct {
TeamID string
ModifiedBy string
BoardModifier BoardModifier
BlockModifier BlockModifier
}
// ErrUnsupportedArchiveVersion is an error returned when trying to import an

View File

@ -55,6 +55,10 @@ type User struct {
// If the user is a bot or not
// required: true
IsBot bool `json:"is_bot"`
// If the user is a guest or not
// required: true
IsGuest bool `json:"is_guest"`
}
// UserPropPatch is a user property patch

View File

@ -205,7 +205,7 @@ func (b *Backend) OnMention(userID string, evt notify.BlockChangeEvent) {
}
// BroadcastSubscriptionChange sends a websocket message with details of the changed subscription to all
// connected users in the workspace.
func (b *Backend) BroadcastSubscriptionChange(workspaceID string, subscription *model.Subscription) {
b.wsAdapter.BroadcastSubscriptionChange(workspaceID, subscription)
// connected users in the team.
func (b *Backend) BroadcastSubscriptionChange(teamID string, subscription *model.Subscription) {
b.wsAdapter.BroadcastSubscriptionChange(teamID, subscription)
}

View File

@ -31,7 +31,7 @@ type BlockChangeEvent struct {
}
type SubscriptionChangeNotifier interface {
BroadcastSubscriptionChange(subscription *model.Subscription)
BroadcastSubscriptionChange(teamID string, subscription *model.Subscription)
}
// Backend provides an interface for sending notifications.
@ -113,7 +113,7 @@ func (s *Service) BlockChanged(evt BlockChangeEvent) {
// BroadcastSubscriptionChange sends a websocket message with details of the changed subscription to all
// connected users in the workspace.
func (s *Service) BroadcastSubscriptionChange(subscription *model.Subscription) {
func (s *Service) BroadcastSubscriptionChange(teamID string, subscription *model.Subscription) {
s.mux.RLock()
backends := make([]Backend, len(s.backends))
copy(backends, s.backends)
@ -125,7 +125,7 @@ func (s *Service) BroadcastSubscriptionChange(subscription *model.Subscription)
mlog.String("block_id", subscription.BlockID),
mlog.String("subscriber_id", subscription.SubscriberID),
)
scn.BroadcastSubscriptionChange(subscription)
scn.BroadcastSubscriptionChange(teamID, subscription)
}
}
}

View File

@ -4,6 +4,7 @@ import (
"database/sql"
"encoding/json"
mmModel "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/plugin"
sq "github.com/Masterminds/squirrel"
@ -12,7 +13,6 @@ import (
"github.com/mattermost/focalboard/server/services/store"
"github.com/mattermost/focalboard/server/utils"
mmModel "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
@ -55,7 +55,8 @@ func (s *MattermostAuthLayer) GetRegisteredUserCount() (int, error) {
query := s.getQueryBuilder().
Select("count(*)").
From("Users").
Where(sq.Eq{"deleteAt": 0})
Where(sq.Eq{"deleteAt": 0}).
Where(sq.NotEq{"roles": "system_guest"})
row := query.QueryRow()
var count int
@ -67,67 +68,31 @@ func (s *MattermostAuthLayer) GetRegisteredUserCount() (int, error) {
return count, nil
}
func (s *MattermostAuthLayer) getUserByCondition(condition sq.Eq) (*model.User, error) {
users, err := s.getUsersByCondition(condition)
if err != nil {
return nil, err
}
var user *model.User
for _, u := range users {
user = u
break
}
return user, nil
}
func (s *MattermostAuthLayer) getUsersByCondition(condition sq.Eq) (map[string]*model.User, error) {
query := s.getQueryBuilder().
Select("u.id", "u.username", "u.email", "u.password", "u.MFASecret as mfa_secret", "u.AuthService as auth_service", "COALESCE(u.AuthData, '') as auth_data",
"u.props", "u.CreateAt as create_at", "u.UpdateAt as update_at", "u.DeleteAt as delete_at", "b.UserId IS NOT NULL AS is_bot").
From("Users as u").
LeftJoin("Bots b ON ( b.UserId = u.ID )").
Where(sq.Eq{"u.deleteAt": 0}).
Where(condition)
row, err := query.Query()
if err != nil {
return nil, err
}
users := map[string]*model.User{}
for row.Next() {
user := model.User{}
var propsBytes []byte
err := row.Scan(&user.ID, &user.Username, &user.Email, &user.Password, &user.MfaSecret, &user.AuthService,
&user.AuthData, &propsBytes, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.IsBot)
if err != nil {
return nil, err
}
err = json.Unmarshal(propsBytes, &user.Props)
if err != nil {
return nil, err
}
users[user.ID] = &user
}
return users, nil
}
func (s *MattermostAuthLayer) GetUserByID(userID string) (*model.User, error) {
return s.getUserByCondition(sq.Eq{"id": userID})
mmuser, err := s.pluginAPI.GetUser(userID)
if err != nil {
return nil, err
}
user := mmUserToFbUser(mmuser)
return &user, nil
}
func (s *MattermostAuthLayer) GetUserByEmail(email string) (*model.User, error) {
return s.getUserByCondition(sq.Eq{"email": email})
mmuser, err := s.pluginAPI.GetUserByEmail(email)
if err != nil {
return nil, err
}
user := mmUserToFbUser(mmuser)
return &user, nil
}
func (s *MattermostAuthLayer) GetUserByUsername(username string) (*model.User, error) {
return s.getUserByCondition(sq.Eq{"username": username})
mmuser, err := s.pluginAPI.GetUserByUsername(username)
if err != nil {
return nil, err
}
user := mmUserToFbUser(mmuser)
return &user, nil
}
func (s *MattermostAuthLayer) CreateUser(user *model.User) error {
@ -234,7 +199,10 @@ func (s *MattermostAuthLayer) GetTeam(id string) (*model.Team, error) {
var displayName string
err := row.Scan(&displayName)
if err != nil {
s.logger.Error("GetTeam scan error", mlog.Err(err))
s.logger.Error("GetTeam scan error",
mlog.String("team_id", id),
mlog.Err(err),
)
return nil, err
}
@ -290,6 +258,7 @@ func (s *MattermostAuthLayer) GetUsersByTeam(teamID string) ([]*model.User, erro
Join("TeamMembers as tm ON tm.UserID = u.ID").
LeftJoin("Bots b ON ( b.UserId = Users.ID )").
Where(sq.Eq{"u.deleteAt": 0}).
Where(sq.NotEq{"u.roles": "system_guest"}).
Where(sq.Eq{"tm.TeamId": teamID})
rows, err := query.Query()
@ -321,6 +290,7 @@ func (s *MattermostAuthLayer) SearchUsersByTeam(teamID string, searchQuery strin
sq.Like{"u.lastname": "%" + searchQuery + "%"},
}).
Where(sq.Eq{"tm.TeamId": teamID}).
Where(sq.NotEq{"u.roles": "system_guest"}).
OrderBy("u.username").
Limit(10)
@ -387,6 +357,32 @@ func (s *MattermostAuthLayer) CreatePrivateWorkspace(userID string) (string, err
return channel.Id, nil
}
func mmUserToFbUser(mmUser *mmModel.User) model.User {
props := map[string]interface{}{}
for key, value := range mmUser.Props {
props[key] = value
}
authData := ""
if mmUser.AuthData != nil {
authData = *mmUser.AuthData
}
return model.User{
ID: mmUser.Id,
Username: mmUser.Username,
Email: mmUser.Email,
Password: mmUser.Password,
MfaSecret: mmUser.MfaSecret,
AuthService: mmUser.AuthService,
AuthData: authData,
Props: props,
CreateAt: mmUser.CreateAt,
UpdateAt: mmUser.UpdateAt,
DeleteAt: mmUser.DeleteAt,
IsBot: mmUser.IsBot,
IsGuest: mmUser.IsGuest(),
}
}
func (s *MattermostAuthLayer) GetLicense() *mmModel.License {
return s.pluginAPI.GetLicense()
}

View File

@ -881,18 +881,18 @@ func (mr *MockStoreMockRecorder) GetTeamsForUser(arg0 interface{}) *gomock.Call
}
// GetTemplateBoards mocks base method.
func (m *MockStore) GetTemplateBoards(arg0 string) ([]*model.Board, error) {
func (m *MockStore) GetTemplateBoards(arg0, arg1 string) ([]*model.Board, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTemplateBoards", arg0)
ret := m.ctrl.Call(m, "GetTemplateBoards", arg0, arg1)
ret0, _ := ret[0].([]*model.Board)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTemplateBoards indicates an expected call of GetTemplateBoards.
func (mr *MockStoreMockRecorder) GetTemplateBoards(arg0 interface{}) *gomock.Call {
func (mr *MockStoreMockRecorder) GetTemplateBoards(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateBoards", reflect.TypeOf((*MockStore)(nil).GetTemplateBoards), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateBoards", reflect.TypeOf((*MockStore)(nil).GetTemplateBoards), arg0, arg1)
}
// GetUserByEmail mocks base method.

View File

@ -435,8 +435,8 @@ func (s *SQLStore) GetTeamsForUser(userID string) ([]*model.Team, error) {
}
func (s *SQLStore) GetTemplateBoards(teamID string) ([]*model.Board, error) {
return s.getTemplateBoards(s.db, teamID)
func (s *SQLStore) GetTemplateBoards(teamID string, userID string) ([]*model.Board, error) {
return s.getTemplateBoards(s.db, teamID, userID)
}

View File

@ -54,13 +54,24 @@ func (s *SQLStore) removeDefaultTemplates(db sq.BaseRunner, boards []*model.Boar
return nil
}
// getDefaultTemplateBoards fetches all template blocks .
func (s *SQLStore) getTemplateBoards(db sq.BaseRunner, teamID string) ([]*model.Board, error) {
// getTemplateBoards fetches all template boards .
func (s *SQLStore) getTemplateBoards(db sq.BaseRunner, teamID, userID string) ([]*model.Board, error) {
query := s.getQueryBuilder(db).
Select(boardFields("")...).
From(s.tablePrefix + "boards").
Where(sq.Eq{"coalesce(team_id, '0')": teamID}).
Where(sq.Eq{"is_template": true})
From(s.tablePrefix+"boards as b").
LeftJoin(s.tablePrefix+"board_members as bm on b.id = bm.board_id and bm.user_id = ?", userID).
Where(sq.Eq{"is_template": true}).
Where(sq.Eq{"b.team_id": teamID}).
Where(sq.Or{
// this is to include public templates even if there is not board_member entry
sq.And{
sq.Eq{"bm.board_id": nil},
sq.Eq{"b.type": model.BoardTypeOpen},
},
sq.And{
sq.NotEq{"bm.board_id": nil},
},
})
rows, err := query.Query()
if err != nil {
@ -69,5 +80,10 @@ func (s *SQLStore) getTemplateBoards(db sq.BaseRunner, teamID string) ([]*model.
}
defer s.CloseRows(rows)
return s.boardsFromRows(rows)
userTemplates, err := s.boardsFromRows(rows)
if err != nil {
return nil, err
}
return userTemplates, nil
}

View File

@ -129,7 +129,7 @@ type Store interface {
GetNextNotificationHint(remove bool) (*model.NotificationHint, error)
RemoveDefaultTemplates(boards []*model.Board) error
GetTemplateBoards(teamID string) ([]*model.Board, error)
GetTemplateBoards(teamID, userID string) ([]*model.Board, error)
DBType() string

View File

@ -8,10 +8,8 @@ describe('Login actions', () => {
it('Can perform login/register actions', () => {
// Redirects to login page
cy.log('**Redirects to error then login page**')
cy.log('**Redirects to login page (except plugin mode) **')
cy.visit('/')
cy.location('pathname').should('eq', '/error')
cy.get('button').contains('Log in').click()
cy.location('pathname').should('eq', '/login')
cy.get('.LoginPage').contains('Log in')
cy.get('#login-username').should('exist')
@ -40,7 +38,7 @@ describe('Login actions', () => {
// User should not be logged in automatically
cy.log('**User should not be logged in automatically**')
cy.visit('/')
cy.location('pathname').should('eq', '/error')
cy.location('pathname').should('eq', '/login')
// Can log in registered user
cy.log('**Can log in registered user**')

View File

@ -24,7 +24,6 @@
"ContentBlock.DeleteAction": "حذف",
"ContentBlock.addElement": "إضافة {type}",
"ContentBlock.text": "نص",
"DashboardPage.title": "أهلًا بك إلى Focalboard (تجريبي)!",
"EditableDayPicker.today": "اليوم",
"Filter.is-empty": "فارغ",
"Filter.is-not-empty": "ليس فارغًا",

View File

@ -45,9 +45,7 @@
"KanbanCard.delete": "Eliminar",
"KanbanCard.duplicate": "Duplicar",
"KanbanCard.untitled": "Sense títol",
"Mutator.duplicate-board": "duplicar tauler",
"Mutator.new-card-from-template": "nova targeta des de plantilla",
"Mutator.new-template-from-board": "nova plantilla des de tauler",
"Mutator.new-template-from-card": "nova plantilla des de targeta",
"PropertyMenu.Delete": "Eliminar",
"PropertyMenu.changeType": "Canviar el tipus de propietat",
@ -81,19 +79,15 @@
"Sidebar.add-board": "+ Afegir tauler",
"Sidebar.changePassword": "Canvi de contrasenya",
"Sidebar.delete-board": "Eliminar el tauler",
"Sidebar.duplicate-board": "Duplicar el tauler",
"Sidebar.export-archive": "Arxiu d'exportació",
"Sidebar.import-archive": "Arxiu d'importació",
"Sidebar.invite-users": "Convida usuaris",
"Sidebar.logout": "Tanca sessió",
"Sidebar.no-views-in-board": "Cap pàgina a l'interior",
"Sidebar.random-icons": "Icones aleatòries",
"Sidebar.set-language": "Seleccionar idioma",
"Sidebar.set-theme": "Definir un tema",
"Sidebar.settings": "Paràmetres",
"Sidebar.template-from-board": "Nova plantilla desde tauler",
"Sidebar.untitled-board": "(Tauler sense títol)",
"Sidebar.untitled-view": "(Vista sense títol)",
"TableComponent.add-icon": "Afegeix icona",
"TableComponent.name": "Nom",
"TableComponent.plus-new": "+ Nou",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "Keine {property}",
"BoardComponent.no-property-title": "Elemente mit einer leeren {property} Eigenschaft erscheinen hier. Diese Spalte kann nicht entfernt werden.",
"BoardComponent.show": "Anzeigen",
"BoardMember.schemeAdmin": "Administrator",
"BoardMember.schemeEditor": "Bearbeiter",
"BoardMember.schemeNone": "Keine",
"BoardPage.newVersion": "Eine neue Version von Boards ist verfügbar, klicke hier, um neu zu laden.",
"BoardPage.syncFailed": "Das Board kann gelöscht oder der Zugang entzogen werden.",
"BoardTemplateSelector.add-template": "Neue Vorlage",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Löschen",
"BoardTemplateSelector.description": "Wähle eine Vorlage um zu starten. Passe die Vorlage einfach an deine Anforderungen an oder erstelle ein leeres Board.",
"BoardTemplateSelector.edit-template": "Bearbeiten",
"BoardTemplateSelector.plugin.no-content-description": "Füge ein Board zur Seitenleiste hinzu, indem du eine der Vorlagen unten verwendest oder starte mit einem leeren Board.{lineBreak} Mitglieder von \"{workspaceName}\" werden Zugriff auf die Boards haben, die hier erstellt werden.",
"BoardTemplateSelector.plugin.no-content-title": "Erstelle ein Board in {workspaceName}",
"BoardTemplateSelector.plugin.no-content-description": "Füge ein Board zur Seitenleiste hinzu, indem du eine der Vorlagen unten verwendest oder starte mit einem leeren Board.{lineBreak} Mitglieder von \"{teamName}\" werden Zugriff auf die Boards haben, die hier erstellt werden.",
"BoardTemplateSelector.plugin.no-content-title": "Erstelle ein Board in {teamName}",
"BoardTemplateSelector.title": "Erstelle ein Board",
"BoardTemplateSelector.use-this-template": "Verwende diese Vorlage",
"BoardsSwitcher.Title": "Finde Boards",
"BoardsUnfurl.Remainder": "+{remainder} mehr",
"BoardsUnfurl.Updated": "Aktualisiert {time}",
"Calculations.Options.average.displayName": "Durchschnitt",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "Karte wirklich löschen!",
"CardDialog.editing-template": "Du bearbeitest eine Vorlage.",
"CardDialog.nocard": "Diese Karte existiert nicht oder ist nicht verfügbar.",
"Categories.CreateCategoryDialog.CancelText": "Abbrechen",
"Categories.CreateCategoryDialog.CreateText": "Erstellen",
"Categories.CreateCategoryDialog.Placeholder": "Benenne deine Kategorie",
"Categories.CreateCategoryDialog.UpdateText": "Aktualisieren",
"CenterPanel.Share": "Teilen",
"ColorOption.selectColor": "Wähle Farbe {color}",
"Comment.delete": "Löschen",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "Nach unten bewegen",
"ContentBlock.moveUp": "Nach oben bewegen",
"ContentBlock.text": "Text",
"DashboardPage.CenterPanel.ChangeChannels": "Verwende den Umschalter zum einfachen Wechseln der Kanäle",
"DashboardPage.CenterPanel.NoWorkspaces": "Leider konnten wir keine Kanäle finden, die diesem Begriff entsprechen",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Bitte versuche nach einem anderen Begriff zu suchen",
"DashboardPage.showEmpty": "Kanäle ohne Boards anzeigen",
"DashboardPage.title": "Dashboard",
"DeleteBoardDialog.confirm-cancel": "Abbrechen",
"DeleteBoardDialog.confirm-delete": "Löschen",
"DeleteBoardDialog.confirm-info": "Bist du sicher, dass du das Board \"{boardTitle}\" löschen möchtest? Wenn du es löschen, werden allen Karten auf diesem Board gelöscht.",
@ -121,6 +124,11 @@
"Filter.not-includes": "beinhaltet nicht",
"FilterComponent.add-filter": "+ Filter hinzufügen",
"FilterComponent.delete": "Löschen",
"FindBoFindBoardsDialog.IntroText": "Suche nach Boards",
"FindBoardsDialog.NoResultsFor": "Keine Ergebnisse für \"{searchQuery}\"",
"FindBoardsDialog.NoResultsSubtext": "Prüfe die Schreibweise oder versuche eine weitere Suche.",
"FindBoardsDialog.SubTitle": "Tippe um ein Board zu finden. Benutze <b>HOCH/RUNTER</b> zum Browsen. <b>ENTER</b> zur Auswahl, <b>ESC</b> zum Schließen",
"FindBoardsDialog.Title": "Finde Boards",
"GalleryCard.copiedLink": "Kopiert!",
"GalleryCard.copyLink": "Link kopieren",
"GalleryCard.delete": "Löschen",
@ -134,9 +142,7 @@
"KanbanCard.delete": "Löschen",
"KanbanCard.duplicate": "Duplizieren",
"KanbanCard.untitled": "Unbenannt",
"Mutator.duplicate-board": "Board duplizieren",
"Mutator.new-card-from-template": "neue Karte aus Vorlage",
"Mutator.new-template-from-board": "neue Vorlage aus Board",
"Mutator.new-template-from-card": "neue Vorlage aus Karte",
"OnboardingTour.AddComments.Body": "Du kannst Themen kommentieren und sogar deine Mattermost-Kollegen @erwähnen, um deren Aufmerksamkeit zu erhalten.",
"OnboardingTour.AddComments.Title": "Kommentare hinzufügen",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "Kopiert!",
"ShareBoard.copyLink": "Link kopieren",
"ShareBoard.regenerate": "Token neu erstellen",
"ShareBoard.teamPermissionsText": "Jeder im {teamName} Team",
"ShareBoard.tokenRegenrated": "Token neu generiert",
"ShareBoard.userPermissionsRemoveMemberText": "Mitglied entfernen",
"ShareBoard.userPermissionsYouText": "(Du)",
"Sidebar.about": "Über Focalboard",
"Sidebar.add-board": "+ Board hinzufügen",
"Sidebar.changePassword": "Passwort ändern",
"Sidebar.delete-board": "Board löschen",
"Sidebar.duplicate-board": "Board duplizieren",
"Sidebar.export-archive": "Archiv exportieren",
"Sidebar.import": "Importieren",
"Sidebar.import-archive": "Archiv importieren",
"Sidebar.invite-users": "Nutzer einladen",
"Sidebar.logout": "Ausloggen",
"Sidebar.no-more-workspaces": "Keine Arbeitsbereiche mehr",
"Sidebar.no-views-in-board": "Keine Seiten enthalten",
"Sidebar.no-boards-in-category": "Keine Boards vorhanden",
"Sidebar.random-icons": "Zufällige Icons",
"Sidebar.set-language": "Sprache übernehmen",
"Sidebar.set-theme": "Theme übernehmen",
"Sidebar.settings": "Einstellungen",
"Sidebar.template-from-board": "Neue Vorlage aus Board",
"Sidebar.untitled-board": "(Unbenanntes Board)",
"Sidebar.untitled-view": "(Unbenannte Ansicht)",
"SidebarCategories.BlocksMenu.Move": "Bewege nach...",
"SidebarCategories.CategoryMenu.CreateNew": "Erstelle neue Kategorie",
"SidebarCategories.CategoryMenu.Delete": "Lösche Kategorie",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "Boards in <b>{categoryName}</b> werden zurück zu den Board-Kategorien bewegt. Du wirst von keinen Boards entfernt.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Diese Kategorie löschen?",
"SidebarCategories.CategoryMenu.Update": "Kategorie umbenennen",
"TableComponent.add-icon": "Symbol hinzufügen",
"TableComponent.name": "Name",
"TableComponent.plus-new": "+ Neu",
@ -282,6 +293,7 @@
"login.register-button": "oder erstelle einen Account wenn du noch keines hast",
"register.login-button": "oder melde dich an, wenn du bereits ein Konto hast",
"register.signup-title": "Registriere dich für deinen Account",
"shareBoard.lastAdmin": "Boards müssen mindestens eine Administrator haben",
"tutorial_tip.finish_tour": "Erledigt",
"tutorial_tip.got_it": "Alles klar",
"tutorial_tip.ok": "Weiter",

View File

@ -20,7 +20,6 @@
"ContentBlock.moveDown": "Μετακίνηση κάτω",
"ContentBlock.moveUp": "Μετακίνηση επάνω",
"ContentBlock.text": "κείμενο",
"DashboardPage.showEmpty": "Προβολή άδειου",
"EditableDayPicker.today": "Σήμερα",
"Filter.includes": "περιέχει",
"Filter.is-empty": "είναι άδειο",

View File

@ -181,10 +181,13 @@
"ShareBoard.tokenRegenrated": "Token regenerated",
"ShareBoard.userPermissionsRemoveMemberText": "Remove member",
"ShareBoard.userPermissionsYouText": "(You)",
"ShareTemplate.Title": "Share Template",
"Sidebar.about": "About Focalboard",
"Sidebar.add-board": "+ Add board",
"Sidebar.changePassword": "Change password",
"Sidebar.delete-board": "Delete board",
"Sidebar.duplicate-board": "Duplicate board",
"Sidebar.template-from-board": "New template from board",
"Sidebar.export-archive": "Export archive",
"Sidebar.import": "Import",
"Sidebar.import-archive": "Import archive",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "No {property}",
"BoardComponent.no-property-title": "Items with an empty {property} property will go here. This column cannot be removed.",
"BoardComponent.show": "Show",
"BoardMember.schemeAdmin": "Admin",
"BoardMember.schemeEditor": "Editor",
"BoardMember.schemeNone": "None",
"BoardPage.newVersion": "A new version of Boards is available, click here to reload.",
"BoardPage.syncFailed": "Board may be deleted or access revoked.",
"BoardTemplateSelector.add-template": "New template",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Delete",
"BoardTemplateSelector.description": "Choose a template to help you get started. Easily customise the template to fit your needs, or create an empty board to start from scratch.",
"BoardTemplateSelector.edit-template": "Edit",
"BoardTemplateSelector.plugin.no-content-description": "Add a board to the sidebar using any of the templates defined below or start from scratch.{lineBreak} Members of '{workspaceName}' will have access to boards created here.",
"BoardTemplateSelector.plugin.no-content-title": "Create a Board in {workspaceName}",
"BoardTemplateSelector.plugin.no-content-description": "Add a board to the sidebar using any of the templates defined below or start from scratch.{lineBreak} Members of '\\{teamName}'\\ will have access to boards created here.",
"BoardTemplateSelector.plugin.no-content-title": "Create a Board in {teamName}",
"BoardTemplateSelector.title": "Create a Board",
"BoardTemplateSelector.use-this-template": "Use this template",
"BoardsSwitcher.Title": "Find Boards",
"BoardsUnfurl.Remainder": "+{remainder} more",
"BoardsUnfurl.Updated": "Updated {time}",
"Calculations.Options.average.displayName": "Average",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "Confirm card deletion?",
"CardDialog.editing-template": "You're editing a template.",
"CardDialog.nocard": "This card doesn't exist or is inaccessible.",
"Categories.CreateCategoryDialog.CancelText": "Cancel",
"Categories.CreateCategoryDialog.CreateText": "Create",
"Categories.CreateCategoryDialog.Placeholder": "Name your category",
"Categories.CreateCategoryDialog.UpdateText": "Update",
"CenterPanel.Share": "Share",
"ColorOption.selectColor": "Select {color} Colour",
"Comment.delete": "Delete",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "Move down",
"ContentBlock.moveUp": "Move up",
"ContentBlock.text": "text",
"DashboardPage.CenterPanel.ChangeChannels": "Use the switcher to easily change channels",
"DashboardPage.CenterPanel.NoWorkspaces": "No channels matching that term could be found",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Please try searching for another term",
"DashboardPage.showEmpty": "Show empty",
"DashboardPage.title": "Dashboard",
"DeleteBoardDialog.confirm-cancel": "Cancel",
"DeleteBoardDialog.confirm-delete": "Delete",
"DeleteBoardDialog.confirm-info": "Are you sure you want to delete the board '{boardTitle}'? This will remove all cards in the board.",
@ -121,6 +124,11 @@
"Filter.not-includes": "doesn't include",
"FilterComponent.add-filter": "+ Add filter",
"FilterComponent.delete": "Delete",
"FindBoFindBoardsDialog.IntroText": "Search for boards",
"FindBoardsDialog.NoResultsFor": "No results for '\\{searchQuery}'\\",
"FindBoardsDialog.NoResultsSubtext": "Check the spelling or try another search.",
"FindBoardsDialog.SubTitle": "Type to find a board. Use <b>UP/DOWN</b> to browse. <b>ENTER</b> to select, <b>ESC</b> to dismiss",
"FindBoardsDialog.Title": "Find Boards",
"GalleryCard.copiedLink": "Copied!",
"GalleryCard.copyLink": "Copy link",
"GalleryCard.delete": "Delete",
@ -134,9 +142,7 @@
"KanbanCard.delete": "Delete",
"KanbanCard.duplicate": "Duplicate",
"KanbanCard.untitled": "Untitled",
"Mutator.duplicate-board": "duplicate board",
"Mutator.new-card-from-template": "new card from template",
"Mutator.new-template-from-board": "new template from board",
"Mutator.new-template-from-card": "new template from card",
"OnboardingTour.AddComments.Body": "You can comment on issues, and even @mention your fellow Mattermost users to get their attention.",
"OnboardingTour.AddComments.Title": "Add comments",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "Copied!",
"ShareBoard.copyLink": "Copy link",
"ShareBoard.regenerate": "Regenerate token",
"ShareBoard.teamPermissionsText": "Everyone at {teamName} Team",
"ShareBoard.tokenRegenrated": "Token regenerated",
"ShareBoard.userPermissionsRemoveMemberText": "Remove member",
"ShareBoard.userPermissionsYouText": "(You)",
"Sidebar.about": "About Focalboard",
"Sidebar.add-board": "+ Add board",
"Sidebar.changePassword": "Change password",
"Sidebar.delete-board": "Delete board",
"Sidebar.duplicate-board": "Duplicate board",
"Sidebar.export-archive": "Export archive",
"Sidebar.import": "Import",
"Sidebar.import-archive": "Import archive",
"Sidebar.invite-users": "Invite users",
"Sidebar.logout": "Log out",
"Sidebar.no-more-workspaces": "No more workspaces",
"Sidebar.no-views-in-board": "No pages contained within",
"Sidebar.no-boards-in-category": "No boards inside",
"Sidebar.random-icons": "Random icons",
"Sidebar.set-language": "Set language",
"Sidebar.set-theme": "Set theme",
"Sidebar.settings": "Settings",
"Sidebar.template-from-board": "New template from board",
"Sidebar.untitled-board": "(Untitled Board)",
"Sidebar.untitled-view": "(Untitled View)",
"SidebarCategories.BlocksMenu.Move": "Move To...",
"SidebarCategories.CategoryMenu.CreateNew": "Create New Category",
"SidebarCategories.CategoryMenu.Delete": "Delete Category",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "Boards in <b>{categoryName}</b> will move back to the Boards categories. You're not removed from any boards.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Delete this category?",
"SidebarCategories.CategoryMenu.Update": "Rename Category",
"TableComponent.add-icon": "Add icon",
"TableComponent.name": "Name",
"TableComponent.plus-new": "+ New",
@ -282,6 +293,7 @@
"login.register-button": "or create an account if you don't have one",
"register.login-button": "or log in if you already have an account",
"register.signup-title": "Sign up for your account",
"shareBoard.lastAdmin": "Boards must have at least one Administrator",
"tutorial_tip.finish_tour": "Done",
"tutorial_tip.got_it": "Got it",
"tutorial_tip.ok": "Next",

View File

@ -7,11 +7,34 @@
"BoardComponent.no-property": "Sin {property}",
"BoardComponent.no-property-title": "Elementos sin la propiedad {property} irán aquí. Esta columna no se puede eliminar.",
"BoardComponent.show": "Mostrar",
"BoardMember.schemeAdmin": "Administrador",
"BoardMember.schemeEditor": "Editor",
"BoardMember.schemeNone": "Ninguno",
"BoardPage.newVersion": "Una nueva versión de Board está disponible, haz click aquí para recargar.",
"BoardPage.syncFailed": "El tablero puede estar eliminado o el acceso fue revocado.",
"BoardTemplateSelector.add-template": "Nueva plantilla",
"BoardTemplateSelector.create-empty-board": "Crear pizarra vacía",
"BoardTemplateSelector.delete-template": "Suprimir",
"BoardTemplateSelector.edit-template": "Editar",
"BoardTemplateSelector.use-this-template": "Utiliza esta plantilla",
"BoardsUnfurl.Updated": "Actualizado {time}",
"Calculations.Options.count.displayName": "Cantidad",
"Calculations.Options.count.label": "Cantidad",
"Calculations.Options.countChecked.displayName": "Marcado",
"Calculations.Options.countUnchecked.displayName": "Deseleccionado",
"Calculations.Options.countValue.displayName": "Valores",
"Calculations.Options.dateRange.displayName": "Rango",
"Calculations.Options.dateRange.label": "Rango",
"Calculations.Options.max.displayName": "Máx",
"Calculations.Options.max.label": "Máx",
"Calculations.Options.median.displayName": "Mediana",
"Calculations.Options.median.label": "Mediana",
"Calculations.Options.min.displayName": "Mín",
"Calculations.Options.min.label": "Mín",
"Calculations.Options.none.displayName": "Calcular",
"Calculations.Options.none.label": "Ninguna",
"Calculations.Options.percentChecked.displayName": "Marcado",
"Calculations.Options.range.displayName": "Rango",
"CardDetail.add-content": "Añadir contenido",
"CardDetail.add-icon": "Añadir icono",
"CardDetail.add-property": "+ Añadir propiedad",
@ -41,11 +64,6 @@
"ContentBlock.moveDown": "Mover hacia abajo",
"ContentBlock.moveUp": "Mover hacia arriba",
"ContentBlock.text": "texto",
"DashboardPage.CenterPanel.ChangeChannels": "Usa el selector para cambiar fácilmente de canal",
"DashboardPage.CenterPanel.NoWorkspaces": "Lo sentimos, no pudimos encontrar ningún canal que coincida con ese término",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Por favor, intenta buscar otro término",
"DashboardPage.showEmpty": "Mostrar vacío",
"DashboardPage.title": "Tablero",
"Dialog.closeDialog": "Cerrar diálogo",
"EditableDayPicker.today": "Hoy",
"Error.websocket-closed": "Conexión de Websocket cerrada, conexión interrumpida. Si esto persiste, verifique la configuración de su servidor o proxy web.",
@ -66,9 +84,7 @@
"KanbanCard.delete": "Eliminar",
"KanbanCard.duplicate": "Duplicar",
"KanbanCard.untitled": "Sin título",
"Mutator.duplicate-board": "duplicar panel",
"Mutator.new-card-from-template": "nueva tarjeta desde una plantilla",
"Mutator.new-template-from-board": "nueva plantilla a partir de un panel",
"Mutator.new-template-from-card": "nueva plantilla desde una tarjeta",
"PropertyMenu.Delete": "Borrar",
"PropertyMenu.changeType": "Cambiar el tipo de propiedad",
@ -102,20 +118,15 @@
"Sidebar.add-board": "+ Añadir panel",
"Sidebar.changePassword": "Cambiar contraseña",
"Sidebar.delete-board": "Borrar Panel",
"Sidebar.duplicate-board": "Duplicar panel",
"Sidebar.export-archive": "Exportar Archivo",
"Sidebar.import-archive": "Importar Archivo",
"Sidebar.invite-users": "Invitar usuarios",
"Sidebar.logout": "Cerrar sesión",
"Sidebar.no-more-workspaces": "No hay más espacios de trabajo",
"Sidebar.no-views-in-board": "No hay páginas dentro",
"Sidebar.random-icons": "Íconos random",
"Sidebar.set-language": "Establecer idioma",
"Sidebar.set-theme": "Establecer apariencia",
"Sidebar.settings": "Configuración",
"Sidebar.template-from-board": "Nueva plantilla desde un panel",
"Sidebar.untitled-board": "(Panel sin titulo)",
"Sidebar.untitled-view": "(Vista sin titulo)",
"TableComponent.add-icon": "Añadir Icono",
"TableComponent.name": "Nombre",
"TableComponent.plus-new": "+ Nueva",

View File

@ -60,8 +60,6 @@
"ContentBlock.moveDown": "Liiguta alla",
"ContentBlock.moveUp": "Liiguta üles",
"ContentBlock.text": "tekst",
"DashboardPage.showEmpty": "Näita tühja",
"DashboardPage.title": "Töölaud",
"DeleteBoardDialog.confirm-cancel": "Loobu",
"DeleteBoardDialog.confirm-delete": "Kustuta",
"EditableDayPicker.today": "Täna",

View File

@ -66,10 +66,6 @@
"ContentBlock.moveDown": "Déplacer vers le bas",
"ContentBlock.moveUp": "Déplacer vers le haut",
"ContentBlock.text": "texte",
"DashboardPage.CenterPanel.ChangeChannels": "Utiliser le sélecteur pour changer de canal",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Essayez de rechercher un autre terme",
"DashboardPage.showEmpty": "Tout afficher",
"DashboardPage.title": "Bienvenue dans Focalboard !",
"DeleteBoardDialog.confirm-cancel": "Annuler",
"DeleteBoardDialog.confirm-delete": "Supprimer",
"DeleteBoardDialog.confirm-info": "Êtes-vous sûr de vouloir supprimer le tableau «{boardTitle}» ? Cela supprimera toutes les cartes dans ce tableau.",
@ -96,9 +92,7 @@
"KanbanCard.delete": "Supprimer",
"KanbanCard.duplicate": "Dupliquer",
"KanbanCard.untitled": "Sans titre",
"Mutator.duplicate-board": "dupliquer le tableau",
"Mutator.new-card-from-template": "nouvelle carte depuis un modèle",
"Mutator.new-template-from-board": "nouveau modèle depuis un tableau",
"Mutator.new-template-from-card": "nouveau modèle depuis une carte",
"OnboardingTour.AddComments.Body": "Vous pouvez commenter les bugs et même @mentionner les utilisateurs de Mattermost pour attirer leur attention.",
"OnboardingTour.AddComments.Title": "Ajouter des commentaires",
@ -152,21 +146,16 @@
"Sidebar.add-board": "+ Ajouter un tableau",
"Sidebar.changePassword": "Modifier le mot de passe",
"Sidebar.delete-board": "Supprimer le tableau",
"Sidebar.duplicate-board": "Dupliquer le tableau",
"Sidebar.export-archive": "Exporter une archive",
"Sidebar.import": "Importer",
"Sidebar.import-archive": "Importer une archive",
"Sidebar.invite-users": "Inviter des utilisateurs",
"Sidebar.logout": "Se déconnecter",
"Sidebar.no-more-workspaces": "Plus d'espace de travail",
"Sidebar.no-views-in-board": "Pas de page incluse",
"Sidebar.random-icons": "Icônes aléatoires",
"Sidebar.set-language": "Choisir la langue",
"Sidebar.set-theme": "Choisir le thème",
"Sidebar.settings": "Réglages",
"Sidebar.template-from-board": "Nouveau modèle depuis le tableau",
"Sidebar.untitled-board": "(Tableau sans titre)",
"Sidebar.untitled-view": "(Vue sans titre)",
"TableComponent.add-icon": "Ajouter une icône",
"TableComponent.name": "Nom",
"TableComponent.plus-new": "+ Nouveau",

1
webapp/i18n/he.json Normal file
View File

@ -0,0 +1 @@
{}

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "Bez svojstva {property}",
"BoardComponent.no-property-title": "Elementi s praznim svojstvom {property} smjestit će se ovdje. Ovaj se stupac ne može ukloniti.",
"BoardComponent.show": "Prikaži",
"BoardMember.schemeAdmin": "Administrator",
"BoardMember.schemeEditor": "Urednik",
"BoardMember.schemeNone": "Ništa",
"BoardPage.newVersion": "Dostupna je nova verzija za „Ploče”. Pritisni ovdje za ponovno učitavanje.",
"BoardPage.syncFailed": "Ploča se može izbrisati ili pristup opozvati.",
"BoardTemplateSelector.add-template": "Novi predložak",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Izbriši",
"BoardTemplateSelector.description": "Za početak odaberi predložak. Prilagodi predložak kako bi odgovarao tvojim potrebama ili stvori praznu ploču.",
"BoardTemplateSelector.edit-template": "Uredi",
"BoardTemplateSelector.plugin.no-content-description": "Dodaj ploču u bočnu traku koristeći bilo koji od niže dolje definiranih predložaka ili počni ispočetka.{lineBreak} „{workspaceName}” članovi imat će pristup ovdje stvorenim pločama.",
"BoardTemplateSelector.plugin.no-content-title": "Stvori ploču u {workspaceName}",
"BoardTemplateSelector.plugin.no-content-description": "Dodaj ploču u bočnu traku koristeći bilo koji od niže dolje definiranih predložaka ili počni ispočetka.{lineBreak} Članovi tima „{teamName}” imat će pristup ovdje stvorenim pločama.",
"BoardTemplateSelector.plugin.no-content-title": "Stvori ploču u timu {teamName}",
"BoardTemplateSelector.title": "Stvori ploču",
"BoardTemplateSelector.use-this-template": "Koristi ovaj predložak",
"BoardsSwitcher.Title": "Pronađi ploče",
"BoardsUnfurl.Remainder": "+ još {remainder}",
"BoardsUnfurl.Updated": "Aktulaizirano {time}",
"Calculations.Options.average.displayName": "Prosjek",
@ -67,20 +71,24 @@
"CardDetail.new-comment-placeholder": "Dodaj komentar …",
"CardDetailProperty.confirm-delete-heading": "Potvrdi brisanje svojstva",
"CardDetailProperty.confirm-delete-subtext": "Stvarno želiš izbrisati svojstvo „{propertyName}”? Brisanjem će se izbrisati svojstvo sa svih kartica na ovoj ploči.",
"CardDetailProperty.confirm-property-name-change-subtext": "Stvarno želiš promijeniti svojstvo „{propertyName}” {customText}? To će utjecati na vrijednosti u {numOfcards} kartica na ovoj ploči, a može rezultirati gubitkom podataka.",
"CardDetailProperty.confirm-property-name-change-subtext": "Stvarno želiš promijeniti svojstvo „{propertyName}” {customText}? To će utjecati na vrijednosti na {numOfCards} kartica na ovoj ploči i može prouzročiti gubitak podataka.",
"CardDetailProperty.confirm-property-type-change": "Potvrdi promjenu vrste svojstva!",
"CardDetailProperty.delete-action-button": "Izbriši",
"CardDetailProperty.property-change-action-button": "Promijeni svojstvo",
"CardDetailProperty.property-changed": "Promjena svojstva uspjela!",
"CardDetailProperty.property-deleted": "Svojstvo {propertyName} uspješno izbrisano!",
"CardDetailProperty.property-name-change-subtext": "vrsta iz „{oldPropType}” u „{newPropType}”",
"CardDetailProperty.property-type-change-subtext": "Ime u „{newPropName}”",
"CardDetailProperty.property-name-change-subtext": "vrste „{oldPropType}” u „{newPropType}”",
"CardDetailProperty.property-type-change-subtext": "ime u „{newPropName}”",
"CardDialog.copiedLink": "Kopirano!",
"CardDialog.copyLink": "Kopiraj poveznicu",
"CardDialog.delete-confirmation-dialog-button-text": "Izbriši",
"CardDialog.delete-confirmation-dialog-heading": "Potvrdi brisanje karte!",
"CardDialog.editing-template": "Uređuješ predložak.",
"CardDialog.nocard": "Ova kartica ne postoji ili nije dostupna.",
"Categories.CreateCategoryDialog.CancelText": "Odustani",
"Categories.CreateCategoryDialog.CreateText": "Stvori",
"Categories.CreateCategoryDialog.Placeholder": "Zadaj ime kategoriji",
"Categories.CreateCategoryDialog.UpdateText": "Aktualiziraj",
"CenterPanel.Share": "Dijeli",
"ColorOption.selectColor": "Odaberi boju {color}",
"Comment.delete": "Izbriši",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "Pomakni dolje",
"ContentBlock.moveUp": "Pomakni gore",
"ContentBlock.text": "tekst",
"DashboardPage.CenterPanel.ChangeChannels": "Koristi prekidač za jednostavno mijenjanja kanala",
"DashboardPage.CenterPanel.NoWorkspaces": "Nažalost, nismo mogli pronaći nijedan kanal koji odgovara tom pojmu",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Pokušaj tražiti jedan drugi pojam",
"DashboardPage.showEmpty": "Prikaži prazne",
"DashboardPage.title": "Pregledna ploča",
"DeleteBoardDialog.confirm-cancel": "Odustani",
"DeleteBoardDialog.confirm-delete": "Izbriši",
"DeleteBoardDialog.confirm-info": "Stvarno želiš izbrisati ploču „{boardTitle}”? Brisanjem će se izbrisati sve karte na ploči.",
@ -121,20 +124,25 @@
"Filter.not-includes": "ne uključuje",
"FilterComponent.add-filter": "+ Dodaj filtar",
"FilterComponent.delete": "Izbriši",
"FindBoFindBoardsDialog.IntroText": "Traži ploče",
"FindBoardsDialog.NoResultsFor": "Nema rezultata za „{searchQuery}”",
"FindBoardsDialog.NoResultsSubtext": "Provjeri pravopis ili pretraži s jednim drugim pojmom.",
"FindBoardsDialog.SubTitle": "Utipkaj ime za pronalaženje ploče. Koristi <b>GORE/DOLJE</b> za pretraživanje. <b>ENTER</b> za odabiranje, <b>ESC</b> za prekid",
"FindBoardsDialog.Title": "Pronađi ploče",
"GalleryCard.copiedLink": "Kopirano!",
"GalleryCard.copyLink": "Kopiraj poveznicu",
"GalleryCard.delete": "Izbriši",
"GalleryCard.duplicate": "Dupliciraj",
"General.BoardCount": "{count, plural, one {# ploča} few {# ploče} other {# ploča}}",
"GroupBy.hideEmptyGroups": "Sakrij {count} prazne grupe",
"GroupBy.showHiddenGroups": "Prikaži {count} skrivene grupe",
"GroupBy.ungroup": "Razgrupiraj",
"KanbanCard.copiedLink": "Kopirano!",
"KanbanCard.copyLink": "Kopiraj poveznicu",
"KanbanCard.delete": "Izbriši",
"KanbanCard.duplicate": "Dupliciraj",
"KanbanCard.untitled": "Bez naslova",
"Mutator.duplicate-board": "dupliciraj ploču",
"Mutator.new-card-from-template": "nova kartica iz predloška",
"Mutator.new-template-from-board": "novi predložak iz ploče",
"Mutator.new-template-from-card": "novi predložak iz kartice",
"OnboardingTour.AddComments.Body": "Probleme možeš komentirati. Možeš čak i @spomenuti svoje Mattermost kolege za privlačenje njihove pozornosti.",
"OnboardingTour.AddComments.Title": "Dodaj komentare",
@ -183,26 +191,31 @@
"ShareBoard.copiedLink": "Kopirano!",
"ShareBoard.copyLink": "Kopiraj poveznicu",
"ShareBoard.regenerate": "Ponovo generiraj token",
"ShareBoard.teamPermissionsText": "Svatko u timu {teamName}",
"ShareBoard.tokenRegenrated": "Token je ponovo generiran",
"ShareBoard.userPermissionsRemoveMemberText": "Ukloni člana",
"ShareBoard.userPermissionsYouText": "(Ti)",
"Sidebar.about": "O programu Focalboard",
"Sidebar.add-board": "+ Dodaj ploču",
"Sidebar.changePassword": "Promijeni lozinku",
"Sidebar.delete-board": "Izbriši ploču",
"Sidebar.duplicate-board": "Dupliciraj ploču",
"Sidebar.export-archive": "Izvezi arhivu",
"Sidebar.import": "Uvezi",
"Sidebar.import-archive": "Uvezi arhivu",
"Sidebar.invite-users": "Pozovi korisnika",
"Sidebar.logout": "Odjavi se",
"Sidebar.no-more-workspaces": "Nema daljnjih radnih prostora",
"Sidebar.no-views-in-board": "Unutra nema stranica",
"Sidebar.no-boards-in-category": "Nema ploča u kategoriji",
"Sidebar.random-icons": "Slučajne ikone",
"Sidebar.set-language": "Postavi jezik",
"Sidebar.set-theme": "Postavi temu",
"Sidebar.settings": "Postavke",
"Sidebar.template-from-board": "Novi predložak iz ploče",
"Sidebar.untitled-board": "(Ploča bez naslova)",
"Sidebar.untitled-view": "(Prikaz bez naslova)",
"SidebarCategories.BlocksMenu.Move": "Premjesti u …",
"SidebarCategories.CategoryMenu.CreateNew": "Stvori novu kategoriju",
"SidebarCategories.CategoryMenu.Delete": "Izbriši kategoriju",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "Ploče u kategoriji <b>{categoryName}</b> vratit će se u kategorije ploča. Nećeš biti uklonjen/a s nijedne ploče.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Izbrisati ovu kategoriju?",
"SidebarCategories.CategoryMenu.Update": "Preimenuj kategoriju",
"TableComponent.add-icon": "Dodaj ikonu",
"TableComponent.name": "Ime",
"TableComponent.plus-new": "+ Novo",
@ -266,6 +279,8 @@
"calendar.week": "Tjedan",
"default-properties.badges": "Komentari i opis",
"default-properties.title": "Naslov",
"error.back-to-boards": "Natrag na ploče",
"error.back-to-home": "Natrag na početnu stranicu",
"error.go-login": "Prijava",
"error.not-logged-in": "Tvoja sesija je istekla ili nisi prijavljen/prijavljena.",
"error.page.title": "Oprosti, dogodila se greška",
@ -278,6 +293,7 @@
"login.register-button": "ili stvori račun, ako ga još nemaš",
"register.login-button": "ili se prijavi ako već imaš račun",
"register.signup-title": "Prijavi se na svoj račun",
"shareBoard.lastAdmin": "Ploče moraju imati barem jednog administratora",
"tutorial_tip.finish_tour": "Gotovo",
"tutorial_tip.got_it": "Razumijem",
"tutorial_tip.ok": "Dalje",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "Nincs {property}",
"BoardComponent.no-property-title": "Elemek üres {property} tulajdonsággal kerülnek ide. Ez az oszlop nem eltávolítható.",
"BoardComponent.show": "Mutat",
"BoardMember.schemeAdmin": "Admin",
"BoardMember.schemeEditor": "Szerkesztő",
"BoardMember.schemeNone": "Nincs",
"BoardPage.newVersion": "Elérhető a Táblák egy új verziója, kattintson ide az újratöltéshez.",
"BoardPage.syncFailed": "A tábla törölve lett vagy hozzáférés vissza lett vonva.",
"BoardTemplateSelector.add-template": "Új sablon",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Törlés",
"BoardTemplateSelector.description": "Válasszon egy sablont, amely segít a kezdésben. Könnyedén testre szabhatja a sablont, hogy megfeleljen az Ön igényeinek, vagy létrehozhat egy üres táblát, hogy a nulláról kezdhesse.",
"BoardTemplateSelector.edit-template": "Szerkesztés",
"BoardTemplateSelector.plugin.no-content-description": "Adjon hozzá egy táblát az oldalsávhoz az alább definiált sablonok bármelyikével, vagy kezdje elölről.{lineBreak} A \"{workspaceName}\" tagjai hozzáférhetnek az itt létrehozott táblákhoz.",
"BoardTemplateSelector.plugin.no-content-title": "Tábla létrehozása a {workspaceName} munkaterületben",
"BoardTemplateSelector.plugin.no-content-description": "Adjon hozzá egy táblát az oldalsávhoz az alább megadott sablonok bármelyikével, vagy kezdje elölről.{lineBreak} A \"{teamName}\" tagjai hozzáférhetnek az itt létrehozott táblákhoz.",
"BoardTemplateSelector.plugin.no-content-title": "Tábla létrehozása a {teamName} csapathoz",
"BoardTemplateSelector.title": "Tábla létrehozása",
"BoardTemplateSelector.use-this-template": "Használja ezt a sablont",
"BoardsSwitcher.Title": "Táblák keresése",
"BoardsUnfurl.Remainder": "+{remainder} további",
"BoardsUnfurl.Updated": "Frissítve {time}",
"Calculations.Options.average.displayName": "Átlag",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "Hagyja jóvá a kártya törlését!",
"CardDialog.editing-template": "Ön egy sablont szerkeszt.",
"CardDialog.nocard": "Ez a kártya nem létezik vagy elérhetetlen.",
"Categories.CreateCategoryDialog.CancelText": "Mégsem",
"Categories.CreateCategoryDialog.CreateText": "Létrehozás",
"Categories.CreateCategoryDialog.Placeholder": "Nevezze el a kategóriáját",
"Categories.CreateCategoryDialog.UpdateText": "Frissítés",
"CenterPanel.Share": "Megosztás",
"ColorOption.selectColor": "{color} szín kiválasztása",
"Comment.delete": "Törlés",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "Mozgatás le",
"ContentBlock.moveUp": "Mozgatás fel",
"ContentBlock.text": "szöveg",
"DashboardPage.CenterPanel.ChangeChannels": "Használja a váltót a beszélgetések könnyű váltásához",
"DashboardPage.CenterPanel.NoWorkspaces": "Sajnáljuk, de nem találtunk egy beszélgetést sem ami ennek a kifejezésnek megfelelne",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Kérjük próbáljon keresni egy másik kifejezésre",
"DashboardPage.showEmpty": "Mutassa az üreseket",
"DashboardPage.title": "Vezérlőpult",
"DeleteBoardDialog.confirm-cancel": "Mégsem",
"DeleteBoardDialog.confirm-delete": "Törlés",
"DeleteBoardDialog.confirm-info": "Biztos benne, hogy törölni szeretné a “{boardTitle}” táblát? A törlésével az összes benne lévő kártya is törlődni fog.",
@ -121,6 +124,11 @@
"Filter.not-includes": "nem tartalmazza",
"FilterComponent.add-filter": "+ Szűrő hozzáadása",
"FilterComponent.delete": "Törlés",
"FindBoFindBoardsDialog.IntroText": "Táblák keresése",
"FindBoardsDialog.NoResultsFor": "Nincs találat a \"{searchQuery}\" kereséshez",
"FindBoardsDialog.NoResultsSubtext": "Ellenőrizze az elgépelést vagy próbáljon egy új keresést.",
"FindBoardsDialog.SubTitle": "Gépeljen, hogy megtalálja a táblát. Használja a <b>FEL/LE</b> gombokat a böngészéshez. <b>ENTER</b> gombot a kiválasztáshoz és <b>ESC</b> gombot az eldobáshoz",
"FindBoardsDialog.Title": "Táblák keresése",
"GalleryCard.copiedLink": "Másolva!",
"GalleryCard.copyLink": "Link másolása",
"GalleryCard.delete": "Törlés",
@ -134,9 +142,7 @@
"KanbanCard.delete": "Törlés",
"KanbanCard.duplicate": "Duplikálás",
"KanbanCard.untitled": "Névtelen",
"Mutator.duplicate-board": "tábla duplikálása",
"Mutator.new-card-from-template": "új kártya sablonból",
"Mutator.new-template-from-board": "új sablon táblából",
"Mutator.new-template-from-card": "új sablon kártyából",
"OnboardingTour.AddComments.Body": "Hozzászólhat a témákhoz, sőt, más Mattermost felhasználó társát is @megemlítheti, hogy felhívja a figyelmüket.",
"OnboardingTour.AddComments.Title": "Megjegyzés hozzáadása",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "Másolt!",
"ShareBoard.copyLink": "Link másolása",
"ShareBoard.regenerate": "Token újragenerálása",
"ShareBoard.teamPermissionsText": "Mindenki a {teamName} Csapatban",
"ShareBoard.tokenRegenrated": "Token újragenerálva",
"ShareBoard.userPermissionsRemoveMemberText": "Tag eltávolítása",
"ShareBoard.userPermissionsYouText": "(Ön)",
"Sidebar.about": "Focalboard névjegye",
"Sidebar.add-board": "+ Tábla hozzáadása",
"Sidebar.changePassword": "Jelszó módosítása",
"Sidebar.delete-board": "Tábla törlése",
"Sidebar.duplicate-board": "Tábla duplikálása",
"Sidebar.export-archive": "Archiváltak exportálása",
"Sidebar.import": "Importálás",
"Sidebar.import-archive": "Archiváltak importálása",
"Sidebar.invite-users": "Felhasználók meghívása",
"Sidebar.logout": "Kijelentkezés",
"Sidebar.no-more-workspaces": "Nincs több munkaterület",
"Sidebar.no-views-in-board": "Nincsennek benne lapok",
"Sidebar.no-boards-in-category": "Nincsennek bent táblák",
"Sidebar.random-icons": "Véletlen ikonok",
"Sidebar.set-language": "Nyelv megadása",
"Sidebar.set-theme": "Téma megadása",
"Sidebar.settings": "Beállítások",
"Sidebar.template-from-board": "Új sablon táblából",
"Sidebar.untitled-board": "(Névtelen tábla)",
"Sidebar.untitled-view": "(Névtelen nézet)",
"SidebarCategories.BlocksMenu.Move": "Áthelyezés...",
"SidebarCategories.CategoryMenu.CreateNew": "Új kategória létrehozása",
"SidebarCategories.CategoryMenu.Delete": "Kategória törlése",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "A <b>{categoryName}</b> kategóriában lévő táblák visszakerülnek a Táblák kategóriákba. Ön egyik táblából sem lesz eltávolítva.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Törli ezt a kategóriát?",
"SidebarCategories.CategoryMenu.Update": "Kategória átnevezése",
"TableComponent.add-icon": "Ikon hozzáadása",
"TableComponent.name": "Név",
"TableComponent.plus-new": "+ Új",
@ -268,6 +279,8 @@
"calendar.week": "Hét",
"default-properties.badges": "Megjegyzések és leírás",
"default-properties.title": "Cím",
"error.back-to-boards": "Vissza a táblákba",
"error.back-to-home": "Vissza a kezdőlapra",
"error.go-login": "Bejelentkezés",
"error.not-logged-in": "Lehet, hogy lejárt a munkamenete, vagy nincs bejelentkezve.",
"error.page.title": "Sajnálom, valami rosszul sikerült",
@ -280,6 +293,7 @@
"login.register-button": "vagy hozzon létre egy fiókot ha még nincs",
"register.login-button": "vagy jelentkezzen be ha már van fiókja",
"register.signup-title": "Regisztráljon fiókjáért",
"shareBoard.lastAdmin": "A tábláknak legalább egy Adminisztárorral kell rendelkezniük",
"tutorial_tip.finish_tour": "Kész",
"tutorial_tip.got_it": "Értettem",
"tutorial_tip.ok": "Következő",

View File

@ -44,11 +44,6 @@
"ContentBlock.moveDown": "Turunkan",
"ContentBlock.moveUp": "Naikkan",
"ContentBlock.text": "teks",
"DashboardPage.CenterPanel.ChangeChannels": "Gunakan tombol saklar untuk berpindah kanal dengan mudah",
"DashboardPage.CenterPanel.NoWorkspaces": "Maaf, kami tidak dapat menemukan kanal yang sesuai dengan kata tersebut",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Mohon lalukan pencarian untuk kata yang lain",
"DashboardPage.showEmpty": "Tampilan kosong",
"DashboardPage.title": "Dasbor",
"Dialog.closeDialog": "Tutup dialog",
"EditableDayPicker.today": "Hari Ini",
"Error.websocket-closed": "Koneksi ke soket web tertutup, koneksi terganggu. Jika hal ini terus berlanjut, periksa konfigurasi server atau proxy web Anda.",
@ -69,9 +64,7 @@
"KanbanCard.delete": "Hapus",
"KanbanCard.duplicate": "Duplikasikan",
"KanbanCard.untitled": "Tidak berjudul",
"Mutator.duplicate-board": "duplikasikan papan",
"Mutator.new-card-from-template": "kartu baru dari template",
"Mutator.new-template-from-board": "template baru dari papan",
"Mutator.new-template-from-card": "template baru dari kartu",
"PropertyMenu.Delete": "Hapus",
"PropertyMenu.changeType": "Ubah jenis properti",
@ -105,20 +98,15 @@
"Sidebar.add-board": "+ Tambahkan papan",
"Sidebar.changePassword": "Ubah kata sandi",
"Sidebar.delete-board": "Hapus papan",
"Sidebar.duplicate-board": "Duplikasikan papan",
"Sidebar.export-archive": "Ekpor arsip",
"Sidebar.import-archive": "Impor arsip",
"Sidebar.invite-users": "Undang pengguna",
"Sidebar.logout": "Keluar",
"Sidebar.no-more-workspaces": "Tidak ada ruang kerja",
"Sidebar.no-views-in-board": "Tidak ada halaman di dalam",
"Sidebar.random-icons": "Ikon acak",
"Sidebar.set-language": "Tetapkan bahasa",
"Sidebar.set-theme": "Tetapkan tema",
"Sidebar.settings": "Pengaturan",
"Sidebar.template-from-board": "Template baru dari papan",
"Sidebar.untitled-board": "(Papan Tak Berjudul)",
"Sidebar.untitled-view": "(Tampilan Tak Berjudul)",
"TableComponent.add-icon": "Tambahkan ikon",
"TableComponent.name": "Nama",
"TableComponent.plus-new": "+ Buat",

View File

@ -101,11 +101,6 @@
"ContentBlock.moveDown": "Sposta giù",
"ContentBlock.moveUp": "Sposta su",
"ContentBlock.text": "testo",
"DashboardPage.CenterPanel.ChangeChannels": "Usa lo switch per cambiare facilmente canali",
"DashboardPage.CenterPanel.NoWorkspaces": "Spiacente, non siamo riusciti a trovare nessuno canale corrispondente a quel termine",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Per favore prova a cercare un altro termine",
"DashboardPage.showEmpty": "Mostra vuoto",
"DashboardPage.title": "Dashboard",
"DeleteBoardDialog.confirm-cancel": "Annulla",
"DeleteBoardDialog.confirm-delete": "Elimina",
"DeleteBoardDialog.confirm-info": "Sei sicuro di voler eliminare la bacheca \"{boardTitle}\"? Eliminandola, rimuoverai tutte le schede in bacheca.",
@ -132,9 +127,7 @@
"KanbanCard.delete": "Elimina",
"KanbanCard.duplicate": "Duplica",
"KanbanCard.untitled": "Senza titolo",
"Mutator.duplicate-board": "duplica contenitore",
"Mutator.new-card-from-template": "nuova scheda da modello",
"Mutator.new-template-from-board": "nuovo modello da contenitore",
"Mutator.new-template-from-card": "nuovo modello da scheda",
"PropertyMenu.Delete": "Elimina",
"PropertyMenu.changeType": "Cambia il tipo di proprietà",
@ -174,20 +167,15 @@
"Sidebar.add-board": "+ Aggiungi Contenitore",
"Sidebar.changePassword": "Cambia password",
"Sidebar.delete-board": "Elimina contenitore",
"Sidebar.duplicate-board": "Duplica contenitore",
"Sidebar.export-archive": "Esporta archivio",
"Sidebar.import-archive": "Importa archivio",
"Sidebar.invite-users": "Invita utenti",
"Sidebar.logout": "Logout",
"Sidebar.no-more-workspaces": "Non ci sono spazi di lavoro",
"Sidebar.no-views-in-board": "Nessuna pagina all'interno",
"Sidebar.random-icons": "Icone casuali",
"Sidebar.set-language": "Imposta la lingua",
"Sidebar.set-theme": "Imposta il tema",
"Sidebar.settings": "Impostazioni",
"Sidebar.template-from-board": "Nuovo modello da contenitore",
"Sidebar.untitled-board": "(Contenitore senza titolo)",
"Sidebar.untitled-view": "(Vista senza titolo)",
"TableComponent.add-icon": "Aggiungi icona",
"TableComponent.name": "Nome",
"TableComponent.plus-new": "+ Nuovo",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "{property} 無し",
"BoardComponent.no-property-title": "{property}が空のアイテムがここに表示されます。このカラムは削除できません。",
"BoardComponent.show": "表示",
"BoardMember.schemeAdmin": "管理者",
"BoardMember.schemeEditor": "編集者",
"BoardMember.schemeNone": "なし",
"BoardPage.newVersion": "ボードの新しいバージョンが利用可能です。ここをクリックして再読み込みしてください。",
"BoardPage.syncFailed": "ボードが削除されたか、アクセスが取り消されました。",
"BoardTemplateSelector.add-template": "新しいテンプレート",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "削除する",
"BoardTemplateSelector.description": "手軽に始めるにはテンプレートを選択します。ニーズに合わせてテンプレートを簡単にカスタマイズしたり、空のボードを作成してゼロから始めることもできます。",
"BoardTemplateSelector.edit-template": "編集",
"BoardTemplateSelector.plugin.no-content-description": "サイドバーにボードを追加するには、以下のテンプレートを利用するか、空の状態から作成します。{lineBreak} \"{workspaceName}\"のメンバーは、作成されたボードにアクセスできます。",
"BoardTemplateSelector.plugin.no-content-title": "{workspaceName} にボードを作成する",
"BoardTemplateSelector.plugin.no-content-description": "サイドバーにボードを追加するには、以下のテンプレートを利用するか、空の状態から作成します。{lineBreak} \"{teamName}\"のメンバーは、作成されたボードにアクセスできます。",
"BoardTemplateSelector.plugin.no-content-title": "{teamName} にボードを作成する",
"BoardTemplateSelector.title": "ボードを作成する",
"BoardTemplateSelector.use-this-template": "このテンプレートを使う",
"BoardsSwitcher.Title": "ボードを探す",
"BoardsUnfurl.Remainder": "残り +{remainder}",
"BoardsUnfurl.Updated": "更新日時 {time}",
"Calculations.Options.average.displayName": "平均",
@ -73,7 +77,7 @@
"CardDetailProperty.property-change-action-button": "プロパティの変更",
"CardDetailProperty.property-changed": "プロパティが変更されました!",
"CardDetailProperty.property-deleted": "{propertyName} が正常に削除されました!",
"CardDetailProperty.property-name-change-subtext": "種別を \"{oldPropType}\" から\"{newProptype}\" に",
"CardDetailProperty.property-name-change-subtext": "種別を \"{oldPropType}\" から\"{newPropType}\" に",
"CardDetailProperty.property-type-change-subtext": "名前を \"{newPropName}\" に",
"CardDialog.copiedLink": "コピーしました!",
"CardDialog.copyLink": "リンクをコピー",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "カード削除の確認",
"CardDialog.editing-template": "テンプレートを編集しています。",
"CardDialog.nocard": "このカードは存在しないか、アクセスできません。",
"Categories.CreateCategoryDialog.CancelText": "キャンセル",
"Categories.CreateCategoryDialog.CreateText": "作成",
"Categories.CreateCategoryDialog.Placeholder": "カテゴリ名を入力してください",
"Categories.CreateCategoryDialog.UpdateText": "更新",
"CenterPanel.Share": "共有",
"ColorOption.selectColor": "{color} 色を選択",
"Comment.delete": "削除",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "下へ移動する",
"ContentBlock.moveUp": "上へ移動する",
"ContentBlock.text": "テキスト",
"DashboardPage.CenterPanel.ChangeChannels": "スイッチャーで簡単にチャンネルを変更できます",
"DashboardPage.CenterPanel.NoWorkspaces": "その言葉に一致するチャンネルは見つかりませんでした",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "別の言葉で検索してみてください",
"DashboardPage.showEmpty": "空のボードを表示",
"DashboardPage.title": "ダッシュボード",
"DeleteBoardDialog.confirm-cancel": "キャンセル",
"DeleteBoardDialog.confirm-delete": "削除",
"DeleteBoardDialog.confirm-info": "本当にボード \"{boardTitle}\" を削除しますか? 削除すると、このボードのすべてのカードが削除されます。",
@ -121,6 +124,11 @@
"Filter.not-includes": "を含まない",
"FilterComponent.add-filter": "+ フィルターを追加する",
"FilterComponent.delete": "削除",
"FindBoFindBoardsDialog.IntroText": "ボードを検索する",
"FindBoardsDialog.NoResultsFor": "\"{searchQuery}\"に対する結果はありません",
"FindBoardsDialog.NoResultsSubtext": "スペルを確認し、再度検索してください。",
"FindBoardsDialog.SubTitle": "ボードを検索するために文字を入力してください。<b>UP/DOWN</b>で閲覧、<b>ENTER</b>で選択、<b>ESC</b>でキャンセル",
"FindBoardsDialog.Title": "ボードを探す",
"GalleryCard.copiedLink": "コピーしました!",
"GalleryCard.copyLink": "リンクをコピー",
"GalleryCard.delete": "削除",
@ -134,9 +142,7 @@
"KanbanCard.delete": "削除",
"KanbanCard.duplicate": "複製",
"KanbanCard.untitled": "無題",
"Mutator.duplicate-board": "ボードを複製する",
"Mutator.new-card-from-template": "テンプレートから新しいカードを作成",
"Mutator.new-template-from-board": "ボードから新しいテンプレートを作成",
"Mutator.new-template-from-card": "カードから新しいテンプレートを作成",
"OnboardingTour.AddComments.Body": "問題にコメントしたり、仲間のMattermostユーザーの注意を引くために@メンションすることもできます。",
"OnboardingTour.AddComments.Title": "コメントを追加する",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "コピーしました!",
"ShareBoard.copyLink": "リンクをコピーする",
"ShareBoard.regenerate": "トークンを再生成する",
"ShareBoard.teamPermissionsText": "{teamName}チームの全員",
"ShareBoard.tokenRegenrated": "トークンが再生成されました",
"ShareBoard.userPermissionsRemoveMemberText": "メンバーを削除する",
"ShareBoard.userPermissionsYouText": "(あなた)",
"Sidebar.about": "Focalboardについて",
"Sidebar.add-board": "+ ボードを追加する",
"Sidebar.changePassword": "パスワードを変更する",
"Sidebar.delete-board": "ボードを削除",
"Sidebar.duplicate-board": "ボードを複製する",
"Sidebar.export-archive": "エクスポート",
"Sidebar.import": "インポート",
"Sidebar.import-archive": "インポート",
"Sidebar.invite-users": "ユーザーを招待する",
"Sidebar.logout": "ログアウト",
"Sidebar.no-more-workspaces": "他のワークスペースがありません",
"Sidebar.no-views-in-board": "ページがありません",
"Sidebar.no-boards-in-category": "カテゴリ内にボードがありません",
"Sidebar.random-icons": "ランダムアイコン",
"Sidebar.set-language": "言語設定",
"Sidebar.set-theme": "テーマ設定",
"Sidebar.settings": "設定",
"Sidebar.template-from-board": "ボードから新しいテンプレートを作成",
"Sidebar.untitled-board": "(無題のボード)",
"Sidebar.untitled-view": "(無題のビュー)",
"SidebarCategories.BlocksMenu.Move": "移動...",
"SidebarCategories.CategoryMenu.CreateNew": "新しいカテゴリを作成する",
"SidebarCategories.CategoryMenu.Delete": "カテゴリを削除する",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "<b>{categoryName}</b> にあるボードは、Boards カテゴリに戻されます。どのボードからも削除されることはありません。",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "このカテゴリを削除しますか?",
"SidebarCategories.CategoryMenu.Update": "カテゴリ名を変更する",
"TableComponent.add-icon": "アイコンを追加する",
"TableComponent.name": "名前",
"TableComponent.plus-new": "+ 新規",
@ -282,6 +293,7 @@
"login.register-button": "アカウントをお持ちでない方はアカウントを作成してください",
"register.login-button": "または、すでにアカウントをお持ちの方はログインしてください",
"register.signup-title": "アカウント登録",
"shareBoard.lastAdmin": "ボードには少なくとも1名の管理者が必要です",
"tutorial_tip.finish_tour": "完了",
"tutorial_tip.got_it": "了解",
"tutorial_tip.ok": "次へ",

View File

@ -86,11 +86,6 @@
"ContentBlock.moveDown": "Түсіру",
"ContentBlock.moveUp": "Көтеру",
"ContentBlock.text": "мәтін",
"DashboardPage.CenterPanel.ChangeChannels": "Арналарды оңай өзгерту үшін ауыстырғышты қолданыныз",
"DashboardPage.CenterPanel.NoWorkspaces": "Кешіріңіз, біз бұл термінге сәйкес ешбір арнаны таба алмадық",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Басқа термінді іздеп көрініз",
"DashboardPage.showEmpty": "Босты көрсету",
"DashboardPage.title": "Дашборт",
"DeleteBoardDialog.confirm-cancel": "Болдырмау",
"DeleteBoardDialog.confirm-delete": "Жою",
"DeleteBoardDialog.confirm-info": "\"{boardTitle}\" тақтасын шынымен жойғыңыз келе ме? Оны жою тақтадағы барлық кәртелерді жояды.",
@ -116,9 +111,7 @@
"KanbanCard.delete": "Жою",
"KanbanCard.duplicate": "Көшірмесін жасау",
"KanbanCard.untitled": "Атаусыз",
"Mutator.duplicate-board": "тақта көшірмесін жасау",
"Mutator.new-card-from-template": "үлгіден жаңа кәрте жасау",
"Mutator.new-template-from-board": "тақтадан жаңа үлгі",
"Mutator.new-template-from-card": "кәртеден жаңа үлгі",
"PropertyMenu.Delete": "Жою",
"PropertyMenu.changeType": "Property түрін өзгерту",
@ -154,20 +147,15 @@
"Sidebar.add-board": "+ Тақта қосу",
"Sidebar.changePassword": "Кілтсөзді өзгерту",
"Sidebar.delete-board": "Тақтаны жою",
"Sidebar.duplicate-board": "Тақтанын көшірмесін жасау",
"Sidebar.export-archive": "Мұрағатты экспорттау",
"Sidebar.import-archive": "Мұрағатты импорттау",
"Sidebar.invite-users": "Қолданушыларды шақыру",
"Sidebar.logout": "Шығу",
"Sidebar.no-more-workspaces": "Басқа workspace жоқ",
"Sidebar.no-views-in-board": "Ішінде беттер жоқ",
"Sidebar.random-icons": "Рандом икондар",
"Sidebar.set-language": "Тілді таңдау",
"Sidebar.set-theme": "Теміні орнату",
"Sidebar.settings": "Баптаулар",
"Sidebar.template-from-board": "Тақтадан жаңа үлгі жасау",
"Sidebar.untitled-board": "(Атаусыз Тақта)",
"Sidebar.untitled-view": "(Атаусыз Көрініс)",
"TableComponent.add-icon": "Иконды қосу",
"TableComponent.name": "Атауы",
"TableComponent.plus-new": "+ Қосу",

View File

@ -100,11 +100,6 @@
"ContentBlock.moveDown": "아래로 이동하기",
"ContentBlock.moveUp": "위로 이동하기",
"ContentBlock.text": "텍스트",
"DashboardPage.CenterPanel.ChangeChannels": "채널을 쉽게 바꾸기 위해 전환기를 사용하세요",
"DashboardPage.CenterPanel.NoWorkspaces": "죄송합니다. 해당 단어와 일치하는 채널을 찾을 수 없습니다",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "다른 단어로 검색해보세요",
"DashboardPage.showEmpty": "빈칸 표시",
"DashboardPage.title": "대시보드",
"DeleteBoardDialog.confirm-cancel": "취소",
"DeleteBoardDialog.confirm-delete": "삭제",
"DeleteBoardDialog.confirm-info": "“{boardTitle}” 보드를 삭제하시겠습니까? 이 보드에 있는 모든 카드들이 삭제됩니다.",
@ -131,9 +126,7 @@
"KanbanCard.delete": "삭제",
"KanbanCard.duplicate": "복제",
"KanbanCard.untitled": "제목 없음",
"Mutator.duplicate-board": "보드 복제",
"Mutator.new-card-from-template": "템플릿에서 새 카드 만들기",
"Mutator.new-template-from-board": "보드에서 새 템플릿 만들기",
"Mutator.new-template-from-card": "카드에서 새 템플릿 만들기",
"PropertyMenu.Delete": "삭제",
"PropertyMenu.changeType": "속성 유형 변경",
@ -169,20 +162,15 @@
"Sidebar.add-board": "+ 보드 추가",
"Sidebar.changePassword": "패스워드 변경",
"Sidebar.delete-board": "보드 삭제",
"Sidebar.duplicate-board": "보드 복제",
"Sidebar.export-archive": "아카이브 내보내기",
"Sidebar.import-archive": "아카이브 들여오기",
"Sidebar.invite-users": "사용자 초대",
"Sidebar.logout": "로그아웃",
"Sidebar.no-more-workspaces": "더 이상 작업 공간이 없습니다",
"Sidebar.no-views-in-board": "페이지가 없습니다",
"Sidebar.random-icons": "임의 아이콘",
"Sidebar.set-language": "언어 설정",
"Sidebar.set-theme": "테마 설정",
"Sidebar.settings": "설정",
"Sidebar.template-from-board": "보드에서 새 템플릿 만들기",
"Sidebar.untitled-board": "(제목 없는 보드)",
"Sidebar.untitled-view": "(제목 없는 뷰)",
"TableComponent.add-icon": "아이콘 추가",
"TableComponent.name": "이름",
"TableComponent.plus-new": "+ 생성",

View File

@ -7,6 +7,8 @@
"BoardComponent.no-property": "ഇല്ല {property}",
"BoardComponent.no-property-title": "ശൂന്യമായ {property} പ്രോപ്പർട്ടി ഉള്ള ഇനങ്ങൾ ഇവിടെ പോകും. ഈ കോളം നീക്കം ചെയ്യാൻ കഴിയില്ല.",
"BoardComponent.show": "കാണിക്കുക",
"BoardMember.schemeAdmin": "അഡ്മിൻ",
"BoardMember.schemeEditor": "എഡിറ്റർ",
"BoardPage.newVersion": "ബോർഡുകളുടെ ഒരു പുതിയ പതിപ്പ് ലഭ്യമാണ്, റീലോഡ് ചെയ്യാൻ ഇവിടെ ക്ലിക്ക് ചെയ്യുക.",
"BoardPage.syncFailed": "ബോർഡ് ഇല്ലാതാക്കുകയോ ആക്സസ് റദ്ദാക്കുകയോ ചെയ്യാം.",
"BoardTemplateSelector.add-template": "പുതിയ ടെംപ്ലേറ്റ്",
@ -81,6 +83,9 @@
"CardDialog.delete-confirmation-dialog-heading": "കാർഡ് ഇല്ലാതാക്കൽ സ്ഥിരീകരിക്കുക!",
"CardDialog.editing-template": "നിങ്ങൾ ഒരു ടെംപ്ലേറ്റ് എഡിറ്റ് ചെയ്യുകയാണ്.",
"CardDialog.nocard": "ഈ കാർഡ് നിലവിലില്ല അല്ലെങ്കിൽ ആക്സസ് ചെയ്യാനാകുന്നില്ല.",
"Categories.CreateCategoryDialog.CancelText": "റദ്ദാക്കുക",
"Categories.CreateCategoryDialog.CreateText": "സൃഷ്ടിക്കുക",
"Categories.CreateCategoryDialog.UpdateText": "അപ്ഡേറ്റ് ചെയ്യുക",
"CenterPanel.Share": "പങ്കിടുക",
"ColorOption.selectColor": "നിറം {color} തിരഞ്ഞെടുക്കുക",
"Comment.delete": "ഇല്ലാതാക്കുക",
@ -101,11 +106,6 @@
"ContentBlock.moveDown": "താഴേക്ക് നീക്കുക",
"ContentBlock.moveUp": "മുകളിലേക്കു നീക്കുക",
"ContentBlock.text": "വാചകം",
"DashboardPage.CenterPanel.ChangeChannels": "ചാനലുകൾ എളുപ്പത്തിൽ മാറ്റാൻ സ്വിച്ചർ ഉപയോഗിക്കുക",
"DashboardPage.CenterPanel.NoWorkspaces": "ക്ഷമിക്കണം, ആ പദവുമായി പൊരുത്തപ്പെടുന്ന ചാനലുകളൊന്നും കണ്ടെത്താൻ ഞങ്ങൾക്ക് കഴിഞ്ഞില്ല",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "ദയവായി മറ്റൊരു പദത്തിനായി തിരയാൻ ശ്രമിക്കുക",
"DashboardPage.showEmpty": "ശൂന്യമായി കാണിക്കുക",
"DashboardPage.title": "ഡാഷ്ബോർഡ്",
"DeleteBoardDialog.confirm-cancel": "നിര്‍ത്തലാക്കുക",
"DeleteBoardDialog.confirm-delete": "നീക്കം ചെയ്യുക",
"DeleteBoardDialog.confirm-info": "\"{boardTitle}\" എന്ന ബോർഡ് ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ? ഇത് ഇല്ലാതാക്കുന്നത് ബോർഡിലെ എല്ലാ കാർഡുകളും ഇല്ലാതാക്കും.",
@ -134,9 +134,7 @@
"KanbanCard.delete": "ഇല്ലാതാക്കുക",
"KanbanCard.duplicate": "തനിപ്പകർപ്പ്",
"KanbanCard.untitled": "ശീർഷകമില്ലാത്തത്",
"Mutator.duplicate-board": "ബോർഡിൻറെ തനിപ്പകർപ്പ്",
"Mutator.new-card-from-template": "ടെംപ്ലേറ്റിൽ നിന്നുള്ള പുതിയ കാർഡ്",
"Mutator.new-template-from-board": "ബോർഡിൽ നിന്നുള്ള പുതിയ ടെംപ്ലേറ്റ്",
"Mutator.new-template-from-card": "കാർഡിൽ നിന്നുള്ള പുതിയ ടെംപ്ലേറ്റ്",
"OnboardingTour.AddComments.Body": "നിങ്ങൾക്ക് പ്രശ്‌നങ്ങളിൽ അഭിപ്രായമിടാം, ഒപ്പം നിങ്ങളുടെ സഹ മാറ്റർമോസ് ഉപയോക്താക്കളെ അവരുടെ ശ്രദ്ധ ആകർഷിക്കാൻ അവരെ @പരാമർശിക്കുകയും ചെയ്യാം.",
"OnboardingTour.AddComments.Title": "അഭിപ്രായങ്ങൾ ചേർക്കുക",
@ -190,21 +188,16 @@
"Sidebar.add-board": "+ ബോർഡ് ചേർക്കുക",
"Sidebar.changePassword": "പാസ്സ്‌വേഡ്‌ മാറ്റുക",
"Sidebar.delete-board": "ബോർഡ് നീക്കം ചെയ്യുക",
"Sidebar.duplicate-board": "ബോർഡിൻറെ തനിപ്പകർപ്പ്",
"Sidebar.export-archive": "ആർക്കൈവ് എക്സ്പോർട്ട് ചെയ്യുക",
"Sidebar.import": "ഇറക്കുമതി ചെയ്യുക",
"Sidebar.import-archive": "ആർക്കൈവ് ഇമ്പോർട്ട് ചെയ്യുക",
"Sidebar.invite-users": "ഉപയോക്താക്കളെ ക്ഷണിക്കുക",
"Sidebar.logout": "ലോഗ്ഔട്ട്",
"Sidebar.no-more-workspaces": "കൂടുതൽ വർക്ക്‌സ്‌പെയ്‌സുകളൊന്നുമില്ല",
"Sidebar.no-views-in-board": "അകത്ത് പേജുകളൊന്നുമില്ല",
"Sidebar.random-icons": "ക്രമരഹിതമായ ഐക്കണുകൾ",
"Sidebar.set-language": "ഭാഷ സജ്ജമാക്കുക",
"Sidebar.set-theme": "തീം സജ്ജമാക്കുക",
"Sidebar.settings": "ക്രമീകരണങ്ങൾ",
"Sidebar.template-from-board": "ബോർഡിൽ നിന്നുള്ള പുതിയ ടെംപ്ലേറ്റ്",
"Sidebar.untitled-board": "(പേരില്ലാത്ത ബോർഡ്)",
"Sidebar.untitled-view": "(ശീർഷകമില്ലാത്ത കാഴ്ച)",
"TableComponent.add-icon": "ഐക്കൺ ചേർക്കുക",
"TableComponent.name": "പേര്",
"TableComponent.plus-new": "+ പുതിയത്",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "Geen {property}",
"BoardComponent.no-property-title": "Items met een lege {property} eigenschap komen hier te staan. Deze kolom kan niet worden verwijderd.",
"BoardComponent.show": "Toon",
"BoardMember.schemeAdmin": "Beheerder",
"BoardMember.schemeEditor": "Bewerker",
"BoardMember.schemeNone": "Geen",
"BoardPage.newVersion": "Er is een nieuwe versie van Boards, klik hier om te herladen.",
"BoardPage.syncFailed": "Het bord kan worden verwijderd of de toegang kan worden ingetrokken.",
"BoardTemplateSelector.add-template": "Nieuw sjabloon",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Verwijderen",
"BoardTemplateSelector.description": "Kies een sjabloon om je op weg te helpen. Pas het sjabloon eenvoudig aan jouw behoeften aan, of maak een leeg bord om vanaf nul te beginnen.",
"BoardTemplateSelector.edit-template": "Bewerken",
"BoardTemplateSelector.plugin.no-content-description": "Voeg een bord toe aan de zijbalk met behulp van een van de sjablonen die hieronder zijn gedefinieerd of begin vanaf nul.{lineBreak} Leden van \"{workspaceName}\" hebben toegang tot de boards die hier gemaakt zijn.",
"BoardTemplateSelector.plugin.no-content-title": "Maak een Board in {workspaceName}",
"BoardTemplateSelector.plugin.no-content-description": "Voeg een bord toe aan de zijbalk door gebruik te maken van één van de sjablonen die hieronder zijn gedefinieerd of begin vanaf nul.{lineBreak} Leden van \"{teamName}\" zullen toegang hebben tot de boards die hier zijn gemaakt.",
"BoardTemplateSelector.plugin.no-content-title": "Maak een Board in {teamName}",
"BoardTemplateSelector.title": "Maak een Board",
"BoardTemplateSelector.use-this-template": "Gebruik dit sjabloon",
"BoardsSwitcher.Title": "Boards vinden",
"BoardsUnfurl.Remainder": "+{remainder} meer",
"BoardsUnfurl.Updated": "Bijgewerkt {time}",
"Calculations.Options.average.displayName": "Gemiddeld",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "Bevestig kaart verwijderen!",
"CardDialog.editing-template": "Je bent een sjabloon aan het bewerken.",
"CardDialog.nocard": "Deze kaart bestaat niet of is ontoegankelijk.",
"Categories.CreateCategoryDialog.CancelText": "Annuleren",
"Categories.CreateCategoryDialog.CreateText": "Aanmaken",
"Categories.CreateCategoryDialog.Placeholder": "Geef je categorie een naam",
"Categories.CreateCategoryDialog.UpdateText": "Bijwerken",
"CenterPanel.Share": "Delen",
"ColorOption.selectColor": "Selecteer {color} Kleur",
"Comment.delete": "Verwijderen",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "Naar beneden verplaatsen",
"ContentBlock.moveUp": "Naar boven verplaatsen",
"ContentBlock.text": "tekst",
"DashboardPage.CenterPanel.ChangeChannels": "Gebruik de wisselaar om gemakkelijk van kanaal te veranderen",
"DashboardPage.CenterPanel.NoWorkspaces": "Sorry, we konden geen kanalen vinden die aan deze term voldoen",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Probeer op een andere term te zoeken",
"DashboardPage.showEmpty": "Leeg tonen",
"DashboardPage.title": "Dashboard",
"DeleteBoardDialog.confirm-cancel": "Annuleren",
"DeleteBoardDialog.confirm-delete": "Verwijderen",
"DeleteBoardDialog.confirm-info": "Weet je zeker dat u het bord \"{boardTitle}\" wil verwijderen? Het verwijderen van het bord zal alle kaarten in het bord verwijderen.",
@ -121,6 +124,11 @@
"Filter.not-includes": "bevat niet",
"FilterComponent.add-filter": "+ Filter toevoegen",
"FilterComponent.delete": "Verwijderen",
"FindBoFindBoardsDialog.IntroText": "Zoeken naar borden",
"FindBoardsDialog.NoResultsFor": "Geen resultaten voor \"{searchQuery}\"",
"FindBoardsDialog.NoResultsSubtext": "Controleer de spelling of probeer een andere zoekopdracht.",
"FindBoardsDialog.SubTitle": "Typ om een bord te vinden. Gebruik <b>UP/DOWN</b> om te bladeren. <b>ENTER</b> om te selecteren, <b>ESC</b> om te annuleren",
"FindBoardsDialog.Title": "Boards vinden",
"GalleryCard.copiedLink": "Gekopieerd!",
"GalleryCard.copyLink": "Kopieer link",
"GalleryCard.delete": "Verwijderen",
@ -134,9 +142,7 @@
"KanbanCard.delete": "Verwijderen",
"KanbanCard.duplicate": "Kopiëren",
"KanbanCard.untitled": "Titelloos",
"Mutator.duplicate-board": "bord kopiëren",
"Mutator.new-card-from-template": "nieuwe kaart van sjabloon",
"Mutator.new-template-from-board": "nieuw sjabloon van bord",
"Mutator.new-template-from-card": "nieuw sjabloon van kaart",
"OnboardingTour.AddComments.Body": "Je kunt commentaar geven op onderwerpen, en zelfs je medeMattermostgebruikers @vermelden om hun aandacht te trekken.",
"OnboardingTour.AddComments.Title": "Opmerkingen toevoegen",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "Gekopieerd!",
"ShareBoard.copyLink": "Link kopiëren",
"ShareBoard.regenerate": "Token opnieuw genereren",
"ShareBoard.teamPermissionsText": "Iedereen van team {teamName}",
"ShareBoard.tokenRegenrated": "Token opnieuw gegenereerd",
"ShareBoard.userPermissionsRemoveMemberText": "Lid verwijderen",
"ShareBoard.userPermissionsYouText": "(jij)",
"Sidebar.about": "Over Focalboard",
"Sidebar.add-board": "+ Bord toevoegen",
"Sidebar.changePassword": "Wachtwoord wijzigen",
"Sidebar.delete-board": "Verwijder bord",
"Sidebar.duplicate-board": "Bord kopiëren",
"Sidebar.export-archive": "Archief exporteren",
"Sidebar.import": "Importeren",
"Sidebar.import-archive": "Archief importeren",
"Sidebar.invite-users": "Gebruikers uitnodigen",
"Sidebar.logout": "Afmelden",
"Sidebar.no-more-workspaces": "Geen werkruimtes meer",
"Sidebar.no-views-in-board": "Geen pagina's binnenin",
"Sidebar.no-boards-in-category": "Geen boards hier",
"Sidebar.random-icons": "Willekeurige iconen",
"Sidebar.set-language": "Taal instellen",
"Sidebar.set-theme": "Thema instellen",
"Sidebar.settings": "Instellingen",
"Sidebar.template-from-board": "Nieuw sjabloon van bord",
"Sidebar.untitled-board": "(Titelloze bord )",
"Sidebar.untitled-view": "(Titelloze weergave)",
"SidebarCategories.BlocksMenu.Move": "Verplaatsen naar...",
"SidebarCategories.CategoryMenu.CreateNew": "Maak een nieuwe categorie",
"SidebarCategories.CategoryMenu.Delete": "Categorie verwijderen",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "Borden in <b>{categoryName}</b> zullen terug verhuizen naar de Boards categorieën. Je zal niet verwijderd worden uit enig board.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Deze categorie verwijderen?",
"SidebarCategories.CategoryMenu.Update": "Categorie hernoemen",
"TableComponent.add-icon": "Pictogram toevoegen",
"TableComponent.name": "Naam",
"TableComponent.plus-new": "+ Nieuw",
@ -261,7 +272,7 @@
"WelcomePage.Description": "Boards is een projectmanagementtool die helpt bij het definiëren, organiseren, volgen en beheren van werk door teams heen, met behulp van een bekende kanban-bordweergave",
"WelcomePage.Explore.Button": "Start een rondleiding",
"WelcomePage.Heading": "Welkom bij Boards",
"WelcomePage.NoThanks.Text": "Nee bedankt, ik zoek het zelf wel uit.",
"WelcomePage.NoThanks.Text": "Nee bedankt, ik zoek het zelf wel uit",
"Workspace.editing-board-template": "Je bent een bordsjabloon aan het bewerken.",
"calendar.month": "Maand",
"calendar.today": "VANDAAG",
@ -282,6 +293,7 @@
"login.register-button": "of maak een account aan als je er nog geen hebt",
"register.login-button": "of meldt je aan als je al een account hebt",
"register.signup-title": "Maak een nieuw account",
"shareBoard.lastAdmin": "Besturen moeten ten minste één beheerder hebben",
"tutorial_tip.finish_tour": "Klaar",
"tutorial_tip.got_it": "Begrepen",
"tutorial_tip.ok": "Volgende",

View File

@ -40,11 +40,6 @@
"ContentBlock.moveDown": "Desplaçar al dejós",
"ContentBlock.moveUp": "Desplaçar al dessús",
"ContentBlock.text": "tèxt",
"DashboardPage.CenterPanel.ChangeChannels": "Utilizatz l’alternator per cambiar facilament de cadenas",
"DashboardPage.CenterPanel.NoWorkspaces": "O planhèm, avèm pas trobat cap de cadena correspondenta al tèrme",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Mercés d’ensajar d’autres tèrmes",
"DashboardPage.showEmpty": "Mostrar void",
"DashboardPage.title": "Tablèu de bòrd",
"Dialog.closeDialog": "Tampar la fenèstra de dialòg",
"EditableDayPicker.today": "Uèi",
"Error.websocket-closed": "Connexion al websocket tampada, connexion interrompuda. S’aquò ten de se produire, verificatz la configuracion del servidor o del servidor mandatari.",
@ -65,9 +60,7 @@
"KanbanCard.delete": "Suprimir",
"KanbanCard.duplicate": "Duplicar",
"KanbanCard.untitled": "Sens títol",
"Mutator.duplicate-board": "duplicar lo tablèu",
"Mutator.new-card-from-template": "zòna novèla a partir d’un modèl",
"Mutator.new-template-from-board": "modèl novèl a parti d’un tablèu",
"Mutator.new-template-from-card": "modèl novèl a partir d’una zòna",
"PropertyMenu.Delete": "Suprimir",
"PropertyMenu.changeType": "Modificar lo tipe de proprietat",
@ -103,20 +96,15 @@
"Sidebar.add-board": "+ Apondre un tablèu",
"Sidebar.changePassword": "Modificar lo senhal",
"Sidebar.delete-board": "Suprimir lo tablèu",
"Sidebar.duplicate-board": "Duplicar lo tablèu",
"Sidebar.export-archive": "Exportar un archiu",
"Sidebar.import-archive": "Importar un archiu",
"Sidebar.invite-users": "Convidar utilizaires",
"Sidebar.logout": "Se desconnectar",
"Sidebar.no-more-workspaces": "Pas mai d’espaci de trabalh",
"Sidebar.no-views-in-board": "Cap de pagina pas inclusa",
"Sidebar.random-icons": "Icònas aleatòrias",
"Sidebar.set-language": "Definir la lenga",
"Sidebar.set-theme": "Causir lo tèma",
"Sidebar.settings": "Paramètres",
"Sidebar.template-from-board": "Modèl novèl a partir del tablèu",
"Sidebar.untitled-board": "(Tablèu sens títol)",
"Sidebar.untitled-view": "(Vista sens títol)",
"TableComponent.add-icon": "Apondre una icòna",
"TableComponent.name": "Nom",
"TableComponent.plus-new": "+ Novèl",

View File

@ -101,11 +101,6 @@
"ContentBlock.moveDown": "Przesuń w dół",
"ContentBlock.moveUp": "Przesuń do góry",
"ContentBlock.text": "tekst",
"DashboardPage.CenterPanel.ChangeChannels": "Użyj przełącznika, aby łatwo zmieniać kanały",
"DashboardPage.CenterPanel.NoWorkspaces": "Niestety, nie znaleźliśmy żadnych kanałów pasujących do tej frazy",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Proszę spróbować wyszukać inną frazę",
"DashboardPage.showEmpty": "Pokaż puste",
"DashboardPage.title": "Tablica",
"DeleteBoardDialog.confirm-cancel": "Anuluj",
"DeleteBoardDialog.confirm-delete": "Usuń",
"DeleteBoardDialog.confirm-info": "Czy na pewno chcesz usunąć tablicę \"{boardTitle}\"? Usunięcie jej spowoduje usunięcie wszystkich kart na tablicy.",
@ -126,16 +121,30 @@
"GalleryCard.delete": "Usuń",
"GalleryCard.duplicate": "Duplikuj",
"General.BoardCount": "{count, plural, one {# Tablica} other {# Tablice}}",
"GroupBy.hideEmptyGroups": "Ukryj {count} pustych grup",
"GroupBy.showHiddenGroups": "Pokaż {count} ukrytych grup",
"GroupBy.ungroup": "Rozgrupuj",
"KanbanCard.copiedLink": "Skopiowane!",
"KanbanCard.copyLink": "Kopiuj odnośnik",
"KanbanCard.delete": "Usuń",
"KanbanCard.duplicate": "Duplikuj",
"KanbanCard.untitled": "Bez tytułu",
"Mutator.duplicate-board": "duplikuj tablicę",
"Mutator.new-card-from-template": "nowa karta z szablonu",
"Mutator.new-template-from-board": "nowy szablon z tablicy",
"Mutator.new-template-from-card": "nowy szablon z karty",
"OnboardingTour.AddComments.Body": "Możesz komentować wydarzenia, a nawet @mention innych użytkowników Mattermost, aby zwrócić na siebie ich uwagę.",
"OnboardingTour.AddComments.Title": "Dodaj komentarze",
"OnboardingTour.AddDescription.Body": "Dodaj opis do swojej karty, aby koledzy z zespołu wiedzieli, czego ona dotyczy .",
"OnboardingTour.AddDescription.Title": "Dodaj opis",
"OnboardingTour.AddProperties.Body": "Dodawaj różne właściwości do kart, aby zwiększyć ich moc!",
"OnboardingTour.AddProperties.Title": "Dodaj właściwości",
"OnboardingTour.AddView.Body": "Przejdź tutaj, aby utworzyć nowy widok w celu uporządkowania tablicy przy użyciu różnych układów.",
"OnboardingTour.AddView.Title": "Dodaj nowy widok",
"OnboardingTour.CopyLink.Body": "Karty można udostępniać kolegom z zespołu, kopiując łącze i wklejając je w kanale, Wiadomości Bezpośredniej lub Wiadomości Grupowej.",
"OnboardingTour.CopyLink.Title": "Kopiuj odnośnik",
"OnboardingTour.OpenACard.Body": "Otwórz kartę, aby poznać różne sposoby, w których Tablice mogą pomóc Ci w organizacji pracy.",
"OnboardingTour.OpenACard.Title": "Otwórz kartę",
"OnboardingTour.ShareBoard.Body": "Możesz udostępniać swoją tablicę wewnętrznie, w ramach zespołu, lub publikować ją publicznie, aby była widoczna poza organizacją.",
"OnboardingTour.ShareBoard.Title": "Udostępnij tablicę",
"PropertyMenu.Delete": "Usuń",
"PropertyMenu.changeType": "Zmień typ właściwości",
"PropertyMenu.selectType": "Wybierz typ właściwości",
@ -174,20 +183,16 @@
"Sidebar.add-board": "+ Dodaj tablicę",
"Sidebar.changePassword": "Zmień hasło",
"Sidebar.delete-board": "Usuń tablicę",
"Sidebar.duplicate-board": "Duplikuj tablicę",
"Sidebar.export-archive": "Eksportuj archiwum",
"Sidebar.import": "Importuj",
"Sidebar.import-archive": "Importuj archiwum",
"Sidebar.invite-users": "Zaproś użytkowników",
"Sidebar.logout": "Wyloguj się",
"Sidebar.no-more-workspaces": "Nie ma więcej obszaru roboczego",
"Sidebar.no-views-in-board": "Brak stron wewnątrz",
"Sidebar.random-icons": "Losowe ikony",
"Sidebar.set-language": "Ustaw język",
"Sidebar.set-theme": "Ustaw motyw",
"Sidebar.settings": "Ustawienia",
"Sidebar.template-from-board": "Nowy szablon z tablicy",
"Sidebar.untitled-board": "(Tablica bez tytułu)",
"Sidebar.untitled-view": "(Widok bez Tytułu)",
"TableComponent.add-icon": "Dodaj Ikonę",
"TableComponent.name": "Nazwa",
"TableComponent.plus-new": "+ Nowy",
@ -242,18 +247,32 @@
"ViewTitle.show-description": "pokaż opis",
"ViewTitle.untitled-board": "Tablica bez tytułu",
"WelcomePage.Description": "Tablice to narzędzie do zarządzania projektami, które pomaga definiować, organizować, śledzić i zarządzać pracą w zespołach, wykorzystując widok znanych tablic kanban",
"WelcomePage.Explore.Button": "Poznaj",
"WelcomePage.Explore.Button": "Wybierz się na wycieczkę",
"WelcomePage.Heading": "Witamy w Tablicach",
"WelcomePage.NoThanks.Text": "Nie, dzięki, sam sobie z tym poradzę",
"Workspace.editing-board-template": "Edytujesz szablon tablicy.",
"calendar.month": "Miesiąc",
"calendar.today": "DZIŚ",
"calendar.week": "Tydzień",
"default-properties.badges": "Uwagi i opis",
"default-properties.title": "Tytuł",
"error.back-to-boards": "Powrót do tablic",
"error.back-to-home": "Powrót na stronę główną",
"error.go-login": "Zaloguj się",
"error.not-logged-in": "Być może Twoja sesja wygasła lub nie jesteś zalogowany.",
"error.page.title": "Przepraszam, coś poszło nie tak",
"error.relogin": "Zaloguj się ponownie",
"error.unknown": "Wystąpił błąd.",
"error.workspace-undefined": "Nie jest to prawidłowy obszar roboczy.",
"generic.previous": "Wstecz",
"login.log-in-button": "Zaloguj się",
"login.log-in-title": "Zaloguj się",
"login.register-button": "lub załóż konto, jeśli jeszcze go nie masz",
"register.login-button": "lub zaloguj się, jeśli masz już konto",
"register.signup-title": "Zarejestruj się na swoim koncie"
"register.signup-title": "Zarejestruj się na swoim koncie",
"tutorial_tip.finish_tour": "Gotowe",
"tutorial_tip.got_it": "Jasne",
"tutorial_tip.ok": "Dalej",
"tutorial_tip.out": "Zrezygnuj z tych porad",
"tutorial_tip.seen": "Widziałeś to wcześniej?"
}

View File

@ -32,7 +32,6 @@
"ContentBlock.moveDown": "Mover para baixo",
"ContentBlock.moveUp": "Mover para cima",
"ContentBlock.text": "texto",
"DashboardPage.title": "Welcome to Focalboard!",
"Dialog.closeDialog": "Fechar diálogo",
"EditableDayPicker.today": "Hoje",
"Error.websocket-closed": "Conexão Websocket fechada, conexão interrompida. Se isso persistir, verifique a configuração do seu servidor ou proxy da web.",
@ -48,9 +47,7 @@
"KanbanCard.delete": "Deletar",
"KanbanCard.duplicate": "Duplicar",
"KanbanCard.untitled": "Sem nome",
"Mutator.duplicate-board": "quadro duplicado",
"Mutator.new-card-from-template": "novo card à partir de um template",
"Mutator.new-template-from-board": "novo template à partir de um quadro",
"Mutator.new-template-from-card": "novo template à partir de um card",
"PropertyMenu.Delete": "Deletar",
"PropertyMenu.changeType": "Alterar tipo da propriedade",
@ -84,19 +81,15 @@
"Sidebar.add-board": "+ Adicionar Quadro",
"Sidebar.changePassword": "Mudar senha",
"Sidebar.delete-board": "Deletar quadro",
"Sidebar.duplicate-board": "Duplicar quadro",
"Sidebar.export-archive": "Exportar arquivo",
"Sidebar.import-archive": "Importar arquivo",
"Sidebar.invite-users": "Convidar Usuários",
"Sidebar.logout": "Sair",
"Sidebar.no-views-in-board": "Sem páginas dentro",
"Sidebar.random-icons": "Ícones aleatórios",
"Sidebar.set-language": "Definir linguagem",
"Sidebar.set-theme": "Definir tema",
"Sidebar.settings": "Configurações",
"Sidebar.template-from-board": "Novo modelo à partir do quadro",
"Sidebar.untitled-board": "(Quadro sem nome)",
"Sidebar.untitled-view": "(Vista sem nome)",
"TableComponent.add-icon": "Adicionar Ícone",
"TableComponent.name": "Nome",
"TableComponent.plus-new": "+ Novo",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "{property} пусто",
"BoardComponent.no-property-title": "Здесь будут элементы с пустым свойством {property}. Этот столбец не может быть удален.",
"BoardComponent.show": "Показать",
"BoardMember.schemeAdmin": "Администратор",
"BoardMember.schemeEditor": "Редактор",
"BoardMember.schemeNone": "Никто",
"BoardPage.newVersion": "Доступна новая версия Доски. Нажмите здесь, чтобы перезагрузить.",
"BoardPage.syncFailed": "Доска может быть удалена или доступ аннулирован.",
"BoardTemplateSelector.add-template": "Новый шаблон",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Удалить",
"BoardTemplateSelector.description": "Выберите шаблон, который поможет Вам начать работу. Легко настройте шаблон в соответствии со своими потребностями или создайте пустую доску, чтобы начать с нуля.",
"BoardTemplateSelector.edit-template": "Редактировать",
"BoardTemplateSelector.plugin.no-content-description": "Добавьте доску на боковую панель, используя любой из указанных ниже шаблонов, или начните с нуля.{lineBreak} Участники \"{workspaceName}\" будут иметь доступ к созданным здесь доскам.",
"BoardTemplateSelector.plugin.no-content-title": "Создать Доску в {workspaceName}",
"BoardTemplateSelector.plugin.no-content-description": "Добавьте доску на боковую панель, используя любой из указанных ниже шаблонов, или начните с нуля.{lineBreak} Участники \"{teamName}\" будут иметь доступ к созданным здесь доскам.",
"BoardTemplateSelector.plugin.no-content-title": "Создать доску в {teamName}",
"BoardTemplateSelector.title": "Создать Доску",
"BoardTemplateSelector.use-this-template": "Использовать этот шаблон",
"BoardsSwitcher.Title": "Найти доски",
"BoardsUnfurl.Remainder": "+{remainder} ещё",
"BoardsUnfurl.Updated": "Обновлено {time}",
"Calculations.Options.average.displayName": "Среднее",
@ -72,7 +76,7 @@
"CardDetailProperty.delete-action-button": "Удалить",
"CardDetailProperty.property-change-action-button": "Изменить свойство",
"CardDetailProperty.property-changed": "Свойство изменено успешно!",
"CardDetailProperty.property-deleted": "{PropertyName} успешно удалено!",
"CardDetailProperty.property-deleted": "{propertyName} успешно удалено!",
"CardDetailProperty.property-name-change-subtext": "тип из \"{oldPropType}\" в \"{newPropType}\"",
"CardDetailProperty.property-type-change-subtext": "название для \"{newPropName}\"",
"CardDialog.copiedLink": "Скопировано!",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "Подтвердите удаление карточки!",
"CardDialog.editing-template": "Вы редактируете шаблон.",
"CardDialog.nocard": "Эта карточка не существует или недоступна.",
"Categories.CreateCategoryDialog.CancelText": "Отмена",
"Categories.CreateCategoryDialog.CreateText": "Создать",
"Categories.CreateCategoryDialog.Placeholder": "Назовите свою категорию",
"Categories.CreateCategoryDialog.UpdateText": "Обновить",
"CenterPanel.Share": "Поделится",
"ColorOption.selectColor": "Выберите цвет {color}",
"Comment.delete": "Удалить",
@ -101,14 +109,9 @@
"ContentBlock.moveDown": "Опустить",
"ContentBlock.moveUp": "Поднять",
"ContentBlock.text": "текст",
"DashboardPage.CenterPanel.ChangeChannels": "Используйте переключатель, чтобы легко сменить каналы",
"DashboardPage.CenterPanel.NoWorkspaces": "К сожалению, мы не смогли найти ни одного канала, соответствующего этому термину",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Пожалуйста, попробуйте найти другой термин",
"DashboardPage.showEmpty": "Показать пустой",
"DashboardPage.title": "Панель управления",
"DeleteBoardDialog.confirm-cancel": "Отмена",
"DeleteBoardDialog.confirm-delete": "Удалить",
"DeleteBoardDialog.confirm-info": "Вы уверены, что хотите удалить доску \"{boardTitle}\"? Его удаление приведет к удалению всех карточек на доске.",
"DeleteBoardDialog.confirm-info": "Вы уверены, что хотите удалить доску \"{boardTitle}\"? Ее удаление приведет к удалению всех карточек на доске.",
"DeleteBoardDialog.confirm-tite": "Подтвердить удаление доски",
"DeleteBoardDialog.confirm-tite-template": "Подтвердите удаление шаблона Доски",
"Dialog.closeDialog": "Закрыть диалог",
@ -121,11 +124,16 @@
"Filter.not-includes": "не содержит",
"FilterComponent.add-filter": "+ Добавить фильтр",
"FilterComponent.delete": "Удалить",
"FindBoFindBoardsDialog.IntroText": "Поиск досок",
"FindBoardsDialog.NoResultsFor": "Нет результатов для \"{searchQuery}\"",
"FindBoardsDialog.NoResultsSubtext": "Проверьте правильность написания или попробуйте другой запрос.",
"FindBoardsDialog.SubTitle": "Введите запрос, чтобы найти доску. Используйте <b>ВВЕРХ/ВНИЗ</b> для просмотра. <b>ENTER</b> для выбора, <b>ESC</b> для закрытия",
"FindBoardsDialog.Title": "Найти доски",
"GalleryCard.copiedLink": "Скопировано!",
"GalleryCard.copyLink": "Копировать ссылку",
"GalleryCard.delete": "Удалить",
"GalleryCard.duplicate": "Создать дубликат",
"General.BoardCount": "{count, plural, one {# Доска} other {# Доски}}",
"General.BoardCount": "{count, plural, one {# Доска} few {# Доски} other {# Досок}}",
"GroupBy.hideEmptyGroups": "Скрыть {count} пустых групп",
"GroupBy.showHiddenGroups": "Показать {count} скрытых групп",
"GroupBy.ungroup": "Разгруппировать",
@ -134,9 +142,7 @@
"KanbanCard.delete": "Удалить",
"KanbanCard.duplicate": "Создать дубликат",
"KanbanCard.untitled": "Без названия",
"Mutator.duplicate-board": "сделать дубликат доски",
"Mutator.new-card-from-template": "новая карточка из шаблона",
"Mutator.new-template-from-board": "новый шаблон из доски",
"Mutator.new-template-from-card": "новый шаблон из карточки",
"OnboardingTour.AddComments.Body": "Вы можете комментировать проблемы и даже @упоминать своих коллег-пользователей Mattermost, чтобы привлечь их внимание.",
"OnboardingTour.AddComments.Title": "Добавить комментарии",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "Скопировано!",
"ShareBoard.copyLink": "Скопировать ссылку",
"ShareBoard.regenerate": "Восстановить токен",
"ShareBoard.teamPermissionsText": "Все в команде {teamName}",
"ShareBoard.tokenRegenrated": "Токен пересоздан",
"ShareBoard.userPermissionsRemoveMemberText": "Удалить участника",
"ShareBoard.userPermissionsYouText": "(Вы)",
"Sidebar.about": "О Focalboard",
"Sidebar.add-board": "+ Добавить доску",
"Sidebar.changePassword": "Изменить пароль",
"Sidebar.delete-board": "Удалить доску",
"Sidebar.duplicate-board": "Сделать дубликат доски",
"Sidebar.export-archive": "Экспорт архива",
"Sidebar.import": "Импорт",
"Sidebar.import-archive": "Импорт архива",
"Sidebar.invite-users": "Пригласить пользователей",
"Sidebar.logout": "Выйти",
"Sidebar.no-more-workspaces": "Рабочих пространств больше нет",
"Sidebar.no-views-in-board": "Внутри нет страниц",
"Sidebar.no-boards-in-category": "Без досок внутри",
"Sidebar.random-icons": "Случайные иконки",
"Sidebar.set-language": "Язык",
"Sidebar.set-theme": "Тема",
"Sidebar.settings": "Настройки",
"Sidebar.template-from-board": "Новый шаблон из доски",
"Sidebar.untitled-board": "(Доска без названия)",
"Sidebar.untitled-view": "(Вид без названия)",
"SidebarCategories.BlocksMenu.Move": "Перейти к...",
"SidebarCategories.CategoryMenu.CreateNew": "Создать новую категорию",
"SidebarCategories.CategoryMenu.Delete": "Удалить категорию",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "Доски в <b>{categoryName}</b> вернутся к категориям \"Доски\". Вы не удалены ни с одной доски.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Удалить эту категорию?",
"SidebarCategories.CategoryMenu.Update": "Переименовать категорию",
"TableComponent.add-icon": "Добавить иконку",
"TableComponent.name": "Название",
"TableComponent.plus-new": "+ Создать",
@ -282,6 +293,7 @@
"login.register-button": "или создать аккаунт, если у Вас его нет",
"register.login-button": "или войти в систему, если у вас уже есть аккаунт",
"register.signup-title": "Зарегистрируйте свой аккаунт",
"shareBoard.lastAdmin": "Доски должны иметь хотя бы одного администратора",
"tutorial_tip.finish_tour": "Готово",
"tutorial_tip.got_it": "Понятно",
"tutorial_tip.ok": "Следующий",

View File

@ -86,11 +86,6 @@
"ContentBlock.moveDown": "Presuň dole",
"ContentBlock.moveUp": "Presuň hore",
"ContentBlock.text": "text",
"DashboardPage.CenterPanel.ChangeChannels": "Na zmenu kanálov použite prepínač",
"DashboardPage.CenterPanel.NoWorkspaces": "Prepáčte, nenašli sa kanály s daným výrazom",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Skúste vyhľadať iný výraz",
"DashboardPage.showEmpty": "Zobraziť prázdne",
"DashboardPage.title": "Dashboard",
"DeleteBoardDialog.confirm-cancel": "Zrušiť",
"DeleteBoardDialog.confirm-delete": "Odstrániť",
"DeleteBoardDialog.confirm-info": "Naozaj chcete odstrániť nástenku “{boardTitle}”? Odstránením vymažete všetky karty na tabuli.",
@ -116,9 +111,7 @@
"KanbanCard.delete": "Odstrániť",
"KanbanCard.duplicate": "Duplikuj",
"KanbanCard.untitled": "Nepomenované",
"Mutator.duplicate-board": "duplikuj nástenku",
"Mutator.new-card-from-template": "nová karta z template-u",
"Mutator.new-template-from-board": "nový template z nástenky",
"Mutator.new-template-from-card": "nový template z karty",
"PropertyMenu.Delete": "Odstrániť",
"PropertyMenu.changeType": "Zmeniť vlastnosť",
@ -154,20 +147,15 @@
"Sidebar.add-board": "+ Pridať nástenku",
"Sidebar.changePassword": "Zmeniť heslo",
"Sidebar.delete-board": "Odstrániť nástenku",
"Sidebar.duplicate-board": "Duplikuj nástenku",
"Sidebar.export-archive": "Export archívu",
"Sidebar.import-archive": "Import archívu",
"Sidebar.invite-users": "Pozvať užívateľa",
"Sidebar.logout": "Odhlásiť sa",
"Sidebar.no-more-workspaces": "Žiadne miesta",
"Sidebar.no-views-in-board": "Bez obsahu",
"Sidebar.random-icons": "Náhodné ikony",
"Sidebar.set-language": "Nastaviť jazyk",
"Sidebar.set-theme": "Nastaviť tému",
"Sidebar.settings": "nastavenia",
"Sidebar.template-from-board": "Nový template z nástenky",
"Sidebar.untitled-board": "(nástenka bez názvu)",
"Sidebar.untitled-view": "(náhľad bez názvu)",
"TableComponent.add-icon": "Pridať ikonu",
"TableComponent.name": "názov",
"TableComponent.plus-new": "+ Nový",

View File

@ -80,11 +80,6 @@
"ContentBlock.moveDown": "Flytta ned",
"ContentBlock.moveUp": "Flytta upp",
"ContentBlock.text": "text",
"DashboardPage.CenterPanel.ChangeChannels": "Använd kanalväljaren för att smidigt växla mellan kanaler",
"DashboardPage.CenterPanel.NoWorkspaces": "Tyvärr hittade vi inga kanaler som matchar den termen",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Försök att söka efter en annan term",
"DashboardPage.showEmpty": "Visa tomma",
"DashboardPage.title": "Dashboard",
"DeleteBoardDialog.confirm-cancel": "Avbryt",
"DeleteBoardDialog.confirm-delete": "Radera",
"DeleteBoardDialog.confirm-info": "Är du säker på att du vill ta bort tavlan “{boardTitle}”? När du tar bort den kommer du radera alla kort på tavlan.",
@ -108,11 +103,9 @@
"KanbanCard.copiedLink": "Kopierad!",
"KanbanCard.copyLink": "Kopiera länk",
"KanbanCard.delete": "Radera",
"KanbanCard.duplicate": "Radera",
"KanbanCard.duplicate": "Kopiera",
"KanbanCard.untitled": "Saknar titel",
"Mutator.duplicate-board": "duplicera tavla",
"Mutator.new-card-from-template": "nytt kort från mall",
"Mutator.new-template-from-board": "ny mall från tavla",
"Mutator.new-template-from-card": "ny mall från kort",
"PropertyMenu.Delete": "Radera",
"PropertyMenu.changeType": "Ändra egenskapstyp",
@ -148,20 +141,15 @@
"Sidebar.add-board": "+ Lägg till tavla",
"Sidebar.changePassword": "Ändra lösenord",
"Sidebar.delete-board": "Radera tavla",
"Sidebar.duplicate-board": "Duplicera tavla",
"Sidebar.export-archive": "Exportera arkiv",
"Sidebar.import-archive": "Importera arkiv",
"Sidebar.invite-users": "Bjud in användare",
"Sidebar.logout": "Logga ut",
"Sidebar.no-more-workspaces": "Inga fler arbetsytor",
"Sidebar.no-views-in-board": "Inga vyer på tavla",
"Sidebar.random-icons": "Slumpmässiga ikoner",
"Sidebar.set-language": "Välj språk",
"Sidebar.set-theme": "Välj tema",
"Sidebar.settings": "Inställningar",
"Sidebar.template-from-board": "Ny mall från tavla",
"Sidebar.untitled-board": "(Tavla saknar titel)",
"Sidebar.untitled-view": "(Vy saknar titel)",
"TableComponent.add-icon": "Lägg till ikon",
"TableComponent.name": "Namn",
"TableComponent.plus-new": "+ Ny",
@ -213,7 +201,7 @@
"ViewTitle.show-description": "visa beskrivning",
"ViewTitle.untitled-board": "Tavla saknar titel",
"WelcomePage.Description": "Anslagstavlan är ett projekthanteringsverktyg som hjälper till att definiera, organisera, spåra och hantera arbete mellan team med hjälp av en välbekant Kanban-vy",
"WelcomePage.Explore.Button": "Utforska",
"WelcomePage.Explore.Button": "Starta en rundtur",
"WelcomePage.Heading": "Välkommen till Anslagstavlan",
"Workspace.editing-board-template": "Du redigerar en tavelmall.",
"calendar.month": "Månad",

View File

@ -7,6 +7,9 @@
"BoardComponent.no-property": "{property} yok",
"BoardComponent.no-property-title": "{property} alanı boş olan ögeler buraya atanır. Bu sütun silinemez.",
"BoardComponent.show": "Görüntüle",
"BoardMember.schemeAdmin": "Yönetici",
"BoardMember.schemeEditor": "Düzenleyici",
"BoardMember.schemeNone": "Yok",
"BoardPage.newVersion": "Yeni bir pano sürümü yayınlanmış. Yeniden yüklemek için buraya tıklayın.",
"BoardPage.syncFailed": "Pano silinmiş ya da erişim izni geri alınmış olabilir.",
"BoardTemplateSelector.add-template": "Yeni kalıp",
@ -14,10 +17,11 @@
"BoardTemplateSelector.delete-template": "Sil",
"BoardTemplateSelector.description": "Başlamanıza yardımcı olacak bir kalıp seçin. Kalıbı gereksinimlerinize göre kolayca özelleştirin ya da sıfırdan başlamak için boş bir pano oluşturun.",
"BoardTemplateSelector.edit-template": "Düzenle",
"BoardTemplateSelector.plugin.no-content-description": "Aşağıda tanımlanan kalıplardan herhangi birini kullanarak yan çubuğa bir pano ekleyin ya da sıfırdan başlayın.{lineBreak} \"{workspaceName}\" üyeleri burada oluşturulan panolara erişebilecek.",
"BoardTemplateSelector.plugin.no-content-title": "{workspaceName} çalışma alanında bir pano oluştur",
"BoardTemplateSelector.plugin.no-content-description": "Aşağıda tanımlanan kalıplardan herhangi birini kullanarak yan çubuğa bir pano ekleyin ya da sıfırdan başlayın.{lineBreak} \"{teamName}\" üyeleri burada oluşturulan panolara erişebilecek.",
"BoardTemplateSelector.plugin.no-content-title": "{teamName} çalışma alanında bir pano oluştur",
"BoardTemplateSelector.title": "Bir pano oluştur",
"BoardTemplateSelector.use-this-template": "Bu kalıp kullanılsın",
"BoardsSwitcher.Title": "Pano arama",
"BoardsUnfurl.Remainder": "+{remainder} diğer",
"BoardsUnfurl.Updated": "Güncellenme: {time}",
"Calculations.Options.average.displayName": "Ortalama",
@ -81,6 +85,10 @@
"CardDialog.delete-confirmation-dialog-heading": "Kartı silmeyi onaylayın!",
"CardDialog.editing-template": "Bir kalıbı düzenliyorsunuz.",
"CardDialog.nocard": "Bu kart bulunamadı ya da erişilebilir değil.",
"Categories.CreateCategoryDialog.CancelText": "İptal",
"Categories.CreateCategoryDialog.CreateText": "Ekle",
"Categories.CreateCategoryDialog.Placeholder": "Kategorinize bir ad verin",
"Categories.CreateCategoryDialog.UpdateText": "Güncelle",
"CenterPanel.Share": "Paylaş",
"ColorOption.selectColor": "{color} rengi seçin",
"Comment.delete": "Sil",
@ -101,11 +109,6 @@
"ContentBlock.moveDown": "Alta taşı",
"ContentBlock.moveUp": "Üste taşı",
"ContentBlock.text": "metin",
"DashboardPage.CenterPanel.ChangeChannels": "Kanalları kolayca değiştirmek için değiştiriciyi kullanın",
"DashboardPage.CenterPanel.NoWorkspaces": "Maalesef, bu arama ifadesine uyan bir kanal bulunamadı",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "Lütfen başka bir ifade ile aramayı deneyin",
"DashboardPage.showEmpty": "Boş olanları görüntüle",
"DashboardPage.title": "Pano",
"DeleteBoardDialog.confirm-cancel": "İptal",
"DeleteBoardDialog.confirm-delete": "Sil",
"DeleteBoardDialog.confirm-info": "“{boardTitle}” panosunu silmek istediğinize emin misiniz? Silme işlemi bu panodaki tüm kartları siler.",
@ -121,6 +124,11 @@
"Filter.not-includes": "şunu içermeyen",
"FilterComponent.add-filter": "+ Süzgeç ekle",
"FilterComponent.delete": "Sil",
"FindBoFindBoardsDialog.IntroText": "Pano arama",
"FindBoardsDialog.NoResultsFor": "\"{searchQuery}\" için bir sonuç bulunamadı",
"FindBoardsDialog.NoResultsSubtext": "Yazımı denetleyin ya da başka bir arama yapmayı deneyin.",
"FindBoardsDialog.SubTitle": "Bulmak istediğiniz pano adını yazmaya başlayın. Gezinmek için <b>YUKAR/AŞAĞI</b>, seçmek için <b>ENTER</b>, vazgeçmek için <b>ESC</b> tuşlarını kullanın",
"FindBoardsDialog.Title": "Pano arama",
"GalleryCard.copiedLink": "Kopyalandı!",
"GalleryCard.copyLink": "Bağlantıyı kopyala",
"GalleryCard.delete": "Sil",
@ -134,9 +142,7 @@
"KanbanCard.delete": "Sil",
"KanbanCard.duplicate": "Kopyala",
"KanbanCard.untitled": "Başlıksız",
"Mutator.duplicate-board": "panoyu kopyala",
"Mutator.new-card-from-template": "kalıptan yeni kart oluştur",
"Mutator.new-template-from-board": "panodan yeni kalıp oluştur",
"Mutator.new-template-from-card": "karttan yeni kalıp oluştur",
"OnboardingTour.AddComments.Body": "Sorunlar hakkında yorum yapabilir ve Mattermost kullanıcılarının dikkatini çekmek için @anabilirsiniz.",
"OnboardingTour.AddComments.Title": "Yorum yap",
@ -185,26 +191,31 @@
"ShareBoard.copiedLink": "Kopyalandı!",
"ShareBoard.copyLink": "Bağlantıyı kopyala",
"ShareBoard.regenerate": "Kodu yeniden oluştur",
"ShareBoard.teamPermissionsText": "{teamName} takımındaki herkes",
"ShareBoard.tokenRegenrated": "Kod yeniden oluşturuldu",
"ShareBoard.userPermissionsRemoveMemberText": "Üyelikten çıkar",
"ShareBoard.userPermissionsYouText": "(Siz)",
"Sidebar.about": "Focalboard hakkında",
"Sidebar.add-board": "+ Pano ekle",
"Sidebar.changePassword": "Parola değiştir",
"Sidebar.delete-board": "Panoyu sil",
"Sidebar.duplicate-board": "Panoyu kopyala",
"Sidebar.export-archive": "Arşivi dışa aktar",
"Sidebar.import": "İçe aktar",
"Sidebar.import-archive": "Arşivi içe aktar",
"Sidebar.invite-users": "Kullanıcıları çağır",
"Sidebar.logout": "Oturumu kapat",
"Sidebar.no-more-workspaces": "Başka bir çalışma alanı yok",
"Sidebar.no-views-in-board": "İçeride bir sayfa yok",
"Sidebar.no-boards-in-category": "İçeride bir pano yok",
"Sidebar.random-icons": "Rastgele simgeler",
"Sidebar.set-language": "Dil ayarla",
"Sidebar.set-theme": "Tema ayarla",
"Sidebar.settings": "Ayarlar",
"Sidebar.template-from-board": "Panodan yeni kalıp",
"Sidebar.untitled-board": "(Başlıksız pano)",
"Sidebar.untitled-view": "(Başlıksız görünüm)",
"SidebarCategories.BlocksMenu.Move": "Şuraya taşı...",
"SidebarCategories.CategoryMenu.CreateNew": "Yeni kategori ekle",
"SidebarCategories.CategoryMenu.Delete": "Kategoriyi sił",
"SidebarCategories.CategoryMenu.DeleteModal.Body": "<b>{categoryName}</b> İçindeki panolar Panolar kategorisine taşınacak. Herhangi bir panodan çıkarılmayacaksınız.",
"SidebarCategories.CategoryMenu.DeleteModal.Title": "Bu kategori silinsin mi?",
"SidebarCategories.CategoryMenu.Update": "Kategoriyi yeniden adlandır",
"TableComponent.add-icon": "Simge ekle",
"TableComponent.name": "Ad",
"TableComponent.plus-new": "+ Yeni",
@ -282,6 +293,7 @@
"login.register-button": "ya da hesabınız yoksa bir hesap açın",
"register.login-button": "ya da bir hesabınız varsa oturum açın",
"register.signup-title": "Hesap açın",
"shareBoard.lastAdmin": "Panoların en az bir yöneticisi olmalıdır",
"tutorial_tip.finish_tour": "Tamam",
"tutorial_tip.got_it": "Anladım",
"tutorial_tip.ok": "Sonraki",

View File

@ -43,7 +43,6 @@
"ContentBlock.moveDown": "下移",
"ContentBlock.moveUp": "上移",
"ContentBlock.text": "文字",
"DashboardPage.title": "仪表板",
"Dialog.closeDialog": "关闭对话框",
"EditableDayPicker.today": "今天",
"Error.websocket-closed": "Websocket 连接关闭,连接中断。如果这种情况仍然存在,请检查您的服务器或网页代理配置。",
@ -59,9 +58,7 @@
"KanbanCard.delete": "删除",
"KanbanCard.duplicate": "复制",
"KanbanCard.untitled": "无标题",
"Mutator.duplicate-board": "复制版面",
"Mutator.new-card-from-template": "使用模板新增卡片",
"Mutator.new-template-from-board": "从版面新增模板",
"Mutator.new-template-from-card": "从卡片新增模板",
"PropertyMenu.Delete": "删除",
"PropertyMenu.changeType": "修改属性类型",
@ -95,19 +92,15 @@
"Sidebar.add-board": "+ 新增版面",
"Sidebar.changePassword": "变更密码",
"Sidebar.delete-board": "删除版面",
"Sidebar.duplicate-board": "复制版面",
"Sidebar.export-archive": "导出档案",
"Sidebar.import-archive": "导入档案",
"Sidebar.invite-users": "邀请使用者",
"Sidebar.logout": "登出",
"Sidebar.no-views-in-board": "里面没有页面",
"Sidebar.random-icons": "随机图标",
"Sidebar.set-language": "设定语言",
"Sidebar.set-theme": "设置主题",
"Sidebar.settings": "设定",
"Sidebar.template-from-board": "从版面创建模板",
"Sidebar.untitled-board": "(无标题版面)",
"Sidebar.untitled-view": "(无标题视图)",
"TableComponent.add-icon": "加入图标",
"TableComponent.name": "姓名",
"TableComponent.plus-new": "+ 新增",

View File

@ -44,9 +44,6 @@
"ContentBlock.moveDown": "下移",
"ContentBlock.moveUp": "上移",
"ContentBlock.text": "文字",
"DashboardPage.CenterPanel.NoWorkspaces": "很抱歉,我們找不到與符合該字詞的任何頻道",
"DashboardPage.CenterPanel.NoWorkspacesDescription": "請嘗試以其他字詞進行搜尋",
"DashboardPage.title": "資訊面板",
"DeleteBoardDialog.confirm-cancel": "取消",
"DeleteBoardDialog.confirm-delete": "刪除",
"Dialog.closeDialog": "關閉對話框",
@ -67,9 +64,7 @@
"KanbanCard.delete": "刪除",
"KanbanCard.duplicate": "建立副本",
"KanbanCard.untitled": "無標題",
"Mutator.duplicate-board": "建立版面副本",
"Mutator.new-card-from-template": "使用範本新增卡片",
"Mutator.new-template-from-board": "從版面新增範本",
"Mutator.new-template-from-card": "從卡片新增範本",
"PropertyMenu.Delete": "刪除",
"PropertyMenu.changeType": "修改屬性類型",
@ -104,20 +99,15 @@
"Sidebar.add-board": "+ 新增版面",
"Sidebar.changePassword": "變更密碼",
"Sidebar.delete-board": "刪除版面",
"Sidebar.duplicate-board": "建立版面副本",
"Sidebar.export-archive": "匯入打包檔",
"Sidebar.import-archive": "匯出打包檔",
"Sidebar.invite-users": "邀請使用者",
"Sidebar.logout": "登出",
"Sidebar.no-more-workspaces": "沒有更多工作區",
"Sidebar.no-views-in-board": "裡面沒有頁面",
"Sidebar.random-icons": "隨機圖示",
"Sidebar.set-language": "設定語言",
"Sidebar.set-theme": "設定佈景主題",
"Sidebar.settings": "設定",
"Sidebar.template-from-board": "從版面新增範本",
"Sidebar.untitled-board": "(無標題版面)",
"Sidebar.untitled-view": "(無標題視圖)",
"TableComponent.add-icon": "加入圖示",
"TableComponent.name": "姓名",
"TableComponent.plus-new": "+ 新增",

View File

@ -40,7 +40,7 @@ exports[`components/blockIconSelector return menu on click 1`] = `
</span>
</div>
<div
class="Menu noselect bottom"
class="Menu noselect bottom "
>
<div
class="menu-contents"

View File

@ -433,7 +433,7 @@ exports[`components/cardDialog return cardDialog menu content 1`] = `
/>
</button>
<div
class="Menu noselect left"
class="Menu noselect left "
>
<div
class="menu-contents"
@ -485,8 +485,8 @@ exports[`components/cardDialog return cardDialog menu content 1`] = `
class="MenuOption TextOption menu-option"
role="button"
>
<div
class="noicon"
<i
class="CompassIcon icon-plus undefined"
/>
<div
class="menu-name"

View File

@ -695,7 +695,20 @@ exports[`components/centerPanel return centerPanel and press touch 1 with readon
</div>
<div
class="shareButtonWrapper"
/>
>
<div
class="ShareBoardLoginButton"
>
<button
title="Login"
type="button"
>
<span>
Login
</span>
</button>
</div>
</div>
</div>
<div
class="ViewHeader"

View File

@ -24,7 +24,7 @@ exports[`components/contentBlock return commentBlock and click on menuwrapper 1`
/>
</button>
<div
class="Menu noselect bottom"
class="Menu noselect bottom "
>
<div
class="menu-contents"

View File

@ -6,7 +6,7 @@ Object {
"baseElement": <body>
<div>
<div
class="Menu noselect bottom"
class="Menu noselect bottom "
>
<div
class="menu-contents"
@ -182,7 +182,7 @@ Object {
</body>,
"container": <div>
<div
class="Menu noselect bottom"
class="Menu noselect bottom "
>
<div
class="menu-contents"
@ -415,7 +415,7 @@ Object {
"baseElement": <body>
<div>
<div
class="Menu noselect bottom"
class="Menu noselect bottom "
>
<div
class="menu-contents"
@ -532,7 +532,7 @@ Object {
</body>,
"container": <div>
<div
class="Menu noselect bottom"
class="Menu noselect bottom "
>
<div
class="menu-contents"

View File

@ -970,7 +970,20 @@ exports[`src/components/workspace return workspace readonly and showcard 1`] = `
</div>
<div
class="shareButtonWrapper"
/>
>
<div
class="ShareBoardLoginButton"
>
<button
title="Login"
type="button"
>
<span>
Login
</span>
</button>
</div>
</div>
</div>
<div
class="ViewHeader"
@ -2174,7 +2187,20 @@ exports[`src/components/workspace should match snapshot with readonly 1`] = `
</div>
<div
class="shareButtonWrapper"
/>
>
<div
class="ShareBoardLoginButton"
>
<button
title="Login"
type="button"
>
<span>
Login
</span>
</button>
</div>
</div>
</div>
<div
class="ViewHeader"

View File

@ -231,7 +231,6 @@ describe('components/boardTemplateSelector/boardTemplateSelector', () => {
const editIcon = screen.getByText(template1Title).parentElement?.querySelector('.EditIcon')
expect(editIcon).not.toBeNull()
userEvent.click(editIcon!)
expect(history.push).toBeCalledTimes(1)
})
test('return BoardTemplateSelector and click to add board from template', async () => {
render(wrapDNDIntl(

View File

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {useEffect, useState, useCallback, useMemo} from 'react'
import {FormattedMessage, useIntl} from 'react-intl'
import {generatePath, useHistory, useRouteMatch} from 'react-router-dom'
import {useHistory, useRouteMatch} from 'react-router-dom'
import {Board} from '../../blocks/board'
import IconButton from '../../widgets/buttons/iconButton'
@ -23,6 +23,10 @@ import {IUser, UserConfigPatch, UserPropPrefix} from '../../user'
import {getMe, patchProps} from '../../store/users'
import {BaseTourSteps, TOUR_BASE} from '../onboardingTour'
import {Utils} from "../../utils"
import {Constants} from "../../constants"
import BoardTemplateSelectorPreview from './boardTemplateSelectorPreview'
import BoardTemplateSelectorItem from './boardTemplateSelectorItem'
@ -44,17 +48,14 @@ const BoardTemplateSelector = (props: Props) => {
const me = useAppSelector<IUser|null>(getMe)
const showBoard = useCallback(async (boardId) => {
const params = {...match.params, boardId: boardId || ''}
delete params.viewId
const newPath = generatePath(match.path, params)
history.push(newPath)
Utils.showBoard(boardId, match, history)
if (onClose) {
onClose()
}
}, [match, history, onClose])
useEffect(() => {
if (octoClient.teamId !== '0' && globalTemplates.length === 0) {
if (octoClient.teamId !== Constants.globalTeamId && globalTemplates.length === 0) {
dispatch(fetchGlobalTemplates())
}
}, [octoClient.teamId])
@ -96,7 +97,7 @@ const BoardTemplateSelector = (props: Props) => {
}
const handleUseTemplate = async () => {
await mutator.addBoardFromTemplate(currentTeam?.id || '0', intl, showBoard, () => showBoard(currentBoardId), activeTemplate.id, currentTeam?.id)
await mutator.addBoardFromTemplate(currentTeam?.id || Constants.globalTeamId, intl, showBoard, () => showBoard(currentBoardId), activeTemplate.id, currentTeam?.id)
if (activeTemplate.title === OnboardingBoardTitle) {
resetTour()
}

View File

@ -10,6 +10,7 @@ import EditIcon from '../../widgets/icons/edit'
import DeleteBoardDialog from '../sidebar/deleteBoardDialog'
import './boardTemplateSelectorItem.scss'
import {Constants} from "../../constants"
type Props = {
isActive: boolean
@ -38,7 +39,9 @@ const BoardTemplateSelectorItem = (props: Props) => {
>
<span className='template-icon'>{template.icon}</span>
<span className='template-name'>{template.title}</span>
{!template.templateVersion &&
{/* don't show template menu options for default templates */}
{template.teamId !== Constants.globalTeamId &&
<div className='actions'>
<IconButton
icon={<DeleteIcon/>}

View File

@ -19,7 +19,7 @@ exports[`components/cardDetail/cardDetailContentsMenu return cardDetailContentsM
</span>
</button>
<div
class="Menu noselect top"
class="Menu noselect top "
>
<div
class="menu-contents"
@ -178,7 +178,7 @@ exports[`components/cardDetail/cardDetailContentsMenu return cardDetailContentsM
</span>
</button>
<div
class="Menu noselect top"
class="Menu noselect top "
>
<div
class="menu-contents"

Some files were not shown because too many files have changed in this diff Show More