mirror of
https://github.com/mattermost/focalboard.git
synced 2024-12-24 13:43:12 +02:00
GH 2393 Move calculationColumns from board to view (#2762)
* move calculation columns to view * update tests * add conversion for column calculations * remove column_Calculations from boards and boards_history * updates from testing * update for sqlite * fixes from testing * fix lint, cleanup * update templates,remove field from boards * revert bad changes * update snapshots * Update server/services/store/sqlstore/migrations/000017_add_teams_and_boards.up.sql Co-authored-by: Miguel de la Cruz <miguel@mcrx.me> Co-authored-by: Miguel de la Cruz <miguel@mcrx.me> Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
c9e449ee85
commit
90677ba7b8
@ -270,18 +270,17 @@ func (a *App) blockToBoard(block *model.Block, opt model.ImportArchiveOptions) (
|
||||
}
|
||||
|
||||
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{}),
|
||||
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),
|
||||
}
|
||||
|
||||
if icon, ok := stringValue(block.Fields, "icon"); ok {
|
||||
@ -305,9 +304,6 @@ func (a *App) blockToBoard(block *model.Block, opt model.ImportArchiveOptions) (
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
@ -6,7 +6,7 @@
|
||||
{"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":"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":{"a8daz81s4xjgke1ww6cwik5w7ye":"sum"},"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"}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"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":"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"}],"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"}}
|
||||
|
@ -72,10 +72,6 @@ type Board struct {
|
||||
// required: false
|
||||
CardProperties []map[string]interface{} `json:"cardProperties"`
|
||||
|
||||
// The calculations on the board's cards
|
||||
// required: false
|
||||
ColumnCalculations map[string]interface{} `json:"columnCalculations"`
|
||||
|
||||
// The creation time
|
||||
// required: true
|
||||
CreateAt int64 `json:"createAt"`
|
||||
@ -127,14 +123,6 @@ type BoardPatch struct {
|
||||
// The board removed card properties
|
||||
// required: false
|
||||
DeletedCardProperties []string `json:"deletedCardProperties"`
|
||||
|
||||
// The board updated column calculations
|
||||
// required: false
|
||||
UpdatedColumnCalculations map[string]interface{} `json:"updatedColumnCalculations"`
|
||||
|
||||
// The board deleted column calculations
|
||||
// required: false
|
||||
DeletedColumnCalculations []string `json:"deletedColumnCalculations"`
|
||||
}
|
||||
|
||||
// BoardMember stores the information of the membership of a user on a board
|
||||
@ -301,14 +289,6 @@ func (p *BoardPatch) Patch(board *Board) *Board {
|
||||
board.CardProperties = newCardProperties
|
||||
}
|
||||
|
||||
for key, columnCalculation := range p.UpdatedColumnCalculations {
|
||||
board.ColumnCalculations[key] = columnCalculation
|
||||
}
|
||||
|
||||
for _, key := range p.DeletedColumnCalculations {
|
||||
delete(board.ColumnCalculations, key)
|
||||
}
|
||||
|
||||
return board
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,6 @@ func boardFields(prefix string) []string {
|
||||
"template_version",
|
||||
"COALESCE(properties, '{}')",
|
||||
"COALESCE(card_properties, '[]')",
|
||||
"COALESCE(column_calculations, '{}')",
|
||||
"create_at",
|
||||
"update_at",
|
||||
"delete_at",
|
||||
@ -77,7 +76,6 @@ func boardHistoryFields() []string {
|
||||
"template_version",
|
||||
"COALESCE(properties, '{}')",
|
||||
"COALESCE(card_properties, '[]')",
|
||||
"COALESCE(column_calculations, '{}')",
|
||||
"COALESCE(create_at, 0)",
|
||||
"COALESCE(update_at, 0)",
|
||||
"COALESCE(delete_at, 0)",
|
||||
@ -103,7 +101,6 @@ func (s *SQLStore) boardsFromRows(rows *sql.Rows) ([]*model.Board, error) {
|
||||
var board model.Board
|
||||
var propertiesBytes []byte
|
||||
var cardPropertiesBytes []byte
|
||||
var columnCalculationsBytes []byte
|
||||
|
||||
err := rows.Scan(
|
||||
&board.ID,
|
||||
@ -120,7 +117,6 @@ func (s *SQLStore) boardsFromRows(rows *sql.Rows) ([]*model.Board, error) {
|
||||
&board.TemplateVersion,
|
||||
&propertiesBytes,
|
||||
&cardPropertiesBytes,
|
||||
&columnCalculationsBytes,
|
||||
&board.CreateAt,
|
||||
&board.UpdateAt,
|
||||
&board.DeleteAt,
|
||||
@ -140,11 +136,6 @@ func (s *SQLStore) boardsFromRows(rows *sql.Rows) ([]*model.Board, error) {
|
||||
s.logger.Error("board card properties unmarshal error", mlog.Err(err))
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(columnCalculationsBytes, &board.ColumnCalculations)
|
||||
if err != nil {
|
||||
s.logger.Error("board column calculation unmarshal error", mlog.Err(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
boards = append(boards, &board)
|
||||
}
|
||||
@ -300,17 +291,6 @@ func (s *SQLStore) insertBoard(db sq.BaseRunner, board *model.Board, userID stri
|
||||
return nil, err
|
||||
}
|
||||
|
||||
columnCalculationsBytes, err := json.Marshal(board.ColumnCalculations)
|
||||
if err != nil {
|
||||
s.logger.Error(
|
||||
"failed to marshal board.ColumnCalculations",
|
||||
mlog.String("board_id", board.ID),
|
||||
mlog.String("board.ColumnCalculations", fmt.Sprintf("%v", board.ColumnCalculations)),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingBoard, err := s.getBoard(db, board.ID)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, fmt.Errorf("insertBoard error occurred while fetching existing board %s: %w", board.ID, err)
|
||||
@ -322,24 +302,23 @@ func (s *SQLStore) insertBoard(db sq.BaseRunner, board *model.Board, userID stri
|
||||
now := utils.GetMillis()
|
||||
|
||||
insertQueryValues := map[string]interface{}{
|
||||
"id": board.ID,
|
||||
"team_id": board.TeamID,
|
||||
"channel_id": board.ChannelID,
|
||||
"created_by": board.CreatedBy,
|
||||
"modified_by": userID,
|
||||
"type": board.Type,
|
||||
"title": board.Title,
|
||||
"description": board.Description,
|
||||
"icon": board.Icon,
|
||||
"show_description": board.ShowDescription,
|
||||
"is_template": board.IsTemplate,
|
||||
"template_version": board.TemplateVersion,
|
||||
"properties": propertiesBytes,
|
||||
"card_properties": cardPropertiesBytes,
|
||||
"column_calculations": columnCalculationsBytes,
|
||||
"create_at": board.CreateAt,
|
||||
"update_at": now,
|
||||
"delete_at": board.DeleteAt,
|
||||
"id": board.ID,
|
||||
"team_id": board.TeamID,
|
||||
"channel_id": board.ChannelID,
|
||||
"created_by": board.CreatedBy,
|
||||
"modified_by": userID,
|
||||
"type": board.Type,
|
||||
"title": board.Title,
|
||||
"description": board.Description,
|
||||
"icon": board.Icon,
|
||||
"show_description": board.ShowDescription,
|
||||
"is_template": board.IsTemplate,
|
||||
"template_version": board.TemplateVersion,
|
||||
"properties": propertiesBytes,
|
||||
"card_properties": cardPropertiesBytes,
|
||||
"create_at": board.CreateAt,
|
||||
"update_at": now,
|
||||
"delete_at": board.DeleteAt,
|
||||
}
|
||||
|
||||
if existingBoard != nil {
|
||||
@ -355,7 +334,6 @@ func (s *SQLStore) insertBoard(db sq.BaseRunner, board *model.Board, userID stri
|
||||
Set("template_version", board.TemplateVersion).
|
||||
Set("properties", propertiesBytes).
|
||||
Set("card_properties", cardPropertiesBytes).
|
||||
Set("column_calculations", columnCalculationsBytes).
|
||||
Set("update_at", now).
|
||||
Set("delete_at", board.DeleteAt)
|
||||
|
||||
@ -413,30 +391,25 @@ func (s *SQLStore) deleteBoard(db sq.BaseRunner, boardID, userID string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
columnCalculationsBytes, err := json.Marshal(board.ColumnCalculations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
insertQueryValues := map[string]interface{}{
|
||||
"id": board.ID,
|
||||
"team_id": board.TeamID,
|
||||
"channel_id": board.ChannelID,
|
||||
"created_by": board.CreatedBy,
|
||||
"modified_by": userID,
|
||||
"type": board.Type,
|
||||
"title": board.Title,
|
||||
"description": board.Description,
|
||||
"icon": board.Icon,
|
||||
"show_description": board.ShowDescription,
|
||||
"is_template": board.IsTemplate,
|
||||
"template_version": board.TemplateVersion,
|
||||
"properties": propertiesBytes,
|
||||
"card_properties": cardPropertiesBytes,
|
||||
"column_calculations": columnCalculationsBytes,
|
||||
"create_at": board.CreateAt,
|
||||
"update_at": now,
|
||||
"delete_at": now,
|
||||
"id": board.ID,
|
||||
"team_id": board.TeamID,
|
||||
"channel_id": board.ChannelID,
|
||||
"created_by": board.CreatedBy,
|
||||
"modified_by": userID,
|
||||
"type": board.Type,
|
||||
"title": board.Title,
|
||||
"description": board.Description,
|
||||
"icon": board.Icon,
|
||||
"show_description": board.ShowDescription,
|
||||
"is_template": board.IsTemplate,
|
||||
"template_version": board.TemplateVersion,
|
||||
"properties": propertiesBytes,
|
||||
"card_properties": cardPropertiesBytes,
|
||||
"create_at": board.CreateAt,
|
||||
"update_at": now,
|
||||
"delete_at": now,
|
||||
}
|
||||
|
||||
// writing board history
|
||||
@ -731,11 +704,6 @@ func (s *SQLStore) undeleteBoard(db sq.BaseRunner, boardID string, modifiedBy st
|
||||
return err
|
||||
}
|
||||
|
||||
columnCalculationsJSON, err := json.Marshal(board.ColumnCalculations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := utils.GetMillis()
|
||||
columns := []string{
|
||||
"id",
|
||||
@ -752,7 +720,6 @@ func (s *SQLStore) undeleteBoard(db sq.BaseRunner, boardID string, modifiedBy st
|
||||
"template_version",
|
||||
"properties",
|
||||
"card_properties",
|
||||
"column_calculations",
|
||||
"create_at",
|
||||
"update_at",
|
||||
"delete_at",
|
||||
@ -773,7 +740,6 @@ func (s *SQLStore) undeleteBoard(db sq.BaseRunner, boardID string, modifiedBy st
|
||||
board.TemplateVersion,
|
||||
propertiesJSON,
|
||||
cardPropertiesJSON,
|
||||
columnCalculationsJSON,
|
||||
board.CreateAt,
|
||||
now,
|
||||
0,
|
||||
|
@ -11,16 +11,42 @@ ALTER TABLE {{.prefix}}blocks ADD COLUMN board_id VARCHAR(36);
|
||||
ALTER TABLE {{.prefix}}blocks_history ADD COLUMN board_id VARCHAR(36);
|
||||
|
||||
{{- /* cleanup incorrect data format in column calculations */ -}}
|
||||
{{- /* then move from 'board' type to 'view' type*/ -}}
|
||||
{{if .mysql}}
|
||||
UPDATE {{.prefix}}blocks SET fields = JSON_SET(fields, '$.columnCalculations', cast('{}' as json)) WHERE fields->'$.columnCalculations' = cast('[]' as json);
|
||||
{{end}}
|
||||
UPDATE {{.prefix}}blocks SET fields = JSON_SET(fields, '$.columnCalculations', cast('{}' as json)) WHERE fields->'$.columnCalculations' = cast('[]' as json);
|
||||
|
||||
UPDATE {{.prefix}}blocks b
|
||||
JOIN (
|
||||
SELECT id, fields->'$.columnCalculations' as board_calculations from {{.prefix}}blocks
|
||||
WHERE fields -> '$.columnCalculations' <> cast('{}' as json)
|
||||
) AS s on s.id = b.root_id
|
||||
SET fields = JSON_SET(fields, '$.columnCalculations', cast(s.board_calculations as json))
|
||||
WHERE b.fields->'$.viewType' = 'table'
|
||||
AND b.type = 'view';
|
||||
{{end}}
|
||||
{{if .postgres}}
|
||||
UPDATE {{.prefix}}blocks SET fields = fields::jsonb - 'columnCalculations' || '{"columnCalculations": {}}' WHERE fields->>'columnCalculations' = '[]';
|
||||
{{end}}
|
||||
|
||||
WITH subquery AS (
|
||||
SELECT id, fields->'columnCalculations' as board_calculations from {{.prefix}}blocks
|
||||
WHERE fields ->> 'columnCalculations' <> '{}')
|
||||
UPDATE {{.prefix}}blocks b
|
||||
SET fields = b.fields::jsonb|| json_build_object('columnCalculations', s.board_calculations::jsonb)::jsonb
|
||||
FROM subquery AS s
|
||||
WHERE s.id = b.root_id
|
||||
AND b.fields ->> 'viewType' = 'table'
|
||||
AND b.type = 'view';
|
||||
{{end}}
|
||||
{{if .sqlite}}
|
||||
UPDATE {{.prefix}}blocks SET fields = replace(fields, '"columnCalculations":[]', '"columnCalculations":{}');
|
||||
|
||||
UPDATE {{.prefix}}blocks AS b
|
||||
SET fields = (
|
||||
SELECT json_set(a.fields, '$.columnCalculations',json_extract(c.fields, '$.columnCalculations')) from {{.prefix}}blocks AS a
|
||||
JOIN {{.prefix}}blocks AS c on c.id = a.root_id
|
||||
WHERE a.id = b.id)
|
||||
WHERE json_extract(b.fields,'$.viewType') = 'table'
|
||||
AND b.type = 'view';
|
||||
{{end}}
|
||||
|
||||
/* TODO: Migrate the columnCalculations at app level and remove it from the boards and boards_history tables */
|
||||
@ -47,17 +73,14 @@ CREATE TABLE {{.prefix}}boards (
|
||||
{{if .mysql}}
|
||||
properties JSON,
|
||||
card_properties JSON,
|
||||
column_calculations JSON,
|
||||
{{end}}
|
||||
{{if .postgres}}
|
||||
properties JSONB,
|
||||
card_properties JSONB,
|
||||
column_calculations JSONB,
|
||||
{{end}}
|
||||
{{if .sqlite}}
|
||||
properties TEXT,
|
||||
card_properties TEXT,
|
||||
column_calculations TEXT,
|
||||
{{end}}
|
||||
create_at BIGINT,
|
||||
update_at BIGINT,
|
||||
@ -87,17 +110,14 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
{{if .mysql}}
|
||||
properties JSON,
|
||||
card_properties JSON,
|
||||
column_calculations JSON,
|
||||
{{end}}
|
||||
{{if .postgres}}
|
||||
properties JSONB,
|
||||
card_properties JSONB,
|
||||
column_calculations JSONB,
|
||||
{{end}}
|
||||
{{if .sqlite}}
|
||||
properties TEXT,
|
||||
card_properties TEXT,
|
||||
column_calculations TEXT,
|
||||
{{end}}
|
||||
create_at BIGINT,
|
||||
update_at BIGINT,
|
||||
@ -118,7 +138,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE((fields->'showDescription')::text::boolean, false),
|
||||
COALESCE((fields->'isTemplate')::text::boolean, false),
|
||||
COALESCE((B.fields->'templateVer')::text::int, 0),
|
||||
'{}', B.fields->'cardProperties', B.fields->'columnCalculations', B.create_at,
|
||||
'{}', B.fields->'cardProperties', B.create_at,
|
||||
B.update_at, B.delete_at
|
||||
FROM {{.prefix}}blocks AS B
|
||||
INNER JOIN channels AS C ON C.Id=B.channel_id
|
||||
@ -132,7 +152,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE((fields->'showDescription')::text::boolean, false),
|
||||
COALESCE((fields->'isTemplate')::text::boolean, false),
|
||||
COALESCE((B.fields->'templateVer')::text::int, 0),
|
||||
'{}', B.fields->'cardProperties', B.fields->'columnCalculations', B.create_at,
|
||||
'{}', B.fields->'cardProperties', B.create_at,
|
||||
B.update_at, B.delete_at
|
||||
FROM {{.prefix}}blocks_history AS B
|
||||
INNER JOIN channels AS C ON C.Id=B.channel_id
|
||||
@ -148,7 +168,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE(B.fields->'$.showDescription', 'false') = 'true',
|
||||
COALESCE(JSON_EXTRACT(B.fields, '$.isTemplate'), 'false') = 'true',
|
||||
COALESCE(B.fields->'$.templateVer', 0),
|
||||
'{}', B.fields->'$.cardProperties', B.fields->'$.columnCalculations', B.create_at,
|
||||
'{}', B.fields->'$.cardProperties', B.create_at,
|
||||
B.update_at, B.delete_at
|
||||
FROM {{.prefix}}blocks AS B
|
||||
INNER JOIN Channels AS C ON C.Id=B.channel_id
|
||||
@ -162,7 +182,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE(B.fields->'$.showDescription', 'false') = 'true',
|
||||
COALESCE(JSON_EXTRACT(B.fields, '$.isTemplate'), 'false') = 'true',
|
||||
COALESCE(B.fields->'$.templateVer', 0),
|
||||
'{}', B.fields->'$.cardProperties', B.fields->'$.columnCalculations', B.create_at,
|
||||
'{}', B.fields->'$.cardProperties', B.create_at,
|
||||
B.update_at, B.delete_at
|
||||
FROM {{.prefix}}blocks_history AS B
|
||||
INNER JOIN Channels AS C ON C.Id=B.channel_id
|
||||
@ -179,7 +199,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE((fields->'showDescription')::text::boolean, false),
|
||||
COALESCE((fields->'isTemplate')::text::boolean, false),
|
||||
COALESCE((B.fields->'templateVer')::text::int, 0),
|
||||
'{}', fields->'cardProperties', fields->'columnCalculations', create_at,
|
||||
'{}', fields->'cardProperties', create_at,
|
||||
update_at, delete_at
|
||||
FROM {{.prefix}}blocks AS B
|
||||
WHERE type='board'
|
||||
@ -192,7 +212,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE((fields->'showDescription')::text::boolean, false),
|
||||
COALESCE((fields->'isTemplate')::text::boolean, false),
|
||||
COALESCE((B.fields->'templateVer')::text::int, 0),
|
||||
'{}', fields->'cardProperties', fields->'columnCalculations', create_at,
|
||||
'{}', fields->'cardProperties', create_at,
|
||||
update_at, delete_at
|
||||
FROM {{.prefix}}blocks_history AS B
|
||||
WHERE type='board'
|
||||
@ -207,7 +227,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE(B.fields->'$.showDescription', 'false') = 'true',
|
||||
COALESCE(JSON_EXTRACT(B.fields, '$.isTemplate'), 'false') = 'true',
|
||||
COALESCE(B.fields->'$.templateVer', 0),
|
||||
'{}', fields->'$.cardProperties', fields->'$.columnCalculations', create_at,
|
||||
'{}', fields->'$.cardProperties', create_at,
|
||||
update_at, delete_at
|
||||
FROM {{.prefix}}blocks AS B
|
||||
WHERE type='board'
|
||||
@ -220,7 +240,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
COALESCE(B.fields->'$.showDescription', 'false') = 'true',
|
||||
COALESCE(JSON_EXTRACT(B.fields, '$.isTemplate'), 'false') = 'true',
|
||||
COALESCE(B.fields->'$.templateVer', 0),
|
||||
'{}', fields->'$.cardProperties', fields->'$.columnCalculations', create_at,
|
||||
'{}', fields->'$.cardProperties', create_at,
|
||||
update_at, delete_at
|
||||
FROM {{.prefix}}blocks_history AS B
|
||||
WHERE type='board'
|
||||
@ -233,7 +253,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
json_extract(fields, '$.description'),
|
||||
json_extract(fields, '$.icon'), json_extract(fields, '$.showDescription'), json_extract(fields, '$.isTemplate'),
|
||||
COALESCE(json_extract(fields, '$.templateVer'), 0),
|
||||
'{}', json_extract(fields, '$.cardProperties'), json_extract(fields, '$.columnCalculations'), create_at,
|
||||
'{}', json_extract(fields, '$.cardProperties'), create_at,
|
||||
update_at, delete_at
|
||||
FROM {{.prefix}}blocks
|
||||
WHERE type='board'
|
||||
@ -244,7 +264,7 @@ CREATE TABLE {{.prefix}}boards_history (
|
||||
json_extract(fields, '$.description'),
|
||||
json_extract(fields, '$.icon'), json_extract(fields, '$.showDescription'), json_extract(fields, '$.isTemplate'),
|
||||
COALESCE(json_extract(fields, '$.templateVer'), 0),
|
||||
'{}', json_extract(fields, '$.cardProperties'), json_extract(fields, '$.columnCalculations'), create_at,
|
||||
'{}', json_extract(fields, '$.cardProperties'), create_at,
|
||||
update_at, delete_at
|
||||
FROM {{.prefix}}blocks_history
|
||||
WHERE type='board'
|
||||
|
@ -386,15 +386,13 @@ func testPatchBoard(t *testing.T, store store.Store) {
|
||||
boardID := utils.NewID(utils.IDTypeBoard)
|
||||
properties := map[string]interface{}{"prop1": "val1"}
|
||||
cardProperties := []map[string]interface{}{{"prop2": "val2"}}
|
||||
columnCalculations := map[string]interface{}{"calc3": "val3"}
|
||||
|
||||
board := &model.Board{
|
||||
ID: boardID,
|
||||
TeamID: testTeamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
Properties: properties,
|
||||
CardProperties: cardProperties,
|
||||
ColumnCalculations: columnCalculations,
|
||||
ID: boardID,
|
||||
TeamID: testTeamID,
|
||||
Type: model.BoardTypeOpen,
|
||||
Properties: properties,
|
||||
CardProperties: cardProperties,
|
||||
}
|
||||
|
||||
newBoard, err := store.InsertBoard(board, userID)
|
||||
@ -403,7 +401,6 @@ func testPatchBoard(t *testing.T, store store.Store) {
|
||||
require.Equal(t, newBoard.Type, model.BoardTypeOpen)
|
||||
require.Equal(t, properties, newBoard.Properties)
|
||||
require.Equal(t, cardProperties, newBoard.CardProperties)
|
||||
require.Equal(t, columnCalculations, newBoard.ColumnCalculations)
|
||||
|
||||
// wait to avoid hitting pk uniqueness constraint in history
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
@ -415,7 +412,6 @@ func testPatchBoard(t *testing.T, store store.Store) {
|
||||
require.Equal(t, model.BoardTypePrivate, patchedBoard.Type)
|
||||
require.Equal(t, properties, patchedBoard.Properties)
|
||||
require.Equal(t, cardProperties, patchedBoard.CardProperties)
|
||||
require.Equal(t, columnCalculations, patchedBoard.ColumnCalculations)
|
||||
})
|
||||
|
||||
t.Run("a patch that removes a card property and updates another should work correctly", func(t *testing.T) {
|
||||
|
@ -20,10 +20,8 @@ Array [
|
||||
"boardPatches": Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
],
|
||||
@ -46,10 +44,8 @@ Array [
|
||||
"boardPatches": Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
],
|
||||
@ -75,10 +71,8 @@ Array [
|
||||
"boardPatches": Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
],
|
||||
@ -99,10 +93,8 @@ Array [
|
||||
"boardPatches": Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
],
|
||||
@ -114,7 +106,6 @@ exports[`board tests correctly generate patches from two boards should add card
|
||||
Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [
|
||||
Object {
|
||||
@ -130,17 +121,14 @@ Array [
|
||||
"type": "select",
|
||||
},
|
||||
],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
Object {
|
||||
"deletedCardProperties": Array [
|
||||
"new-property-id",
|
||||
],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
]
|
||||
@ -150,7 +138,6 @@ exports[`board tests correctly generate patches from two boards should add card
|
||||
Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [
|
||||
Object {
|
||||
@ -166,12 +153,10 @@ Array [
|
||||
"type": "select",
|
||||
},
|
||||
],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [
|
||||
Object {
|
||||
@ -187,7 +172,6 @@ Array [
|
||||
"type": "select",
|
||||
},
|
||||
],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
]
|
||||
@ -197,7 +181,6 @@ exports[`board tests correctly generate patches from two boards should add card
|
||||
Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [
|
||||
Object {
|
||||
@ -213,12 +196,10 @@ Array [
|
||||
"type": "select",
|
||||
},
|
||||
],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [
|
||||
Object {
|
||||
@ -234,7 +215,6 @@ Array [
|
||||
"type": "select",
|
||||
},
|
||||
],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
]
|
||||
@ -244,22 +224,18 @@ exports[`board tests correctly generate patches from two boards should add prope
|
||||
Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {
|
||||
"prop1": "val1",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [
|
||||
"prop1",
|
||||
],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
]
|
||||
@ -269,43 +245,14 @@ exports[`board tests correctly generate patches from two boards should generate
|
||||
Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`board tests correctly generate patches from two boards should update a column calculation on the redo and revert it on the undo 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {
|
||||
"cal1": "val1",
|
||||
},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
Object {
|
||||
"deletedCardProperties": Array [],
|
||||
"deletedColumnCalculations": Array [],
|
||||
"deletedProperties": Array [],
|
||||
"updatedCardProperties": Array [],
|
||||
"updatedColumnCalculations": Object {
|
||||
"cal1": "another-val1",
|
||||
},
|
||||
"updatedProperties": Object {},
|
||||
},
|
||||
]
|
||||
|
@ -94,20 +94,6 @@ describe('board tests', () => {
|
||||
const result = createPatchesFromBoards(board, oldBoard)
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should update a column calculation on the redo and revert it on the undo', () => {
|
||||
const board = TestBlockFactory.createBoard()
|
||||
const oldBoard = createBoard(board)
|
||||
board.columnCalculations = {
|
||||
cal1: 'val1',
|
||||
}
|
||||
oldBoard.columnCalculations = {
|
||||
cal1: 'another-val1',
|
||||
}
|
||||
|
||||
const result = createPatchesFromBoards(board, oldBoard)
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe('correctly generate patches for boards and blocks', () => {
|
||||
|
@ -29,7 +29,6 @@ type Board = {
|
||||
templateVersion: number
|
||||
properties: Record<string, string | string[]>
|
||||
cardProperties: IPropertyTemplate[]
|
||||
columnCalculations: Record<string, string>
|
||||
|
||||
createAt: number
|
||||
updateAt: number
|
||||
@ -48,9 +47,6 @@ type BoardPatch = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
updatedCardProperties?: IPropertyTemplate[]
|
||||
deletedCardProperties?: string[]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
updatedColumnCalculations?: Record<string, any>
|
||||
deletedColumnCalculations?: string[]
|
||||
}
|
||||
|
||||
type BoardMember = {
|
||||
@ -132,7 +128,6 @@ function createBoard(board?: Board): Board {
|
||||
templateVersion: board?.templateVersion || 0,
|
||||
properties: board?.properties || {},
|
||||
cardProperties,
|
||||
columnCalculations: board?.columnCalculations || {},
|
||||
createAt: board?.createAt || now,
|
||||
updateAt: board?.updateAt || now,
|
||||
deleteAt: board?.deleteAt || 0,
|
||||
@ -224,7 +219,6 @@ function createCardPropertiesPatches(newCardProperties: IPropertyTemplate[], old
|
||||
// action, in case it happens
|
||||
function createPatchesFromBoards(newBoard: Board, oldBoard: Board): BoardPatch[] {
|
||||
const newDeletedProperties = difference(Object.keys(newBoard.properties || {}), Object.keys(oldBoard.properties || {}))
|
||||
const newDeletedColumnCalculations = difference(Object.keys(newBoard.columnCalculations), Object.keys(oldBoard.columnCalculations))
|
||||
|
||||
const newUpdatedProperties: Record<string, any> = {}
|
||||
Object.keys(newBoard.properties || {}).forEach((val) => {
|
||||
@ -232,25 +226,17 @@ function createPatchesFromBoards(newBoard: Board, oldBoard: Board): BoardPatch[]
|
||||
newUpdatedProperties[val] = newBoard.properties[val]
|
||||
}
|
||||
})
|
||||
const newUpdatedColumnCalculations: Record<string, any> = {}
|
||||
Object.keys(newBoard.columnCalculations).forEach((val) => {
|
||||
if (oldBoard.columnCalculations[val] !== newBoard.columnCalculations[val]) {
|
||||
newUpdatedColumnCalculations[val] = newBoard.columnCalculations[val]
|
||||
}
|
||||
})
|
||||
|
||||
const newData: Record<string, any> = {}
|
||||
Object.keys(newBoard).forEach((val) => {
|
||||
if (val !== 'properties' &&
|
||||
val !== 'cardProperties' &&
|
||||
val !== 'columnCalculations' &&
|
||||
(oldBoard as any)[val] !== (newBoard as any)[val]) {
|
||||
newData[val] = (newBoard as any)[val]
|
||||
}
|
||||
})
|
||||
|
||||
const oldDeletedProperties = difference(Object.keys(oldBoard.properties || {}), Object.keys(newBoard.properties || {}))
|
||||
const oldDeletedColumnCalculations = difference(Object.keys(oldBoard.columnCalculations), Object.keys(newBoard.columnCalculations))
|
||||
|
||||
const oldUpdatedProperties: Record<string, any> = {}
|
||||
Object.keys(oldBoard.properties || {}).forEach((val) => {
|
||||
@ -258,18 +244,11 @@ function createPatchesFromBoards(newBoard: Board, oldBoard: Board): BoardPatch[]
|
||||
oldUpdatedProperties[val] = oldBoard.properties[val]
|
||||
}
|
||||
})
|
||||
const oldUpdatedColumnCalculations: Record<string, any> = {}
|
||||
Object.keys(oldBoard.columnCalculations).forEach((val) => {
|
||||
if (newBoard.columnCalculations[val] !== oldBoard.columnCalculations[val]) {
|
||||
oldUpdatedColumnCalculations[val] = oldBoard.columnCalculations[val]
|
||||
}
|
||||
})
|
||||
|
||||
const oldData: Record<string, any> = {}
|
||||
Object.keys(oldBoard).forEach((val) => {
|
||||
if (val !== 'properties' &&
|
||||
val !== 'cardProperties' &&
|
||||
val !== 'columnCalculations' &&
|
||||
(newBoard as any)[val] !== (oldBoard as any)[val]) {
|
||||
oldData[val] = (oldBoard as any)[val]
|
||||
}
|
||||
@ -283,16 +262,12 @@ function createPatchesFromBoards(newBoard: Board, oldBoard: Board): BoardPatch[]
|
||||
...cardPropertiesPatch,
|
||||
updatedProperties: newUpdatedProperties,
|
||||
deletedProperties: oldDeletedProperties,
|
||||
updatedColumnCalculations: newUpdatedColumnCalculations,
|
||||
deletedColumnCalculations: oldDeletedColumnCalculations,
|
||||
},
|
||||
{
|
||||
...oldData,
|
||||
...cardPropertiesUndoPatch,
|
||||
updatedProperties: oldUpdatedProperties,
|
||||
deletedProperties: newDeletedProperties,
|
||||
updatedColumnCalculations: oldUpdatedColumnCalculations,
|
||||
deletedColumnCalculations: newDeletedColumnCalculations,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ describe('components/boardTemplateSelector/boardTemplateSelectorItem', () => {
|
||||
templateVersion: 0,
|
||||
icon: '🚴🏻♂️',
|
||||
cardProperties: [groupProperty],
|
||||
columnCalculations: {},
|
||||
properties: {},
|
||||
}
|
||||
|
||||
@ -76,7 +75,6 @@ describe('components/boardTemplateSelector/boardTemplateSelectorItem', () => {
|
||||
description: 'test',
|
||||
showDescription: false,
|
||||
cardProperties: [groupProperty],
|
||||
columnCalculations: {},
|
||||
isTemplate: true,
|
||||
templateVersion: 2,
|
||||
properties: {},
|
||||
|
@ -71,7 +71,7 @@ describe('components/table/calculation/CalculationRow', () => {
|
||||
})
|
||||
|
||||
test('should match snapshot', async () => {
|
||||
board.columnCalculations = {
|
||||
view.fields.columnCalculations = {
|
||||
property_2: 'count',
|
||||
property_3: 'countValue',
|
||||
property_4: 'countUniqueValue',
|
||||
|
@ -1,11 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useState} from 'react'
|
||||
import React, {useState, useMemo} from 'react'
|
||||
|
||||
import {Constants} from '../../../constants'
|
||||
|
||||
import './calculationRow.scss'
|
||||
import {Board, createBoard, IPropertyTemplate} from '../../../blocks/board'
|
||||
import {Board, IPropertyTemplate} from '../../../blocks/board'
|
||||
|
||||
import mutator from '../../../mutator'
|
||||
import Calculation from '../../calculations/calculation'
|
||||
@ -26,6 +26,7 @@ type Props = {
|
||||
}
|
||||
|
||||
const CalculationRow = (props: Props): JSX.Element => {
|
||||
const {board, cards, activeView, resizingColumn, offset, readonly} = props
|
||||
const toggleOptions = (templateId: string, show: boolean) => {
|
||||
const newShowOptions = new Map<string, boolean>(showOptions)
|
||||
newShowOptions.set(templateId, show)
|
||||
@ -37,24 +38,24 @@ const CalculationRow = (props: Props): JSX.Element => {
|
||||
id: Constants.titleColumnId,
|
||||
} as IPropertyTemplate
|
||||
|
||||
const templates: IPropertyTemplate[] = [
|
||||
const visiblePropertyTemplates = useMemo(() => ([
|
||||
titleTemplate,
|
||||
...props.board.cardProperties.filter((template) => props.activeView.fields.visiblePropertyIds.includes(template.id)),
|
||||
]
|
||||
...activeView.fields.visiblePropertyIds.map((id) => board.cardProperties.find((t) => t.id === id)).filter((i) => i) as IPropertyTemplate[]
|
||||
]), [board.cardProperties, activeView.fields.visiblePropertyIds])
|
||||
|
||||
const selectedCalculations = props.board.columnCalculations || []
|
||||
const selectedCalculations = activeView.fields.columnCalculations || []
|
||||
|
||||
const [hovered, setHovered] = useState(false)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={'CalculationRow octo-table-row'}
|
||||
onMouseEnter={() => setHovered(!props.readonly)}
|
||||
onMouseEnter={() => setHovered(!readonly)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
{
|
||||
templates.map((template) => {
|
||||
const style = {width: columnWidth(props.resizingColumn, props.activeView.fields.columnWidths, props.offset, template.id)}
|
||||
visiblePropertyTemplates.map((template) => {
|
||||
const style = {width: columnWidth(resizingColumn, activeView.fields.columnWidths, offset, template.id)}
|
||||
const defaultValue = template.id === Constants.titleColumnId ? Options.count.value : Options.none.value
|
||||
const value = selectedCalculations[template.id] || defaultValue
|
||||
|
||||
@ -62,20 +63,18 @@ const CalculationRow = (props: Props): JSX.Element => {
|
||||
<Calculation
|
||||
key={template.id}
|
||||
style={style}
|
||||
class={`octo-table-cell ${props.readonly ? 'disabled' : ''}`}
|
||||
class={`octo-table-cell ${readonly ? 'disabled' : ''}`}
|
||||
value={value}
|
||||
menuOpen={Boolean(props.readonly ? false : showOptions.get(template.id))}
|
||||
menuOpen={Boolean(readonly ? false : showOptions.get(template.id))}
|
||||
onMenuClose={() => toggleOptions(template.id, false)}
|
||||
onMenuOpen={() => toggleOptions(template.id, true)}
|
||||
onChange={(v: string) => {
|
||||
const calculations = {...selectedCalculations}
|
||||
calculations[template.id] = v
|
||||
const newBoard = createBoard(props.board)
|
||||
newBoard.columnCalculations = calculations
|
||||
mutator.updateBoard(newBoard, props.board, 'update_calculation')
|
||||
mutator.changeViewColumnCalculations(board.id, activeView.id, selectedCalculations, calculations, "change column calculation")
|
||||
setHovered(false)
|
||||
}}
|
||||
cards={props.cards}
|
||||
cards={cards}
|
||||
property={template}
|
||||
hovered={hovered}
|
||||
optionsComponent={TableCalculationOptions}
|
||||
|
@ -856,6 +856,19 @@ class Mutator {
|
||||
)
|
||||
}
|
||||
|
||||
async changeViewColumnCalculations(boardId: string, viewId: string, oldCalculations: Record<string, string>, calculations: Record<string, string>, description = 'updated kanban calculations'): Promise<void> {
|
||||
await undoManager.perform(
|
||||
async () => {
|
||||
await octoClient.patchBlock(boardId, viewId, {updatedFields: {columnCalculations: calculations}})
|
||||
},
|
||||
async () => {
|
||||
await octoClient.patchBlock(boardId, viewId, {updatedFields: {columnCalculations: oldCalculations}})
|
||||
},
|
||||
description,
|
||||
this.undoGroupId,
|
||||
)
|
||||
}
|
||||
|
||||
async changeViewCardOrder(boardId: string, viewId: string, oldCardOrder: string[], cardOrder: string[], description = 'reorder'): Promise<void> {
|
||||
await undoManager.perform(
|
||||
async () => {
|
||||
|
Loading…
Reference in New Issue
Block a user