folderBundle.debug.js 676 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| IBM Cognos Products: Content Explorer
  5. *| (C) Copyright IBM Corp. 2015, 2018
  6. *|
  7. *| US Government Users Restricted Rights - Use, duplication or disclosure
  8. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *+------------------------------------------------------------------------+
  10. */
  11. define('bacontentnav/common/ui/list_actions/ListAction',[
  12. '../../../lib/@waca/core-client/js/core-client/ui/core/Class',
  13. '../../../utils/ContentStoreObject',
  14. 'underscore'
  15. ], function(Class, ContentStoreObject, _) {
  16. 'use strict';
  17. var ListAction = Class.extend({
  18. /**
  19. These options are optional, either they get passed in the constructor or in the options
  20. when calling the isItemVisible and onSelectItems methods
  21. options.oListControl {object}
  22. options.aSelctedContext {object}
  23. **/
  24. init: function(options) {
  25. ListAction.inherited('init', this, arguments);
  26. _.extend(this, options);
  27. },
  28. isItemVisible: function(options) {
  29. void(options);
  30. var elements = options.target.itemId.split('.');
  31. var actionName = elements.pop();
  32. var listControl = this.getListControl(options);
  33. if (listControl && listControl.contentView.isEnabledAction) {
  34. return listControl.contentView.isEnabledAction(actionName);
  35. } else if (options.target.activeObject && options.target.activeObject.contentView.isEnabledAction) {
  36. return options.target.activeObject.contentView.isEnabledAction(actionName);
  37. }
  38. return true;
  39. },
  40. /**
  41. Glass API, this is what gets called when a menu item is clicked
  42. **/
  43. onSelectItem: function(options) {
  44. return this.getMissingData(options).then(function(options) {
  45. this.execute(options);
  46. }.bind(this));
  47. },
  48. /**
  49. * Returns an array of properties
  50. */
  51. getRequiredPropertiesList: function(options) {
  52. void(options);
  53. //To be overridden by subclass as needed.
  54. },
  55. getMissingData: function(options) {
  56. var requiredProperties = this.getRequiredPropertiesList(options);
  57. if (!requiredProperties || !requiredProperties.length) {
  58. return Promise.resolve(options);
  59. }
  60. var missingProperties = [];
  61. requiredProperties.forEach(function(field) {
  62. if (!options.target.activeObject.aSelectedContext[0][field]) {
  63. missingProperties.push(field);
  64. }
  65. });
  66. if (!missingProperties.length) {
  67. return Promise.resolve(options);
  68. }
  69. return options.glassContext.getCoreSvc('.Ajax').ajax({
  70. 'url': ContentStoreObject.getSelfLink(options.target.activeObject.aSelectedContext[0]),
  71. 'dataType': 'json',
  72. 'data': {
  73. 'fields': missingProperties.join(',')
  74. },
  75. 'type': 'GET'
  76. })
  77. .then(function(response) {
  78. missingProperties.forEach(function(field) {
  79. var data = response.data && response.data.data[0] || {};
  80. if (field.indexOf('base') !== -1) {
  81. options.target.activeObject.aSelectedContext[0].base = data.base;
  82. } else {
  83. options.target.activeObject.aSelectedContext[0][field] = data[field];
  84. }
  85. }.bind(this));
  86. return options;
  87. }.bind(this));
  88. },
  89. getListControl: function(options) {
  90. if (!this.oListControl && options && options.target && options.target.activeObject) {
  91. this.oListControl = options.target.activeObject.oListControl;
  92. }
  93. return this.oListControl;
  94. },
  95. getSelectedContext: function(options) {
  96. if (options && options.target && options.target.activeObject) {
  97. return options.target.activeObject.aSelectedContext;
  98. }
  99. },
  100. getParentSlideout: function(options) {
  101. if (!this.parentSlideout && options && options.target && options.target.activeObject) {
  102. this.parentSlideout = options.target.activeObject.slideout;
  103. }
  104. return this.parentSlideout;
  105. },
  106. hasStateID: function(options, stateId) {
  107. var listControl = this.getListControl(options);
  108. return !!(listControl && listControl.stateId && listControl.stateId === stateId);
  109. }
  110. });
  111. return ListAction;
  112. });
  113. /*
  114. *+------------------------------------------------------------------------+
  115. *| Licensed Materials - Property of IBM
  116. *| IBM Cognos Products: BI Content Explorer
  117. *| (C) Copyright IBM Corp. 2015, 2020
  118. *|
  119. *| US Government Users Restricted Rights - Use, duplication or disclosure
  120. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  121. *+------------------------------------------------------------------------+
  122. */
  123. define('bacontentnav/common/ui/list_actions/AddInlineAction',[
  124. './ListAction',
  125. '../../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  126. '../../../lib/@waca/core-client/js/core-client/utils/BrowserUtils',
  127. 'underscore'
  128. ], function(ListAction, BidiUtil, BrowserUtils, _) {
  129. 'use strict'; //NOSONAR
  130. var AddInlineAction = ListAction.extend({
  131. getDefaultName: function() {
  132. return '';
  133. },
  134. getType: function() {
  135. return 'text';
  136. },
  137. getClass: function() {
  138. return 'inlineAdded';
  139. },
  140. destroy: function() {
  141. AddInlineAction.inherited('destroy', this, arguments);
  142. this._clearBlurTimeout();
  143. },
  144. _clearBlurTimeout: function() {
  145. window.clearTimeout(this._blurTimeout);
  146. this._blurTimeout = null;
  147. },
  148. execute: function() {
  149. this._isCancelled = false;
  150. this._handledSave = false;
  151. this._clearBlurTimeout();
  152. var listControl = this.getListControl();
  153. listControl.setInStandbyMode(true);
  154. return listControl.addRowData([{
  155. 'defaultName': this.getDefaultName(),
  156. 'type': this.getType(),
  157. 'uid': _.uniqueId('new_' + this.getType() + '_')
  158. }], true).then(function(nTRs) {
  159. this._inlineTR = nTRs[0];
  160. this._updateRowForInlineEdit(this._inlineTR);
  161. }.bind(this));
  162. },
  163. cancel: function() {
  164. if (!this._isCancelled && this._inlineTR) {
  165. this._isCancelled = true;
  166. var listControl = this.getListControl();
  167. listControl.removeRow(this._inlineTR);
  168. listControl.setInStandbyMode(false);
  169. }
  170. },
  171. _updateRowForInlineEdit: function(TR) {
  172. var listControl = this.getListControl();
  173. listControl.setInStandbyMode(true);
  174. // Make sure the datatable doesn't try to render anymore rows when we scroll
  175. // the new row into view
  176. listControl.setRenderRowsOnScroll(false);
  177. // Scroll the TR into view
  178. var scrollPosition = ($(TR).height() * TR.rowIndex) - (listControl._scrollNode.height() / 2);
  179. listControl.getScrollingNode().scrollTop(scrollPosition);
  180. this._scrollStartTime = new Date();
  181. this._createInput($(TR));
  182. },
  183. _createInput: function($TR) {
  184. var listControl = this.getListControl();
  185. var $theDiv = $TR.find('.nameColumnDiv:first');
  186. $TR.addClass(this.getClass());
  187. var tdEllipsisCell = $theDiv.parent();
  188. tdEllipsisCell.empty();
  189. var $theInput = $(document.createElement('input'));
  190. $theInput.attr('type', 'text');
  191. if (BrowserUtils.isIE11 && BrowserUtils.isIE11()) {
  192. $theInput.attr('value', this.getDefaultName());
  193. $theInput.attr('onfocus', 'this.select()');
  194. } else {
  195. $theInput.attr('placeholder', this.getDefaultName());
  196. }
  197. tdEllipsisCell.append($theInput);
  198. BidiUtil.initElementForBidi($theInput[0]);
  199. $theInput.on('keydown', function(evt) {
  200. // call the blur event when the Enter key is pressed
  201. switch (evt.keyCode) {
  202. //enter
  203. case 13:
  204. this._handleBlur(evt);
  205. evt.stopPropagation();
  206. break;
  207. //esc
  208. case 27:
  209. evt.stopPropagation();
  210. this.cancel();
  211. break;
  212. }
  213. }.bind(this));
  214. $theInput.on('blur', function(evt) {
  215. this._handleBlur(evt);
  216. }.bind(this));
  217. if (BrowserUtils.isIPad()) {
  218. $theInput.on('clicktap', function(evt) {
  219. evt.stopPropagation();
  220. });
  221. $(window).on('clicktap.addInlineAction', function() {
  222. this._handleBlur({
  223. 'currentTarget': $theInput
  224. });
  225. $(window).off('.addInlineAction');
  226. }.bind(this));
  227. } else {
  228. // Only attach the scroll event if we're not on an ipad since this sometimes
  229. // gets triggered when the keyboard opens
  230. // Weird way to bind but it's the only way to correctly be able to 'unbind' once we've created the folder
  231. listControl.$el.find('.dataTables_scrollBody').on('scroll', null, {
  232. 'input': $theInput,
  233. 'this': this
  234. }, this._onScroll);
  235. $theInput.focus();
  236. }
  237. },
  238. _onScroll: function(event) {
  239. var $theInput = event.data.input;
  240. var thisObj = event.data.this;
  241. // Lots of scrolling events when trying to scroll the TR into View. Only process scroll events
  242. // if we haven't had one for 250ms (i.e. after the scroll into view is done)
  243. var ellapsedTime = (new Date() - thisObj._scrollStartTime);
  244. if (ellapsedTime > 250) {
  245. $theInput.blur();
  246. return true;
  247. } else {
  248. thisObj._scrollStartTime = new Date();
  249. }
  250. },
  251. _handleBlur: function(evt) {
  252. //ensure we don't handle multiple blurs.
  253. if (this._blurTimeout) {
  254. return;
  255. }
  256. this._blurTimeout = window.setTimeout(function() {
  257. this._onBlurTimeout(evt);
  258. }.bind(this), 300);
  259. },
  260. _onBlurTimeout: function(evt) {
  261. this._clearBlurTimeout();
  262. // Detach the scroll event
  263. var listControl = this.getListControl();
  264. listControl.$el.find('.dataTables_scrollBody').off('scroll', null, this._onScroll);
  265. if (!this._isCancelled) {
  266. if (!this._handledSave) {
  267. var targetValue = $(evt.currentTarget).val();
  268. var oData = {
  269. 'defaultName': this._validateInput(targetValue),
  270. 'type': this.getType()
  271. };
  272. this._handledSave = true;
  273. this.sendAddRequest(oData, this.getListControl());
  274. }
  275. } else {
  276. this.cancel();
  277. }
  278. },
  279. _validateInput: function(inputString) {
  280. // remove whitespaces from both ends of the input string
  281. var trim = inputString ? inputString.trim() : '';
  282. // replace whitespace characters to normal space, could escape unicode non-breaking character
  283. trim = trim.replace(/\s/g, ' ');
  284. // use default if the trimmed input is empty
  285. return trim || this.getDefaultName();
  286. },
  287. // need to override, pass in data, listControl
  288. sendAddRequest: function() {
  289. return Promise.resolve(true);
  290. }
  291. });
  292. return AddInlineAction;
  293. });
  294. /*
  295. *+------------------------------------------------------------------------+
  296. *| Licensed Materials - Property of IBM
  297. *| IBM Cognos Products: Dashboard
  298. *| (C) Copyright IBM Corp. 2015, 2016
  299. *|
  300. *| US Government Users Restricted Rights - Use, duplication or disclosure
  301. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  302. *+------------------------------------------------------------------------+
  303. */
  304. define('bacontentnav/lib/gemini/dashboard/nls/DashboardResources',{
  305. "root": true,
  306. "cs": true,
  307. "da": true,
  308. "de": true,
  309. "es": true,
  310. "fi": true,
  311. "fr": true,
  312. "hr": true,
  313. "hu": true,
  314. "it": true,
  315. "ja": true,
  316. "kk": true,
  317. "ko": true,
  318. "no": true,
  319. "nb": true,
  320. "nl": true,
  321. "pl": true,
  322. "pt": true,
  323. "pt-br": true,
  324. "ro": true,
  325. "ru": true,
  326. "sl": true,
  327. "sv": true,
  328. "th": true,
  329. "tr": true,
  330. "zh": true,
  331. "zh-cn": true,
  332. "zh-tw": true
  333. });
  334. /**
  335. * Licensed Materials - Property of IBM
  336. *
  337. * IBM Cognos Products: BI Glass
  338. *
  339. * Copyright IBM Corp. 2017
  340. *
  341. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  342. */
  343. define('bacontentnav/lib/gemini/dashboard/nls/root/DashboardResources',{
  344. "noSourcesSelectedLabel": "No sources selected",
  345. "heatChartProp_colorPaletteLabel": "Color palettes",
  346. "barChartProp_hideGridLinesDescription": "Hide grid lines",
  347. "lineChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  348. "editDashboardCoachMarkContents": "Click the pencil icon to edit this dashboard.",
  349. "lineChartProp_lineColorLabel": "Line and symbol color",
  350. "lineChartProp_interpolationLabel": "Smooth lines",
  351. "NoPinsCollected": "No items collected",
  352. "clusterLineDataSlot_valuesRepeatingLabel": "Value",
  353. "moreMembers": "Show more...",
  354. "areaChartProp_interpolationDescription": "Lines connecting the data points are curved.",
  355. "radialChartCaption": "Radial",
  356. "clusterColumnName": "Column",
  357. "heatDataSlot_yAxisLabel": "Vertical axis",
  358. "stackedColumnDataSlot_categoriesLabel": "Axis label",
  359. "radialBarChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  360. "barChartCaption": "Bar",
  361. "mapDescription": "Legacy Map",
  362. "errorLoadingDataSetMetaData": "An error occurred while reading the metadata",
  363. "lineColumnComboChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  364. "backLabel": "Go back",
  365. "lineColumnComboChartProp_hideSymbolsLabel": "Hide symbols",
  366. "hideShowSummaries": "Hide show summaries",
  367. "pieChartDataSlot_categoriesLabel": "Categories",
  368. "bubbleDataSlot_yAxisLabel": "Vertical axis",
  369. "heatDescription": "Heat",
  370. "scatterPlotDescription": "Scatter plot",
  371. "tabName_general": "General",
  372. "lineChartProp_hideSymbolsDescription": "Hide symbols",
  373. "dataAssetPropertiesLabel": "Visualization properties",
  374. "treeMapName": "Tree map",
  375. "scatterPlotChartNoCatDataSlot_yAxisLabel": "Vertical axis",
  376. "tabName_animation": "Animation",
  377. "bodySmallTextLabel": "Body Small",
  378. "pointChart1catProp_symbolShapeLabel": "Symbol shape",
  379. "propWordColor": "Word color",
  380. "areaDataSlot_valuesLabel": "Value",
  381. "scatterPlotChartNoCatProp_elementColorLabel": "Element color",
  382. "heatChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  383. "columnChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  384. "areaChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  385. "packedBubbleChart1CatDataSlot_categoriesLabel": "Categories",
  386. "clusterBarDataSlot_categoriesLabel": "Axis label",
  387. "wordChart1Cat1MeasureProp_elementColorLabel": "Word color",
  388. "pieDescription": "Pie",
  389. "okButton": "OK",
  390. "lineColumnComboChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  391. "treeMapDataSlot_valuesLabel": "Size by",
  392. "lineChartProp_interpolationDescription": "Lines connecting the data points are curved.",
  393. "radialBarDataSlot_categoriesLabel": "Categories",
  394. "packedBubbleChart1CatProp_hideLabelLabel": "Hide label",
  395. "pointDataSlot_categoriesLabel": "Axis label",
  396. "areaChartDataSlot_valuesLabel": "Value",
  397. "imageWidgetLabel": "Image",
  398. "areaChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  399. "packedBubbleDataSlot_colorLabel": "Color by",
  400. "radialChartProp_hideRadialValueLabel": "Hide value",
  401. "clusterColumnDataSlot_valuesLabel": "Value",
  402. "barChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  403. "map1measureDataSlot_valuesLabel": "Region heat",
  404. "noStoryFound": "The story cannot be retrieved. Either it no longer exists or you don't have sufficient privileges to view it.",
  405. "addDataDashboardCoachMarkContents": "Drag and drop data from the data panel onto your dashboard.",
  406. "heatChartDataSlot_valuesLabel": "Heat by",
  407. "bubbleChartProp_colorPaletteLabel": "Color palettes",
  408. "selectTemplateLabel": "Select a template",
  409. "columnChartProp_hideGridLinesDescription": "Hide grid lines",
  410. "stackedColumnDescription": "Stack column",
  411. "sourcePaneLabel": "Selected sources",
  412. "propLineColor": "Line color",
  413. "radialChartProp_elementColorLabel": "Radial bar color",
  414. "noDashboardFound": "The dashboard cannot be retrieved. Either it no longer exists or you don't have sufficient privileges to view it.",
  415. "clusterLineName": "Line",
  416. "stackedColumnDataSlot_colorLabel": "Color by",
  417. "radialChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  418. "barChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  419. "heatChartProp_hideLegendDescription": "Hide the legend.",
  420. "tabName_textDetails": "Text details",
  421. "cmDuplicateName": "An item with this name already exists. Try another name",
  422. "editStoryCoachMarkTitle": "Edit story",
  423. "lineColumnComboChartProp_symbolShapeLabel": "Symbol shape",
  424. "HistogramYAxisTitle": "Count",
  425. "pinAddedToast": "Item was successfully collected",
  426. "crosstabName": "Crosstab",
  427. "lineColumnComboChartDataSlot_lineValueLabel": "Line value",
  428. "mapDataSlot_sizeHeatLabel": "Point heat",
  429. "propElementColor": "Visualization element color",
  430. "stackedColumnName": "Stack column",
  431. "wordChart1Cat1MeasureProp_suppressZerosLabel": "Hide empty",
  432. "addSourceLabel": "Add a source",
  433. "radialBarChartProp_colorPaletteLabel": "Color palettes",
  434. "treeMap1Cat1MeasureChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  435. "radialDataSlot_categoriesLabel": "Categories",
  436. "summaryChartDescription": "Summary",
  437. "heatChartProp_legendPositionLabel": "Legend position",
  438. "preAggregateLabel": "Apply prompt values from the data source",
  439. "wordChart1Cat1MeasureProp_maintainAxisScalesLabel": "Maintain axis scale",
  440. "noStoryPermision": "You do not have sufficient privileges to view this story",
  441. "pieDataSlot_valuesLabel": "Value",
  442. "heatName": "Heat",
  443. "lineColumnComboChartProp_hideLegendLabel": "Hide legend",
  444. "pieChartDataSlot_valuesLabel": "Value",
  445. "pieName": "Pie",
  446. "darkThemeLabel": "Dark",
  447. "lineColumnComboChartDataSlot_categoryLabel": "Axis label",
  448. "map1measureProp_heatScalePaletteLabel": "Color order",
  449. "barChartProp_suppressZerosLabel": "Hide empty",
  450. "pointChart1catProp_colorPaletteLabel": "Color palettes",
  451. "pieChartProp_legendPositionLabel": "Legend position",
  452. "tabName_visDetails": "Details",
  453. "wordCloudDataSlot_colorLabel": "Color by",
  454. "treeMapDescription": "Tree map",
  455. "treeMap1Cat1MeasureChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  456. "bubbleChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  457. "lineColumnComboDataSlot_lineValueLabel": "Line value",
  458. "bubbleChartProp_hideGridLinesDescription": "Hide grid lines",
  459. "stackedBarDataSlot_valuesRepeatingLabel": "Value",
  460. "noMatchDatasets": "No matched data sets found.",
  461. "scatterPlotDataSlot_yAxisLabel": "Vertical axis",
  462. "timelineAnimationProperties": "Open animation properties",
  463. "quoteSmallTextLabel": "Quote Small",
  464. "value_is_not_available": "N/A",
  465. "barChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  466. "areaName": "Area",
  467. "bubbleChartDataSlot_sizeLabel": "Size by",
  468. "packedBubbleChart1CatProp_suppressZerosDescription": "Hide categories with no associated values.",
  469. "treeMap1Cat1MeasureChartProp_hideLegendLabel": "Hide legend",
  470. "treeMap1Cat1MeasureChartProp_colorPaletteLabel": "Color palettes",
  471. "postAggregateLabel": "Apply prompt values in the report",
  472. "pointChart1catDataSlot_categoriesLabel": "Axis label",
  473. "scatterPlotDataSlot_categoriesLabel": "Points",
  474. "metadataPickerTitle": "Create Data Set",
  475. "pieChartProp_pieAsDonutLabel": "Display as donut chart",
  476. "areaDescription": "Area",
  477. "scatterPlotName": "Scatter plot",
  478. "packedBubbleName": "Packed bubble",
  479. "areaChartProp_lineColorLabel": "Area color",
  480. "bubbleChartDataSlot_xAxisLabel": "Horizontal axis",
  481. "scatterPlotChartNoCatProp_symbolShapeLabel": "Symbol shape",
  482. "bubbleChartProp_hideLegendLabel": "Hide legend",
  483. "lineColumnComboChartProp_hideLegendDescription": "Hide the legend.",
  484. "lineColumnComboDataSlot_categoryLabel": "Axis label",
  485. "radialName": "Radial",
  486. "clusterLineDataSlot_colorLabel": "Color by",
  487. "propHideEmpty": "Hide empty",
  488. "heatChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  489. "columnChartProp_elementColorLabel": "Column color",
  490. "shapesDoubleChevron": "Double chevron",
  491. "lineColumnComboChartProp_elementColorLabel": "Column color",
  492. "playerDescription": "Data player",
  493. "map1measureProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  494. "lineColumnComboChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  495. "stackedColumnDataSlot_valuesLabel": "Value",
  496. "clusterBarDescription": "Bar",
  497. "packedBubbleChart1CatProp_suppressZerosLabel": "Hide empty",
  498. "areaChartProp_suppressZerosLabel": "Hide empty",
  499. "clearFilterValueToolTip": "Clear filter values",
  500. "treeMap1Cat1MeasureChartProp_hideLegendDescription": "Hide the legend.",
  501. "lineChartProp_hideGridLinesDescription": "Hide grid lines",
  502. "noDashboardCapability": "You do not have the capability to run the dashboard application",
  503. "timeline_filter_moved_to": "Time line filter %{id} moved to %{time}",
  504. "packedBubbleDataSlot_categoriesLabel": "Categories",
  505. "lineChartProp_hideDataLinesLabel": "Hide line(s)",
  506. "cmEmptySelectionStory": "The story has been deleted. Try to save as a new story",
  507. "barChartDataSlot_valuesLabel": "Value",
  508. "dataset_location": "location",
  509. "bodyTextLabel": "Body",
  510. "gridName": "Grid",
  511. "dataset_time": "time",
  512. "bubbleChartDataSlot_colorLabel": "Color by",
  513. "dashboard": "Dashboard",
  514. "propRadialbarColor": "Radial bar color",
  515. "areaChartProp_interpolationLabel": "Smooth lines",
  516. "radialBarChartProp_suppressZerosLabel": "Hide empty",
  517. "cmEmptySelection": "The dashboard has been deleted. Try to save as a new dashboard",
  518. "clusterBarDataSlot_valuesLabel": "Value",
  519. "stackedBarDataSlot_colorLabel": "Color by",
  520. "deletePinConfirm": "Confirm delete",
  521. "areaChartProp_colorPaletteLabel": "Color palettes",
  522. "propLineAndSymbolColor": "Line and symbol color",
  523. "barChartDataSlot_categoriesLabel": "Axis label",
  524. "createDashboardTitle": "Create dashboard",
  525. "pieChartProp_suppressZerosLabel": "Hide empty",
  526. "treeMapDataSlot_colorLabel": "Heat by",
  527. "columnChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  528. "wordChart1Cat1MeasureDataSlot_wordLabel": "Words",
  529. "webpageWidgetLabel": "Webpage",
  530. "pieChartProp_pieAsDonutDescription": "Display as donut chart",
  531. "panAndZoomShimCoachmarkContent": "Select this story type to create an animated presentation that pans and zooms from scene to scene.",
  532. "radialBarDataSlot_valuesLabel": "Value",
  533. "treeMap2Cat2MeasureChartProp_colorPaletteLabel": "Color palettes",
  534. "scatterPlotChartNoCatProp_colorPaletteLabel": "Color palettes",
  535. "lineChartProp_hideDataLinesDescription": "Hide line(s)",
  536. "treeMap1Cat2MeasureChartProp_colorPaletteLabel": "Color palettes",
  537. "lineColumnComboChartCaption": "Line and column",
  538. "wordCloudDataSlot_scaleLabel": "Size by",
  539. "pinDeletedToast": "Collected item was removed",
  540. "radialDescription": "Radial",
  541. "areaChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  542. "wordChart1Cat1MeasureProp_colorPaletteLabel": "Color palettes",
  543. "heatDataSlot_xAxisLabel": "Horizontal axis",
  544. "heatChartDataSlot_yAxisLabel": "Vertical axis",
  545. "lineColumnComboChartDataSlot_columnValueLabel": "Column value",
  546. "lineChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  547. "treeMap1Cat1MeasureChartCaption": "Tree map",
  548. "summaryChartName": "Summary",
  549. "subtitleTextLabel": "Subtitle",
  550. "bubbleDataSlot_xAxisLabel": "Horizontal axis",
  551. "lineChartProp_hideGridLinesLabel": "Hide grid lines",
  552. "pointChart1catProp_suppressZerosDescription": "Hide categories with no associated values.",
  553. "captionTextLabel": "Caption",
  554. "pointChart1catProp_maintainAxisScalesLabel": "Maintain axis scale",
  555. "heatChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  556. "radialDataSlot_valuesLabel": "Value",
  557. "lineColumnComboChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  558. "pointChart1catProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  559. "clusterColumnDataSlot_colorLabel": "Color by",
  560. "bubbleChartProp_hideGridLinesLabel": "Hide grid lines",
  561. "lineColumnComboName": "Line and column",
  562. "packedBubbleDataSlot_sizeLabel": "Size by",
  563. "radialChartProp_colorPaletteLabel": "Color palettes",
  564. "pieChartCaption": "Pie",
  565. "addDataCoachMarkTitle": "Add data",
  566. "scatterPlotChartNoCatDataSlot_xAxisLabel": "Horizontal axis",
  567. "barChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  568. "radialBarChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  569. "lineChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  570. "pinLabel": "Collection",
  571. "wordChart1Cat1MeasureProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  572. "heatChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  573. "radialBarChartDataSlot_valuesLabel": "Value",
  574. "map1measureProp_maintainAxisScalesLabel": "Maintain axis scale",
  575. "mediaWidgetLabel": "Media",
  576. "columnChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  577. "radialBarChartDataSlot_categoriesLabel": "Categories",
  578. "stackedBarDataSlot_valuesLabel": "Value",
  579. "radialChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  580. "playerDataSlot_categoriesLabel": "Axis label",
  581. "mapName": "Legacy Map",
  582. "pieChartProp_hideLegendDescription": "Hide the legend.",
  583. "swapRowsAndColumns": "Swap rows and columns",
  584. "treeMapDataSlot_level3Label": "Level three",
  585. "editDashboardCoachMarkTitle": "Edit dashboard",
  586. "bubbleDataSlot_colorLabel": "Color by",
  587. "clusterLineDataSlot_categoriesLabel": "Horizontal axis",
  588. "mapDataSlot_sizeLabel": "Point size",
  589. "lineColumnComboChartProp_lineColorLabel": "Line and symbol color",
  590. "lineChartDataSlot_valuesLabel": "Value",
  591. "radialBarChartCaption": "Radial bar",
  592. "expandSceneCoachmarkContent": "Animate a scene by adjusting object visibility based on time and duration.",
  593. "titleSmallTextLabel": "Title Small",
  594. "addDataStoryCoachMarkContents": "Drag and drop data from the data panel onto your story.",
  595. "bubbleChartCaption": "Bubble",
  596. "pointChart1catProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  597. "areaChartProp_hideGridLinesLabel": "Hide grid lines",
  598. "lineChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  599. "errorLoadingDataSet": "The metadata for data set '%{datasetName}' did not load. Please contact your administrator for details.",
  600. "treeMap3Cat1MeasureChartProp_colorPaletteLabel": "Color palettes",
  601. "clusterBarDataSlot_colorLabel": "Color by",
  602. "scatterPlotChartNoCatProp_symbolFillLabel": "Fill shape",
  603. "titleTextLabel": "Title",
  604. "dataset_date": "date",
  605. "pointDescription": "Point",
  606. "bubbleDescription": "Bubble",
  607. "treeMap2Cat1MeasureChartProp_colorPaletteLabel": "Color palettes",
  608. "tabName_webDetails": "Web page details",
  609. "clusterColumnDescription": "Column",
  610. "applyFilter": "Apply filter",
  611. "lineColumnComboChartProp_suppressZerosLabel": "Hide empty",
  612. "dataset_number": "number",
  613. "columnChartCaption": "Column",
  614. "wordCloudName": "Word cloud",
  615. "map1measureProp_suppressZerosDescription": "Hide categories with no associated values.",
  616. "lineChartProp_hideSymbolsLabel": "Hide Symbols",
  617. "scatterPlotChartNoCatProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  618. "pointChart1catProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  619. "find_label": "Find",
  620. "invertSelectionToolTip": "Invert filter selections",
  621. "intentSearchTitle": "Create a visualization based on your search",
  622. "lineColumnComboChartProp_interpolationLabel": "Smooth lines",
  623. "overviewCoachmarkTitle": "Overview scenes",
  624. "bubbleName": "Bubble",
  625. "columnChartDataSlot_valuesLabel": "Value",
  626. "radialBarName": "Radial bar",
  627. "areaDataSlot_categoriesLabel": "Axis label",
  628. "treeMap1Cat1MeasureChartDataSlot_categoriesLabel": "Level one",
  629. "pointChart1catProp_symbolFillDescription": "Display fill color for the symbols.",
  630. "pieChartProp_hideLegendLabel": "Hide legend",
  631. "summaryChartDataSlot_valuesLabel": "Value",
  632. "packedBubbleChart1CatProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  633. "barChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  634. "radialChartProp_suppressZerosLabel": "Hide empty",
  635. "packedBubbleChart1CatProp_elementColorLabel": "Bubble color",
  636. "radialBarChartProp_hideRadialTitleLabel": "Hide title",
  637. "treeMap1Cat1MeasureChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  638. "invertFilterSelection": "Invert",
  639. "gridDescription": "Grid",
  640. "columnChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  641. "mapDataSlot_categoriesLabel": "Regions",
  642. "lineColumnComboDataSlot_columnValueLabel": "Column value",
  643. "defaultName": "New dashboard",
  644. "scatterPlotChartNoCatProp_symbolFillDescription": "Display fill color for the symbols.",
  645. "story": "Story",
  646. "expandSceneCoachmarkTitle": "Open timeline",
  647. "editStoryCoachMarkContents": "Click the pencil icon to edit this story.",
  648. "treeMapDataSlot_level2Label": "Level two",
  649. "areaDataSlot_colorLabel": "Color by",
  650. "previewUnavailable": "The data tray and global filters are unavailable for Framework Manager packages.",
  651. "clusterLineDataSlot_valuesLabel": "Vertical axis",
  652. "heatChartCaption": "Heat",
  653. "columnChartProp_colorPaletteLabel": "Color palettes",
  654. "lineColumnComboDescription": "Line and column",
  655. "stackedBarName": "Stack bar",
  656. "lineColumnComboChartProp_colorPaletteLabel": "Color palettes",
  657. "areaChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  658. "map1measureProp_hideLegendDescription": "Hide the legend.",
  659. "errorLoadingDataSets": "An error occurred while loading the list of data sets",
  660. "map1measureProp_colorPaletteLabel": "Color palettes",
  661. "map1measureDataSlot_categoriesLabel": "Regions",
  662. "pinDeleteError": "We can't delete one or more assets from the collection. Try again later.",
  663. "noDashboardPermision": "You do not have sufficient privileges to view this dashboard",
  664. "wordCloudDescription": "Word cloud",
  665. "deletePin": "Delete the collected item",
  666. "areaChartDataSlot_categoriesLabel": "Axis label",
  667. "scatterPlotDataSlot_xAxisLabel": "Horizontal axis",
  668. "createStoryTitle": "Create story",
  669. "radialChartProp_hideRadialTitleLabel": "Hide title",
  670. "clusterColumnDataSlot_categoriesLabel": "Axis label",
  671. "overviewCoachmarkContent": "Use the overview scenes at the start and end of your story to show the big picture of all the scenes. From an overview scene, click and drag a scene to swap it with another scene. You can show or hide the overview scenes in the story properties.",
  672. "heatChartProp_heatScalePaletteLabel": "Color order",
  673. "intentSearchLabel": "Intent search",
  674. "cancelButton": "Cancel",
  675. "wordChart1Cat1MeasureDataSlot_scaleLabel": "Size by",
  676. "lineChartProp_colorPaletteLabel": "Color palettes",
  677. "treeMap3Cat2MeasureChartProp_colorPaletteLabel": "Color palettes",
  678. "lineColumnComboChartProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  679. "itemCountText": "%{itemCount} Item(s) selected",
  680. "radialChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  681. "radialChartDataSlot_categoriesLabel": "Categories",
  682. "pointChart1catProp_suppressZerosLabel": "Hide empty",
  683. "pinRetrieveError": "We can't retrieve one or more collected items. Try again later.",
  684. "bubbleChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  685. "scatterPlotChartNoCatCaption": "Scatter plot",
  686. "wordChart1Cat1MeasureCaption": "Word cloud",
  687. "lineChartProp_symbolShapeLabel": "Symbol shape",
  688. "propColumnColor": "Column color",
  689. "barChartProp_hideGridLinesLabel": "Hide grid lines",
  690. "pieChartProp_hideRadialValueLabel": "Hide value",
  691. "scatterPlotDataSlot_colorLabel": "Color by",
  692. "unSupportedPromptType": "The prompt scenario is not currently supported.",
  693. "missingDataSetData": "The data for this data set is not available. Refresh the data set or contact your administrator for access to the source.",
  694. "columnChartProp_suppressZerosLabel": "Hide empty",
  695. "heatChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  696. "treeMap1Cat1MeasureChartProp_suppressZerosLabel": "Hide empty",
  697. "addDataSourceDialogButtonLabel": "Add",
  698. "timelineFilter": "Add filter",
  699. "map1measureProp_suppressZerosLabel": "Hide empty",
  700. "wordChart1Cat1MeasureProp_suppressZerosDescription": "Hide categories with no associated values.",
  701. "propHideLeafNode": "Hide Lead Labels",
  702. "heatChartProp_suppressZerosLabel": "Hide empty",
  703. "lineColumnComboChartProp_hideGridLinesLabel": "Hide grid lines",
  704. "radialBarChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  705. "deletePinConfirmationMessage": "Are you sure you want to delete this collected item? This cannot be undone.",
  706. "treeMapDataSlot_categoriesLabel": "Level one",
  707. "sweepTransitionLabel": "Sweep",
  708. "packedBubbleChart1CatCaption": "Packed bubble",
  709. "clusterBarDataSlot_valuesRepeatingLabel": "Value",
  710. "bubbleChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  711. "packedBubbleChart1CatProp_maintainAxisScalesLabel": "Maintain axis scale",
  712. "pointChart1catDataSlot_valuesLabel": "Value",
  713. "pointChart1catCaption": "Point",
  714. "mapDataSlot_valuesLabel": "Region heat",
  715. "lineChartProp_maintainAxisScalesDescription": "Always display the minimum and maximum values on the axes.",
  716. "conditionalPalettePickerLabel": "Distribution of %{title} values",
  717. "tabName_imageDetails": "Image details",
  718. "pointDataSlot_colorLabel": "Color by",
  719. "propColorOrder": "Color order",
  720. "heatDataSlot_valuesLabel": "Heat by",
  721. "areaChartCaption": "Area",
  722. "radialDataSlot_maxSizeLabel": "Maximum value",
  723. "treeMap1Cat1MeasureChartProp_legendPositionLabel": "Legend position",
  724. "pieChartProp_suppressZerosDescription": "Hide categories with no associated values.",
  725. "noTransitionLabel": "None",
  726. "map1measureProp_hideLegendLabel": "Hide legend",
  727. "packedBubbleChart1CatProp_hideValueLabel": "Hide value",
  728. "heatChartProp_hideLegendLabel": "Hide legend",
  729. "pieDataSlot_categoriesLabel": "Categories",
  730. "errorLabel": "Error",
  731. "lineColumnComboChartProp_hideGridLinesDescription": "Hide grid lines",
  732. "tabName_mediaDetails": "Media details",
  733. "quoteTextLabel": "Quote",
  734. "propColorPalettes": "Color palettes",
  735. "radialBarChartProp_elementColorLabel": "Radial bar color",
  736. "noStoryCapability": "You do not have the capability to use stories",
  737. "pointDataSlot_valuesLabel": "Value",
  738. "defaultStoryName": "New story",
  739. "clusterLineDescription": "Line",
  740. "panAndZoomShimCoachmarkTitle": "Guided journey",
  741. "defaultThemeLabel": "Default",
  742. "modelFilter": "Filter",
  743. "sourceNotFound": "We can't load the visualization, because its associated source '%{sourceName}' isn't available",
  744. "propBarColor": "Bar color",
  745. "sceneTransitionPropertyLabel": "Scene transition",
  746. "radialBarDescription": "Radial bar",
  747. "propAreaColor": "Area color",
  748. "progressiveTransitionLabel": "Progressive",
  749. "clusterBarName": "Bar",
  750. "gridDataSlot_grid_colsLabel": "Column",
  751. "wordCloudDataSlot_wordLabel": "Words",
  752. "areaChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  753. "treeMap1Cat1MeasureChartDataSlot_valuesLabel": "Size by",
  754. "heatChartDataSlot_xAxisLabel": "Horizontal axis",
  755. "bubbleChartDataSlot_yAxisLabel": "Vertical axis",
  756. "clearTextFilterValue": "Clear",
  757. "radialChartDataSlot_valuesLabel": "Value",
  758. "stackedBarDataSlot_categoriesLabel": "Axis label",
  759. "responsiveTextLabel": "Auto-size",
  760. "pointChart1catProp_symbolFillLabel": "Fill shape",
  761. "barChartProp_elementColorLabel": "Bar color",
  762. "bubbleChartProp_hideAxisTitleLabelsLabel": "Hide axis title labels",
  763. "searchHierarchyMembers": "Use search to find members...",
  764. "map1measureProp_legendPositionLabel": "Legend position",
  765. "pointName": "Point",
  766. "itemExcludeCountText": "%{itemCount} Item(s) excluded",
  767. "scatterPlotChartNoCatProp_hideGridLinesLabel": "Hide grid lines",
  768. "pointChart1catProp_elementColorLabel": "Shape color",
  769. "lineColumnComboChartProp_interpolationDescription": "Lines connecting the data points are curved.",
  770. "filter_includesAll": "Includes all",
  771. "moreTitle": "More",
  772. "lineColumnComboChartProp_hideDataLinesDescription": "Hide line(s)",
  773. "dataset_text": "text",
  774. "preAggregateText": "The range uses the values in the data source, not the values displayed in the dashboard.",
  775. "pointChart1catProp_hideGridLinesLabel": "Hide grid lines",
  776. "widgetConditionalFormatLabel": "Toggle conditional format controls",
  777. "lineColumnComboChartProp_hideSymbolsDescription": "Hide symbols",
  778. "stackedColumnDataSlot_valuesRepeatingLabel": "Value",
  779. "barChartProp_colorPaletteLabel": "Color palettes",
  780. "bubbleChartProp_hideLegendDescription": "Hide the legend.",
  781. "areaChartProp_hideGridLinesDescription": "Hide grid lines",
  782. "clusterColumnDataSlot_valuesRepeatingLabel": "Value",
  783. "remove_slider_handle": "Remove handle",
  784. "packedBubbleChart1CatDataSlot_sizeLabel": "Size by",
  785. "summaryCaption": "Summary",
  786. "addDataSourceDialogTitle": "Add a data source",
  787. "lineChartCaption": "Line",
  788. "bubbleChartProp_legendPositionLabel": "Legend position",
  789. "columnChartDataSlot_categoriesLabel": "Axis label",
  790. "lineChartDataSlot_categoriesLabel": "Axis label",
  791. "columnChartProp_hideGridLinesLabel": "Hide grid lines",
  792. "scatterPlotChartNoCatProp_hideGridLinesDescription": "Hide grid lines",
  793. "lineChartProp_suppressZerosLabel": "Hide empty",
  794. "scatterPlotChartNoCatProp_hideAxisTitleLabelsDescription": "Hide the titles for the axes.",
  795. "pointChart1catProp_hideGridLinesDescription": "Hide grid lines",
  796. "lineColumnComboChartProp_legendPositionLabel": "Legend position",
  797. "bubbleDataSlot_sizeLabel": "Size by",
  798. "columnChartProp_maintainAxisScalesLabel": "Maintain axis scale",
  799. "lightThemeLabel": "Light",
  800. "packedBubbleChart1CatProp_colorPaletteLabel": "Color palettes",
  801. "map1measureCaption": "Map",
  802. "packedBubbleDescription": "Packed bubble",
  803. "stackedBarDescription": "Stack bar",
  804. "lineColumnComboChartProp_hideDataLinesLabel": "Hide line(s)",
  805. "pieChartProp_colorPaletteLabel": "Color palettes",
  806. "playerName": "Data player"
  807. });
  808. /**
  809. * Licensed Materials - Property of IBM
  810. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  811. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  812. */
  813. define('bacontentnav/lib/gemini/app/nls/DashboardResources',{
  814. root: {
  815. // Application Title
  816. 'appTitle': 'Project Gemini',
  817. 'appExit': 'Go to Welcome page',
  818. 'widgetsListLabel': 'Widgets list. Select a widget and press enter to add.',
  819. //General
  820. listSeparator: ', ',
  821. pointSeparator: ':',
  822. 'insync': 'Up-to-date',
  823. 'dirty': 'Not up-to-date',
  824. 'conflict': 'Conflict saving the view',
  825. 'error': 'Problem saving the view',
  826. 'failure': 'Unable to contact the server',
  827. 'saveFailed': 'Unable to save the view',
  828. 'wa_insync': 'Saved',
  829. 'wa_conflict': 'Conflict saving the view',
  830. 'wa_error': 'Unable to save the view',
  831. 'wa_failure': 'Unable to contact the server',
  832. // Menu Labels
  833. 'changeDisplay': 'Change display',
  834. 'changeToColumnChart': 'Change to column chart',
  835. 'changeToBubbleChart': 'Change to bubble chart',
  836. 'toggleMoveHandles': 'Toggle move handles',
  837. 'undo': 'Undo',
  838. 'redo': 'Redo',
  839. 'mode': 'Change the mode',
  840. 'untitled': 'Untitled',
  841. 'remove': 'Remove',
  842. 'editTitle': 'Edit the title',
  843. 'edit': 'Edit',
  844. 'done': 'Done',
  845. // Create a board
  846. 'createAV': 'Create',
  847. 'createAvEditNameLabel': '1. Name your view',
  848. 'createAvSelectTemplateLabel': '2. Select a template',
  849. 'selectTemplateLabel': 'Select a template',
  850. 'singlePageLayoutLabel': 'Single page layout',
  851. 'tabLayoutLabel': 'Tabbed layout',
  852. 'slideShowLayoutLabel': 'Slide show layout',
  853. 'panAndZoomLayoutLabel': 'Guided journey layout',
  854. 'panAndZoomShimLayoutFooter': 'A guided journey layout is a collection of scenes on a single canvas. When you run this type of story, the presentation zooms and pans on each individual scene in sequential order. This differs from a slide show layout where each scene is presented on a new canvas. The guided journey layout with three scenes connected by lines allows you to create a horizontal sequence of scenes. This is useful for showing a timeline.',
  855. 'infographicsLayoutLabel': 'Infographic layout',
  856. 'panAndZoomShimLayoutLabel': 'Guided journey layout',
  857. 'freeformTemplate': 'Freeform',
  858. 'freeformTemplateDesc': 'Visualizations in a freeform layout appear exactly as you size and place them in the view, regardless of the screen size. In the other layouts, the size and position of visualizations adjust to fit into the screen.',
  859. //label for each template
  860. 'NoTemplate': 'Free form',
  861. 'Template1': 'Blank',
  862. 'Template2': 'Title 1 by 2',
  863. 'Template3': '2 over 1',
  864. 'Template4': '4 over 1',
  865. 'Template5': 'Footer 1 by 2 ',
  866. 'Template6': '3 beside 1 over 1',
  867. 'Template7': '4 beside 3 over 1',
  868. 'Template8': '2 over 3 by 2',
  869. 'Template9': '2 by 2',
  870. 'Template10': '1 by 2 beside 2 by 2 over 1',
  871. 'Template11': '3 by 1 over 1 by 2',
  872. 'Template12': '2 over 1 beside 1 by 2',
  873. 'Template13': 'One beside 1 by 2 beside 1 by 4',
  874. 'Infographics1': 'Blank',
  875. 'Infographics2': '4 rows',
  876. 'Infographics3': '4 rows with headers',
  877. 'Infographics4': '2 by 4',
  878. 'Infographics5': 'Large top display with 2 by 2',
  879. 'Infographics6': '2 by 4 with vertical gap',
  880. 'Infographics7': '2 by 4 staggered',
  881. 'Infographics8': 'Tennis court',
  882. 'Infographics9': '3 by 4',
  883. 'Infographics10': '4 by 8',
  884. 'PanAndZoomShim1': '5 scenes arranged in a rectangular shape',
  885. 'PanAndZoomShim2': '4 scenes arranged in a staircase shape going up from left to right',
  886. 'PanAndZoomShim3': '6 scenes arranged in a rectangular shape',
  887. 'PanAndZoomShim4': '7 scenes arranged in a rectangular shape, with 6 small scenes on the top and 1 large scene on the bottom',
  888. 'PanAndZoomShim5': '4 scenes arranged with 2 small scenes on the top, 1 large scene in the middle, and 1 small scene on the bottom-left',
  889. 'PanAndZoomShim6': 'A sequence of 4 scenes arranged horizontally',
  890. // Objects
  891. 'createAvDashboardLabel': 'Dashboard',
  892. 'createAvDataStoryLabel': 'Story',
  893. // Templates
  894. 'createAvSinglePageLabel': 'Single page',
  895. 'createAvTabLabel': 'Tabbed',
  896. 'createAvInfographicsLabel': 'Infographic',
  897. 'createAvSlideShowLabel': 'Slide show',
  898. 'createAvPanAndZoomLabel': 'Guided journey',
  899. // Data tray
  900. 'dataTrayHandleOpenLabel': 'Open data tray',
  901. 'dataTrayHandleCloseLabel': 'Close data tray',
  902. 'dataTrayHandleOpenLabelSceneSelector': 'Open scene selector',
  903. 'dataTrayHandleCloseLabelSceneSelector': 'Close scene selector',
  904. // Dialogs
  905. 'dlg_loading': 'Loading...',
  906. 'dlg_ok': 'OK',
  907. 'dlg_cancel': 'Cancel',
  908. 'dlg_close': 'Close',
  909. 'dlg_update': 'Update',
  910. 'dlg_renameBoardTitle': 'Rename this object',
  911. 'dlg_renameDatasetTitle': 'Rename this data set',
  912. 'dlg_renameSceneTitle': 'Rename this scene',
  913. 'dlg_NameLabel': 'Name:',
  914. 'dlg_NewNameLabel': 'New name:',
  915. 'dlg_DefaultNameWithDataSet': '%{name} View',
  916. 'dlg_ShareTitle': 'Share content',
  917. 'dlg_UnshareTitle': 'Remove content sharing',
  918. 'dlg_ShareUser': 'User ID:',
  919. 'dlg_NewColumnLabel': 'New calculation name',
  920. 'dlg_new': 'New...',
  921. 'dlg_open': 'Open...',
  922. 'dlg_makeACopy': 'Make a copy',
  923. 'dlg_rename': 'Rename...',
  924. 'dlg_moreToCome': 'More actions coming...',
  925. 'dlg_createStory': 'Create a story',
  926. 'dlg_use': 'Use',
  927. 'dlg_IntentResultsTitle': 'Select a data set',
  928. 'dlg_IntentHeaderName': 'Name',
  929. 'dlg_IntentHeaderDate': 'Date',
  930. 'dlg_IntentSearchClear': 'Clear intent search terms',
  931. 'dlg_IntentNoMatch': 'We can\'t find any matches. Try again with different terms.',
  932. 'dlg_RelinkDatasetTitle': 'Replace data set \'%{datasetName}\' with ...',
  933. open_error: 'A problem occurred while opening the view.',
  934. // Delete Board
  935. 'del_dialogTitle': 'Confirm deletion',
  936. 'del_itemMsg': 'Are you sure you want to delete \'%{name}\'?',
  937. 'del_itemsMsg': 'Are you sure you want to delete %{count} items?',
  938. 'del_deleteErr': 'Unable to delete \'%{name}\'',
  939. // List Sorting
  940. 'dlg_ascending': 'ascending',
  941. 'dlg_descending': 'descending',
  942. 'dlg_custom': 'custom',
  943. 'dlg_none': 'none',
  944. // Input Placeholders
  945. 'search': 'Search',
  946. 'searchHint': 'Search all your data',
  947. 'clearSearchResult': 'Clear search results',
  948. // Shapes and shapes categories
  949. // Basic shapes
  950. 'shapesBasicShapesCat': 'Basic',
  951. 'shapesCircle': 'Circle',
  952. 'shapesHexagon': 'Hexagon',
  953. 'shapesLine': 'Line',
  954. 'shapesOctagon': 'Octagon',
  955. 'shapesPentagon': 'Pentagon',
  956. 'shapesSquare': 'Square',
  957. 'shapesTriangle': 'Triangle',
  958. 'shapesDiamond': 'Diamond',
  959. 'shapesTitle': 'Shape properties',
  960. // Advanced shapes
  961. 'shapesAdvancedShapesCat': 'Advanced',
  962. 'shapesSquareRounded': 'Rounded square',
  963. 'shapesStar': 'Star',
  964. 'shapesChevron': 'Chevron',
  965. 'shapesBadge_ribbon': 'Badge ribbon',
  966. 'shapesBadge': 'Badge',
  967. 'shapesHeart': 'Heart',
  968. 'shapesExclamation': 'Exclamation',
  969. 'shapesTrendingup': 'Trending up',
  970. 'shapesTrendingdown': 'Trending down',
  971. 'shapesX': 'X',
  972. // People shapes
  973. 'shapesPeopleCat': 'People',
  974. 'shapesFemale': 'Female',
  975. 'shapesHappyface': 'Happy face',
  976. 'shapesMale': 'Male',
  977. 'shapesMan': 'Man',
  978. 'shapesNeutralface': 'Neutral face',
  979. 'shapesSadface': 'Sad face',
  980. 'shapesShakehands': 'Shake hands',
  981. 'shapesThumbsdown': 'Thumbs down',
  982. 'shapesThumbsup': 'Thumbs up',
  983. 'shapesWoman': 'Woman',
  984. // Weather and places
  985. 'shapesPlacesWeatherCat': 'Places & weather',
  986. 'shapesCity': 'City',
  987. 'shapesCloud': 'Cloud',
  988. 'shapesEducation': 'Education',
  989. 'shapesGovernment': 'Government',
  990. 'shapesHalfcloud': 'Half cloud',
  991. 'shapesHouse': 'House',
  992. 'shapesMoon': 'Moon',
  993. 'shapesRain': 'Rain',
  994. 'shapesSunny': 'Sunny',
  995. //Vehicles
  996. 'shapesVehiclesCat': 'Vehicles',
  997. 'shapesAirplane': 'Airplane',
  998. 'shapesCar': 'Car',
  999. 'shapesShip': 'Ship',
  1000. 'shapesShoppingcart': 'Shopping cart',
  1001. 'shapesTrain': 'Train',
  1002. 'shapesTruck': 'Truck',
  1003. //Objects
  1004. 'shapesObjectsCat': 'Objects',
  1005. 'shapesBook': 'Book',
  1006. 'shapesBriefcase': 'Briefcase',
  1007. 'shapesCalendar': 'Calendar',
  1008. 'shapesCheck': 'Check',
  1009. 'shapesClock': 'Clock',
  1010. 'shapesDesktop': 'Desktop',
  1011. 'shapesDocument': 'Document',
  1012. 'shapesFood': 'Food',
  1013. 'shapesGear': 'Gear',
  1014. 'shapesHealth': 'Health',
  1015. 'shapesIdea': 'Idea',
  1016. 'shapesMobile': 'Mobile',
  1017. 'shapesMoney_bill': 'Money bill',
  1018. 'shapesMoney_coin': 'Money coin',
  1019. 'shapesPiggybank': 'Piggy bank',
  1020. 'shapesStackofpaper': 'Stack of paper',
  1021. 'shapesStickynote1': 'Sticky Note 1',
  1022. 'shapesStickynote2': 'Sticky Note 2',
  1023. 'shapesTarget': 'Target',
  1024. 'shapesTool': 'Tool',
  1025. 'shapesUmbrella': 'Umbrella',
  1026. 'shapesBrain': 'Brain',
  1027. 'shapesSkull': 'Skull',
  1028. 'shapesEye': 'Eye',
  1029. // Arrows shapes
  1030. 'shapesArrowsCat': 'Arrows',
  1031. 'shapesRightArrow': 'Right arrow',
  1032. 'shapesLeftArrow': 'Left arrow',
  1033. 'shapesDoubleArrow': 'Double arrow',
  1034. 'shapesCurvedArrow': 'Curved arrow',
  1035. // Callouts shapes
  1036. 'shapesCalloutsCat': 'Callouts',
  1037. 'shapesRectCallout': 'Callout',
  1038. // Images
  1039. 'imageWidgetTitle': 'Image widget',
  1040. 'imageTextLabel': 'Paste the URL and press Enter to save it',
  1041. 'imgUrl': 'Image URL',
  1042. 'imgPasteLink': 'Paste the URL and press Enter to save it',
  1043. 'imgAltText': 'Alternate text',
  1044. 'imgAltTextDescription': 'Text that is read by a screen reader',
  1045. 'imgResizeToFit': 'Resize to fit the image\'s size',
  1046. 'imgHeight': 'Height:',
  1047. 'imgWidth': 'Width:',
  1048. 'imgTransparency': 'Transparency:',
  1049. 'imgMissingUrl': 'The image URL is missing',
  1050. 'imgUrlValidationError': 'The image URL is not valid',
  1051. // Data player widget
  1052. 'playButtonLabel': 'Play',
  1053. 'dataPlayerValueListLabel': 'Data player values',
  1054. // Text Widget
  1055. 'textStyle': 'Styles',
  1056. 'textStyleDescription': 'Preformatted text styles',
  1057. 'textTitleStyle': 'Title',
  1058. 'textTitleSmallStyle': 'Title small',
  1059. 'textSubtitleStyle': 'Subtitle',
  1060. 'textBodyStyle': 'Body',
  1061. 'textBodySmallStyle': 'Body small',
  1062. 'textCaptionStyle': 'Caption',
  1063. 'textQuoteStyle': 'Quote',
  1064. 'textQuoteSmallStyle': 'Quote small',
  1065. 'textResponsiveStyle': 'Auto-size',
  1066. 'textAutoFontSize': 'Auto',
  1067. 'responsiveCoachmarkTitle': 'Auto-size font',
  1068. 'responsiveCoachmarkContent': 'The font size automatically resizes to fit when you resize this text type. You can set the font size in the text properties.',
  1069. 'propText': 'Text properties',
  1070. 'propTextReturn': 'Text properties',
  1071. 'textPlaceHolder': 'Enter your text here.',
  1072. 'textFontSize': 'Font size',
  1073. 'textFontFamily': 'Font family',
  1074. 'textFontWeight': 'Font weight',
  1075. // Widget Properties
  1076. 'propAltText': 'Alternate text',
  1077. 'propImageLink': 'Image link',
  1078. 'propMissingURL': 'Enter URL',
  1079. 'propMissingAltText': 'Enter alternate text',
  1080. 'propImgTop': 'Image properties',
  1081. 'propGeneralReturn': 'General properties',
  1082. 'propStyle': 'General',
  1083. 'propStyleReturn': 'General',
  1084. 'propFillColor': 'Fill color',
  1085. 'propTextColor': 'Text color',
  1086. 'propBorderColor': 'Border color',
  1087. 'propMaintainAxisScales': 'Maintain axis scale',
  1088. 'propShowItemLabel': 'Show the item label',
  1089. 'propHideLegend': 'Hide the legend',
  1090. 'propColorPalette': 'Palette',
  1091. 'propLegendPosition': 'Legend position',
  1092. 'propHideAxisTitleLabels': 'Hide axis titles',
  1093. 'propLineColor': 'Line color',
  1094. 'propBubbleColor': 'Bubble color',
  1095. 'propInterpolation': 'Smooth lines',
  1096. 'propElementColor': 'Visualization element color',
  1097. 'propSymbolShape': 'Symbol shape',
  1098. 'propHeatScalePalette': 'Color order',
  1099. 'propHeatScalePalette_tooltipDarkerForLowerValue': 'Darker colors represent smaller values.',
  1100. 'propHeatScalePalette_tooltipDarkerForHigherValue': 'Darker colors represent larger values.',
  1101. 'propImageDetails': 'Image details',
  1102. 'propWebDetails': 'Web page details',
  1103. 'propMediaDetails': 'Media details',
  1104. 'propPasteLink': 'Enter the URL and press Enter',
  1105. 'propScaleLabel': 'Quantity of icons',
  1106. 'propScaleDescription': 'Select the quantity of icons',
  1107. 'propScaleFew': 'Low',
  1108. 'propScaleDefault': 'Default',
  1109. 'propScaleMany': 'High',
  1110. 'mediaAriaLabel': 'url input',
  1111. 'ariaGroupLabel': 'Dropdown list category: %{cateoryLabel} item: %{itemLabel}. Press DOWN key to expand. Press UP and DOWN key to navigate or Press ESCAPE key to collapse.',
  1112. // Theme
  1113. 'propTheme': 'Theme',
  1114. // Timer
  1115. 'lastRefresh': 'Last refresh: %{timeInterval} ago',
  1116. 'widgetTimer': 'Widget timer',
  1117. // Theme colors
  1118. 'transparent': 'No color',
  1119. 'white': 'White',
  1120. 'lightGrey': 'Light grey',
  1121. 'grey': 'Grey',
  1122. 'darkGrey': 'Dark grey',
  1123. 'black': 'Black',
  1124. 'lightBlue': 'Light blue',
  1125. 'blue': 'Blue',
  1126. 'darkBlue': 'Dark blue',
  1127. 'yellow': 'Yellow',
  1128. 'orange': 'Orange',
  1129. 'lime': 'Lime',
  1130. 'green': 'Green',
  1131. 'peach': 'Peach',
  1132. 'red': 'Red',
  1133. 'violet': 'Violet',
  1134. 'aqua': 'Aqua',
  1135. 'purple': 'Purple',
  1136. 'plum': 'plum',
  1137. // Dashboard
  1138. 'propDashboardBackgroundColor': 'Background color',
  1139. //Story
  1140. 'propShowStoryOverviewFirstSlide': 'Show all scenes at the start',
  1141. 'propShowStoryOverviewLastSlide': 'Show all scenes at the end',
  1142. // Vis widget
  1143. 'propVisType': 'Visualization types',
  1144. 'propVisTypeReturn': 'Visualization types',
  1145. 'propVisDetails': 'Details',
  1146. // Animation properties for widgets
  1147. 'propAniDetails': 'Animation',
  1148. 'propAniDetailsReturn': 'Animation',
  1149. 'propAniEntrance': 'Entrance',
  1150. 'propAniTypeEntrance': 'Animation',
  1151. 'propAniTypeEntranceSlideIn': 'Slide in',
  1152. 'propAniTypeEntranceFadeIn': 'Fade in',
  1153. 'propAniTypeEntrancePivotIn': 'Pivot in',
  1154. 'propAniTypeEntranceScaleIn': 'Scale in',
  1155. 'propAniTypeEntranceShrinkIn': 'Shrink in',
  1156. 'propAniDirectionIn': 'Direction',
  1157. 'propAniDirectionInLeft': 'From left',
  1158. 'propAniDirectionInRight': 'From right',
  1159. 'propAniDirectionInTop': 'From top',
  1160. 'propAniDirectionInBottom': 'From bottom',
  1161. 'propAniExit': 'Exit',
  1162. 'propAniTypeExit': 'Animation',
  1163. 'propAniTypeExitSlideIn': 'Slide out',
  1164. 'propAniTypeExitFadeIn': 'Fade out',
  1165. 'propAniTypeExitPivotOut': 'Pivot out',
  1166. 'propAniTypeExitScaleIn': 'Scale out',
  1167. 'propAniTypeExitExpandOut': 'Expand out',
  1168. 'propAniDirectionOut': 'Direction',
  1169. 'propAniDirectionOutLeft': 'To left',
  1170. 'propAniDirectionOutRight': 'To right',
  1171. 'propAniDirectionOutTop': 'To top',
  1172. 'propAniDirectionOutBottom': 'To bottom',
  1173. // Alignment picker
  1174. 'propAlignPickTop': 'Align top',
  1175. 'propAlignPickRight': 'Align right',
  1176. 'propAlignPickBottom': 'Align bottom',
  1177. 'propAlignPickLeft': 'Align left',
  1178. 'propAlignPickCenter': 'Align center',
  1179. 'propAlignPicker': 'Alignment',
  1180. // Toolbar picker
  1181. 'propToolbarPickBold': 'Bold',
  1182. 'propToolbarPickUnderline': 'Underline',
  1183. 'propToolbarPickItalic': 'Italic',
  1184. 'propToolbarPickJustifyLeft': 'Align left',
  1185. 'propToolbarPickJustifyCenter': 'Align center',
  1186. 'propToolbarPickJustifyRight': 'Align right',
  1187. 'propToolbarPickJustify': 'Justify',
  1188. // Symbol shapes
  1189. 'propCircle': 'Circle',
  1190. 'propTriangle': 'Triangle',
  1191. 'propSquare': 'Square',
  1192. 'propRect': 'Rectangle',
  1193. 'propStar': 'Star',
  1194. 'propCross': 'Cross',
  1195. 'propPlus': 'Plus',
  1196. 'propPoly': 'Polygon',
  1197. // True and false selection
  1198. 'propTrue': 'True',
  1199. 'propFalse': 'False',
  1200. // Position selection
  1201. 'propLeft': 'Left',
  1202. 'propRight': 'Right',
  1203. 'propTop': 'Top',
  1204. 'propBottom': 'Bottom',
  1205. // Interpolation options
  1206. 'propSmooth': 'Smooth',
  1207. 'propStraight': 'Straight',
  1208. // indentedListView
  1209. 'srILVTreeLabel': 'List', // screen reader label for tree role
  1210. // widget move
  1211. 'srWidgetMoveLeft': 'Move left', // screen reader
  1212. 'srWidgetMoveUp': 'Move up', // screen reader
  1213. 'srWidgetMoveRight': 'Move right', // screen reader
  1214. 'srWidgetMoveDown': 'Move down', // screen reader
  1215. // widget resize
  1216. 'srWidgetResizeBigger': 'Increase the size proportionally', // screen reader
  1217. 'srWidgetResizeSmaller': 'Decrease the size proportionally', // screen reader
  1218. 'srWidgetResizeBiggerV': 'Increase the size vertically', // screen reader
  1219. 'srWidgetResizeSmallerV': 'Decrease the size vertically', // screen reader
  1220. 'srWidgetResizeBiggerH': 'Increase the size horizontally', // screen reader
  1221. 'srWidgetResizeSmallerH': 'Decrease the size horizontally', // screen reader
  1222. // widget rotate
  1223. 'srWidgetRotateCW': 'Rotate clockwise', // screen reader
  1224. 'srWidgetRotateCCW': 'Rotate counterclockwise', // screen reader
  1225. // Recommended types
  1226. 'visRecommendedTypes': 'Recommended visualization types',
  1227. 'visMore': 'More...',
  1228. 'visMoreTooltip': 'More visualizations',
  1229. 'visOtherTypes': 'Other visualization types',
  1230. 'visChange': 'Change visualization',
  1231. 'automaticArchetypeCaption': 'Automatic',
  1232. // Visualization
  1233. 'visualizationLabel': 'Visualization',
  1234. 'chartLabel': '%{chartName} chart',
  1235. 'dataWidgetDescription': '%{widgetLabel}: %{columnNames}',
  1236. 'f12KeyDescription': 'Press F12 to navigate within the widget',
  1237. 'f10KeyDescription': 'Press F10 to launch the widget focus view',
  1238. 'WidgetLabelWithDescripion': '%{label}. %{description}',
  1239. 'summaryLabel': '%{label} with value %{value}',
  1240. 'shapeColorLabel': 'Shape color',
  1241. 'showLegendLabel': 'Show legend',
  1242. //Webpage
  1243. 'webpageWidgetTitle': 'Webpage widget',
  1244. 'webpagePasteLink': 'Paste the URL and press Enter to save it',
  1245. 'propWebpageLink': 'Web page URL',
  1246. 'propWebpageTitle': 'Web page title',
  1247. 'propWebpageTitleDescription': 'Title of the web page',
  1248. 'propWebpageTop': 'Web page properties',
  1249. 'webpageMissingUrl': 'The web page URL is missing',
  1250. 'webpageUrlValidationError': 'The web page URL is not valid',
  1251. 'webpageHttpValidationError': 'The web page must be accessed using an HTTPS link for the browser to display it',
  1252. //VizState
  1253. 'vzErrorLoading': 'Unable to load visualization',
  1254. 'vzErrorLoadingMissingData': 'Unable to load visualization, missing context data',
  1255. //Media (Video / Audio)
  1256. 'mediaWidgetTitle': 'Media widget',
  1257. 'mediaPasteLink': 'Paste the URL and press Enter to save it',
  1258. 'videoHeight': 'Height:',
  1259. 'videoWidth': 'Width:',
  1260. 'propMediaLink': 'Media link',
  1261. 'propMediaTitle': 'Media title',
  1262. 'propMediaTitleDescription': 'Title of the media',
  1263. 'propMediaTop': 'Media properties',
  1264. 'mediaMissingUrl': 'The media link URL is missing',
  1265. 'mediaUrlValidationError': 'The media file URL is not valid',
  1266. 'mediaUnknownValidationError': 'This type of media is not supported',
  1267. 'mediaHttpValidationError': 'The media file must be accessed using an HTTPS link for the browser to display it',
  1268. // Properties pane
  1269. 'commonPropertiesLabel': 'Properties',
  1270. // Data strip
  1271. 'dataSetsLabel': 'Data set',
  1272. 'dataViewsLabel': 'View',
  1273. 'columnQuality': 'Data quality',
  1274. 'columnProperties': 'Data properties',
  1275. 'dataQuality': 'Data quality',
  1276. 'dataQualityRowCount': 'Number of rows',
  1277. 'dataQualityDistribution': 'Distribution',
  1278. 'dataRowLabel': 'Data',
  1279. // Timeline strip
  1280. 'storytellingSceneLabel': 'Scene',
  1281. 'storytellingAddSceneLabel': 'Add a new scene',
  1282. 'storytellingInsertSceneLabel': 'Insert a new scene',
  1283. 'storySceneSingleCountLabel': '1 scene',
  1284. 'storySceneCountLabel': '%{count} scenes',
  1285. 'storySceneRangeCountLabel': 'Scene %{index} of %{count}',
  1286. 'storySceneExpand': 'Open timeline',
  1287. 'timelineRightContainerLabel': 'Timeline button control group',
  1288. 'timelineViewLabel': 'Timeline',
  1289. 'timelineZoomFit': 'Zoom to fit',
  1290. 'timelineZoomIn': 'Zoom in',
  1291. 'timelineZoomOut': 'Zoom out',
  1292. 'timelineLeftHandle': 'left handle',
  1293. 'timelineRightHandle': 'right handle',
  1294. // object is timelineLeftHandle, timelineRightHandle or the title of the widget
  1295. 'timelineMoveLeft': 'Move %{object} left',
  1296. 'timelineMoveRight': 'Move %{object} right',
  1297. 'timelinePositionIndicatorMoveLeftTo': 'timeline position indicator move left to %{position}',
  1298. 'timelinePositionIndicatorMoveRightTo': 'timeline position indicator move right to %{position}',
  1299. // Admin UI
  1300. 'adminTitle': 'Administration',
  1301. 'adminAccount': 'Account',
  1302. 'adminConnCreate': 'Create new connection',
  1303. 'adminConnEdit': 'Edit connection',
  1304. 'adminConnTest': 'Test connection',
  1305. 'adminConnTestButton': 'Test',
  1306. 'adminConnTestConnection': 'Please provide credentials for the connection %{name}:',
  1307. 'adminConnTestFailed': 'Failed',
  1308. 'adminConnTestFailure': 'We can\'t connect to the <i>%{name}</i> database. Review the message that we received from the database then attempt to correct the problem.',
  1309. 'adminConnTestFailureDetailsLess': 'Hide details',
  1310. 'adminConnTestFailureDetailsMore': 'Show details',
  1311. 'adminConnTestFailureLess': 'Less',
  1312. 'adminConnTestFailureMore': 'More',
  1313. 'adminConnTestInProgress': 'Testing',
  1314. 'adminConnTestSuccess': 'Succeeded',
  1315. 'adminDataConnections': 'Data connections',
  1316. 'adminSecureGateway': 'Secured gateways',
  1317. 'adminEmail': 'Contact email',
  1318. 'adminFullname': 'Full name',
  1319. 'adminRole': 'Role',
  1320. 'adminScxRole': 'Subscription roles',
  1321. 'adminSignonUnchanged': 'User ID is set, edit to change.',
  1322. 'adminUserId': 'User ID',
  1323. 'adminUserProfile': 'User profile',
  1324. 'adminUsers': 'Users',
  1325. 'adminFirstName': 'First name',
  1326. 'adminLastName': 'Last name',
  1327. 'adminErrorTitle': 'We\'re sorry',
  1328. 'adminServiceError': 'The server or service stopped responding. Please try again later.',
  1329. 'adminServiceInviteConflict': 'We\'re unable to send the invitation. This happens if the user has already been invited but hasn\'t accepted the invitation yet. Or the user might have been deleted from the account.',
  1330. 'scxServerNotAvailable': 'The subscription administration service is currently unavailable.',
  1331. 'adminSelectRoleTitle': 'Select a role',
  1332. 'adminLastAdminErrorTitle': 'Unable to change role',
  1333. 'adminLastAdminError': 'There is the only user with Administrator role.\n\nYou need to have at least one user with Administrator role.',
  1334. // Admin account
  1335. 'adminSubscriptionLabel': 'Subscription',
  1336. 'adminSubscriptionVersion': 'You are currently subscribed to <b>%{version}</b>.',
  1337. 'adminSubscriptionUpgrade': '<a href="" target="_blank" class="upgradeLink"><span class="wfg_add"></span>Edit options</a> for storage space, licenses, and subscriptions.',
  1338. 'adminSubscriptionLearnMore': 'Learn more about other subscription options.',
  1339. 'adminPurchasesLabel': 'Purchases',
  1340. 'adminTotalSpaceLabel': 'Total space',
  1341. 'adminSpaceInfo': 'Your maximum upload size is %{maxUpload} and the maximum number of columns allowed in your data set is %{numCols} columns.',
  1342. 'adminAvailableLabel': 'Available',
  1343. 'adminUsedLabel': 'Used',
  1344. 'adminTotalLabel': 'Total',
  1345. 'adminLicensesLabel': 'Licenses',
  1346. 'adminEditLabel': 'Edit',
  1347. 'adminPromoCodeLabel': 'Promotion code',
  1348. 'adminAccountError': 'We can\'t retrieve the account details. Please try again later.',
  1349. 'adminUnitsB': 'B',
  1350. 'adminUnitsBLabel': '%{value} B',
  1351. 'adminUnitsKB': 'KB',
  1352. 'adminUnitsKBLabel': '%{value} KB',
  1353. 'adminUnitsMB': 'MB',
  1354. 'adminUnitsMBLabel': '%{value} MB',
  1355. 'adminUnitsGB': 'GB',
  1356. 'adminUnitsGBLabel': '%{value} GB',
  1357. 'adminUnitsTB': 'TB',
  1358. 'adminUnitsTBLabel': '%{value} TB',
  1359. 'adminUnitsPB': 'PB',
  1360. 'adminUnitsPBLabel': '%{value} PB',
  1361. 'adminOperatorPrefix': '%{prefix} %{value}',
  1362. 'adminUnknown': 'Unknown',
  1363. 'adminNoPurchases': 'No purchases found',
  1364. // Admin UI - Users tab
  1365. 'adminUserDelete': 'Are you sure you want to delete this user?', // to_review
  1366. 'adminUsersDelete': 'Are you sure you want to delete these users?', // to_review
  1367. 'adminUsersDeleteFailDesc': 'Errors with deleting users.', // to_review
  1368. 'adminUsersDeleteFailTitle': 'Delete Error', // to_review
  1369. 'adminUsersDeleteSuccessDesc': 'Users were successfully deleted.', // to_review
  1370. 'adminUsersDeleteSuccessTitle': 'Success!', // to_review
  1371. 'adminUsersHeadingName': 'Name',
  1372. 'adminUsersHeadingStatus': 'Status',
  1373. 'adminUsersHeadingLastModified': 'Last modified',
  1374. 'adminUsersInviteLabel': 'Invite user',
  1375. 'adminUsersManageAccountsLabel': 'Manage user accounts',
  1376. 'adminDropHere': 'Drop your .csv file here or tap to browse',
  1377. 'adminInviteCancelled': 'This user wasn\'t invited yet. Request was cancelled.',
  1378. 'adminInviteCount': 'You selected %{count} users. (max %{max})',
  1379. 'adminInviteDisclaimer': '* You can invite %{count} users at a time',
  1380. 'adminInviteErrorCode': '[Error %{errorcode}]',
  1381. 'adminInviteErrorLine': '%{email} - %{reason} %{action} %{errorcode}',
  1382. 'adminInviteInProgress': 'Inviting users...',
  1383. 'adminInviteCancelDesc': 'Cancelling...',
  1384. 'adminInviteCancelTitle': 'Cancel',
  1385. 'adminInviteFailDesc': 'We encountered %{count} errors.<br>Review the messages below to determine which user invitations failed.',
  1386. 'adminInviteFailTitle': 'We didn\'t invite everyone',
  1387. 'adminInviteOverLimit': 'This user wasn\'t invited yet. You can invite up to %{count} users at a time and this user exceeded that limit.',
  1388. 'adminInviteSuccessCount': 'We successfully invited %{count} of your selected %{selectedCount} users.',
  1389. 'adminInviteTryAgain': 'Tap "Invite uploaded users" again to invite the next %{count} users.',
  1390. 'adminInviteServerError': 'Server error (%{errorcode}). Please try again.',
  1391. 'adminInviteSuccessDesc': 'Successfully invited users.',
  1392. 'adminInviteSuccessTitle': 'Success!',
  1393. 'adminUpload': 'Upload data',
  1394. 'adminUploadDesc': 'To invite multiple users, create a .csv file or save a spreadsheet as the file type <b>CSV</b>.<br><br>The CSV file must have 3 columns in this order: email address, given name, and family name.<br>Do not include other columns.',
  1395. 'adminUploadHelpLink': 'Learn more',
  1396. 'adminUsersDeleteAll': 'Delete users',
  1397. 'adminUsersInviteAll': 'Invite uploaded users',
  1398. 'adminUsersUpload': 'Upload users',
  1399. 'adminUploading': 'Uploading Data...',
  1400. 'adminUploadErrorLine': 'Line %{line}: %{reason}',
  1401. 'adminUploadSuccess': 'Success!',
  1402. 'adminUploadSuccessDesc': 'Your file \'%{name}\' has been successfuly uploaded.',
  1403. 'adminUploadFailCount': 'We found %{failedCount} errors in your file.',
  1404. 'adminUploadFailDesc': 'Make sure that there are no empty fields and that all email addresses are valid. <br><br>Please check your file and resubmit.',
  1405. 'adminUploadFailTitle': 'We can\'t upload your file',
  1406. 'adminUserStatus_PRELOAD': 'Not invited yet',
  1407. 'adminUserStatus_INVITATION_PENDING': 'Invited',
  1408. 'adminUserStatus_INACTIVE_PENDING': 'Invited but not activated',
  1409. 'adminUserStatus_ACTIVE': 'Active',
  1410. 'adminUserStatus_INACTIVE_SUSPENDED': 'Suspended',
  1411. // Data connection parameters (for the values returned by /externalconnections/types. 'conn_' + [parameter name]
  1412. 'conn_biurl': 'URL',
  1413. 'conn_dbname': 'Database name',
  1414. 'conn_dbtypeid': 'Database type',
  1415. 'conn_host': 'Server name',
  1416. 'conn_name': 'Connection name',
  1417. 'conn_password': 'Password',
  1418. 'conn_password_confirm': 'Confirm password',
  1419. 'conn_port': 'Port number',
  1420. 'conn_port_validation': 'Only numbers are allowed for port.',
  1421. 'conn_schema': 'Database schema',
  1422. 'conn_signon': 'Include signon',
  1423. 'conn_ssl': 'Use SSL',
  1424. 'conn_sslcertificate': 'SSL certificate (optional)',
  1425. 'conn_sslcertificate_set': 'SSL certificate is set, edit to change.',
  1426. 'conn_url': 'JDBC connection parameters (optional)',
  1427. 'conn_user': 'User ID',
  1428. // Data Connection types (for the values returned by /externalconnections/types. 'connType_' + [name]
  1429. 'connType_Cognos_BI': 'IBM Cognos BI Server',
  1430. 'connType_IBM_DB2': 'IBM DB2',
  1431. 'connType_MySQL': 'MySQL',
  1432. 'connType_Oracle': 'Oracle',
  1433. 'connType_Postgres': 'PostgreSQL',
  1434. 'connType_SQLDB': 'IBM SQL Database for Bluemix',
  1435. 'connType_SQL_Server': 'Microsoft SQL Server',
  1436. 'connType_dashDB': 'IBM dashDB',
  1437. 'bi_connect_error': 'Connection files have not been installed in the required folder on your IBM Cognos BI server.<br><br>Contact your IBM Cognos BI administrator, who can enable the connection. For more information, see the <a class="wah-anchor" href="https://watson.analytics.ibmcloud.com/docs/help/#wa_an_overview/wa-an-admin-dataconn-c10_admin.html" target="_blank">Docs</a>.',
  1438. 'bi_notrunning_error': 'We can\'t reach the IBM Cognos BI server using the URL you provided.<br><br>Verify that the URL is correct. See the <a class="wah-anchor" href="https://watson.analytics.ibmcloud.com/docs/help/#wa_an_overview/wa_an_hlp_c10_conn_err.html" target="_blank">Docs</a> for other possible reasons why you can\'t connect.',
  1439. 'bi_info': 'The server must use a secure web protocol and the URL must begin with https.<br>For example, https://bi_server.example.com/ibmcognos',
  1440. 'dbTypeRestrictionLabel': 'With your subscription, you can only create and use connections to one database type at a time.<br><br>To connect to another database type, delete all database connections, then create new connections.&nbsp;&nbsp;To connect to multiple database types simultaneously, upgrade your subscription. ',
  1441. // Modelling UI
  1442. 'typeColumn': 'Type',
  1443. 'modellingColumnType': 'Type',
  1444. 'modellingColumnAggregation': 'Aggregation',
  1445. 'modellingColumnUsage': 'Usage',
  1446. 'modellingColumnSort': 'Sort',
  1447. 'modellingColumnFormat': 'Format',
  1448. 'modellingColumnCategory': 'Category',
  1449. 'modellingLoading': 'Loading...',
  1450. 'modellingProcessing': 'Processing...',
  1451. 'modellingImport': 'Import',
  1452. 'modellingReimport': 'Re-import',
  1453. 'modellingDatasourceTitle': 'Data source',
  1454. 'modellingImportStartedTitle': 'Importing started',
  1455. 'modellingImportStartedText': 'Importing your data may take a bit of time.\n\n(You can create a view while the data is imported.)',
  1456. 'importDatasourceTitle': 'Connections',
  1457. 'dropHere': 'Drop here to create a new data source...',
  1458. 'browseButton': 'Browse',
  1459. 'errorNoData': 'There is no data to process.',
  1460. 'errorNoFile': 'There is no file to upload.',
  1461. 'errorUploadFailed': 'Unable to upload.',
  1462. 'uploadSucceessful': 'Upload succeessful',
  1463. 'del_datasourceTitle': 'Delete data set',
  1464. 'del_datasourceMsg': 'Are you sure you wish to delete \'%{name}\'?',
  1465. 'modellingFileUpdate': 'Update',
  1466. 'modellingFileUpdateTitle': 'Update data set',
  1467. 'modellingFileUpdateDescription': 'Do you want to update \'%{name}\'?',
  1468. 'modellingFileUpdatingTitle': 'Updating \'%{name}\'',
  1469. 'modellingUpdateStartedTitle': 'Update import started',
  1470. 'modellingUpdateStartedText': 'Updating your data may take a bit of time.\n\n(You can create a view while the data is updated.)',
  1471. 'modellingErrorImportUploadNoFile': 'No file to upload.',
  1472. 'modellingErrorImportUploadFailed': 'Unable to upload.',
  1473. 'modellingErrorImportUploadInvalidType': 'The file type is not valid.',
  1474. 'modellingErrorImportUploadTableFailed': 'Unable to get tables.',
  1475. 'modellingIntentResultsTitle': 'Select the proposed data set to use',
  1476. 'modellingColumnViewRelationships': 'View related tables',
  1477. 'modellingTableRelatedTables': 'Tables related to \'%{name}\'',
  1478. 'modellingTable': '%{name} - Table',
  1479. 'modellingColumnIncludedInDataSet': 'Added',
  1480. 'modellingDataSet': 'Data set',
  1481. 'modellingViewInDataSet': 'View in data set',
  1482. 'modellingViewRelatedTables': 'View related',
  1483. 'modellingRelatedTablesNoneFound': 'No related tables found',
  1484. 'modellingValidatingDataset': 'Validating...',
  1485. 'datasetFinishedRefreshing': 'Data set %{datasetName} has been refreshed.',
  1486. // Join UI - Navigation Controller titles
  1487. 'modellingJoinTable': 'Resolve join path:',
  1488. 'modellingJoinColumns': 'Define a join path for table: %{name}',
  1489. 'modellingJoinToTable': 'Join to table: %{name}',
  1490. // Data Quality
  1491. 'excluded': 'Excluded',
  1492. 'metricPrefixThousand': 'K',
  1493. 'metricPrefixMillion': 'M',
  1494. 'metricPrefixBillion': 'B',
  1495. 'metricPrefixTrillion': 'T',
  1496. 'metricPrefixQuadrillion': 'Q',
  1497. //Column Flyout
  1498. 'modellingColumnFilter': 'Filter',
  1499. 'modellingColumnSortNone': 'Clear the sort',
  1500. 'modellingColumnSortAsc': 'Sort ascending',
  1501. 'modellingColumnSortDesc': 'Sort descending',
  1502. 'modellingColumnRemove': 'Remove this column',
  1503. // Import File Browser
  1504. dropboxPageTitle: 'New Dropbox connection',
  1505. sizeColumn: 'Size',
  1506. //Modelling Column Property Values
  1507. 'dataType_string': 'String',
  1508. 'dataType_date': 'Date',
  1509. 'dataType_integer': 'Integer',
  1510. 'dataType_double': 'Double',
  1511. 'dataType_float': 'Float',
  1512. 'dataType_boolean': 'Boolean',
  1513. 'defaultAggregation_count': 'Count',
  1514. 'defaultAggregation_countdistinct': 'Count distinct',
  1515. 'defaultAggregation_max': 'Maximum',
  1516. 'defaultAggregation_min': 'Minimum',
  1517. 'defaultAggregation_avg': 'Average',
  1518. 'defaultAggregation_sum': 'Sum',
  1519. 'defaultAggregation_auto': 'Auto (%{aggregationType})',
  1520. 'type_fact': 'Fact',
  1521. 'type_attribute': 'Attribute',
  1522. 'defaultSort_none': 'Do not sort',
  1523. 'defaultSort_asc': 'Sort ascending',
  1524. 'defaultSort_desc': 'Sort descending',
  1525. 'category_none': 'None',
  1526. 'category_location': 'Location',
  1527. 'category_monetary': 'Monetary',
  1528. 'category_time': 'Time',
  1529. // Root menu
  1530. rootMenuTitle: 'Main menu',
  1531. errorMessageTitle: 'Error',
  1532. errorMessageDetails: 'Details: ',
  1533. errorMessageTitleAssetAlreadyExists: 'Asset already exists',
  1534. defaultTabTitle: 'Tab %{index}',
  1535. tabAddBtnTitle: 'Add a new tab',
  1536. // Homepage View
  1537. nameColumn: 'Name',
  1538. creatorColumn: 'Created by',
  1539. creationDateColumn: 'Date created',
  1540. versionColumn: 'Version',
  1541. modifiedColumn: 'Last Modified',
  1542. filterBy: 'Filter items',
  1543. allFilter: 'All items',
  1544. createdByMeFilter: 'Created by me',
  1545. sharedWithMeFilter: 'Shared with me',
  1546. favoritesFilter: 'My favorites',
  1547. recentsFilter: 'Recently added',
  1548. sortBy: 'Sort by',
  1549. // Sort Menu
  1550. sortModified: 'Modified',
  1551. sortUpdated: 'Updated',
  1552. sortName: 'Name',
  1553. viewAs: 'View as',
  1554. thumbnailsView: 'View as thumbnails',
  1555. listView: 'View as a list',
  1556. createMenu: 'Create',
  1557. newAppItem: 'Dashboard',
  1558. newDataSet: 'Data set',
  1559. newStory: 'Story',
  1560. menuSelectionState_a11y: '"%{item}" selector set to "%{selectedItem}"',
  1561. unableToShareItem: 'Unable to share item "%{item}".',
  1562. toastFetchingContent: 'Getting more content...',
  1563. unableToGetData: 'Unable to get content.',
  1564. unableToFavorite: 'Unable to change the Favorite status.',
  1565. hpErrorMissingRequiredOptions: 'Missing required initialization options',
  1566. unableToOpenBoard: 'Unable to open "%{name}".',
  1567. unableToDuplicateBoard: 'Unable to duplicate "%{name}".',
  1568. unableToCreateBoard: 'Unable to create "%{name}".',
  1569. unableToCreateBoardNameConflict: 'An asset with the same name already exists.',
  1570. // DataSet Detail View
  1571. status: 'Status',
  1572. numberOfRows: 'Rows',
  1573. importWarnings: 'Warnings',
  1574. lineNumbers: 'Lines',
  1575. excerptFromSource: 'Excerpt',
  1576. reason: 'Reason',
  1577. numberOfRowsDropped: 'rows dropped',
  1578. oneRowDropped: '1 row was dropped',
  1579. // Type Menu
  1580. typeMenuLabel: 'Type',
  1581. dashboardsLabel: 'Dashboards',
  1582. datasetsLabel: 'Data sets',
  1583. storiesLabel: 'Stories',
  1584. allLabel: 'All types',
  1585. // Board Page View App Bar
  1586. datasets: 'Data sets',
  1587. settings: 'Properties',
  1588. add: 'Add',
  1589. widgets: 'Widgets',
  1590. dashboardProperties: 'Dashboard properties',
  1591. storyProperties: 'Story properties',
  1592. pins: 'Collection',
  1593. // For languages with more than one plural form, provide the different forms delimited by |||| in the string below.
  1594. // See https://github.com/airbnb/polyglot.js#pluralization
  1595. pinCount: '%{smart_count} collected item |||| %{smart_count} collected items',
  1596. pinSearch: 'Search',
  1597. pinListView: 'List view',
  1598. pinIconView: 'Icon view',
  1599. pinRemove: 'Remove',
  1600. pinCreate: 'Create',
  1601. pinDateFilter: 'Date Filter',
  1602. pinDateFilterAll: 'All',
  1603. pinDateFilterToday: 'Today',
  1604. pinDateFilterYesterday: 'Yesterday',
  1605. pinDateFilterPastWeek: 'Past week',
  1606. pinDateFilterPastMonth: 'Past month',
  1607. pinDateFilterEarlier: 'Earlier',
  1608. // widgets contextual toolbar labels
  1609. toolbarRegionLabel: 'Toolbar',
  1610. toolbarActionDelete: 'Delete',
  1611. toolbarActionGroup: 'Group',
  1612. toolbarActionUngroup: 'Ungroup',
  1613. toolbarActionOrder: 'Order',
  1614. toolbarActionEditTitle: 'Edit the title',
  1615. toolbarActionPin: 'Collect',
  1616. //Story scene toolbar
  1617. toolbarActionTimeline: 'Set the scene timeline',
  1618. // data widget contextual toolbar labels
  1619. toolbarActionSort: 'Sort',
  1620. toolbarActionSortAscending: 'Sort ascending',
  1621. toolbarActionSortDescending: 'Sort descending',
  1622. toolbarActionSortAuto: 'Auto (%{sortOrder})',
  1623. toolbarActionFormat: 'Format',
  1624. toolbarActionFormatAbbreviation: 'Abbreviate',
  1625. toolbarActionFormatNone: 'Auto',
  1626. toolbarActionFilter: 'Filter',
  1627. toolbarActionTopBottom: 'Top or bottom',
  1628. toolbarActionToggleShapeDrop: 'Infographic shape',
  1629. toolbarActionToggleShapeDropTitle: 'Create an infographic',
  1630. toolbarActionToggleShapeDropText: 'Drag a shape to this field to create an infographic.',
  1631. toolbarActionAggregationType: 'Summarize',
  1632. toolbarActionFilterLocalKeepSelected: 'Keep',
  1633. toolbarActionFilterLocalExcludeSelected: 'Exclude',
  1634. toolbarActionFilterAllKeepSelected: 'Filter',
  1635. toolbarActionSimpleCalculation: 'Simple calculation',
  1636. toolbarActionDrillBack: 'Back',
  1637. toolbarActionDrillUp: 'Drill up',
  1638. toolbarActionDrillDown: 'Drill down',
  1639. toolbarActionNavigate: 'Navigate',
  1640. toolbarActionCreateFilterGroup: 'Create new connection',
  1641. toolbarActionDisconnectFilterGroup: 'Break all links',
  1642. toolbarActionLinkFilterGroup: 'Add to an existing connection',
  1643. toolbarLabel: '%{labelName}:',
  1644. toolbarNoValueLabel: '%{labelName}',
  1645. // Side bar
  1646. 'sidebarAdd': 'Add',
  1647. 'sidebarMultiselect': 'Toggle multiple selection',
  1648. 'multiselectMsg': '%{count} selected',
  1649. 'multiselectWithTotalMsg': '%{count} of %{total}',
  1650. 'sidebarGoBack': 'Go back',
  1651. //DataSet pane
  1652. errorLoadingDataSets: 'We can\'t load this data set',
  1653. errorLoadingDataSetMetaData: 'We can\'t load this data set',
  1654. 'dataSetPaneLastUpdated': 'Last updated: %{date}',
  1655. 'dataSetPaneDateUnknown': 'Unknown',
  1656. 'sourcePaneLabel': 'Selected sources',
  1657. 'addSourceLabel': 'Add a source',
  1658. 'intentSearchLabel': 'Intent search',
  1659. 'find_label': 'Find',
  1660. 'navigationPathsLabel': 'Navigation paths',
  1661. //widgetlist
  1662. errorLoadingWidgetList: 'We can\'t load the objects.',
  1663. errorLoadingThemeFile: 'We can\'t load the theme definition',
  1664. errorLoadingLayoutFile: 'We can\'t load the view.',
  1665. //data widget
  1666. dwErrorLoadingAvailableVisualizations: 'We can\'t load the available visualization definitions',
  1667. dwErrorLoadingVisualizationNotFound: 'We can\'t load the object, because it is missing a visualization definition',
  1668. dwErrorLoadingVisualizationListNotFound: 'We can\'t load the visualization.',
  1669. dwErrorRunningQuery: 'We can\'t retrieve the data from data set %{datasetName}.',
  1670. dwErrorGeoData: 'We\'re having trouble displaying the geographic data in a map. Please choose another visualization type. ',
  1671. dwPromptSignonCancelWarning: 'The data for this visualization is unavailable. Please provide the correct credentials.',
  1672. dwErrorMissingDataset: 'We can\'t load the visualization, because its associated data set \'%{datasetName}\' isn\'t available.',
  1673. dwErrorRenderingVisualization: 'We can\'t load this visualization.',
  1674. dwErrorVisualizationTooSmall: 'The visualization is too small to display the data it contains. Make the visualization larger or limit the data it contains.',
  1675. aria_label_datatable: 'Data table',
  1676. aria_key_navi_datatable_desc: 'Use arrow keys to navigate to each cell. Press Control and Home key to move to the first row, Control and End key to move to the last row.',
  1677. geomapUnrecognizedLocations: 'Unrecognized locations:',
  1678. geomapAmbiguousLocations: 'Ambiguous regions:',
  1679. // custom widget
  1680. customWidget: 'Custom widget',
  1681. noCustomWidgets: 'No custom widgets',
  1682. // Action names
  1683. 'toggleContextBar': 'Toggle the context bar',
  1684. 'delete': 'Delete',
  1685. 'share': 'Share',
  1686. 'unshare': 'Unshare',
  1687. 'rename': 'Rename',
  1688. 'close': 'Close',
  1689. 'duplicate': 'Duplicate',
  1690. 'copyOf': 'Copy of %{name}',
  1691. 'retry': 'Retry',
  1692. 'changeTemplate': 'Change template',
  1693. // Aggregation Types
  1694. 'sum': 'Sum',
  1695. 'count': 'Count',
  1696. 'countdistinct': 'Count distinct',
  1697. 'avg': 'Average',
  1698. 'min': 'Minimum',
  1699. 'max': 'Maximum',
  1700. 'custom': 'Custom',
  1701. 'calculated': "Calculated",
  1702. 'aggregatedColumnLabel': '%{column} (%{aggregationTypeLabel})', // For example, the sum of Revenue
  1703. //simple calculation
  1704. 'percDifferenceOp': '% change',
  1705. //For example, Profit - Expenses
  1706. 'calculationTitle': '%{col1} %{operator} %{col2}',
  1707. 'quickadd': 'What do you want to see? For example, Revenue by Year.',
  1708. 'templateWidgetPlaceholderInput': 'Visualization criteria...',
  1709. 'QuickAddResultsHeader': 'Data visualizations',
  1710. 'NoQuickAddResults': 'Nothing matched your intent. Create a new data set?',
  1711. 'NoQuickAddResultsRetry': 'We can\'t find any matches. Try again with different terms.',
  1712. 'templateWidgetTitle': 'Template',
  1713. nullValueLabel: '(blank)',
  1714. nullValueContent: '(no value)',
  1715. // Modelling / Data Shaping
  1716. textFilterControlRegionLabel: 'Text filter - %{columnName}',
  1717. textFilterSelectTab: 'Select',
  1718. textFilterConditionTab: 'Set a condition',
  1719. textFilterItemsSelected: '(%{selected})',
  1720. textFilterItemsNotFound: 'No items are available.',
  1721. textFilterEquals: 'Equals',
  1722. textFilterContains: 'Contains',
  1723. textFilterBeginsWith: 'Begins with',
  1724. textFilterEndsWith: 'Ends with',
  1725. textFilterDoesNotEqual: 'Does not equal',
  1726. textFilterDoesNotContain: 'Does not contain',
  1727. textFilterDoesNotBeginWith: 'Does not begin with',
  1728. textFilterDoesNotEndWith: 'Does not end with',
  1729. textFilterSampleText: 'For example: A',
  1730. textFilterAndButton: 'And',
  1731. textFilterOrButton: 'Or',
  1732. dateFilterMessage: 'Select a range of dates',
  1733. dateRangeControlRegionLabel: 'Date range filter - %{columnName}',
  1734. dateFilterRangeOption: 'Range option',
  1735. dateFilterDateLabel: 'Date',
  1736. dateFilterBlank: '(blank)',
  1737. dateFilterBefore: 'Before',
  1738. dateFilterAfter: 'After',
  1739. dateFilterBetween: 'Between',
  1740. dateFilterSampleText: 'YYYY-MM-DD',
  1741. dateTitle: 'Date',
  1742. dateIncludeBlankLabel: 'Include blank date',
  1743. timeTitle: 'Time',
  1744. timeFilterMessage: 'Select a range of times',
  1745. dateTimeFilterMessage: 'Select a range of dates and times',
  1746. topbottomSelectOption: 'Top or bottom option',
  1747. topbottomOptionLabel: 'Show',
  1748. searchByLabel: 'By',
  1749. searchNoMatches: 'No matches found',
  1750. topbottomRankColumnLabel: 'Add a rank column to grid',
  1751. topbottomNone: 'None',
  1752. topFive: 'Top 5',
  1753. bottomFive: 'Bottom 5',
  1754. topTen: 'Top 10',
  1755. bottomTen: 'Bottom 10',
  1756. topbottomSearchColumn: 'Find a column',
  1757. searchColumnAriaLabel: 'Find a column. Type the name of the column to search for then use the down arrow to find the column in a list',
  1758. rankColumnLabel: 'Rank (%{columnLabel})',
  1759. rangeFilterControlRegionLabel: 'Range filter - %{columnName}',
  1760. // Slider
  1761. sliderRegionLabel: 'Slider control, use right and left arrows to move the slider handles',
  1762. sliderHandleLabel: 'Slider handle',
  1763. a11ySliderHandleLabel: 'Slider handle %{sliderValue}',
  1764. sliderInputLabel: 'value',
  1765. // Refinery - Hidden columns
  1766. datasetItemsUnavailable: 'Some data set items used in this visualization are unavailable.',
  1767. datasetItemUnavailable: 'This data set item is unavailable',
  1768. //Authoring topBottom
  1769. topOperator: 'Top',
  1770. bottomOperator: 'Bottom',
  1771. //For dimension column. eg: Top 5 by Quantity. %{operator} is topOperator or bottomOperator, %{val} is a number and %{fact} is a column name.
  1772. topBottomFact: '%{operator} %{value} by %{columnLabel}',
  1773. //For fact column. eg: Top 10. %{operator} is topOperator or bottomOperator and %{val} is a number.
  1774. topBottomDimension: '%{operator} %{value}',
  1775. topBottomTitle: 'This object only',
  1776. deleteTopBottom: 'Delete top or bottom count',
  1777. editTopBottom: 'Edit top or bottom count',
  1778. deleteDrillState: 'Delete current drill state',
  1779. ariaDeleteDrillStateLabel: 'Press ENTER key to edit top or bottom count.',
  1780. drillUpStateTitle: 'Drill Up',
  1781. drillDownStateTitle: 'Drill Down',
  1782. ariaEditTopBottomLabel: 'Press ENTER key to edit top or bottom count.',
  1783. ariaDeleteTopBottomLabel: 'Press DELETE key to delete top or bottom count.',
  1784. // Authoring filtering
  1785. dimFilterIn: 'Includes: %{in}',
  1786. dimFilterNotIn: 'Excludes: %{out}',
  1787. measureFilterBetween: 'Between %{lowerBound} and %{upperBound}',
  1788. measureFilterNotBetween: 'Not between %{lowerBound} and %{upperBound}',
  1789. gtFilter: 'After %{lowerBound}',
  1790. ltFilter: 'Before %{upperBound}',
  1791. localFilterTitle: 'This object only',
  1792. globalFilterTitle: 'All objects',
  1793. deleteFilter: 'Delete filter',
  1794. editFilter: 'Edit filter',
  1795. ariaEditFilterLabel: 'Press ENTER key to edit filter.',
  1796. ariaDeleteFilterLabel: 'Press DELETE key to delete filter.',
  1797. // Prompts
  1798. ariaEditPrompt: 'Press ENTER key to change the prompt value',
  1799. moreDataIndicator: 'Your data was clipped at %{threshold} items. Apply a filter to show less.',
  1800. // data point filtering
  1801. dataPointFilterTitle: 'Data points',
  1802. dataPointFilterIncludeSummary: 'Included %{valueCount} data points',
  1803. dataPointFilterExcludeSummary: 'Excluded %{valueCount} data points',
  1804. // DB2 connection page
  1805. db2Database: 'DB2 Database (%{jdbcConnection})',
  1806. db2Title: 'Connect to IBM DB2',
  1807. // Database
  1808. databaseConnectionMessage: 'Provide your database connection details:',
  1809. connectionString: 'Database connection string',
  1810. databaseCredentials: 'Credentials: ',
  1811. databaseUserName: 'User name',
  1812. databasePassword: 'Password',
  1813. databaseConnect: 'Connect',
  1814. // Twitter Keyword page
  1815. twitterTitle: 'Twitter',
  1816. twitterKeywordMessage: 'Enter a search term:',
  1817. twitterKeyword: 'Keyword',
  1818. twitterSearch: 'Search',
  1819. // NewConnectionView Providers
  1820. twitterProvider: 'Twitter',
  1821. dropboxProvider: 'Dropbox',
  1822. db2Provider: 'DB2',
  1823. workbookCreateFailed: 'We can\'t create the view: %{error}\nFailed operation: %{lastOp}',
  1824. // Expanded View, Focus View
  1825. widgetFiltersLabel: 'Widget filters',
  1826. missingColumn: 'Missing: %{columnLabel}',
  1827. missingFiltering: 'Missing filters on following column IDs:',
  1828. heatByLabel: 'Heat by',
  1829. 'evCollapse': 'Collapse',
  1830. 'evColumns': 'Columns',
  1831. 'evLocalFilters': 'Local filters',
  1832. 'evExpand': 'Expand',
  1833. 'evFilterTooltip': 'Filter',
  1834. 'evAdd': 'Add a column',
  1835. // Navigation View
  1836. 'navigationBack': 'Back',
  1837. //Storytelling
  1838. storyTellingDefaultSceneTitle: 'Scene %{index}',
  1839. storyTellingTabAddBtnTitle: 'Add a new scene',
  1840. storyTellingOverviewBtnLabel: 'Overview',
  1841. storyTellingSelectSceneWarning: 'Please select a scene',
  1842. storyTellingSceneAddBtnTitle: 'Add a new scene',
  1843. storyTellingNumScenes: '%{index} scenes',
  1844. storyTellingTimelineDisabledInteraction: 'Tap again to pause and interact',
  1845. timelineRecord: 'Record',
  1846. timelineRecording: 'Capturing property changes...',
  1847. timelinePlay: 'Play',
  1848. timelinePause: 'Pause',
  1849. sceneStart: 'Jump to the beginning of the scene',
  1850. sceneEnd: 'Jump to the end of the scene',
  1851. sceneNavigation: 'Scene navigation',
  1852. navNextScene: 'Next scene',
  1853. navPrevScene: 'Previous scene',
  1854. navPrevSceneAbbreviated: 'Prev scene',
  1855. navExitFullScreen: 'Exit full screen',
  1856. navToggleOverview: 'Toggle overview',
  1857. fullscreen: 'Enter full screen',
  1858. fullscreenMenuLabel: 'Full screen',
  1859. betaStorytelling_1: 'This is a Beta feature and is subject to the terms of use found ',
  1860. betaStorytelling_2: 'here',
  1861. betaStorytelling_3: '. By using this Beta feature you agree to those terms.',
  1862. betaDialog: 'Technology Preview Code (TPC) provided with the IBM SaaS are not part of the IBM SaaS. TPC is provided under the same terms as the IBM SaaS, except as provided below. Some or all of the TPC may not be made generally available by IBM as or in a product or offering. You are permitted to use TPC only for internal use for evaluation purposes and not for use in a production environment. You may use the TPC until IBM withdraws the TPC or terminates access to it. IBM provides the TPC without obligation of support and "AS IS," WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE WARRANTY OF TITLE, NON-INFRINGEMENT OR NON-INTERFERENCE AND ANY IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. You should take precautions to avoid any loss of data that might result when the TPC can no longer be used. You agree IBM may use all feedback and suggestions you provide. ',
  1863. //time journey
  1864. 'sceneListStart': 'Start',
  1865. 'sceneListEnd': 'End',
  1866. // Pinning
  1867. 'contentPinFail': 'We can\'t collect the content: %{error}',
  1868. // Layouts
  1869. 'dropZoneLabel': 'Drop here to maximize',
  1870. //Share
  1871. shareDefaultPageTitle: 'Page %{index}',
  1872. shareDefaultStoryPageTitle: 'Scene %{index}',
  1873. nextPage: 'Next page',
  1874. previousPage: 'Previous page',
  1875. assetAssembly: 'view',
  1876. assetStory: 'story',
  1877. toolbar_save: 'Save',
  1878. brgr_saveAs: 'Save as',
  1879. brgr_refresh: 'Refresh',
  1880. saving: 'Saving...',
  1881. save_success: 'Your view has been saved.',
  1882. save_failure: 'We\'re sorry. Your view could not be saved. Please try again later.',
  1883. geminiLeave: 'You are about to leave IBM Watson Analytics.',
  1884. warning: 'Warning',
  1885. missingDataSetData: 'The data for this data set is not available. Refresh the data set or contact your administrator for access to the source.',
  1886. // Calculations
  1887. error_calculation_in_use: 'The selected calculation is in use and cannot be deleted.',
  1888. resize: 'Resize',
  1889. rotate: 'Rotate',
  1890. moveHandle: 'Move widget',
  1891. panHandle: 'Pan',
  1892. //Navigation
  1893. navigateTitle: 'Navigate to',
  1894. // Slide out titles
  1895. shapeSlideoutTitle: 'Shapes',
  1896. textSlideoutTitle: 'Text',
  1897. mediaSlideoutTitle: 'Media',
  1898. visualizationSlideoutTitle: 'Visualizations',
  1899. // Board Model Dialog Messages
  1900. invalidJSONResponse: 'Provided JSON is invalid. See error log for more information.',
  1901. // Widget type labels
  1902. shape_label: 'Shape',
  1903. image_label: 'Image',
  1904. data_label: 'Chart',
  1905. media_label: 'Media',
  1906. text_label: 'Text',
  1907. embedMedia_label: 'Media',
  1908. youtube_label: 'YouTube video',
  1909. webpage_label: 'Webpage',
  1910. // **** Smart names for objects ****
  1911. // You might think that one_name is useless, but we have it in case we need to change that resource into one_name_numbered
  1912. one_name: '%{name}',
  1913. one_name_numbered: '%{name} (%{number})',
  1914. noExtraText_shape: 'Shape',
  1915. noExtraText_shape_numbered: 'Shape (%{number})',
  1916. few_shape: 'Group of %{count} shapes',
  1917. many_shape: 'Group of %{count} shapes',
  1918. // %{text} is the alternate text of the image, specified in the properties by the user
  1919. one_image: '%{text} image',
  1920. one_image_number: '%{text} image (%{number})',
  1921. noExtraText_image: 'Image',
  1922. noExtraText_image_numbered: 'Image (%{number})',
  1923. few_image: 'Group of %{count} images',
  1924. many_image: 'Group of %{count} images',
  1925. noExtraText_text: 'Empty text box',
  1926. noExtraText_text_numbered: 'Empty text box (%{number})',
  1927. few_text: 'Group of %{count} text boxes',
  1928. many_text: 'Group of %{count} text boxes',
  1929. // %{name} is the user-provided name of the chart
  1930. one_named_data: '%{name} chart',
  1931. one_named_data_numbered: '%{name} chart (%{number})',
  1932. one_unknown_data: 'Chart',
  1933. one_unknown_data_numbered: 'Chart (%{number})',
  1934. // Bubble chart: y-axis vs x-axis by color bubble chart
  1935. RAVE2_bubble_has_mapping: '%{y} vs %{x} by %{color} bubble chart',
  1936. RAVE2_bubble_has_mapping_numbered: '%{y} vs %{x} by %{color} bubble chart (%{number})',
  1937. RAVE2_bubble_no_mapping: 'Empty bubble chart',
  1938. RAVE2_bubble_no_mapping_numbered: 'Empty bubble chart (%{number})',
  1939. RAVE2_bubble_named: '%{name} bubble chart',
  1940. RAVE2_bubble_named_numbered: '%{name} bubble chart (%{number})',
  1941. // Clustered Bar chart: y-axis by value bar chart - note that the labels are mislabeld vis-a-vis the slotIds
  1942. RAVE2_clusteredbar_has_mapping: '%{x} by %{y} bar chart',
  1943. RAVE2_clusteredbar_has_mapping_numbered: '%{x} by %{y} bar chart (%{number})',
  1944. RAVE2_clusteredbar_no_mapping: 'Empty bar chart',
  1945. RAVE2_clusteredbar_no_mapping_numbered: 'Empty bar chart (%{number})',
  1946. RAVE2_clusteredbar_named: '%{name} bar chart',
  1947. RAVE2_clusteredbar_named_numbered: '%{name} bar chart (%{number})',
  1948. // Clustered Column chart: value by x-axis column chart - note that the labels are mislabeld vis-a-vis the slotIds
  1949. RAVE2_clusteredcolumn_has_mapping: '%{y} by %{x} column chart',
  1950. RAVE2_clusteredcolumn_has_mapping_numbered: '%{y} by %{x} column chart (%{number})',
  1951. RAVE2_clusteredcolumn_no_mapping: 'Empty column chart',
  1952. RAVE2_clusteredcolumn_no_mapping_numbered: 'Empty column chart (%{number})',
  1953. RAVE2_clusteredcolumn_named: '%{name} column chart',
  1954. RAVE2_clusteredcolumn_named_numbered: '%{name} column chart (%{number})',
  1955. // Crosstab: values by Row1 (and Column1)
  1956. crosstab_opt_mapping: '%{values} by %{row_level1} and %{column_level1}',
  1957. crosstab_opt_mapping_numbered: '%{values} by %{row_level1} and %{column_level1} (%{number})',
  1958. crosstab_has_mapping: '%{values} by %{row_level1}',
  1959. crosstab_has_mapping_numbered: '%{values} by %{row_level1} (%{number})',
  1960. crosstab_no_mapping: 'Empty crosstab',
  1961. crosstab_no_mapping_numbered: 'Empty crosstab (%{number})',
  1962. crosstab_named: '%{name} crosstab',
  1963. crosstab_named_numbered: '%{name} crosstab (%{number})',
  1964. // Data player: axis label dataplayer
  1965. dataPlayer_has_mapping: '%{categories} data player',
  1966. dataPlayer_has_mapping_numbered: '%{categories} data player (%{number})',
  1967. dataPlayer_no_mapping: 'Empty data player',
  1968. dataPlayer_no_mapping_numbered: 'Empty data player (%{number})',
  1969. dataPlayer_named: '%{name} data player',
  1970. dataPlayer_named_numbered: '%{name} data player (%{number})',
  1971. // Grid: first column grid
  1972. JQGrid_has_mapping: '%{grid_cols} grid',
  1973. JQGrid_has_mapping_numbered: '%{grid_cols} grid (%{number})',
  1974. JQGrid_no_mapping: 'Empty grid',
  1975. JQGrid_no_mapping_numbered: 'Empty grid (%{number})',
  1976. JQGrid_named: '%{name} grid',
  1977. JQGrid_named_numbered: '%{name} grid (%{number})',
  1978. // Heatmap: color by x axis and y axis heatmap
  1979. RAVE2_heatmap_has_mapping: '%{color} by %{x} and %{y} heatmap',
  1980. RAVE2_heatmap_has_mapping_numbered: '%{color} by %{x} and %{y} heatmap (%{number})',
  1981. RAVE2_heatmap_no_mapping: 'Empty heatmap',
  1982. RAVE2_heatmap_no_mapping_numbered: 'Empty heatmap (%{number})',
  1983. RAVE2_heatmap_named: '%{name} heatmap',
  1984. RAVE2_heatmap_named_numbered: '%{name} heatmap (%{number})',
  1985. // Hierarchy: level one hierarchy
  1986. hierarchy_has_mapping: '%{level1} hierarchy',
  1987. hierarchy_has_mapping_numbered: '%{level1} hierarchy (%{number})',
  1988. hierarchy_no_mapping: 'Empty hierarchy',
  1989. hierarchy_no_mapping_numbered: 'Empty hierarchy (%{number})',
  1990. hierarchy_named: '%{name} hierarchy',
  1991. hierarchy_named_numbered: '%{name} hierarchy (%{number})',
  1992. // Legacy map: Region heat by Regions map
  1993. map_has_mapping: '%{values} by %{categories} map',
  1994. map_has_mapping_numbered: '%{values} by %{categories} map (%{number})',
  1995. map_no_mapping: 'Empty map',
  1996. map_no_mapping_numbered: 'Empty map (%{number})',
  1997. map_named: '%{name} map',
  1998. map_named_numbered: '%{name} map (%{number})',
  1999. // Line and column chart
  2000. RAVE2_compositeSmoothOneDataSet_has_mapping: 'Line and column chart',
  2001. RAVE2_compositeSmoothOneDataSet_has_mapping_numbered: 'Line and column chart (%{number})',
  2002. RAVE2_compositeSmoothOneDataSet_named: '%{name} line and column chart',
  2003. RAVE2_compositeSmoothOneDataSet_named_numbered: '%{name} line and column chart (%{number})',
  2004. // (New) map: region color by regions map
  2005. RAVE2_tiledmap_has_mapping: '%{value} by %{featureId} map',
  2006. RAVE2_tiledmap_has_mapping_numbered: '%{value} by %{featureId} map (%{number})',
  2007. RAVE2_tiledmap_no_mapping: 'Empty map',
  2008. RAVE2_tiledmap_no_mapping_numbered: 'Empty map (%{number})',
  2009. RAVE2_tiledmap_named: '%{name} map',
  2010. RAVE2_tiledmap_named_numbered: '%{name} map (%{number})',
  2011. // Packed bubble chart: categories by size bubble chart
  2012. RAVE2_packedBubble_has_mapping: '%{label} by %{size} bubble chart',
  2013. RAVE2_packedBubble_has_mapping_numbered: '%{label} by %{size} bubble chart (%{number})',
  2014. RAVE2_packedBubble_no_mapping: 'Empty bubble chart',
  2015. RAVE2_packedBubble_no_mapping_numbered: 'Empty bubble chart (%{number})',
  2016. RAVE2_packedBubble_named: '%{name} bubble chart',
  2017. RAVE2_packedBubble_named_numbered: '%{name} bubble chart (%{number})',
  2018. // Pie chart: values by categories pie chart
  2019. RAVE2_pie_has_mapping: '%{value} by %{color} pie chart',
  2020. RAVE2_pie_has_mapping_numbered: '%{value} by %{color} pie chart (%{number})',
  2021. RAVE2_pie_no_mapping: 'Empty pie chart',
  2022. RAVE2_pie_no_mapping_numbered: 'Empty pie chart (%{number})',
  2023. RAVE2_pie_named: '%{name} pie chart',
  2024. RAVE2_pie_named_numbered: '%{name} pie chart (%{number})',
  2025. // Point chart: value by x axis point chart
  2026. RAVE2_point_has_mapping: '%{y} by %{x} point chart',
  2027. RAVE2_point_has_mapping_numbered: '%{y} by %{x} point chart (%{number})',
  2028. RAVE2_point_no_mapping: 'Empty point chart',
  2029. RAVE2_point_no_mapping_numbered: 'Empty point chart (%{number})',
  2030. RAVE2_point_named: '%{name} point chart',
  2031. RAVE2_point_named_numbered: '%{name} point chart (%{number})',
  2032. // Radial chart: value by label radial chart
  2033. RAVE2_dial_has_mapping: '%{value} by %{label} radial chart',
  2034. RAVE2_dial_has_mapping_numbered: '%{value} by %{label} radial chart (%{number})',
  2035. RAVE2_dial_no_mapping: 'Empty radial chart',
  2036. RAVE2_dial_no_mapping_numbered: 'Empty radial chart (%{number})',
  2037. RAVE2_dial_named: '%{name} radial chart',
  2038. RAVE2_dial_named_numbered: '%{name} radial chart (%{number})',
  2039. // Radial bar, category labels chart: value by categories radial bar chart
  2040. RAVE2_multipleDialCategoryLabel_has_mapping: '%{value} by %{category} radial bar chart',
  2041. RAVE2_multipleDialCategoryLabel_has_mapping_numbered: '%{value} by %{category} radial bar chart (%{number})',
  2042. RAVE2_multipleDialCategoryLabel_no_mapping: 'Empty radial bar chart',
  2043. RAVE2_multipleDialCategoryLabel_no_mapping_numbered: 'Empty radial bar chart (%{number})',
  2044. RAVE2_multipleDialCategoryLabel_named: '%{name} radial bar chart',
  2045. RAVE2_multipleDialCategoryLabel_named_numbered: '%{name} radial bar chart (%{number})',
  2046. // Scatter plot: points by x axis and y axis scatter plot OR (if no points) x axis vs y axis scatter plot
  2047. RAVE2_scatter_opt_mapping: '%{label} by %{x} and %{y} scatter plot',
  2048. RAVE2_scatter_opt_mapping_numbered: '%{label} by %{x} and %{y} scatter plot (%{number})',
  2049. RAVE2_scatter_has_mapping: '%{x} vs %{y} scatter plot',
  2050. RAVE2_scatter_has_mapping_numbered: '%{x} vs %{y} scatter plot (%{number})',
  2051. RAVE2_scatter_no_mapping: 'Empty scatter plot',
  2052. RAVE2_scatter_no_mapping_numbered: 'Empty scatter plot (%{number})',
  2053. RAVE2_scatter_named: '%{name} scatter plot',
  2054. RAVE2_scatter_named_numbered: '%{name} scatter plot (%{number})',
  2055. // Smooth area chart: value by x axis smooth area chart
  2056. RAVE2_smoothArea_has_mapping: '%{y} by %{x} smooth area chart',
  2057. RAVE2_smoothArea_has_mapping_numbered: '%{y} by %{x} smooth area chart (%{number})',
  2058. RAVE2_smoothArea_no_mapping: 'Empty smooth area chart',
  2059. RAVE2_smoothArea_no_mapping_numbered: 'Empty smooth area chart (%{number})',
  2060. RAVE2_smoothArea_named: '%{name} smooth area chart',
  2061. RAVE2_smoothArea_named_numbered: '%{name} smooth area chart (%{number})',
  2062. // Smooth line chart: value by x axis smooth line chart
  2063. RAVE2_smoothline_has_mapping: '%{y} by %{x} smooth line chart',
  2064. RAVE2_smoothline_has_mapping_numbered: '%{y} by %{x} smooth line chart (%{number})',
  2065. RAVE2_smoothline_no_mapping: 'Empty smooth line chart',
  2066. RAVE2_smoothline_no_mapping_numbered: 'Empty smooth line chart (%{number})',
  2067. RAVE2_smoothline_named: '%{name} smooth line chart',
  2068. RAVE2_smoothline_named_numbered: '%{name} smooth line chart (%{number})',
  2069. // Stacked Bar chart: x-axis by value bar chart - note that the labels are mislabeld vis-a-vis the slotIds
  2070. RAVE2_stackedbar_has_mapping: '%{x} by %{y} bar chart',
  2071. RAVE2_stackedbar_has_mapping_numbered: '%{x} by %{y} bar chart (%{number})',
  2072. RAVE2_stackedbar_no_mapping: 'Empty bar chart',
  2073. RAVE2_stackedbar_no_mapping_numbered: 'Empty bar chart (%{number})',
  2074. RAVE2_stackedbar_named: '%{name} bar chart',
  2075. RAVE2_stackedbar_named_numbered: '%{name} bar chart (%{number})',
  2076. // Stacked Column chart: x-axis by value column chart - note that the labels are mislabeld vis-a-vis the slotIds
  2077. RAVE2_stackedcolumn_has_mapping: '%{x} by %{y} column chart',
  2078. RAVE2_stackedcolumn_has_mapping_numbered: '%{x} by %{y} column chart (%{number})',
  2079. RAVE2_stackedcolumn_no_mapping: 'Empty column chart',
  2080. RAVE2_stackedcolumn_no_mapping_numbered: 'Empty column chart (%{number})',
  2081. RAVE2_stackedcolumn_named: '%{name} column chart',
  2082. RAVE2_stackedcolumn_named_numbered: '%{name} column chart (%{number})',
  2083. // Summary value: value summary value
  2084. summary_has_mapping: '%{values} summary value',
  2085. summary_has_mapping_numbered: '%{values} summary value (%{number})',
  2086. summary_no_mapping: 'Empty summary value',
  2087. summary_no_mapping_numbered: 'Empty summary value (%{number})',
  2088. summary_named: '%{name} summary value',
  2089. summary_named_numbered: '%{name} summary value (%{number})',
  2090. // (Infographic summary) Infographic: value infographic
  2091. infographicSummary_has_mapping: '%{values} infographic',
  2092. infographicSummary_has_mapping_numbered: '%{values} infographic (%{number})',
  2093. infographicSummary_no_mapping: 'Empty infographic',
  2094. infographicSummary_no_mapping_numbered: 'Empty infographic (%{number})',
  2095. infographicSummary_named: '%{name} infographic',
  2096. infographicSummary_named_numbered: '%{name} infographic (%{number})',
  2097. // Tree map: 'size by' by 'level 1' tree map
  2098. treeMap_has_mapping: '%{categories} by %{values} tree map',
  2099. treeMap_has_mapping_numbered: '%{categories} by %{values} tree map (%{number})',
  2100. treeMap_no_mapping: 'Empty tree map',
  2101. treeMap_no_mapping_numbered: 'Empty tree map (%{number})',
  2102. treeMap_named: '%{name} tree map',
  2103. treeMap_named_numbered: '%{name} tree map (%{number})',
  2104. // Word cloud: words word cloud
  2105. RAVE2_wordcloud_has_mapping: '%{label} word cloud',
  2106. RAVE2_wordcloud_has_mapping_numbered: '%{label} word cloud (%{number})',
  2107. RAVE2_wordcloud_no_mapping: 'Empty word cloud',
  2108. RAVE2_wordcloud_no_mapping_numbered: 'Empty word cloud (%{number})',
  2109. RAVE2_wordcloud_named: '%{name} word cloud',
  2110. RAVE2_wordcloud_named_numbered: '%{name} word cloud (%{number})',
  2111. few_data: 'Group of %{count} charts',
  2112. many_data: 'Group of %{count} charts',
  2113. noExtraText_youtube: 'YouTube video',
  2114. noExtraText_youtube_numbered: 'YouTube video (%{number})',
  2115. // %{text} is the user-provided title of the video
  2116. one_youtube: '%{text} YouTube video',
  2117. one_youtube_numbered: '%{text} YouTube video (%{number})',
  2118. few_youtube: 'Group of %{count} YouTube videos',
  2119. many_youtube: 'Group of %{count} YouTube videos',
  2120. noExtraText_embedMedia: 'Media link',
  2121. noExtraText_embedMedia_numbered: 'Media link (%{number})',
  2122. // %{text} is the user-provided title of the media link
  2123. one_embedMedia: '%{text} media link',
  2124. one_embedMedia_numbered: '%{text} media link (%{number})',
  2125. few_embedMedia: 'Group of %{count} media links',
  2126. many_embedMedia: 'Group of %{count} media links',
  2127. noExtraText_media: 'Media',
  2128. noExtraText_media_numbered: 'Media (%{number})',
  2129. // %{text} is the user-provided title of the media link
  2130. one_media: '%{text} media',
  2131. one_media_numbered: '%{text} media (%{number})',
  2132. few_media: 'Group of %{count} media',
  2133. many_media: 'Group of %{count} media',
  2134. noExtraText_webpage: 'Web page',
  2135. noExtraText_webpage_numbered: 'Web page (%{number})',
  2136. // %{text} is the user-provided title of the web page
  2137. one_webpage: '%{text} web page',
  2138. one_webpage_numbered: '%{text} web page (%{number})',
  2139. few_webpage: 'Group of %{count} web pages',
  2140. many_webpage: 'Group of %{count} web pages',
  2141. one_unknown: 'An object',
  2142. one_unknown_numbered: 'An object (%{number})',
  2143. few_unknown: 'Group of %{count} objects',
  2144. many_unknown: 'Group of %{count} objects',
  2145. //a11y label for the left/right arrow for navigation path
  2146. next: 'Next',
  2147. previous: 'Previous',
  2148. //a11y description
  2149. current_nav_group: 'Current navigation group is %{navigation_group_name}',
  2150. //Page Context
  2151. 'filterBlank': '(blank)'
  2152. },
  2153. "cs": true,
  2154. "da": true,
  2155. "de": true,
  2156. "es": true,
  2157. "fi": true,
  2158. "fr": true,
  2159. "hr": true,
  2160. "hu": true,
  2161. "it": true,
  2162. "ja": true,
  2163. "kk": true,
  2164. "ko": true,
  2165. "no": true,
  2166. "nb": true,
  2167. "nl": true,
  2168. "pl": true,
  2169. "pt": true,
  2170. "pt-br": true,
  2171. "ro": true,
  2172. "ru": true,
  2173. "sl": true,
  2174. "sv": true,
  2175. "th": true,
  2176. "tr": true,
  2177. "zh": true,
  2178. "zh-cn": true,
  2179. "zh-tw": true
  2180. });
  2181. /**
  2182. * Licensed Materials - Property of IBM
  2183. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  2184. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  2185. */
  2186. define('bacontentnav/lib/gemini/app/nls/StringResources',[
  2187. 'i18n!../../dashboard/nls/DashboardResources',
  2188. 'i18n!../nls/DashboardResources',
  2189. 'polyglot'
  2190. ], function(titanResources, geminiResources, Polyglot) {
  2191. /**
  2192. * Module which provides simple access to string resources.
  2193. *
  2194. */
  2195. var titanPoly = new Polyglot({
  2196. phrases: titanResources,
  2197. allowMissing: true
  2198. });
  2199. var geminiPoly = new Polyglot({
  2200. phrases: geminiResources
  2201. });
  2202. var StringResources = function() {};
  2203. /**
  2204. * Get the string resource for the given key and interpolation options
  2205. *
  2206. * @param key The key of the string to return
  2207. * @param interpolationOptions Optional interpolation options (see poly.t documentation for details)
  2208. * @returns The string to display
  2209. */
  2210. StringResources.prototype.get = function( key, interpolationOptions ) {
  2211. var msg = titanPoly.t(key, interpolationOptions);
  2212. if(msg === key){
  2213. msg = geminiPoly.t(key, interpolationOptions);
  2214. }
  2215. return msg;
  2216. };
  2217. return new StringResources();
  2218. });
  2219. /**
  2220. * Licensed Materials - Property of IBM
  2221. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  2222. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  2223. */
  2224. define('bacontentnav/lib/gemini/app/ui/dialogs/BaseDialog',['../../../../@waca/core-client/js/core-client/ui/core/Class', 'jquery', 'underscore', '../../nls/StringResources', '../../../../@waca/core-client/js/core-client/utils/EventHelper'], function(Class, $, _, stringResources) {
  2225. 'use strict';
  2226. var Dialog = Class.extend({
  2227. _buttons: ['ok', 'cancel'],
  2228. _showCloseX: false,
  2229. _width: null,
  2230. _minWidth:null,
  2231. init: function( options ) {
  2232. this._dialogId = _.uniqueId('modalDialog_');
  2233. this._queryId = '#' + this._dialogId;
  2234. this._defaultKeyMap = { "13": this.ok, "27": this.cancel };
  2235. this.keyMap = this._getKeyCodeMap();
  2236. // set dialog options
  2237. this.setDialogOptions( options );
  2238. },
  2239. // Children can override to provide different key event mappings
  2240. _getKeyCodeMap: function() {
  2241. return this._defaultKeyMap;
  2242. },
  2243. setDialogOptions: function( options ){
  2244. // process options
  2245. if( options ) {
  2246. // set width as necessary
  2247. if( options.width ) {
  2248. this._width = options.width;
  2249. }
  2250. if(options.minWidth){
  2251. this._minWidth = options.minWidth;
  2252. }
  2253. // set closeX button option
  2254. if( options.showCloseX ) {
  2255. this._showCloseX = options.showCloseX;
  2256. }
  2257. // Check for buttons passed in and override defaults.
  2258. if( options.buttons ) {
  2259. this._buttons = options.buttons;
  2260. }
  2261. }
  2262. },
  2263. destroy: function() {
  2264. $(this._queryId).remove();
  2265. },
  2266. remove: function() {
  2267. this.destroy();
  2268. },
  2269. hide: function() {
  2270. $(this._queryId).removeClass('show');
  2271. this.destroy();
  2272. },
  2273. open: function() {
  2274. this.showBlocker();
  2275. this.show();
  2276. },
  2277. // Children can override to provide different blocker cell definitions to use
  2278. getBlockerCell: function() {
  2279. return $('<div>', {
  2280. 'id': this._dialogId + 'Container',
  2281. 'class': 'dialogBlockerCell'
  2282. });
  2283. },
  2284. showBlocker: function() {
  2285. var nBlocker = $(this._queryId);
  2286. if (!nBlocker.length) {
  2287. nBlocker = $('<div>', {
  2288. 'id': this._dialogId,
  2289. 'class': 'dialogBlocker show'
  2290. });
  2291. // set the blocker height (works with scrollbars)
  2292. nBlocker.height($(document).height());
  2293. var nBlockerCell = this.getBlockerCell();
  2294. $('body').append(
  2295. nBlocker.append(
  2296. nBlockerCell.text( stringResources.get('dlg_loading') )
  2297. )
  2298. );
  2299. nBlocker.on('keydown', this.onKey.bind(this));
  2300. }
  2301. },
  2302. show: function() {
  2303. var nContainer = this._container();
  2304. // set width as necessary
  2305. if( this._width ) {
  2306. nContainer.css("max-width", this._width );
  2307. }
  2308. if( this._minWidth ) {
  2309. nContainer.css("min-width", this._minWidth );
  2310. }
  2311. // build dialog as necessary
  2312. if (nContainer.length) {
  2313. nContainer.empty();
  2314. var header = $('<div>', {'class': 'dialogHeader'}),
  2315. title = this.renderTitle( $('<header>', {'class': 'dialogTitle'}) ),
  2316. closeX = this.renderCloseX(),
  2317. content = this.renderContent( $('<div>', {'class': 'dialogContent'}) ),
  2318. footer = this.renderFooter( $('<footer>') );
  2319. // pop the title and closeX into the header
  2320. header.append( title, closeX );
  2321. // set width as necessary (this prevents content from collapsing)
  2322. if( this._width ) {
  2323. header.css( 'max-width',this._width );
  2324. }
  2325. if( this._minWidth ) {
  2326. header.css( 'min-width',this._minWidth );
  2327. }
  2328. // assemble dialog
  2329. nContainer.append(
  2330. $('<div>', {
  2331. 'class': 'modalDialog',
  2332. 'tabIndex': '0',
  2333. 'role': 'dialog'
  2334. }).append(
  2335. header,
  2336. content,
  2337. footer
  2338. )
  2339. );
  2340. //Support for IE
  2341. var modalDialog = nContainer.find('.modalDialog');
  2342. if(this._width){
  2343. modalDialog.css('max-width', this._width);
  2344. }
  2345. if(this._minWidth){
  2346. modalDialog.css('min-width', this._minWidth);
  2347. }
  2348. this.focusOnButton();
  2349. }
  2350. },
  2351. // Children can override to provide different initial button focusing behaviour
  2352. focusOnButton: function() {
  2353. var firstBtn = this._container().find('footer').children('.dialogButton')[0];
  2354. if (firstBtn) {
  2355. firstBtn.focus();
  2356. }
  2357. },
  2358. renderContent: function(n) {
  2359. n.text('Dialog Content');
  2360. return n;
  2361. },
  2362. renderTitle: function(n) {
  2363. n.text('Dialog Title');
  2364. return n;
  2365. },
  2366. /**
  2367. * This function adds a CSS class that will cause the dialog to be centered vertically.
  2368. * This could potentially be affected by additional styles in extended dialog classes.
  2369. **/
  2370. verticalAlignDialog: function() {
  2371. this._container().addClass( 'dialogVerticalAlign' );
  2372. },
  2373. renderCloseX: function() {
  2374. // only render if required
  2375. if( !this._showCloseX ){
  2376. return null;
  2377. }
  2378. // create button
  2379. var closeX = $('<div>',
  2380. {
  2381. 'class': 'wfg_shape_x dialogCloseX',
  2382. 'title': stringResources.get('dlg_close'),
  2383. 'aria-label': stringResources.get('dlg_close'),
  2384. 'role': 'button'
  2385. });
  2386. closeX.onClick( this.cancel.bind( this ) );
  2387. return closeX;
  2388. },
  2389. renderFooter: function(n) {
  2390. // loop though button collection and process
  2391. for (var i = 0, iLen = this._buttons.length; i < iLen; i++) {
  2392. var btnSpec = this._getButtonDef( this._buttons[i] );
  2393. var b = {
  2394. 'class': 'dialogButton ' + btnSpec.type,
  2395. 'text': btnSpec.text,
  2396. 'aria-label' : btnSpec.text,
  2397. 'role' : 'button',
  2398. 'tabIndex': '0'
  2399. };
  2400. n.append($('<button>', b).onClick(btnSpec.handler.bind(this)));
  2401. }
  2402. return n;
  2403. },
  2404. /**
  2405. * This function takes a given button id or partial definition and updates it to return a complete definition.
  2406. *
  2407. * A button can be an id such as: "ok", "cancel", or "close" OR
  2408. * a button can be an object containing one or more of the following options:
  2409. * {
  2410. * text: String label to display
  2411. * handler: Callback function
  2412. * defaultId: If specified this will use the spec specified by the id (i.e. "ok") for missing info
  2413. * type: "primary" or "secondary" will set the class and visuals accordingly. "destructive"
  2414. * is not currently supportted but might be in the future
  2415. * }
  2416. *
  2417. * @param button Button id or partial spec object
  2418. * @returns Object Complete button spec.
  2419. **/
  2420. _getButtonDef: function( button ) {
  2421. // define the default button spec
  2422. var buttonsDef = {
  2423. 'ok': { 'text': stringResources.get('dlg_ok'), 'handler': this.ok, 'type':'primary' },
  2424. 'cancel': { 'text': stringResources.get('dlg_cancel'), 'handler': this.cancel, 'type':'secondary' },
  2425. 'close': { 'text': stringResources.get('dlg_close'), 'handler': this.cancel, 'type':'primary' }
  2426. };
  2427. // if object is passed then fill in missing otherwise lookup and return
  2428. if( typeof( button ) === 'object' ) {
  2429. // check for defaultId
  2430. if( button.defaultId ) {
  2431. // default text if necessary
  2432. if( !button.text ) {
  2433. button.text = buttonsDef[ button.defaultId ].text;
  2434. }
  2435. // default handler if necesssary
  2436. if( !button.handler ) {
  2437. button.handler = buttonsDef[ button.defaultId ].handler;
  2438. }
  2439. // default type if necesssary
  2440. if( !button.type ) {
  2441. button.type = buttonsDef[ button.defaultId ].type;
  2442. }
  2443. }
  2444. // return
  2445. return button;
  2446. }
  2447. return buttonsDef[ button ];
  2448. },
  2449. onKey: function(evt) {
  2450. var keyCodeString = evt.keyCode.toString();
  2451. if (this.keyMap.hasOwnProperty(keyCodeString)) {
  2452. this.keyMap[keyCodeString].call(this);
  2453. return false;
  2454. }
  2455. return true;
  2456. },
  2457. ok: function() {
  2458. this.hide();
  2459. },
  2460. cancel: function() {
  2461. this.hide();
  2462. },
  2463. /**
  2464. *
  2465. */
  2466. enableOk: function(bEnabled) {
  2467. var btn = $('.dialogButton', this._container()).eq(0);
  2468. btn.toggleClass('disabled', bEnabled === false); // if bEnabled is undefined, it means true.
  2469. if (bEnabled === false) {
  2470. btn.attr('disabled','disabled');
  2471. }
  2472. else {
  2473. btn.removeAttr('disabled');
  2474. }
  2475. },
  2476. disableOk: function() {
  2477. this.enableOk(false);
  2478. },
  2479. _container: function() {
  2480. return $(this._queryId + 'Container');
  2481. }
  2482. });
  2483. return Dialog;
  2484. });
  2485. /**
  2486. * Licensed Materials - Property of IBM
  2487. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014
  2488. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  2489. */
  2490. define('bacontentnav/lib/gemini/app/ui/dialogs/MessageBox',['./BaseDialog', 'jquery', 'underscore'], function(BaseDialog, $, _) {
  2491. var Dialog = null;
  2492. Dialog = BaseDialog.extend({
  2493. _buttons: ['ok'],
  2494. init: function(sType, sTitle, sMessage) {
  2495. this._props = {
  2496. 'type': sType,
  2497. 'title': sTitle,
  2498. 'msg': sMessage
  2499. };
  2500. Dialog.inherited('init', this, arguments);
  2501. },
  2502. renderContent: function(n) {
  2503. n.append(
  2504. $('<div>', {
  2505. 'class': 'messageBox ' + this._props.type,
  2506. 'html': _.escape(this._props.msg)
  2507. })
  2508. );
  2509. return n;
  2510. },
  2511. renderTitle: function(n) {
  2512. n.text(this._props.title);
  2513. return n;
  2514. }
  2515. });
  2516. return Dialog;
  2517. });
  2518. /*
  2519. *+------------------------------------------------------------------------+
  2520. *| Licensed Materials - Property of IBM
  2521. *| IBM Cognos Products: Content Explorer
  2522. *| (C) Copyright IBM Corp. 2015, 2018
  2523. *|
  2524. *| US Government Users Restricted Rights - Use, duplication or disclosure
  2525. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  2526. *+------------------------------------------------------------------------+
  2527. */
  2528. define('bacontentnav/ui/dialogs/NameCollisionDialog',[
  2529. '../../lib/gemini/app/ui/dialogs/MessageBox',
  2530. '../../nls/StringResource',
  2531. '../../lib/@waca/core-client/js/core-client/ui/properties/CheckBox'
  2532. ], function(MessageBox, StringResource, CheckBox) {
  2533. var Dialog = null;
  2534. Dialog = MessageBox.extend({
  2535. //Design was debating between two dialog options, the bulk dialog, and the one by one dialog.
  2536. //Set this to false to display the One by One dialog, with the checkbox.
  2537. _DISPLAY_BULK_DIALOG: true,
  2538. _buttons: [],
  2539. _replaceCallback: null,
  2540. _keepBothCallback: null,
  2541. _skipCallback: null,
  2542. create: function(replace, keepBoth, skip, isCopyAction, name) {
  2543. this._replaceCallback = replace;
  2544. this._keepBothCallback = keepBoth;
  2545. this._skipCallback = skip;
  2546. this._name = name;
  2547. /*Set the strings for the buttons, depending on whether the current action is copy or move*/
  2548. var replaceStr, skipObj, keepBothStr;
  2549. if (this._DISPLAY_BULK_DIALOG) {
  2550. replaceStr = StringResource.get('overwrite');
  2551. keepBothStr = StringResource.get('rename');
  2552. skipObj = 'cancel';
  2553. } else {
  2554. replaceStr = (isCopyAction) ? StringResource.get('copyReplace') : StringResource.get('moveReplace');
  2555. keepBothStr = StringResource.get('keepBoth');
  2556. var skipStr = (isCopyAction) ? StringResource.get('copySkip') : StringResource.get('moveSkip');
  2557. skipObj = {
  2558. 'text': skipStr,
  2559. 'handler': this.skip,
  2560. 'type': 'primary copy',
  2561. 'defaultId': 'skipButton'
  2562. };
  2563. }
  2564. this._buttons = [];
  2565. if (this._replaceCallback) {
  2566. this._buttons.push({
  2567. 'text': replaceStr,
  2568. 'handler': this.replace,
  2569. 'type': 'primary move',
  2570. 'defaultId': 'replaceButton'
  2571. });
  2572. }
  2573. if (this._keepBothCallback) {
  2574. this._buttons.push({
  2575. 'text': keepBothStr,
  2576. 'handler': this.keepBoth,
  2577. 'type': 'primary move',
  2578. 'defaultId': 'keepBothButton'
  2579. });
  2580. }
  2581. this._buttons.push(skipObj);
  2582. /* Create a few global variables shared by all NameCollisionDialogs */
  2583. if (typeof Dialog.stack === 'undefined') {
  2584. Dialog.stack = [];
  2585. }
  2586. if (typeof Dialog._repeatActionCallBack === 'undefined') {
  2587. Dialog._repeatActionCallBack = null;
  2588. }
  2589. if (typeof Dialog._doRepeatAction === 'undefined') {
  2590. Dialog._doRepeatAction = false;
  2591. }
  2592. /*Variable that keeps track of whether or not this dialog is the last dialog to appear*/
  2593. this.isLastInstance = true;
  2594. if (Dialog.stack.length !== 0) {
  2595. Dialog.stack[Dialog.stack.length - 1].isLastInstance = false;
  2596. }
  2597. Dialog.stack.push(this);
  2598. if (this._DISPLAY_BULK_DIALOG) {
  2599. if (Dialog.stack.length > 1) {
  2600. this._props.title = StringResource.get('bulkNameCollision', {
  2601. 'noOfItems': Dialog.stack.length
  2602. });
  2603. }
  2604. } else {
  2605. this._props.title = StringResource.get('nameCollision', {
  2606. 'nameOfItem': this._name
  2607. });
  2608. }
  2609. },
  2610. replace: function() {
  2611. this.checkRepeat('replace');
  2612. if (this._replaceCallback) {
  2613. this._replaceCallback();
  2614. }
  2615. Dialog.inherited('ok', this, arguments);
  2616. },
  2617. keepBoth: function() {
  2618. this.checkRepeat('keepBoth');
  2619. if (this._keepBothCallback) {
  2620. this._keepBothCallback();
  2621. }
  2622. Dialog.inherited('ok', this, arguments);
  2623. },
  2624. skip: function() {
  2625. this.checkRepeat('skip');
  2626. if (this._skipCallback) {
  2627. this._skipCallback();
  2628. }
  2629. Dialog.inherited('cancel', this, arguments);
  2630. },
  2631. cancel: function() {
  2632. this.checkRepeat('cancel');
  2633. Dialog.inherited('cancel', this, arguments);
  2634. },
  2635. hide: function() {
  2636. Dialog.inherited('hide', this, arguments);
  2637. //Remove the curent element in the stack
  2638. Dialog.stack = $.grep(Dialog.stack, function(value) {
  2639. return value !== this;
  2640. }.bind(this));
  2641. if (Dialog.stack.length > 0) {
  2642. //Open next element. Only one dialog should be opened at a time.
  2643. if (!this._DISPLAY_BULK_DIALOG && !Dialog._doRepeatAction) {
  2644. Dialog.stack[0].open();
  2645. } else {
  2646. /*The user selected the checkbox to apply his action for all dialogs.
  2647. Do not open the other dialogs, but do apply the saved action.*/
  2648. Dialog.stack[0].doRepeat();
  2649. }
  2650. } else {
  2651. //There is no more dialogs to process. Clear the global variables.
  2652. Dialog._doRepeatAction = false;
  2653. Dialog._repeatActionCallBack = null;
  2654. }
  2655. },
  2656. open: function() {
  2657. Dialog.inherited('open', this, arguments);
  2658. this.renderContent($('<div>'));
  2659. /*
  2660. Add the checkbox to apply the selected action to all remaining dialogs.
  2661. Do not add the checkbox if only 1 dialog remains.
  2662. */
  2663. if (!this._DISPLAY_BULK_DIALOG && Dialog.stack.length > 1) {
  2664. var footer = this._container().find('footer');
  2665. footer.addClass('propertyUIControl');
  2666. var $checkBoxDiv = $('<div></div>');
  2667. footer.prepend($checkBoxDiv);
  2668. var labelStr = StringResource.get('repeatNameCollisionAction', {
  2669. 'noItems': Dialog.stack.length - 1
  2670. });
  2671. //If there are exactly 2 elements in the stack, fetch the singular string
  2672. if (Dialog.stack.length - 1 === 1) {
  2673. labelStr = StringResource.get('repeatNameCollisionActionSingular');
  2674. }
  2675. var aCheckbox = new CheckBox({
  2676. 'el': $checkBoxDiv,
  2677. 'id': 'nameCollision',
  2678. 'name': 'nameCollision',
  2679. 'position': 'leading',
  2680. 'label': labelStr,
  2681. 'controlOnLeft': true,
  2682. 'onChange': function(event) {
  2683. void(event);
  2684. Dialog._doRepeatAction = !Dialog._doRepeatAction;
  2685. }.bind(this)
  2686. });
  2687. aCheckbox.render();
  2688. Dialog._doRepeatAction = false;
  2689. }
  2690. if (!this._DISPLAY_BULK_DIALOG || Dialog.stack.length === 1) {
  2691. var header = this._container().find('div.dialogHeader');
  2692. var $nameHeader = $('<header></header>');
  2693. $nameHeader.addClass('dialogTitle');
  2694. $nameHeader.text(this._name);
  2695. header.append($nameHeader);
  2696. }
  2697. this._container().addClass('nameCollisionDialog');
  2698. },
  2699. checkRepeat: function(str) {
  2700. if (this._DISPLAY_BULK_DIALOG || (!Dialog._repeatActionCallBack && Dialog._doRepeatAction)) {
  2701. Dialog._repeatActionCallBack = str;
  2702. }
  2703. },
  2704. doRepeat: function() {
  2705. switch (Dialog._repeatActionCallBack) {
  2706. case 'replace':
  2707. this.replace();
  2708. break;
  2709. case 'keepBoth':
  2710. this.keepBoth();
  2711. break;
  2712. case 'skip':
  2713. this.skip();
  2714. break;
  2715. case 'cancel':
  2716. this.cancel();
  2717. break;
  2718. default:
  2719. break;
  2720. }
  2721. },
  2722. isLast: function() {
  2723. return this.isLastInstance;
  2724. }
  2725. });
  2726. return Dialog;
  2727. });
  2728. /*
  2729. *+------------------------------------------------------------------------+
  2730. *| Licensed Materials - Property of IBM
  2731. *| IBM Cognos Products: Content Explorer
  2732. *| (C) Copyright IBM Corp. 2015, 2020
  2733. *|
  2734. *| US Government Users Restricted Rights - Use, duplication or disclosure
  2735. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  2736. *+------------------------------------------------------------------------+
  2737. */
  2738. define('bacontentnav/utils/ContentManagement',[
  2739. 'underscore',
  2740. '../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  2741. './ContentServiceUrls',
  2742. './ContentStoreObject',
  2743. './GlassContextHelper',
  2744. '../nls/StringResource',
  2745. '../ui/dialogs/NameCollisionDialog'
  2746. ], function(_, BidiUtil, ContentServiceUrls, ContentStoreObject, GlassContextHelper, StringResource, NameCollisionDialog) {
  2747. 'use strict'; //NOSONAR
  2748. var _singletonInstance = null;
  2749. var ContentManagement = function() {
  2750. if (ContentManagement.prototype._singletonInstance) {
  2751. return ContentManagement.prototype._singletonInstance;
  2752. }
  2753. };
  2754. ContentManagement.prototype._init = function(options) {
  2755. this._glassContext = options.glassContext;
  2756. this._ajaxService = this._glassContext.getCoreSvc('.Ajax');
  2757. this._contentServicePromise = this._glassContext.getSvc('.Content');
  2758. this._options = options;
  2759. };
  2760. ContentManagement.prototype._onAllSettled = function(action, results) {
  2761. // refresh content if any move was successful
  2762. var successCount = _.filter(results, function(result) {
  2763. return result.isFulfilled();
  2764. }).length;
  2765. if (successCount) {
  2766. // show toast of successful items and refresh content
  2767. this._displayToast(action, successCount, results.length);
  2768. this._refreshContent();
  2769. }
  2770. // show name collision dialog if necessary
  2771. if (NameCollisionDialog.stack && NameCollisionDialog.stack.length) {
  2772. NameCollisionDialog.stack[NameCollisionDialog.stack.length - 1].open();
  2773. }
  2774. };
  2775. //TODO: this should be extracted to a common core utility
  2776. ContentManagement.prototype._allSettled = function(promiseArray) {
  2777. return Promise.all(promiseArray.map(function(promise) {
  2778. return promise.reflect();
  2779. }));
  2780. };
  2781. /**
  2782. * Returns the message associated with the given action, number of objects and name.
  2783. */
  2784. ContentManagement.prototype._displayToast = function(action, successCount, totalCount) {
  2785. var msg;
  2786. var isSingleSuccessfulAction = totalCount === 1 && successCount === 1;
  2787. switch (action) {
  2788. case 'copy':
  2789. msg = (isSingleSuccessfulAction) ?
  2790. StringResource.get('toastDoneCopyingSingular', {
  2791. 'nameOfItem': BidiUtil.enforceTextDirection(this._options.inputObjects[0].defaultName)
  2792. }) :
  2793. StringResource.get('toastDoneCopying', {
  2794. 'noOfItems': successCount
  2795. });
  2796. break;
  2797. case 'shortcut':
  2798. msg = (isSingleSuccessfulAction) ?
  2799. StringResource.get('toastDoneShortcuttingSingular', {
  2800. 'nameOfItem': BidiUtil.enforceTextDirection(this._getShortCutName(this._options.inputObjects[0].defaultName))
  2801. }) :
  2802. StringResource.get('toastDoneShortcutting', {
  2803. 'noOfItems': successCount
  2804. });
  2805. break;
  2806. default: // move
  2807. msg = (isSingleSuccessfulAction) ?
  2808. StringResource.get('toastDoneMovingSingular', {
  2809. 'nameOfItem': BidiUtil.enforceTextDirection(this._options.inputObjects[0].defaultName)
  2810. }) :
  2811. StringResource.get('toastDoneMoving', {
  2812. 'noOfItems': successCount
  2813. });
  2814. }
  2815. GlassContextHelper.displayToast(this._glassContext, msg);
  2816. };
  2817. ContentManagement.prototype.isNameConflict = function(error) {
  2818. var errorCode = (error && error.jqXHR && error.jqXHR.responseJSON && error.jqXHR.responseJSON.errorCode) || '';
  2819. if (error && error.code === 400) {
  2820. if (errorCode.indexOf('cmUpdateFailed1') !== -1) {
  2821. //check if we have a CM-REQ-4036 error (duplicate error).
  2822. var jqXHRMessages = error.jqXHR.responseJSON.messages || [];
  2823. return _.some(jqXHRMessages, function(message) {
  2824. return message.indexOf('CM-REQ-4036') !== -1;
  2825. });
  2826. } else {
  2827. return ['cmDuplicateName','cmNameConflict', 'cmDuplicateObject'].indexOf(errorCode) !== -1;
  2828. }
  2829. }
  2830. return false;
  2831. };
  2832. /**
  2833. * returns true if the error contains a CM-REQ-4335 uknown error message
  2834. * @param error an error from CM
  2835. * @return boolean if this is an unknown update error.
  2836. */
  2837. ContentManagement.prototype.isUnknownUpdateError = function(error) {
  2838. if (error && error.code === 400 && error.jqXHR && error.jqXHR.responseJSON) {
  2839. //check if we have a CM-REQ-4036 error (duplicate error).
  2840. var jqXHRMessages = error.jqXHR.responseJSON.messages || [];
  2841. return _.some(jqXHRMessages, function(message) {
  2842. return message.indexOf('CM-REQ-4335') !== -1;
  2843. });
  2844. }
  2845. return false;
  2846. };
  2847. ContentManagement.prototype._getActionPromises = function(action, data) {
  2848. var aPromises = [];
  2849. this._options.inputObjects.forEach(function(obj) {
  2850. aPromises.push(new Promise(function(resolve, reject) {
  2851. // map to all relevant informations of the item being copied or moved
  2852. var requestDataMap = {
  2853. 'obj': obj,
  2854. 'data': data,
  2855. 'action': action
  2856. };
  2857. // only update MRU if moving an item (?)
  2858. var newMRUInfo = (this.ancestors && action === 'move') ? {
  2859. id: obj.id,
  2860. ancestors: this.ancestors,
  2861. selfUrl: ContentStoreObject.getSelfLink(obj)
  2862. } : null;
  2863. this._ajaxService.ajax(this._getRequestOptions(requestDataMap))
  2864. .then(function(newMRUInfo) {
  2865. // update the mru entry and resolve
  2866. this._contentServicePromise.then(function(contentSvc){
  2867. contentSvc.updateMRUEntry(newMRUInfo);
  2868. });
  2869. resolve();
  2870. }.bind(this, newMRUInfo))
  2871. .catch(function(newMRUInfo, err) {
  2872. if (this.isNameConflict(err)) {
  2873. if (requestDataMap.action === 'shortcut') {
  2874. // not an error, do a rename, then resolve
  2875. this._renameCopy(requestDataMap, 0, newMRUInfo);
  2876. resolve();
  2877. } else {
  2878. this.createConflictDialogSingle(requestDataMap, newMRUInfo);
  2879. reject(err);
  2880. }
  2881. } else {
  2882. this._handleError(err, requestDataMap, 0);
  2883. reject(err);
  2884. }
  2885. }.bind(this, newMRUInfo));
  2886. }.bind(this)));
  2887. }.bind(this));
  2888. return aPromises;
  2889. };
  2890. ContentManagement.prototype._createURL = function(sBaseURL, oParams) {
  2891. return sBaseURL + '?' + $.param(oParams);
  2892. };
  2893. /**
  2894. * @param requestDataMap : A map to all relevant informations of the item being copied or moved
  2895. *
  2896. * Expects requestDataMap to be {'obj': xxx, 'data':yyy, 'isCopyAction':boolean}
  2897. * Builds the Ajax options for either Copy or Move, depending on isCopyAction
  2898. */
  2899. ContentManagement.prototype._getRequestOptions = function(requestDataMap, bReplaceRequest) {
  2900. if (!requestDataMap) {
  2901. return;
  2902. }
  2903. var requestOptions;
  2904. var oParams;
  2905. if (requestDataMap.action === 'copy') {
  2906. // create id string
  2907. var sourceId = _.map(this._options.inputObjects, function(obj){
  2908. return ContentStoreObject.getObjectId(obj);
  2909. }).join(',');
  2910. oParams = {
  2911. 'recursive': 'true',
  2912. 'source': sourceId
  2913. };
  2914. // multi select
  2915. if (this._options.inputObjects.length > 1) {
  2916. oParams.updateAction = 'fail';
  2917. }
  2918. // replace
  2919. if (bReplaceRequest === true) {
  2920. oParams.updateAction = 'replace';
  2921. } else if (bReplaceRequest === false) {
  2922. oParams.updateAction = 'update';
  2923. }
  2924. // rename data
  2925. var data = requestDataMap.rename ? {
  2926. 'defaultName': requestDataMap.obj.defaultName
  2927. } : {};
  2928. requestOptions = {
  2929. 'contentType': 'application/json',
  2930. 'type': 'POST',
  2931. 'url': this._createURL(requestDataMap.data, oParams),
  2932. 'data': JSON.stringify(data)
  2933. };
  2934. } else if (requestDataMap.action === 'shortcut') {
  2935. requestOptions = {
  2936. 'contentType': 'application/json',
  2937. 'type': 'POST',
  2938. 'url': this._createURL(requestDataMap.data, {}),
  2939. 'data': JSON.stringify({
  2940. 'type': 'shortcut',
  2941. 'target': [{
  2942. 'type': 'baseClass',
  2943. 'searchPath': requestDataMap.obj.searchPath || 'storeID("' + requestDataMap.obj.id + '")'
  2944. }],
  2945. 'defaultName': this._getShortCutName(requestDataMap.obj.defaultName)
  2946. })
  2947. };
  2948. } else {
  2949. // move
  2950. // rename is only needed when there is a name conflict
  2951. if (requestDataMap.rename) {
  2952. requestDataMap.data.defaultName = requestDataMap.obj.defaultName;
  2953. }
  2954. var sURL;
  2955. if (bReplaceRequest == true) {
  2956. sURL = this._createURL(ContentStoreObject.getSelfLink(requestDataMap.obj), {
  2957. 'updateAction': 'replace'
  2958. });
  2959. } else if (bReplaceRequest == false) {
  2960. sURL = this._createURL(ContentStoreObject.getSelfLink(requestDataMap.obj), {
  2961. 'updateAction': 'update'
  2962. });
  2963. } else {
  2964. sURL = ContentStoreObject.getSelfLink(requestDataMap.obj);
  2965. }
  2966. requestOptions = {
  2967. 'dataType': 'json',
  2968. 'contentType': 'application/json',
  2969. 'type': 'PUT',
  2970. 'url': sURL,
  2971. 'data': JSON.stringify(requestDataMap.data)
  2972. };
  2973. }
  2974. return requestOptions;
  2975. };
  2976. ContentManagement.prototype._getShortCutName = function(itemName) {
  2977. return StringResource.get('shortcutToItem', {
  2978. itemName: itemName
  2979. });
  2980. };
  2981. /**
  2982. * Refresh the content view if there is an associated listControl
  2983. */
  2984. ContentManagement.prototype._refreshContent = function() {
  2985. if (this._options.listControl && this._options.listControl.contentView && this._options.listControl.contentView.onCopyMove) {
  2986. return this._options.listControl.contentView.onCopyMove();
  2987. }
  2988. if (this._options.listControl && this._options.listControl.contentView && this._options.listControl.contentView.refresh) {
  2989. return this._options.listControl.contentView.refresh();
  2990. }
  2991. };
  2992. /**
  2993. * Returns a promise resolved with the destination
  2994. */
  2995. ContentManagement.prototype._getDestinationInfo = function() {
  2996. var destinationUrl = this._options.destinationUrl;
  2997. return this._ajaxService.ajax({
  2998. 'dataType': 'json',
  2999. 'contentType': 'application/json',
  3000. 'type': 'GET',
  3001. 'data': {
  3002. 'fields': 'id,defaultName,ancestors'
  3003. },
  3004. 'url': destinationUrl
  3005. })
  3006. .then(function(response) {
  3007. var data = response.data && response.data.data[0];
  3008. this.ancestors = ContentStoreObject.getAncestors(data);
  3009. // if the destination is not a root folder, build an entry for the destination from its ancestors
  3010. if (this.ancestors &&
  3011. destinationUrl !== ContentServiceUrls.getMyFoldersURL() &&
  3012. destinationUrl !== ContentServiceUrls.getPublicFoldersURL()) {
  3013. this.ancestors.push(ContentStoreObject.buildAncestorEntry(data));
  3014. }
  3015. return Promise.resolve(data);
  3016. }.bind(this));
  3017. };
  3018. /*
  3019. Handles a name colission by attempting to rename the object. Otherwise, opens an error dialog.
  3020. */
  3021. ContentManagement.prototype._handleError = function(error, requestDataMap, count) {
  3022. if (error.code === 400) {
  3023. // ew?
  3024. var parent = requestDataMap.obj && requestDataMap.obj.ancestors && requestDataMap.obj.ancestors[requestDataMap.obj.ancestors.length - 1];
  3025. var isCopiedInsideParent = ((requestDataMap.action === 'copy') && parent && requestDataMap.data.indexOf(parent.id) !== -1);
  3026. // if copying to same folder or handling a name conflict with count less than 20, rename auto-magically
  3027. if (((isCopiedInsideParent && !requestDataMap.isCopiedInsideParent) || this.isNameConflict(error)) && (count < 20)) {
  3028. requestDataMap.isCopiedInsideParent = isCopiedInsideParent; // only check once
  3029. count += 1;
  3030. return this._renameCopy(requestDataMap, count);
  3031. }
  3032. }
  3033. GlassContextHelper.showAjaxServiceError(this._glassContext, error);
  3034. };
  3035. /*
  3036. Moves an array of objects to a destination folder or package
  3037. @param options.glassContext - {object} glass context from view calling this function
  3038. @param options.inputObjects - {array} objects that are being moved (oData format)
  3039. @param options.destinationUrl - {string} REST URL for the destination folder
  3040. @param options.listControl - {object} list control that will have rows removed from it after move
  3041. */
  3042. ContentManagement.prototype.moveObjects = function(options) {
  3043. this._init(options);
  3044. return this._getDestinationInfo()
  3045. .then(function(destinationInfo) {
  3046. var requestData = {
  3047. 'parent': [{
  3048. 'id': ContentStoreObject.getObjectId(destinationInfo)
  3049. }]
  3050. };
  3051. return this._allSettled(this._getActionPromises('move', requestData))
  3052. .then(this._onAllSettled.bind(this, 'move'));
  3053. }.bind(this));
  3054. };
  3055. /**
  3056. * Copies an array of objects to a destination folder or package
  3057. * @param options.glassContext - {object} glass context from view calling this function
  3058. * @param options.inputObjects - {array} objects that are being copied (oData format)
  3059. * @param options.destinationItemsUrl - {string} REST URL for the destination folder
  3060. */
  3061. ContentManagement.prototype.shortcutObjects = function(options) {
  3062. this._init(options);
  3063. return this._allSettled(this._getActionPromises('shortcut', options.destinationItemsUrl))
  3064. .then(this._onAllSettled.bind(this, 'shortcut'));
  3065. };
  3066. /**
  3067. * Copies multple objects using one bulk copy api so that report linked items are also copied
  3068. *
  3069. * @param bReplaceRequest - {boolean} true to set the request to replace conflicting objects
  3070. */
  3071. ContentManagement.prototype.copyMultipleObjects = function(bReplaceRequest) {
  3072. var requestDataMap = {
  3073. 'action': 'copy',
  3074. 'data': this._options.destinationItemsUrl
  3075. };
  3076. return this._ajaxService.ajax(this._getRequestOptions(requestDataMap, bReplaceRequest))
  3077. .then(function() {
  3078. GlassContextHelper.displayToast(this._glassContext, StringResource.get('toastDoneCopying', {
  3079. 'noOfItems': this._options.inputObjects.length
  3080. }));
  3081. this._refreshContent();
  3082. }.bind(this))
  3083. .catch(function(err) {
  3084. if (err && err.jqXHR && this.isNameConflict(err)) {
  3085. // bulk copy name conflicts don't give the user the option of renaming, just overwrite and cancel
  3086. var dialog = this.createConflictDialogMulti(requestDataMap);
  3087. dialog.open();
  3088. } else {
  3089. //TODO: improve error message?
  3090. GlassContextHelper.showAjaxServiceError(this._glassContext, err);
  3091. }
  3092. }.bind(this));
  3093. };
  3094. /*
  3095. copies an array of objects to a destination folder or package
  3096. @param options.glassContext - {object} glass context from view calling this function
  3097. @param options.inputObjects - {array} objects that are being copied (oData format)
  3098. @param options.destinationItemsUrl - {string} REST URL for the destination folder
  3099. */
  3100. ContentManagement.prototype.copyObjects = function(options) {
  3101. this._init(options);
  3102. return this._options.inputObjects.length > 1 ?
  3103. this.copyMultipleObjects() : // special bulk action for copying multiple objects
  3104. this._allSettled(this._getActionPromises('copy', options.destinationItemsUrl))
  3105. .then(this._onAllSettled.bind(this, 'copy'));
  3106. };
  3107. /*
  3108. Called when the initial copy/move/shortcut action fails due to a name collision, when copying a single asset.
  3109. Creates the dialog that will allow the user to handle the error.
  3110. @param this._destinationChildrenPromise : A keeper variable used by the 'replace' function. Avoids repetitive ajax calls
  3111. to access the same destination info
  3112. */
  3113. ContentManagement.prototype.createConflictDialogSingle = function(requestDataMap, newMRUInfo) {
  3114. this._destinationChildrenPromise = null; //?
  3115. var oDialog = new NameCollisionDialog('nameCollision', StringResource.get('nameCollision', {
  3116. 'nameOfItem': requestDataMap.obj.defaultName
  3117. }), StringResource.get('nameCollisionMessage'));
  3118. // option 1, replace existing item
  3119. var replace = function() {
  3120. return this._replaceExisting(requestDataMap, newMRUInfo);
  3121. }.bind(this);
  3122. // option 2, copy - renaming the new item
  3123. var keepBoth = function() {
  3124. return this._renameCopy(requestDataMap, 0, newMRUInfo);
  3125. }.bind(this);
  3126. // option 3, cancel
  3127. var cancel = function() {
  3128. return Promise.resolve();
  3129. };
  3130. oDialog.create(replace, keepBoth, cancel, requestDataMap.action, requestDataMap.obj.defaultName);
  3131. return oDialog;
  3132. };
  3133. /*
  3134. Called when the initial copy/move/shortcut action fails due to a name collision, when copying multiple assets.
  3135. Creates the dialog that will allow the user to handle the error.
  3136. @param requestDataMap - {object} information on the copy request
  3137. */
  3138. ContentManagement.prototype.createConflictDialogMulti = function(requestDataMap) {
  3139. this._destinationChildrenPromise = null;
  3140. var oDialog = new NameCollisionDialog('nameCollisionGeneric', StringResource.get('nameCollisionGeneric'), StringResource.get('nameCollisionMessage'));
  3141. var replace = function() {
  3142. // check if an update or replace action is required when overwriting
  3143. return this._glassContext.services.config.getConfigValue('ContentApps/updateTargetObjectWhenOverwrite').then(function(isUpdate) {
  3144. var bReplaceRequest = true;
  3145. if ((isUpdate === 'true')) {
  3146. bReplaceRequest = false;
  3147. }
  3148. return this.copyMultipleObjects(bReplaceRequest);
  3149. }.bind(this));
  3150. }.bind(this);
  3151. var keepBoth = null;
  3152. var skip = function() {
  3153. /*Closes the dialog without doing anything*/
  3154. return Promise.resolve();
  3155. };
  3156. oDialog.create(replace, keepBoth, skip, requestDataMap.action, '');
  3157. return oDialog;
  3158. };
  3159. /*
  3160. Called by the keepBoth() function of the NameCollisionDialog
  3161. @param requestDataMap : A map to all relevant informations of the item being copied or moved
  3162. @param count : The number to append to the name of the renamed item.
  3163. Bounces back and forth with the _handleError() function until a name can be appended with a proper count value
  3164. */
  3165. ContentManagement.prototype._renameCopy = function(requestDataMap, count, newMRUInfo) {
  3166. if (!count) {
  3167. var extractedNameAndCount = this._extractNameAndCount(requestDataMap);
  3168. requestDataMap.obj.defaultName = extractedNameAndCount.name;
  3169. count = extractedNameAndCount.count + 1;
  3170. }
  3171. var originalName = requestDataMap.obj.defaultName;
  3172. if (count > 0) {
  3173. requestDataMap.obj.defaultName += ' (' + count + ')';
  3174. requestDataMap.rename = true;
  3175. if (newMRUInfo) {
  3176. newMRUInfo.defaultName = requestDataMap.obj.defaultName;
  3177. }
  3178. }
  3179. var requestOptions = this._getRequestOptions(requestDataMap);
  3180. var newName = requestDataMap.obj.defaultName;
  3181. requestDataMap.obj.defaultName = originalName;
  3182. return this._ajaxService.ajax(requestOptions)
  3183. .then(function() {
  3184. this._contentServicePromise.then(function(contentSvc){
  3185. contentSvc.updateMRUEntry(newMRUInfo);
  3186. });
  3187. if (requestDataMap.action === 'copy') {
  3188. GlassContextHelper.displayToast(this._glassContext, StringResource.get('toastDoneCopyingSingular', {
  3189. 'nameOfItem': BidiUtil.enforceTextDirection(requestDataMap.obj.defaultName)
  3190. }));
  3191. // renaming a short cut happens automagically when there's a name conflict so do not display rename message
  3192. } else if (requestDataMap.action !== 'shortcut') {
  3193. GlassContextHelper.displayToast(this._glassContext, StringResource.get('RenameFileSuccessfully', {
  3194. 'originalNameOfObject': BidiUtil.enforceTextDirection(requestDataMap.obj.defaultName),
  3195. 'newNameOfObject': BidiUtil.enforceTextDirection(newName)
  3196. }));
  3197. }
  3198. this._refreshContent();
  3199. }.bind(this))
  3200. .catch(function(err){
  3201. this._handleError(err, requestDataMap, count);
  3202. }.bind(this));
  3203. };
  3204. /*
  3205. If given a name such as "New Folder (14)", this function will extract the name from the count and
  3206. return the two under the form {'name': "New Folder", 'count': 14}
  3207. @regex '\\s\\([1-9]\d*\\)' : This will find a non-zero number of any length that is surronded on the left by a space
  3208. and open bracket ' (' and on the right a closing bracket ')'.
  3209. */
  3210. ContentManagement.prototype._extractNameAndCount = function(requestDataMap) {
  3211. var originalName = requestDataMap.obj.defaultName;
  3212. var extractedStr = originalName.match('\\s\\([1-9]\\d*\\)');
  3213. var returnValue = {
  3214. 'name': originalName,
  3215. 'count': 0
  3216. };
  3217. if (extractedStr !== null) {
  3218. extractedStr = extractedStr[extractedStr.length - 1];
  3219. var theCount = parseInt(extractedStr.substring(2, extractedStr.length - 1), 10);
  3220. if (typeof theCount === 'number') {
  3221. returnValue.name = originalName.replace(extractedStr, '');
  3222. returnValue.count = theCount;
  3223. }
  3224. }
  3225. return returnValue;
  3226. };
  3227. /*
  3228. Called by the replace() function of the NameCollisionDialog
  3229. First deletes an existing element with the current item's name, then adds the current item to the destination
  3230. */
  3231. ContentManagement.prototype._replaceExisting = function(requestDataMap, newMRUInfo) {
  3232. // delete existing item with the same name in the MRU
  3233. return this._getDestinationChildrenInfo(requestDataMap.action)
  3234. .then(function(destinationChildren) {
  3235. destinationChildren.data.forEach(function(child) {
  3236. if (child.defaultName === requestDataMap.obj.defaultName) {
  3237. return this._glassContext.getCoreSvc('.Config').getConfigValue('ContentApps/updateTargetObjectWhenOverwrite').then(function(isUpdate){
  3238. this._contentServicePromise.then(function(contentSvc){
  3239. contentSvc.removeFromMRU(child);
  3240. });
  3241. // replace by default
  3242. var bReplaceRequest = true;
  3243. if ((isUpdate === 'true') && (child.type === requestDataMap.obj.type)) {
  3244. bReplaceRequest = false;
  3245. }
  3246. // replace the source item in the destination folder
  3247. return this._ajaxService.ajax(this._getRequestOptions(requestDataMap, bReplaceRequest))
  3248. .then(function() {
  3249. // add new item to the MRU
  3250. this._contentServicePromise.then(function(contentSvc){
  3251. contentSvc.updateMRUEntry(newMRUInfo);
  3252. });
  3253. // display toast
  3254. GlassContextHelper.displayToast(this._glassContext, StringResource.get('OverwriteFileSuccessfully', {
  3255. 'nameOfObject': BidiUtil.enforceTextDirection(requestDataMap.obj.defaultName)
  3256. }));
  3257. this._refreshContent();
  3258. }.bind(this))
  3259. .catch(function(err) {
  3260. this._handleError(err, requestDataMap, 0);
  3261. }.bind(this));
  3262. }.bind(this));
  3263. }
  3264. }.bind(this));
  3265. }.bind(this));
  3266. };
  3267. /*
  3268. Finds and returns a promise containing the array of items at the destination.
  3269. Saves the result in this._destinationChildrenPromise to avoid duplicate ajax calls in the case
  3270. where multiple collisions at once create multiple dialogs.
  3271. */
  3272. ContentManagement.prototype._getDestinationChildrenInfo = function(action) {
  3273. if (!this._destinationChildrenPromise) {
  3274. var url;
  3275. if (action === 'copy' || action === 'shortcut') {
  3276. url = this._options.destinationItemsUrl + '?fields=ancestors,defaultName';
  3277. } else {
  3278. url = this._options.destinationUrl + '/items';
  3279. }
  3280. this._destinationChildrenPromise = this._ajaxService.ajax({
  3281. 'dataType': 'json',
  3282. 'contentType': 'application/json',
  3283. 'type': 'GET',
  3284. 'url': url,
  3285. 'cache': false
  3286. })
  3287. .then(function(response){
  3288. return response && response.data;
  3289. });
  3290. }
  3291. return this._destinationChildrenPromise;
  3292. };
  3293. var _static = {
  3294. getInstance: function() {
  3295. if (!_singletonInstance) {
  3296. _singletonInstance = new ContentManagement();
  3297. }
  3298. return _singletonInstance;
  3299. }
  3300. };
  3301. return _static.getInstance();
  3302. });
  3303. /*
  3304. *+------------------------------------------------------------------------+
  3305. *| Licensed Materials - Property of IBM
  3306. *| IBM Cognos Products: Content Explorer
  3307. *| (C) Copyright IBM Corp. 2018
  3308. *|
  3309. *| US Government Users Restricted Rights - Use, duplication or disclosure
  3310. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  3311. *+------------------------------------------------------------------------+
  3312. */
  3313. define('bacontentnav/utils/ActionHelper',[
  3314. 'jquery',
  3315. './ContentManagement'
  3316. ], function($, ContentManagement) {
  3317. 'use strict';
  3318. return {
  3319. /**
  3320. * Handles an error received when creating a Content Nav asset (due to name conflict, etc.)
  3321. * @param {object} listControl host list control
  3322. * @param {object} assetInfo asset information for creation
  3323. * @param {object} err error recieved from creation failure
  3324. * @param {object} messages i18n error messages to display, if appl.
  3325. * @return {promise} resolved with asset info if successful, otherwise reject with error
  3326. */
  3327. handleAddItemError: function(listControl, assetInfo, err, messages) {
  3328. // check for client side error
  3329. if (err.code === 400) {
  3330. // if name duplication, try to increment (up to 20)
  3331. if (ContentManagement.isNameConflict(err)) {
  3332. var newNameString = this._getNewNameString(listControl, assetInfo);
  3333. if (this.count < 20) {
  3334. assetInfo.defaultName = newNameString;
  3335. return Promise.resolve(assetInfo);
  3336. } else {
  3337. err = this._applyErrorMessage(err, messages['itemsOverLimit']);
  3338. return Promise.reject(err);
  3339. }
  3340. } else {
  3341. return Promise.reject(err);
  3342. }
  3343. } else {
  3344. // If the URL name is > then 255 characters
  3345. if (err.code === 500 && assetInfo.defaultName.length > 255) {
  3346. err = this._applyErrorMessage(err, messages['nameLengthError']);
  3347. }
  3348. return Promise.reject(err);
  3349. }
  3350. },
  3351. /**
  3352. * Generates a non-conflicting file name (e.g. if there's a: 'New Report (3)', it will generate 'New Report (4)')
  3353. * @param {object} listControl host list control
  3354. * @param {object} assetInfo asset information for creation
  3355. * @return {string} new name
  3356. */
  3357. _getNewNameString: function(listControl, assetInfo) {
  3358. var nameList = [];
  3359. var aData = listControl._dTable.fnGetData();
  3360. aData.forEach(function(rowData) { // Get a small list of names that has the substring assetInfo.defaultName
  3361. var name = rowData.defaultName.toLowerCase();
  3362. if (name.indexOf(assetInfo.defaultName.toLowerCase()) === 0) {
  3363. nameList.push(name);
  3364. }
  3365. });
  3366. var newNameString;
  3367. for (var i = 1; i <= nameList.length; i++) {
  3368. newNameString = assetInfo.defaultName + ' (' + i + ')';
  3369. if ($.inArray(newNameString.toLowerCase(), nameList) === -1) {
  3370. break;
  3371. }
  3372. }
  3373. this.count = i;
  3374. return newNameString;
  3375. },
  3376. /**
  3377. * Set's-up the error's responseJSON with the message to show to the user
  3378. * @param {object} err error recieved from creation failure
  3379. * @param {object} messages i18n error messages to display, if appl.
  3380. * @return {object} modified error object
  3381. */
  3382. _applyErrorMessage: function(err, message) {
  3383. // Remove unnecessary message generated from the error
  3384. var responseJSON = err.jqXHR && err.jqXHR.responseJSON || {};
  3385. responseJSON.messages.splice(1, 1);
  3386. responseJSON.messages[0] = message;
  3387. return err;
  3388. }
  3389. };
  3390. });
  3391. /*
  3392. *+------------------------------------------------------------------------+
  3393. *| Licensed Materials - Property of IBM
  3394. *| IBM Cognos Products: ba-content-nav
  3395. *| (C) Copyright IBM Corp. 2015, 2018
  3396. *|
  3397. *| US Government Users Restricted Rights - Use, duplication or disclosure
  3398. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  3399. *+------------------------------------------------------------------------+
  3400. */
  3401. define('bacontentnav/common/ui/list_actions/AddFolderAction',[
  3402. 'jquery',
  3403. './AddInlineAction',
  3404. '../../../utils/ActionHelper',
  3405. '../../../nls/StringResource',
  3406. '../../../utils/ContentManagement',
  3407. '../../../utils/GlassContextHelper',
  3408. '../../../lib/@waca/core-client/js/core-client/utils/BidiUtil'
  3409. ], function($, AddInlineAction, ActionHelper, StringResource, ContentManagement, GlassContextHelper, BidiUtil) {
  3410. 'use strict';
  3411. var AddFolderAction = AddInlineAction.extend({
  3412. getDefaultName: function() {
  3413. return StringResource.get('newFolderDefaultName');
  3414. },
  3415. getType: function() {
  3416. return 'folder';
  3417. },
  3418. getClass: function() {
  3419. return 'newFolderRow';
  3420. },
  3421. _addFolder: function(data, listControl) {
  3422. var displayName = data.defaultName;
  3423. var requestOptions = {
  3424. 'headers': {
  3425. 'Accept': 'application/json',
  3426. 'Content-Type': 'application/json'
  3427. },
  3428. 'type': 'POST',
  3429. 'url': listControl.url,
  3430. 'data': JSON.stringify(data)
  3431. };
  3432. listControl.addFolderNameForFocus = displayName;
  3433. return listControl.glassContext.getCoreSvc('.Ajax').ajax(requestOptions)
  3434. .then(function() {
  3435. GlassContextHelper.displayToast(listControl.glassContext, StringResource.get('toastCreateNewFolder', {
  3436. 'nameOfFolder': BidiUtil.enforceTextDirection(displayName)
  3437. }));
  3438. })
  3439. .catch(function(err) {
  3440. var messages = {
  3441. 'itemsOverLimit': StringResource.get('itemsOverLimit', {
  3442. itemName: data.defaultName
  3443. }),
  3444. 'nameLengthError': StringResource.get('errorMessageLengthFolderName')
  3445. };
  3446. return ActionHelper.handleAddItemError(listControl, data, err, messages)
  3447. .then(function() {
  3448. // resolved a name conflict so try again
  3449. return this._addFolder(data, listControl);
  3450. }.bind(this))
  3451. .catch(function (err) {
  3452. listControl.updateDatatable();
  3453. GlassContextHelper.showAjaxServiceError(listControl.glassContext, err);
  3454. return Promise.reject(err);
  3455. });
  3456. }.bind(this));
  3457. },
  3458. sendAddRequest: function(data, listControl) {
  3459. // check if the defaultName contains both ' and " which is not allowed by CM
  3460. if ((data.defaultName.indexOf('\'') > -1) && (data.defaultName.indexOf('"') > -1)){
  3461. listControl.cancelActions();
  3462. return GlassContextHelper.displayToast(listControl.glassContext, StringResource.get('errorMessageApostropheError'), {
  3463. 'type': 'error'
  3464. });
  3465. }
  3466. return this._addFolder(data, listControl)
  3467. .then(function() {
  3468. listControl.updateDatatable();
  3469. });
  3470. }
  3471. });
  3472. return AddFolderAction;
  3473. });
  3474. /**
  3475. * Licensed Materials - Property of IBM
  3476. * IBM Cognos Products: ba-content-nav
  3477. * (C) Copyright IBM Corp. 2018
  3478. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  3479. */
  3480. define('bacontentnav/utils/MRUHelper',[
  3481. '../lib/@waca/core-client/js/core-client/ui/dialogs/ConfirmationDialog',
  3482. '../nls/StringResource',
  3483. './ContentServiceUrls'
  3484. ], function(ConfirmationDialog, StringResource, ContentServiceUrls) {
  3485. var MRUHelper = {
  3486. /**
  3487. * Returns true if the given view requires asset verification for MRU purposes
  3488. * @param {object} view
  3489. */
  3490. requiresAssetVerification: function(view) {
  3491. return view && view.requiresAssetVerification === true;
  3492. },
  3493. /**
  3494. * Shows the no access dialog offering to remove the given asset from the user's recent list
  3495. * @param {object} glassContext
  3496. * @param {string} oDataId - the id of the asset
  3497. */
  3498. showNoAccessDialog: function(glassContext, oDataId) {
  3499. if (glassContext && oDataId) {
  3500. var oDialog = new ConfirmationDialog('noAccessRecent', StringResource.get('noAccessRecent'), StringResource.get('noAccessRecentMsg'));
  3501. oDialog.confirm(function() {
  3502. glassContext.getSvc('.Content')
  3503. .then(function(contentSvc) {
  3504. contentSvc.removeFromMRU({ id: oDataId });
  3505. })
  3506. .catch(function(err) {
  3507. // log the error, don't cascade as there's nothing a user can do
  3508. glassContext.getCoreSvc('.Logger').error(err);
  3509. });
  3510. });
  3511. return oDialog;
  3512. }
  3513. },
  3514. /**
  3515. * Returns a promise with true or false depending on whether the user can access the given object id, showing the no access dialog if not.
  3516. * Verifies whether the user can access this item (it does not check if the user has permissions to execute any action)
  3517. * @param {object} glassContext
  3518. * @param {string} oDataId - the id of the object to be verified
  3519. */
  3520. verifyAccess: function(glassContext, oDataId) {
  3521. if (glassContext && oDataId) {
  3522. var options = {
  3523. url: ContentServiceUrls.getBaseObjectsURL() + '/' + oDataId,
  3524. dataType: 'json',
  3525. data: { 'fields': 'permissions' }
  3526. };
  3527. return glassContext.getCoreSvc('.Ajax').ajax(options)
  3528. .then(function(response) {
  3529. var freshData = response.data.data[0];
  3530. if (!freshData || freshData.permissions.length === 0) {
  3531. this.showNoAccessDialog(glassContext, oDataId);
  3532. return false;
  3533. } else {
  3534. return true;
  3535. }
  3536. }.bind(this))
  3537. .catch(function(err) {
  3538. // show no access if an error has occurred
  3539. glassContext.getCoreSvc('.Logger').error(err);
  3540. this.showNoAccessDialog(glassContext, oDataId);
  3541. return false;
  3542. }.bind(this));
  3543. } else {
  3544. // in the unlikely event this happens, let's just tell the caller we couldn't verify access
  3545. return Promise.resolve(false);
  3546. }
  3547. }
  3548. };
  3549. return MRUHelper;
  3550. });
  3551. /*
  3552. *+------------------------------------------------------------------------+
  3553. *| Licensed Materials - Property of IBM
  3554. *| IBM Cognos Products: Content Explorer
  3555. *| (C) Copyright IBM Corp. 2015, 2018
  3556. *|
  3557. *| US Government Users Restricted Rights - Use, duplication or disclosure
  3558. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  3559. *+------------------------------------------------------------------------+
  3560. */
  3561. define('bacontentnav/common/ui/list_actions/DefaultAction',[
  3562. '../../../lib/@waca/core-client/js/core-client/ui/core/Class',
  3563. '../../../utils/ContentServiceUrls',
  3564. '../../../utils/ContentStoreObject',
  3565. '../../../utils/GlassContextHelper',
  3566. '../../../utils/MRUHelper',
  3567. '../../../utils/UIHelper',
  3568. '../../../nls/StringResource',
  3569. 'underscore'
  3570. ], function(Class, ContentServiceUrls, ContentStoreObject, GlassContextHelper, MRUHelper, UIHelper, StringResource, _) {
  3571. 'use strict'; //NOSONAR
  3572. var DefaultAction = Class.extend({
  3573. /**
  3574. options.glassContext
  3575. options.oData {object} - (optional) This is the content service response for the object
  3576. options.storeId {string} - (optional) If no oData is provided, we will use the storeId to query for the object information
  3577. options.listControl
  3578. **/
  3579. init: function(options) {
  3580. DefaultAction.inherited('init', this, arguments);
  3581. _.extend(this, options);
  3582. },
  3583. canExecute: function() {
  3584. // if it's an MRU view - let's check later in case the state has changed
  3585. var view = this.listControl && this.listControl.contentView || this.contentView;
  3586. if (MRUHelper.requiresAssetVerification(view)) {
  3587. return Promise.resolve(true);
  3588. }
  3589. return this._canExecute();
  3590. },
  3591. execute: function() {
  3592. var view = this.listControl && this.listControl.contentView || this.contentView;
  3593. return this._getData(view).then(function(oData) {
  3594. this.oData = oData;
  3595. if (MRUHelper.requiresAssetVerification(view)) {
  3596. this._canExecute()
  3597. .then(function(canExecute) {
  3598. if (canExecute) {
  3599. return this._executeAction();
  3600. } else {
  3601. // Show the no access dialog
  3602. MRUHelper.showNoAccessDialog(this.glassContext, this.oData && this.oData.id || this.storeId);
  3603. // If we were able to find the asset, let's make sure it's up to date in the mru
  3604. if (this.oData) {
  3605. return this.glassContext.getSvc('.Content').then(function(contentSvc){
  3606. contentSvc.addToMRU(this.oData);
  3607. }.bind(this));
  3608. } else {
  3609. return Promise.resolve();
  3610. }
  3611. }
  3612. }.bind(this));
  3613. } else if (!this.oData) {
  3614. return Promise.reject(new Error('No data for default action'));
  3615. } else {
  3616. return this._executeAction();
  3617. }
  3618. }.bind(this));
  3619. },
  3620. _updateMRU: function() {
  3621. return this.glassContext.getSvc('.Content').then(function(contentSvc){
  3622. ContentStoreObject.setGlassContext(this.glassContext);
  3623. contentSvc.addToMRU(this.oData);
  3624. }.bind(this));
  3625. },
  3626. _canExecute: function() {
  3627. if (!this.oData) {
  3628. return Promise.resolve(false);
  3629. }
  3630. return Promise.resolve(this.glassContext.appController.canExecuteAction(this._getActionId(), this._buildPayload()));
  3631. },
  3632. _executeAction: function() {
  3633. return ContentStoreObject.getPermissions(this.oData, true)
  3634. .then(function(permissions) {
  3635. this.oData[ContentStoreObject.PERMISSIONS] = permissions;
  3636. var payload = this._buildPayload();
  3637. var actionId = this._getActionId();
  3638. return this.glassContext.appController.performAction(actionId, payload)
  3639. .then(function() {
  3640. // If an AppView exists, wait for the AppView to render before updating the MRU, else just update MRU
  3641. if(this.glassContext.appController.currentAppView) {
  3642. this.glassContext.appController.currentAppView.onViewRendered().then(function() {
  3643. // We've successfully done a defaultAction, add the object to the MRU list
  3644. this._updateMRU();
  3645. }.bind(this));
  3646. } else {
  3647. this._updateMRU();
  3648. }
  3649. }.bind(this))
  3650. .catch(function(err) {
  3651. this.glassContext.getCoreSvc('.Logger').error(err);
  3652. this._showToastOnLaunchError(this.oData);
  3653. return Promise.reject(err);
  3654. }.bind(this));
  3655. }.bind(this));
  3656. },
  3657. _getActionId: function() {
  3658. var objType = ContentStoreObject.getType(this.oData);
  3659. if (objType === null) {
  3660. return null;
  3661. }
  3662. return 'com.ibm.bi.contentApps.defaultAction.' + objType;
  3663. },
  3664. _getData: function(view) {
  3665. this.storeId = this.storeId || this.oData && this.oData.id;
  3666. if (this.oData && !MRUHelper.requiresAssetVerification(view)) {
  3667. return Promise.resolve(this.oData);
  3668. } else if (this.storeId) {
  3669. var options = {
  3670. url: ContentServiceUrls.getBaseObjectsURL() + '/' + this.storeId,
  3671. dataType: 'json',
  3672. data: view && view.getURLParameters && view.getURLParameters()
  3673. };
  3674. return this.glassContext.getCoreSvc('.Ajax').ajax(options)
  3675. .then(function(response) {
  3676. return Promise.resolve(response.data && response.data.data[0]);
  3677. })
  3678. .catch(function(err) {
  3679. if (MRUHelper.requiresAssetVerification(view)) {
  3680. return Promise.resolve();
  3681. } else {
  3682. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  3683. return Promise.reject(err);
  3684. }
  3685. }.bind(this));
  3686. } else {
  3687. return Promise.reject(new Error('No data or storeId to do the action with.'));
  3688. }
  3689. },
  3690. _buildPayload: function() {
  3691. return {
  3692. 'glassContext': this.glassContext,
  3693. 'target': {
  3694. 'activeObject': {
  3695. 'oListControl': this.listControl,
  3696. 'aSelectedContext': [this.oData]
  3697. },
  3698. 'itemId': this._getActionId()
  3699. }
  3700. };
  3701. },
  3702. _showToastOnLaunchError: function(data) {
  3703. GlassContextHelper.displayToast(this.glassContext, StringResource.get('toastLaunchPerspectiveError', {
  3704. objectType: UIHelper.getTypeNameFromObject(data)
  3705. }), {
  3706. type: 'error'
  3707. });
  3708. }
  3709. });
  3710. return DefaultAction;
  3711. });
  3712. /*
  3713. *+------------------------------------------------------------------------+
  3714. *| Licensed Materials - Property of IBM
  3715. *| IBM Cognos Products: Content Explorer
  3716. *| (C) Copyright IBM Corp. 2017
  3717. *|
  3718. *| US Government Users Restricted Rights - Use, duplication or disclosure
  3719. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  3720. *+------------------------------------------------------------------------+
  3721. */
  3722. define('bacontentnav/common/ui/list_actions/DefaultActionHandler',[
  3723. 'underscore',
  3724. '../list_actions/DefaultAction',
  3725. '../../../utils/ContentStoreObject',
  3726. '../../../utils/UIHelper'
  3727. ], function(_, DefaultAction, ContentStoreObject, UIHelper) {
  3728. 'use strict';
  3729. return {
  3730. /**
  3731. * Executes the given action on an item in the given list control
  3732. * @param {object} options
  3733. * @param {object} options.evt - the triggering event
  3734. * @param {object} options.oData - the asset data
  3735. * @param {object} options.listControl - the list control that contents the row
  3736. * @param {object} options.glassContext - the glass context
  3737. * @param {object} options.action - the action to execute
  3738. *
  3739. * @return Promise
  3740. */
  3741. executeAction: function(options) {
  3742. // parse the options
  3743. var oData = options.oData;
  3744. var listControl = options.listControl;
  3745. var glassContext = options.glassContext;
  3746. // only perform an action if no item is in creation mode (i.e. NewFolder) and we're not doing multiselect
  3747. if (listControl.isMultitouchActive() || listControl.isInStandbyMode()) {
  3748. return Promise.resolve(true); // shortcut the rest
  3749. }
  3750. // set so _selectRow can hide properties page
  3751. listControl.contentView.propertiesOverride = true;
  3752. // hide slideout on launch if not navigating
  3753. if (!UIHelper.isContainer(ContentStoreObject.getType(oData))) {
  3754. glassContext.appController.hideSlideOut();
  3755. }
  3756. // do the action TODO: does this always return a promise?
  3757. options.action.execute();
  3758. return Promise.resolve(true);
  3759. },
  3760. /**
  3761. * Executes the default action on an item in the list control after checking permissions
  3762. * @param {object} options
  3763. * @param {object} options.$div - the content nav row being selected
  3764. * @param {object} options.oData - the asset data
  3765. * @param {object} options.listControl - the list control that contents the row
  3766. * @param {object} options.glassContext - the glass context
  3767. *
  3768. * @return Promise
  3769. */
  3770. executeDefaultAction: function(options) {
  3771. return new Promise(function(resolve/*, reject*/) {
  3772. // parse the options
  3773. var oData = options.oData;
  3774. var listControl = options.listControl;
  3775. var glassContext = options.glassContext;
  3776. // create the action and set on options to pass along
  3777. var defaultAction = new DefaultAction({
  3778. 'glassContext': glassContext,
  3779. 'oData': oData,
  3780. 'listControl': listControl
  3781. });
  3782. options.action = defaultAction;
  3783. // search results don't return any permissions, so always show the item as a link TODO: can we improve this?
  3784. var permissionPromise = oData[ContentStoreObject.PERMISSIONS] ? defaultAction.canExecute() : Promise.resolve(true);
  3785. // check permissions
  3786. permissionPromise
  3787. .then(function(options, bCanExecute) {
  3788. if (bCanExecute) {
  3789. this.executeAction(options);
  3790. }
  3791. resolve();
  3792. }.bind(this, options))
  3793. .catch(function() {
  3794. //TODO: should we log something if the action was not executed?
  3795. resolve();
  3796. });
  3797. }.bind(this));
  3798. }
  3799. };
  3800. });
  3801. define('text!bacontentnav/common/templates/ListControlTemplate.html',[],function () { return '<div id="listContainer{{=it.id}}" class="ca-listContainer">\n\t<table summary="{{=it.accessibleLabel}}" aria-label="{{=it.accessibleLabel}}" id="{{=it.id}}" class="listControl">\n\t\t<thead>\n\t\t\t<tr role="row" tabindex="-1">\n\t\t\t\t{{~it.columns :column}}\n\t\t\t\t\t<th role="columnheader" class="cth_{{=(column.name + \'_\' + it.id)}}" scope="col">\n\t\t\t\t\t\t<div class="columnText{{?column.headerClass}} {{=column.headerClass}}{{?}}">\n\t\t\t\t\t\t\t<div class="{{? it.sort }} sortable {{=(\'cdiv_\' + column.name + \'_\' + it.id)}}{{?}} {{? column.hiddenLabel }} hidden{{?}}">{{? column.label }}{{=column.label}}{{?? column.hiddenLabel }}{{=column.hiddenLabel}}{{??}}&nbsp;{{?}}\n\t\t\t\t\t\t\t<div class="sort_underline"></div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class="columnSpacer"></div>\n\t\t\t\t\t</th>\n\t\t\t\t{{~}}\n\t\t\t</tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t</tbody>\n\t</table>\n</div>\n';});
  3802. define('text!bacontentnav/common/templates/EmptyListTemplate.html',[],function () { return '<div class="emptyTableContent{{?it.shortTable == true}} shortTable{{?}}">\n\t{{?it.emptyIcon}}\n\t<div class="emptyTableImage {{?it.iconStyle}} {{=it.iconStyle}}{{?}}">\n\t\t<svg class="svgIcon {{?it.isSpinner}}loadingSpinner--animation{{?}}" role="img" focusable="false"><use style="pointer-events:none;" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href={{=it.emptyIcon}}></use></svg>\n\t</div>\n\t{{?}}\n\t<div class="emptyTableTextBlock">\n\t\t<div class="emptyTableText" aria-label="{{=it.text}}" tabindex="0">{{=it.text}}</div>\n\t\t{{?it.textParagraph}}\n\t\t\t<div class="emptyTableTextParagraph" aria-label="{{=it.textParagraph}}" tabindex="0">{{=it.textParagraph}}</div>\n\t\t{{?}}\n\t</div>\n</div>\n';});
  3803. !function(a,s){if("object"==typeof exports&&"object"==typeof module)module.exports=s(require("@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"));else if("function"==typeof define&&define.amd)define('bacontentnav/lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/empty-folder_128',["@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"],s);else{var c=s("object"==typeof exports?require("@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"):a["@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"]);for(var i in c)("object"==typeof exports?exports:a)[i]=c[i]}}("undefined"!=typeof self?self:this,function(a){return webpackJsonPBaGraphics([105],{"099720445ff350ff6c39":function(a,s,c){"use strict";var i=c("9689a9c94ae38b47fa2c"),r=c.n(i),e=c("9ce58a7deea14f49ef01"),t=c.n(e),h=new r.a({id:"empty-folder_128_v7",use:"empty-folder_128_v7-usage",viewBox:"0 0 200 200",content:'<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" id="empty-folder_128_v7"><circle class="ba-graphics-neutral-white4" cx="100" cy="100" r="100" /><path class="ba-graphics-white" d="M2.07 170.06h4.76" /><path class="ba-graphics-gray60" d="M6.83 172.06H2.07a2 2 0 110-4h4.76a2 2 0 110 4z" /><path class="ba-graphics-white" d="M14.92 170.06h183.06" /><path class="ba-graphics-gray60" d="M198 172.06H14.92a2 2 0 110-4H198a2 2 0 010 4z" /><circle class="ba-graphics-gray60" cx="104.14" cy="22.46" r="2" /><circle class="ba-graphics-gray60" cx="133.32" cy="37.1" r="2" /><path class="ba-graphics-gray60" d="M62.85 36.1a4 4 0 004-4 1 1 0 112 0 4 4 0 004 4 1 1 0 010 2 4 4 0 00-4 4 1 1 0 01-2 0 4 4 0 00-4-4 1 1 0 010-2z" /><rect class="ba-graphics-gray40" x="28.16" y="68.05" width="144" height="104" rx="2" /><path class="ba-graphics-gray60" d="M168.16 72.05v96h-136v-96h136m2-4h-140a2 2 0 00-2 2v100a2 2 0 002 2h140a2 2 0 002-2v-100a2 2 0 00-2-2z" /><g style="opacity:.1"><path class="ba-graphics-gray80" d="M170.16 168h-140a2 2 0 01-2-2V79a2 2 0 012-2h18.23a4 4 0 013 1.31l7.61 8.4a4.17 4.17 0 003 1.35h108.16a2 2 0 012 2v76a2 2 0 01-2 1.94z" /><path class="ba-graphics-gray80" d="M48.39 81L56 89.4a8.21 8.21 0 005.8 2.66h106.36v72h-136V81h16.23m0-4H30.16a2 2 0 00-2 2v87a2 2 0 002 2h140a2 2 0 002-2V90a2 2 0 00-1.94-2H61.93a4.17 4.17 0 01-3-1.35l-7.62-8.38a4 4 0 00-3-1.31z" /></g><path class="ba-graphics-white" d="M170.16 172.05h-140a2 2 0 01-2-2v-87a2 2 0 012-2h18.23a4 4 0 013 1.31L59 90.75a4 4 0 003 1.3h108.16a2 2 0 012 2v76a2 2 0 01-2 2z" /><path class="ba-graphics-gray60" d="M48.39 85.05L56 93.44a8 8 0 005.92 2.61h106.24v72h-136v-83h16.23m0-4H30.16a2 2 0 00-2 2v87a2 2 0 002 2h140a2 2 0 002-2v-76a2 2 0 00-2-2H61.93a4 4 0 01-3-1.3l-7.62-8.39a4 4 0 00-3-1.31z" /><path class="ba-graphics-white" d="M88.66 148.74h19.08" /><path class="ba-graphics-gray60" d="M107.74 150.74H88.65a2 2 0 010-4h19.09a2 2 0 110 4z" /><circle class="ba-graphics-gray60" cx="75.32" cy="137.69" r="3.47" /><circle class="ba-graphics-gray60" cx="121" cy="137.69" r="3.47" /></symbol>'});t.a.add(h);s.a=h},"3865314c5959606874d4":function(s,c){s.exports=a},"9616210854fe62536956":function(a,s,c){"use strict";Object.defineProperty(s,"__esModule",{value:!0});var i=c("3865314c5959606874d4"),r=(c.n(i),c("099720445ff350ff6c39"));s.default=r.a}},["9616210854fe62536956"])});
  3804. !function(a,s){if("object"==typeof exports&&"object"==typeof module)module.exports=s(require("@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"));else if("function"==typeof define&&define.amd)define('bacontentnav/lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/search-results_128',["@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"],s);else{var c=s("object"==typeof exports?require("@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"):a["@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"]);for(var i in c)("object"==typeof exports?exports:a)[i]=c[i]}}("undefined"!=typeof self?self:this,function(a){return webpackJsonPBaGraphics([35],{"3865314c5959606874d4":function(s,c){s.exports=a},b86a89ab812875d2eaf9:function(a,s,c){"use strict";var i=c("9689a9c94ae38b47fa2c"),e=c.n(i),t=c("9ce58a7deea14f49ef01"),r=c.n(t),l=new e.a({id:"search-results_128_v7",use:"search-results_128_v7-usage",viewBox:"0 0 200 200",content:'<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" id="search-results_128_v7"><circle class="ba-graphics-neutral-white4" cx="100" cy="100" r="100" /><path class="ba-graphics-white" d="M14.97 170.08h135.66" /><path class="ba-graphics-gray60" d="M150.63 172.08H15a2 2 0 110-4h135.63a2 2 0 010 4z" /><path class="ba-graphics-white" d="M2 170.08h4.97" /><path class="ba-graphics-gray60" d="M7 172.08H2a2 2 0 010-4h5a2 2 0 010 4z" /><path class="ba-graphics-white" d="M179.03 170.08H198" /><path class="ba-graphics-gray60" d="M198 172.08h-19a2 2 0 010-4h19a2 2 0 010 4z" /><path class="ba-graphics-white" d="M158.63 170.08h12.4" /><path class="ba-graphics-gray60" d="M171 172.08h-12.4a2 2 0 010-4H171a2 2 0 010 4z" /><circle class="ba-graphics-gray60" cx="55.73" cy="70.9" r="2" /><circle class="ba-graphics-gray60" cx="99.29" cy="34.77" r="2" /><path class="ba-graphics-gray60" d="M54.38 36.33a4 4 0 004-4 1 1 0 012 0 4 4 0 004 4 1 1 0 010 2 4 4 0 00-4 4 1 1 0 01-2 0 4 4 0 00-4-4 1 1 0 010-2zm80.04-12.56a2.65 2.65 0 002.65-2.65.66.66 0 011.32 0 2.65 2.65 0 002.61 2.65.66.66 0 010 1.32 2.65 2.65 0 00-2.65 2.65.66.66 0 01-1.32 0 2.65 2.65 0 00-2.65-2.65.66.66 0 110-1.32z" /><path class="ba-graphics-neutral-white4" d="M82.18 121.06l1 1.08a2.85 2.85 0 01-.23 4l-23.62 21.12a2.86 2.86 0 01-2.06.73 2.89 2.89 0 01-2-1l-5.93-6.64a2.84 2.84 0 01.22-4l23.62-21.14a2.89 2.89 0 012.07-.72 2.82 2.82 0 012 1l1.16 1.3 4.95-4.36a38.26 38.26 0 113.73 4.3z" /><path class="ba-graphics-gray60" d="M57.43 150.2h-.29a5.06 5.06 0 01-3.49-1.69l-5.93-6.63a5.07 5.07 0 01.4-7.14l23.62-21.14a5.05 5.05 0 016.84.09l1.82-1.61a40.65 40.65 0 116.6 7.62l-1.79 1.58a5.07 5.07 0 01-.87 6.51L60.8 148.91a5.12 5.12 0 01-3.37 1.29zm17.68-33.48a.67.67 0 00-.43.16L51.07 138a.64.64 0 00-.22.48.66.66 0 00.16.43l5.99 6.66a.62.62 0 00.44.21.67.67 0 00.47-.16l23.57-21.11a.65.65 0 00.06-.91l-2.42-2.73 8.1-7.18 1.47 1.46a36.11 36.11 0 10-3.52-4.05l1.21 1.63-8.12 7.17-2.62-3a.63.63 0 00-.44-.22z" /><circle class="ba-graphics-white" cx="114.08" cy="89.49" r="27.3" /><path class="ba-graphics-gray60" d="M114.08 118.91a29.42 29.42 0 1129.41-29.42 29.45 29.45 0 01-29.41 29.42zm0-54.61a25.2 25.2 0 1025.2 25.19 25.22 25.22 0 00-25.2-25.19z" /></symbol>'});r.a.add(l);s.a=l},f0f5b3d0dafd8138f35f:function(a,s,c){"use strict";Object.defineProperty(s,"__esModule",{value:!0});var i=c("3865314c5959606874d4"),e=(c.n(i),c("b86a89ab812875d2eaf9"));s.default=e.a}},["f0f5b3d0dafd8138f35f"])});
  3805. !function(a,s){if("object"==typeof exports&&"object"==typeof module)module.exports=s(require("@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"));else if("function"==typeof define&&define.amd)define('bacontentnav/lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/recent-activity_128',["@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"],s);else{var c=s("object"==typeof exports?require("@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"):a["@ba-ui-toolkit/ba-graphics/dist/illustrations-js/ba-graphics-icons-commons.js"]);for(var i in c)("object"==typeof exports?exports:a)[i]=c[i]}}("undefined"!=typeof self?self:this,function(a){return webpackJsonPBaGraphics([50],{"06ed3a87abd189187ff5":function(a,s,c){"use strict";Object.defineProperty(s,"__esModule",{value:!0});var i=c("3865314c5959606874d4"),h=(c.n(i),c("2ad33f842a20668c416d"));s.default=h.a},"2ad33f842a20668c416d":function(a,s,c){"use strict";var i=c("9689a9c94ae38b47fa2c"),h=c.n(i),t=c("9ce58a7deea14f49ef01"),r=c.n(t),e=new h.a({id:"recent-activity_128_v7",use:"recent-activity_128_v7-usage",viewBox:"0 0 200 200",content:'<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" id="recent-activity_128_v7"><circle class="ba-graphics-neutral-white4" cx="100" cy="100" r="100" /><path class="ba-graphics-white" d="M14.97 170.08h135.66" /><path class="ba-graphics-gray60" d="M150.63 172.08H15a2 2 0 110-4h135.63a2 2 0 010 4z" /><path class="ba-graphics-white" d="M2 170.08h4.97" /><path class="ba-graphics-gray60" d="M7 172.08H2a2 2 0 010-4h5a2 2 0 010 4z" /><path class="ba-graphics-white" d="M179.03 170.08H198" /><path class="ba-graphics-gray60" d="M198 172.08h-19a2 2 0 010-4h19a2 2 0 010 4z" /><path class="ba-graphics-white" d="M158.63 170.08h12.4" /><path class="ba-graphics-gray60" d="M171 172.08h-12.4a2 2 0 010-4H171a2 2 0 010 4z" /><circle class="ba-graphics-gray60" cx="137.78" cy="38.33" r="2" /><circle class="ba-graphics-gray60" cx="105.47" cy="18.8" r="2" /><path class="ba-graphics-gray1" d="M67.62 122.77H18.1v-11.93h49.52z" /><path class="ba-graphics-gray60" d="M69.1 124.25H16.62v-14.89H69.1zm-49.53-3h46.58v-9H19.57z" /><path class="ba-graphics-gray60" d="M42 118.34H25.68a1.48 1.48 0 010-3H42a1.48 1.48 0 010 3zm11.77 0h-7.39a1.48 1.48 0 010-3h7.39a1.48 1.48 0 010 3zM66 28.18a4 4 0 004-4 1 1 0 012 0 4 4 0 004 4 1 1 0 010 2 4 4 0 00-4 4 1 1 0 11-2 0 4 4 0 00-4-4 1 1 0 010-2z" /><circle class="ba-graphics-white" cx="100" cy="100" r="51.75" /><path class="ba-graphics-gray60" d="M100 153.75A53.75 53.75 0 11153.75 100 53.81 53.81 0 01100 153.75zm0-103.5A49.75 49.75 0 10149.75 100 49.81 49.81 0 00100 50.25z" /><path class="ba-graphics-gray60" d="M132.26 134.26a2 2 0 01-1.41-.58l-4.75-4.75a2 2 0 012.83-2.83l4.75 4.75a2 2 0 01-1.42 3.41zM72.49 74.49a2 2 0 01-1.42-.59l-4.75-4.75a2 2 0 012.83-2.83l4.75 4.75a2 2 0 01-1.41 3.42zm-4.75 59.77a2 2 0 01-1.42-3.41l4.75-4.75a2 2 0 012.83 2.83l-4.75 4.75a2 2 0 01-1.41.58zm59.77-59.77a2 2 0 01-1.41-3.42l4.75-4.75a2 2 0 012.83 2.83l-4.75 4.75a2 2 0 01-1.42.59zM61.09 102h-6.72a2 2 0 010-4h6.72a2 2 0 010 4zm84.54 0h-6.72a2 2 0 010-4h6.72a2 2 0 010 4zM100 63.09a2 2 0 01-2-2v-6.72a2 2 0 014 0v6.72a2 2 0 01-2 2zm0 84.54a2 2 0 01-2-2v-6.72a2 2 0 014 0v6.72a2 2 0 01-2 2zm.1-50.57a2 2 0 01-2-2V70.57a2 2 0 014 0v24.49a2 2 0 01-2 2zm17.78 5.14h-13.13a2 2 0 010-4h13.13a2 2 0 010 4z" /><path class="ba-graphics-gray60" d="M100 106.15a6.15 6.15 0 116.15-6.15 6.16 6.16 0 01-6.15 6.15zm0-8.3a2.15 2.15 0 102.15 2.15 2.16 2.16 0 00-2.15-2.15z" /><g style="opacity:.1"><path class="ba-graphics-gray80" d="M183.25 91.68h-49.53V79.74h49.53z" /><path class="ba-graphics-gray80" d="M185.25 93.68h-53.53V77.74h53.53zm-49.53-4h45.53v-7.94h-45.53z" /></g><path class="ba-graphics-white" d="M181.76 90.18h-49.53V78.24h49.53z" /><path class="ba-graphics-gray60" d="M183.24 91.65h-52.49V76.76h52.49zm-49.53-3h46.57v-9h-46.57z" /><path class="ba-graphics-gray60" d="M156.08 85.74h-16.26a1.48 1.48 0 110-3h16.26a1.48 1.48 0 010 3zm11.83 0h-7.39a1.48 1.48 0 110-3h7.39a1.48 1.48 0 010 3z" /></symbol>'});r.a.add(e);s.a=e},"3865314c5959606874d4":function(s,c){s.exports=a}},["06ed3a87abd189187ff5"])});
  3806. /*
  3807. *+------------------------------------------------------------------------+
  3808. *| Licensed Materials - Property of IBM
  3809. *| IBM Cognos Products: ba_content_nav
  3810. *| (C) Copyright IBM Corp. 2015, 2021
  3811. *|
  3812. *| US Government Users Restricted Rights - Use, duplication or disclosure
  3813. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  3814. *+------------------------------------------------------------------------+
  3815. */
  3816. define('bacontentnav/common/ui/ListControl',[
  3817. 'q',
  3818. 'doT',
  3819. 'jquery',
  3820. 'require',
  3821. 'underscore',
  3822. './list_actions/AddFolderAction',
  3823. './list_actions/DefaultActionHandler',
  3824. 'text!../templates/ListControlTemplate.html',
  3825. 'text!../templates/EmptyListTemplate.html',
  3826. '../../lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/empty-folder_128',
  3827. '../../lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/search-results_128',
  3828. '../../lib/@ba-ui-toolkit/ba-graphics/dist/illustrations-js/recent-activity_128',
  3829. '../../nls/StringResource',
  3830. '../../utils/UIHelper',
  3831. '../../utils/ContentStoreObject',
  3832. '../../lib/@waca/baglass/js/baglass/app/ContentView',
  3833. '../../lib/@waca/core-client/js/core-client/utils/Utils',
  3834. '../../lib/@waca/core-client/js/core-client/ui/Menu',
  3835. 'datatables',
  3836. 'datatables-natural'
  3837. ], function(Q, dot, $, LocalRequire, _, AddFolderAction, DefaultActionHandler, listControlTemplate, emptyListTemplate, emptyFolder_128, emptySearch_128, emptyRecents_128, StringResource, UIHelper, ContentStoreObject, ContentView, Utils, Menu) {
  3838. 'use strict';
  3839. // Keep a list of visible list controls - needed for the resize handler
  3840. var listControls = {};
  3841. // Loops through each list control and call their resize
  3842. var resizeEventHandler = function() {
  3843. $.each(listControls, (function(index, listControl) {
  3844. listControl.resize();
  3845. }));
  3846. };
  3847. $(window).on('resize', resizeEventHandler);
  3848. var ListControl = ContentView.extend({
  3849. sort: true,
  3850. sortIndexes: null,
  3851. disableColumnHeaders: false,
  3852. propertiesSpacing: null,
  3853. dataTableOptions: {},
  3854. aSelectedRows: [],
  3855. oSelectedData: undefined,
  3856. multiSelect: true,
  3857. _isShowingEmptyMessage: false,
  3858. rightClickContextMenu: true,
  3859. // How many items we add to the list when you scroll to the bottom
  3860. _showLoadBuffer: 40,
  3861. browserResize: true,
  3862. spinnerTimeout: null,
  3863. /**
  3864. * @param options.$el JQuery node to append the table HTML
  3865. * @param options.url {string} - URL for the ajax request to get the JSON
  3866. * @param options.urlParameters {object} - object of key/value pairs representing URL parameters
  3867. * @param options.columns {object} - An array of column metadata. Must provide both a name property and a label property. Also can specify any property supported by datatables aoColumnDefs property
  3868. * @param options.sort {boolean} - default is true
  3869. * @param options.propertiesSpacing {String} - css string value of for the width of the column before the context menu button (only applies when context menu takes up the last column), value of null disables the resizing
  3870. * @param options.ajaxProp {String} - location to find the array of objects in the data response. Defaults to 'data'
  3871. * @param options.dataTableOptions {object} - datatable option used to override defaults
  3872. * @param options.defaultSort {array} - array containing the index {int} and order {string}, for example [1, 'asc']
  3873. * @param options.multiSelect {boolean} - allow multi-select functionality - default is true
  3874. * @param options.disableColumnHeaders {boolean} - default is false
  3875. * @param options.resizeCallback {function} - gets called after the resize() function
  3876. * @param options.singleSelectCallback {function} - gets called after a single selection is made
  3877. * @param options.deselectCallback {function} - gets called after all selection is removed
  3878. * @param options.rightClickContextMenu {boolean} - default is true
  3879. * @param options.emptyFolderString {string} - heading string that accompanies the empty svgIcon logo - default: "There is nothing in this folder."
  3880. * @param options.emptyParagraphString {string} - paragraph string that accompanies the empty svgIcon logo - default: none
  3881. * @param options.showEmptyNewFolderButton {boolean} - should the new folder button show up when a folder is empty? default: true
  3882. * @param options.rowLimit {int} - Limits the datatable to only show x rows.
  3883. * @param options.debounceRate {int} - The number of milliseconds for the debounce before we call this._dTable._fnDraw() in the resize(). Defaults to 300ms.
  3884. * @param options.filterByTypes {string} - regular expression filter on index column. For example, if you want to only display folders, packages, and reports; set to "folder|package|report"."
  3885. * @param options.setFocusOnDraw {boolean} - if true, will set focus to the first item in the list after drawing is complete. defaults to true.
  3886. * @param options.getJSONDataCallback {function} - optional, if specified the method will be called to get the JSON data for the datatable to render. Must return a resolved promise with the JSON object.
  3887. * @param options.dataManipulationCallback {function} - optional, called after the Ajax call to do any changes to the response before the datatable renders it
  3888. * @param options.selectedRow {[string, string]} - optional, allows user to select one row of the data table. First string is the property to match, and second string is the value.
  3889. * @param options.browserResize {boolean} - optional, default is true. Allows caller to specify whether to call on the browser resize to resize the datatable
  3890. * @param options.calcExtraNonTableHeight {function} - optional, called to calculate extra non-table height if it is applicable;
  3891. * @param options.groupByColumnAPI {object} - optional, default is undefined. Allows caller to specify how rows should be grouped
  3892. * @param options.groupByColumnAPI.shouldGroup {function} - returns boolean to determine if rows should be grouped. Takes the datatable API as a parameter.
  3893. * @param options.groupByColumnAPI.getGroupName {function} - optional, takes column value as parameter and returns the name for that group.
  3894. * @param options.groupByColumnAPI.columnIndex {integer} - index of the column to group by.
  3895. * @param options.contentView.isDialog {boolean} - If true, the ListControl is in a modal dialog.
  3896. * @param options.contentView.onDefaultAction {object} - Handler to the dialog object so we can close it on default actions.
  3897. */
  3898. init: function(options) {
  3899. // Need to keep the original options around for the loading more rows logic
  3900. this._initialOptions = _.extend({}, options);
  3901. this._lastShiftSelectedRow = null;
  3902. this.aSelectedRows = [];
  3903. this.wasSelected = false;
  3904. this.showEmptyNewFolderButton = true;
  3905. this.parentHasWritePermission = true;
  3906. this.setFocusOnDraw = true;
  3907. this.emptyFolderString = StringResource.get('emptyTableContentMessage');
  3908. if (this.textParagraph) {
  3909. this.emptyParagraphString = this.textParagraph;
  3910. }
  3911. this._scrollTop = null;
  3912. ListControl.inherited('init', this, arguments);
  3913. this.ajaxProp = 'data';
  3914. this.accessibleLabel = options.accessibleLabel || '';
  3915. _.extend(this, options);
  3916. // the URL needs to be set to something, or the datatable won't try to render and getJSONDataCallback won't be called
  3917. this.url = this.url || ' ';
  3918. this.getData = this.getJSONDataCallback;
  3919. // Add ourselves to the listControls object so that resize gets handled
  3920. this._id = _.uniqueId('lc_');
  3921. listControls[this._id] = this;
  3922. this._renderedRowCount = this._showLoadBuffer;
  3923. this._renderRowsOnScroll = true;
  3924. this._showWorking = false;
  3925. this._cancelDebounce = false;
  3926. this.debounceRate = options.debounceRate || 300; //300 ms debounce on render
  3927. this._emptyIcon = options.emptyIcon;
  3928. this._calcExtraNonTableHeight = options.calcExtraNonTableHeight;
  3929. this._groupByColumnAPI = options.groupByColumnAPI;
  3930. this.oSelectedData = {};
  3931. },
  3932. createColumnObject: function(columnSpec, ColumnModule) {
  3933. return new ColumnModule($.extend(columnSpec, {
  3934. 'listControl': this,
  3935. 'glassContext': this.glassContext
  3936. }));
  3937. },
  3938. /**
  3939. Main entry point - will render the data table with the information supplied
  3940. @return - promise that will be resolved when the datatable is rendered
  3941. **/
  3942. _loadModule: function(moduleId) {
  3943. return new Promise(function(resolve, reject) {
  3944. if (typeof moduleId === 'function') {
  3945. resolve(moduleId);
  3946. } else {
  3947. LocalRequire([moduleId], function(Module) {
  3948. if (Module) {
  3949. resolve(Module);
  3950. } else {
  3951. this.logger.error('Module id is not set');
  3952. reject({ msg: ' Module id is not set', causedBy: 'Module id is not set' });
  3953. }
  3954. }.bind(this), function (error) {
  3955. this.logger.error(moduleId + ' id is not loaded');
  3956. reject({ msg: moduleId + ' is not loaded', causedBy: error });
  3957. }.bind(this));
  3958. }
  3959. }.bind(this));
  3960. },
  3961. render: function() {
  3962. var aPromises = [];
  3963. $.each(this.columns, function(index, column) {
  3964. if ((column.type && column.type.indexOf('natural') === -1) || column.module ) {
  3965. var columnObj = column;
  3966. var path = column.module || './list_columns/' + column.type;
  3967. aPromises.push(new Promise(function(resolve){
  3968. this._loadModule(path).then(function(ColumnModule) {
  3969. delete columnObj.type;
  3970. var col = this.createColumnObject(columnObj, ColumnModule);
  3971. col.getSpec().then(function(spec) {
  3972. _.extend(columnObj, spec);
  3973. // Set the column index correctly
  3974. columnObj.aTargets = [index];
  3975. resolve();
  3976. });
  3977. }.bind(this));
  3978. }.bind(this)));
  3979. }
  3980. }.bind(this));
  3981. // Wait until all the promises are resolved before rendering the data table
  3982. return Promise.all(aPromises).then(function() {
  3983. var sHtml = dot.template(listControlTemplate)({
  3984. id: this._id,
  3985. accessibleLabel: this.accessibleLabel,
  3986. columns: this.columns,
  3987. sort: this.sort
  3988. });
  3989. this.$el.append(sHtml);
  3990. return this._renderDataTable().then(function() {
  3991. this._registerEvents();
  3992. return this;
  3993. }.bind(this));
  3994. }.bind(this))
  3995. .catch(function(e) {
  3996. //show the empty table message
  3997. this.showEmptyTableMessage();
  3998. //and rethrow
  3999. throw(e);
  4000. }.bind(this));
  4001. },
  4002. _registerEvents: function() {
  4003. if (this.rightClickContextMenu) {
  4004. $('#' + this._id + ' tbody').on('contextmenu', 'tr', function(evt) {
  4005. if ($(evt.target).is('INPUT')) {
  4006. return true;
  4007. }
  4008. this._hideSlideoutChildrenToTheRight();
  4009. if (this.contentView.slideout && this.contentView.slideout.child && this.contentView.slideout.child.hideHandler) {
  4010. return false;
  4011. }
  4012. var trNode = evt.currentTarget;
  4013. // Clear all the selections if right clicking on a row that wasn't previously selected
  4014. if (!$(trNode).hasClass('selected')) {
  4015. this.selectSingleRow(trNode); //hide multi-select bar after clearing rows
  4016. }
  4017. if (this.aSelectedRows === null || this.aSelectedRows.length < 1) {
  4018. if (!this.canSelectCallback || (this.canSelectCallback && this.canSelectCallback(this.getRowData(trNode)))) {
  4019. this.aSelectedRows = [trNode];
  4020. this._updateSelectedData();
  4021. }
  4022. }
  4023. if (this.aSelectedRows && this.aSelectedRows.length > 0) {
  4024. evt.stopPropagation();
  4025. this._updateSizeForSelection();
  4026. $(trNode).addClass('selected');
  4027. this._toggleCheckBox(trNode, true);
  4028. this.getActionPayload(evt).then(function(actionPayload) {
  4029. this.glassContext.appController.showContextMenu(actionPayload);
  4030. }.bind(this));
  4031. return false;
  4032. }
  4033. return true;
  4034. }.bind(this));
  4035. }
  4036. // process row events
  4037. this._dTable.on('primaryaction', 'tr', this.handleClick.bind(this));
  4038. this._dTable.on('dblclick', 'tr', this.handleDoubleClick.bind(this));
  4039. this._dTable.on('hold', this.handleHoldEvent.bind(this));
  4040. },
  4041. /**
  4042. * Process the row via up/down keyboard navigation - needed a way to check if we are at the bottom of the currently loaded datatable or not. If we are then load the remainder of data (if there is any to load).
  4043. *
  4044. * @param {Object} options
  4045. */
  4046. _processRowForMoreDataLoad: function(options) {
  4047. var currentRowLocation = options.dataTable.find(options.currentRow).index() + 1;
  4048. if (options.lastRenderedRow <= currentRowLocation + 1) {
  4049. this._handleReRender();
  4050. }
  4051. },
  4052. _handleReRender: function() {
  4053. if (!this._hasVerticalScrollbar()) {
  4054. return;
  4055. }
  4056. // Flag to make sure we don't process multiple scroll events at the same time
  4057. this.setRenderRowsOnScroll(false);
  4058. var aData = this._dTable.fnGetData();
  4059. // If we're already showing all the data
  4060. if (this._renderedRowCount >= aData.length) {
  4061. this.setRenderRowsOnScroll(true);
  4062. this._renderedRowCount = aData.length;
  4063. // Hide the loading animation container
  4064. this._scrollNode.find('.listControlLoadingMore').css('display', 'none');
  4065. return;
  4066. }
  4067. // Show the loading animation
  4068. this._scrollNode.find('.loadingAnimation').css('display', 'block');
  4069. this._renderExtraRows(this._renderedRowCount, this._showLoadBuffer).then(function() {
  4070. this.setRenderRowsOnScroll(true);
  4071. this._scrollNode.find('.loadingAnimation').css('display', 'none');
  4072. }.bind(this));
  4073. },
  4074. getContextMenuId: function() {
  4075. return this.contextMenuId ? this.contextMenuId : 'com.ibm.bi.contentApps.listViewMenu';
  4076. },
  4077. _getTargetPromise: function(actionPayload) {
  4078. var selectedObjects = this.getSelectedObjects();
  4079. if (selectedObjects && selectedObjects.length === 1 && UIHelper.hasSource(selectedObjects[0])) {
  4080. return ContentStoreObject.getTargetSearchPath(selectedObjects[0], true).then(function(selectionTarget) {
  4081. if (selectionTarget) {
  4082. return this.glassContext.getSvc('.Content').then(function(contentService) {
  4083. return this.glassContext.getCoreSvc('.Ajax').ajax({
  4084. url: contentService.getSearchPathUrl(ContentStoreObject.getSearchPath(selectionTarget)),
  4085. dataType: 'json',
  4086. data: this.urlParameters
  4087. }).then(function(response) {
  4088. var target = response && response.data && response.data.data;
  4089. if (target && target.length === 1) {
  4090. actionPayload.activeObject.targetSelectedContext = selectedObjects;
  4091. return Promise.resolve(target);
  4092. } else {
  4093. this.logger.warn('Asset with target does not return proper source target: ' + selectionTarget && selectionTarget.id);
  4094. return Promise.resolve(selectedObjects);
  4095. }
  4096. }.bind(this))
  4097. .catch(function(err){
  4098. this.logger.warn('Target is not found:' + err);
  4099. return Promise.resolve(selectedObjects);
  4100. }.bind(this));
  4101. }.bind(this));
  4102. }
  4103. }.bind(this));
  4104. } else {
  4105. return Promise.resolve(selectedObjects);
  4106. }
  4107. },
  4108. getActionPayload: function(event) {
  4109. // figure out the position for the context menu
  4110. var position = {};
  4111. var pageX = event.pageX;
  4112. var gestureCenterPageX = event.gesture && event.gesture.center && event.gesture.center.pageX;
  4113. if (!(pageX || gestureCenterPageX)) {
  4114. position = $(event.target).offset();
  4115. } else {
  4116. position.left = pageX || gestureCenterPageX;
  4117. position.top = event.pageY || event.gesture.center.pageY;
  4118. }
  4119. // set up action payload
  4120. var actionPayload = {
  4121. activeObject: {
  4122. oListControl: this,
  4123. handler: this.contentView,
  4124. slideout: this.contentView.slideout,
  4125. // being explicit here to raise awareness of the targetSelectedContext,
  4126. // it is only used in scenario of an action that needs to operate on the
  4127. // event targetted asset (eg a shortcut) instead its source target
  4128. targetSelectedContext: undefined
  4129. },
  4130. position: {
  4131. pageX: position.left,
  4132. pageY: position.top
  4133. },
  4134. menuId: this.getContextMenuId()
  4135. };
  4136. // figure out objects to act on...
  4137. return this._getTargetPromise(actionPayload)
  4138. .then(this.getSelectedObjectFolderCapabilities.bind(this))
  4139. .then(this.getSelectedObjectWPermissions.bind(this))
  4140. .then(this.checkSetVersionsSupported.bind(this))
  4141. .then(function(selectedContext) {
  4142. // add objects to payload - consider deprecating options
  4143. actionPayload.activeObject.aSelectedContext = selectedContext;
  4144. actionPayload.options = this.getPublicSelectedObjects(selectedContext);
  4145. return Promise.resolve(actionPayload);
  4146. }.bind(this));
  4147. },
  4148. getFirstFocusElement: function() {
  4149. var $firstTableThing;
  4150. if (this._isShowingEmptyMessage) {
  4151. $firstTableThing = this.$el.find(".newFolderLabel[tabindex='0']");
  4152. } else {
  4153. $firstTableThing = this.$el.find("td[tabindex='0']");
  4154. }
  4155. return $firstTableThing;
  4156. },
  4157. setFocus: function() {
  4158. var $firstTableThing = null;
  4159. if (this.addFolderNameForFocus) {
  4160. var newFocus = this.$el.find('td.name').filter(function(ind, el) {
  4161. return $(el).text() === this.addFolderNameForFocus;
  4162. }.bind(this));
  4163. //var $newFocus = this.$el.find("td:contains('" + this.addFolderNameForFocus + "')");
  4164. if (newFocus.length !== 0) {
  4165. $firstTableThing = $(newFocus[0]);
  4166. }
  4167. //need to reset the addFolderNameForFocus as it is always one time shot
  4168. this.addFolderNameForFocus = undefined;
  4169. }
  4170. if ($firstTableThing === null) {
  4171. $firstTableThing = this.getFirstFocusElement();
  4172. }
  4173. if ($firstTableThing.length > 0) {
  4174. $firstTableThing.focus();
  4175. return true;
  4176. } else {
  4177. return false;
  4178. }
  4179. },
  4180. handleDoubleClick: function(evt) {
  4181. // hooking into this flag for now, TODO: verify there are no cases where they differ
  4182. var oData = this.getSelectedObjects()[0]; // the selected object
  4183. if (this.rightClickContextMenu) {
  4184. // find the row and select it
  4185. var trNode = this.findRowNode(evt.currentTarget);
  4186. this.selectSingleRow(trNode);
  4187. // find current selection
  4188. var $div = $(evt.currentTarget); // the row
  4189. // launch the action on the selected object
  4190. DefaultActionHandler.executeDefaultAction({
  4191. listControl: this,
  4192. glassContext: this.glassContext,
  4193. $div: $div,
  4194. evt: evt,
  4195. oData: oData
  4196. });
  4197. // for automation - set the row to idle
  4198. if (ContentStoreObject.getDisabled(oData)) {
  4199. $div.addClass('dimmed idle');
  4200. }
  4201. }
  4202. if (this.contentView.isDialog) {
  4203. if (typeof this.contentView.onDefaultAction !== 'undefined' && !ContentStoreObject.getDisabled(oData)) {
  4204. this.contentView.onDefaultAction();
  4205. }
  4206. }
  4207. },
  4208. handleClick: function(evt) {
  4209. var trNode = this.findRowNode(evt.currentTarget);
  4210. // Click still fired by browser for hold events on iPad, this is to catch and nullify the click
  4211. if (evt.type === 'click' && this.multiSelectEvent && this.multiSelectEvent.type === 'hold') {
  4212. return;
  4213. }
  4214. // Click a folder and its property page is open, do nothing and stop the event
  4215. if (this.aSelectedRows.length === 1 && trNode.rowIndex === this.aSelectedRows[0].rowIndex && $(trNode).hasClass('selected') && this.contentView._propertiesOpen) {
  4216. return;
  4217. }
  4218. if (evt.which === 3 && (evt.shiftKey || evt.ctrlKey || evt.metaKey || $(trNode).hasClass('selected'))) {
  4219. return false;
  4220. }
  4221. // Process <Shift>click
  4222. if (evt.shiftKey && this.multiSelect) {
  4223. // no rows previously selected, handle like normal click
  4224. if (this.aSelectedRows.length === 0) {
  4225. this._handleSingleSelect(trNode, evt.target);
  4226. this._lastShiftSelectedRow = null;
  4227. }
  4228. // Get last selected row
  4229. var oLastSelectedRow = this._lastShiftSelectedRow;
  4230. var iLastSelectedRowIndex = 1;
  4231. if (oLastSelectedRow) {
  4232. iLastSelectedRowIndex = oLastSelectedRow.rowIndex;
  4233. if (iLastSelectedRowIndex < 0) {
  4234. iLastSelectedRowIndex = 1;
  4235. }
  4236. }
  4237. // Clear all rows of 'selected' class
  4238. this._clearRows();
  4239. var iEndRow = Math.max(iLastSelectedRowIndex, trNode.rowIndex);
  4240. var iStartRow = Math.min(iLastSelectedRowIndex, trNode.rowIndex);
  4241. // Get filtered table rows
  4242. var aNodes = this._dTable.$('tr', {
  4243. 'filter': 'applied'
  4244. });
  4245. for (var i = iStartRow; i <= iEndRow; i = i + 1) {
  4246. if (!this.canSelectCallback || (this.canSelectCallback && this.canSelectCallback(this.getRowData(aNodes[i - 1])))) {
  4247. $(aNodes[i - 1]).addClass('selected');
  4248. this._toggleCheckBox(aNodes[i - 1], true);
  4249. this.aSelectedRows.push(aNodes[i - 1]);
  4250. }
  4251. }
  4252. if (this.aSelectedRows.length > 1) {
  4253. this._showMultiSelectBar();
  4254. }
  4255. this._updateSelectedData();
  4256. this._updateRowsCounter();
  4257. } else if (((evt.ctrlKey || evt.metaKey) && this.multiSelect) || (evt.type === 'tap' && this.touchMultiSelectEnabled)) {
  4258. // Process <Ctrl>click
  4259. if (this.aSelectedRows.length === 0) {
  4260. // no rows previously selected, handle like normal click
  4261. this._handleSingleSelect(trNode, evt.target);
  4262. } else {
  4263. this._handleMultiSelect(trNode, evt.target);
  4264. }
  4265. } else if (this._handleSingleSelect(trNode, evt.target) === false) {
  4266. // Process normal mouse click
  4267. return false;
  4268. }
  4269. },
  4270. _handleMultiSelect: function(trNode, target) {
  4271. this._updateSizeForSelection();
  4272. if (!this.canSelectCallback || (this.canSelectCallback && this.canSelectCallback(this.getRowData(trNode)))) {
  4273. // Toggle 'selected' class of current row
  4274. if (!($(trNode).hasClass('selected') && $(target).hasClass('forceRowSelection'))) {
  4275. $(trNode).toggleClass('selected');
  4276. this._toggleCheckBox(trNode, $(trNode).hasClass('selected'));
  4277. }
  4278. // Maintain the array of selected rows
  4279. var iIndex = this.aSelectedRows.indexOf(trNode);
  4280. if (iIndex > -1) {
  4281. if (!$(target).hasClass('forceRowSelection')) {
  4282. this.aSelectedRows.splice(iIndex, 1);
  4283. }
  4284. } else {
  4285. this.aSelectedRows.push(trNode);
  4286. }
  4287. this._updateSelectedData();
  4288. this._updateRowsCounter();
  4289. }
  4290. if (this.aSelectedRows.length === 0) {
  4291. this._clearRows();
  4292. this._hideMultiSelectBar();
  4293. } else {
  4294. this._lastShiftSelectedRow = trNode;
  4295. this._showMultiSelectBar();
  4296. }
  4297. },
  4298. _handleSingleSelect: function(trNode, target) {
  4299. // behavior for regular click
  4300. if (!$(target).hasClass('forceRowSelection')) {
  4301. this._hideMultiSelectBar();
  4302. if (this.aSelectedRows.length === 1 && trNode.rowIndex === this.aSelectedRows[0].rowIndex) {
  4303. if ($(trNode).hasClass('selected') && this.contentView._propertiesOpen) {
  4304. return false;
  4305. }
  4306. if (this.deselectCallback) {
  4307. this.deselectCallback();
  4308. }
  4309. $(trNode).removeClass('selected');
  4310. this._toggleCheckBox(trNode, false);
  4311. this.aSelectedRows = [];
  4312. this._updateSelectedData();
  4313. }
  4314. this.selectSingleRow(trNode);
  4315. } else {
  4316. // behavior for ellipsis button (only change the selection if the row isn't already selected)
  4317. var found = false;
  4318. this.aSelectedRows.forEach(function(selRow) {
  4319. if (selRow.rowIndex === trNode.rowIndex) {
  4320. found = true;
  4321. }
  4322. });
  4323. if (!found) {
  4324. this.selectSingleRow(trNode);
  4325. }
  4326. }
  4327. },
  4328. selectSingleRow: function(trNode) {
  4329. var selectedObject = this.getRowData(trNode);
  4330. if (!this.canSelectCallback || (this.canSelectCallback && this.canSelectCallback(selectedObject))) {
  4331. this._hideMultiSelectBar();
  4332. this._clearRows();
  4333. this._selectRow(trNode);
  4334. }
  4335. if ((!this.isInStandbyMode() || this.selectAcrossFolders) && this.singleSelectCallback) {
  4336. this.singleSelectCallback(selectedObject);
  4337. }
  4338. },
  4339. selectAll: function() {
  4340. this._clearRows();
  4341. // Get filtered table rows
  4342. var aNodes = this._dTable.$('tr', {
  4343. 'filter': 'applied'
  4344. });
  4345. for (var i = 0; i < aNodes.length; i++) {
  4346. if (!this.canSelectCallback || (this.canSelectCallback && this.canSelectCallback(this.getRowData(aNodes[i])))) {
  4347. $(aNodes[i]).addClass('selected');
  4348. this._toggleCheckBox(aNodes[i], true);
  4349. this.aSelectedRows.push(aNodes[i]);
  4350. }
  4351. }
  4352. if (this.aSelectedRows.length > 1) {
  4353. this._showMultiSelectBar();
  4354. }
  4355. this._updateSelectedData();
  4356. this._updateRowsCounter();
  4357. },
  4358. clearAll: function() {
  4359. this._clearRows();
  4360. this._updateSelectedData();
  4361. },
  4362. clearAllSelected: function() {
  4363. this._clearRows();
  4364. this.oSelectedData = {};
  4365. this._updateSelectedData();
  4366. },
  4367. _updateRowsCounter: function() {
  4368. var noOfItemSelected = StringResource.get('noOfItemSelected', {
  4369. 'noOfItems': this.aSelectedRows.length
  4370. });
  4371. if (this.contentView.updateMultiSelectBarText) {
  4372. this.contentView.updateMultiSelectBarText(noOfItemSelected);
  4373. }
  4374. },
  4375. _showMultiSelectBar: function() {
  4376. if(this.$el.hasClass('singleSelectMode')){
  4377. this.$el.removeClass('singleSelectMode');
  4378. }
  4379. if (this.contentView.showMultiSelectBar) {
  4380. this.contentView.showMultiSelectBar(this.isAccountPickerSlideout());
  4381. }
  4382. },
  4383. _hideMultiSelectBar: function() {
  4384. this.$el.addClass('singleSelectMode'); //make ellipsesButton visible only in single select mode
  4385. if (this.contentView && this.contentView.hideMultiSelectBar) {
  4386. this.contentView.hideMultiSelectBar();
  4387. }
  4388. },
  4389. _hideSlideoutChildrenToTheRight: function() {
  4390. if (this.contentView && this.contentView.slideout && this.contentView.slideout.child) {
  4391. this.contentView.slideout.child.hide(this.contentView.slideout.child); //TODO: ?
  4392. }
  4393. },
  4394. handleHoldEvent: function(evt) {
  4395. this._updateSizeForSelection();
  4396. this._showMultiSelectBar();
  4397. this._clearRows();
  4398. this.touchMultiSelectEnabled = true;
  4399. var node = this.findRowNode(evt.target.parentNode);
  4400. if (!this.canSelectCallback || (this.canSelectCallback && this.canSelectCallback(this.getRowData(node)))) {
  4401. $(node).addClass('selected');
  4402. this._toggleCheckBox(node, true);
  4403. this.aSelectedRows.push(node);
  4404. this.multiSelectEvent = evt;
  4405. this._updateSelectedData();
  4406. this._updateRowsCounter();
  4407. }
  4408. },
  4409. findRowNode: function(node) {
  4410. while (node.nodeName.toLowerCase() !== 'tr') {
  4411. node = node.parentNode;
  4412. }
  4413. return node;
  4414. },
  4415. /**
  4416. * Clear all selected rows in dataTable
  4417. **/
  4418. _clearRows: function() {
  4419. _.each(this.aSelectedRows, function(oRow) {
  4420. $(oRow).removeClass('selected');
  4421. this._toggleCheckBox(oRow, false);
  4422. }.bind(this));
  4423. this.aSelectedRows = [];
  4424. // Clear button and counter for multi-select on touch devices
  4425. this.touchMultiSelectEnabled = false;
  4426. },
  4427. /**
  4428. * Deselect a row in dataTable
  4429. **/
  4430. _deselectRow: function(trNode) {
  4431. $(trNode).removeClass('selected');
  4432. this._toggleCheckBox(trNode, false);
  4433. this.aSelectedRows = this.aSelectedRows.filter(function(selRow){
  4434. return selRow.rowIndex !== trNode.rowIndex;
  4435. });
  4436. this._updateSelectedData();
  4437. },
  4438. /**
  4439. * Toggle checkbox checked state
  4440. **/
  4441. _toggleCheckBox: function(parent, toggleState) {
  4442. var $checkBox = $(parent).find('input.checkBoxes[type=checkbox]');
  4443. if ($checkBox) {
  4444. toggleState = toggleState !== undefined ? toggleState : !$checkBox.prop('checked');
  4445. $checkBox.prop('checked', toggleState);
  4446. }
  4447. },
  4448. /**
  4449. * Select a row in dataTable
  4450. **/
  4451. _selectRow: function(trNode) {
  4452. this._updateSizeForSelection();
  4453. $(trNode).addClass('selected');
  4454. this._toggleCheckBox(trNode, true);
  4455. this.aSelectedRows.push(trNode);
  4456. this._updateSelectedData();
  4457. this._lastShiftSelectedRow = trNode;
  4458. },
  4459. _updateSelectedData: function() {
  4460. if (this.selectAcrossFolders) {
  4461. var parentId = this._ancestors[this._ancestors.length-1].id;
  4462. this.oSelectedData[parentId] = this.getSelectedObjects();
  4463. if (this.selectAcrossFoldersSelectionChangeCallback) {
  4464. this.selectAcrossFoldersSelectionChangeCallback(_.flatten(_.map(this.oSelectedData, _.values)));
  4465. }
  4466. }
  4467. },
  4468. _doUpdateSize: function() {
  4469. if (!this._dataRendered) {
  4470. return;
  4471. }
  4472. var $head = this.$el.find('.dataTables_scrollBody');
  4473. var height = $head.css('height');
  4474. if (height !== undefined) {
  4475. var num = parseInt(height.substr(0, height.length - 2));
  4476. if (!isNaN(num)) {
  4477. $head.css('height', num + 2 + 'px');
  4478. }
  4479. }
  4480. },
  4481. _updateSizeForSelection: function() {
  4482. if ($('body').hasClass('highcontrast') && !this.wasSelected){
  4483. this._doUpdateSize();
  4484. this.wasSelected = true;
  4485. }
  4486. },
  4487. /**
  4488. * Create the datatable
  4489. **/
  4490. _renderDataTable: function() {
  4491. var deferred = Q.defer();
  4492. var xbound = this.$el.width();
  4493. jQuery.fn.dataTableExt.oSort['string-asc'] = function(a, b) {
  4494. a = a.toString().toLowerCase();
  4495. b = b.toString().toLowerCase();
  4496. return UIHelper.getCollator().compare(a, b);
  4497. };
  4498. jQuery.fn.dataTableExt.oSort['string-desc'] = function(a, b) {
  4499. a = a.toString().toLowerCase();
  4500. b = b.toString().toLowerCase();
  4501. return UIHelper.getCollator().compare(a, b) * -1;
  4502. };
  4503. delete jQuery.fn.dataTableExt.oSort['string-pre'];
  4504. var self = this;
  4505. var datatableSettings = {
  4506. 'width': '55%',
  4507. 'iDisplayLength': 40,
  4508. 'autoWidth': true,
  4509. 'sAjaxSource': this.url,
  4510. 'sAjaxDataProp': this.ajaxProp,
  4511. 'bServerSide': false,
  4512. 'bFilter': true,
  4513. 'bInfo': false,
  4514. 'bAutoWidth': false,
  4515. 'paging': true,
  4516. 'bScrollInfinite': true,
  4517. 'bScrollCollapse': true,
  4518. 'bDeferRender': true,
  4519. 'orderClasses': false,
  4520. 'bSort': this.sort,
  4521. 'sDom': 'rti',
  4522. 'asStripeClasses': [''],
  4523. 'aaSorting': this.defaultSort || [],
  4524. 'sScrollY': this.skipYBound ? undefined: this._calcYBound(),
  4525. 'sScrollX': xbound,
  4526. 'sScrollXInner': '100%',
  4527. 'aoColumnDefs': this.columns,
  4528. 'fnInitComplete': function(oSettings) {
  4529. self._dTable = this;
  4530. self._fnInitComplete(oSettings);
  4531. deferred.resolve();
  4532. },
  4533. 'fnServerData': function(sSource, aoData, fnCallback, oSettings) {
  4534. // Use a timeout so that if there isn't going to be a wait, it doesn't flash the spinner
  4535. this._dataRendered = false;
  4536. if (!this.isInitialized) {
  4537. window.clearTimeout(this.spinnerTimeout);
  4538. this.spinnerTimeout = window.setTimeout(this.showWorking.bind(this), 600);
  4539. }
  4540. var options = {
  4541. 'url': sSource,
  4542. 'dataType': 'json',
  4543. 'data': this.urlParameters,
  4544. 'type': 'GET'
  4545. };
  4546. var handleResponse = function(data, jqXHR) {
  4547. this.removeEmptyTableMessage();
  4548. oSettings.jqXHR = jqXHR;
  4549. this._dataRetrieved = true;
  4550. if (this.dataManipulationCallback) {
  4551. this.dataManipulationCallback(data, this.sortIndexes);
  4552. }
  4553. if (this.rowLimit) {
  4554. if (this.ajaxProp && data[this.ajaxProp].length > this.rowLimit) {
  4555. data[this.ajaxProp] = data[this.ajaxProp].slice(0, this.rowLimit);
  4556. } else if (data.length > this.rowLimit) {
  4557. data = data.slice(0, this.rowLimit);
  4558. }
  4559. }
  4560. fnCallback(data);
  4561. this._dataRendered = true;
  4562. // Stops text selection when the user does shift+click in the table in IE11
  4563. $(oSettings.nTable).bind('selectstart', function(element) {
  4564. return $(element.target).is(':text');
  4565. });
  4566. }.bind(this);
  4567. if (this.getData) {
  4568. // Leaving for now to be backwards compatible
  4569. this.getData(options)
  4570. .done(function(data, textStatus, jqXHR) {
  4571. handleResponse(data, jqXHR);
  4572. })
  4573. .fail(function(jqXHR) {
  4574. oSettings.jqXHR = jqXHR;
  4575. deferred.reject(jqXHR);
  4576. }.bind(this));
  4577. } else {
  4578. this.glassContext.getCoreSvc('.Ajax').ajax(options)
  4579. .then(function(response) {
  4580. handleResponse(response.data, response.jqXHR);
  4581. })
  4582. .catch(function(err) {
  4583. oSettings.jqXHR = err.jqXHR;
  4584. deferred.reject(err);
  4585. }.bind(this));
  4586. }
  4587. }.bind(this),
  4588. 'preDrawCallback': function(oSettings) {
  4589. this._preDrawCallback(oSettings);
  4590. }.bind(this),
  4591. 'drawCallback': function(oSettings) {
  4592. this._drawCallback(oSettings);
  4593. }.bind(this),
  4594. 'createdRow': this.createdRowCallback || function(row, data, index) {
  4595. void(index);
  4596. if (this.selectedRow && data[this.selectedRow[0]] === this.selectedRow[1]) {
  4597. this._selectRow(row);
  4598. this.selectedRow = null;
  4599. }
  4600. //Restore selection if we allow selection across folders
  4601. if (this.selectAcrossFolders && this._previousSelections) {
  4602. if (this._previousSelections[data.id]) {
  4603. this._updateSizeForSelection();
  4604. $(row).addClass('selected');
  4605. this._toggleCheckBox(row, true);
  4606. this.aSelectedRows.push(row);
  4607. this._lastShiftSelectedRow = row;
  4608. }
  4609. }
  4610. $(row).attr('data-name', data.defaultName);
  4611. }.bind(this)
  4612. };
  4613. var options = _.extend(datatableSettings, this.dataTableOptions);
  4614. this._dTable = $('#' + this._id).dataTable(options);
  4615. // We call the internal _fnDraw as fnDraw does a sort, and it makes resizing very slow. All we need is a draw as we are in resize()
  4616. if (!this.debouncedDraw) {
  4617. this.debouncedDraw = _.debounce(function() {
  4618. //_cancelRedraw is a flag to indicate if this debounce should go or not
  4619. // we set it to false on remove() because underscore doesn't have a way to cancel a debounce. (lodash does, btw).
  4620. if (this._cancelDebounce !== true) {
  4621. this._dTable._fnDraw();
  4622. }
  4623. }.bind(this), this.debounceRate);
  4624. }
  4625. return deferred.promise;
  4626. },
  4627. _fnInitComplete: function(oSettings) {
  4628. this.isInitialized = true;
  4629. this._scrollNode = this.$el.find('.dataTables_scrollBody');
  4630. if (this.filterByTypes) {
  4631. this._filterInfo = {
  4632. 'filterValue': this.filterByTypes,
  4633. 'column': this.filterColumnIndex,
  4634. 'regExpression': true
  4635. };
  4636. this._dTable.fnFilter(this.filterByTypes, this.filterColumnIndex, true);
  4637. }
  4638. if (this.disableColumnHeaders) {
  4639. $(oSettings.nScrollHead).remove();
  4640. }
  4641. var tabEl = $(oSettings.nScrollHead).find('table');
  4642. var lab = tabEl.attr('aria-label');
  4643. tabEl.removeAttr('aria-label');
  4644. tabEl.attr('aria-labelledby', this._id + '_tableHeaderLab1 ' + this._id + '_tableHeaderLab2');
  4645. var hiddenDiv1 = $('<div style="position: absolute; left: -999px" aria-hidden="true" id="' + this._id + '_tableHeaderLab1"></div>');
  4646. hiddenDiv1.text(lab);
  4647. var hiddenDiv2 = $('<div style="position: absolute; left: -999px" aria-hidden="true" id="' + this._id + '_tableHeaderLab2">' + StringResource.get('listControlColumns') + '</div>');
  4648. tabEl.parent().append(hiddenDiv1);
  4649. tabEl.parent().append(hiddenDiv2);
  4650. //If the last column is the properties column, add the ability to specially handle the 2nd last column
  4651. if (this.propertiesSpacing && oSettings.aoColumns[oSettings.aoColumns.length - 1].sName === 'properties') {
  4652. oSettings.aoColumns[oSettings.aoColumns.length - 2].weight = null;
  4653. oSettings.aoColumns[oSettings.aoColumns.length - 2].sWidth = this.propertiesSpacing;
  4654. }
  4655. this._handleColumnCallbacks(oSettings);
  4656. this._processColumnWeights(oSettings);
  4657. this.resize();
  4658. if (!this.browserResize) {
  4659. this._drawCallback(oSettings);
  4660. }
  4661. var scrollToPos = 0;
  4662. if (this.aSelectedRows && this.aSelectedRows.length > 0) {
  4663. scrollToPos = $(this.aSelectedRows[0]).offset().top - (this._scrollNode.height() / 2);
  4664. }
  4665. this._scrollNode.scrollTop(scrollToPos);
  4666. this._scrollNode.bind('scroll', this._onScroll.bind(this));
  4667. this._initRenderedRowCount();
  4668. this._updateLoadingMoreDiv();
  4669. },
  4670. getScrollingNode: function() {
  4671. return this._scrollNode;
  4672. },
  4673. setRenderRowsOnScroll: function(bValue) {
  4674. this._renderRowsOnScroll = bValue;
  4675. },
  4676. _onScroll: function(event) {
  4677. if (!this.isInitialized || !this._dataRetrieved || !this._dataRendered) {
  4678. return;
  4679. }
  4680. var $target = $(event.target);
  4681. // If we've scrolled to the bottom
  4682. if (this._renderRowsOnScroll && ($target.scrollTop() + $target.innerHeight()) >= ($target[0].scrollHeight - 20)) {
  4683. this._handleReRender();
  4684. }
  4685. //RTC#202962 hide contextmenu when scrolling
  4686. Menu.hideOpenMenus();
  4687. },
  4688. /**
  4689. Will load more rows into the datatable. This is done by rendering a dummy listControl off the screen
  4690. and moving its TR elements over to the main listControl
  4691. @startIndex - the starting index in the list data of the row to render
  4692. @count - how many rows starting from the 'startIndex' to render
  4693. **/
  4694. _renderExtraRows: function(startIndex, count) {
  4695. // Build a div off the screen to contain the listControl
  4696. var $listControlContainer = $('<div></div>');
  4697. // Need to set it's width to match the current listControls width so that the ellipses get processed correctly
  4698. $listControlContainer.css('width', this._scrollNode.width() + 'px');
  4699. $listControlContainer.css('position', 'absolute');
  4700. $listControlContainer.css('left', '-1000px');
  4701. $listControlContainer.css('height', '0px');
  4702. $listControlContainer.css('overflow', 'hidden');
  4703. $(document.body).append($listControlContainer);
  4704. var rowInfoToRender = this._getRowInfoToRender(startIndex, count);
  4705. // Nothing left to display
  4706. if (rowInfoToRender.length === 0) {
  4707. // Hide the loading animation container
  4708. this._scrollNode.find('.listControlLoadingMore').css('display', 'none');
  4709. return Promise.resolve();
  4710. }
  4711. // Build the options for the dummy listControl
  4712. var options = _.extend({}, this._initialOptions, {
  4713. 'el': $listControlContainer[0],
  4714. '$el': $listControlContainer,
  4715. // our data is already sorted
  4716. 'sort': false,
  4717. // no need to have any resize callbacks going for the hidden list control
  4718. 'resizeCallback': null,
  4719. 'getJSONDataCallback': function(rowInfoToRender) {
  4720. // Return the rows that should get rendered by the dummy listControl
  4721. var deferred = $.Deferred();
  4722. var response = {};
  4723. if (this.ajaxProp) {
  4724. response[this.ajaxProp] = rowInfoToRender.aData;
  4725. } else {
  4726. response = rowInfoToRender.aData;
  4727. }
  4728. // this call seems to rely on $ deferred's sync nature
  4729. deferred.resolve(response);
  4730. return deferred.promise();
  4731. }.bind(this, rowInfoToRender)
  4732. });
  4733. var listControl = new ListControl(options);
  4734. // renderExtraRows creates a new instance of listControl, needs to keep the selectedData and selectedRows in sync
  4735. listControl.oSelectedData = this.oSelectedData;
  4736. listControl.aSelectedRows = this.aSelectedRows;
  4737. return listControl.render().then(function() {
  4738. // Get all the TRs that were rendered
  4739. var nTRs = $listControlContainer.find('.dataTables_scrollBody').find('tbody').find('tr');
  4740. // Append the rendered TRs to our table
  4741. this._scrollNode.find('tbody').append(nTRs);
  4742. $listControlContainer.remove();
  4743. var oSettings = this._dTable.fnSettings();
  4744. // Some badness to get our datatable to know about the TRs we've just added
  4745. nTRs.each(function(index, nTr) {
  4746. // This is the index of datatables internal map. Maps data to the index of the TR in the table
  4747. var dataIndex = rowInfoToRender.aIndexMappding ? rowInfoToRender.aIndexMappding[index] : startIndex + index;
  4748. var rowMapIndex = this._dTable.api().rows()[0][dataIndex];
  4749. if (rowMapIndex >= 0) {
  4750. // Fix the _DT_RowIndex property found on the TR
  4751. nTr._DT_RowIndex = rowMapIndex;
  4752. // Fix the internal aoData to know about the TR we inserted
  4753. oSettings.aoData[rowMapIndex].nTr = nTr;
  4754. oSettings.aoData[rowMapIndex].anCells = nTr.cells;
  4755. this._formatRowsContent(oSettings.aoColumns,[oSettings.aoData[rowMapIndex]]);
  4756. }
  4757. }.bind(this));
  4758. this._groupByColumnCallback(startIndex);
  4759. return nTRs;
  4760. }.bind(this));
  4761. },
  4762. /**
  4763. Format rows based on column specification
  4764. @param aoColumns - array of columns
  4765. @param aData - array of rows (data) to format
  4766. **/
  4767. _formatRowsContent: function(aoColumns,aoData){
  4768. aoColumns.forEach(function(column,index){
  4769. aoData.forEach(function(rowData){
  4770. this._formatContent(rowData,column,index);
  4771. }.bind(this));
  4772. }.bind(this));
  4773. },
  4774. /**
  4775. Format one row data based on column specification
  4776. @param rowData - a row data
  4777. @param columnMeta - current column's specification
  4778. @param col - current column
  4779. **/
  4780. _formatContent : function(rowData,columnMeta,col) {
  4781. if (rowData.anCells && rowData.anCells[col]){
  4782. if (columnMeta.formatContent) {
  4783. columnMeta.formatContent(rowData.anCells[col]);
  4784. }
  4785. var $cell = $(rowData.anCells[col]);
  4786. var scope = columnMeta.scope;
  4787. if (scope === 'row') {
  4788. $cell.attr('role', 'rowheader');
  4789. } else {
  4790. $cell.attr('role', 'gridcell');
  4791. }
  4792. $cell.attr('tabindex', '-1');
  4793. }
  4794. },
  4795. /**
  4796. Return row data, only rows that should be displayed (not filtered out) will be returned
  4797. **/
  4798. _getRowInfoToRender: function(startIndex, count) {
  4799. // If we're not filtering, simply return the next section of data to render
  4800. if (!this._filterInfo) {
  4801. this._renderedRowCount = startIndex + count;
  4802. return {
  4803. 'aData': this._dTable.api().rows().data().splice(startIndex, count)
  4804. };
  4805. } else {
  4806. var aData = [];
  4807. var aIndexMappding = [];
  4808. var tableApi = this._dTable.api();
  4809. var data = tableApi.rows().data();
  4810. var dataIndex = startIndex;
  4811. var isFiltered;
  4812. // This is data of the column used for filtering. Usually this will be an array of 'types', 1 entry for each row
  4813. var aColumnDataToFilter = tableApi.column(this._filterInfo.column).data();
  4814. // If we're filtering using a regex
  4815. if (this._filterInfo.regExpression) {
  4816. var regex = new RegExp(this._filterInfo.filterValue);
  4817. isFiltered = function(rowIndex) {
  4818. return !regex.test(aColumnDataToFilter[rowIndex]);
  4819. }.bind(this);
  4820. } else {
  4821. // No regex, do a simple compare
  4822. isFiltered = function(rowIndex) {
  4823. return this._filterInfo.filterValue !== aColumnDataToFilter[rowIndex];
  4824. }.bind(this);
  4825. }
  4826. // Loops through the data until we've gotten enough rows to render or we've hit the end of the data
  4827. while (aData.length < count && dataIndex < data.length) {
  4828. if (!isFiltered(dataIndex)) {
  4829. aData.push(data[dataIndex]);
  4830. aIndexMappding.push([dataIndex]);
  4831. }
  4832. dataIndex = dataIndex + 1;
  4833. }
  4834. this._renderedRowCount = dataIndex;
  4835. return {
  4836. 'aData': aData,
  4837. 'aIndexMappding': aIndexMappding
  4838. };
  4839. }
  4840. },
  4841. /**
  4842. Add data to the internal data object of the datatable
  4843. @param aData - array of objects (data) to add
  4844. @param forceRowRender {boolean}
  4845. **/
  4846. addRowData: function(aData, forceRowRender) {
  4847. var tableApi = this._dTable.api();
  4848. var newRows = tableApi.rows.add(aData).draw(false);
  4849. if (forceRowRender) {
  4850. var aPromises = [];
  4851. var mapping = tableApi.row()[0];
  4852. var newRowIndexes = newRows[0];
  4853. newRowIndexes.forEach(function(rowIndex) {
  4854. aPromises.push(new Promise(function(resolve) {
  4855. var row = tableApi.row(rowIndex);
  4856. // If there are already 40 or more rows rendered (initial render is 40), then the TR
  4857. // will not get rendered automatically since we need to render it ourselves.
  4858. if (!row.node()) {
  4859. // Find the index of the data we just added using datatables internal map
  4860. for (var dataIndex = 0; dataIndex < mapping.length; dataIndex = dataIndex + 1) {
  4861. if (mapping[dataIndex] === rowIndex) {
  4862. break;
  4863. }
  4864. }
  4865. // Render the row
  4866. this._renderExtraRows(dataIndex, 1).then(function(nTRs) {
  4867. resolve(nTRs[0]);
  4868. });
  4869. } else {
  4870. resolve(row.node());
  4871. }
  4872. }.bind(this)));
  4873. }.bind(this));
  4874. return Promise.all(aPromises).then(function(nTRs) {
  4875. return nTRs;
  4876. });
  4877. }
  4878. },
  4879. /**
  4880. If we should show the working icon instead of the bee when there's an empty table
  4881. **/
  4882. setShowWorking: function(showWorking) {
  4883. this._showWorking = showWorking;
  4884. },
  4885. _isShortTable: function() {
  4886. var listContainer = this.$el.find('#listContainer' + this._id);
  4887. return listContainer.height() < 200;
  4888. },
  4889. /**
  4890. Show the working icon in the empty table
  4891. **/
  4892. showWorking: function() {
  4893. if (this._isShowingWorking) {
  4894. return;
  4895. }
  4896. this.removeEmptyTableMessage();
  4897. var listContainer = this.$el.find('#listContainer' + this._id);
  4898. var sHtml = dot.template(emptyListTemplate)({
  4899. 'text': '',
  4900. 'shortTable': this._isShortTable(),
  4901. 'isSpinner': true,
  4902. 'iconStyle': 'contentLoadingSpinner',
  4903. 'emptyIcon': '#ba_content_nav-load'
  4904. });
  4905. listContainer.append(sHtml).hide().fadeIn(300);
  4906. this._isShowingWorking = true;
  4907. },
  4908. /**
  4909. Show the empty table graphic
  4910. **/
  4911. showEmptyTableMessage: function() {
  4912. if (this._isShowingEmptyMessage) {
  4913. return;
  4914. }
  4915. this.removeEmptyTableMessage();
  4916. var listContainer = this.$el.find('#listContainer' + this._id);
  4917. var sHtml = dot.template(emptyListTemplate)({
  4918. 'text': this.emptyFolderString,
  4919. 'textParagraph': this.emptyParagraphString,
  4920. 'shortTable': this._isShortTable(),
  4921. 'emptyIcon': this._emptyIcon
  4922. });
  4923. listContainer.append(sHtml);
  4924. var svg = listContainer.find('.svgIcon');
  4925. var use = listContainer.find('use');
  4926. use.remove();
  4927. if (this._emptyIcon === '#ba_content_nav-search_64') {
  4928. Utils.setIcon(svg, emptySearch_128.default.id);
  4929. } else if (this._emptyIcon === '#ba_content_nav-time_64') {
  4930. Utils.setIcon(svg, emptyRecents_128.default.id);
  4931. } else {
  4932. Utils.setIcon(svg, emptyFolder_128.default.id);
  4933. }
  4934. this._isShowingEmptyMessage = true;
  4935. },
  4936. removeEmptyTableMessage: function() {
  4937. if (this._isShowingWorking || this._isShowingEmptyMessage) {
  4938. this.$el.find('.emptyTableContent').remove();
  4939. this._isShowingEmptyMessage = false;
  4940. this._isShowingWorking = false;
  4941. }
  4942. if (this.spinnerTimeout) {
  4943. clearTimeout(this.spinnerTimeout);
  4944. this.spinnerTimeout = null;
  4945. }
  4946. },
  4947. /**
  4948. Show the empty table graphic
  4949. **/
  4950. showEmptyFilterMessage: function() {
  4951. if (this._isShowingEmptyMessage) {
  4952. return;
  4953. }
  4954. this.removeEmptyTableMessage();
  4955. var listContainer = this.$el.find('#listContainer' + this._id);
  4956. var sHtml = dot.template(emptyListTemplate)({
  4957. 'text': StringResource.get('noFilterResult'),
  4958. 'textParagraph': StringResource.get('tryOtherFilter'),
  4959. 'shortTable': this._isShortTable(),
  4960. 'emptyIcon': this._emptyIcon
  4961. });
  4962. listContainer.append(sHtml);
  4963. this._isShowingEmptyMessage = true;
  4964. },
  4965. _preDrawCallback: function(oSettings) {
  4966. void(oSettings);
  4967. if (this.getScrollingNode()) {
  4968. this._scrollTop = this.getScrollingNode().scrollTop();
  4969. }
  4970. this._ancestors = this.contentView.getAncestors && this.contentView.getAncestors();
  4971. //Parse the selection to restore visual selection to selected items
  4972. this._previousSelections = null;
  4973. if (this.selectAcrossFolders && this._ancestors && this._ancestors.length) {
  4974. var parentId = this._ancestors[this._ancestors.length-1].id;
  4975. if (this.oSelectedData[parentId] && this.oSelectedData[parentId].length) {
  4976. var selection = this.oSelectedData[parentId];
  4977. this._previousSelections = {};
  4978. for (var i=0; i<selection.length; i++) {
  4979. this._previousSelections[selection[i].id] = true;
  4980. }
  4981. }
  4982. }
  4983. },
  4984. _drawCallback: function(oSettings) {
  4985. if (this.getScrollingNode() && this._scrollTop !== null) {
  4986. var height = this.getScrollingNode().height();
  4987. if (this._scrollTop >= height) {
  4988. this._scrollTop = 0;
  4989. }
  4990. this.getScrollingNode().scrollTop(this._scrollTop);
  4991. this._scrollTop = null;
  4992. }
  4993. if (this.isInitialized && this._dataRetrieved) {
  4994. // If there is no data, first try to set a spinner while we wait for the data
  4995. if (oSettings.aoData.length === 0) {
  4996. if (this._showWorking) {
  4997. this.setShowWorking(false); // Don't execute this the second time around
  4998. window.clearTimeout(this.spinnerTimeout);
  4999. this.spinnerTimeout = window.setTimeout(this.showWorking.bind(this), 1000); // Start showing spinner after 1s
  5000. } else {
  5001. // After trying to show the spinner and wait, we still returned with nothing. Show empty list
  5002. this.showEmptyTableMessage();
  5003. // Just in case - remove the timeout so it is not called after this
  5004. clearTimeout(this.spinnerTimeout);
  5005. this.spinnerTimeout = null;
  5006. }
  5007. } else if (oSettings.aoData.length > 0) {
  5008. if (oSettings.fnRecordsDisplay() === 0){
  5009. this.showEmptyFilterMessage();
  5010. }else{
  5011. this.removeEmptyTableMessage();
  5012. }
  5013. }
  5014. this._groupByColumnCallback(0);
  5015. //Each column can have a function fnDrawCallback(nTd) which will be called when the table fnDrawCallback is drawn
  5016. this._formatRowsContent(oSettings.aoColumns,oSettings.aoData);
  5017. this._initRenderedRowCount();
  5018. // Make sure we reset the scrolling properties since we've just redrawn the datatable
  5019. this.setRenderRowsOnScroll(true);
  5020. this._updateLoadingMoreDiv();
  5021. if (this.widgetKeyController) {
  5022. this.widgetKeyController.setInitialTabIndex();
  5023. if (this.setFocusOnDraw) {
  5024. this.setFocus();
  5025. }
  5026. }
  5027. }
  5028. },
  5029. _createRowGroupHeader: function(group, firstGroup) {
  5030. var groupName = group;
  5031. if (this._groupByColumnAPI.getGroupName) {
  5032. groupName = this._groupByColumnAPI.getGroupName(group);
  5033. }
  5034. var groupHeader = '<tr class="group';
  5035. if ( firstGroup ){
  5036. groupHeader += ' firstGroup';
  5037. }
  5038. groupHeader += '"><td><span aria-label="' + groupName + '">'+ groupName +'</span></td><td class="contentListFocusable"></td><td class="contentListFocusable"></td></tr>';
  5039. return groupHeader;
  5040. },
  5041. /*
  5042. * Create row group headers
  5043. * @startIndex - optional, the index to start creating row groups
  5044. */
  5045. _groupByColumnCallback: function(startIndex) {
  5046. if ( this._groupByColumnAPI ){
  5047. if ( startIndex === undefined ) {
  5048. startIndex = 0;
  5049. }
  5050. var tableApi = this._dTable.api();
  5051. if ( this._groupByColumnAPI.shouldGroup(tableApi) ) {
  5052. var rows = tableApi.rows().nodes();
  5053. var columnData = tableApi.column(this._groupByColumnAPI.columnIndex).data();
  5054. var last;
  5055. if ( startIndex !== 0 ) {
  5056. last = columnData[startIndex-1];
  5057. } else {
  5058. last = null;
  5059. }
  5060. var isFiltered = null;
  5061. if (this._filterInfo) {
  5062. var aColumnDataToFilter = tableApi.column(this._filterInfo.column).data();
  5063. if (this._filterInfo.regExpression) {
  5064. var regex = new RegExp(this._filterInfo.filterValue);
  5065. isFiltered = function(i) {
  5066. return !regex.test(aColumnDataToFilter[i]);
  5067. }.bind(this);
  5068. }
  5069. }
  5070. columnData.each( function (group, i) {
  5071. if ( i>=startIndex && last !== group ) {
  5072. if (!isFiltered || !isFiltered(i)) {
  5073. // Add group title when no Filter defined or the first non filtered row found
  5074. var groupHeader = this._createRowGroupHeader(group, i===0);
  5075. $(rows).eq(i).before(groupHeader);
  5076. last = group;
  5077. }
  5078. }
  5079. }.bind(this));
  5080. this.$el.find('.dataTables_scrollBody').css('min-height', this._calcYBound() + 'px');
  5081. }
  5082. }
  5083. },
  5084. _initRenderedRowCount: function() {
  5085. this._renderedRowCount = this._showLoadBuffer;
  5086. // If we're filtering we don't really know the index of the last drawn data row. Figure it out.
  5087. if (this._filterInfo) {
  5088. var nLastTR = this._scrollNode.find('tr:last');
  5089. var _DT_RowIndex = nLastTR[0]._DT_RowIndex;
  5090. var rowMapIndex = this._dTable.api().rows()[0];
  5091. for (var dataIndex = 0; dataIndex < rowMapIndex.length; dataIndex += 1) {
  5092. if (rowMapIndex[dataIndex] === _DT_RowIndex) {
  5093. this._renderedRowCount = dataIndex + 1;
  5094. break;
  5095. }
  5096. }
  5097. }
  5098. },
  5099. _hasVerticalScrollbar: function() {
  5100. return this._scrollNode && this._scrollNode[0] && this._scrollNode[0].scrollHeight > this._scrollNode[0].clientHeight;
  5101. },
  5102. _updateLoadingMoreDiv: function() {
  5103. if (!this._scrollNode) {
  5104. this._scrollNode = this.$el.find('.dataTables_scrollBody');
  5105. }
  5106. // Hide the fetch more data animation, we don't want it to be the cause of a scrollbar
  5107. if (this._$loadingAnimationContainer) {
  5108. this._$loadingAnimationContainer.css('display', 'none');
  5109. }
  5110. // If we have a vertical scrollbar, add in the fetch more data animation
  5111. if (this._hasVerticalScrollbar() && this._dTable.fnGetData().length > this._showLoadBuffer) {
  5112. if (!this._$loadingAnimationContainer) {
  5113. var loadingAnimation = Utils.getLoadingAnimation(1);
  5114. this._$loadingAnimationContainer = $('<div class="listControlLoadingMore"></div>', {
  5115. 'class': 'listControlLoadingMore'
  5116. });
  5117. $(loadingAnimation).addClass('loadingAnimation');
  5118. this._$loadingAnimationContainer.append(loadingAnimation);
  5119. this._scrollNode.append(this._$loadingAnimationContainer);
  5120. }
  5121. this._$loadingAnimationContainer.css('display', 'block');
  5122. }
  5123. },
  5124. /**
  5125. Updates the content of the datatable with an optional URL for new data
  5126. **/
  5127. updateDatatable: function(url) {
  5128. if (!this._dTable) return;
  5129. if (url) {
  5130. this._dTable.fnSettings().sAjaxSource = url;
  5131. this.url = url;
  5132. // clear multi-selected rows and buttons/counters for touch devices when launching a new view
  5133. this._clearRows();
  5134. // Scroll back to the top on url change
  5135. if (this.getScrollingNode()) {
  5136. this.getScrollingNode().scrollTop(0);
  5137. }
  5138. // When there is a new url, there is a potential need to show loading content - set to true to show spinner
  5139. this.setShowWorking(true);
  5140. // Clear the table so the user cannot click on the same row before the refresh.
  5141. this._dTable.fnClearTable();
  5142. }
  5143. this._dataRetrieved = false;
  5144. this._dataRendered = false;
  5145. this._dTable.api().ajax.reload();
  5146. this._dTable.fnDraw();
  5147. this._clearRows();
  5148. this.setInStandbyMode(false);
  5149. this.setShowWorking(false);
  5150. },
  5151. updateCell: function(colData, row, colIndex) {
  5152. var table = this._dTable;
  5153. table.fnUpdate(colData, row, colIndex);
  5154. var $tdEl = $($(row).find('td')[colIndex]);
  5155. table.fnSettings().aoColumns[colIndex].fnCreatedCell($tdEl, table.fnGetData($tdEl.get(0)), colData);
  5156. },
  5157. getDatatable: function() {
  5158. return this._dTable;
  5159. },
  5160. /**
  5161. Call to remove the list control from the DOM and disconnect any events
  5162. **/
  5163. remove: function() {
  5164. if (this._addFolderAction) {
  5165. this._addFolderAction.destroy();
  5166. }
  5167. // remove ourselves from the listControls object so that the resize event not longer gets fired
  5168. listControls[this._id] = null;
  5169. delete listControls[this._id];
  5170. if (this._dTable) {
  5171. this._cancelDebounce = true;
  5172. this._dTable.api().destroy(true);
  5173. this._dTable.remove();
  5174. }
  5175. this.$el.find('.ca-listContainer').remove();
  5176. },
  5177. /**
  5178. Returns an array of the selected rows (tr's)
  5179. **/
  5180. getSelectedRows: function() {
  5181. return this.aSelectedRows || [];
  5182. },
  5183. /**
  5184. Returns an array of objects that are being represented by the selected rows
  5185. **/
  5186. getSelectedObjects: function() {
  5187. var i;
  5188. var rowObjects = [];
  5189. for (i = 0; i < this.aSelectedRows.length; i += 1) {
  5190. var obj = this.getRowData(this.aSelectedRows[i]);
  5191. if (obj) {
  5192. rowObjects.push(obj);
  5193. } else {
  5194. // this can happen if, for example, a user has clicked on a grouping label
  5195. this.logger.error(new Error('Selection was not found in the datatable: ' + this.aSelectedRows[i]));
  5196. }
  5197. }
  5198. return rowObjects;
  5199. },
  5200. getRowData: function(trNode) {
  5201. var obj = this._dTable.fnGetData(trNode);
  5202. // Augment the object information with ancestor info if it doesn't already have it
  5203. if (obj) {
  5204. if (!obj[ContentStoreObject.ANCESTORS] && this._ancestors && this._ancestors.length > 0) {
  5205. obj[ContentStoreObject.ANCESTORS] = this._ancestors.slice();
  5206. }
  5207. }
  5208. return obj;
  5209. },
  5210. /**
  5211. * Get an array of objects destined for the public API
  5212. * @returns {Object} Where the type, name and id are publicly available
  5213. */
  5214. getPublicSelectedObjects: function(selectedObjects) {
  5215. return $.map(selectedObjects, function(obj) {
  5216. return {
  5217. type: obj.type,
  5218. name: obj.defaultName,
  5219. id: obj.id
  5220. };
  5221. });
  5222. },
  5223. /**
  5224. Returns an object represented by the selected row
  5225. If necessary, object is augmented with the permissions data
  5226. **/
  5227. getSelectedObjectWPermissions: function(selectedObjects) {
  5228. if (!selectedObjects) {
  5229. selectedObjects = this.getSelectedObjects();
  5230. }
  5231. if (selectedObjects.length === 1) {
  5232. if (selectedObjects[0].type === 'report') {
  5233. return ContentStoreObject.getPermissionsOwnerIdAndMetadataModelPackageEffectiveUserCapabilities(selectedObjects[0], true).then(function(selected, data) {
  5234. selected[0][ContentStoreObject.PERMISSIONS] = data.permissions;
  5235. selected[0][ContentStoreObject.OWNER] = data.owner;
  5236. selected[0][ContentStoreObject.METADATA_MODEL_PACKAGE] = data.metadataModelPackage;
  5237. return Promise.resolve(selected);
  5238. }.bind(this, selectedObjects));
  5239. } else if (selectedObjects[0].type === 'reportView') {
  5240. return ContentStoreObject.getPermissionsOwnerIdAndBasePermissions(selectedObjects[0], true, true).then(function(selected, data) {
  5241. selected[0][ContentStoreObject.PERMISSIONS] = data.permissions;
  5242. selected[0][ContentStoreObject.OWNER] = data.owner;
  5243. selected[0][ContentStoreObject.BASE] = data.base;
  5244. return Promise.resolve(selected);
  5245. }.bind(this, selectedObjects));
  5246. } else {
  5247. return ContentStoreObject.getPermissionsOwnerIdAndCapabilities(selectedObjects[0], true).then(function(selected, data) {
  5248. selected[0][ContentStoreObject.PERMISSIONS] = data.permissions;
  5249. selected[0][ContentStoreObject.OWNER] = data.owner;
  5250. selected[0][ContentStoreObject.EFFECTIVE_USER_CAPABILITIES] = data.effectiveUserCapabilities;
  5251. return Promise.resolve(selected);
  5252. }.bind(this, selectedObjects));
  5253. }
  5254. } else {
  5255. return Promise.resolve(selectedObjects);
  5256. }
  5257. },
  5258. checkSetVersionsSupported: function(selectedObjects) {
  5259. for (var i = 0; i < selectedObjects.length; i = i + 1) {
  5260. // we will show page for versions all the time, a hack so we can access archives even if there are no versions
  5261. if (!_.isBoolean(selectedObjects[i].versionsSupported)) {
  5262. selectedObjects[i].versionsSupported = UIHelper.isVersionsSupported(selectedObjects[i]);
  5263. }
  5264. }
  5265. return Promise.resolve(selectedObjects);
  5266. },
  5267. /**
  5268. Loops through the selected rows and removes them from the datatable
  5269. **/
  5270. removeSelectedRows: function() {
  5271. if (this.aSelectedRows) {
  5272. while (this.aSelectedRows.length > 0) {
  5273. this.removeRow(this.aSelectedRows.pop());
  5274. }
  5275. this._updateSelectedData();
  5276. this._updateRowsCounter();
  5277. this._hideMultiSelectBar();
  5278. }
  5279. },
  5280. /**
  5281. Adds a row to the datatable
  5282. **/
  5283. addFolder: function() {
  5284. this._clearRows();
  5285. this._addFolderAction = new AddFolderAction({
  5286. 'oListControl': this
  5287. });
  5288. return this._addFolderAction.execute();
  5289. },
  5290. /**
  5291. Cancels any current actions ('addFolder' for eample)
  5292. */
  5293. cancelActions: function() {
  5294. if (this._addFolderAction) {
  5295. this._addFolderAction.cancel();
  5296. }
  5297. },
  5298. /**
  5299. Removes a row from the datatable
  5300. @param $tr - jquery node for the table row that is being removed from the DataTable
  5301. **/
  5302. removeRow: function($tr) {
  5303. if (this._scrollNode.scrollTop() !== 0) {
  5304. this._scrollNode.scrollTop(0); // scroll to top so we don't trigger scrolling events
  5305. }
  5306. this._dTable.fnDeleteRow($tr);
  5307. },
  5308. /**
  5309. Removes all the rows that are represented by objects
  5310. @param rowsToDelete - a collection of numbers noting the index of the rows to delete
  5311. **/
  5312. removeIndexRows: function(rowsToDelete) {
  5313. var rows = this.$el.find('tbody tr');
  5314. rowsToDelete.forEach(function(anIndex) {
  5315. this.removeRow(rows[anIndex]);
  5316. }.bind(this));
  5317. },
  5318. /**
  5319. Calculates the available room for the data table
  5320. **/
  5321. _calcYBound: function() {
  5322. var containerHeight = this.$container ? (this.$container.height() - 40) : this.$el.height();
  5323. var headerHeight = this.$el.find('.dataTables_scrollHead').outerHeight(true) || 0;
  5324. // Get the height of all the other elements in our pageView that aren't the actual data table
  5325. var nonTableHeight;
  5326. nonTableHeight = this.$el.children(':not(.dataTables_wrapper, .contentViewSwitcher, .ca-listContainer)').outerHeight(true);
  5327. if (!nonTableHeight) {
  5328. nonTableHeight = 0;
  5329. }
  5330. nonTableHeight += this._calcExtraNonTableHeight ? this._calcExtraNonTableHeight(this) : 0;
  5331. if (this.$container) {
  5332. var descendantNode = this.$el[0];
  5333. var $currentNode = this.$el.parent();
  5334. while ($currentNode[0] && $currentNode[0] !== this.$container.parent()[0]) {
  5335. var children = $currentNode.children();
  5336. for (var i = 0; i < children.length; i = i + 1) {
  5337. var child = children[i];
  5338. if (child !== descendantNode) {
  5339. nonTableHeight += $(child).outerHeight(true);
  5340. }
  5341. }
  5342. descendantNode = $currentNode[0];
  5343. $currentNode = $currentNode.parent();
  5344. }
  5345. }
  5346. var newHeight = containerHeight - headerHeight - nonTableHeight;
  5347. if (this.minHeight && newHeight < this.minHeight) {
  5348. newHeight = this.minHeight;
  5349. }
  5350. return newHeight;
  5351. },
  5352. /**
  5353. Called on browser resize to resize the datatable
  5354. **/
  5355. resize: function() {
  5356. if (!this.browserResize) {
  5357. return;
  5358. }
  5359. var oSettings = this._dTable && this._dTable.fnSettings && this._dTable.fnSettings();
  5360. if (oSettings) {
  5361. oSettings.oScroll.sY = this._calcYBound() + 'px';
  5362. oSettings.oScroll.sX = this.$el.width() + 'px';
  5363. oSettings.oScroll.sXInner = (this.$el.width() < this.minWidth) ? this.minWidth + 'px' : '100%';
  5364. this.debouncedDraw && this.debouncedDraw();
  5365. this.$el.find('.dataTables_scrollBody').css('max-height', oSettings.oScroll.sY);
  5366. }
  5367. if (this.resizeCallback) {
  5368. this.resizeCallback();
  5369. }
  5370. },
  5371. /**
  5372. Filter on column with value
  5373. @filterValue {string} - the filter to be applied
  5374. @column {int} - the column to apply the filter to
  5375. @regExpression {boolean} - is the @filterValue a regular expression
  5376. **/
  5377. filter: function(filterValue, column, regExpression) {
  5378. // We don't want to trigger adding more rows from scrolling events while we filter.
  5379. this.setRenderRowsOnScroll(false);
  5380. this._filterInfo = {
  5381. 'filterValue': filterValue,
  5382. 'column': column,
  5383. 'regExpression': regExpression
  5384. };
  5385. this._dTable.fnFilter(filterValue, column, regExpression);
  5386. this._dTable.fnDraw(false);
  5387. },
  5388. /**
  5389. Uses weights to properly assign percent widths to columns that need them
  5390. Assigns percentages based on the unused percent of the space available
  5391. **/
  5392. _processColumnWeights: function(oSettings) {
  5393. var weightSum = 0;
  5394. var percentSum = 0;
  5395. oSettings.aoColumns.forEach(function(column) {
  5396. if (column.weight) {
  5397. weightSum += column.weight;
  5398. } else if (column.sWidth && column.sWidth.slice(-1) === '%') {
  5399. percentSum += parseInt(column.sWidth.slice(0, -1), 10);
  5400. }
  5401. });
  5402. oSettings.aoColumns.forEach(function(column) {
  5403. if (column.weight) {
  5404. column.sWidth = Math.floor(column.weight / weightSum * (100 - percentSum)) + '%';
  5405. }
  5406. });
  5407. },
  5408. /**
  5409. Executes arbitrary callbacks on each row in a column if the column defines the postprocessRowCallback function
  5410. **/
  5411. _handleColumnCallbacks: function(oSettings) {
  5412. var i;
  5413. function postProcessHelper(row) {
  5414. oSettings.aoColumns[i].postprocessRowCallback(row, i);
  5415. }
  5416. for (i = 0; i < oSettings.aoColumns.length; i += 1) {
  5417. if (oSettings.aoColumns[i].postprocessRowCallback) {
  5418. oSettings.aoData.forEach(postProcessHelper);
  5419. }
  5420. }
  5421. },
  5422. setInStandbyMode: function(inStandbyMode) {
  5423. this._inStandbyMode = inStandbyMode;
  5424. },
  5425. isInStandbyMode: function() {
  5426. return this._inStandbyMode || this.aSelectedRows.length >= 2 ||
  5427. (this.multiSelect && this.touchMultiSelectEnabled);
  5428. },
  5429. isMultitouchActive: function() {
  5430. return this.touchMultiSelectEnabled;
  5431. },
  5432. setIsAccountPickerSlideout: function() {
  5433. this._isAccountPickerSlideout = true;
  5434. },
  5435. isAccountPickerSlideout: function() {
  5436. return this._isAccountPickerSlideout || false;
  5437. },
  5438. setShowEmptyNewFolderButton: function(bShowNewFolderLink) {
  5439. this.showEmptyNewFolderButton = bShowNewFolderLink;
  5440. },
  5441. setParentHasWritePermission: function(bHasWritePermission) {
  5442. this.parentHasWritePermission = bHasWritePermission;
  5443. },
  5444. selectFirstRow: function() {
  5445. this.selectSingleRow(this.findRowNode(this.getFirstFocusElement()[0]));
  5446. },
  5447. /**
  5448. Returns an object represented by the selected row
  5449. If necessary, object is augmented with the last ancestor folder/package capability data
  5450. **/
  5451. getSelectedObjectFolderCapabilities: function(selectedObjects) {
  5452. if (!selectedObjects) {
  5453. selectedObjects = this.getSelectedObjects();
  5454. }
  5455. if (!this.contentView.slideout || selectedObjects.length !== 1 || UIHelper.isContainer(ContentStoreObject.getType(selectedObjects[0])) || !ContentStoreObject.getAncestors(selectedObjects[0])) {
  5456. return Promise.resolve(selectedObjects);
  5457. } else {
  5458. var lastAncestor = _.last(selectedObjects[0].ancestors);
  5459. return ContentStoreObject.getEffectiveUserCapabilities(lastAncestor, true).then(function(selectedObjects) {
  5460. return Promise.resolve(selectedObjects);
  5461. }.bind(this, selectedObjects));
  5462. }
  5463. }
  5464. });
  5465. return ListControl;
  5466. });
  5467. /**
  5468. * Licensed Materials - Property of IBM
  5469. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  5470. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  5471. */
  5472. define('bacontentnav/lib/gemini/app/util/View',[ 'jquery', 'underscore', 'doT', '../../../@waca/core-client/js/core-client/ui/core/Events', '../../../@waca/core-client/js/core-client/utils/EventHelper' ], function($, _, dot, Events) {
  5473. 'use strict';
  5474. var View = null;
  5475. var eventsRegex = /^(\S+)\s*(.*)$/;
  5476. // View related attributes that are supported
  5477. var viewAttributes = ['el', 'id', 'className', 'tagName', 'events'];
  5478. /**
  5479. * A Backbone style base View Class. UI Views should extend this class.
  5480. *
  5481. */
  5482. View = Events.extend({
  5483. templateString: null,
  5484. id: null,
  5485. init: function(attributes) {
  5486. View.inherited('init', this, arguments);
  5487. this.viewId = _.uniqueId('view');
  5488. this.dotTemplate = dot.template(this.templateString || '');
  5489. _.extend(this, _.pick(attributes || {}, viewAttributes));
  5490. this._initDomElement();
  5491. this._attachEvents();
  5492. },
  5493. /**
  5494. * The tag name given to the view's DOM element. By default it's a DIV.
  5495. */
  5496. tagName: 'div',
  5497. /**
  5498. * Initialize the DOM element for this view
  5499. */
  5500. _initDomElement: function() {
  5501. if ( !this.el ) {
  5502. var attrs = {};
  5503. if (this.id) {
  5504. attrs.id = _.result(this, 'id');
  5505. }
  5506. if (this.className) {
  5507. attrs['class'] = _.result(this, 'className');
  5508. }
  5509. this.setElement(document.createElement(this.tagName));
  5510. this.$el.attr(attrs);
  5511. }
  5512. else {
  5513. this.setElement(_.result(this, 'el'));
  5514. }
  5515. },
  5516. /**
  5517. * Convenience function to use jQuery to find a DOM element within this view. This is
  5518. * faster then doing a global lockup.
  5519. */
  5520. $: function(selector) {
  5521. return this.$el.find(selector);
  5522. },
  5523. /**
  5524. * Hide the view
  5525. */
  5526. hide: function() {
  5527. this.$el.hide();
  5528. },
  5529. /**
  5530. * Show the view if hidden
  5531. */
  5532. show: function() {
  5533. this.$el.show();
  5534. },
  5535. /**
  5536. * Make sure the target is the intended dom node, using CSS class to validate.
  5537. * If not the right node, check out the parents.
  5538. */
  5539. getTarget: function(target, sClass) {
  5540. var $t = $(target);
  5541. if ( !$t.hasClass(sClass) ){
  5542. var parents = $t.parents('.' + sClass);
  5543. if (parents.length > 0) {
  5544. target = parents[0];
  5545. }
  5546. }
  5547. return target;
  5548. },
  5549. /**
  5550. * Render is the main function of the View. Views should implement (override) the render
  5551. * method to populate this.el with the appropriate HTML. Render should always return this
  5552. * to allow chaining of calls.
  5553. */
  5554. render: function() {
  5555. return this;
  5556. },
  5557. /**
  5558. * Remove this view:
  5559. * -Remove the element from the DOM
  5560. * -Remove the event listeners
  5561. */
  5562. remove: function() {
  5563. if (this.$el) {
  5564. this.$el.remove();
  5565. }
  5566. if (this.off) {
  5567. this.off();
  5568. }
  5569. return this;
  5570. },
  5571. /**
  5572. * Set the view element to a new DOM element
  5573. */
  5574. setElement: function(el) {
  5575. this._detachEvents();
  5576. this.$el = el instanceof $ ? el : $(el);
  5577. this.el = this.$el[0];
  5578. this._attachEvents();
  5579. return this;
  5580. },
  5581. /**
  5582. * Attaches the events in this.events to this.el for this view
  5583. */
  5584. _attachEvents: function() {
  5585. var events = this.events;
  5586. this._detachEvents();
  5587. for ( var key in events) {
  5588. if (events.hasOwnProperty(key)) {
  5589. var callback = events[key];
  5590. if (!_.isFunction(callback)) {
  5591. callback = this[events[key]];
  5592. }
  5593. if (!callback) {
  5594. continue;
  5595. }
  5596. var match = key.match(eventsRegex);
  5597. var eventName = match[1];
  5598. var selector = match[2];
  5599. // add the event to the element, with a namespace 'privateViewEvents'
  5600. this.$el.on(eventName + '.privateViewEvents' + this.viewId, selector, callback.bind(this));
  5601. }
  5602. }
  5603. return this;
  5604. },
  5605. /**
  5606. * Detaches all the events from the element
  5607. */
  5608. _detachEvents: function() {
  5609. if (this.$el) {
  5610. this.$el.off('.privateViewEvents' + this.viewId);
  5611. }
  5612. return this;
  5613. }
  5614. });
  5615. return View;
  5616. });
  5617. /**
  5618. * Licensed Materials - Property of IBM
  5619. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2016, 2017
  5620. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  5621. */
  5622. define('bacontentnav/lib/gemini/app/ui/Toolbar',[
  5623. '../util/View',
  5624. 'jquery',
  5625. 'underscore',
  5626. '../../../@waca/core-client/js/core-client/utils/ClassFactory'
  5627. ], function(View, $, _, ClassFactory) {
  5628. 'use strict';
  5629. var Toolbar = null;
  5630. /**
  5631. * Creates an application bar to serve as a main menu bar
  5632. */
  5633. Toolbar = View.extend({
  5634. moduleMap: [],
  5635. addItemsDeferred: null,
  5636. init: function(options) {
  5637. Toolbar.inherited('init', this, arguments);
  5638. this.items = options.items;
  5639. this.itemMap = {};
  5640. this.readyArray = [];
  5641. this.labelsView = false;
  5642. },
  5643. /**
  5644. * Adds an item to the toolbar
  5645. *
  5646. * Returns a deferred object that will be resolve once the rendered item is added to the toolbar
  5647. */
  5648. addItem: function(itemSpec) {
  5649. // Need to add the item to the bar before requiring a module
  5650. var $item = $('<div>');
  5651. this.$el.append($item);
  5652. return this._renderItem(itemSpec, $item);
  5653. },
  5654. _renderItem: function(itemSpec, $item) {
  5655. if (!itemSpec.type && !itemSpec.module) {
  5656. itemSpec.type = 'Menu';
  5657. }
  5658. var module = itemSpec.type ? ('app/ui/toolbar_components/' + itemSpec.type) : itemSpec.module;
  5659. return this._renderItemHelper(module, itemSpec, $item);
  5660. },
  5661. _renderItemHelper: function(module, itemSpec, $item) {
  5662. var deferred = $.Deferred();
  5663. this.readyArray.push(deferred.promise());
  5664. ClassFactory.loadModule(module).then(function(Item) {
  5665. itemSpec.el = $item;
  5666. var item = new Item(itemSpec, this.rootMenu || this.parentView, this);
  5667. item.render();
  5668. this.itemMap[item.name] = item;
  5669. deferred.resolve();
  5670. if (item.notifyRenderComplete) {
  5671. item.notifyRenderComplete();
  5672. }
  5673. }.bind(this));
  5674. return deferred;
  5675. },
  5676. /**
  5677. * Removes an item from the toolbar
  5678. */
  5679. removeItem: function(itemName){
  5680. this.itemMap[itemName].remove();
  5681. delete this.itemMap[itemName];
  5682. },
  5683. /**
  5684. * Add an array of items to the toolbar
  5685. * @param itemSpecArray
  5686. *
  5687. * Returns a deferred object that will be resolved when all items are rendered and added to the toolbar
  5688. */
  5689. addItems: function(itemSpecArray){
  5690. var deferredArray = [];
  5691. _.each(itemSpecArray, function(itemSpec){
  5692. deferredArray.push(this.addItem(itemSpec));
  5693. }.bind(this));
  5694. this.addItemsDeferred = Promise.all(deferredArray);
  5695. return this.addItemsDeferred;
  5696. },
  5697. clearItems: function(){
  5698. _.each(this.itemMap, function(item){
  5699. item.remove();
  5700. }.bind(this));
  5701. this.$el.empty();
  5702. this.itemMap = {};
  5703. this.readyArray = [];
  5704. },
  5705. /**
  5706. * Draws the Toolbar
  5707. */
  5708. render: function() {
  5709. this.$el.empty();
  5710. if (this.items) {
  5711. return this.addItems(this.items);
  5712. }
  5713. return $.Deferred().resolve().promise();
  5714. },
  5715. ready: function(){
  5716. var deferred = $.Deferred();
  5717. if (this.readyArray.length > 0){
  5718. $.when.apply($, this.readyArray).done(function(){
  5719. deferred.resolve();
  5720. });
  5721. } else {
  5722. deferred.resolve();
  5723. }
  5724. return deferred.promise();
  5725. },
  5726. setFocus: function() {
  5727. var first = Object.keys(this.itemMap)[0];
  5728. if (first) {
  5729. var focusElement = this.itemMap[first];
  5730. if(focusElement && focusElement.setFocus) {
  5731. focusElement.setFocus();
  5732. }
  5733. }
  5734. }
  5735. });
  5736. return Toolbar;
  5737. });
  5738. define('text!bacontentnav/lib/gemini/app/ui/templates/Menu.html',[],function () { return '<div class="dropdown-toggle" id="{{=it.id}}_toggle" data-toggle="dropdown" aria-describedby="{{=it.id}}_ddtMenu" aria-label="{{!it.label}}" tabindex="0" role="button" aria-haspopup="true">\n\t{{? it.hcLabel}}\n\t\t<span class="hcLabel">{{=it.label}}</span>\n\t{{?}}\n\t{{? it.labelOnly}}\n\t\t<span id="{{=it.id}}_ddtMenu" class="menu-label">{{=it.label}}</span>\n\t{{?}}\n</div>\n<div class="arrow-wrapper">\n\t<div class="arrow"></div>\n</div>\n<ul class="dropdown-menu" id="{{=it.id}}_toggle" aria-labelledby="{{=it.id}}_toggle" role="menu">\n\t\t{{? it.showTitle}}\n\t\t<h1 role="presentation" class="dropdown-header header-{{!it.name}}">{{!it.label}}</h1>\n\t\t{{?}}\n\t\t{{~it.items :item :index}}\n\t\t\t{{? item.disabled && item.icon}}\n\t\t\t\t<li role="presentation" class="dropdown-header header-{{!item.name}} {{?item.hidden}}hidden{{?}}" aria-disabled="true" id="{{=it.id}}_{{=item.name}}">\n\t\t\t\t\t<span class="{{!item.icon}} menuitem-icon"></span>{{!item.label}}</li>\n\t\t\t{{?? item.disabled}}\n\t\t\t\t<li role="presentation" class="dropdown-header header-{{!item.name}} {{?item.hidden}}hidden{{?}}" aria-disabled="true" id="{{=it.id}}_{{=item.name}}">{{!item.label}}</li>\n\t\t\t{{??}}\n\t\t\t\t<li class="dropdown-menuitem {{=item.name}} {{?item.hidden}}hidden{{?}} propertyUIControl" id="{{=it.id}}_{{=item.name}}">\n\t\t\t\t{{? it.showTick && item.icon}}\n\t\t\t\t\t<a role="menuitemcheckbox" href="#" aria-label="{{!item.label}}" aria-checked="true" class="propertyRow {{? index=== 0}}firstMenuItem{{?}} {{? index === it.items.length - 1}}lastMenuItem{{?}}">\n\t\t\t\t\t\t{{!item.label}}\n\t\t\t\t\t</a>\n\t\t\t\t{{?? it.showTick}}\n\t\t\t\t\t<a role="menuitemcheckbox" href="#" aria-label="{{!item.label}}" aria-checked="true" class="textOnly {{? index=== 0}}firstMenuItem{{?}} {{? index === it.items.length - 1}}lastMenuItem{{?}}">\n\t\t\t\t\t\t<input type="checkbox"/>\n\t\t\t\t\t\t{{!item.label}}\n\t\t\t\t\t</a>\n\t\t\t\t{{?? it.isSort && item.icon}}\n\t\t\t\t\t<a role="menuitem" href="#" {{? index=== 0}}class="firstMenuItem"{{?}} {{? index === it.items.length - 1}}class="lastMenuItem"{{?}}>\n\t\t\t\t\t\t{{!item.label}}\n\t\t\t\t\t\t<span class="{{!item.icon}} menuitem-icon" style="display: none;">\n\t\t\t\t\t\t\t<svg class="svgIcon" aria-hidden="true"><use xlink:href="#common-previous" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span class="wfg_accept"></span>\n\t\t\t\t\t</a>\n\t\t\t\t{{?? it.isSort}}\n\t\t\t\t\t<a role="menuitemsort" href="#" aria-label="{{!item.label}}" class="sortMenuItem {{? index=== 0}}firstMenuItem{{?}} {{? index === it.items.length - 1}}lastMenuItem{{?}}">\n\t\t\t\t\t\t{{!item.label}}\n\t\t\t\t\t</a>\n\t\t\t\t{{?? item.icon}}\n\t\t\t\t\t<a href="#" aria-label="{{!item.label}}" {{? index=== 0}}class="firstMenuItem"{{?}} {{? index === it.items.length - 1}}class="lastMenuItem"{{?}}>\n\t\t\t\t\t\t<span class="{{!item.icon}} menuitem-icon"></span><span class="wfg_accept"></span>&nbsp;{{!item.label}}</a>\n\t\t\t\t{{??}}\n\t\t\t\t\t<a role="menuitem" href="#" aria-label="{{!item.label}}" class="textOnly {{? index=== 0}}firstMenuItem{{?}} {{? index === it.items.length - 1}}lastMenuItem{{?}}">{{!item.label}}</a>\n\t\t\t\t{{?}}\n\t\t{{?}}\n\t\t</li>\n\t{{~}}\n</ul>\n';});
  5739. /**
  5740. * Licensed Materials - Property of IBM
  5741. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  5742. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  5743. */
  5744. define('bacontentnav/lib/gemini/app/ui/toolbar_components/Menu',[ '../../util/View', 'jquery', 'underscore', '../../../../@waca/core-client/js/core-client/utils/BidiUtil', 'text!../templates/Menu.html' ], function(View, $, _, bidi, template) {
  5745. var MenuItem = null;
  5746. /**
  5747. * Represents a drop down menu that can be added to an app bar
  5748. */
  5749. MenuItem = View.extend({
  5750. templateString: template,
  5751. events: {
  5752. 'keydown': '_handleKeyboard',
  5753. 'click .dropdown-menuitem': '_handleClick'
  5754. },
  5755. itemActions: null,
  5756. itemSpecMap: null,
  5757. baseClass: 'toolbar',
  5758. hcLabel: null, // create an element for high contrast label
  5759. showTitle: true,
  5760. /**
  5761. * Creates a new menu item
  5762. *
  5763. * @param spec -
  5764. * The menu item spec
  5765. * @param root -
  5766. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  5767. */
  5768. init: function(spec) {
  5769. _.defaults(spec, {hcLabel: true});
  5770. _.extend(this, spec);
  5771. this.itemActions = {};
  5772. this.itemSpecMap = {};
  5773. _.each(this.items, function(item) {
  5774. this.itemSpecMap[item.name] = item;
  5775. }.bind(this));
  5776. MenuItem.inherited('init', this, arguments);
  5777. },
  5778. _handleClick: function(event){
  5779. event.preventDefault();
  5780. this._performAction(event.currentTarget.id);
  5781. },
  5782. _performAction: function(id) {
  5783. var action = this.itemActions[id];
  5784. if (action){
  5785. // Delay the action slightly to allow bootstrap to close the menu before
  5786. // the action is fired
  5787. setTimeout(function() {
  5788. action();
  5789. }, 10);
  5790. }
  5791. },
  5792. /**
  5793. * Removes a menu item
  5794. */
  5795. removeItem: function(name){
  5796. var id = this.viewId + '_' + name;
  5797. this.$menu.children('#' + id).remove();
  5798. delete this.itemSpecMap[name];
  5799. delete this.itemActions[id];
  5800. },
  5801. addDivider: function() {
  5802. var divider = $('<li role="presentation" class="divider">');
  5803. this.$menu.append(divider);
  5804. return divider;
  5805. },
  5806. /**
  5807. * Adds a new menu item to the drop down
  5808. */
  5809. addItem: function(item) {
  5810. this.itemSpecMap[item.name] = item;
  5811. var menuItem = $('<li id="' + this._getItemId(item.name) + '">');
  5812. var action = null;
  5813. if (item.checked) {
  5814. action = $('<a role="menuitem" href="#" aria-label="' + item.label + '" aria-checked="true" class="menuitem-toggled">' + item.label + '</a>');
  5815. }
  5816. else {
  5817. action = $('<a role="menuitem" href="#" aria-label="' + item.label + '" aria-checked="false">' + item.label + '</a>');
  5818. }
  5819. menuItem.append(action);
  5820. menuItem.addClass('dropdown-menuitem');
  5821. menuItem.addClass(item.name);
  5822. this.$menu.append(menuItem);
  5823. this._buildMenuItem(item);
  5824. return menuItem;
  5825. },
  5826. showItem: function(name){
  5827. this.$menu.find('.'+ name).removeClass('hidden');
  5828. },
  5829. hideItem: function(name){
  5830. this.$menu.find('.' + name).addClass('hidden');
  5831. },
  5832. _handleKeyboard: function(e) {
  5833. var keyCode = e.which || e.keyCode || e.charCode;
  5834. var $target = $(e.target);
  5835. var $nextFocus;
  5836. switch (keyCode) {
  5837. case 9: //tabkey
  5838. if (e.shiftKey) {
  5839. if ($target.hasClass("firstMenuItem")){
  5840. $nextFocus = $target.closest("ul").find("a.lastMenuItem");
  5841. $nextFocus.focus();
  5842. e.preventDefault();
  5843. }
  5844. } else {
  5845. if ($target.hasClass('lastMenuItem')) {
  5846. $nextFocus = $target.closest("ul").find("a.firstMenuItem");
  5847. $nextFocus.focus();
  5848. e.preventDefault();
  5849. }
  5850. }
  5851. break;
  5852. case 13: // enter key
  5853. case 32: // space
  5854. e.preventDefault();
  5855. this.$toggle.dropdown('toggle');
  5856. if ($(e.target).hasClass('dropdown-toggle')) {
  5857. var first = this.$el.find('.dropdown-menu a').first();
  5858. first.focus();
  5859. } else {
  5860. var currentItem = this.getTarget(e.target, 'dropdown-menuitem');
  5861. this._performAction(currentItem.id);
  5862. }
  5863. break;
  5864. case 37: // left arrow
  5865. case 39: // right arrow
  5866. if ($(e.target.parentNode).hasClass('dropdown-menuitem')) {
  5867. var downKeyEvt = _.clone(e);
  5868. downKeyEvt.keyCode = keyCode + 1; // left to up arrow: 38, right to down arrow:40;
  5869. $(e.target).trigger(downKeyEvt); // delegate to bootstrap
  5870. }
  5871. break;
  5872. default:
  5873. break;
  5874. }
  5875. },
  5876. _templateParams: function() {
  5877. return {
  5878. id: this.viewId,
  5879. items: this.items,
  5880. label: this.label,
  5881. icon: this.icon,
  5882. hcLabel: this.hcLabel,
  5883. baseClass: this.baseClass,
  5884. labelOnly: this.labelOnly,
  5885. showTitle: this.showTitle
  5886. };
  5887. },
  5888. /**
  5889. * Draws the MenuItem
  5890. */
  5891. render: function() {
  5892. var sHtml = this.dotTemplate( this._templateParams() );
  5893. this.$el.append(sHtml);
  5894. this.$el.addClass(this.baseClass + 'ItemWrapper');
  5895. this.$el.addClass('dropdown');
  5896. this.$toggle = this.$el.children('.dropdown-toggle');
  5897. this.$toggle.addClass(this.baseClass + 'Icon');
  5898. this.$iconImage = $('<span class="' + this.icon + '"></span>');
  5899. if (this.icon) {
  5900. this.$toggle.prepend(this.$iconImage);
  5901. }
  5902. this.$toggle.attr('title', this.label);
  5903. this.$toggle.addClass(this.baseClass + 'Item');
  5904. this.$menu = this.$el.children('.dropdown-menu');
  5905. if (this.trailing) {
  5906. this.$menu.addClass('dropdown-menu-right');
  5907. }
  5908. var promise = this._buildDropDown();
  5909. this.$menuLabel = this.$el.find('.menu-label');
  5910. return promise;
  5911. },
  5912. _buildDropDown: function() {
  5913. var deferred = $.Deferred();
  5914. require([ 'bsdropdown' ], function() {
  5915. this.$toggle.dropdown();
  5916. /**
  5917. * A callback can be passed to opening behavior
  5918. */
  5919. if (this.action) {
  5920. this.$el.on('show.bs.dropdown', this.action.bind(this));
  5921. }
  5922. this._buildMenuItems();
  5923. deferred.resolve(this.$el);
  5924. }.bind(this));
  5925. return deferred.promise();
  5926. },
  5927. _buildMenuItems: function() {
  5928. _.each(this.items, function(item) {
  5929. this._buildMenuItem(item);
  5930. }.bind(this));
  5931. },
  5932. _getItemId: function(name) {
  5933. return this.viewId + '_' + name;
  5934. },
  5935. _buildMenuItem: function(item) {
  5936. var itemID = this._getItemId(item.name);
  5937. this.itemActions[itemID] = item.action;
  5938. var itemNode = $('#' + itemID);
  5939. var elem = itemNode.get(0);
  5940. if (elem) {
  5941. bidi.initElementForBidi(elem);
  5942. }
  5943. }
  5944. });
  5945. return MenuItem;
  5946. });
  5947. /**
  5948. * Licensed Materials - Property of IBM
  5949. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2015, 2017
  5950. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  5951. */
  5952. define('bacontentnav/lib/gemini/app/ui/toolbar_components/Button',[
  5953. '../../util/View',
  5954. 'underscore',
  5955. '../../../../@waca/core-client/js/core-client/utils/Utils'
  5956. ], function(View, _, CommonsUtils) {
  5957. 'use strict';
  5958. var Button = null;
  5959. /**
  5960. * Represents a drop down menu that can be added to an app bar
  5961. */
  5962. Button = View.extend({
  5963. events: {
  5964. 'primaryaction' : '_handleClick',
  5965. 'mousedown': '_handleStartDrag',
  5966. 'dragdown': '_handleStartDrag'
  5967. },
  5968. baseClass: 'toolbar',
  5969. /**
  5970. * Creates a new menu item
  5971. *
  5972. * @param spec -
  5973. * The menu item spec
  5974. * @param root -
  5975. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  5976. */
  5977. init: function(spec, parentItem, toolbar) {
  5978. this.group = null; //group can be set for sets of buttons that act as states of an action
  5979. this.selected = false;
  5980. this.toolbar = toolbar;
  5981. _.extend(this, spec);
  5982. Button.inherited('init', this, arguments);
  5983. },
  5984. _handleClick: function () {
  5985. if (this.$('button').prop('disabled')){
  5986. return;
  5987. }
  5988. var dfd = null;
  5989. if (this.action) {
  5990. dfd = this.action.apply(this, arguments);
  5991. }
  5992. if (this.arrow && dfd && dfd.then) {
  5993. dfd.then( this.$el.addClass.bind(this.$el, 'open') );
  5994. }
  5995. if (this.$('button').prop('update')){
  5996. this.toolbar.updateButtons();
  5997. }
  5998. },
  5999. _handleStartDrag: function(){
  6000. if (this.$('button').prop('disabled')){
  6001. return;
  6002. }
  6003. if (this.startDrag) {
  6004. this.startDrag.apply(this, arguments);
  6005. }
  6006. },
  6007. /**
  6008. * Draws the MenuItem
  6009. */
  6010. render: function() {
  6011. var $button;
  6012. if (this.text) {
  6013. $button = $('<button>' + this.text + '</button>');
  6014. } else {
  6015. $button = $('<button></button>');
  6016. }
  6017. // Sets the attribute only if value is defined. Helper to reduce complexity while doing validation.
  6018. var _setAttr = function(sAttr, sValue) {
  6019. if (sValue) {
  6020. $button.attr(sAttr, sValue);
  6021. }
  6022. };
  6023. // Adds the sClassname if it's defined to the element. Helper to reduce complexity while doing validation.
  6024. var _addClass = function($el, className) {
  6025. if (className) {
  6026. $el.addClass(className);
  6027. }
  6028. };
  6029. _setAttr('title', this.label);
  6030. if(this.icon) {
  6031. CommonsUtils.setIcon($button, this.icon, this.label, this.label);
  6032. }
  6033. else{
  6034. _setAttr('aria-label', this.label);
  6035. }
  6036. _addClass($button, this.className);
  6037. _setAttr('id', this.id);
  6038. _setAttr('accesskey', this.accesskey);
  6039. if (typeof this.disabled === "function") {
  6040. if(this.disabled()===true){
  6041. $button.prop('disabled', true);
  6042. }
  6043. }else if(this.disabled === true){
  6044. $button.prop('disabled', true);
  6045. }
  6046. if (typeof this.update === "function") {
  6047. if(this.update()===true){
  6048. $button.prop('update', true);
  6049. }
  6050. }else if(this.update === true){
  6051. $button.prop('update', true);
  6052. }
  6053. if (this.hidden) {
  6054. this.$el.hide();
  6055. }
  6056. this.$el
  6057. .empty()
  6058. .addClass(this.baseClass + 'Icon ' + this.baseClass + 'Item')
  6059. .prepend( $button );
  6060. if (this.selected) {
  6061. this.$el.addClass('selected');
  6062. }
  6063. _addClass(this.$el, this.group);
  6064. if (this.arrow) {
  6065. this.$el.append( $('<div class="arrow-wrapper"><div class="arrow"></div></div>') );
  6066. }
  6067. return this;
  6068. },
  6069. setFocus: function(){
  6070. this.$('button').focus();
  6071. }
  6072. });
  6073. return Button;
  6074. });
  6075. define('text!bacontentnav/lib/gemini/app/ui/templates/ApplicationBar.html',[],function () { return '<div id="{{=it.id}}" class="appbar" role="menubar">\n\t<div class="appbarRow">\n\t\t{{? it.showHome}}\n\t\t<div class="appbarHome" id="{{=it.id}}_home"></div>\n\t\t{{?}}\n\t\t<div class="appbarLeading" id="{{=it.id}}_leading"></div>\n\t\t<div class="appbarCenter" id="{{=it.id}}_center"></div>\n\t\t<div class="appbarTrailing" id="{{=it.id}}_trailing"></div>\n\t\t<div class="appbarOverflow" id="{{=it.id}}_root"></div>\n\t\t<div class="appbarProfile" id="{{=it.id}}_profile"></div>\n\t</div>\n</div>\n<div id="{{=it.id}}_subbar" class="subbar">\n</div>\n';});
  6076. /**
  6077. * Licensed Materials - Property of IBM
  6078. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014
  6079. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6080. */
  6081. define('bacontentnav/lib/gemini/app/ui/ApplicationBar',[ './Toolbar', 'jquery', './toolbar_components/Menu', './toolbar_components/Button', 'text!./templates/ApplicationBar.html', '../nls/StringResources' ],
  6082. function(Toolbar, $, Menu, Button, template, resources) {
  6083. var ApplicationBar = null;
  6084. var WEBFONT_USER_ICON = 'wfg_user';
  6085. /**
  6086. * A variation of the toolbar to represent the application main bar.
  6087. */
  6088. ApplicationBar = Toolbar.extend({
  6089. templateString: template,
  6090. moduleMap: [],
  6091. defaultHeight: 70,
  6092. smallHeight: 45,
  6093. init: function(options) {
  6094. ApplicationBar.inherited('init', this, arguments);
  6095. this.profile = options.profile;
  6096. this.rootItems = options.rootItems;
  6097. this.authURL = options.authURL;
  6098. this.logoutUrl = options.logoutUrl;
  6099. this.appController = options.appController;
  6100. this.config = options.appBarConfig || {showHome: true, showLogout: true};
  6101. this.hasCollapsedItems = false;
  6102. this.onHide = options.onHide;
  6103. this.onShow = options.onShow;
  6104. // add keydown handler
  6105. this._onKeyHandle = $('html').on('keydown.ApplicationBar', this.onKeydown.bind(this));
  6106. },
  6107. /**
  6108. * Handle keydown event
  6109. * @return void
  6110. */
  6111. onKeydown: function( event ){
  6112. // trap the F10 keydown event and focus the home button
  6113. if( event.keyCode === 121 ){
  6114. // if there is a home button then give it focus
  6115. if( this.homeButton ){
  6116. this.homeButton.$el.find( 'button' ).focus();
  6117. }
  6118. // stop propagation
  6119. event.stopPropagation();
  6120. // must return false to prevent browser F10 interaction
  6121. return false;
  6122. }
  6123. },
  6124. /**
  6125. * Clean up event handlers
  6126. * @return void
  6127. */
  6128. remove: function() {
  6129. this._onKeyHandle.off();
  6130. this._onKeyHandle = null;
  6131. ApplicationBar.inherited('remove', this, arguments);
  6132. },
  6133. /**
  6134. * Adds an item to the application bar
  6135. */
  6136. addItem: function(itemSpec) {
  6137. // Need to add the item to the bar before requiring a module
  6138. var deferred = null;
  6139. var $item = $('<div>');
  6140. if (itemSpec.position === 'trailing') {
  6141. this.$trailingActions.append($item);
  6142. }
  6143. else if (itemSpec.position === 'center') {
  6144. this.$centerActions.append($item);
  6145. }
  6146. else {
  6147. this.$leadingActions.append($item);
  6148. }
  6149. itemSpec.baseClass = 'appbar';
  6150. deferred = this._renderItem(itemSpec, $item);
  6151. if (!itemSpec.supportCustomCollapse) {
  6152. this._buildCollapsedItem(itemSpec, $item);
  6153. }
  6154. return deferred;
  6155. },
  6156. /**
  6157. * Add a list root items to the application bar root menu
  6158. */
  6159. addRootItems: function(items) {
  6160. if (items){
  6161. this.rootMenu.$el.removeClass('visible-xs');
  6162. }
  6163. _.each(items, function(item) {
  6164. this.rootItems[item.name] = item;
  6165. this.rootMenu.addItem(item);
  6166. }.bind(this));
  6167. },
  6168. /**
  6169. * Clears all items except those from the root and profile menu. Collapsed root items will be removed
  6170. */
  6171. clearItems: function() {
  6172. _.each(this.itemMap, function(item) {
  6173. this.removeItem(item.name);
  6174. }.bind(this));
  6175. this.$leadingActions.empty();
  6176. this.$trailingActions.empty();
  6177. this.itemMap = {};
  6178. },
  6179. removeItem: function(itemName) {
  6180. this._removeSubSection(itemName);
  6181. var item = this.itemMap[itemName];
  6182. if (item.items) {
  6183. _.each(item.items, function(subItem) {
  6184. this.rootMenu.removeItem(subItem.name);
  6185. }.bind(this));
  6186. }
  6187. else {
  6188. this.rootMenu.removeItem(itemName);
  6189. }
  6190. ApplicationBar.inherited('removeItem', this, arguments);
  6191. },
  6192. clearRootItems: function() {
  6193. this.rootMenu.$el.addClass('visible-xs');
  6194. _.each(this.rootItems, function(item) {
  6195. this.removeRootItem(item.name);
  6196. }.bind(this));
  6197. this.rootItems = {};
  6198. },
  6199. removeRootItem: function(itemName) {
  6200. this.rootMenu.removeItem(itemName);
  6201. delete this.rootItems[itemName];
  6202. },
  6203. getAddedItem: function(itemName) {
  6204. return this.addItemsDeferred.then(function() {
  6205. if (this.itemMap[itemName]) {
  6206. return Promise.resolve(this.itemMap[itemName]);
  6207. } else {
  6208. return Promise.reject();
  6209. }
  6210. }.bind(this));
  6211. },
  6212. _buildCollapsedItem: function(itemSpec, $item) {
  6213. itemSpec.responsive = (itemSpec.responsive === undefined) ? true : itemSpec.responsive;
  6214. if (itemSpec.responsive) {
  6215. if (!this.hasCollapseItems){
  6216. this.hasCollapseItems = true;
  6217. this._addRootMenuDivider();
  6218. }
  6219. $item.addClass('hidden-xs');
  6220. if (itemSpec.items) {
  6221. this._addSubSection(itemSpec);
  6222. }else if (itemSpec.type === 'Separator'){
  6223. this._addRootMenuDivider();
  6224. }
  6225. else {
  6226. var $subItem = this.rootMenu.addItem(itemSpec, true);
  6227. $subItem.addClass('visible-xs');
  6228. }
  6229. }
  6230. },
  6231. _removeSubSection: function(name) {
  6232. this.rootMenu.$menu.children('.header-' + name).remove();
  6233. },
  6234. _addRootMenuDivider: function(){
  6235. // Don't add a second divider if there is a divider already
  6236. if (!this.rootMenu.$menu.children().last().hasClass('divider')) {
  6237. var divider = this.rootMenu.addDivider();
  6238. divider.addClass('visible-xs');
  6239. return divider;
  6240. }
  6241. return null;
  6242. },
  6243. _addSubSection: function(itemSpec) {
  6244. var rootMenuHeader = $('<li role="presentation" class="dropdown-header header-' + itemSpec.name + '">' + itemSpec.label + '</li>');
  6245. rootMenuHeader.addClass('visible-xs');
  6246. var divider = this._addRootMenuDivider();
  6247. if (divider){
  6248. // This class allows the divider to be removed when the section is removed
  6249. divider.addClass('header-' + itemSpec.name );
  6250. }
  6251. this.rootMenu.$menu.append(rootMenuHeader);
  6252. _.each(itemSpec.items, function(subItem) {
  6253. this.rootMenu.addItem(subItem).addClass('visible-xs');
  6254. }.bind(this));
  6255. divider =this._addRootMenuDivider();
  6256. if (divider){
  6257. divider.addClass('header-' + itemSpec.name );
  6258. }
  6259. },
  6260. /**
  6261. * Draws the AppBar
  6262. */
  6263. render: function() {
  6264. var sHtml = this.dotTemplate({
  6265. id: this.viewId,
  6266. showHome: this.config.showHome
  6267. });
  6268. this.$el.html(sHtml);
  6269. var deferred = $.Deferred();
  6270. this._createRootMenu().done(function(){
  6271. if(this.config.showHome) {
  6272. this._createHomeButton();
  6273. }
  6274. this._createProfileMenu().then(function(){
  6275. this.$leadingActions = $('#' + this.viewId + '_leading');
  6276. this.$trailingActions = $('#' + this.viewId + '_trailing');
  6277. this.$centerActions = $('#' + this.viewId + '_center');
  6278. this.addItems(this.items).done( function() {
  6279. if(_.isEmpty(this.rootMenu.itemActions) ) {
  6280. this.rootMenu.$el.removeClass('visible-xs');
  6281. this.rootMenu.$el.hide();
  6282. }
  6283. deferred.resolve(this);
  6284. }.bind(this));
  6285. }.bind(this));
  6286. }.bind(this));
  6287. return deferred.promise();
  6288. },
  6289. _createHomeButton: function(){
  6290. var $itemEl = $('<div></div>');
  6291. $('#' + this.viewId + '_home').append($itemEl);
  6292. var spec = {
  6293. name: 'home',
  6294. label: resources.get('rootMenuTitle'),
  6295. type: 'Button',
  6296. el: $itemEl,
  6297. icon: 'wfg_gemini',
  6298. baseClass: 'appbar',
  6299. action: this._goHomeAction.bind(this)
  6300. };
  6301. this.homeButton = new Button(spec);
  6302. this.homeButton.render();
  6303. },
  6304. _goHomeAction: function () {
  6305. if(this.config.showHome) {
  6306. this.appController.goHome();
  6307. this.homeButton.$el.find('button').blur();
  6308. }
  6309. },
  6310. /**
  6311. * Creates the root (i.e. hamburger) menu. Besides holding root items, when the app bar is small horizontally actions will be collapsed to this menu
  6312. */
  6313. _createRootMenu: function() {
  6314. var $itemEl = $('<div></div>');
  6315. $('#' + this.viewId + '_root').append($itemEl);
  6316. var spec = {
  6317. name: 'mainMenu',
  6318. label: resources.get('rootMenuTitle'),
  6319. type: 'Menu',
  6320. el: $itemEl,
  6321. icon: 'wfg_menuoverflow',
  6322. trailing: true,
  6323. baseClass: 'appbar',
  6324. items: this.rootItems
  6325. };
  6326. this.rootMenu = new Menu(spec);
  6327. var promise = this.rootMenu.render();
  6328. if (!this.rootItems || this.rootItems.length === 0 ){
  6329. this.rootMenu.$el.addClass('visible-xs');
  6330. }
  6331. return promise;
  6332. },
  6333. _createProfileMenu: function() {
  6334. if (!this.profile || !this.config.showLogout) {
  6335. return $.Deferred().resolve().promise();
  6336. }
  6337. var $itemEl = $('<div></div>');
  6338. $('#' + this.viewId + '_profile').append($itemEl);
  6339. var spec = {
  6340. name: 'profileMenu',
  6341. label: this.profile.displayName,
  6342. hcLabel: false,
  6343. type: 'Menu',
  6344. el: $itemEl,
  6345. icon: 'profileIcon',
  6346. baseClass: 'appbar',
  6347. trailing: true,
  6348. items: [ {
  6349. name: 'logout',
  6350. label: 'Logout',
  6351. action: this._logout.bind(this)
  6352. } ]
  6353. };
  6354. this.profileMenu = new Menu(spec);
  6355. var promise = this.profileMenu.render();
  6356. var bHighContrast = $(document.body).hasClass('highcontrast'),
  6357. bUseBadge = this.profile._attachmentInfo && this.profile._attachmentInfo.badge;
  6358. if (!bHighContrast && bUseBadge) {
  6359. var badgeURL = '/app/account/' + this.profile._meta.bundleID + '/badge';
  6360. this.profileMenu.$iconImage.css('backgroundImage', 'url(\'' + badgeURL + '\')');
  6361. }
  6362. else {
  6363. this.profileMenu.$iconImage.addClass(WEBFONT_USER_ICON);
  6364. }
  6365. return promise;
  6366. },
  6367. _logout: function() {
  6368. window.location.href = this.logoutUrl;
  6369. },
  6370. show: function() {
  6371. $(this.$el).find('.appbar').show();
  6372. },
  6373. hide: function() {
  6374. $(this.$el).find('.appbar').hide();
  6375. }
  6376. });
  6377. return ApplicationBar;
  6378. });
  6379. /*
  6380. *+------------------------------------------------------------------------+
  6381. *| Licensed Materials - Property of IBM
  6382. *| IBM Cognos Products: Content Explorer
  6383. *| (C) Copyright IBM Corp. 2015, 2018
  6384. *|
  6385. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6386. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6387. *+------------------------------------------------------------------------+
  6388. */
  6389. define('bacontentnav/common/ui/ContentBar',[
  6390. 'require',
  6391. '../../lib/gemini/app/ui/ApplicationBar'
  6392. ], function(LocalRequire, ApplicationBar) {
  6393. 'use strict';
  6394. var ContentBar = ApplicationBar.extend({
  6395. /**
  6396. * #gemini: overriding the render() as 'options.profile' is assumed to be always available
  6397. * and it is not in this case.
  6398. */
  6399. render: function() {
  6400. var sHtml = this.dotTemplate({
  6401. 'id': this.viewId
  6402. });
  6403. this.$el.html(sHtml);
  6404. return this._createRootMenu().then(function() {
  6405. this.$leadingActions = $('#' + this.viewId + '_leading');
  6406. this.$trailingActions = $('#' + this.viewId + '_trailing');
  6407. this.$centerActions = $('#' + this.viewId + '_center');
  6408. return this.addItems(this.items).then(function() {
  6409. if (($(this.el).find('.appbarLeading').children()).length === 0) {
  6410. $(this.el).find('.appbarLeading').append(this.items[0].el);
  6411. }
  6412. $(this.el).find('.appbarLeading').children().addClass('contentBarItem');
  6413. $(this.el).find('.appbarCenter').children().addClass('contentBarItem');
  6414. $(this.el).find('.appbarTrailing').children().addClass('contentBarItem');
  6415. this.resize();
  6416. return this;
  6417. }.bind(this));
  6418. }.bind(this));
  6419. },
  6420. resize: function() {
  6421. if (this.itemMap.breadcrumbs) {
  6422. this.itemMap.breadcrumbs.resize();
  6423. }
  6424. },
  6425. /* override Gemini's show/hide as it does not show/hide the entire bar div element */
  6426. hide: function() {
  6427. if (this.onHide) {
  6428. this.onHide();
  6429. }
  6430. this.$el.hide();
  6431. },
  6432. show: function() {
  6433. if (this.onShow) {
  6434. this.onShow();
  6435. }
  6436. this.$el.show();
  6437. },
  6438. isVisible: function() {
  6439. return this.$el[0].style.display !== 'none';
  6440. },
  6441. _renderItem: function(itemSpec, $item) {
  6442. if (!itemSpec.type && !itemSpec.module) {
  6443. itemSpec.type = 'Menu';
  6444. }
  6445. var module = itemSpec.type ? ('../../lib/gemini/app/ui/toolbar_components/' + itemSpec.type) : itemSpec.module;
  6446. return this._renderItemHelper(module, itemSpec, $item);
  6447. },
  6448. _loadModule: function(moduleId) {
  6449. return new Promise(function(resolve, reject) {
  6450. if (typeof moduleId === 'function') {
  6451. resolve(moduleId);
  6452. } else {
  6453. return LocalRequire([moduleId], function(Module) {
  6454. if (Module) {
  6455. resolve(Module);
  6456. } else {
  6457. reject(new Error('No module found'));
  6458. }
  6459. }.bind(this));
  6460. }
  6461. }.bind(this));
  6462. },
  6463. _renderItemHelper: function(module, itemSpec, $item) {
  6464. var promise = this._loadModule(module).then(function(Item) {
  6465. itemSpec.el = $item;
  6466. var item = new Item(itemSpec, this.rootMenu || this.parentView, this);
  6467. item.render();
  6468. this.itemMap[item.name] = item;
  6469. if (item.notifyRenderComplete) {
  6470. item.notifyRenderComplete();
  6471. }
  6472. }.bind(this));
  6473. this.readyArray.push(promise);
  6474. return promise;
  6475. }
  6476. });
  6477. return ContentBar;
  6478. });
  6479. /*
  6480. *+------------------------------------------------------------------------+
  6481. *| Licensed Materials - Property of IBM
  6482. *| IBM Cognos Products: Content Explorer
  6483. *| (C) Copyright IBM Corp. 2016
  6484. *|
  6485. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6486. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6487. *+------------------------------------------------------------------------+
  6488. */
  6489. define('bacontentnav/utils/A11YHelper',[], function() {
  6490. 'use strict';
  6491. var _singletonInstance = null;
  6492. var A11YHelper = function() {
  6493. this.SCREENREADER_ALERT_ID = 'ca_screenreader_alert';
  6494. };
  6495. A11YHelper.prototype.screenReaderAlertUser = function(sMessage) {
  6496. if (!sMessage || !sMessage.length) {
  6497. return;
  6498. }
  6499. var $divElem = $('#' + this.SCREENREADER_ALERT_ID);
  6500. if ($divElem.length) {
  6501. $divElem.remove();
  6502. }
  6503. $divElem = $('<div>', {
  6504. 'id': this.SCREENREADER_ALERT_ID,
  6505. 'style': 'position:absolute; top:-9000px;',
  6506. 'role': 'alert'
  6507. });
  6508. $divElem.text(sMessage);
  6509. $('body').append($divElem);
  6510. };
  6511. var _static = {
  6512. getInstance: function() {
  6513. if (!_singletonInstance) {
  6514. _singletonInstance = new A11YHelper();
  6515. }
  6516. return _singletonInstance;
  6517. }
  6518. };
  6519. return _static.getInstance();
  6520. });
  6521. /*
  6522. *+------------------------------------------------------------------------+
  6523. *| Licensed Materials - Property of IBM
  6524. *| IBM Cognos Products: Content Explorer
  6525. *| (C) Copyright IBM Corp. 2016
  6526. *|
  6527. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6528. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6529. *+------------------------------------------------------------------------+
  6530. */
  6531. define('bacontentnav/utils/BaseNavigatorPlugin',[
  6532. '../lib/@waca/core-client/js/core-client/ui/core/Class',
  6533. 'underscore'
  6534. ], function(Class, _) {
  6535. 'use strict';
  6536. var BaseNavigatorPlugin = Class.extend({
  6537. init: function(options) {
  6538. BaseNavigatorPlugin.inherited('init', this, arguments);
  6539. _.extend(this, options);
  6540. this.focusElmentContainer = '_need to override this';
  6541. },
  6542. upPressed: function(srcEl, nonPrintKeyStatus) { void(nonPrintKeyStatus); },
  6543. downPressed: function(srcEl, nonPrintKeyStatus) { void(nonPrintKeyStatus); },
  6544. rightPressed: function(srcEl, nonPrintKeyStatus) { void(nonPrintKeyStatus); },
  6545. leftPressed: function(srcEl, nonPrintKeyStatus) { void(nonPrintKeyStatus); },
  6546. escPressed: function(srcEl, nonPrintKeyStatus) { void(nonPrintKeyStatus); },
  6547. tabPressed: function(srcEl, nonPrintKeyStatus) { void(nonPrintKeyStatus); }
  6548. });
  6549. return BaseNavigatorPlugin;
  6550. });
  6551. /*
  6552. *+------------------------------------------------------------------------+
  6553. *| Licensed Materials - Property of IBM
  6554. *| IBM Cognos Products: Content Explorer
  6555. *| (C) Copyright IBM Corp. 2015, 2017
  6556. *|
  6557. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6558. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6559. *+------------------------------------------------------------------------+
  6560. */
  6561. define('bacontentnav/utils/TableNavigatorPlugin',[
  6562. './BaseNavigatorPlugin',
  6563. 'underscore'
  6564. ], function(BaseNavigatorPlugin, _) {
  6565. 'use strict';
  6566. var TableNavigatorPlugin = BaseNavigatorPlugin.extend({
  6567. init: function(options) {
  6568. TableNavigatorPlugin.inherited('init', this, arguments);
  6569. _.extend(this, options);
  6570. this.focusElmentContainer = 'td';
  6571. this.actionMode = false;
  6572. },
  6573. spacePressed: function(srcEl) {
  6574. var focList = this.navObj.getFocusableItemsList($(srcEl));
  6575. if (focList.length === 1 && !$(srcEl).hasClass('newFolderRow') || $(srcEl).hasClass('ellipsesButton_cell') || $(srcEl).hasClass('nowrap multiProp')) {
  6576. $(focList[0]).focus();
  6577. return false;
  6578. } else {
  6579. return true;
  6580. }
  6581. },
  6582. enterPressed: function(srcEl) {
  6583. var $srcEl = $(srcEl);
  6584. var focList;
  6585. if ((!this.actionMode) && ($srcEl.prop('tagName') === 'TD')) {
  6586. focList = this.navObj.getFocusableItemsList($srcEl);
  6587. if (focList.length === 1) {
  6588. //if ther is only one item them simulate a click to that item
  6589. focList.trigger('click');
  6590. return false;
  6591. } else if (focList.length > 0) {
  6592. //more then one item the just focus to the first one
  6593. this.actionMode = true;
  6594. this.enableCellContentTabCycling(focList);
  6595. $(focList[0]).focus();
  6596. return false;
  6597. }
  6598. } else {
  6599. this.actionMode = false;
  6600. focList = this.navObj.getFocusableItemsList($srcEl.closest('td'));
  6601. this.disableCellContentTabCycling(focList);
  6602. return true;
  6603. }
  6604. },
  6605. disableCellContentTabCycling: function(focList) {
  6606. var tr = $(focList).closest('tr');
  6607. setTimeout(function() { tr.removeClass('actionMode'); }, 100);
  6608. $(focList[0]).removeClass('tabCycleStart').removeClass('innerText');
  6609. $(focList[focList.length - 1]).removeClass('tabCycleEnd').removeClass('innerText');
  6610. focList.toArray().forEach(function(item) {
  6611. $(item).attr('tabindex', '-1');
  6612. });
  6613. },
  6614. enableCellContentTabCycling: function(focList) {
  6615. $(focList).closest('tr').addClass('actionMode');
  6616. $(focList[0]).addClass('tabCycleStart').addClass('innerText');
  6617. $(focList[focList.length - 1]).addClass('tabCycleEnd').addClass('innerText');
  6618. focList.toArray().forEach(function(item) {
  6619. $(item).attr('tabindex', '0');
  6620. });
  6621. },
  6622. escPressed: function(srcEl) {
  6623. if (this.actionMode) {
  6624. var $srcEl = $(srcEl);
  6625. this.actionMode = false;
  6626. var focList = this.navObj.getFocusableItemsList($srcEl);
  6627. this.disableCellContentTabCycling(focList);
  6628. var $currentTd = $($(srcEl).closest('td')[0]);
  6629. $currentTd.focus();
  6630. return false;
  6631. }
  6632. return true;
  6633. },
  6634. tabPressed: function(srcEl, nonPrintKeyStatus) {
  6635. if (this.actionMode) {
  6636. var $srcEl = $(srcEl);
  6637. var $currentTd;
  6638. if (($srcEl.hasClass('tabCycleEnd')) && (!nonPrintKeyStatus.isShiftKeyPressed)) {
  6639. $currentTd = $($(srcEl).closest('td')[0]);
  6640. $currentTd.find('.tabCycleStart').focus();
  6641. return false;
  6642. } else if (($srcEl.hasClass('tabCycleStart')) && (nonPrintKeyStatus.isShiftKeyPressed)) {
  6643. $currentTd = $($(srcEl).closest('td')[0]);
  6644. $currentTd.find('.tabCycleEnd').focus();
  6645. return false;
  6646. } else {
  6647. return true;
  6648. }
  6649. } else {
  6650. return true;
  6651. }
  6652. },
  6653. upPressed: function(srcEl) {
  6654. if (!this.actionMode) {
  6655. var $trEl = $($(srcEl).closest('tr')[0]);
  6656. var nextTr = $trEl.prev('tr');
  6657. this._processUpDownMove(srcEl, $trEl, nextTr);
  6658. }
  6659. return true;
  6660. },
  6661. _processUpDownMove: function(srcEl, $trEl, nextTr) {
  6662. var $currentTd = $($(srcEl).closest('td')[0]);
  6663. var nextTD = $(nextTr).children()[$currentTd.index()];
  6664. this.navObj.changeFocusFrom($(srcEl), $currentTd, $(nextTD));
  6665. },
  6666. downPressed: function(srcEl) {
  6667. if (!this.actionMode) {
  6668. var $trEl = $($(srcEl).closest('tr')[0]);
  6669. var nextTr = $trEl.next('tr');
  6670. this._processUpDownMove(srcEl, $trEl, nextTr);
  6671. }
  6672. return true;
  6673. },
  6674. rightPressed: function(srcEl) {
  6675. if (!this.actionMode) {
  6676. var $currentTd = $($(srcEl).closest('td')[0]);
  6677. var nextTD = $currentTd.next('td');
  6678. var focusElFound = false;
  6679. while (nextTD.length > 0 && !focusElFound) {
  6680. focusElFound = this.navObj.changeFocusFrom($(srcEl), $currentTd, $(nextTD));
  6681. nextTD = nextTD.next('td');
  6682. }
  6683. }
  6684. return true;
  6685. },
  6686. leftPressed: function(srcEl) {
  6687. if (!this.actionMode) {
  6688. var $currentTd = $($(srcEl).closest('td')[0]);
  6689. var nextTD = $currentTd.prev('td');
  6690. var focusElFound = false;
  6691. while (nextTD.length > 0 && !focusElFound) {
  6692. focusElFound = this.navObj.changeFocusFrom($(srcEl), $currentTd, $(nextTD));
  6693. nextTD = nextTD.prev('td');
  6694. }
  6695. }
  6696. return true;
  6697. }
  6698. });
  6699. return TableNavigatorPlugin;
  6700. });
  6701. /*
  6702. *+------------------------------------------------------------------------+
  6703. *| Licensed Materials - Property of IBM
  6704. *| IBM Cognos Products: Content Explorer
  6705. *| (C) Copyright IBM Corp. 2015, 2017
  6706. *|
  6707. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6708. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6709. *+------------------------------------------------------------------------+
  6710. */
  6711. define('bacontentnav/utils/ListControlWidgetNavigator',[
  6712. './TableNavigatorPlugin'
  6713. ], function(TableNavigatorPlugin) {
  6714. 'use strict';
  6715. var ListControlWidgetNavigator = TableNavigatorPlugin.extend({
  6716. upPressed: function(srcEl, options) {
  6717. options.closestTr = $(srcEl).closest('tr');
  6718. this._processEvent(options);
  6719. ListControlWidgetNavigator.inherited('upPressed', this, arguments);
  6720. },
  6721. downPressed: function(srcEl, options) {
  6722. options.closestTr = $(srcEl).closest('tr');
  6723. this._processEvent(options);
  6724. ListControlWidgetNavigator.inherited('downPressed', this, arguments);
  6725. },
  6726. _processEvent: function(options) {
  6727. try {
  6728. options._keyDownEvent.preventDefault();
  6729. var dt = (this.navObj.$el.length === 1) ? this.navObj.$el : $(this.navObj.$el[1]);
  6730. this._totalRecords = this._totalRecords || dt.DataTable().page.info().recordsTotal;
  6731. this._lastRenderedRow = dt.find('tr:last').index() + 1;
  6732. this.fCallBack({
  6733. dataTable: dt,
  6734. currentRow: options.closestTr,
  6735. lastRenderedRow: this._lastRenderedRow,
  6736. dTTotalRecords: this._totalRecords
  6737. });
  6738. } catch (error) {
  6739. window.console.error('Expecting _keyDownEvent to be here.');
  6740. window.console.error(error);
  6741. }
  6742. }
  6743. });
  6744. return ListControlWidgetNavigator;
  6745. });
  6746. /*
  6747. *+------------------------------------------------------------------------+
  6748. *| Licensed Materials - Property of IBM
  6749. *| IBM Cognos Products: Content Explorer
  6750. *| (C) Copyright IBM Corp. 2016
  6751. *|
  6752. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6753. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6754. *+------------------------------------------------------------------------+
  6755. */
  6756. define('bacontentnav/utils/WidgetNavigator',[
  6757. '../lib/@waca/core-client/js/core-client/ui/core/Class',
  6758. '../lib/@waca/core-client/js/core-client/ui/KeyCodes',
  6759. './TableNavigatorPlugin',
  6760. './ListControlWidgetNavigator',
  6761. 'underscore'
  6762. ], function(Class, KeyCodes, TableNavigatorPlugin, ListControlWidgetNavigator, _) {
  6763. 'use strict';
  6764. /***
  6765. handlers are plugable classes that must implement the following api:
  6766. focusElmentContainer property representing the element name of the element that contains all the focusable elements within a cell
  6767. upPressed - method respond to up key navigations return true if the press should continue propagation false if the press should not
  6768. downPressed - method respond to down key navigation return true if the press should continue propagation false if the press should not
  6769. rightPressed - method respond to right key navigation return true if the press should continue propagation false if the press should not
  6770. leftPressed - method respond to left key navigation return true if the press should continue propagation false if the press should not
  6771. enterPressed - method respond to enter key return true if the press should continue propagation false if the press should not
  6772. Note that upper case must be used for the handlerMap key
  6773. **/
  6774. var handlerMap = {
  6775. 'TABLE': TableNavigatorPlugin,
  6776. 'LISTCONTROL': ListControlWidgetNavigator
  6777. };
  6778. var WidgetNavigator = Class.extend({
  6779. /**
  6780. options.$el - containing element of the widget
  6781. options.focusClass - class used to find focusable elements
  6782. **/
  6783. init: function(options) {
  6784. WidgetNavigator.inherited('init', this, arguments);
  6785. _.extend(this, options);
  6786. var elName = this.$el.prop('tagName');
  6787. var elClassName = this.$el.prop('className');
  6788. var elClassNameList = [];
  6789. if (elClassName !== undefined) {
  6790. elClassNameList = this.$el.prop('className').split(' ');
  6791. }
  6792. for (var index = 0; index < elClassNameList.length; index += 1) {
  6793. var currentClass = elClassNameList[index].toUpperCase();
  6794. if (handlerMap[currentClass]) {
  6795. this.handler = new handlerMap[currentClass];
  6796. this.handler.fCallBack = this.fCallBack || undefined;
  6797. this.fCallBack = undefined;
  6798. break;
  6799. }
  6800. }
  6801. if (this.handler === undefined) {
  6802. var handConst = handlerMap[elName];
  6803. if (handConst) {
  6804. this.handler = new handConst;
  6805. } else {
  6806. //if the handler is still undefined then just create a table handler by default
  6807. this.handler = new TableNavigatorPlugin();
  6808. }
  6809. }
  6810. this.handler.navObj = this;
  6811. this.setInitialTabIndex();
  6812. this.installKeyHandler();
  6813. },
  6814. installKeyHandler: function() {
  6815. this.$el.on('keydown keyup', this._keyHandler.bind(this));
  6816. },
  6817. _keyHandler: function(evt) {
  6818. var sourceEl = evt.target;
  6819. var result = true;
  6820. var options = {};
  6821. options.isShiftKeyPressed = evt.shiftKey;
  6822. options._keyDownEvent = (_.isFunction(this.handler.fCallBack)) ? evt : undefined;
  6823. if (evt.type === 'keyup') {
  6824. switch (evt.which) {
  6825. case KeyCodes.ESCAPE:
  6826. // Escape has to be on keyup in order to prevent the default functionality of closing the slideout
  6827. result = this.handler.escPressed(sourceEl, options);
  6828. break;
  6829. default:
  6830. }
  6831. } else {
  6832. switch (evt.which) {
  6833. case KeyCodes.UP_ARROW:
  6834. result = this.handler.upPressed(sourceEl, options);
  6835. break;
  6836. case KeyCodes.DOWN_ARROW:
  6837. result = this.handler.downPressed(sourceEl, options);
  6838. break;
  6839. case KeyCodes.LEFT_ARROW:
  6840. result = this.handler.leftPressed(sourceEl, options);
  6841. break;
  6842. case KeyCodes.SPACE:
  6843. result = this.handler.spacePressed(sourceEl);
  6844. break;
  6845. case KeyCodes.RIGHT_ARROW:
  6846. result = this.handler.rightPressed(sourceEl, options);
  6847. break;
  6848. case KeyCodes.ENTER:
  6849. result = this.handler.enterPressed(sourceEl, options);
  6850. break;
  6851. case KeyCodes.TAB:
  6852. result = this.handler.tabPressed(sourceEl, options);
  6853. break;
  6854. default:
  6855. }
  6856. }
  6857. if (!result) {
  6858. evt.preventDefault();
  6859. }
  6860. if (evt.which === KeyCodes.RIGHT_ARROW) {
  6861. evt.preventDefault();
  6862. }
  6863. return result;
  6864. },
  6865. getFocusableItemsList: function($parentNode) {
  6866. if ($parentNode.children().length === 0) {
  6867. if ($parentNode.hasClass(this.focusClass)) {
  6868. return $parentNode;
  6869. } else {
  6870. return $();
  6871. }
  6872. } else {
  6873. return $parentNode.find('.' + this.focusClass);
  6874. }
  6875. },
  6876. _updateTabIndeciesFor: function($oldParent, $newParent) {
  6877. if ($oldParent) {
  6878. $oldParent.attr('tabindex', '-1');
  6879. }
  6880. $newParent.attr('tabindex', '0');
  6881. },
  6882. /* $srcEl is the element that currently has the focus
  6883. $oldParent is the containing element of the srcElement
  6884. $newParent is a potential candidate for focus change, if there are not focusable elements found
  6885. in $newParent then it will return false and do nothing. It is up to the caller to try another candidate
  6886. */
  6887. changeFocusFrom: function($srcEl, $oldParent, $newParent) {
  6888. var $newFocusEl = this.getFocusableItemsList($newParent);
  6889. if ($newFocusEl.length === 0) {
  6890. return false;
  6891. } else {
  6892. /*
  6893. tabable items that are only visible on hover need some special handling to show them
  6894. first and then we can focus to them....otherwise bad things happen.....terrible things
  6895. */
  6896. var oldFocusList = this.getFocusableItemsList($oldParent);
  6897. var $oldFocEl = $(oldFocusList[0]);
  6898. // jQuery addClass, hasClass and removeClass does not work for SVG elements (use DOM methods)
  6899. if ($oldFocEl[0].classList.contains('tempAddVis')) {
  6900. $oldFocEl[0].classList.remove('tempAddVis');
  6901. $oldFocEl.css('visibility', '');
  6902. }
  6903. if ($newFocusEl.css('visibility') === 'hidden') {
  6904. $newFocusEl.css('visibility', 'visible');
  6905. $newFocusEl[0].classList.add('tempAddVis');
  6906. }
  6907. this._updateTabIndeciesFor($oldParent, $newParent);
  6908. $($newFocusEl[0]).closest(this.handler.focusElmentContainer).focus();
  6909. return true;
  6910. }
  6911. },
  6912. _hasScroll: function(el) {
  6913. var overflowY = $(el).css('overflow-y');
  6914. return (overflowY === 'scroll' || overflowY === 'auto') && el.scrollHeight > el.clientHeight;
  6915. },
  6916. _getScrollingParent: function($el) {
  6917. var res = null;
  6918. $el.parents().each(function(i, node){
  6919. if (this._hasScroll(node)) {
  6920. res = $(node);
  6921. return false;
  6922. }
  6923. }.bind(this));
  6924. return res;
  6925. },
  6926. // Sets the tab index to the first visible element containing focusClass
  6927. setInitialTabIndex: function() {
  6928. if (this.$el) {
  6929. var $fistFocusElList = this.$el.find('.' + this.focusClass);
  6930. var $scrollingTop = 0;
  6931. var $scrollingParent = this._getScrollingParent($fistFocusElList.first());
  6932. if ($scrollingParent) {
  6933. $scrollingTop = $scrollingParent[0].getBoundingClientRect().top;
  6934. }
  6935. $.each($fistFocusElList, function(i, node) {
  6936. var top = node.getBoundingClientRect().top;
  6937. if (top >= $scrollingTop) {
  6938. var $fistFocusEl = $(node);
  6939. var $currentTd = $($fistFocusEl.closest(this.handler.focusElmentContainer)[0]);
  6940. this._updateTabIndeciesFor(null, $currentTd);
  6941. return false;
  6942. }
  6943. }.bind(this));
  6944. }
  6945. }
  6946. });
  6947. return WidgetNavigator;
  6948. });
  6949. /*
  6950. *+------------------------------------------------------------------------+
  6951. *| Licensed Materials - Property of IBM
  6952. *| IBM Cognos Products: Content Explorer
  6953. *| (C) Copyright IBM Corp. 2015, 2018
  6954. *|
  6955. *| US Government Users Restricted Rights - Use, duplication or disclosure
  6956. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  6957. *+------------------------------------------------------------------------+
  6958. */
  6959. define('bacontentnav/common/ui/BreadcrumbDropDown',[
  6960. 'jquery',
  6961. '../../lib/@waca/core-client/js/core-client/ui/DropDownMenu',
  6962. '../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  6963. 'underscore'
  6964. ], function($, DropDownMenu, ContentFormatter, _) {
  6965. 'use strict';
  6966. var BreadCrumbDropDown = DropDownMenu.extend({
  6967. /*
  6968. * options.propagateEvent {boolean} - optional. true - event should be propagated
  6969. */
  6970. propagateEvent: true,
  6971. render: function() {
  6972. $(this.actionElement).on('primaryaction', this._handlePrimaryAction.bind(this));
  6973. this.$el = $(this.actionElement);
  6974. this.menuButton = $(this.actionElement);
  6975. this.menuButtonDom = this.actionElement;
  6976. this._setTitle();
  6977. $(window).on('shown.bs.popover', this._updatePopupover.bind(this));
  6978. return Promise.resolve(this.$el);
  6979. },
  6980. destroy: function(){
  6981. this.hidePopup();
  6982. $(this.actionElement).off('primaryaction');
  6983. $(window).off('shown.bs.popover');
  6984. },
  6985. hidePopup: function() {
  6986. if (this.$ddPopover) {
  6987. this.$ddPopover.popover('destroy');
  6988. this.$ddPopover = null;
  6989. }
  6990. },
  6991. _handlePrimaryAction: function(event) {
  6992. /*jshint unused: false */
  6993. this._onMenuSelect(event);
  6994. if (!this.propagateEvent) {
  6995. event.stopPropagation();
  6996. }
  6997. return this.propagateEvent;
  6998. },
  6999. _updatePopupover: function(event) {
  7000. if ((event) && (event.target) && (event.target.title === this.title) && (this.$ddPopover)) {
  7001. var popupId = this.$ddPopover.attr('aria-describedby');
  7002. var $popupEl = $('#' + popupId);
  7003. var $popupItems = $popupEl.find('.commonMenuLink');
  7004. var maxWidth = $popupItems.width();
  7005. _.each($popupItems, function(item) {
  7006. var menuChildren = $(item).children();
  7007. var $iconEl;
  7008. var $spanEl;
  7009. var calMaxWidth;
  7010. if ($(menuChildren[0]).is('svg')) {
  7011. $iconEl = $(menuChildren[0]);
  7012. $spanEl = $(menuChildren[1]);
  7013. calMaxWidth = maxWidth - $iconEl.outerWidth(true);
  7014. } else {
  7015. $spanEl = $(menuChildren[0]);
  7016. var iconWidth = $('.commonMenuLink .svgIcon', menuChildren).outerWidth(true);
  7017. var spanPadding = $spanEl.innerWidth() - $spanEl.width();
  7018. calMaxWidth = maxWidth - iconWidth - spanPadding;
  7019. }
  7020. ContentFormatter.updateEllipsesBasedOnWidth($spanEl[0], calMaxWidth, $spanEl.width());
  7021. }, this);
  7022. }
  7023. }
  7024. });
  7025. return BreadCrumbDropDown;
  7026. });
  7027. /*
  7028. *+------------------------------------------------------------------------+
  7029. *| Licensed Materials - Property of IBM
  7030. *| IBM Cognos Products: ba-content-nav
  7031. *| (C) Copyright IBM Corp. 2015, 2018
  7032. *|
  7033. *| US Government Users Restricted Rights - Use, duplication or disclosure
  7034. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  7035. *+------------------------------------------------------------------------+
  7036. */
  7037. define('bacontentnav/common/ui/Breadcrumbs',[
  7038. '../../lib/@waca/core-client/js/core-client/ui/View',
  7039. 'jquery',
  7040. 'underscore',
  7041. './BreadcrumbDropDown',
  7042. '../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  7043. '../../utils/ContentStoreObject',
  7044. '../../utils/UIHelper',
  7045. '../../nls/StringResource',
  7046. '../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  7047. '../../lib/@waca/core-client/js/core-client/utils/Utils'
  7048. ], function(View, $, _, DropDownMenu, ContentFormatter, ContentStoreObject, UIHelper, StringResource, BidiUtil, Utils) {
  7049. 'use strict';
  7050. var BreadCrumb = View.extend({
  7051. /**
  7052. options.$el {jquery node} - container node where the breadcrumbs should be rendered
  7053. options.ancestors {array} - ancestors property from content service
  7054. options.navigateCallback - callback to call when a breadcrumb part is clicked
  7055. **/
  7056. collapsedBreadCrumbIcon: 'ba_content_nav-folder-overflow_16',
  7057. previousIcon: 'ba_content_nav-back-previous_16',
  7058. chevronRightIcon: (BidiUtil.isMirrored ? 'common-chevron_left' : 'common-chevron_right'),
  7059. defaultWidth: 400,
  7060. bcPrev: null,
  7061. NumOfResponsiveBC: 3,
  7062. init: function(options) {
  7063. BreadCrumb.inherited('init', this, arguments);
  7064. _.extend(this, options);
  7065. this._bSetFocusToSelf = false;
  7066. this._oVisibleBreadcrumb = null;
  7067. },
  7068. _getOuterWidth: function($elem, inclusive) {
  7069. // jQuery 3 returns undefined (previously, null) for an empty set of elements,
  7070. // so we need to make sure we have a number to do operations correctly
  7071. return $elem.outerWidth(!!inclusive) || 0;
  7072. },
  7073. _getMenuItems: function(ancestors) {
  7074. var menuItems = [];
  7075. var i;
  7076. for (i = 0; i < ancestors.length - 1; i += 1) {
  7077. var ancestor = ancestors[i];
  7078. var icon = UIHelper.getSVGIconForType(ContentStoreObject.getType(ancestor));
  7079. if (icon.indexOf('#') === 0) {
  7080. icon = icon.substring(1);
  7081. }
  7082. var newMenuItem = {
  7083. 'label': ContentStoreObject.getName(ancestor),
  7084. 'icon': icon,
  7085. 'onSelect': this.breadcrumbClicked.bind(this, i)
  7086. };
  7087. menuItems.push(newMenuItem);
  7088. }
  7089. return menuItems;
  7090. },
  7091. /**
  7092. Renders the collapsed breadcrumb control for breadcrumbs that do not fit the screen
  7093. **/
  7094. _renderCollapsedItems: function(container) {
  7095. var length = this.ancestors.length;
  7096. var list = $('<ul>', {
  7097. 'class': 'breadcrumbCompact'
  7098. });
  7099. container.append(list);
  7100. var listItem = this._createBreadcrumbItem();
  7101. list.append(listItem);
  7102. this._createCollapsedBreadCrumbItem(listItem, this.collapsedBreadCrumbIcon, length - 1);
  7103. this._updateResponsiveItems(list);
  7104. },
  7105. /**
  7106. * Creates a list item element that represents one breadcrumb item
  7107. *
  7108. * @param bIsFocusable if the item should be focusable
  7109. * @param label the item's label <optional>
  7110. * @param iconId the item's icon id <optional>
  7111. * @param index the item's index in the list of items <optional
  7112. * @return a list item element that represents one breadcrumb item
  7113. **/
  7114. _createBreadcrumbItem: function(bIsFocusable, label, iconId, index) {
  7115. var $elem = $('<li>', {
  7116. 'class': 'active'
  7117. });
  7118. if (iconId) {
  7119. $elem.append(this._createSvgIcon(iconId));
  7120. }
  7121. var $div = $('<div>', {
  7122. 'class': 'breadcrumbItemTxt'
  7123. });
  7124. var $span = $('<span>');
  7125. if (bIsFocusable) {
  7126. $div.attr('tabindex', '0');
  7127. $div.attr('role', 'link');
  7128. if (index !== undefined && index >=0) {
  7129. $div.on('primaryaction', this.breadcrumbClicked.bind(this, index));
  7130. }
  7131. } else {
  7132. $div.attr('role', 'presentation');
  7133. }
  7134. if (label) {
  7135. $div.attr('aria-label', label);
  7136. $span.text(BidiUtil.enforceTextDirection(label));
  7137. }
  7138. $div.append($span);
  7139. $elem.append($div);
  7140. return $elem;
  7141. },
  7142. /**
  7143. * Renders the big breadcrumb control for breadcrumbs that fit the screen
  7144. *
  7145. * @param container a container element for the full items list
  7146. **/
  7147. _renderFullItems: function(container) {
  7148. var length = this.ancestors.length;
  7149. var $list = $('<ul>', {
  7150. 'class': 'breadcrumbFull'
  7151. });
  7152. container.append($list);
  7153. for (var i = 1; i < length; i += 1) {
  7154. var bIsLastItem = (i === (length - 1));
  7155. var bIsFocusable = !bIsLastItem;
  7156. var name = ContentStoreObject.getName(this.ancestors[i]);
  7157. $list.append(this._createBreadcrumbItem(bIsFocusable, name, this.chevronRightIcon, i));
  7158. }
  7159. },
  7160. _Ellipsize: function($item) {
  7161. var stringWidth = $item.find('span').width();
  7162. ContentFormatter.updateEllipsesBasedOnWidth($item.find('span').get(0), this._getOuterWidth($item), stringWidth);
  7163. },
  7164. _createEllipses: function(widthForBreadCrumbs) {
  7165. void (widthForBreadCrumbs);
  7166. var $compactBreadCrumb = this.$el.find('.breadcrumbCompact');
  7167. var items = $compactBreadCrumb.find('li.responsive .breadcrumbItemTxt');
  7168. if (items.length > 0) {
  7169. for(var i = items.length - 1; i >=0 ; i--) {
  7170. var $item = $(items.get(i));
  7171. var ancestor = this.ancestors[this.ancestors.length - items.length + i];
  7172. if(items.find('span').width() !== 0){
  7173. $item.find('span').text(BidiUtil.enforceTextDirection(ContentStoreObject.getName(ancestor)));
  7174. }
  7175. this._Ellipsize($(items.get(i)));
  7176. }
  7177. }
  7178. },
  7179. _getResponsiveWidth: function() {
  7180. var $appBar = this.$el.parents('.appbarRow');
  7181. var $unresponsiveAppBar = $appBar.find('.appbarTrailing');
  7182. var $breadcrumbPrevious = this.$el.find('.breadcrumbPrevious');
  7183. var $breadcrumbRoot = this.$el.find('.breadcrumbRoot');
  7184. var widthForBreadCrumbs = this._getOuterWidth($appBar) - this._getOuterWidth($unresponsiveAppBar);
  7185. widthForBreadCrumbs = widthForBreadCrumbs - this._getOuterWidth($breadcrumbPrevious);
  7186. widthForBreadCrumbs = widthForBreadCrumbs - this._getOuterWidth($breadcrumbRoot);
  7187. return widthForBreadCrumbs;
  7188. },
  7189. _showResponsiveItems: function() {
  7190. var fullBreadCrumb = this.$el.find('.breadcrumbFull');
  7191. var compactBreadCrumb = this.$el.find('.breadcrumbCompact');
  7192. var $breadcrumbs = this.$el.find('.breadcrumbs');
  7193. $breadcrumbs.removeClass('compactMode');
  7194. var widthForBreadCrumbs = this._getResponsiveWidth();
  7195. var fullBreadCrumbWidth = this._getFullWidth(fullBreadCrumb);
  7196. if (widthForBreadCrumbs <= fullBreadCrumbWidth) {
  7197. this._updateNumOfResponsiveBC();
  7198. $breadcrumbs.addClass('compactMode');
  7199. this._oVisibleBreadcrumb = compactBreadCrumb;
  7200. } else {
  7201. $breadcrumbs.removeClass('compactMode');
  7202. this._oVisibleBreadcrumb = fullBreadCrumb;
  7203. }
  7204. widthForBreadCrumbs = this._getResponsiveWidth();
  7205. this._checkRoot($breadcrumbs);
  7206. this._createEllipses(widthForBreadCrumbs);
  7207. },
  7208. _updateNumOfResponsiveBC: function(){
  7209. var appBar = this.$el.parents('.appbarRow');
  7210. var appBarWidth = this._getOuterWidth(appBar);
  7211. var appBarDefaultWidth = 365;
  7212. var appBarBreakpointWidth = 290;
  7213. if(appBarWidth <= appBarDefaultWidth){
  7214. //create breakpoints that determines numOfResponsiveBC
  7215. this.NumOfResponsiveBC = ((appBarWidth >= appBarBreakpointWidth && this.ancestors.length > 3) || (appBarWidth < appBarBreakpointWidth && this.ancestors.length > 2)) ? 1 : 3;
  7216. }else{
  7217. this.NumOfResponsiveBC = 3;
  7218. }
  7219. this._updateCollapsedBreadCrumb();
  7220. },
  7221. _getFullWidth: function(elem) {
  7222. var totalWidth = 0;
  7223. $.each(elem.children(), function(i, value) {
  7224. //Passing 'true' to outerWidth to include the margins in the width of the element
  7225. totalWidth += this._getOuterWidth($(value), true);
  7226. }.bind(this));
  7227. return totalWidth;
  7228. },
  7229. _goUp: function() {
  7230. if (this.ancestors.length - 2 >= 0) {
  7231. this.breadcrumbClicked(this.ancestors.length - 2);
  7232. }
  7233. },
  7234. _goRoot: function() {
  7235. this.breadcrumbClicked(0);
  7236. },
  7237. _createLeftArrow: function(nav) {
  7238. var $list = $('<ul>', {
  7239. 'class': 'breadcrumbPrevious'
  7240. });
  7241. var $item = $('<li>', {});
  7242. var $svgContainer = this._createSvgIcon(this.previousIcon);
  7243. $svgContainer.attr('tabindex', '0');
  7244. $svgContainer.attr('role', 'button');
  7245. $svgContainer.attr('title', StringResource.get('previous'));
  7246. $svgContainer.attr('aria-label', StringResource.get('previous'));
  7247. $svgContainer.on('primaryaction', this._goUp.bind(this));
  7248. if (BidiUtil.isMirrored) {
  7249. $svgContainer.css({ transform: 'scaleX(-1)' });
  7250. }
  7251. $item.append($svgContainer);
  7252. $list.append($item);
  7253. nav.append($list);
  7254. this.bcPrev = $list;
  7255. this._updateLeftArrowVisible();
  7256. },
  7257. _createRoot: function(nav) {
  7258. var $list = $('<ul>', {
  7259. 'class': 'breadcrumbRoot'
  7260. });
  7261. var $item = this._createRootItem();
  7262. $list.append($item);
  7263. $list = this.ancestors.length === 1 ? $list.addClass('currentFolder'):$list.removeClass('currentFolder');
  7264. nav.append($list);
  7265. },
  7266. _createRootItem: function() {
  7267. var $item = $('<li>', {});
  7268. var defaultName = ContentStoreObject.getName(this.ancestors[0]);
  7269. var iconId = UIHelper.getSVGIconForType(ContentStoreObject.getType(this.ancestors[0]));
  7270. var $iconEl = this._createSvgIcon(iconId);
  7271. $iconEl.attr('tabindex', '0');
  7272. $iconEl.attr('role', 'button');
  7273. $iconEl.on('primaryaction', this._goRoot.bind(this));
  7274. $iconEl.attr('aria-label', defaultName);
  7275. $iconEl.attr('title', defaultName);
  7276. var rootName = BidiUtil.enforceTextDirection(defaultName);
  7277. var $div = $('<div>', {
  7278. 'class': 'breadcrumbRootTxt'
  7279. });
  7280. $div.text(rootName);
  7281. $div.attr('tabindex', '0');
  7282. $div.attr('role', 'link');
  7283. $div.attr('aria-label', defaultName);
  7284. $div.on('primaryaction', this._goRoot.bind(this));
  7285. $item.append($iconEl);
  7286. $item.append($div);
  7287. return $item;
  7288. },
  7289. _checkRoot: function(container) {
  7290. if (this.ancestors.length !== 1) {
  7291. container.find('.breadcrumbCustomRoot').remove();
  7292. return;
  7293. }
  7294. if (this.$el && this.$el.parents('.pageView').length) {
  7295. var slideout = this.$el.parents('.pageView');
  7296. if (slideout.get(0).id === 'customFoldersSlideoutContent') {
  7297. var item = this._createBreadcrumbItem(false, this.ancestors[0].defaultName, this.collapsedBreadCrumbIcon, 0);
  7298. item.addClass('breadcrumbCustomRoot').addClass('responsive');
  7299. container.find('.breadcrumbCompact').append(item);
  7300. this._Ellipsize(item.find('div.breadcrumbItemTxt'));
  7301. }
  7302. }
  7303. },
  7304. /**
  7305. Renders the breadcrumb control
  7306. **/
  7307. render: function() {
  7308. if (!this.ancestors) {
  7309. return;
  7310. }
  7311. this.$el.addClass('breadcrumbContainer');
  7312. var container = $('<div>', {
  7313. 'class': 'breadcrumbs',
  7314. 'aria-label': this.label,
  7315. 'aria-controls': this.ariaControls
  7316. });
  7317. this.$el.append(container);
  7318. this._createLeftArrow(container);
  7319. this._createRoot(container);
  7320. this._renderCollapsedItems(container);
  7321. this._renderFullItems(container);
  7322. this._showResponsiveItems();
  7323. return this;
  7324. },
  7325. resize: function() {
  7326. this._showResponsiveItems();
  7327. },
  7328. /**
  7329. Call the supplied callback for the breadcrumb that's been clicked
  7330. **/
  7331. breadcrumbClicked: function(index) {
  7332. this.navigateCallback(index);
  7333. },
  7334. /**
  7335. Call the supplied callback for the breadcrumb that's been clicked
  7336. **/
  7337. rootBreadcrumbClicked: function(event) {
  7338. if (event && event.target) {
  7339. var index = null;
  7340. if ($(event.target).is('li')) {
  7341. index = $(event.target).index();
  7342. } else if ($(event.target).is('span') || $(event.target).is('svg')) {
  7343. index = $(event.target).parent().index();
  7344. }
  7345. if (index !== null) {
  7346. this.breadcrumbClicked(index);
  7347. }
  7348. }
  7349. },
  7350. /**
  7351. Creates an SVG icon based on the icon id, and optional icon class.
  7352. **/
  7353. _createSvgIcon: function(iconId, iconClass) {
  7354. var $icon = $('<div class="bsIcon"></div>');
  7355. Utils.setIcon($icon, this.getSvgId(iconId));
  7356. if (iconClass) {
  7357. $icon.find('.svgIcon').addClass(iconClass);
  7358. }
  7359. return $icon;
  7360. },
  7361. _updateSvgIcon: function($parent, iconId) {
  7362. if ($parent) {
  7363. $parent.find('svg.svgIcon').first().remove();
  7364. Utils.setIcon($parent, this.getSvgId(iconId));
  7365. }
  7366. },
  7367. _updateRoot: function(breadcrumbs) {
  7368. var rootItem = this.ancestors[0];
  7369. var rootItemName = ContentStoreObject.getName(rootItem);
  7370. // get the root
  7371. var $breadcrumbRoot = this.$el.find('.breadcrumbRoot');
  7372. // update icon
  7373. var $icon = $breadcrumbRoot.find('.bsIcon');
  7374. $icon.attr('aria-label', rootItemName);
  7375. this._updateSvgIcon($icon, UIHelper.getSVGIconForType(ContentStoreObject.getType(rootItem)));
  7376. // update text
  7377. var $label = $breadcrumbRoot.find('.breadcrumbRootTxt');
  7378. $label.attr('aria-label', rootItemName);
  7379. $label.text(BidiUtil.enforceTextDirection(rootItemName));
  7380. // select if required
  7381. if (breadcrumbs.length === 1 ) {
  7382. $breadcrumbRoot.addClass('currentFolder');
  7383. } else {
  7384. $breadcrumbRoot.removeClass('currentFolder');
  7385. }
  7386. },
  7387. _updateFullBreadCrumb: function(breadcrumbs) {
  7388. var newBreadcrumbs = breadcrumbs.slice(1);
  7389. var i;
  7390. var $ul = this.$el.find('.breadcrumbFull');
  7391. var oldLength = $ul[0].childNodes.length;
  7392. var newLength = newBreadcrumbs.length;
  7393. if (newLength > oldLength) {
  7394. //update tabindex and role of previous last item
  7395. var prevLastItem = $ul.find('li:nth-child(' + oldLength + ')');
  7396. var prevLastItemTxt = prevLastItem.find('div.breadcrumbItemTxt');
  7397. prevLastItemTxt.attr('tabindex', '0');
  7398. prevLastItemTxt.attr('role', 'link');
  7399. for (i = oldLength; i < newLength; i += 1) {
  7400. var bIsLastItem = (i === (newLength - 1));
  7401. $ul.append(this._createBreadcrumbItem(!bIsLastItem, null, this.chevronRightIcon, i+1));
  7402. }
  7403. prevLastItemTxt.on('primaryaction', this.breadcrumbClicked.bind(this, oldLength));
  7404. } else {
  7405. for (i = oldLength; i > newLength; i -= 1) {
  7406. $($ul.children()[$ul[0].childNodes.length - 1]).remove();
  7407. }
  7408. //remove role=link from last item
  7409. var lastItem = $ul.find('li:last-child');
  7410. var lastItemTxt = lastItem.find('div.breadcrumbItemTxt');
  7411. lastItemTxt.removeAttr('tabindex');
  7412. lastItemTxt.attr('role', 'presentation');
  7413. }
  7414. for (i = 0; i < newLength; i += 1) {
  7415. var $textItem = $($ul[0].childNodes[i]).find('div.breadcrumbItemTxt');
  7416. var defaultName = ContentStoreObject.getName(newBreadcrumbs[i]);
  7417. $textItem.attr('aria-label', defaultName);
  7418. $textItem.find('span').get(0).textContent = BidiUtil.enforceTextDirection(defaultName);
  7419. }
  7420. },
  7421. _createDropDown: function(parentEl) {
  7422. var menuItems = this._getMenuItems(this.ancestors);
  7423. this.ddMenu = new DropDownMenu({
  7424. dropDownMenuSpec: {
  7425. 'class': 'breadcrumbs-popover',
  7426. 'title': this.name || '',
  7427. 'icon': this.collapsedBreadCrumbIcon,
  7428. 'items': menuItems,
  7429. 'actionElement': parentEl,
  7430. 'ddMenuPlacement': 'bottom',
  7431. 'propagateEvent': false
  7432. }
  7433. });
  7434. this.ddMenu.render();
  7435. },
  7436. _createCollapsedBreadCrumbItem: function($parentEl, icon, number) {
  7437. var $chevronRightIcon = this._createSvgIcon(this.chevronRightIcon);
  7438. var $iconEl = this._createSvgIcon(this.collapsedBreadCrumbIcon, 'collapsedBreadCrumbIcon');
  7439. $parentEl.off('primaryaction');
  7440. if (number > 0) {
  7441. this._createDropDown($iconEl);
  7442. $iconEl.attr('aria-haspopup', 'true');
  7443. } else {
  7444. $parentEl.removeAttr('aria-haspopup');
  7445. $iconEl.on('primaryaction', this.rootBreadcrumbClicked.bind(this));
  7446. }
  7447. $parentEl.attr('role', 'link');
  7448. $parentEl.empty();
  7449. $iconEl.attr('tabindex', '0');
  7450. $iconEl.attr('role', 'button');
  7451. $iconEl.attr('aria-label', StringResource.get('collapsedBreadCrumb'));
  7452. $iconEl.attr('title', StringResource.get('collapsedBreadCrumb'));
  7453. $iconEl.addClass('collapsedBreadCrumbIcon');
  7454. $parentEl.append($chevronRightIcon);
  7455. $parentEl.append($iconEl);
  7456. },
  7457. _updateCollapsedBreadCrumb: function() {
  7458. var $ul = this.$el.find('.breadcrumbCompact');
  7459. var $firstElement = $($ul[0].childNodes[0]);
  7460. this._createCollapsedBreadCrumbItem($firstElement, UIHelper.getSVGIconForType(ContentStoreObject.getType(this.ancestors[0])), this.ancestors.length - 1);
  7461. this._updateResponsiveItems($ul);
  7462. },
  7463. _updateResponsiveItems: function($ul) {
  7464. $ul.find('li.responsive').remove();
  7465. for(var i = this.NumOfResponsiveBC; i > 0; i--) {
  7466. if ((this.ancestors.length - i) >= 1) {
  7467. var bIsFocusable = (i !== 1);
  7468. var name = ContentStoreObject.getName(this.ancestors[this.ancestors.length - i]);
  7469. var $item = this._createBreadcrumbItem(bIsFocusable, name, this.chevronRightIcon, this.ancestors.length - i);
  7470. $item.addClass('responsive');
  7471. $ul.append($item);
  7472. }
  7473. }
  7474. },
  7475. _updateLeftArrowVisible: function() {
  7476. if (this.ancestors.length > 1) {
  7477. this.bcPrev.removeClass('hidden');
  7478. } else {
  7479. this.bcPrev.addClass('hidden');
  7480. }
  7481. },
  7482. updateBreadcrumb: function(newAncestors) {
  7483. if (this.ddMenu) {
  7484. this.ddMenu.hidePopup();
  7485. }
  7486. if (!newAncestors) {
  7487. return;
  7488. }
  7489. this.ancestors = newAncestors;
  7490. this._updateRoot(newAncestors);
  7491. this._updateFullBreadCrumb(newAncestors);
  7492. this._updateLeftArrowVisible();
  7493. this._updateCollapsedBreadCrumb();
  7494. this._showResponsiveItems();
  7495. },
  7496. getSvgId: function(iconId) {
  7497. return iconId.charAt(0) === '#'? iconId.substr(1) : iconId;
  7498. }
  7499. });
  7500. return BreadCrumb;
  7501. });
  7502. /*
  7503. *+------------------------------------------------------------------------+
  7504. *| Licensed Materials - Property of IBM
  7505. *| IBM Cognos Products: Content Explorer
  7506. *| (C) Copyright IBM Corp. 2015, 2019
  7507. *|
  7508. *| US Government Users Restricted Rights - Use, duplication or disclosure
  7509. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  7510. *+------------------------------------------------------------------------+
  7511. */
  7512. /**
  7513. Base class for Content Views that need to show breadcrumbs, filters or a content list
  7514. Properties to override
  7515. trackBreadcrumbs {boolean} - defaults to false, set to true if you want to track breadcrumb information (if showBreadcrumbs is true, it is not necessary to set this to true)
  7516. showBreadcrumbs {boolean} - defaults to false, set to true if you want to show breadcrumbs
  7517. showFilter {boolean} - defaults to false, set to true if you want to show the filter control
  7518. showAddFolder {boolean} - defaults to false, set to true if you want to show the 'Add folder' button
  7519. showNewItem {boolean} - defaults to false, set to true if you want to show the 'New' button
  7520. stateId {string} - if you want the save state information (filter setting, sorting, ...) set this property to a unique value (i.e. class name)
  7521. contentListContainer {object} - optional container
  7522. Functions to override
  7523. renderContent - gets called after the content bar is rendered. This is where you'll render your own content or call renderContentList with options to render the data table.
  7524. This method needs to return a promise that will be resolved when the content is done drawing.
  7525. getModuleName - if your view supports Navigating, then you must override this function and return the path to your View
  7526. getViewContainerClass - if you want to specify a different css class on the main container div
  7527. contentbarItems - Override if you want to add extra controls in the content bar. Returns an array of items, uses the Gemini syntax
  7528. getFilterColumnIndex - If you're using the filter control and the icon column isn't the first column, override this returning the index of the 'type' column to be used to filter
  7529. getRootAncestor - If you're using breadcrumbs, this function should return the Label to use for the first breadcrumb
  7530. Functions to know about
  7531. renderContentList - creates a ListControl object to render the table. The possible options are documented in bacontentnav/common/ui/ListControl.js
  7532. removeContentList - deletes the ListControl from the View
  7533. **/
  7534. define('bacontentnav/common/ContentListPageView',[
  7535. 'jquery',
  7536. 'underscore',
  7537. '../lib/@waca/baglass/js/baglass/app/ContentView',
  7538. './ui/ListControl',
  7539. './ui/ContentBar',
  7540. '../nls/StringResource',
  7541. '../utils/ContentStoreObject',
  7542. '../utils/UIHelper',
  7543. '../utils/GlassContextHelper',
  7544. '../utils/A11YHelper',
  7545. '../utils/WidgetNavigator',
  7546. '../utils/ContentServiceUrls',
  7547. './ui/Breadcrumbs',
  7548. './ui/BreadcrumbDropDown'
  7549. /* jshint maxparams:false */
  7550. ], function($, _, ContentView, ListControl, ContentBar, StringResource, ContentStoreObject,
  7551. UIHelper, GlassContextHelper, A11YHelper, WidgetNavigator, ContentServiceUrls, Breadcrumbs, DropDownMenu) { //NOSONAR
  7552. 'use strict'; //NOSONAR
  7553. var ContentListPageView = ContentView.extend({
  7554. showSort: false,
  7555. contentListFacets: null,
  7556. contentListSortIndexes: null,
  7557. contentListFilters: ['name', ContentStoreObject.MODIFICATION_TIME],
  7558. currentFilters: {}, // Key/value JSON holding filter id/name pair
  7559. /**
  7560. Update the data table by re-fetching the data
  7561. **/
  7562. refresh: function(url) {
  7563. this.logger.debug('ContentListPageView.refresh');
  7564. // ensure flag for content-nav team root is correct
  7565. this._updateTeamRoot();
  7566. if (this._listControl) {
  7567. this._listControl.updateDatatable(url);
  7568. }
  7569. // Hide multiselect bar if it's still displayed
  7570. if (this.multiselectBar !== undefined && this.multiselectBar.isVisible()) {
  7571. this._listControl._clearRows();
  7572. this.multiselectBar.hide();
  7573. this.contentBar.show();
  7574. }
  7575. },
  7576. /**
  7577. @options.url {string} - Rest URL to used to query the items to display. (itemLink)
  7578. @options.selfUrl {boolean} - Rest URL for the object to display (selfLink)
  7579. @options.showBreadcrumbs {boolean} - should the breadcrumb control be shown. Default is false
  7580. @options.showFilter {boolean} - should the filter control be shown. Default is false
  7581. @options.showAddFolder {boolean} - should the Add Folder button be shown. Default is false
  7582. @options.showNewItem {boolean} - should the New button be shown. Default is false
  7583. @options.ancestors {array} - ancestors property from the content service
  7584. @options.skipAncestors {boolean} - should the ancestors to be rendered. Default is false
  7585. @options.showSwitchButton {boolean} - should the view switch button be shown. Default is false. Implement _getSwitchViewIcon to choose icon
  7586. @options.navigateCallback {function} - if you want to be notified when navigation takes place
  7587. @options.navigateOnRowSelect {boolean} - default false
  7588. @options.selectedRow {array} - select default rows in the contentList
  7589. **/
  7590. init: function(options) {
  7591. this.ancestors = [];
  7592. this.showSwitchButton = false;
  7593. // Default is to not show the breadcrumbs of filter
  7594. this.showBreadcrumbs = false;
  7595. this.trackBreadcrumbs = false;
  7596. this.showFilter = false;
  7597. this.skipAncestors = false;
  7598. this.showNewItem = false;
  7599. this.navigateOnRowSelect = false;
  7600. this._urlParameters = {};
  7601. // Override this in your subclasses if you show filter
  7602. //otherwise the filters will collide
  7603. this.menuNamePrefix = 'CONTENTLISTPV_';
  7604. // Reset the filter dropdown to it's default (All Content)
  7605. this.updateFilterString('');
  7606. ContentListPageView.inherited('init', this, arguments);
  7607. _.extend(this, options);
  7608. // WHAAA TODO HACK, ContentStoreObject was designed as a singleton, when relatively referenced,
  7609. // it doesn't have the glassContext set, reset it here
  7610. ContentStoreObject.setGlassContext(this.glassContext);
  7611. this.facets = this.getSortSpec();
  7612. this.sortMappingSpec = this.getSortMappingSpec();
  7613. this._resetSelectedSortViewFacets();
  7614. },
  7615. _findFolderCmId: function() {
  7616. if (this.folder && !this._folderIsId()) {
  7617. return this.glassContext.getSvc('.Content')
  7618. .then(function(contentSvc) {
  7619. return contentSvc.getPathUrl(this.folder);
  7620. }.bind(this))
  7621. .then(function(requestEndpoint) {
  7622. return this.glassContext.getCoreSvc('.Ajax').ajax({
  7623. url: requestEndpoint,
  7624. type: 'GET',
  7625. dataType: 'json'
  7626. });
  7627. }.bind(this))
  7628. .then(function(result) {
  7629. this.folder = result.data.data[0].id;
  7630. }.bind(this));
  7631. } else {
  7632. return Promise.resolve();
  7633. }
  7634. },
  7635. /**
  7636. * Main entry point to render the View
  7637. **/
  7638. render: function() {
  7639. return new Promise(function(resolve, reject) {
  7640. this.getContainer().addClass(this.getViewContainerClass());
  7641. $('.dialogBlockerCell').addClass('transparent');
  7642. UIHelper.initializeRegistry(this.glassContext)
  7643. .then(function() {
  7644. return this._findFolderCmId()
  7645. .then(function() {
  7646. this.selfUrl = this.selfUrl ? this.selfUrl : this._getDefaultSelfURL();
  7647. this.url = this.url ? this.url : this._getDefaultRequestURL();
  7648. return this._renderContentBar()
  7649. .then(function(contentbar) {
  7650. // Render the table after the context bar so it gets sized correctly
  7651. return (this.renderContent && this.renderContent() || Promise.resolve())
  7652. .then(function() {
  7653. this._renderSelectionControlBar();
  7654. $('.dialogBlockerCell').removeClass('transparent');
  7655. resolve(contentbar);
  7656. }.bind(this));
  7657. }.bind(this));
  7658. }.bind(this));
  7659. }.bind(this))
  7660. .catch(function(err){
  7661. reject(err);
  7662. });
  7663. // Populate the filter options
  7664. _.each(this.getFilterSpec(), function(filterObj) {
  7665. this.currentFilters[filterObj.name + '_' + this.id] = filterObj.name;
  7666. }.bind(this));
  7667. this._createMultiSelectBar();
  7668. // Pick up whether properties should be closing and close them here.
  7669. this.getContainer().on('clicktap', function(evt) {
  7670. var target = evt.target;
  7671. //The target is BUTTON on FF/IE and svg on Chrome/Safari
  7672. if (target.tagName && target.tagName.toLowerCase() === 'svg' && target.parentElement && target.parentElement.tagName.toLowerCase() === 'button') {
  7673. target = evt.target.parentElement;
  7674. }
  7675. if ($(target).hasClass('parentProperties') && $(target).hasClass('common-configure-manage')) {
  7676. return true;
  7677. }
  7678. if (this._retainProperties) {
  7679. this._retainProperties = false;
  7680. }
  7681. }.bind(this));
  7682. // Responsive sizing (designed for iPad for now)
  7683. var debounced = _.debounce(this._adjustWidth.bind(this), 300);
  7684. this._resizeHandler = $(window).on('resize', debounced);
  7685. this._adjustWidth();
  7686. if (this.slideout) {
  7687. this.slideout.on('show', function() {
  7688. this.refresh();
  7689. }.bind(this));
  7690. this.getContainer().attr('tabindex', '0');
  7691. }
  7692. }.bind(this));
  7693. },
  7694. bindWidgetNavigator: function() {
  7695. var contentViewSwitcherTable = this.getContainer().find('.contentViewSwitcher table');
  7696. var contentViewSwitcherRows = contentViewSwitcherTable.find('tr');
  7697. this._listControl.widgetKeyController = new WidgetNavigator({
  7698. $el: this.getContainer().find('.listControl'),
  7699. focusClass: 'contentListFocusable',
  7700. fCallBack: this._listControl._processRowForMoreDataLoad.bind(this._listControl)
  7701. });
  7702. if (contentViewSwitcherTable) {
  7703. _.each(contentViewSwitcherRows, function(row) {
  7704. $(row).addClass('keyboardAccess');
  7705. });
  7706. }
  7707. },
  7708. /**
  7709. * Callback for row selection in the list view
  7710. **/
  7711. _selectRow: function(oData) {
  7712. if (this._propertiesOpen && this.propertiesOverride !== true) {
  7713. this.getContainer().focus();
  7714. this._retainProperties = true;
  7715. //deselect all text fields inside of the slideout
  7716. this.propertiesSlideout.$el.find(':focus').blur();
  7717. setTimeout(function() {
  7718. this.showProperties(oData);
  7719. }.bind(this), 10);
  7720. } else if (this.navigateOnRowSelect && ContentStoreObject.hasPermissions(oData, ['traverse']) &&
  7721. UIHelper.hasRequiredCapabilities(oData, this.typesToOpen, this.capabilitiesRequired)) {
  7722. this.navigate(oData);
  7723. }
  7724. if (_.isFunction(this.listControlCallback)) {
  7725. this.listControlCallback(oData);
  7726. }
  7727. this._resetPropertiesOverride();
  7728. },
  7729. _resetPropertiesOverride: function() {
  7730. this.propertiesOverride = false;
  7731. },
  7732. closeProperties: function() {
  7733. if (this._propertiesOpen) {
  7734. this.togglePropertiesMode();
  7735. if (this.propertiesSlideout) {
  7736. this.propertiesSlideout.onHide();
  7737. }
  7738. }
  7739. },
  7740. /**
  7741. * Appropriately shows properties in either the child pane or a pane on the right
  7742. **/
  7743. showProperties: function( /*objectInformation*/ ) {
  7744. // do nothing
  7745. },
  7746. closeNewURL: function() {
  7747. if (this._newURLOpen) {
  7748. this.toggleNewURLMode();
  7749. if (this.newURLSlideout) {
  7750. this.newURLSlideout.onHide();
  7751. }
  7752. }
  7753. },
  7754. /**
  7755. * Appropriately shows 'New URL' in the child pane
  7756. **/
  7757. showNewURL: function() {
  7758. // do nothing
  7759. },
  7760. /**
  7761. * Callback for a screen resize
  7762. **/
  7763. _adjustWidth: function() {
  7764. //detect iPad width
  7765. if ($(window).width() <= 1024) {
  7766. this.getContainer().addClass('pageview-small');
  7767. } else {
  7768. this.getContainer().removeClass('pageview-small');
  7769. }
  7770. if (this.contentBar) {
  7771. this.contentBar.resize();
  7772. }
  7773. },
  7774. /**
  7775. * Create a ListControl object to render the table. The possible options are documented in bacontentnav/common/ui/ListControl.js
  7776. * @param {object} - object containing options
  7777. * @returns - promise that will resolve to the rendered datatable
  7778. **/
  7779. renderContentList: function(options) {
  7780. // UI Registry should already be initialized - but some tests bypass 'render', so ensure it's done :(
  7781. return UIHelper.initializeRegistry(this.glassContext)
  7782. .then(function() {
  7783. options.urlParameters = this.getURLParameters();
  7784. this._listControl = new ListControl(this._getDatatableOptions(options));
  7785. if (options.dataManipulationCallback !== undefined) {
  7786. this.getListControl().dataManipulationCallback = options.dataManipulationCallback;
  7787. if (this.contentListSortIndexes) {
  7788. this.getListControl().sortIndexes = this.contentListSortIndexes;
  7789. }
  7790. }
  7791. return this._listControl.render().then(this.bindWidgetNavigator.bind(this));
  7792. }.bind(this));
  7793. },
  7794. /**
  7795. * Override this in any view that can switch modes
  7796. **/
  7797. switchViewMode: function() {
  7798. // do nothing
  7799. },
  7800. /**
  7801. * Add a new folder using listControl's addFolder()
  7802. **/
  7803. _addFolder: function() {
  7804. if (this._listControl) {
  7805. if (this._propertiesOpen) {
  7806. this.closeProperties();
  7807. }
  7808. this._listControl.addFolder();
  7809. }
  7810. },
  7811. _getContentBarAccesibleLabel: function() {
  7812. if ((this.contentBar !== undefined) && (this.contentBar.itemMap !== undefined)) {
  7813. if (this.contentBar.itemMap.nameLabel === undefined) {
  7814. return '';
  7815. } else {
  7816. return this.contentBar.itemMap.nameLabel.label;
  7817. }
  7818. }
  7819. },
  7820. /**
  7821. * Return the combination of default options with the ones passed in by the sub class
  7822. **/
  7823. _getDatatableOptions: function(options) {
  7824. var contentBarLabel = this._getContentBarAccesibleLabel();
  7825. var hasWrite = ContentStoreObject.hasPermissions(this.parentObj, ['write']);
  7826. var datatableOptions = {
  7827. 'el': this.getContainer(),
  7828. 'defaultSort': this.getDefaultSort(),
  7829. 'stateId': this.stateId || null,
  7830. 'glassContext': this.glassContext,
  7831. 'singleSelectCallback': this._selectRow.bind(this),
  7832. 'contentView': this,
  7833. 'accessibleLabel': StringResource.get('ViewAccessibleLabel', {
  7834. label: contentBarLabel
  7835. }),
  7836. 'filterColumnIndex': this.getFilterColumnIndex(),
  7837. 'showEmptyNewFolderButton': hasWrite
  7838. };
  7839. if (this.selectedRow) {
  7840. datatableOptions.selectedRow = this.selectedRow;
  7841. delete this.selectedRow;
  7842. }
  7843. var listControlOptions = this.getListControlOptions();
  7844. if (listControlOptions) {
  7845. _.extend(datatableOptions, listControlOptions);
  7846. }
  7847. _.extend(datatableOptions, options);
  7848. return datatableOptions;
  7849. },
  7850. setFocus: function() {
  7851. if (this.slideout) {
  7852. this.getContainer().focus();
  7853. }
  7854. },
  7855. getListControlOptions: function() {
  7856. return null;
  7857. },
  7858. getDefaultSort: function() {
  7859. return [1, 'asc'];
  7860. },
  7861. /**
  7862. * Delete the ListControl from the View
  7863. **/
  7864. removeContentList: function() {
  7865. this.logger.debug('ContentListPageView.removeContentList', this._listControl);
  7866. if (this._listControl) {
  7867. this._listControl.remove();
  7868. }
  7869. if(this.newItemDropDown){
  7870. this.newItemDropDown.destroy();
  7871. }
  7872. },
  7873. /**
  7874. * Remove the View from the DOM
  7875. **/
  7876. remove: function() {
  7877. this.removeContentList();
  7878. return ContentListPageView.inherited('remove', this, arguments);
  7879. },
  7880. /**
  7881. * View extending this class that support navigating folders must override this function to return the path to their View
  7882. **/
  7883. getModuleName: function() {
  7884. // do nothing
  7885. },
  7886. /**
  7887. * Class to be placed on the main pageView container
  7888. **/
  7889. getViewContainerClass: function() {
  7890. return 'ContentListPageView';
  7891. },
  7892. /**
  7893. * Return the items url for the root folder of the view, can be overridden if not opening a folder
  7894. **/
  7895. _getDefaultRequestURL: function() {
  7896. var returnUrl = '';
  7897. if (this.folder) {
  7898. returnUrl = ContentServiceUrls.getBaseObjectsURL() + '/' + this.folder + '/items';
  7899. }
  7900. return returnUrl;
  7901. },
  7902. /**
  7903. * Render and show the content bar if it's required
  7904. **/
  7905. _renderContentBar: function() {
  7906. return this._createContentBar()
  7907. .then(function(contentBar) {
  7908. if (contentBar) {
  7909. contentBar.show();
  7910. }
  7911. return this._updateAppBar()
  7912. .then(function() {
  7913. return contentBar;
  7914. });
  7915. }.bind(this));
  7916. },
  7917. _renderSelectionControlBar: function() {
  7918. if (this.selectAcrossFolders) {
  7919. this.$selectionControlBar = $('<div class="selectionControlBar"><span class="selectAll"><a role="button" tabindex="0"></a></span><span class="clearAll"><a role="button" tabindex="0"></a></span></div>');
  7920. var selectAll = this.$selectionControlBar.find('.selectAll a');
  7921. selectAll.text(StringResource.get('selectAllFolder'));
  7922. selectAll.attr('aria-label', StringResource.get('selectAllFolder'));
  7923. selectAll.on('primaryaction', function() {
  7924. if (this._listControl) {
  7925. this._listControl.selectAll();
  7926. }
  7927. }.bind(this));
  7928. var clearAll = this.$selectionControlBar.find('.clearAll a');
  7929. clearAll.text(StringResource.get('deselectAllFolder'));
  7930. clearAll.attr('aria-label', StringResource.get('deselectAllFolder'));
  7931. clearAll.on('primaryaction', function() {
  7932. if (this._listControl) {
  7933. this._listControl.clearAll();
  7934. }
  7935. }.bind(this));
  7936. this.getContainer().append(this.$selectionControlBar);
  7937. }
  7938. },
  7939. clearAllSelected: function() {
  7940. if (this._listControl) {
  7941. this._listControl.clearAllSelected();
  7942. }
  7943. },
  7944. /**
  7945. * Set up the container for the view to render differently when a properties pane is open
  7946. **/
  7947. togglePropertiesMode: function() {
  7948. if (this._propertiesOpen) {
  7949. this.getContainer().removeClass('propertiesMode');
  7950. this._propertiesOpen = false;
  7951. } else {
  7952. this.getContainer().addClass('propertiesMode');
  7953. this._propertiesOpen = true;
  7954. }
  7955. },
  7956. /**
  7957. * Set up the container for the view to render differently when a 'New URL'' pane is open
  7958. **/
  7959. toggleNewURLMode: function() {
  7960. if (this._newURLOpen) {
  7961. this.getContainer().removeClass('newURLMode');
  7962. this._newURLOpen = false;
  7963. } else {
  7964. this.getContainer().addClass('newURLMode');
  7965. this._newURLOpen = true;
  7966. }
  7967. },
  7968. /**
  7969. * Return a promise which will resolve with an array of controls to show in the toolbar
  7970. **/
  7971. _contentbarItems: function() {
  7972. var items = [];
  7973. return this.initializeAncestors()
  7974. .then(function() {
  7975. if (this.showBreadcrumbs) {
  7976. items.push({
  7977. 'name': 'breadcrumbs',
  7978. 'position': 'leading',
  7979. 'label': StringResource.get('breadCrumbsAccessibleLabel'),
  7980. 'responsive': false,
  7981. 'module': Breadcrumbs,
  7982. 'navigateCallback': this._navigateAncestor.bind(this),
  7983. 'ancestors': this.ancestors
  7984. });
  7985. }
  7986. if (this.showParentPropertiesButton && this.ancestors && this.ancestors[0].id === '.public_folders') {
  7987. items.push({
  7988. 'name': 'parentProperties',
  7989. 'position': 'trailing',
  7990. 'module': './contentbar_components/Button',
  7991. 'className': 'parentProperties',
  7992. 'label': StringResource.get('properties', {
  7993. 'objectName': StringResource.get('teamContent')
  7994. }),
  7995. 'responsive': false,
  7996. 'icon': 'common-properties',
  7997. 'action': function() {
  7998. this._listControl._clearRows();
  7999. if (!this._propertiesOpen) {
  8000. this.showProperties({
  8001. 'selfUrl': this.selfUrl
  8002. });
  8003. } else {
  8004. this.closeProperties();
  8005. }
  8006. }.bind(this)
  8007. });
  8008. }
  8009. if (this.showAddFolder) {
  8010. items.push({
  8011. 'name': 'addFolderButton',
  8012. 'position': 'trailing',
  8013. 'label': StringResource.get('newFolderLabel'),
  8014. 'responsive': false,
  8015. 'module': './contentbar_components/Button',
  8016. 'className': 'addNewFolder',
  8017. 'icon': 'common-add-folder',
  8018. 'action': function() {
  8019. this._addFolder();
  8020. }.bind(this)
  8021. });
  8022. }
  8023. if (this.showNewItem) {
  8024. items.push({
  8025. 'name': 'newItemButton',
  8026. 'position': 'trailing',
  8027. 'label': StringResource.get('newItemMenuLabel'),
  8028. 'responsive': false,
  8029. 'module': './contentbar_components/Button',
  8030. 'className': 'newItemButton',
  8031. 'icon': 'common-add',
  8032. 'action': function() {
  8033. this._openNewItemMenu();
  8034. }.bind(this)
  8035. });
  8036. }
  8037. if (this.showFilter) {
  8038. items.push({
  8039. 'name': 'contentNavFilter',
  8040. 'label': StringResource.get('filterBy'),
  8041. 'responsive': false,
  8042. 'labelOnly': false,
  8043. 'hcLabel': false,
  8044. 'position': 'trailing',
  8045. 'supportCustomCollapse': true,
  8046. 'showTitle': false,
  8047. 'updateLabel': false,
  8048. 'icon': 'common-filter',
  8049. 'bSVG': true,
  8050. 'module': './contentbar_components/Button',
  8051. 'className': 'contentNavFilter',
  8052. 'pushed': false,
  8053. 'action': this.filterViewClicked.bind(this)
  8054. });
  8055. }
  8056. if (this.showSort) {
  8057. items.push({
  8058. 'name': 'facetButton',
  8059. 'module': './contentbar_components/Button',
  8060. 'position': 'trailing',
  8061. 'label': StringResource.get('sort'),
  8062. 'responsive': false,
  8063. 'className': 'contentNavSortButton',
  8064. 'icon': 'ba_content_nav-sort_16',
  8065. 'bSVG': true,
  8066. 'disabled': false,
  8067. 'pushed': false,
  8068. 'action': this._sortViewFacetClicked.bind(this)
  8069. });
  8070. }
  8071. items = items.concat(this.contentbarItems());
  8072. return Promise.resolve(items);
  8073. }.bind(this));
  8074. },
  8075. _sortViewFacetClicked: function() {
  8076. var filterButton = this.contentBar.itemMap.facetButton.$el.find('button');
  8077. if (this.contentBar.itemMap.facetButton.pushed === false && filterButton.prop('disabled') === false) {
  8078. this.contentBar.itemMap.facetButton.pushed = true;
  8079. filterButton.addClass('filtered');
  8080. this.glassContext.appController.showSlideOut({
  8081. 'parent': this.slideout,
  8082. 'label': StringResource.get('sort'),
  8083. 'width': '200px',
  8084. 'content': {
  8085. 'module': 'bacontentnav/common/SortView',
  8086. 'view': this
  8087. }
  8088. }).on('hide', function() {
  8089. filterButton.removeClass('filtered');
  8090. this.contentBar.itemMap.facetButton.pushed = false;
  8091. }.bind(this));
  8092. }
  8093. },
  8094. _resetSelectedSortViewFacets: function() {
  8095. // Default setting
  8096. this.selected = {
  8097. sortBy: 'name',
  8098. order: 'asc'
  8099. };
  8100. this.updateSortColumn(this.selected);
  8101. },
  8102. /**
  8103. * Should be overridden if custom controls are to be placed in the content bar
  8104. **/
  8105. contentbarItems: function() {
  8106. return [];
  8107. },
  8108. /**
  8109. * Should be overridden if copy/move action will be invoked from this view
  8110. **/
  8111. _getDefaultSelfURL: function() {
  8112. var returnUrl = '';
  8113. if (this.folder) {
  8114. returnUrl = ContentServiceUrls.getBaseObjectsURL() + '/' + this.folder;
  8115. }
  8116. return returnUrl;
  8117. },
  8118. /**
  8119. * Create the content bar
  8120. **/
  8121. _createContentBar: function() {
  8122. return this._contentbarItems().then(function(items) {
  8123. if (!items || items.length === 0) {
  8124. return Promise.resolve(null);
  8125. } else {
  8126. this.$contentbar = $('<div class="contentexplorerbar"></div>');
  8127. this.getContainer().prepend(this.$contentbar);
  8128. this.contentBar = new ContentBar({
  8129. el: this.$contentbar,
  8130. items: items,
  8131. appController: this.appController,
  8132. appBarConfig: {
  8133. showHome: false,
  8134. showLogout: false
  8135. }
  8136. });
  8137. return this.contentBar.render().then(function() {
  8138. return Promise.resolve(this);
  8139. }.bind(this.contentBar));
  8140. }
  8141. }.bind(this));
  8142. },
  8143. /**
  8144. * Query for properties from the parent object if we don't already have them
  8145. **/
  8146. getParentProperties: function() {
  8147. if (this.parentObj || !this.selfUrl) {
  8148. return Promise.resolve(true);
  8149. }
  8150. var options = {
  8151. url: this.selfUrl,
  8152. dataType: 'json',
  8153. type: 'GET',
  8154. data: {
  8155. 'fields': 'permissions'
  8156. }
  8157. };
  8158. return this.glassContext.getCoreSvc('.Ajax').ajax(options)
  8159. .then(function(response) {
  8160. this.parentObj = response.data.data[0];
  8161. // Make sure the last ancestor has the information we just queried for. This helps reduce the
  8162. // number of http requests when navigating using the breadcrumbs
  8163. if (this.ancestors) {
  8164. _.last(this.ancestors).permissions = this.parentObj.permissions;
  8165. }
  8166. }.bind(this))
  8167. .catch(function(err) {
  8168. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  8169. return Promise.reject(err);
  8170. }.bind(this));
  8171. },
  8172. getContextMenuId: function() {
  8173. return UIHelper.getConfiguration('contextMenuId');
  8174. },
  8175. getPersonalViewModulePath: function() {
  8176. return UIHelper.getConfiguration('modulePaths').myContent;
  8177. },
  8178. getTeamViewModulePath: function() {
  8179. return UIHelper.getConfiguration('modulePaths').teamContent;
  8180. },
  8181. _multiselectbarItems: function() {
  8182. return Promise.resolve([{
  8183. 'name': 'selectedLabel',
  8184. 'position': 'leading',
  8185. 'label': '',
  8186. 'module': '../../lib/gemini/app/ui/toolbar_components/Label',
  8187. 'style': 'selectedLabel'
  8188. }, {
  8189. 'name': 'cancelButton',
  8190. 'position': 'trailing',
  8191. 'label': StringResource.get('cancel'),
  8192. 'text': StringResource.get('cancel'),
  8193. 'labelOnly': true,
  8194. 'module': './contentbar_components/Button',
  8195. 'className': 'cancelButton',
  8196. 'action': function() {
  8197. this._listControl._clearRows();
  8198. this.hideMultiSelectBar();
  8199. this.setFocus();
  8200. }.bind(this)
  8201. }, {
  8202. 'name': 'ellipsesButton',
  8203. 'position': 'trailing',
  8204. 'icon': 'common-menuoverflow',
  8205. 'module': './contentbar_components/Button',
  8206. 'label': StringResource.get('more'),
  8207. 'className': 'ellipsesButton',
  8208. 'action': function(event) {
  8209. var position = {};
  8210. if (event.type === 'keypress') {
  8211. position = $(event.target).offset();
  8212. } else {
  8213. position.left = event.pageX || event.gesture.center.pageX;
  8214. position.top = event.pageY || event.gesture.center.pageY;
  8215. }
  8216. var selectedContext = this._listControl.getSelectedObjects();
  8217. var args = {
  8218. 'position': {
  8219. 'pageX': position.left,
  8220. 'pageY': position.top
  8221. },
  8222. 'menuId': this.getContextMenuId(),
  8223. 'activeObject': {
  8224. 'oListControl': this._listControl,
  8225. 'aSelectedContext': selectedContext
  8226. },
  8227. options: this._listControl.getPublicSelectedObjects(selectedContext)
  8228. };
  8229. event.stopPropagation();
  8230. this.glassContext.appController.showContextMenu(args);
  8231. return false;
  8232. }.bind(this)
  8233. }]);
  8234. },
  8235. /**
  8236. * Return/create the multiselect bar
  8237. **/
  8238. _createMultiSelectBar: function() {
  8239. return this._multiselectbarItems().then(function(items) {
  8240. this.$multiselectbar = $('<div id="' + _.uniqueId('multiselectbar_') + '" class="multiselectbar"></div>');
  8241. this.getContainer().prepend(this.$multiselectbar);
  8242. this.multiselectBar = new ContentBar({
  8243. el: this.$multiselectbar,
  8244. items: items,
  8245. appController: this.appController,
  8246. appBarConfig: {
  8247. showHome: false,
  8248. showLogout: false
  8249. },
  8250. onHide: function() {
  8251. this.$el.removeClass('multiselectbarContentNav');
  8252. },
  8253. onShow: function() {
  8254. this.$el.addClass('multiselectbarContentNav');
  8255. }
  8256. });
  8257. this.$multiselectbar.attr('aria-live', 'polite');
  8258. this.multiselectBar.hide();
  8259. return this.multiselectBar.render().then(function() {
  8260. return Promise.resolve(this);
  8261. }.bind(this.multiselectBar));
  8262. }.bind(this));
  8263. },
  8264. getFilterColumnIndex: function() {
  8265. return 0;
  8266. },
  8267. getAncestors: function() {
  8268. return this.ancestors;
  8269. },
  8270. /**
  8271. * Filter the datatable
  8272. **/
  8273. _filter: function(filterString) {
  8274. if (!this._listControl) {
  8275. return;
  8276. }
  8277. if (filterString === 'allContent' && this.currentFilters[filterString + '_' + this.id]) {
  8278. // All Content exists - it was checked and now it is being unchecked - get rid of everything
  8279. _.each(this.getFilterSpec(), function(filterObj) {
  8280. delete this.currentFilters[filterObj.name + '_' + this.id];
  8281. }.bind(this));
  8282. } else if (filterString === 'allContent') {
  8283. // All Content does not exist - it was unchecked and now it is being checked - add all filters
  8284. _.each(this.getFilterSpec(), function(filterObj) {
  8285. this.currentFilters[filterObj.name + '_' + this.id] = filterObj.name;
  8286. }.bind(this));
  8287. } else if (this.currentFilters[filterString + '_' + this.id]) {
  8288. // The selected filter is already checked, delete it
  8289. delete this.currentFilters[filterString + '_' + this.id];
  8290. // When we remove a filter, it could be the first one removed - this should toggle off the all content
  8291. if (this.currentFilters['allContent_' + this.id]) {
  8292. delete this.currentFilters['allContent_' + this.id];
  8293. }
  8294. } else {
  8295. this.currentFilters[filterString + '_' + this.id] = filterString;
  8296. // When we add a filter, it could make every filter checked - if so, toggle on the all content again
  8297. if (this.getFilterCountPerId() === this.getFilterSpec().length - 1) {
  8298. this.currentFilters['allContent_' + this.id] = 'allContent';
  8299. }
  8300. }
  8301. // Build the filter string
  8302. var contentListFilter = '';
  8303. if (this.getFilterCountPerId() === 0) {
  8304. contentListFilter = 'none';
  8305. } else if (this.contentListFacets && !this.currentFilters['allContent_' + this.id]) {
  8306. _.each(this.getFilterSpec(), function(filterObj) {
  8307. if (this.currentFilters[filterObj.name + '_' + this.id]) {
  8308. contentListFilter = this.contentListFacets[filterObj.name] + (contentListFilter ? '|' + contentListFilter : '');
  8309. }
  8310. }.bind(this));
  8311. }
  8312. this._listControl.filter(contentListFilter, this.getFilterColumnIndex(), true);
  8313. },
  8314. /**
  8315. * When there are several different filter menus (distinguished by their menu id), need to be able to determine how many
  8316. * filters are set for a specific menu.
  8317. */
  8318. getFilterCountPerId: function() {
  8319. return Object.keys(this.currentFilters).filter(function(key) {
  8320. return key.indexOf(this.id) > -1;
  8321. }.bind(this)).length;
  8322. },
  8323. updateFilterString: function(filterString) {
  8324. if (this.stateId && UIHelper.isLocalStorageSupported()) {
  8325. localStorage.setItem('filterString_' + this.stateId, filterString);
  8326. }
  8327. },
  8328. /**
  8329. Default to public folders, unless it's my_folders or specific storeid
  8330. **/
  8331. getRootAncestor: function() {
  8332. return (this.folder === '.my_folders') ? ContentStoreObject.getRootMyFoldersAncestors() : ContentStoreObject.getRootPublicFoldersAncestor();
  8333. },
  8334. /**
  8335. Check whether this.folder is a public/my folder or a storeId
  8336. **/
  8337. _folderIsId: function() {
  8338. return this.folder && this.folder.match(/^i[0-9A-F]{32}$/);
  8339. },
  8340. initializeAncestors: function() {
  8341. return new Promise(function(resolve) {
  8342. //Sometimes the breadcrumbs will need to be kept track of without being shown
  8343. if ((this.showBreadcrumbs || this.trackBreadcrumbs) && this.ancestors.length === 0) {
  8344. if (!this._folderIsId()) {
  8345. this.ancestors.push(this.getRootAncestor());
  8346. resolve(this.ancestors);
  8347. } else if (this.skipAncestors) {
  8348. this._sendRequestForMissingInfo('permissions,defaultName', this.selfUrl).then(function(oData) {
  8349. this.ancestors = [ContentStoreObject.buildAncestorEntry(oData)];
  8350. resolve(this.ancestors);
  8351. }.bind(this));
  8352. } else {
  8353. this._sendRequestForMissingInfo('permissions,ancestors,defaultName', this.selfUrl).then(function(oData) {
  8354. this.ancestors = ContentStoreObject.buildAncestorTree(oData);
  8355. resolve(this.ancestors);
  8356. }.bind(this));
  8357. }
  8358. } else {
  8359. resolve(this.ancestors);
  8360. }
  8361. }.bind(this));
  8362. },
  8363. addURLParameters: function(oProperties) {
  8364. $.each(oProperties, function(name, value) {
  8365. // Special case for fields, each view can add to the list of properties needed
  8366. if (this._urlParameters[name] && name === 'fields') {
  8367. this._urlParameters[name] = this._urlParameters[name] + ',' + value;
  8368. } else {
  8369. this._urlParameters[name] = value;
  8370. }
  8371. }.bind(this));
  8372. },
  8373. getURLParameters: function() {
  8374. return this._urlParameters;
  8375. },
  8376. /**
  8377. Creates the Wide view(s) to the object oData
  8378. @param showChildren {boolean}: optional argument, if true the view will show the children of the first parameter oData
  8379. **/
  8380. openSlideoutView: function(oData, showChildren) {
  8381. this.logger.debug('ContentListPageView.openSlideoutView', oData, showChildren);
  8382. var renderFromReact = oData.renderFromReact;
  8383. this._queryMissingInfoToOpenView(oData).then(function(oData) {
  8384. var ancestors = ContentStoreObject.getAncestors(oData);
  8385. if (!ancestors) {
  8386. return;
  8387. }
  8388. if(ancestors.length > 0){
  8389. var rootUrl = ContentStoreObject.getSelfLink(ancestors[0]);
  8390. var pluginId = rootUrl === ContentServiceUrls.getPublicFoldersURL() ? 'com.ibm.bi.contentApps.teamFoldersSlideout' : 'com.ibm.bi.contentApps.myContentFoldersSlideout';
  8391. }
  8392. var plugin = this.glassContext.appController.findPlugin(pluginId);
  8393. if(plugin) {
  8394. if(plugin.$el) {
  8395. this.glassContext.appController.hideSlideOut().then(function(){
  8396. plugin.$el.trigger('click');
  8397. });
  8398. } else {
  8399. this.logger.error('Plugin with id="' + pluginId + '" does not have $el');
  8400. }
  8401. plugin.itemSpec.options.content.initialFolder = oData;
  8402. plugin.itemSpec.options.content.renderFromReact = renderFromReact;
  8403. } else {
  8404. this.logger.error('Cannot find plugin with id="' + pluginId + '"');
  8405. }
  8406. }.bind(this)).catch(function() {
  8407. // Add function to catch the error
  8408. });
  8409. },
  8410. _queryMissingInfoToOpenView: function(oData) {
  8411. return new Promise(function(resolve, reject) {
  8412. var url = ContentStoreObject.getSelfLink(oData);
  8413. var ancestors = ContentStoreObject.getAncestors(oData);
  8414. if (url && ancestors) {
  8415. resolve(oData);
  8416. } else if (url) {
  8417. // Query for the information we need to open the view (ancestors and defaultName)
  8418. this._sendRequestForMissingInfo('ancestors,defaultName', url).then(function(obj) {
  8419. resolve(obj);
  8420. });
  8421. } else {
  8422. reject(new Error('No self url to open view'));
  8423. }
  8424. }.bind(this));
  8425. },
  8426. _sendRequestForMissingInfo: function(fields, url) {
  8427. var options = {
  8428. url: url,
  8429. dataType: 'json',
  8430. type: 'GET',
  8431. data: {
  8432. 'fields': fields
  8433. }
  8434. };
  8435. return this.glassContext.getCoreSvc('.Ajax').ajax(options)
  8436. .then(function(response) {
  8437. return response.data.data[0];
  8438. })
  8439. .catch(function(err) {
  8440. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  8441. return Promise.reject(err);
  8442. }.bind(this));
  8443. },
  8444. /**
  8445. * Callback used when the user clicks on a breadcrumb
  8446. * @index {int} - the index in the ancestor array for the breadcrumb that was clicked on
  8447. **/
  8448. _navigateAncestor: function(index) {
  8449. if (index >= this.ancestors.length - 1 || (this._propertiesOpen) || (this._newURLOpen)) {
  8450. if (this._propertiesOpen) {
  8451. this.closeProperties();
  8452. }
  8453. if (this._newURLOpen) {
  8454. this.closeNewURL();
  8455. }
  8456. return;
  8457. }
  8458. var ancestorEntry = this.ancestors[index];
  8459. this.ancestors = this.ancestors.slice(0, index);
  8460. this.navigate(ancestorEntry);
  8461. },
  8462. /**
  8463. * Helper function to render a new pageView with new content
  8464. **/
  8465. navigate: function(oData, row) {
  8466. this.logger.debug('ContentListPageView.navigate', oData);
  8467. void(row);
  8468. if (!oData) {
  8469. return;
  8470. }
  8471. if (!UIHelper.isContainer(ContentStoreObject.getType(oData))) {
  8472. return;
  8473. }
  8474. if (this._propertiesOpen) {
  8475. this.closeProperties();
  8476. }
  8477. this.parentObj = oData.permissions ? oData : null;
  8478. this.url = ContentStoreObject.getItemsLink(oData);
  8479. this.selfUrl = ContentStoreObject.getSelfLink(oData);
  8480. if (this.parentObj && this.parentObj.permissions) {
  8481. this._listControl.setParentHasWritePermission(ContentStoreObject.hasPermissions(this.parentObj, ['write']));
  8482. }
  8483. if (this._listControl && this._listControl.updateDatatable) {
  8484. this._listControl.updateDatatable(this.url);
  8485. this.refreshBreadcrumbs(oData);
  8486. this._updateAppBar();
  8487. }
  8488. var currentLocation = ContentStoreObject.getName(this.ancestors[this.ancestors.length - 1]);
  8489. if (currentLocation && currentLocation.length) {
  8490. A11YHelper.screenReaderAlertUser(StringResource.get('a11yContentListUpdatedNotification', {
  8491. 'folderOrPackageName': currentLocation
  8492. }));
  8493. }
  8494. },
  8495. _updateTeamRoot: function(){
  8496. if (this.inTeamRoot) {
  8497. $('body').addClass('inTeamRootNav');
  8498. } else {
  8499. $('body').removeClass('inTeamRootNav');
  8500. }
  8501. },
  8502. _updateAppBar: function() {
  8503. // update team root flag and then do the team root update
  8504. this.inTeamRoot = this.ancestors && this.ancestors.length === 1 && this.ancestors[0].id === '.public_folders';
  8505. this._updateTeamRoot();
  8506. return this.getParentProperties().then(function() {
  8507. var hasWrite = ContentStoreObject.hasPermissions(this.parentObj, ['write']);
  8508. if (this.showParentPropertiesButton) {
  8509. // Only show the parent properties button if we're at the root of Team Content
  8510. var display = this.inTeamRoot && hasWrite ? 'inline-block' : 'none';
  8511. this._updateAppbarButton('.parentProperties', display);
  8512. }
  8513. if (this.showAddFolder) {
  8514. this._updateAppbarButton('.addNewFolder', hasWrite ? 'inline-block' : 'none');
  8515. }
  8516. // hide new item button if the context menu is empty
  8517. // context menu is empty when user cannot create url or user cannot create new folder
  8518. if (!this.isAllowNewFolder() && this.inTeamRoot){
  8519. this._updateAppbarButton('.newItemButton', 'none');
  8520. } else {
  8521. this._updateAppbarButton('.newItemButton', 'inline-block');
  8522. }
  8523. }.bind(this));
  8524. },
  8525. /**
  8526. * check if user has the capability to create a new folder
  8527. * */
  8528. isAllowNewFolder: function() {
  8529. var userProfileSettings = this.glassContext.services.userProfile && this.glassContext.services.userProfile.userProfileSettings;
  8530. var allowNewFolder = !(userProfileSettings &&
  8531. userProfileSettings.ui_excludedFeatures &&
  8532. userProfileSettings.ui_excludedFeatures.ids &&
  8533. userProfileSettings.ui_excludedFeatures.ids.indexOf('com.ibm.bi.contentApps.Folder') >= 0);
  8534. return allowNewFolder;
  8535. },
  8536. _updateAppbarButton: function(cssClass, display) {
  8537. if(this.$contentbar) {
  8538. var button = this.$contentbar.find(cssClass).parent();
  8539. button.css('display', display);
  8540. // Hide/show the separator if it's right after the button we're updating
  8541. var nextNode = button.next();
  8542. var previousVisibleNode = button.prevAll(':visible:first');
  8543. if ((previousVisibleNode.length === 0 || previousVisibleNode.hasClass('appbarSeparatorItem')) && nextNode.hasClass('appbarSeparatorItem')) {
  8544. nextNode.css('display', display);
  8545. }
  8546. }
  8547. },
  8548. refreshBreadcrumbs: function(oData) {
  8549. this.logger.debug('ContentListPageView.refreshBreadcrumbs', oData);
  8550. var ancestorEntry = ContentStoreObject.buildAncestorEntry(oData);
  8551. this.ancestors.push(ancestorEntry);
  8552. if (this.showBreadcrumbs) {
  8553. this.contentBar.getAddedItem('breadcrumbs').then(function(breadcrumbsView) {
  8554. breadcrumbsView.updateBreadcrumb(this.ancestors);
  8555. }.bind(this));
  8556. }
  8557. if (this.navigateCallback) {
  8558. this.navigateCallback(this.ancestors);
  8559. }
  8560. },
  8561. isEnabledAction: function(actionName) {
  8562. return !(this.disabledActions && this.disabledActions.indexOf(actionName) > -1);
  8563. },
  8564. _getFilterItems: function(filterSpec, filterMenuPrefix, defaultFilterValue, doFilter) {
  8565. return _.map(filterSpec, function(item) {
  8566. return {
  8567. 'name': filterMenuPrefix + item.name,
  8568. 'icon': 'wft_checkmark',
  8569. 'label': item.label,
  8570. 'checked': item.value === defaultFilterValue,
  8571. 'action': function() {
  8572. doFilter(item.name);
  8573. }
  8574. };
  8575. });
  8576. },
  8577. // Overridden
  8578. getFilterSpec: function() {
  8579. return [];
  8580. },
  8581. // Overridden
  8582. getSortSpec: function() {
  8583. return {
  8584. sortBy: {
  8585. name: 'name',
  8586. modificationTime: 'modificationTime'
  8587. },
  8588. order: {
  8589. sortedAscending: 'asc',
  8590. sortedDescending: 'desc'
  8591. }
  8592. };
  8593. },
  8594. // Overridden
  8595. // Map single column sorting to multi-column sorting
  8596. getSortMappingSpec: function() {
  8597. return {
  8598. name: ['groupByFolder', 'name'],
  8599. modificationTime: ['groupByFolder', 'modificationTime'],
  8600. type: ['groupByType', 'name']
  8601. };
  8602. },
  8603. getListControl: function() {
  8604. return this._listControl;
  8605. },
  8606. sort: function() {
  8607. if (!this.getListControl()) {
  8608. return;
  8609. }
  8610. var columnName = localStorage.getItem('sortColumnName_' + this.stateId);
  8611. var direction = localStorage.getItem('sortColumnDir_' + this.stateId);
  8612. var sortArray = [];
  8613. if (this.getListControl()) {
  8614. var dt = this.getListControl().getDatatable();
  8615. var index = -1;
  8616. for (var i = 0; i < this.sortMappingSpec[columnName].length; i++) {
  8617. index = dt.api().column(this.sortMappingSpec[columnName][i] + ':name').index();
  8618. if (index >= 0) {
  8619. sortArray.push([index, direction]);
  8620. }
  8621. }
  8622. }
  8623. if (sortArray.length > 0) {
  8624. dt.api().order(sortArray).draw();
  8625. }
  8626. },
  8627. updateSortColumn: function(selectedSort) {
  8628. if (this.stateId && UIHelper.isLocalStorageSupported()) {
  8629. localStorage.setItem('sortColumnName_' + this.stateId, selectedSort.sortBy);
  8630. localStorage.setItem('sortColumnDir_' + this.stateId, selectedSort.order);
  8631. }
  8632. },
  8633. _getSortItems: function(sortSpec, menuPrefix, defaultColumn, defaultSortDirection, doSort) {
  8634. return _.map(sortSpec, function(item) {
  8635. return {
  8636. 'name': menuPrefix + item.name,
  8637. 'label': item.label,
  8638. 'icon': 'sortDirection',
  8639. 'sorted': item.value === defaultColumn ? defaultSortDirection : null,
  8640. 'action': function() {
  8641. doSort(item.value);
  8642. }
  8643. };
  8644. });
  8645. },
  8646. filterViewClicked: function() {
  8647. return;
  8648. },
  8649. getContainer: function() {
  8650. return this.contentListContainer || this.$el;
  8651. },
  8652. hideMultiSelectBar: function() {
  8653. if (this.multiselectBar) {
  8654. this.multiselectBar.hide();
  8655. }
  8656. var contentBar = this.folderSearchBar && this.folderSearchBar.isVisible() ? this.folderSearchBar : this.contentBar;
  8657. if (contentBar) {
  8658. contentBar.show();
  8659. }
  8660. },
  8661. showMultiSelectBar: function(isAccountPickerSlideout) {
  8662. if (this.selectAcrossFolders) {
  8663. return;
  8664. }
  8665. var contentBar = this.folderSearchBar && this.folderSearchBar.isVisible() ? this.folderSearchBar : this.contentBar;
  8666. if (contentBar) {
  8667. contentBar.hide();
  8668. }
  8669. if (this.multiselectBar) {
  8670. if (isAccountPickerSlideout) {
  8671. var ellipsis = this.multiselectBar.$el.find('div.appbarLeading');
  8672. $(ellipsis[0]).css('visibility', 'hidden');
  8673. }
  8674. this.multiselectBar.show();
  8675. }
  8676. },
  8677. updateMultiSelectBarText: function(noOfItemSelected) {
  8678. if (this.multiselectBar) {
  8679. this.multiselectBar.getAddedItem('selectedLabel').then(function(selectedLabelObject) {
  8680. selectedLabelObject.text(noOfItemSelected);
  8681. }.bind(this));
  8682. }
  8683. },
  8684. // Overridden
  8685. getNewItemSpec: function() {
  8686. return Promise.resolve([]);
  8687. },
  8688. // Overridden
  8689. createNewItem: function(type) {
  8690. void(type);
  8691. },
  8692. _getNewItems: function() {
  8693. return this.getNewItemSpec().then(function(data){
  8694. return _.map(data, function(item) {
  8695. // strip '#' prefix, if appl.
  8696. var icon = UIHelper.getSVGIconForType(item.type).replace(/^#/, '');
  8697. return {
  8698. 'label': UIHelper.getTypeName(item.type),
  8699. 'icon': icon,
  8700. 'onSelect': this.createNewItem.bind(this, item.type)
  8701. };
  8702. }.bind(this));
  8703. }.bind(this));
  8704. },
  8705. _createNewItemDropDown: function($parent) {
  8706. return this._getNewItems().then(function(data){
  8707. this.newItemDropDown = new DropDownMenu({
  8708. dropDownMenuSpec: {
  8709. 'title': StringResource.get('newItemMenuLabel'),
  8710. 'id': 'newItemMenu',
  8711. 'label': 'newItemMenu',
  8712. 'icon': '',
  8713. 'items': data,
  8714. 'actionElement': $parent[0],
  8715. 'ddMenuPlacement': 'bottom',
  8716. 'class': 'newItemDropDown'
  8717. }
  8718. });
  8719. return this.newItemDropDown.render();
  8720. }.bind(this));
  8721. },
  8722. _openNewItemMenu: function() {
  8723. if (this.newItemDropDown) {
  8724. this.newItemDropDown.show();
  8725. } else {
  8726. return new Promise(function(resolve, reject){
  8727. var $newItemButton = this.$el.find('.newItemButton');
  8728. $newItemButton.attr('tabindex', '0');
  8729. this._createNewItemDropDown($newItemButton)
  8730. .then(function(newItemDropDown) {
  8731. $newItemButton.trigger('click');
  8732. resolve(newItemDropDown);
  8733. }.bind($newItemButton)).catch(function(err){
  8734. reject(err);
  8735. });
  8736. }.bind(this));
  8737. }
  8738. }
  8739. });
  8740. _.extend(ContentListPageView);
  8741. return ContentListPageView;
  8742. });
  8743. /*
  8744. *+------------------------------------------------------------------------+
  8745. *| Licensed Materials - Property of IBM
  8746. *| IBM Cognos Products: SEARCH
  8747. *| (C) Copyright IBM Corp. 2017, 2018
  8748. *|
  8749. *| US Government Users Restricted Rights - Use, duplication or disclosure
  8750. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  8751. *+------------------------------------------------------------------------+
  8752. */
  8753. define('bacontentnav/common/ui/FolderSearchBar',['jquery',
  8754. 'underscore',
  8755. '../../lib/@waca/core-client/js/core-client/ui/View',
  8756. '../../lib/@waca/core-client/js/core-client/utils/Utils',
  8757. '../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  8758. '../../nls/StringResource',
  8759. 'jquery-ui'], function($, _, View, Utils, BidiUtil, StringResources) {
  8760. /**
  8761. * Represents a search bar that can be added to an app bar
  8762. */
  8763. var FolderSearchBar = View.extend({
  8764. events: {
  8765. clicktap: 'action'
  8766. },
  8767. /**
  8768. * Creates a search bar
  8769. */
  8770. init: function(spec) {
  8771. _.extend(this, spec);
  8772. FolderSearchBar.inherited('init', this, arguments);
  8773. this.folderSearchbarInitialized = false;
  8774. // search input
  8775. this.$input = $('<input class="searchinput">')
  8776. .attr({
  8777. type: 'search',
  8778. value: this.value,
  8779. placeholder: StringResources.get('searchFolder'),
  8780. title: this.label,
  8781. maxlength: 256,
  8782. role: 'combobox',
  8783. 'aria-autocomplete': 'list'
  8784. })
  8785. .on('search', this.search.bind(this))
  8786. .on('change', this.resetState.bind(this))
  8787. .on('focus', this.setCaret.bind(this))
  8788. .keydown(
  8789. function(e) {
  8790. if (e.which === 27) {
  8791. //ESC key
  8792. if (!_.isEmpty(this.getSearchString())) {
  8793. this.hadTypeaheadContent = true;
  8794. this.controller.onClear();
  8795. e.stopPropagation();
  8796. }
  8797. }
  8798. }.bind(this)
  8799. )
  8800. .keyup(
  8801. function(e) {
  8802. if (e.which === 27) {
  8803. //ESC key
  8804. if (this.hadTypeaheadContent) {
  8805. this.hadTypeaheadContent = false;
  8806. e.stopPropagation();
  8807. }
  8808. } else if (e.which !== 9 && e.which !== 16) {
  8809. // if not tab/shift
  8810. this.search(e);
  8811. }
  8812. }.bind(this)
  8813. );
  8814. BidiUtil.initElementForBidi(this.$input[0]);
  8815. // search button
  8816. this.$searchButton = $('<button class="s4h" disabled></button>').attr({
  8817. type: 'button',
  8818. title: StringResources.get('search')
  8819. });
  8820. Utils.setIcon(this.$searchButton, 'common-search');
  8821. // clear search button
  8822. this.$clearSearchButton = $('<button class="s4hReset" ></button>')
  8823. .attr({
  8824. type: 'reset',
  8825. title: StringResources.get('clear')
  8826. })
  8827. .on('clicktap', this.clear.bind(this));
  8828. Utils.setIcon(this.$clearSearchButton, 'common-close-cancel-error');
  8829. this.hadTypeaheadContent = false;
  8830. },
  8831. setCaret: function(e) {
  8832. e.stopPropagation();
  8833. window.setTimeout(
  8834. function() {
  8835. this.moveCaretToEnd(this.$input[0]);
  8836. }.bind(this),
  8837. 0
  8838. );
  8839. },
  8840. moveCaretToEnd: function(el) {
  8841. if (typeof el.selectionStart == 'number' && !this.folderSearchbarInitialized) {
  8842. el.selectionStart = el.selectionEnd = el.value.length;
  8843. this.folderSearchbarInitialized = true;
  8844. } else if (typeof el.createTextRange != 'undefined') {
  8845. el.focus();
  8846. var range = el.createTextRange();
  8847. range.collapse(false);
  8848. range.select();
  8849. }
  8850. },
  8851. /**
  8852. * Draws the Search bar
  8853. */
  8854. render: function() {
  8855. this.$el
  8856. .empty()
  8857. .addClass('searchbar appbarIcon appbarItem filled s4hBar')
  8858. .append(this.$searchButton, [this.$input, this.$clearSearchButton]);
  8859. if (!this.value) {
  8860. this.$el.removeClass('filled');
  8861. }
  8862. this.setFocus();
  8863. return Promise.resolve(this);
  8864. },
  8865. /**
  8866. * Show the Search bar
  8867. * @param {boolean} noFocus - no focus needed
  8868. */
  8869. show: function(noFocus) {
  8870. if (this.isHidden()) {
  8871. this.$input.fadeIn('fast');
  8872. this.$searchButton.fadeIn('fast');
  8873. this.$clearSearchButton.fadeIn('fast');
  8874. this.$el.slideDown('fast');
  8875. if (!noFocus) {
  8876. this.setFocus();
  8877. this.$input.select();
  8878. }
  8879. }
  8880. },
  8881. /**
  8882. * handle search event
  8883. * @param {object} e - search event
  8884. */
  8885. search: function(e) {
  8886. var searchString = this.getSearchString();
  8887. this.controller.applyFilter(searchString);
  8888. this.setFocus();
  8889. this.showHideClearSearchButton();
  8890. if (e) {
  8891. e.preventDefault();
  8892. }
  8893. },
  8894. /**
  8895. * handle the event when clear button is clicked
  8896. */
  8897. clear: function() {
  8898. if (this.$input.val() !== '') {
  8899. this.gainFocus = true;
  8900. this.$input.val('');
  8901. this.$input.select();
  8902. this.setFocus();
  8903. this.showHideClearSearchButton();
  8904. if (this.controller.renderFromReact) {
  8905. this.controller.clearSearch();
  8906. } else {
  8907. this.controller.clearFilter();
  8908. }
  8909. }
  8910. },
  8911. /**
  8912. * set search string to input control
  8913. * @param {string} searchString - search string to be set
  8914. */
  8915. setSearchString: function(searchString) {
  8916. var str = _.isString(searchString) ? searchString : '';
  8917. if (this.getSearchString() !== str) {
  8918. this.$input.val(str);
  8919. }
  8920. this.showHideClearSearchButton();
  8921. },
  8922. /**
  8923. * get search string from input control
  8924. * @return {string} search string in input control
  8925. */
  8926. getSearchString: function() {
  8927. return this.$input.val().trim();
  8928. },
  8929. /**
  8930. * Hide the Search bar
  8931. * @param {boolean} preserveInput - should input value be preserved
  8932. */
  8933. hide: function(preserveInput) {
  8934. if (!this.$el.is(':hidden')) {
  8935. this.$el.slideUp('fast');
  8936. this.$input.fadeOut('fast').blur();
  8937. if (!preserveInput) {
  8938. this.$input.val('');
  8939. }
  8940. this.$searchButton.fadeOut('fast');
  8941. this.$clearSearchButton.fadeOut('fast');
  8942. }
  8943. },
  8944. /**
  8945. * Is the search bar hidden
  8946. * @return {boolean} true - the search is hidden, otherwise false;
  8947. */
  8948. isHidden: function() {
  8949. return this.$el.is(':hidden');
  8950. },
  8951. /**
  8952. * show or hide clear search button based on input value is empty or not
  8953. */
  8954. showHideClearSearchButton: function() {
  8955. if (this.$input.val()) {
  8956. this.$el.addClass('filled');
  8957. } else {
  8958. this.$el.removeClass('filled');
  8959. }
  8960. },
  8961. /**
  8962. * set input control on focus
  8963. */
  8964. setFocus: function() {
  8965. if (!this.$input.is(':focus')) {
  8966. this.$input.focus();
  8967. }
  8968. },
  8969. /**
  8970. * reset state when input value changes
  8971. */
  8972. resetState: function() {
  8973. this.showHideClearSearchButton();
  8974. }
  8975. });
  8976. return FolderSearchBar;
  8977. });
  8978. /*
  8979. *+------------------------------------------------------------------------+
  8980. *| Licensed Materials - Property of IBM
  8981. *| IBM Cognos Products: Content Explorer
  8982. *| (C) Copyright IBM Corp. 2018
  8983. *|
  8984. *| US Government Users Restricted Rights - Use, duplication or disclosure
  8985. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  8986. *+------------------------------------------------------------------------+
  8987. */
  8988. define('bacontentnav/utils/TextUtils',[
  8989. ], function() {
  8990. 'use strict';
  8991. //some misc text manipulation methods
  8992. return {
  8993. /**
  8994. * Returns a modified string where all 'regex' characters (such as \, [, ], $, etc) are escaped.
  8995. * @param {String} string The string on which to replace all characters that could mess up a regex.
  8996. */
  8997. escapeRegexChars: function(string) {
  8998. var retString = string;
  8999. if (string && typeof string === 'string') {
  9000. retString = retString.replace(/[-[\]{}()*+?.\\^$|#]/g, '\\$&');
  9001. }
  9002. return retString;
  9003. }
  9004. };
  9005. });
  9006. /*
  9007. * Licensed Materials - Property of IBM
  9008. *
  9009. * IBM Cognos Products: GLASS
  9010. *
  9011. * (C) Copyright IBM Corp. 2017, 2018
  9012. *
  9013. * US Government Users Restricted Rights - Use, duplication or disclosure
  9014. * restricted by GSA ADP Schedule Contract with IBM Corp.
  9015. */
  9016. define('bacontentnav/common/FolderSearchController',[
  9017. '../lib/@waca/core-client/js/core-client/ui/core/Class',
  9018. 'jquery',
  9019. 'underscore',
  9020. './ui/ContentBar',
  9021. './ui/FolderSearchBar',
  9022. '../utils/TextUtils'
  9023. ], function(BaseClass, $, _, ContentBar, FolderSearchBar, TextUtils) {
  9024. 'use strict';
  9025. /**
  9026. * This Class is folder search bar controller
  9027. */
  9028. var FolderSearchController = BaseClass.extend(
  9029. /**
  9030. * @lends FolderSearchController.prototype
  9031. */
  9032. {
  9033. /**
  9034. * Constructor
  9035. * @param options.pageView {object} - The container's view
  9036. * @param options.class {string} - the css class used to render search bar widget
  9037. */
  9038. init: function(options) {
  9039. _.extend(this, options);
  9040. FolderSearchController.inherited('init', this, arguments);
  9041. this._filterColumnIndex = this._getFilterColumnIndex('MultipleProperties');
  9042. this.value = '';
  9043. },
  9044. /**
  9045. * Returns a promise resolved with search bar items (ie. SearchBar and cancel button )
  9046. **/
  9047. _folderSearchBarItems: function() {
  9048. return new Promise(function(resolve /*,reject*/ ) {
  9049. var items = [{
  9050. 'name': 'searchInput',
  9051. 'module': FolderSearchBar,
  9052. 'position': 'leading',
  9053. 'glassContext': this.pageView.glassContext,
  9054. 'controller': this,
  9055. 'label': '',
  9056. 'value': this.value
  9057. }];
  9058. resolve(items);
  9059. }.bind(this));
  9060. },
  9061. /**
  9062. * Returns/creates the folder search bar
  9063. **/
  9064. createFolderSearchBar: function(onSearchFilter, onClearFilter, onClearSearchFilter, renderFromReact) {
  9065. this.onSearchFilter = onSearchFilter;
  9066. this.onClearFilter = onClearFilter;
  9067. this.onClearSearchFilter = onClearSearchFilter;
  9068. this.renderFromReact = renderFromReact;
  9069. return this._folderSearchBarItems().then(function(items) {
  9070. this.$folderSearchBar = $('<div id="' + _.uniqueId('contentsearchbar_') + '" class="' + this.class + '"></div>');
  9071. this.getContainer().prepend(this.$folderSearchBar);
  9072. this._contentBar = new ContentBar({
  9073. el: this.$folderSearchBar,
  9074. items: items,
  9075. appController: this.pageView.appController,
  9076. appBarConfig: {
  9077. showHome: false,
  9078. showLogout: false
  9079. }
  9080. });
  9081. this.$folderSearchBar.attr('aria-live', 'polite');
  9082. this._contentBar.hide();
  9083. return this._contentBar.render().then(function() {
  9084. return this._contentBar.getAddedItem('searchInput').then(function(_searchInput){
  9085. this.searchInput = _searchInput;
  9086. _searchInput.search();
  9087. return this._contentBar;
  9088. }.bind(this));
  9089. }.bind(this));
  9090. }.bind(this));
  9091. },
  9092. /**
  9093. * apply filter to the list control of the page view
  9094. * @param {string} keyword - keyword uses to filter the list control;
  9095. **/
  9096. applyFilter: function(keyword) {
  9097. var oldValue = this.value;
  9098. if (this.onSearchFilter) {
  9099. this.onSearchFilter(keyword);
  9100. }
  9101. keyword = TextUtils.escapeRegexChars(keyword);
  9102. this.value = keyword;
  9103. if (this.pageView) {
  9104. if (this.pageView.getListControl()) {
  9105. this.pageView.getListControl().filter(keyword, this._filterColumnIndex, true);
  9106. }
  9107. if (this._isStateChange(oldValue, keyword)) {
  9108. this.pageView.trigger('filterState:change');
  9109. }
  9110. }
  9111. },
  9112. /**
  9113. * clear filter to the list control of the page view
  9114. **/
  9115. clearFilter: function() {
  9116. this.onClear();
  9117. },
  9118. clearSearch: function() {
  9119. if (this.searchInput) {
  9120. this.searchInput.clear();
  9121. if (this.onClearSearchFilter) {
  9122. this.onClearSearchFilter();
  9123. }
  9124. }
  9125. },
  9126. /**
  9127. * called when the user clicks on cancel button of the search bar
  9128. **/
  9129. onClear: function() {
  9130. if (this.searchInput) {
  9131. this.searchInput.clear();
  9132. }
  9133. if (this.onClearFilter) {
  9134. this.onClearFilter();
  9135. }
  9136. this.applyFilter('');
  9137. },
  9138. /**
  9139. * find the corresponding index number in list control with the column name
  9140. * @param {string} columnName - the name of the column
  9141. * @return {int} column index number
  9142. **/
  9143. _getFilterColumnIndex: function(columnName) {
  9144. var columns = this.pageView._getColumnSpecification(),
  9145. i;
  9146. for (i = 0; i < columns.length; i++) {
  9147. if (columns[i].type === columnName) {
  9148. return i;
  9149. }
  9150. }
  9151. return -1;
  9152. },
  9153. /**
  9154. * Is the current active element a editable element like input or textArea?
  9155. * @return {boolean}
  9156. */
  9157. _isEditableTag: function(name) {
  9158. return name === 'input' || name === 'textArea';
  9159. },
  9160. /**
  9161. * is current focus on a input
  9162. * @return {boolean} true - the current focus is on a input; otherwise false;
  9163. **/
  9164. _isCurrentFocusEditable: function() {
  9165. var focus = $(document.activeElement);
  9166. if (focus && this._isEditableTag(focus[0].localName)) {
  9167. return true;
  9168. } else {
  9169. return false;
  9170. }
  9171. },
  9172. /**
  9173. * get the container of the current page view;
  9174. * @return {object} - current container view;
  9175. **/
  9176. getContainer: function() {
  9177. return this.pageView.getContainer();
  9178. },
  9179. /**
  9180. * get the content bar of the current page view;
  9181. * @return {object} - current content bar;
  9182. **/
  9183. getContentBar: function() {
  9184. return this.pageView.contentBar;
  9185. },
  9186. /**
  9187. * setter for search input value
  9188. * @param {string} value - input value
  9189. */
  9190. setInputValue: function(value) {
  9191. var oldValue = this.value;
  9192. this.value = value;
  9193. if (this._isStateChange(this.value, oldValue)) {
  9194. this.pageView.trigger('filterState:change');
  9195. }
  9196. },
  9197. _isStateChange: function(oldValue, newValue) {
  9198. return oldValue === '' && newValue !== '' || oldValue !== '' && newValue === '';
  9199. },
  9200. /**
  9201. * test if we should handle the keyboard event caught from contentListPageView
  9202. * @param {object} e - keyboard event
  9203. * @return true should handle the keyboard event; otherwise, false
  9204. **/
  9205. shouldHandle: function(e) {
  9206. /* keyCodesList = [tab, enter, shift, ctrl, alt, esc, arrow left, arrow top, arrow right, arrow bottom]*/
  9207. var keyCodesList = [9,13,16,17,18,27,37,38,39,40];
  9208. var _shouldHandle = keyCodesList.indexOf(e.which) === -1 && keyCodesList.indexOf(e.keyCode) === -1 && !e.ctrlKey && !e.metaKey && !e.altKey;
  9209. if (_shouldHandle && !this._isCurrentFocusEditable()) {
  9210. return true;
  9211. } else {
  9212. return false;
  9213. }
  9214. },
  9215. isDirty: function() {
  9216. return this.value && this.value.trim() !== '';
  9217. }
  9218. });
  9219. return FolderSearchController;
  9220. });
  9221. /*
  9222. *+------------------------------------------------------------------------+
  9223. *| Licensed Materials - Property of IBM
  9224. *| IBM Cognos Products: SEARCH
  9225. *| (C) Copyright IBM Corp. 2017, 2021
  9226. *|
  9227. *| US Government Users Restricted Rights - Use, duplication or disclosure
  9228. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  9229. *+------------------------------------------------------------------------+
  9230. */
  9231. define('bacontentnav/common/FilterViewController',[
  9232. 'underscore',
  9233. 'moment',
  9234. '../lib/@waca/core-client/js/core-client/ui/core/Class'
  9235. ], function(_, Moment, Class) {
  9236. 'use strict';
  9237. /*
  9238. * This class is the filter view controller
  9239. */
  9240. var Fvc = Class.extend({
  9241. propertyUIControlModule: 'bi/commons/ui/properties/PropertyUIControl',
  9242. /**
  9243. * Constructor
  9244. * @param options.view {string} - container's view
  9245. */
  9246. init: function(options) {
  9247. Fvc.inherited('init', this, arguments);
  9248. this.minRange = null;
  9249. this.maxRange = null;
  9250. this.dateModifiedLabel = '';
  9251. this.view = options.view;
  9252. //filterSpecs is a method that returns the columns specifications for filtering
  9253. this.filterSpecs = options.filterSpecs;
  9254. //find the filter column
  9255. this.filterColumn = this.findTypeFilterColumn('Icon');
  9256. this.filterObject = {
  9257. //the filterObject contains all of our filter elements (folders, data, etc.)
  9258. type: options.filterObject,
  9259. modificationTime: options.modificationTime || {}
  9260. };
  9261. this.resultLimit = 50;
  9262. this.setResultLimit = options.setResultLimit;
  9263. this.strokeShown = false; // Small circle that appears above the filter after the filter is selected
  9264. this.resetSelected();
  9265. this.filteredClassShown = false;
  9266. },
  9267. /**
  9268. * Sends out a 'filterState:change' event to the listening view.
  9269. * The view is repsonsible for handling the filtering using the query and column provided.
  9270. * @param {string} filterQuery - string which is passed in to the datatable's filter API
  9271. **/
  9272. filter: function(filterQuery) {
  9273. this.view.trigger('filterState:change', { filterQuery:filterQuery, column:this.filterColumn });
  9274. },
  9275. /**
  9276. * Sets the minimum and maximum range when the date modified filter has been triggered
  9277. * Sends out a 'filterState:changeDate' event to the listening view.
  9278. * The view is responsible for handling the filtering using the minRange, maxRange and/or the modificationTime
  9279. * @param {string} value - string used to set the minRange and maxRange
  9280. **/
  9281. onChangeModificationTime: function(value) {
  9282. var rangeVariable = value.split('|');
  9283. this.minRange = rangeVariable[0] || null;
  9284. this.maxRange = rangeVariable[1] || null;
  9285. this._dateModifiedLabelSetter(value);
  9286. //just redraw the datatable
  9287. if (this.selected.modificationTime !== value) {
  9288. this.selected.modificationTime = value;
  9289. this.view.trigger('filterState:changeDate', { minRange: this.minRange, maxRange: this.maxRange, modificationTime: this.selected.modificationTime });
  9290. }
  9291. },
  9292. /**
  9293. * Sets the result limit.
  9294. * Sends out a 'filterState:changeResutLimit' event to the listening view.
  9295. * The view is responsible for handling the updating the view with the new result limit.
  9296. * @param {number} value - new result limit
  9297. **/
  9298. onChangeResultLimit: function(value) {
  9299. this.resultLimit = value;
  9300. this.view.trigger('filterState:changeResutLimit', { resultLimit: value });
  9301. },
  9302. /**
  9303. * returns the current result limit
  9304. **/
  9305. getResultLimit: function() {
  9306. return this.resultLimit;
  9307. },
  9308. /**
  9309. * Returns the column number where columnName matches what is in filterSpecs
  9310. * @param {string} columnName - string used to find the column number with the associated name
  9311. * @return {int} returns the column index number
  9312. **/
  9313. findTypeFilterColumn: function(columnName) {
  9314. var columns = this.filterSpecs();
  9315. for (var i = 0; i < columns.length; i++) {
  9316. if (columns[i].type === columnName) {
  9317. return i;
  9318. }
  9319. }
  9320. return -1;
  9321. },
  9322. /**
  9323. * returns an array of all individual selected types
  9324. */
  9325. getSelectedTypes: function() {
  9326. var displayTypes = [];
  9327. _.each(this.selected.types, function(type) {
  9328. displayTypes = displayTypes.concat(type.split('|'));
  9329. }.bind(this));
  9330. return displayTypes;
  9331. },
  9332. /**
  9333. * returns a stringified version of the currenctly selected types
  9334. */
  9335. getSelectedTypesQuery: function() {
  9336. return this.selected.types.join('|');
  9337. },
  9338. /**
  9339. * Concatenates queries based on which filter type has been selected
  9340. * Removes queries if they have been unselected
  9341. * @param {string} filter - string used to identify the filter being clicked
  9342. * @param {boolean} state - used to identify whether or not the filter is checked
  9343. * @returns True if the selection was added
  9344. **/
  9345. onChangeTypeFilter: function(filter, state) {
  9346. var filterType = this.filterObject.type[filter];
  9347. var ret = false;
  9348. if (state) {
  9349. if (this.selected.types.indexOf(filterType) === -1) {
  9350. this.selected.types.push(filterType);
  9351. ret = true;
  9352. }
  9353. } else {
  9354. this.selected.types = _.without(this.selected.types, filterType);
  9355. }
  9356. return ret;
  9357. },
  9358. /**
  9359. * Sets the date for modificationTime queries
  9360. **/
  9361. setDefaultFilters: function() {
  9362. this.filterObject.modificationTime = {};
  9363. var now = Moment().hour(0).minute(0).second(0).millisecond(0).add(1, 'd');
  9364. this.filterObject.modificationTime.today = now.clone().subtract(1, 'd').toISOString() +
  9365. '|' + now.toISOString();
  9366. this.filterObject.modificationTime.yesterday = now.clone().subtract(2, 'd').toISOString() +
  9367. '|' + now.clone().subtract(1, 'd').toISOString();
  9368. this.filterObject.modificationTime.pastWeek = now.clone().subtract(1, 'w').toISOString() +
  9369. '|' + now.toISOString();
  9370. this.filterObject.modificationTime.pastMonth = now.clone().subtract(1, 'M').toISOString() +
  9371. '|' + now.toISOString();
  9372. },
  9373. /**
  9374. * programatically sets a filter type.
  9375. * returns a promise that is resolved when the filter is rerendered
  9376. * @param {String} filter
  9377. */
  9378. addFilter: function(filter) {
  9379. if (this.onChangeTypeFilter(filter, true)) {
  9380. this.filter(this.getSelectedTypesQuery(), this.filterColumn);
  9381. }
  9382. //update the UI
  9383. if (this.filterView) {
  9384. return this.filterView.render();
  9385. } else {
  9386. return Promise.resolve();
  9387. }
  9388. },
  9389. /**
  9390. * returns true if the provided filter type has been filtered.
  9391. */
  9392. isFiltered: function(filter) {
  9393. return this.selected.types.indexOf(filter) !== -1;
  9394. },
  9395. /**
  9396. * returns true if the user has filtered anything
  9397. */
  9398. isDirty: function() {
  9399. return this.selected.types.length > 0 || (this.minRange !== null && this.maxRange !== null);
  9400. },
  9401. /**
  9402. * Resets all of our selections
  9403. */
  9404. resetSelected: function() {
  9405. this.setDefaultFilters();
  9406. this.selected = {
  9407. 'types': [],
  9408. 'modificationTime': null
  9409. };
  9410. this.minRange = null;
  9411. this.maxRange = null;
  9412. this.dateModifiedLabel = '';
  9413. },
  9414. /**
  9415. * Removes a 'filtered' css clas to the provided button
  9416. */
  9417. removeFilteredClass: function(button) {
  9418. if (this.selected.types.length == 0 && this.minRange === null && this.maxRange === null) {
  9419. $(button).removeClass('filtered');
  9420. this.filteredClassShown = false;
  9421. }
  9422. },
  9423. /**
  9424. * Adds a 'filtered' css clas to the provided button
  9425. */
  9426. addFilteredClass: function(button) {
  9427. if (!this.filteredClassShown) {
  9428. $(button).addClass('filtered');
  9429. this.filteredClassShown = true;
  9430. }
  9431. },
  9432. /**
  9433. * Returns the currently set Modification Time
  9434. */
  9435. getModificationTime: function() {
  9436. return this.selected.modificationTime;
  9437. },
  9438. /**
  9439. * Returns the currently set Minimum Date range, or null if not set
  9440. */
  9441. getMinRange: function() {
  9442. return this.minRange;
  9443. },
  9444. /**
  9445. * Returns the currently set Maximum Date range, or null if not set
  9446. */
  9447. getMaxRange: function() {
  9448. return this.maxRange;
  9449. },
  9450. /**
  9451. * Sets the dateModifiedLabel (which is a concatenation of minRange and maxRange)
  9452. * @param {string} value - string used to set dateModifiedLabel so the state of date modification time will be remembered
  9453. * if the filter gets re-rendered
  9454. **/
  9455. _dateModifiedLabelSetter: function(value) {
  9456. // Empty string is treated as falsy
  9457. if (value === '') {
  9458. this.dateModifiedLabel = '';
  9459. } else {
  9460. this.dateModifiedLabel = value ? value : this.dateModifiedLabel;
  9461. }
  9462. }
  9463. });
  9464. return Fvc;
  9465. });
  9466. !function(e,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"));else if("function"==typeof define&&define.amd)define('bacontentnav/lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/filter-applied_16',["@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"],i);else{var o=i("object"==typeof exports?require("@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"):e["@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"]);for(var s in o)("object"==typeof exports?exports:e)[s]=o[s]}}("undefined"!=typeof self?self:this,function(e){return webpackJsonPBaGraphics([1239],{"3865314c5959606874d4":function(i,o){i.exports=e},"47a4fa6d8010c58f1e00":function(e,i,o){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var s=o("3865314c5959606874d4"),a=(o.n(s),o("e21347f38ade5a747478"));i.default=a.a},e21347f38ade5a747478:function(e,i,o){"use strict";var s=o("9689a9c94ae38b47fa2c"),a=o.n(s),c=o("9ce58a7deea14f49ef01"),t=o.n(c),n=new a.a({id:"filter-applied_16_v7",use:"filter-applied_16_v7-usage",viewBox:"0 0 16 16",content:'<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" id="filter-applied_16_v7"><path d="M10 7c.8 0 1.5.7 1.5 1.5S10.8 10 10 10s-1.5-.7-1.5-1.5S9.2 7 10 7zm3-5H3c-.6 0-1 .4-1 1v1.8c0 .3.1.5.3.7L6 9.2V13c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1.5c-.3 0-.7-.1-1-.2V13H7V8.8l-4-4V3h10v1.8l-1.3 1.3c.3.2.5.4.7.7l1.3-1.3c.2-.2.3-.4.3-.7V3c0-.6-.4-1-1-1z" /></symbol>'});t.a.add(n);i.a=n}},["47a4fa6d8010c58f1e00"])});
  9467. !function(e,o){if("object"==typeof exports&&"object"==typeof module)module.exports=o(require("@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"));else if("function"==typeof define&&define.amd)define('bacontentnav/lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/filter_16',["@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"],o);else{var s=o("object"==typeof exports?require("@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"):e["@ba-ui-toolkit/ba-graphics/dist/icons-js/ba-graphics-icons-commons.js"]);for(var i in s)("object"==typeof exports?exports:e)[i]=s[i]}}("undefined"!=typeof self?self:this,function(e){return webpackJsonPBaGraphics([1233],{"2a291322f8aea355dd92":function(e,o,s){"use strict";var i=s("9689a9c94ae38b47fa2c"),t=s.n(i),c=s("9ce58a7deea14f49ef01"),a=s.n(c),n=new t.a({id:"filter_16_v7",use:"filter_16_v7-usage",viewBox:"0 0 16 16",content:'<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" id="filter_16_v7"><path d="M9 14H7c-.6 0-1-.4-1-1V9.2L2.3 5.5c-.2-.2-.3-.4-.3-.7V3c0-.6.4-1 1-1h10c.6 0 1 .4 1 1v1.8c0 .3-.1.5-.3.7L10 9.2V13c0 .6-.4 1-1 1zM3 3v1.8l4 4V13h2V8.8l4-4V3H3z" /></symbol>'});a.a.add(n);o.a=n},"3865314c5959606874d4":function(o,s){o.exports=e},e7be0695235c82fb118e:function(e,o,s){"use strict";Object.defineProperty(o,"__esModule",{value:!0});var i=s("3865314c5959606874d4"),t=(s.n(i),s("2a291322f8aea355dd92"));o.default=t.a}},["e7be0695235c82fb118e"])});
  9468. /*
  9469. *+------------------------------------------------------------------------+
  9470. *| Licensed Materials - Property of IBM
  9471. *| IBM Cognos Products: Content Explorer
  9472. *| (C) Copyright IBM Corp. 2015, 2019
  9473. *|
  9474. *| US Government Users Restricted Rights - Use, duplication or disclosure
  9475. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  9476. *+------------------------------------------------------------------------+
  9477. */
  9478. define('bacontentnav/common/BaseContentWideView',[
  9479. './ContentListPageView',
  9480. '../nls/StringResource',
  9481. '../utils/ContentStoreObject',
  9482. '../utils/UIHelper',
  9483. './FolderSearchController',
  9484. './FilterViewController',
  9485. 'moment',
  9486. 'text!./templates/EmptyListTemplate.html',
  9487. '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/filter-applied_16',
  9488. '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/filter_16',
  9489. '../lib/@waca/core-client/js/core-client/utils/Utils',
  9490. 'jquery'
  9491. ], function(ContentListPageView, StringResource, ContentStoreObject, UIHelper, FolderSearchController, FilterViewController, Moment, EmptyListTemplate, filterApplied_16, filter_16, Utils, $) {
  9492. 'use strict'; //NOSONAR
  9493. var BaseContentWideView = ContentListPageView.extend({
  9494. init: function(options) {
  9495. void(options);
  9496. BaseContentWideView.inherited('init', this, arguments);
  9497. this.addURLParameters({
  9498. 'nav_filter': 'true',
  9499. 'fields': 'userInterfaces,defaultName,disabled,hidden,permissions,runInAdvancedViewer,modificationTime,canBurst,iconURI,defaultScreenTip,searchPath,defaultPortalAction,base.defaultName,tags,target.searchPath,target.disabled,effectiveUserCapabilities,base.permissions,options,base.options'
  9500. });
  9501. this.folderSearchController = new FolderSearchController({
  9502. 'pageView': this,
  9503. 'class': 'contentsearchbar'
  9504. });
  9505. this.getContainer().on('keypress', this.handleKeyboard.bind(this));
  9506. this.filterViewController = new FilterViewController({
  9507. filterSpecs: this._getColumnSpecification.bind(this),
  9508. view: this,
  9509. filterObject: UIHelper.getFilterFacets(['content'])
  9510. });
  9511. this._filterRangeCallback();
  9512. this.on('filterState:change', this.onFilterStateChange.bind(this));
  9513. this.on('filterState:changeDate', this.onFilterStateChangeDate.bind(this));
  9514. },
  9515. remove: function() {
  9516. BaseContentWideView.inherited('remove', this, arguments);
  9517. this.off('filterState:change');
  9518. this.off('filterState:changeDate');
  9519. },
  9520. /**
  9521. * Callback from the filterState:change trigger in the filterViewController
  9522. * @param {Object} filterObject An object that contains the 'filterQuery' to use and 'column' index
  9523. */
  9524. onFilterStateChange: function(filterObject) {
  9525. if (filterObject && filterObject.filterQuery !== undefined && this.getListControl()) {
  9526. this.getListControl().filter(filterObject.filterQuery, filterObject.column, true);
  9527. }
  9528. var svgContainer = this.$el.find('.contentNavFilter');
  9529. var svg = svgContainer.find('.svgIcon');
  9530. svg.remove();
  9531. if (this.folderSearchController.isDirty() || this.filterViewController.isDirty()) {
  9532. Utils.setIcon(svgContainer, filterApplied_16.default.id);
  9533. } else {
  9534. Utils.setIcon(svgContainer, filter_16.default.id);
  9535. }
  9536. },
  9537. /**
  9538. * called when the user filters the filtercontroller by date
  9539. */
  9540. onFilterStateChangeDate: function() {
  9541. this.onFilterStateChange();
  9542. if (this.getListControl()) {
  9543. this.getListControl().getDatatable().fnDraw();
  9544. }
  9545. },
  9546. getSlideoutWidth: function() {
  9547. return '300px';
  9548. },
  9549. saveSlideoutWidth: function() {
  9550. var width = this.$el.width();
  9551. UIHelper.saveSlideoutWidth(this.id, width);
  9552. },
  9553. handleKeyboard: function(e) {
  9554. //handle any keypresses that will open the filterview.
  9555. if (this.folderSearchController.shouldHandle(e)) {
  9556. this.folderSearchController.setInputValue(String.fromCharCode(e.which));
  9557. this.filterViewClicked();
  9558. }
  9559. },
  9560. renderContent: function() {
  9561. var _resizeCallback = null;
  9562. return this.renderContentList({
  9563. 'disableColumnHeaders': true,
  9564. 'columns': this._getColumnSpecification(),
  9565. 'url': (this.url || this._getDefaultRequestURL()),
  9566. 'selfDefindedEmptyListTemplate': EmptyListTemplate,
  9567. 'emptyIcon': this.emptyIcon,
  9568. 'resizeCallback': function() {
  9569. //Adjusting the screen width resets the scrolling of the content list view
  9570. var ancestors = this.$el.find('.navigationAncestor');
  9571. if (ancestors.length > 0) {
  9572. var row = ancestors[0];
  9573. var scrollingParent = $(row).closest('.dataTables_scrollBody');
  9574. $(scrollingParent).scrollTop(row.offsetTop - scrollingParent.offsetTop);
  9575. }
  9576. if (_resizeCallback) {
  9577. clearTimeout(_resizeCallback);
  9578. }
  9579. _resizeCallback = setTimeout(this.saveSlideoutWidth.bind(this), 500);
  9580. }.bind(this),
  9581. 'dataManipulationCallback': this.dataManipulationCallback,
  9582. 'groupByColumnAPI': this.getGroupByColumnAPI()
  9583. });
  9584. },
  9585. /**
  9586. * @override
  9587. */
  9588. getListControlOptions: function() {
  9589. return { setFocusOnDraw: true };
  9590. },
  9591. getViewContainerClass: function() {
  9592. return 'ContentListPageView ContentWideView';
  9593. },
  9594. /**
  9595. * @override
  9596. **/
  9597. _addFolder: function() {
  9598. //clear out the search
  9599. this.folderSearchController.clearFilter();
  9600. //if we're filtered, then remove the modification time and add the 'folders' filter
  9601. // to ensure we can see the 'add folder' inline editor.
  9602. if (this.filterViewController.isDirty()) {
  9603. this.filterViewController.onChangeModificationTime('');
  9604. this.filterViewController.addFilter('folders').then(function() {
  9605. BaseContentWideView.inherited('_addFolder', this, arguments);
  9606. }.bind(this));
  9607. } else {
  9608. BaseContentWideView.inherited('_addFolder', this, arguments);
  9609. }
  9610. },
  9611. /**
  9612. Defines the columns for the data table. The structure and properties of the definition come
  9613. from the datatable API.
  9614. **/
  9615. _getColumnSpecification: function() {
  9616. return [{
  9617. 'type': 'Icon',
  9618. 'accessibleLabel': StringResource.get('itemType')
  9619. }, {
  9620. 'type': 'Name',
  9621. 'scope': 'row'
  9622. }, {
  9623. 'type': 'Time',
  9624. 'propertyName': ContentStoreObject.MODIFICATION_TIME
  9625. }, {
  9626. 'type': 'ContextMenu'
  9627. }];
  9628. },
  9629. navigate: function(oData, row) {
  9630. void(row);
  9631. if (UIHelper.isContainer(ContentStoreObject.getType(oData))) {
  9632. if (this.slideout) {
  9633. this.slideout.$el.attr('aria-label', ContentStoreObject.getName(oData));
  9634. }
  9635. } else {
  9636. var ancestors = ContentStoreObject.getAncestors(this);
  9637. if (ancestors) {
  9638. var parent = ancestors[ancestors.length-1];
  9639. arguments[0] = parent;
  9640. this.ancestors.pop();
  9641. }
  9642. }
  9643. BaseContentWideView.inherited('navigate', this, arguments);
  9644. },
  9645. /**
  9646. * Creats slideout and sends information over to FilterView.js
  9647. **/
  9648. filterViewClicked: function() {
  9649. var _show = false;
  9650. if (this._filterSlideout == null && this.contentBar.itemMap.contentNavFilter) {
  9651. var filterButton = this.contentBar.itemMap.contentNavFilter.$el.find('button');
  9652. if (filterButton.prop('disabled') === false) {
  9653. _show = true;
  9654. this._showFilterSlideout();
  9655. }
  9656. }
  9657. if (!_show) {
  9658. this._onFilterSlideoutHide();
  9659. }
  9660. },
  9661. /**
  9662. * show the filter slideout if it is not currently being shown.
  9663. */
  9664. _showFilterSlideout: function() {
  9665. if (this._filterSlideout == null) {
  9666. if (this.contentBar.itemMap.contentNavFilter) {
  9667. var filterButton = this.contentBar.itemMap.contentNavFilter.$el.find('button');
  9668. this.filterViewController.addFilteredClass(filterButton);
  9669. }
  9670. this._filterSlideout = this.glassContext.appController.showSlideOut({
  9671. 'parent': this.slideout,
  9672. 'label': StringResource.get('filterBy'),
  9673. 'width': '200px',
  9674. 'hideOnParentClick': false,
  9675. 'content': {
  9676. 'module': 'bacontentnav/common/FilterView',
  9677. 'view': this,
  9678. 'searchBarController': this.folderSearchController,
  9679. 'filterController': this.filterViewController
  9680. }
  9681. });
  9682. //on hide remove the filtered class
  9683. this._filterSlideout.on('hide', function() {
  9684. this._onFilterSlideoutHide();
  9685. }.bind(this));
  9686. }
  9687. },
  9688. /**
  9689. * called when the user closes the filter view
  9690. */
  9691. _onFilterSlideoutHide: function() {
  9692. if (!this.folderSearchController.isDirty() && !this.filterViewController.isDirty()) {
  9693. var filterButton = this.contentBar.itemMap.contentNavFilter.$el.find('button');
  9694. this.filterViewController.removeFilteredClass(filterButton);
  9695. }
  9696. if (this._filterSlideout) {
  9697. //hide it
  9698. this._filterSlideout.hide();
  9699. this._filterSlideout = null;
  9700. }
  9701. },
  9702. /**
  9703. * Filters the datatable based on a minimum and a maximum range defined in the filterViewController
  9704. **/
  9705. _filterRangeCallback: function() {
  9706. if (!this.registeredCallback) {
  9707. $.fn.dataTable.ext.search.push(this._checkFilterRange.bind(this));
  9708. this.registeredCallback = true;
  9709. }
  9710. },
  9711. /**
  9712. * Private function to filters the datatable based on a minimum and a maximum range
  9713. **/
  9714. _checkFilterRange: function(settings, data, dataIndex) {
  9715. void(dataIndex);
  9716. if (this.getListControl()) {
  9717. var fnSettings = this.getListControl().getDatatable().fnSettings();
  9718. if ((settings && settings.sTableId) === (fnSettings && fnSettings.sTableId)) {
  9719. var createdAt = data[2];
  9720. var minRange = this.filterViewController.getMinRange();
  9721. var maxRange = this.filterViewController.getMaxRange();
  9722. if (minRange && maxRange) {
  9723. return (Moment(createdAt).isSameOrAfter(minRange) && Moment(createdAt).isSameOrBefore(maxRange));
  9724. }
  9725. }
  9726. }
  9727. return true;
  9728. },
  9729. /*
  9730. * Create the getGroupByColumnAPI to be passed to the ListControl
  9731. */
  9732. getGroupByColumnAPI: function() {
  9733. return undefined;
  9734. }
  9735. });
  9736. return BaseContentWideView;
  9737. });
  9738. /**
  9739. * Licensed Materials - Property of IBM
  9740. *
  9741. * IBM Cognos Products: Content Explorer
  9742. *
  9743. * Copyright IBM Corp. 2015, 2018
  9744. *
  9745. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9746. */
  9747. define('bi/content_apps/nls/ContentExplorerResources',{
  9748. "root": true,
  9749. "cs": true,
  9750. "da": true,
  9751. "de": true,
  9752. "es": true,
  9753. "fi": true,
  9754. "fr": true,
  9755. "he": true,
  9756. "hr": true,
  9757. "hu": true,
  9758. "it": true,
  9759. "ja": true,
  9760. "kk": true,
  9761. "ko": true,
  9762. "no": true,
  9763. "nb": true,
  9764. "nl": true,
  9765. "pl": true,
  9766. "pt": true,
  9767. "pt-br": true,
  9768. "ro": true,
  9769. "ru": true,
  9770. "sl": true,
  9771. "sv": true,
  9772. "th": true,
  9773. "tr": true,
  9774. "zh": true,
  9775. "zh-cn": true,
  9776. "zh-tw": true
  9777. });
  9778. /**
  9779. * Licensed Materials - Property of IBM
  9780. * IBM Cognos Products: content-apps
  9781. * (C) Copyright IBM Corp. 2022, 2022
  9782. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9783. */
  9784. define('bi/content_apps/nls/root/ContentExplorerResources',{
  9785. "allContent": "All content",
  9786. "allGenericItems": "All",
  9787. "myContent": "My content",
  9788. "copy": "Copy to",
  9789. "confirmDelete": "Confirm delete",
  9790. "confirmDeleteMessage": "Deleting entries can break links. Are you sure you want to delete the selected entries?",
  9791. "dashboards": "Dashboards",
  9792. "delete": "Delete",
  9793. "edit": "Edit",
  9794. "notebooks": "Notebooks",
  9795. "modificationTime": "Modified",
  9796. "modifiedWithColon": "Modified:",
  9797. "move": "Move to",
  9798. "name": "Name",
  9799. "tenant": "Tenant",
  9800. "tenantSettings": "Tenant settings",
  9801. "tenantSet": "Tenant updated",
  9802. "tenantSetError": "Error setting tenant",
  9803. "tenantClear": "Tenant cleared",
  9804. "tenantClearError": "Error clearing tenant",
  9805. "owner": "Owner",
  9806. "reports": "Reports",
  9807. "copyMove": "Copy or move:",
  9808. "copyOnly": "Copy",
  9809. "goToCloudLocation": "Go to cloud location",
  9810. "noOfItemSelected": "%{noOfItems} selected",
  9811. "selectDestination": "Select a destination",
  9812. "selectAccountGroupOrRole": "Select groups, users or roles",
  9813. "members": "Members",
  9814. "teamFolders": "Team content",
  9815. "folders": "Folders",
  9816. "type": "Type",
  9817. "folderTeamContent": "Folder (Team Content)",
  9818. "typeWithColon": "Type:",
  9819. "unknown": "Unknown",
  9820. "description": "Description",
  9821. "general": "General",
  9822. "advancedProperties": "Advanced",
  9823. "location": "Location",
  9824. "schedule": "Schedule",
  9825. "created": "Created",
  9826. "createdWithColon": "Created:",
  9827. "disableThisEntry": "Disable this entry",
  9828. "hideThisEntry": "Hide this entry",
  9829. "indexed": "Indexed",
  9830. "language": "Language",
  9831. "reportOutputVersions": "Report output versions",
  9832. "reportOutputVersion": "Report output version",
  9833. "rowsPerPageHtmlReport": "Rows per page in HTML Reports",
  9834. "package": "Package",
  9835. "data": "Data",
  9836. "dataModule": "Data module",
  9837. "mode": "Mode",
  9838. "live": "Live",
  9839. "snapshot": "Snapshot",
  9840. "noSnapshotsFound": "No Snapshot found",
  9841. "uploadedFile": "Uploaded file",
  9842. "fileUpload": "Upload files",
  9843. "dataSetEx": "Data set",
  9844. "externalRepository": "External repository",
  9845. "queryMode": "Query mode",
  9846. "queryModeCompatible": "Compatible",
  9847. "queryModeDynamic": "Dynamic",
  9848. "report": "Report",
  9849. "activeReport": "Active Report",
  9850. "query": "Query",
  9851. "analysis": "Analysis",
  9852. "permission": "Permissions",
  9853. "capabilities": "Capabilities",
  9854. "newFolderDefaultName": "New Folder",
  9855. "newFolderLabel": "New folder",
  9856. "switchViewsLabel": "Switch Views",
  9857. "emptyTableContentMessage": "There's nothing in this folder",
  9858. "emptyRecentList": "You haven't viewed any content recently.",
  9859. "back": "Back",
  9860. "optionsMenuLabel": "Options",
  9861. "defaultAction": "Default action",
  9862. "reportOptions": "Report options",
  9863. "promptValues": "Prompt values",
  9864. "runTheReport": "Run the report",
  9865. "viewMostRecentReport": "View most recent report",
  9866. "openWithReportStudio": "Open with Report Studio",
  9867. "comingSoon": "Coming soon",
  9868. "recentlyViewed": "Recently viewed",
  9869. "destination": "Destination:",
  9870. "lastUsed": "Last Used",
  9871. "reportView": "Report View",
  9872. "folder": "Folder",
  9873. "dashboard": "Dashboard",
  9874. "story": "Story",
  9875. "workspace": "Workspace",
  9876. "pagelet": "Page",
  9877. "content": "Content",
  9878. "directory": "Namespaces",
  9879. "dataSet": "Data set",
  9880. "powerPlayCube": "PowerPlay Cube",
  9881. "powerPlayReport": "PowerPlay Report",
  9882. "powerPlay8Report": "PowerPlay Report",
  9883. "powerPlay8ReportView": "PowerPlay Report View",
  9884. "reportTemplate": "Report Template",
  9885. "agent": "Agent",
  9886. "agentDefinition": "Agent Definition",
  9887. "agentDefinitionView": "Agent View",
  9888. "dataMovementTask": "Data Movement Task",
  9889. "dataMovementTaskAlias": "Data Movement Task Alias",
  9890. "document": "Document",
  9891. "DocumentRetention": "Document properties",
  9892. "jobDefinition": "Job Definition",
  9893. "job": "Job",
  9894. "metricsDataSourceETLTask": "Metrics Data Source ETL Task",
  9895. "metricsExportTask": "Metrics Export Task",
  9896. "metricsFileImportTask": "Metrics File Import Task",
  9897. "metricsMaintenanceTask": "Metrics Maintenance Task",
  9898. "planningTask": "Planning Task",
  9899. "shortcut": "Shortcut",
  9900. "URL": "URL",
  9901. "launchable": "Launchable",
  9902. "dataSetFolder": "Data Set Folder",
  9903. "ViewAccessibleLabel": "View %{label}",
  9904. "overrideReportOptions": "Override the default report options",
  9905. "format": "Format",
  9906. "formats": "Formats",
  9907. "saveReport": "Save the report",
  9908. "promptForValues": "Prompt me",
  9909. "promptGenerationHint": "You will be prompted for input before the report runs in background.",
  9910. "html": "HTML",
  9911. "pdf": "PDF",
  9912. "spreadsheetML": "Excel",
  9913. "xlsxData": "Excel Data",
  9914. "csv": "CSV",
  9915. "xml": "XML",
  9916. "runAs": "Run as",
  9917. "permissionHeader": "Permission",
  9918. "read": "Read",
  9919. "write": "Write",
  9920. "execute": "Execute",
  9921. "setPolicy": "Set Policy",
  9922. "full": "Full",
  9923. "traverse": "Traverse",
  9924. "toastDoneMoving": "%{noOfItems} items were moved.",
  9925. "toastDoneCopying": "%{noOfItems} items were copied.",
  9926. "toastDoneShortcutting": "%{noOfItems} shortcuts were created.",
  9927. "toastDoneDeleting": "%{noOfItems} items were deleted.",
  9928. "toastDoneMovingSingular": "%{nameOfItem} was moved.",
  9929. "toastDoneCopyingSingular": "%{nameOfItem} was copied.",
  9930. "toastDoneShortcuttingSingular": "%{nameOfItem} was created.",
  9931. "toastDoneShortcuttingPortalPage": "Shortcut to %{nameOfItem} was created in My portal pages.",
  9932. "toastCreateNewFolder": "%{nameOfFolder} was created.",
  9933. "toastDoneDeletingSingular": "%{nameOfItem} was deleted.",
  9934. "toastLaunchPerspectiveError": "Cannot open object %{objectType}.",
  9935. "toastItemsWereAdded": "%{noOfItems} items were added to the profile.",
  9936. "toastItemsWereAddedSingular": "%{noOfItems} item was added to the profile.",
  9937. "toastItemsAlreadyAddedSingular": "Item has already been added to the profile.",
  9938. "toastItemsAlreadyAdded": "Items have already been added to the profile.",
  9939. "toastItemsWereDeleted": "%{noOfItems} items in the profile were deleted.",
  9940. "toastItemsWereDeletedSingular": "%{noOfItems} item in the profile was deleted.",
  9941. "toastRunRequestWasSubmitted": "Run request was submitted.",
  9942. "toastRunRequestFailed": "Run request failed.",
  9943. "shortCutName": "%{nameOfItem}%{shortCutLabel}",
  9944. "ok": "OK",
  9945. "cancel": "Cancel",
  9946. "permissionDetails": "Permission Details",
  9947. "grant": "Grant",
  9948. "deny": "Deny",
  9949. "overrideParentPermissions": "Override parent permissions",
  9950. "applyToAllChildren": "Apply to all children",
  9951. "policiesTableLable": "Policies",
  9952. "policesAddButtonLabel": "Member",
  9953. "policesAddMemberButtonLabel": "Add",
  9954. "policesRemove": "Remove",
  9955. "policiesFindAUserHint": "Search",
  9956. "policiesFindModeMenuTip": "Search method",
  9957. "policiesFindMode": "Search",
  9958. "policiesTypeInMode": "Type in",
  9959. "policyFilterAccounts": "Users",
  9960. "policyFilterRoles": "Roles",
  9961. "policyFilterGroups": "Groups",
  9962. "policyToastMessageSyntax": "Type the names of the entries to find, separated by semi-colons. Use the format namespace/user, group or role; For example, type Cognos/Everyone",
  9963. "policyToastMessageNamespace": "You must first select a namespace.",
  9964. "emptyPolicyList": "Nothing found",
  9965. "applyLabel": "Apply",
  9966. "permissionRead": "Read",
  9967. "permissionRun": "Run",
  9968. "permissionWrite": "Write",
  9969. "permissionFull": "Full",
  9970. "permissionCustom": "Custom",
  9971. "permissionDetailsColumnAccess": "Access",
  9972. "permissionDetailsColumnPermission": "Permission",
  9973. "permissionDetailsColumnAction": "Action",
  9974. "permissionSetAccess": "Set access",
  9975. "preferencesMyCredentials": "My credentials",
  9976. "preferencesCredentialsLabel": "Credentials",
  9977. "preferencesDataSourceCredentialsLabel": "Data Servers",
  9978. "preferencesDatasourceTitle": "Data server credentials",
  9979. "preferencesDatasourceHeader": "Data server name",
  9980. "preferencesGroupsAndRoles": "Groups and Roles",
  9981. "preferencesMyCapabilities": "My Capabilities",
  9982. "preferencesCredentialsHintText": "Specify the users, groups or roles that can use your credentials to run activities:",
  9983. "preferencesCapabilitiesHintText": "These capabilities are available to you:",
  9984. "preferencesGroupsAndRolesHintText": "In this session, you can use the access permissions of these groups and roles:",
  9985. "preferencesDataSourceCredentialsHintText": "You have saved credentials for these data servers:",
  9986. "enableAccessibilitySupport": "Enable accessibility support",
  9987. "languages": "Languages",
  9988. "True": "True",
  9989. "False": "False",
  9990. "id": "ID",
  9991. "run": "Run",
  9992. "createVersion": "Create a version",
  9993. "create": "Create",
  9994. "size": "Size",
  9995. "sizeByte": "%{value} B",
  9996. "sizeKiloByte": "%{value} KB",
  9997. "sizeMegaByte": "%{value} MB",
  9998. "sizeGigaByte": "%{value} GB",
  9999. "sizeTeraByte": "%{value} TB",
  10000. "sizePetaByte": "%{value} PB",
  10001. "refreshedDatetime": "Refreshed time",
  10002. "dataRefreshed": "Data refreshed",
  10003. "dataRefWithColon": "Data refreshed:",
  10004. "missingPermissions": "You need permissions to view the properties for this item.",
  10005. "missingPolicies": "You only see entries that you have permissions for. You might see different entries if you sign in to a different namespace",
  10006. "versions": "Versions",
  10007. "archives": "Archives",
  10008. "occurrences": "Occurrences",
  10009. "days": "Day(s)",
  10010. "months": "Month(s)",
  10011. "errorMessages": "Messages",
  10012. "errorMessageApostropheError": "Please enter a file name that does not contain both ' and \" characters",
  10013. "error": "Error",
  10014. "warn": "Warning",
  10015. "fatal": "Fatal",
  10016. "debug": "Debug",
  10017. "info": "Information",
  10018. "runTime": "Run time",
  10019. "requestTime": "Request time",
  10020. "startTime": "Start time",
  10021. "endTime": "End time",
  10022. "successful": "Successful",
  10023. "failed": "Failed",
  10024. "noSavedOutputs": "There are no saved outputs.",
  10025. "noVersions": "No versions available",
  10026. "noReportOptionsAvailable": "No report options record available.",
  10027. "showDetails": "Open details panel",
  10028. "unavailable": "Unavailable",
  10029. "runInBackgroundOption": "Run in background",
  10030. "selectAFormat": "Please select a format",
  10031. "delivery": "Delivery",
  10032. "now": "Now",
  10033. "later": "Later",
  10034. "invalidTime": "Time selected is earlier than current time. Please select again.",
  10035. "executionPrompt": "Prompt for values",
  10036. "currentValues": "Current values",
  10037. "noPromptsValuesSet": "You currently have no prompt values set",
  10038. "setValues": "Set values",
  10039. "numOfPromptValues": "prompt values",
  10040. "selectionBasedFeatures": "Enable selection-based interactivity",
  10041. "allowNotifications": "Enable alerts about new versions",
  10042. "advancedOutput": "Enable enhanced user features in saved output versions",
  10043. "allowAnnotations": "Enable comments in saved output versions",
  10044. "clear": "Clear",
  10045. "sourceReport": "Source report",
  10046. "sourceAgent": "Source agent",
  10047. "burst": "Burst the report",
  10048. "associatedSource": "Source package or data module",
  10049. "associatedSourceAgent": "Source package",
  10050. "linkPackageOrModule": "Link the %{itemName} to a package or data module",
  10051. "linkPackage": "Link the %{itemName} to a package",
  10052. "confirmTakeOwnership": "Confirm Take Ownership",
  10053. "confirmTakeOwnershipMessage": "Are you sure you want to take ownership of the selected entries?",
  10054. "SetLabel": "Set...",
  10055. "externalRepositories": "External Repositories",
  10056. "toastTakeOwnership": "You own %{noOfItemsClaimed} of %{noOfItems} selected items.",
  10057. "runAsUser": "With user's credentials",
  10058. "runWithOwnerCapabilities": "With owner capabilities",
  10059. "runAsOwner": "As %{ownerName}",
  10060. "pdfOptions": "PDF options",
  10061. "set": "Set",
  10062. "passwordNotMatched": "Passwords don't match or are missing",
  10063. "Orientation": "Orientation",
  10064. "default": "Default",
  10065. "portrait": "Portrait",
  10066. "landscape": "Landscape",
  10067. "pageSize": "Paper size",
  10068. "letter": "Letter",
  10069. "legal": "Legal",
  10070. "11x17": "11x17",
  10071. "A3": "A3",
  10072. "A4": "A4",
  10073. "B4JIS": "B4 JIS",
  10074. "B5JIS": "B5 JIS",
  10075. "requiresPasswordToOpenReport": "Requires a password to open the report",
  10076. "requiresPasswordToAccessOptions": "Requires a password to access options",
  10077. "password": "Password:",
  10078. "confirmPassword": "Confirm Password:",
  10079. "runHistory": "Run History",
  10080. "viewRunHistory": "View...",
  10081. "runHistoryDetails": "View run history details",
  10082. "jobAdvancedProperties": "Properties",
  10083. "scheduleAJob": "Schedule Job",
  10084. "viewCurrentVersions": "View document versions",
  10085. "viewArchivedVersions": "View archived versions",
  10086. "unknownUpdateError": "Item update failed. Contact your administrator for further assistance.",
  10087. "renameCollisionError": "%{name} already exists. Try a different name.",
  10088. "nameCollision": "An item with this name already exists:",
  10089. "nameCollisionMessage": "What do you want to do?",
  10090. "copyReplace": "Copy and replace",
  10091. "keepBoth": "Keep both",
  10092. "copySkip": "Don't copy",
  10093. "moveReplace": "Move and replace",
  10094. "moveSkip": "Don't move",
  10095. "repeatNameCollisionAction": "Do this for the next %{noItems} conflicts",
  10096. "repeatNameCollisionActionSingular": "Do this for the next conflict",
  10097. "bulkNameCollision": "There are %{noOfItems} items with names that already exist",
  10098. "overwrite": "Overwrite",
  10099. "rename": "Rename",
  10100. "role": "Role",
  10101. "account": "Account",
  10102. "group": "Group",
  10103. "namespace": "Namespace",
  10104. "SetLanguagesLabel": "Set...",
  10105. "SetExternalRespostoryLabel": "Set...",
  10106. "SetCapabilitiesLabel": "Set...",
  10107. "JobAdvancedSettings": "Set...",
  10108. "JobSchedule": "Set...",
  10109. "JobAdvancedRunHistory": "View...",
  10110. "packageConfiguration": "Package configuration",
  10111. "editPackageConfiguration": "Edit...",
  10112. "invalidNumber": "The value entered is not a number. Type a number.",
  10113. "exceedMaxLength": "The text is too long. Shorten to %{maxLength} characters.",
  10114. "invalidInput": "Invalid input",
  10115. "invalidEmailMessage": "Email address is not valid.",
  10116. "typeInHintText": "Example: Namespace1/name; Namespace2/name;",
  10117. "importDeployment": "Import deployment",
  10118. "exportDeployment": "Export deployment",
  10119. "between": "Between",
  10120. "and": "and",
  10121. "properties": "Properties - %{objectName}",
  10122. "none": "None",
  10123. "objectDeleted": "This object doesn't exist",
  10124. "PageLayout": "Page Layout",
  10125. "PageStyle": "Style",
  10126. "Gateway": "Gateway",
  10127. "PowerPlayReport": "PowerPlay Report",
  10128. "more": "More",
  10129. "title": "Title",
  10130. "itemName": "Item name",
  10131. "showMissingPolicies": "show",
  10132. "hideMissingPolicies": "hide",
  10133. "nowOrLaterRadioOptions": "Run now or later options",
  10134. "runHistoryUnits": "Run history units",
  10135. "reportOutputVersionsUnits": "Report output versions units",
  10136. "breadCrumbsAccessibleLabel": "Ancestor Folders",
  10137. "a11yContentListUpdatedNotification": "Now showing contents of %{folderOrPackageName}",
  10138. "a11yPropertyPane": "Properties of object %{nameOfObject}",
  10139. "moreActionsMenu": "More Actions Menu",
  10140. "itemType": "Item type",
  10141. "confirmCancelMessage": "Do you want to discard your changes?",
  10142. "confirmCancel": "Confirm cancel",
  10143. "formatOptions": "Format options",
  10144. "listControlColumns": "List Columns",
  10145. "source": "Source",
  10146. "external": "External",
  10147. "removeSelectedItem": "Remove selected item",
  10148. "deleteReportVersion": "Delete report version",
  10149. "dataset": "Data set",
  10150. "numberRows": "Number of rows",
  10151. "numberColumns": "Number of columns",
  10152. "TimeToRefresh": "Time to refresh",
  10153. "LastRefreshedBy": "Refreshed by",
  10154. "OverwriteFileSuccessfully": "Successfully overwrote the object %{nameOfObject}",
  10155. "RenameFileSuccessfully": "Successfully renamed the object from %{originalNameOfObject} to %{newNameOfObject}",
  10156. "showAllHistory": "Show all history",
  10157. "history": "History",
  10158. "user": "User",
  10159. "confirmDeleteAllowed": "You do not have permission to delete: %{number} item(s). Would you like to proceed and delete the rest?",
  10160. "download": "Download",
  10161. "personal": "Personal",
  10162. "customization": "Customization",
  10163. "schemas": "Schemas",
  10164. "connections": "Connections",
  10165. "numberOutOfRange": "The value entered must be a number between %{min} and %{max}",
  10166. "numberTooSmall": "The value entered must be a number greater than %{min}",
  10167. "numberTooBig": "The value entered must be a number less than %{max}",
  10168. "searchReturnedNoResults": "Your search returned no results.",
  10169. "tryChangingSearchTerms": "Try changing your search terms.",
  10170. "searchAllYourData": "Search all your data",
  10171. "search": "Search",
  10172. "saveSearch": "Save search",
  10173. "narrowYourSearch": "Narrow your search",
  10174. "all": "All",
  10175. "packages": "Packages",
  10176. "savedSearch": "Saved searches",
  10177. "haventSavedSearches": "You haven't saved any searches.",
  10178. "clickTheSaveButton": "You can click the save button after you search.",
  10179. "remove": "Remove",
  10180. "searchWasDeleted": "Search was deleted",
  10181. "searchWasntDeleted": "Search wasn't deleted",
  10182. "searchWasSaved": "Search was saved",
  10183. "searchWasntSaved": "Search wasn't saved",
  10184. "socialInsightsProject": "Social Insights",
  10185. "saveTenSearches": "You can save 10 searches.",
  10186. "deleteASearch": "Delete one to save another.",
  10187. "models": "Models",
  10188. "today": "Today",
  10189. "yesterday": "Yesterday",
  10190. "date": "Date",
  10191. "clearAll": "Clear all",
  10192. "EnterSearchTerms": "Enter a search term before you select a filter type.",
  10193. "pastWeek": "Past Week",
  10194. "pastMonth": "Past Month",
  10195. "createShortcut": "Create shortcut",
  10196. "createShortcutDialogTitle": "Create shortcut:",
  10197. "shortcutTo": "Shortcut to",
  10198. "shortcutToItem": "Shortcut to %{itemName}",
  10199. "add": "Add",
  10200. "close": "Close",
  10201. "confirmClearTenant": "Confirm clear tenant",
  10202. "confirmClearTenantText": "Clearing the tenant will change the value to \"None\" and might allow other tenants to access the content.<br><br>Click OK to make the entry public or Cancel to keep the current tenant",
  10203. "changeTenantWarning": "Changing the tenant of an entry also changes the tenant of child entries.",
  10204. "dataSource": "Data Server",
  10205. "dataSourceConnection": "Data Server Connection",
  10206. "setSourceLocation": "Set Source %{itemName} Location",
  10207. "defaultPortalAction": "Default Portal Action",
  10208. "openReport": "Edit",
  10209. "openAnalysis": "Open with Analysis Studio",
  10210. "openQuery": "Open with Query Studio",
  10211. "openPowerPlay8Report": "Open with PowerPlay Studio",
  10212. "openInteractiveReport": "Edit",
  10213. "searchPath": "Search path",
  10214. "itemsOverLimit": "The specified name '%{itemName}' has exceeded the maximum (20) limit. Please specify a different name to continue.",
  10215. "newURLLabel": "Create URL",
  10216. "newURLDesc": "Specify a name and URL. Optionally, specify a description.",
  10217. "urlNamePlaceholder": "Add a name for the URL",
  10218. "descriptionPlaceholder": "Add a description",
  10219. "urlPlaceholder": "Add a URL that uses an acceptable domain",
  10220. "viewAcceptableDomains": "View acceptable domains",
  10221. "acceptableDomains": "Acceptable domains",
  10222. "noEntries": "There are no entries in the acceptable domains list. Contact your administrator.",
  10223. "fieldsAreMandatory": "The name and URL are mandatory.",
  10224. "errorMessageLengthURLName": "Please enter a URL name that does not exceed 255 characters.",
  10225. "unacceptableDomain": "Your URL uses an invalid domain. Click 'View acceptable domains' to see a list of domains you can use.",
  10226. "toastCreateNewURL": "%{nameofURL} was created.",
  10227. "myPortalPages": "My portal pages",
  10228. "classicView": "Classic view",
  10229. "showUnavailablePolicies": "Show unavailable policies",
  10230. "agentViewOf": "Agent view of %{agentName}"
  10231. });
  10232. /*
  10233. *+------------------------------------------------------------------------+
  10234. *| Licensed Materials - Property of IBM
  10235. *| IBM Cognos Products: Content Explorer
  10236. *| (C) Copyright IBM Corp. 2015, 2018
  10237. *|
  10238. *| US Government Users Restricted Rights - Use, duplication or disclosure
  10239. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  10240. *+------------------------------------------------------------------------+
  10241. */
  10242. define('bi/content_apps/nls/StringResource',['i18n!bi/content_apps/nls/ContentExplorerResources', 'polyglot'], function (localeResources, Polyglot) {
  10243. 'use strict';
  10244. /**
  10245. * Module which provides simple access to string resources.
  10246. *
  10247. */
  10248. var poly = new Polyglot({
  10249. phrases: localeResources
  10250. });
  10251. var StringResources = function () {
  10252. return undefined;
  10253. };
  10254. /**
  10255. * Get the string resource for the given key and interpolation options
  10256. *
  10257. * @param key The key of the string to return
  10258. * @param interpolationOptions Optional interpolation options (see poly.t documentation for details)
  10259. * @returns The string to display
  10260. */
  10261. StringResources.prototype.get = function (key, interpolationOptions) {
  10262. return poly.t(key, interpolationOptions);
  10263. };
  10264. return new StringResources();
  10265. });
  10266. /*
  10267. *+------------------------------------------------------------------------+
  10268. *| Licensed Materials - Property of IBM
  10269. *|
  10270. *| IBM Cognos Products: content-apps
  10271. *|
  10272. *| (C) Copyright IBM Corp. 2015, 2018
  10273. *|
  10274. *| US Government Users Restricted Rights - Use, duplication or disclosure
  10275. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  10276. *+------------------------------------------------------------------------+
  10277. */
  10278. define('bi/content_apps/utils/C10Utils',[
  10279. 'underscore'
  10280. ], function(_) {
  10281. 'use strict';
  10282. var _singletonInstance = null;
  10283. var C10Utils = function() {
  10284. if (C10Utils.prototype._singletonInstance) {
  10285. return C10Utils.prototype._singletonInstance;
  10286. }
  10287. this.typeToStudioMap = {
  10288. 'analysis': 'AnalysisStudio',
  10289. 'query': 'QueryStudio',
  10290. 'agentDefinition': 'EventStudio',
  10291. 'package': 'MetricsStudio',
  10292. 'powerPlay8Report': 'PowerplayStudio'
  10293. };
  10294. this.typeToCapabilityMap = {
  10295. 'analysis': 'canUseAnalysisStudio',
  10296. 'query': 'canUseQueryStudio',
  10297. 'agentDefinition': 'canUseEventStudio'
  10298. };
  10299. this.propGeneralTitanActionEnum = {
  10300. 'lang': 'languages',
  10301. 'repo': 'repository',
  10302. 'routing': 'routing',
  10303. 'url': 'url',
  10304. 'pp': 'powerplay',
  10305. 'document': 'document'
  10306. };
  10307. this.morphletMap = {
  10308. 'propGeneral': 'portal/properties_general_titan.xts',
  10309. 'pageLayout': 'portal/properties_pagelet_layout_titan.xts',
  10310. 'pageStyle': 'portal/properties_pagelet_style_titan.xts',
  10311. 'capabilities': 'portal/properties_capabilities_titan.xts',
  10312. 'archive': 'portal/outputs_titan.xts',
  10313. 'runOptsPP8': 'portal/properties_powerplay_8_run_options.xts',
  10314. 'propPP8': 'portal/properties_powerplay_8_run_options_titan.xts',
  10315. 'proppowerplay': 'portal/properties_powerplay_run_options_titan.xts',
  10316. 'agent': 'portal/properties_agent_titan.xts',
  10317. 'metricsExport': 'portal/properties_metrics_export_titan.xts',
  10318. 'metricsImport': 'portal/properties_metrics_import _titan.xts',
  10319. 'metricsMainTask': 'portal/properties_metrics_maintenance_titan.xts',
  10320. 'launch': 'portal/launch.xts',
  10321. 'package': 'portal/properties_packageconfiguration.xts',
  10322. 'newPackage': 'portal/new_packageconfiguration.xts',
  10323. 'viewHistory': 'portal/history/view_details.xts'
  10324. };
  10325. // extracted for testing purposes
  10326. this.openWindow = function(url) {
  10327. window.open(url, '_blank');
  10328. };
  10329. C10Utils.prototype._singletonInstance = this;
  10330. };
  10331. C10Utils.prototype.openC10Morphlet = function(morphlet, oClass, id, additionalParams) {
  10332. var params = [{
  10333. 'm_class': oClass
  10334. }, {
  10335. 'm_obj': 'storeID("' + id + '")'
  10336. }];
  10337. if (additionalParams) {
  10338. params = params.concat(additionalParams);
  10339. }
  10340. this.openC10Tab(morphlet, params);
  10341. };
  10342. C10Utils.prototype.openC10MorphletWithParams = function(morphlet, params) {
  10343. this.openC10Tab(morphlet, params || []);
  10344. };
  10345. C10Utils.prototype.openC10General = function(action, oClass, id) {
  10346. this.openC10Morphlet(this.morphletMap.propGeneral, oClass, id, [{
  10347. 'titanAction': action
  10348. }]);
  10349. };
  10350. C10Utils.prototype.getC10DeliveryOptArray = function(label, opts) {
  10351. var smtpItems = '';
  10352. var ldapItems = '';
  10353. var smtpCount = 0;
  10354. var ldapCount = 0;
  10355. opts.forEach(function(anOpt) {
  10356. if (anOpt.address.indexOf('@') !== -1) {
  10357. smtpItems += '<item xsi:type="bus:addressSMTP">' + anOpt.address + '</item>';
  10358. smtpCount++;
  10359. } else {
  10360. ldapItems += '<item xsi:type="bus:searchPathMultipleObject">' + anOpt.address + '</item>';
  10361. ldapCount++;
  10362. }
  10363. });
  10364. var result = '';
  10365. if (smtpCount > 0) {
  10366. var smtpResult = '<item xsi:type="bus:deliveryOptionAddressSMTPArray"><name xsi:type="bus:deliveryOptionEnum">' + label + 'Address</name><value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:addressSMTP[##CA_NUM_ITEMS##]">##CA_ITEMS##</value></item>';
  10367. smtpResult = smtpResult.replace('##CA_ITEMS##', smtpItems);
  10368. smtpResult = smtpResult.replace('##CA_NUM_ITEMS##', smtpCount);
  10369. result += smtpResult;
  10370. }
  10371. if (ldapCount > 0) {
  10372. var ldapResult = '<item xsi:type="bus:deliveryOptionSearchPathMultipleObjectArray"><name xsi:type="bus:deliveryOptionEnum">' + label + '</name><value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:searchPathMultipleObject[##CA_NUM_ITEMS##]">##CA_ITEMS##</value></item>';
  10373. ldapResult = ldapResult.replace('##CA_ITEMS##', ldapItems);
  10374. ldapResult = ldapResult.replace('##CA_NUM_ITEMS##', ldapCount);
  10375. result += ldapResult;
  10376. }
  10377. return result;
  10378. };
  10379. C10Utils.prototype.getPowerPlayC10DeliveryOptions = function(deliveryOptions) {
  10380. var c10DeliveryOptions = '<options xmlns:cm="http://developer.cognos.com/schemas/xts-cm/1/" xmlns:send="http://developer.cognos.com/schemas/xts/logic-sheet/xslt/brl/1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="bus:optionArrayProp"><value xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:option[##CA_NUMBER_OPTIONITEMS##]">##CA_ITEMS##</value></options>';
  10381. var items = '';
  10382. var itemCount = 0;
  10383. if ((deliveryOptions.to) && (deliveryOptions.to.length > 0)) {
  10384. items += this.getC10DeliveryOptArray('to', deliveryOptions.to);
  10385. itemCount++;
  10386. }
  10387. if ((deliveryOptions.cc) && (deliveryOptions.cc.length > 0)) {
  10388. items += this.getC10DeliveryOptArray('cc', deliveryOptions.cc);
  10389. itemCount++;
  10390. }
  10391. if ((deliveryOptions.bcc) && (deliveryOptions.bcc.length > 0)) {
  10392. items += this.getC10DeliveryOptArray('bcc', deliveryOptions.bcc);
  10393. itemCount++;
  10394. }
  10395. if (deliveryOptions.subject) {
  10396. items += '<item xsi:type="bus:deliveryOptionString"><name xsi:type="bus:deliveryOptionEnum">subject</name><value xsi:type="xsd:string">' + deliveryOptions.subject + '</value></item>';
  10397. itemCount++;
  10398. }
  10399. var emailAsAttachment = deliveryOptions.emailAsAttachment === true;
  10400. items += '<item xsi:type="bus:powerPlay8OptionBoolean"><name xsi:type="bus:powerPlay8OptionEnum">emailAsAttachment</name><value xsi:type="xsd:boolean">' + emailAsAttachment + '</value></item>';
  10401. itemCount++;
  10402. var emailAsURL = deliveryOptions.emailAsURL === true;
  10403. items += '<item xsi:type="bus:powerPlay8OptionBoolean"><name xsi:type="bus:powerPlay8OptionEnum">emailAsURL</name><value xsi:type="xsd:boolean">' + emailAsURL + '</value></item>';
  10404. itemCount++;
  10405. if (deliveryOptions.memoPart) {
  10406. // var memoText = _.escape(deliveryOptions.memoPart);
  10407. // memoText = memoText.replace(/&amp;nbsp;/g, ' ');
  10408. var encodedMemoText = window.btoa(_.unescape(deliveryOptions.memoPart));
  10409. itemCount++;
  10410. items += '<item xsi:type="bus:deliveryOptionMemoPart"><name xsi:type="bus:deliveryOptionEnum">memoPart</name><value xsi:type="bus:memoPartComposite"><contentDisposition xsi:type="bus:smtpContentDispositionEnum">inline</contentDisposition><contentType xsi:type="bus:smtpContentTypeEnum">alternative</contentType><parts xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:memoPart[2]"><item xsi:type="bus:memoPartString"><contentDisposition xsi:type="bus:smtpContentDispositionEnum">inline</contentDisposition><text xsi:type="xsd:string">' + 'fred' + '</text></item><item xsi:type="bus:memoPartMIMEAttachment"><contentDisposition xsi:type="bus:smtpContentDispositionEnum">inline</contentDisposition><name xsi:type="xsd:string"/><data xsi:type="xsd:base64Binary">' + encodedMemoText + '</data><dataSize xsi:type="xsd:integer">0</dataSize><dataType xsi:type="xsd:string">text/html</dataType></item></parts></value></item>';
  10411. }
  10412. c10DeliveryOptions = c10DeliveryOptions.replace('##CA_ITEMS##', items);
  10413. return c10DeliveryOptions.replace('##CA_NUMBER_OPTIONITEMS##', itemCount);
  10414. };
  10415. C10Utils.prototype.openC10Studio = function(objectInfo, glassContext, isDesignMode) {
  10416. var studio = this.typeToStudioMap[objectInfo.type];
  10417. var urlParms = [{
  10418. 'ui.tool': studio
  10419. }, {
  10420. 'ui.object': 'storeID("' + objectInfo.id + '")'
  10421. }, {
  10422. 'ui.action': 'edit'
  10423. }, {
  10424. 'ui.gateway': glassContext.gateway + '/v1/disp'
  10425. }, {
  10426. 'launch.launchinWindow': 'true'
  10427. }];
  10428. if (isDesignMode) {
  10429. urlParms.push({
  10430. 'ui.crngnd': 'true'
  10431. });
  10432. }
  10433. if (studio === 'MetricsStudio') {
  10434. urlParms['ui.action'] = 'run';
  10435. }
  10436. this.openC10Tab(this.morphletMap.launch, urlParms);
  10437. };
  10438. C10Utils.prototype.isPowerPlay = function(objectType) {
  10439. return (objectType === 'powerPlay8Report' || objectType === 'powerPlay8ReportView');
  10440. };
  10441. C10Utils.prototype.openC10Tab = function(morphlet, urlParams) {
  10442. var c10Parameters = [{
  10443. 'b_action': 'xts.run'
  10444. }, {
  10445. 'backURL': encodeURIComponent('disp?b_action=xts.run&m=portal/close.xts&ui.compid=ps')
  10446. }, {
  10447. 'm': morphlet
  10448. }];
  10449. c10Parameters = c10Parameters.concat(urlParams);
  10450. var url = 'v1/disp';
  10451. var count = 0;
  10452. c10Parameters.forEach(function(item) {
  10453. if (count === 0) {
  10454. url += '?';
  10455. } else {
  10456. url += '&';
  10457. }
  10458. $.each(item, function(key, value) {
  10459. url += key + '=' + value;
  10460. });
  10461. count += 1;
  10462. });
  10463. this.openWindow(url);
  10464. };
  10465. var _static = {
  10466. getInstance: function() {
  10467. if (!_singletonInstance) {
  10468. _singletonInstance = new C10Utils();
  10469. }
  10470. return _singletonInstance;
  10471. }
  10472. };
  10473. return _static.getInstance();
  10474. });
  10475. /*
  10476. *+------------------------------------------------------------------------+
  10477. *| Licensed Materials - Property of IBM
  10478. *| IBM Cognos Products: Content Explorer
  10479. *| (C) Copyright IBM Corp. 2015, 2018
  10480. *|
  10481. *| US Government Users Restricted Rights - Use, duplication or disclosure
  10482. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  10483. *+------------------------------------------------------------------------+
  10484. */
  10485. define('bacontentnav/utils/PolicyHelper',[
  10486. '../nls/StringResource',
  10487. '../lib/@waca/core-client/js/core-client/i18n/Formatter',
  10488. 'underscore'
  10489. ], function(StringResource, Formatter, _) {
  10490. 'use strict';
  10491. var _singletonInstance = null;
  10492. var PolicyHelper = function() {
  10493. if (PolicyHelper.prototype._singletonInstance) {
  10494. return PolicyHelper.prototype._singletonInstance;
  10495. }
  10496. PolicyHelper.prototype._singletonInstance = this;
  10497. PolicyHelper.prototype.permissionEnum = {
  10498. 'r': 'read',
  10499. 'w': 'write',
  10500. 'x': 'execute',
  10501. 'sp': 'setPolicy',
  10502. 't': 'traverse'
  10503. };
  10504. PolicyHelper.prototype.read = [this.permissionEnum.r, this.permissionEnum.t];
  10505. PolicyHelper.prototype.run = [this.permissionEnum.r, this.permissionEnum.t, this.permissionEnum.x];
  10506. PolicyHelper.prototype.write = [this.permissionEnum.r, this.permissionEnum.t, this.permissionEnum.w, this.permissionEnum.x];
  10507. PolicyHelper.prototype.full = [this.permissionEnum.r, this.permissionEnum.t, this.permissionEnum.w, this.permissionEnum.x, this.permissionEnum.sp];
  10508. PolicyHelper.prototype.clonePermissionArray = function(permArray) {
  10509. var newPerm = [];
  10510. permArray.forEach(function(perm) {
  10511. newPerm.push(_.clone(perm));
  10512. });
  10513. return newPerm;
  10514. };
  10515. PolicyHelper.prototype.simplePermEnum = {
  10516. 'read': [{
  10517. 'access': 'grant',
  10518. 'name': this.permissionEnum.r
  10519. }, {
  10520. 'access': 'grant',
  10521. 'name': this.permissionEnum.t
  10522. }],
  10523. 'run': [{
  10524. 'access': 'grant',
  10525. 'name': this.permissionEnum.r
  10526. }, {
  10527. 'access': 'grant',
  10528. 'name': this.permissionEnum.t
  10529. }, {
  10530. 'access': 'grant',
  10531. 'name': this.permissionEnum.x
  10532. }],
  10533. 'write': [{
  10534. 'access': 'grant',
  10535. 'name': this.permissionEnum.r
  10536. }, {
  10537. 'access': 'grant',
  10538. 'name': this.permissionEnum.t
  10539. }, {
  10540. 'access': 'grant',
  10541. 'name': this.permissionEnum.x
  10542. }, {
  10543. 'access': 'grant',
  10544. 'name': this.permissionEnum.w
  10545. }],
  10546. 'full': [{
  10547. 'access': 'grant',
  10548. 'name': this.permissionEnum.r
  10549. }, {
  10550. 'access': 'grant',
  10551. 'name': this.permissionEnum.t
  10552. }, {
  10553. 'access': 'grant',
  10554. 'name': this.permissionEnum.x
  10555. }, {
  10556. 'access': 'grant',
  10557. 'name': this.permissionEnum.w
  10558. }, {
  10559. 'access': 'grant',
  10560. 'name': this.permissionEnum.sp
  10561. }]
  10562. };
  10563. };
  10564. PolicyHelper.prototype.getDisplayPermissionsList = function(permissionsArray) {
  10565. return permissionsArray.map(function(perm){
  10566. return StringResource.get(perm);
  10567. });
  10568. };
  10569. PolicyHelper.prototype.getIconsForPermissionValues = function(permissionsArray) {
  10570. var answer = {};
  10571. ['read', 'write', 'execute', 'traverse', 'setPolicy'].forEach(function(perm) {
  10572. answer[perm] = {
  10573. 'icon': '#common-default_perm',
  10574. 'tooltip': StringResource.get('default'),
  10575. 'label': StringResource.get(perm)
  10576. };
  10577. });
  10578. permissionsArray.forEach(function(perm) {
  10579. if (perm.access === 'grant') {
  10580. answer[perm.name].icon = '#common-grant_perm';
  10581. answer[perm.name].tooltip = StringResource.get('grant');
  10582. } else {
  10583. answer[perm.name].icon = '#common-deny_perm';
  10584. answer[perm.name].tooltip = StringResource.get('deny');
  10585. }
  10586. });
  10587. return answer;
  10588. };
  10589. PolicyHelper.prototype._flattenPermission = function(permissions) {
  10590. var ret = {};
  10591. _.each(permissions, function(permission) {
  10592. if (permission.access !== 'default') {
  10593. ret[permission.name] = permission.access;
  10594. }
  10595. });
  10596. return ret;
  10597. };
  10598. PolicyHelper.prototype.getMySimplifiedPermissions = function(permissions) {
  10599. return this.getSimplifiedPermissions(permissions.map(function(name) {
  10600. return {
  10601. 'access': 'grant',
  10602. 'name': name
  10603. };
  10604. }));
  10605. };
  10606. PolicyHelper.prototype.getSimplifiedPermissions = function(permissionsArray) {
  10607. var permissionsObject = this._flattenPermission(permissionsArray);
  10608. for (var name in this.simplePermEnum) {
  10609. var permObject = this._flattenPermission(this.simplePermEnum[name]);
  10610. if (_.isEqual(permissionsObject, permObject)) {
  10611. return StringResource.get(name);
  10612. }
  10613. }
  10614. return StringResource.get('permissionCustom');
  10615. };
  10616. var _static = {
  10617. getInstance: function() {
  10618. if (!_singletonInstance) {
  10619. _singletonInstance = new PolicyHelper();
  10620. }
  10621. return _singletonInstance;
  10622. }
  10623. };
  10624. return _static.getInstance();
  10625. });
  10626. /*
  10627. *+------------------------------------------------------------------------+
  10628. *| Licensed Materials - Property of IBM
  10629. *|
  10630. *| IBM Cognos Products: content-apps
  10631. *|
  10632. *| (C) Copyright IBM Corp. 2015, 2022
  10633. *|
  10634. *| US Government Users Restricted Rights - Use, duplication or disclosure
  10635. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  10636. *+----
  10637. */
  10638. define('bi/content_apps/PropertiesGeneralTab',[
  10639. 'underscore',
  10640. 'bi/commons/ui/properties/PropertyTabView',
  10641. 'bi/commons/i18n/Formatter',
  10642. 'bi/commons/utils/DateTimeUtils',
  10643. 'bi/commons/utils/Utils',
  10644. 'bi/content_apps/utils/C10Utils',
  10645. 'bi/content_apps/nls/StringResource',
  10646. 'bacontentnav/utils/ContentStoreObject',
  10647. 'bacontentnav/utils/PolicyHelper',
  10648. 'bacontentnav/utils/GlassContextHelper',
  10649. 'bacontentnav/utils/UIHelper'
  10650. ], function(_, PropertyTabView, I18NFormatter, DateTimeUtils, Utils, C10Utils, StringResource, ContentStoreObject, PolicyHelper, GlassContextHelper, UIHelper) {
  10651. 'use strict'; //NOSONAR
  10652. var _numberLabels = ['sizeKiloByte', 'sizeMegaByte', 'sizeGigaByte', 'sizeTeraByte', 'sizePetaByte'];
  10653. var _baseProperties = ['base.defaultName', 'base.defaultDescription', 'base.ancestors', 'base.metadataModelPackage', 'base.module'];
  10654. var _baseReportProperties = ['metadataModelPackage.defaultName', 'metadataModelPackage.ancestors', 'owner.id', 'retentions', 'defaultPortalAction', 'runAsOwner', 'runWithOwnerCapabilities', 'options', 'executionPrompt', 'parameters', 'module.defaultName', 'module.ancestors', 'allowNotification'];
  10655. var _static = {
  10656. 'PROPERTIES_TO_QUERY': {
  10657. 'common': ['id', 'defaultName', 'owner.defaultName', 'ancestors', 'defaultDescription',
  10658. 'modificationTime', 'creationTime', 'contact', 'type', 'disabled', 'hidden', 'name.locale', 'permissions', 'tenantID', 'searchPath'
  10659. ],
  10660. 'metricsExportTask': ['retentions'],
  10661. 'report': _baseReportProperties,
  10662. 'query': _baseReportProperties,
  10663. 'jobDefinition': ['retentions'],
  10664. 'agentDefinition': ['retentions'],
  10665. 'planningTask': ['retentions'],
  10666. 'metricsFileImportTask': ['retentions'],
  10667. 'metricsDataSourceETLTask': ['retentions'],
  10668. 'metricsMaintenanceTask': ['retentions'],
  10669. 'reportView': _baseReportProperties.concat(_baseProperties),
  10670. 'powerPlay8ReportView': _baseReportProperties.concat(_baseProperties),
  10671. 'agentDefinitionView': _baseReportProperties.concat(_baseProperties),
  10672. 'package': ['repositoryRules', 'queryMode', 'routingHints'],
  10673. 'folder': ['repositoryRules'],
  10674. 'uploadedFile': ['history'],
  10675. 'dataSet2': ['metadataModelPackage', 'module'],
  10676. 'shortcut': ['target'],
  10677. 'agent': ['retentions']
  10678. }
  10679. };
  10680. var PropertiesGeneralTab = PropertyTabView.extend({
  10681. init: function(options) {
  10682. PropertiesGeneralTab.inherited('init', this, arguments);
  10683. _.extend(this, options);
  10684. },
  10685. render: function() {
  10686. this._id = _.uniqueId('prop_');
  10687. var descriptionMaxLength = Math.max(1024, this._getDescription().length);
  10688. return this._checkCanSetTenant().then(function(canSetTenant) {
  10689. this._canSetTenant = canSetTenant;
  10690. return this.renderPropertyUIControl({
  10691. 'el': this.$el,
  10692. 'glassContext': this.glassContext,
  10693. 'readOnly': !ContentStoreObject.hasPermissions(this.objectInfo, ['write']),
  10694. 'items': [{
  10695. 'name': 'defaultDescription',
  10696. 'label': StringResource.get('description'),
  10697. 'value': this._getDescription(),
  10698. 'type': 'TextArea',
  10699. 'editable': true,
  10700. 'multiline': true,
  10701. 'validator': {
  10702. 'maxLength': descriptionMaxLength
  10703. }
  10704. }, {
  10705. 'type': 'CollapsibleSection',
  10706. 'label': StringResource.get('advancedProperties'),
  10707. 'items': this._getAdvancedPropertyItems()
  10708. }]
  10709. });
  10710. }.bind(this));
  10711. },
  10712. _getLocation: function() {
  10713. return ContentStoreObject.getLocation(this.objectInfo);
  10714. },
  10715. _getSearchPath: function() {
  10716. return ContentStoreObject.getSearchPath(this.objectInfo);
  10717. },
  10718. _getShortcutTargetLocation: function() {
  10719. return ContentStoreObject.getLocation(this.objectInfo.target[0], true) || StringResource.get('unavailable');
  10720. },
  10721. _getDescription: function() {
  10722. return ContentStoreObject.getDescription(this.objectInfo) || '';
  10723. },
  10724. _getModificationTime: function() {
  10725. return ContentStoreObject.getModificationTime(this.objectInfo, true, 'medium');
  10726. },
  10727. _getDisableThisEntry: function() {
  10728. return this.objectInfo.disabled;
  10729. },
  10730. _getHideThisEntry: function() {
  10731. return this.objectInfo.hidden;
  10732. },
  10733. _getLanguage: function() {
  10734. return this.objectInfo.name ? this.objectInfo.name.locale : null;
  10735. },
  10736. _getScreenTip: function() {
  10737. return this.objectInfo.defaultScreenTip || '';
  10738. },
  10739. _getQueryMode: function() {
  10740. var optionsValue = this.objectInfo.options && this.objectInfo.options[0].value;
  10741. if (optionsValue) {
  10742. return optionsValue.indexOf('compatible') === -1 ? StringResource.get('queryModeDynamic') : StringResource.get('queryModeCompatible');
  10743. }
  10744. return null;
  10745. },
  10746. _getExternalRepository: function() {
  10747. return this.objectInfo.repositoryRules ? this.objectInfo.repositoryRules[0].dataSourceName : null;
  10748. },
  10749. _getSizeOfFile: function() {
  10750. var history = ContentStoreObject.getHistoryConfig(this.objectInfo);
  10751. return history ? this._abbreviateNumber(history.sizeOnDisk) : null;
  10752. },
  10753. _getDataSetSize: function() {
  10754. return (this.objectInfo.dataSetOutputInfo && this.objectInfo.dataSetOutputInfo.dataSize) ? this._abbreviateNumber(this.objectInfo.dataSetOutputInfo.dataSize) : null;
  10755. },
  10756. _setPowerPlayGateway: function() {
  10757. C10Utils.openC10General(C10Utils.propGeneralTitanActionEnum.pp, this.objectInfo.type, this.objectInfo.id);
  10758. },
  10759. _setPageLayoutProperty: function() {
  10760. C10Utils.openC10Morphlet(C10Utils.morphletMap.pageLayout, this.objectInfo.type, this.objectInfo.id);
  10761. },
  10762. _setPageStyleProperty: function() {
  10763. C10Utils.openC10Morphlet(C10Utils.morphletMap.pageStyle, this.objectInfo.type, this.objectInfo.id);
  10764. },
  10765. _setURLProperty: function() {
  10766. C10Utils.openC10General(C10Utils.propGeneralTitanActionEnum.url, this.objectInfo.type, this.objectInfo.id);
  10767. },
  10768. _setLanguageValues: function() {
  10769. C10Utils.openC10General(C10Utils.propGeneralTitanActionEnum.lang, this.objectInfo.type, this.objectInfo.id);
  10770. },
  10771. _setExternalRepository: function() {
  10772. C10Utils.openC10General(C10Utils.propGeneralTitanActionEnum.repo, this.objectInfo.type, this.objectInfo.id);
  10773. },
  10774. _editPackageConfiguration: function() {
  10775. // check if the package configuration exists under the package - in order to launch the new or edit UI
  10776. var requestOptions = {
  10777. dataType: 'json',
  10778. type: 'GET',
  10779. url: 'v1/objects/' + this.objectInfo.id + '/items?types=packageConfiguration'
  10780. };
  10781. this.glassContext.getCoreSvc('.Ajax').ajax(requestOptions)
  10782. .then(function(response) {
  10783. // set up common params
  10784. var objectSearchPath = 'storeID("' + this.objectInfo.id + '")';
  10785. var params = [
  10786. { m_name: this.objectInfo.defaultName },
  10787. { m_obj_search_path: objectSearchPath },
  10788. { m_path: '' }
  10789. ];
  10790. if (response && response.data && response.data.data && response.data.data.length) {
  10791. // note: assuming there is only 1 package configuration, so it's the first one
  10792. params = params.concat([
  10793. { m_class: 'packageConfiguration' },
  10794. { m_new_class: '' },
  10795. { m_obj: 'storeID("' + response.data.data[0].id + '")' }
  10796. ]);
  10797. C10Utils.openC10MorphletWithParams(C10Utils.morphletMap.package, params);
  10798. } else {
  10799. // if there are no package configurations, launch the new configuration editor
  10800. params = params.concat([
  10801. { m_class: 'package' },
  10802. { m_new_class: 'packageConfiguration' },
  10803. { m_obj: objectSearchPath }
  10804. ]);
  10805. C10Utils.openC10MorphletWithParams(C10Utils.morphletMap.newPackage, params);
  10806. }
  10807. }.bind(this));
  10808. },
  10809. _getRefreshTime: function() {
  10810. var history = ContentStoreObject.getHistoryConfig(this.objectInfo);
  10811. return history && DateTimeUtils.formatDateTime(history.refreshTime, 'short', GlassContextHelper.getLocaleTime(this.glassContext)) || null;
  10812. },
  10813. _abbreviateNumber: function(number, localeOverride) {
  10814. // default label and number value
  10815. var labelKey = 'sizeByte';
  10816. var labelValue = Math.round(number * 100) / 100;
  10817. // loop and reduce the number accordingly
  10818. for (var i = 0; i < _numberLabels.length; i = i + 1) {
  10819. // process the number if greater than 1024
  10820. if (Math.round(number * 10) / 10 >= 1024) {
  10821. // update the number... divide by 1024
  10822. number = number / 1024;
  10823. // update label and number value
  10824. labelKey = _numberLabels[i];
  10825. labelValue = Math.round(number * 10) / 10;
  10826. } else {
  10827. // done so exit
  10828. break;
  10829. }
  10830. }
  10831. return StringResource.get(labelKey, {
  10832. 'value': I18NFormatter.formatNumber(labelValue, {
  10833. type: 'decimal',
  10834. locale: localeOverride
  10835. })
  10836. });
  10837. },
  10838. _getSourceLocation: function() {
  10839. var base = ContentStoreObject.getBase(this.objectInfo);
  10840. return base && ContentStoreObject.getLocation(base, true) || StringResource.get('unavailable');
  10841. },
  10842. _getSourcePackageOrModuleLocation: function(objectInfo, appendDefaultName) {
  10843. var source = ContentStoreObject.getMetadataModelPackage(objectInfo) || ContentStoreObject.getModule(objectInfo);
  10844. return source && ContentStoreObject.getLocation(source, appendDefaultName) || StringResource.get('unavailable');
  10845. },
  10846. _buildTenantsList: function() {
  10847. var tenants = this.glassContext.getCoreSvc('.UserProfile').tenants;
  10848. var tenantsList = [{
  10849. label: '',
  10850. value: null,
  10851. selected: true
  10852. }];
  10853. for (var item in tenants) {
  10854. tenantsList.push({
  10855. label: tenants[item].defaultName,
  10856. value: tenants[item]
  10857. });
  10858. }
  10859. return tenantsList;
  10860. },
  10861. _getTenantNameByID: function(tenantID) {
  10862. if (tenantID === '') {
  10863. return StringResource.get('none');
  10864. }
  10865. var tenants = this.glassContext.getCoreSvc('.UserProfile').tenants;
  10866. for (var item in tenants) {
  10867. if (tenants[item].tenantID === tenantID) {
  10868. return tenants[item].defaultName;
  10869. }
  10870. }
  10871. return tenantID;
  10872. },
  10873. _checkCanSetTenant: function() {
  10874. return new Promise(function(resolve /*, reject*/ ) {
  10875. if (this._canSeeTenant()) {
  10876. this.glassContext.getCoreSvc('.UserProfile').isSysAdmin().then(function(isSysAdmin) {
  10877. resolve(isSysAdmin);
  10878. }.bind(this), function() {
  10879. resolve(false);
  10880. });
  10881. } else {
  10882. resolve(false);
  10883. }
  10884. }.bind(this));
  10885. },
  10886. _canSeeTenant: function() {
  10887. // can see tenant information if there are tenants AND (the item's first ancestor is the team content folder OR the object is related to tenants)
  10888. return (this.glassContext.getCoreSvc('.UserProfile').tenants || []).length &&
  10889. ((ContentStoreObject.isTeamContent(this.objectInfo.ancestors && this.objectInfo.ancestors.length > 0 && this.objectInfo.ancestors[0])) ||
  10890. (UIHelper.hasTenantOption(this.objectInfo)));
  10891. },
  10892. //this method could be optimized a bit...
  10893. _getAdvancedPropertyItems: function() {
  10894. var isRoot = ContentStoreObject.isTeamContent(this.objectInfo);
  10895. this._advancedProperties = [];
  10896. if (this._canSeeTenant()) {
  10897. this.currentTenantID = this.objectInfo.tenantID;
  10898. this._advancedProperties.push({
  10899. 'type': 'SingleLineValue',
  10900. 'name': 'changeTenant',
  10901. 'label': StringResource.get('tenant'),
  10902. 'value': this._getTenantNameByID(this.objectInfo.tenantID),
  10903. 'disabled': !this._canSetTenant,
  10904. 'editCallback': function() {
  10905. this.changeTenantSlideout = this.glassContext.appController.showSlideOut({
  10906. 'parent': this.slideout,
  10907. 'position': 'left',
  10908. 'width': '400',
  10909. 'overlay': true,
  10910. 'label': StringResource.get('tenantSettings'),
  10911. 'content': {
  10912. 'module': 'bi/content_apps/TenantSlideoutView',
  10913. 'glassContext': this.glassContext,
  10914. 'title': StringResource.get('Tenants'),
  10915. 'objectInfo': this.objectInfo,
  10916. 'currentTenantID': this.currentTenantID,
  10917. 'onChangeCallback': this.updateTenant.bind(this)
  10918. }
  10919. });
  10920. }.bind(this)
  10921. }, {
  10922. 'type': 'Separator'
  10923. });
  10924. }
  10925. this._advancedProperties.push({
  10926. 'name': 'disabled',
  10927. 'label': StringResource.get('disableThisEntry'),
  10928. 'checked': this._getDisableThisEntry(),
  10929. 'type': 'CheckBox'
  10930. });
  10931. if (!isRoot) {
  10932. var ups = this.glassContext.getCoreSvc('.UserProfile');
  10933. if (ups.capabilities && ups.capabilities.indexOf('canUseShowHiddenObjectsPreference') >= 0) {
  10934. $.merge(this._advancedProperties, [{
  10935. 'type': 'Separator'
  10936. }, {
  10937. 'name': 'hidden',
  10938. 'label': StringResource.get('hideThisEntry'),
  10939. 'checked': this._getHideThisEntry(),
  10940. 'type': 'CheckBox'
  10941. }]);
  10942. }
  10943. $.merge(this._advancedProperties, [{
  10944. 'type': 'Separator'
  10945. }, {
  10946. 'name': 'location',
  10947. 'label': StringResource.get('location'),
  10948. 'value': this._getLocation(),
  10949. 'type': 'SingleLineValue',
  10950. 'isSTT': true
  10951. }]);
  10952. $.merge(this._advancedProperties, [{
  10953. 'type': 'Separator'
  10954. }, {
  10955. 'name': 'searchPath',
  10956. 'label': StringResource.get('searchPath'),
  10957. 'newLook': true,
  10958. 'value': this._getSearchPath(),
  10959. 'type': 'InputLabel',
  10960. 'inputStyles': 'width: 210px',
  10961. 'readOnly': true,
  10962. 'isSTT': true
  10963. }]);
  10964. if (this.objectInfo.type === 'shortcut') {
  10965. $.merge(this._advancedProperties, [{
  10966. 'type': 'Separator'
  10967. }, {
  10968. 'name': 'shortcutTo',
  10969. 'label': StringResource.get('shortcutTo'),
  10970. 'value': this._getShortcutTargetLocation(),
  10971. 'type': 'SingleLineValue'
  10972. }]);
  10973. }
  10974. }
  10975. $.merge(this._advancedProperties, [{
  10976. 'type': 'Separator'
  10977. }, {
  10978. 'name': ContentStoreObject.ID,
  10979. 'label': StringResource.get('id'),
  10980. 'value': ContentStoreObject.getObjectId(this.objectInfo),
  10981. 'type': 'SingleLineValue'
  10982. }, {
  10983. 'type': 'Separator'
  10984. }, {
  10985. 'name': 'myPermissions',
  10986. 'type': 'SingleLineLinks',
  10987. 'items': [{
  10988. 'align': 'left',
  10989. 'items': [{
  10990. 'type': 'text',
  10991. 'value': StringResource.get('permissionHeader'),
  10992. 'name': 'permissionsLab'
  10993. }]
  10994. }, {
  10995. 'align': 'right',
  10996. 'items': [{
  10997. 'type': 'text',
  10998. 'value': PolicyHelper.getMySimplifiedPermissions(ContentStoreObject.getPermissions(this.objectInfo)),
  10999. 'name': 'PermissionValue'
  11000. }, {
  11001. 'type': 'icon',
  11002. 'class': 'permissionInformation displayToolTip',
  11003. 'svgIcon': 'common-info-moreinfo',
  11004. 'iconTooltip': PolicyHelper.getDisplayPermissionsList(ContentStoreObject.getPermissions(this.objectInfo))
  11005. }]
  11006. }]
  11007. }]);
  11008. if (!isRoot) {
  11009. $.merge(this._advancedProperties, [{
  11010. 'type': 'Separator'
  11011. }, {
  11012. 'name': 'languages',
  11013. 'type': 'SingleLineLinks',
  11014. 'items': [{
  11015. 'align': 'left',
  11016. 'items': [{
  11017. 'type': 'text',
  11018. 'name': 'languagesText',
  11019. 'value': StringResource.get('languages')
  11020. }]
  11021. }, {
  11022. 'align': 'right',
  11023. 'items': [{
  11024. 'type': 'text',
  11025. 'name': 'languagesLink',
  11026. 'value': StringResource.get('SetLanguagesLabel'),
  11027. 'clickCallback': this._setLanguageValues.bind(this),
  11028. 'ariaLabelledby': 'languagesText languagesLink'
  11029. }]
  11030. }]
  11031. }]);
  11032. }
  11033. switch (this.objectInfo.type) {
  11034. case 'powerPlayCube':
  11035. case 'powerPlayReport':
  11036. this._advancedProperties = this._advancedProperties.concat([{
  11037. 'type': 'Separator'
  11038. }, {
  11039. 'name': 'layoutProperty',
  11040. 'type': 'SingleLineLinks',
  11041. 'items': [{
  11042. 'align': 'left',
  11043. 'items': [{
  11044. 'type': 'text',
  11045. 'name': 'layoutPropertyText',
  11046. 'value': StringResource.get('Gateway')
  11047. }]
  11048. }, {
  11049. 'align': 'right',
  11050. 'items': [{
  11051. 'type': 'text',
  11052. 'name': 'layoutPropertyLink',
  11053. 'value': StringResource.get('SetExternalRespostoryLabel'),
  11054. 'clickCallback': this._setPowerPlayGateway.bind(this),
  11055. 'ariaLabelledby': 'layoutPropertyText layoutPropertyLink'
  11056. }]
  11057. }]
  11058. }]);
  11059. break;
  11060. case 'pagelet':
  11061. this._advancedProperties = this._advancedProperties.concat([{
  11062. 'type': 'Separator'
  11063. }, {
  11064. 'name': 'layoutProperty',
  11065. 'type': 'SingleLineLinks',
  11066. 'items': [{
  11067. 'align': 'left',
  11068. 'items': [{
  11069. 'type': 'text',
  11070. 'name': 'layoutPropertyText',
  11071. 'value': StringResource.get('PageLayout')
  11072. }]
  11073. }, {
  11074. 'align': 'right',
  11075. 'items': [{
  11076. 'type': 'text',
  11077. 'name': 'layoutPropertyLink',
  11078. 'value': StringResource.get('SetExternalRespostoryLabel'),
  11079. 'clickCallback': this._setPageLayoutProperty.bind(this),
  11080. 'ariaLabelledby': 'layoutPropertyText layoutPropertyLink'
  11081. }]
  11082. }]
  11083. }, {
  11084. 'type': 'Separator'
  11085. }, {
  11086. 'name': 'pageStyleProperty',
  11087. 'type': 'SingleLineLinks',
  11088. 'items': [{
  11089. 'align': 'left',
  11090. 'items': [{
  11091. 'type': 'text',
  11092. 'name': 'pageStylePropertyText',
  11093. 'value': StringResource.get('PageStyle')
  11094. }]
  11095. }, {
  11096. 'align': 'right',
  11097. 'items': [{
  11098. 'type': 'text',
  11099. 'name': 'pageStylePropertyLink',
  11100. 'value': StringResource.get('SetExternalRespostoryLabel'),
  11101. 'clickCallback': this._setPageStyleProperty.bind(this),
  11102. 'ariaLabelledby': 'pageStylePropertyText pageStylePropertyLink'
  11103. }]
  11104. }]
  11105. }]);
  11106. break;
  11107. case 'URL':
  11108. this._advancedProperties = this._advancedProperties.concat([{
  11109. 'type': 'Separator'
  11110. }, {
  11111. 'name': 'urlProperty',
  11112. 'type': 'SingleLineLinks',
  11113. 'items': [{
  11114. 'align': 'left',
  11115. 'items': [{
  11116. 'type': 'text',
  11117. 'name': 'urlPropertyText',
  11118. 'value': StringResource.get('URL')
  11119. }]
  11120. }, {
  11121. 'align': 'right',
  11122. 'items': [{
  11123. 'type': 'text',
  11124. 'name': 'urlPropertyLink',
  11125. 'value': StringResource.get('SetExternalRespostoryLabel'),
  11126. 'clickCallback': this._setURLProperty.bind(this),
  11127. 'ariaLabelledby': 'urlPropertyText urlPropertyLink'
  11128. }]
  11129. }]
  11130. }]);
  11131. break;
  11132. case 'folder':
  11133. case 'content':
  11134. this._advancedProperties = this._advancedProperties.concat([{
  11135. 'type': 'Separator'
  11136. }, {
  11137. 'name': 'expernalRepository',
  11138. 'type': 'SingleLineLinks',
  11139. 'items': [{
  11140. 'align': 'left',
  11141. 'items': [{
  11142. 'type': 'text',
  11143. 'name': 'expernalRepositoryText',
  11144. 'value': StringResource.get('externalRepositories')
  11145. }]
  11146. }, {
  11147. 'align': 'right',
  11148. 'items': [{
  11149. 'type': 'text',
  11150. 'name': 'expernalRepositoryLink',
  11151. 'value': StringResource.get('SetExternalRespostoryLabel'),
  11152. 'clickCallback': this._setExternalRepository.bind(this),
  11153. 'ariaLabelledby': 'expernalRepositoryText expernalRepositoryLink'
  11154. }]
  11155. }]
  11156. }]);
  11157. break;
  11158. case 'package':
  11159. this._advancedProperties = this._advancedProperties.concat([{
  11160. 'type': 'Separator'
  11161. }, {
  11162. 'name': 'queryMode',
  11163. 'label': StringResource.get('queryMode'),
  11164. 'value': this._getQueryMode(),
  11165. 'type': 'SingleLineValue'
  11166. }, {
  11167. 'type': 'Separator'
  11168. }, {
  11169. 'name': 'expernalRepository',
  11170. 'type': 'SingleLineLinks',
  11171. 'items': [{
  11172. 'align': 'left',
  11173. 'items': [{
  11174. 'type': 'text',
  11175. 'name': 'expernalRepositoryText',
  11176. 'value': StringResource.get('externalRepositories')
  11177. }]
  11178. }, {
  11179. 'align': 'right',
  11180. 'items': [{
  11181. 'type': 'text',
  11182. 'name': 'expernalRepositoryLink',
  11183. 'value': StringResource.get('SetExternalRespostoryLabel'),
  11184. 'clickCallback': this._setExternalRepository.bind(this),
  11185. 'ariaLabelledby': 'expernalRepositoryText expernalRepositoryLink'
  11186. }]
  11187. }]
  11188. }, {
  11189. 'type': 'Separator'
  11190. }, {
  11191. 'name': 'packageConfiguration',
  11192. 'type': 'SingleLineLinks',
  11193. 'items': [{
  11194. 'align': 'left',
  11195. 'items': [{
  11196. 'type': 'text',
  11197. 'name': 'editPackageConfiguration',
  11198. 'value': StringResource.get('packageConfiguration')
  11199. }]
  11200. }, {
  11201. 'align': 'right',
  11202. 'items': [{
  11203. 'type': 'text',
  11204. 'name': 'editPackageConfigurationLink',
  11205. 'value': StringResource.get('editPackageConfiguration'),
  11206. 'clickCallback': this._editPackageConfiguration.bind(this),
  11207. 'ariaLabelledby': 'editPackageConfiguration editPackageConfigurationLink'
  11208. }]
  11209. }]
  11210. }]);
  11211. break;
  11212. case 'uploadedFile':
  11213. this._advancedProperties = this._advancedProperties.concat([{
  11214. 'type': 'Separator'
  11215. }, {
  11216. 'name': 'size',
  11217. 'label': StringResource.get('size'),
  11218. 'value': this._getSizeOfFile(),
  11219. 'type': 'SingleLineValue'
  11220. }, {
  11221. 'type': 'Separator'
  11222. }, {
  11223. 'name': 'refreshedDatetime',
  11224. 'label': StringResource.get('refreshedDatetime'),
  11225. 'value': this._getRefreshTime(),
  11226. 'type': 'SingleLineValue'
  11227. }]);
  11228. break;
  11229. case 'powerPlay8Report':
  11230. case 'query':
  11231. case 'report':
  11232. case 'interactiveReport':
  11233. case 'agentDefinition':
  11234. this._advancedProperties = this._advancedProperties.concat([{
  11235. 'type': 'Separator'
  11236. }, {
  11237. 'name': 'setSourceData',
  11238. 'type': 'SingleLineLinks',
  11239. 'items': [{
  11240. 'align': 'left',
  11241. 'items': [{
  11242. 'type': 'text',
  11243. 'name': 'associatedSourceDataText',
  11244. 'value': this.objectInfo.type === 'agentDefinition'? StringResource.get('associatedSourceAgent') : StringResource.get('associatedSource')
  11245. }]
  11246. }, {
  11247. 'align': 'right',
  11248. 'items': [{
  11249. 'type': 'text',
  11250. 'name': 'setAssociatedSourceDataLink',
  11251. 'value': StringResource.get('SetLanguagesLabel'),
  11252. 'clickCallback': this._selectPackage.bind(this, this.objectInfo.type),
  11253. 'ariaLabelledby': 'associatedSourceDataText setAssociatedSourceDataLink'
  11254. }]
  11255. }]
  11256. }, {
  11257. 'name': 'sourceDataLocationName',
  11258. 'label': '',
  11259. 'value': this._getSourcePackageOrModuleLocation(this.objectInfo, true),
  11260. 'type': 'SingleLineValue'
  11261. }]);
  11262. break;
  11263. case 'powerPlay8ReportView':
  11264. case 'reportView':
  11265. case 'agentDefinitionView':
  11266. this._advancedProperties = this._advancedProperties.concat([{
  11267. 'type': 'Separator'
  11268. }, {
  11269. 'name': 'setSourceReport',
  11270. 'type': 'SingleLineLinks',
  11271. 'items': [{
  11272. 'align': 'left',
  11273. 'items': [{
  11274. 'type': 'text',
  11275. 'name': 'associatedSourceText',
  11276. 'value': this.objectInfo.type === 'agentDefinitionView'? StringResource.get('sourceAgent') : StringResource.get('sourceReport')
  11277. }]
  11278. }, {
  11279. 'align': 'right',
  11280. 'items': [{
  11281. 'type': 'text',
  11282. 'name': 'setAssociatedSourceLink',
  11283. 'value': StringResource.get('SetLanguagesLabel'),
  11284. 'clickCallback': this._selectSource.bind(this, this.objectInfo.type),
  11285. 'ariaLabelledby': 'associatedSourceText setAssociatedSourceLink'
  11286. }]
  11287. }]
  11288. }, {
  11289. 'name': 'sourceLocationName',
  11290. 'label': '',
  11291. 'value': this._getSourceLocation(),
  11292. 'type': 'SingleLineValue'
  11293. }]);
  11294. break;
  11295. case 'dataSet2':
  11296. var unknown = StringResource.get('unknown');
  11297. this._advancedProperties = this._advancedProperties.concat([{
  11298. 'type': 'Separator'
  11299. }, {
  11300. 'name': 'setSourceDataSet',
  11301. 'type': 'SingleLineLinks',
  11302. 'items': [{
  11303. 'align': 'left',
  11304. 'items': [{
  11305. 'type': 'text',
  11306. 'name': 'associatedSourceDataText',
  11307. 'value': StringResource.get('associatedSourceAgent')
  11308. }]
  11309. }, {
  11310. 'align': 'right',
  11311. 'items': [{
  11312. 'type': 'text',
  11313. 'name': 'setAssociatedSourceDataLink',
  11314. 'value': StringResource.get('SetLanguagesLabel'),
  11315. 'clickCallback': this._selectPackage.bind(this, this.objectInfo.type),
  11316. 'ariaLabelledby': 'associatedSourceDataText setAssociatedSourceDataLink'
  11317. }]
  11318. }]
  11319. }, {
  11320. 'name': 'sourceDataLocationName',
  11321. 'label': '',
  11322. 'value': this._getSourcePackageOrModuleLocation(this.objectInfo, true),
  11323. 'type': 'SingleLineValue'
  11324. }, {
  11325. 'type': 'Separator'
  11326. }, {
  11327. 'name': 'size',
  11328. 'label': StringResource.get('size'),
  11329. 'value': this._getDataSetSize() || unknown,
  11330. 'type': 'SingleLineValue'
  11331. }, {
  11332. 'type': 'Separator'
  11333. }, {
  11334. 'name': 'numRows',
  11335. 'label': StringResource.get('numberRows'),
  11336. 'value': ContentStoreObject.getDataDescriptor(this.objectInfo.dataSetOutputInfo).numRows || unknown,
  11337. 'type': 'SingleLineValue'
  11338. }, {
  11339. 'type': 'Separator'
  11340. }, {
  11341. 'name': 'numColumns',
  11342. 'label': StringResource.get('numberColumns'),
  11343. 'value': ContentStoreObject.getDataDescriptor(this.objectInfo.dataSetOutputInfo).numColumns || unknown,
  11344. 'type': 'SingleLineValue'
  11345. }, {
  11346. 'type': 'Separator'
  11347. }, {
  11348. 'name': 'timeToRefresh',
  11349. 'label': StringResource.get('TimeToRefresh'),
  11350. 'value': Utils.formatDuration(ContentStoreObject.getDataDescriptor(this.objectInfo.dataSetOutputInfo).elapsedTimeMilli),
  11351. 'type': 'SingleLineValue'
  11352. }, {
  11353. 'type': 'Separator'
  11354. }, {
  11355. 'name': 'refreshedBy',
  11356. 'label': StringResource.get('LastRefreshedBy'),
  11357. 'value': ContentStoreObject.getOwnerName(this.objectInfo.dataSetOutputInfo),
  11358. 'type': 'SingleLineValue'
  11359. }, {
  11360. 'type': 'Separator'
  11361. }]);
  11362. break;
  11363. }
  11364. return this._advancedProperties;
  11365. },
  11366. onClose: function() {
  11367. return this.getPropertyUIControl().onClose();
  11368. },
  11369. getModifiedProperties: function() {
  11370. if (!ContentStoreObject.hasPermissions(this.objectInfo, ['write'])) {
  11371. return null;
  11372. }
  11373. var modifiedProperties = this.getPropertyUIControl().getModifiedProperties();
  11374. if (this.modifiedBaseReport !== undefined) {
  11375. _.extend(modifiedProperties, {
  11376. 'base': [this.modifiedBaseReport]
  11377. });
  11378. } else if (this.modifiedBasePackage !== undefined) {
  11379. //TODO remove asset knowledge
  11380. if (this.modifiedBasePackage.type === 'module') {
  11381. _.extend(modifiedProperties, {
  11382. 'module': [this.modifiedBasePackage],
  11383. 'metadataModelPackage': null, // clear any existing metadata metadataModel or package
  11384. 'metadataModel': null
  11385. });
  11386. } else {
  11387. _.extend(modifiedProperties, {
  11388. 'metadataModelPackage': [this.modifiedBasePackage],
  11389. 'module': null, // clear any existing metadata metadataModel or module
  11390. 'metadataModel': null
  11391. });
  11392. }
  11393. }
  11394. this.logger.debug('PropertiesGeneralTab.getModifiedProperties', modifiedProperties);
  11395. return modifiedProperties;
  11396. },
  11397. updateTenant: function(tenantID) {
  11398. this._oPropertyUIControl.getProperty('changeTenant').setValue(this._getTenantNameByID(tenantID));
  11399. this.currentTenantID = tenantID;
  11400. },
  11401. _selectSource: function(parentType) {
  11402. ContentStoreObject.getBaseObjectType(this.objectInfo).then(function(baseType) {
  11403. require(['bacontentnav/ui/dialogs/OpenDialog'], function(OpenDialog) {
  11404. var objectType = ContentStoreObject.getType(this.objectInfo);
  11405. var type = baseType || UIHelper.getBaseTypes(objectType).join('|');
  11406. var dialog = new OpenDialog({
  11407. glassContext: this.glassContext,
  11408. 'typesToOpen': type.split('|'),
  11409. 'filtersByTypes': 'folder|package' + '|' + type,
  11410. multiSelect: false,
  11411. ancestors: ContentStoreObject.getAncestors(this.objectInfo),
  11412. onOpenCallback: function(selectedItems) {
  11413. this._setBase(selectedItems[0]);
  11414. }.bind(this)
  11415. });
  11416. dialog.title = StringResource.get('setSourceLocation', {
  11417. itemName: StringResource.get(parentType)
  11418. });
  11419. dialog.open();
  11420. }.bind(this));
  11421. }.bind(this));
  11422. },
  11423. _selectPackage: function(parentType) {
  11424. require(['bacontentnav/ui/dialogs/OpenDialog'], function(OpenDialog) {
  11425. var dialog = new OpenDialog({
  11426. glassContext: this.glassContext,
  11427. // Currently, agentDefinition does not support the linkage of 'data module' yet.
  11428. 'typesToOpen': parentType === 'agentDefinition'? ['package'] : ['package', 'module'],
  11429. 'filtersByTypes': 'folder|package|module',
  11430. multiSelect: false,
  11431. ancestors: ContentStoreObject.getAncestors(this.objectInfo),
  11432. capabilitiesRequired: parentType === 'report'? ['canUseReportStudio'] : undefined,
  11433. onOpenCallback: function(selectedItems) {
  11434. this._setBasePackage(selectedItems[0]);
  11435. }.bind(this)
  11436. });
  11437. dialog.title = parentType === 'agentDefinition'? StringResource.get('linkPackage', {
  11438. itemName: StringResource.get(this.objectInfo.type)
  11439. }) : StringResource.get('linkPackageOrModule', {
  11440. itemName: StringResource.get(this.objectInfo.type)
  11441. });
  11442. dialog.open();
  11443. }.bind(this));
  11444. },
  11445. _setBasePackage: function(base) {
  11446. this.modifiedBasePackage = {
  11447. 'searchPath': 'storeID("' + base.id + '")',
  11448. 'type': ContentStoreObject.getType(base)
  11449. };
  11450. this._oPropertyUIControl.getProperty('sourceDataLocationName').setValue(ContentStoreObject.getLocation(base, false));
  11451. },
  11452. _setBase: function(base) {
  11453. this.modifiedBaseReport = {
  11454. 'searchPath': 'storeID("' + base.id + '")',
  11455. 'type': ContentStoreObject.getType(base)
  11456. };
  11457. this._oPropertyUIControl.getProperty('sourceLocationName').setValue(ContentStoreObject.getLocation(base, true));
  11458. }
  11459. });
  11460. PropertiesGeneralTab.getPropertiesToQuery = function(type) {
  11461. return PropertiesGeneralTab.PROPERTIES_TO_QUERY.common.concat(PropertiesGeneralTab.PROPERTIES_TO_QUERY[type]).join(',');
  11462. };
  11463. _.extend(PropertiesGeneralTab, _static);
  11464. return PropertiesGeneralTab;
  11465. });
  11466. define('text!bi/content_apps/propertiespageview.json',[],function () { return '{\n\t"copyright": "Licensed Materials - Property of IBM. IBM Cognos Products: BI Cloud(C) Copyright IBM Corp.2014, 2022. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.",\n\t"tabs": {\n\t\t"jobDefinition": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "job",\n\t\t\t"module": "bi/content_apps/PropertiesJobTab"\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"report": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "report",\n\t\t\t"module": "bi/content_apps/PropertiesReportTab",\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"dataSet2": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}],\n\t\t"reportView": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "report",\n\t\t\t"module": "bi/content_apps/PropertiesReportTab",\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"package": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}, {\n\t\t\t"name": "capabilities",\n\t\t\t"module": "bi/content_apps/PropertiesCapabilitiesTab",\n\t\t\t"requiredCapabilities": ["canUseObjectCapabilities"]\n\t\t}],\n\t\t"folder": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}, {\n\t\t\t"name": "capabilities",\n\t\t\t"module": "bi/content_apps/PropertiesCapabilitiesTab",\n\t\t\t"requiredCapabilities": ["canUseObjectCapabilities"]\n\t\t}],\n\t\t"content": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}, {\n\t\t\t"name": "capabilities",\n\t\t\t"module": "bi/content_apps/PropertiesCapabilitiesTab",\n\t\t\t"requiredCapabilities": ["canUseObjectCapabilities"]\n\t\t}],\n\t\t"dashboard": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"jupyterNotebook": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}],\n\t\t"unknown": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"powerPlayReport": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "PowerPlayReport",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"document": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "document",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"agent": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "agent",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"agentDefinitionView": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "agent",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"planningTask": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "planningTask",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"metricsExportTask": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "metricsExportTask",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"metricsDataSourceETLTask": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "metricsDataSourceETLTask",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"metricsFileImportTask": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "metricsFileImportTask",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"metricsMaintenanceTask": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "metricsMaintenanceTask",\n\t\t\t"module": "bi/content_apps/PropertiesC10Tab"\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}],\n\t\t"powerPlay8ReportView": [{\n\t\t\t"name": "general",\n\t\t\t"module": "bi/content_apps/PropertiesGeneralTab"\n\t\t}, {\n\t\t\t"name": "report",\n\t\t\t"module": "bi/content_apps/PropertiesReportTab",\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "schedule",\n\t\t\t"module": "bi/schedule/views/SchedulesView",\n\t\t\t"requiredCapabilities": ["canUseScheduling"],\n\t\t\t"requiredPermissions": ["read"]\n\t\t}, {\n\t\t\t"name": "permission",\n\t\t\t"module": "bi/content_apps/PropertiesPermissionsTab",\n\t\t\t"requiredPermissions": ["setPolicy"]\n\t\t}]\n\t}\n}\n';});
  11467. /*
  11468. *+------------------------------------------------------------------------+
  11469. *| Licensed Materials - Property of IBM
  11470. *
  11471. *| IBM Cognos Products: content-apps
  11472. *
  11473. *| (C) Copyright IBM Corp. 2015, 2021
  11474. *|
  11475. *| US Government Users Restricted Rights - Use, duplication or disclosure
  11476. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  11477. *+------------------------------------------------------------------------+
  11478. */
  11479. //jshint maxparams: 8
  11480. define('bi/content_apps/PropertiesPageView',[
  11481. 'underscore',
  11482. 'bacontentnav/lib/@waca/core-client/js/core-client/ui/properties/PropertyPageView',
  11483. 'bacontentnav/utils/ContentStoreObject',
  11484. 'bacontentnav/utils/GlassContextHelper',
  11485. 'bacontentnav/utils/UIHelper',
  11486. 'bacontentnav/utils/ContentManagement',
  11487. 'bi/content_apps/nls/StringResource',
  11488. 'bi/content_apps/PropertiesGeneralTab',
  11489. 'text!bi/content_apps/propertiespageview.json'
  11490. ], function(_, PropertyPageView, ContentStoreObject, GlassContextHelper, UIHelper, ContentManagement, StringResource, PropertiesGeneralTab, propertiesPageViewDefinitions) {
  11491. 'use strict'; //NOSONAR
  11492. var PropertiesPageView = PropertyPageView.extend({
  11493. _isSaved: false,
  11494. /**
  11495. * @param options.$el - JQuery node to append the view onto (either a parent pane or the body)
  11496. * @param options.objectInformation {object} - An object that contains the information for the content
  11497. *
  11498. * @constructor
  11499. */
  11500. init: function(options) {
  11501. PropertiesPageView.inherited('init', this, arguments);
  11502. _.extend(this, options);
  11503. this._oPropertiesPageViewDefinitions = JSON.parse(propertiesPageViewDefinitions);
  11504. },
  11505. render: function() {
  11506. return this._getPropertiesInfo().then(function() {
  11507. if (this.objectInformation.objectDeleted) {
  11508. UIHelper.renderInfoMessage(this.$el, StringResource.get('objectDeleted'));
  11509. } else {
  11510. var isRoot = ContentStoreObject.isTeamContent(this.objectInformation);
  11511. var object = ContentStoreObject.getObjectName(this.objectInformation);
  11512. var objectName = isRoot ? StringResource.get('teamFolders') : object;
  11513. return this.renderPropertyUIControl({
  11514. 'el': this.$el,
  11515. 'glassContext': this.glassContext,
  11516. 'slideout': this.slideout,
  11517. 'readOnly': !ContentStoreObject.hasPermissions(this.objectInformation, ['write']),
  11518. 'ariaLabel': StringResource.get('a11yPropertyPane', {
  11519. 'nameOfObject': objectName
  11520. }),
  11521. 'items': [{
  11522. 'name': 'defaultName',
  11523. 'editable': isRoot ? false : true,
  11524. 'svgIcon': UIHelper.getTypeSVGIconFromObject(this.objectInformation),
  11525. 'svgToolTip': UIHelper.getTypeNameFromObject(this.objectInformation),
  11526. 'value': objectName,
  11527. 'type': 'Banner',
  11528. 'ariaLabel': StringResource.get('itemName'),
  11529. 'handleReturnKey': true,
  11530. 'enterKeyCallback': this.update.bind(this),
  11531. 'isString': true
  11532. }, {
  11533. 'type': 'OwnerRow',
  11534. 'owner': isRoot ? StringResource.get('none') : ContentStoreObject.getOwnerName(this.objectInformation),
  11535. 'creationTime': ContentStoreObject.getCreationDate(this.objectInformation, true, 'short', true),
  11536. 'modificationTime': ContentStoreObject.getModificationTime(this.objectInformation, true, 'short', true),
  11537. 'refreshTime': this.objectInformation.dataSetOutputInfo ? this.objectInformation.dataSetOutputInfo.creationTime : null,
  11538. 'fileType': UIHelper.getTypeNameFromObject(this.objectInformation)
  11539. }, {
  11540. 'type': 'TabControl',
  11541. 'items': this._getTabItems()
  11542. }]
  11543. });
  11544. }
  11545. }.bind(this));
  11546. },
  11547. /**
  11548. * Update our objectInformation model.
  11549. * This calls remove() to ensure any changes are saved, sets the new objectInformation and then renders.
  11550. * @param newObjectInformation a new model.
  11551. * @returns a promise that resolves when everything is updated and rendered.
  11552. */
  11553. updateObjectInformationModel: function(newObjectInformation, onPropertiesClose) {
  11554. //update and then render. This is in a finally so that it will update on an error as well.
  11555. return this.update().finally(function() {
  11556. if (this._oPropertyUIControl) {
  11557. this._oPropertyUIControl.remove();
  11558. }
  11559. this._oPropertyUIControl = null;
  11560. this.objectInformation = newObjectInformation;
  11561. if (onPropertiesClose) {
  11562. onPropertiesClose();
  11563. }
  11564. return this.render();
  11565. }.bind(this));
  11566. },
  11567. update: function() {
  11568. if (ContentStoreObject.hasPermissions(this.objectInformation, ['read write'])) {
  11569. return Promise.resolve(true);
  11570. }
  11571. if (!this.getPropertyUIControl()) {
  11572. return Promise.resolve(true);
  11573. }
  11574. var data = this.getPropertyUIControl().getModifiedProperties();
  11575. if (_.size(data) === 0) {
  11576. return Promise.resolve(true);
  11577. }
  11578. // check if the defaultName contains both ' and " which is not allowed by CM
  11579. if (data.defaultName && typeof(data.defaultName) === 'string' && (data.defaultName.indexOf('\'') > -1) && (data.defaultName.indexOf('"') > -1)){
  11580. GlassContextHelper.displayToast(this.glassContext, StringResource.get('errorMessageApostropheError'), {
  11581. 'type': 'error'
  11582. });
  11583. return Promise.resolve(true);
  11584. }
  11585. // Update the parent view which is showing the original object
  11586. return this._directSave(data).then(function() {
  11587. if (typeof (this.parentView.refresh) === 'function') {
  11588. this.parentView.refresh();
  11589. }
  11590. data.id = this.objectInformation.id;
  11591. data.selfUrl = ContentStoreObject.getSelfLink(this.objectInformation);
  11592. this.glassContext.getSvc('.Content').then(function(contentSvc) {
  11593. contentSvc.updateMRUEntry(data);
  11594. });
  11595. }.bind(this));
  11596. },
  11597. _doSave: function() {
  11598. return this.update();
  11599. },
  11600. _directSave: function(data) {
  11601. // Add the type and url to the properties (used in the PUT request)
  11602. var type = null;
  11603. var url = null;
  11604. // Notes:
  11605. // The refReportSelfLink is captured/cached when figuring out the packaging info for agentDefinition object's report child object in terms of avoiding another Ajax call.
  11606. // With our current Object Model, unlike report object containing the defined packaging info, agentDefinition object has to define the packaging info via its report child object.
  11607. // If there are other objects similar to agentDefinition, handle similarly.
  11608. // Currently, agentDefinition does not support the linkage of "data module" which will need to be supported eventually according to OM.
  11609. if (ContentStoreObject.getMetadataModelPackage(data) && this.objectInformation.refReportSelfLink) {
  11610. type = 'report';
  11611. url = this.objectInformation.refReportSelfLink;
  11612. } else {
  11613. type = ContentStoreObject.getType(this.objectInformation);
  11614. url = ContentStoreObject.getSelfLink(this.objectInformation);
  11615. }
  11616. data.type = type;
  11617. // check if the defaultName contains both ' and " before sending update request, which is not allowed by CM
  11618. if (data.defaultName && typeof(data.defaultName) === 'string' && (data.defaultName.indexOf('\'') > -1) && (data.defaultName.indexOf('"') > -1)){
  11619. return GlassContextHelper.displayToast(this.glassContext, StringResource.get('errorMessageApostropheError'), {
  11620. 'type': 'error'
  11621. });
  11622. }
  11623. return this._sendUpdateRequest(data, url);
  11624. },
  11625. _sendUpdateRequest: function(data, url) {
  11626. var options = {
  11627. 'headers': {
  11628. 'Accept': 'application/json',
  11629. 'Content-Type': 'application/json'
  11630. },
  11631. 'type': 'PUT',
  11632. 'url': url,
  11633. 'data': JSON.stringify(data)
  11634. };
  11635. return this._sendRequest(options, false, data);
  11636. },
  11637. _sendRequest: function(options, successHandler, data, ignoreFailure) {
  11638. this.logger.debug('PropertiesPageView._sendRequest', options, data);
  11639. successHandler = successHandler || function() {};
  11640. options.cache = false;
  11641. return new Promise(function(resolve, reject) {
  11642. this.glassContext.getCoreSvc('.Ajax').ajax(options)
  11643. .then(successHandler.bind(this))
  11644. .catch(function(error) {
  11645. if (!ignoreFailure) {
  11646. // check for name collisions or undetailed update errors
  11647. var isDuplicate = ContentManagement.isNameConflict(error);
  11648. var isUnknownUpdateError = !isDuplicate && ContentManagement.isUnknownUpdateError(error);
  11649. if (isDuplicate || isUnknownUpdateError) {
  11650. // use a toast message if this is a name collision or unknown error
  11651. var message = isDuplicate ?
  11652. StringResource.get('renameCollisionError', {
  11653. 'name': data && data.defaultName || ''
  11654. }) :
  11655. StringResource.get('unknownUpdateError');
  11656. GlassContextHelper.displayToast(this.glassContext, message, {
  11657. 'type': 'error'
  11658. });
  11659. } else {
  11660. // show dialog if other error messages are available
  11661. GlassContextHelper.showAjaxServiceErrorMessage(this.glassContext, error.jqXHR);
  11662. }
  11663. reject(new Error());
  11664. }
  11665. }.bind(this))
  11666. .finally(function() {
  11667. resolve();
  11668. });
  11669. }.bind(this));
  11670. },
  11671. _getPropertiesInfo: function() {
  11672. var options = this._getRequestOptions(ContentStoreObject.getSelfLink(this.objectInformation), this._getPropertiesToQuery());
  11673. return this._sendRequest(options, this._handleGetInfoSuccess).then(function() {
  11674. return Promise.all(this._getAdditionalInfo());
  11675. }.bind(this));
  11676. },
  11677. _getAdditionalInfo: function() {
  11678. var aPromises = [];
  11679. // get additional info based on the real object type, NOT PROPERTIES_MAP
  11680. switch (this.objectInformation.type) {
  11681. case 'package':
  11682. var modelGetURL = ContentStoreObject.getModelsLink(this.objectInformation);
  11683. if (modelGetURL) {
  11684. // Send the models request and only resolve this deferred once the models deferred is resolved
  11685. aPromises.push(this._sendRequest(this._getRequestOptions(modelGetURL, 'options'), this._handleGetModelSuccess));
  11686. }
  11687. break;
  11688. case 'reportView':
  11689. case 'powerPlay8ReportView':
  11690. var baseSource = ContentStoreObject.getBaseMetadataModelPackage(this.objectInformation) || ContentStoreObject.getBaseModule(this.objectInformation);
  11691. if (baseSource) {
  11692. var baseSelfURL = ContentStoreObject.getSelfLink(baseSource);
  11693. if (baseSelfURL) {
  11694. aPromises.push(this._sendRequest(this._getRequestOptions(baseSelfURL, 'defaultName,ancestors'), this._handleGetPackageSuccess));
  11695. }
  11696. }
  11697. break;
  11698. case 'dataSet2':
  11699. var metadataModel = ContentStoreObject.getMetadataModelPackage(this.objectInformation) || ContentStoreObject.getModule(this.objectInformation);
  11700. if (metadataModel) {
  11701. var selfLink = ContentStoreObject.getSelfLink(metadataModel);
  11702. if (selfLink) {
  11703. aPromises.push(this._sendRequest(this._getRequestOptions(selfLink, 'defaultName,ancestors'), this._handleGetPackageSuccess));
  11704. }
  11705. }
  11706. aPromises.push(this._sendRequest(this._getRequestOptions(ContentStoreObject.getSelfLink(this.objectInformation) + '/default_output', 'creationTime,dataSize,dataDescriptor,owner.defaultName'), this._handleGetDataSetOutputResponse));
  11707. break;
  11708. case 'shortcut':
  11709. var targetUrl = this.objectInformation.target && this.objectInformation.target[0]._meta.links.path.url;
  11710. if (targetUrl) {
  11711. aPromises.push(this._sendRequest(this._getRequestOptions(targetUrl, 'defaultName,ancestors'), this._handleGetShortcutTargetDataSuccess, null, true));
  11712. }
  11713. break;
  11714. case 'agentDefinition':
  11715. var itemsLink = ContentStoreObject.getItemsLink(this.objectInformation);
  11716. if (itemsLink) {
  11717. aPromises.push(this._sendRequest(this._getRequestOptions(itemsLink, 'metadataModelPackage{defaultName,ancestors}'), this._handleGetReportMetadataModelPackageSuccess, null, true));
  11718. }
  11719. break;
  11720. default:
  11721. }
  11722. return aPromises;
  11723. },
  11724. _getRequestOptions: function(url, fields) {
  11725. return {
  11726. dataType: 'json',
  11727. type: 'GET',
  11728. url: url,
  11729. data: {
  11730. fields: fields
  11731. }
  11732. };
  11733. },
  11734. _getFirstInResponseArray: function(requestResponse) {
  11735. var data = _.isArray(requestResponse.data && requestResponse.data.data) ? requestResponse.data.data : null;
  11736. return data && data.length !== 0 ? data[0] : null;
  11737. },
  11738. _handleGetInfoSuccess: function(requestResponse) {
  11739. var firstData = this._getFirstInResponseArray(requestResponse);
  11740. if (firstData) {
  11741. $.extend(this.objectInformation, firstData);
  11742. } else {
  11743. this.objectInformation.objectDeleted = true;
  11744. }
  11745. },
  11746. _handleGetModelSuccess: function(requestResponse) {
  11747. //just set the options info as we do not want to accidentally overwrite the model info or really anything else
  11748. var firstData = this._getFirstInResponseArray(requestResponse);
  11749. if (firstData) {
  11750. this.objectInformation.options = firstData.options;
  11751. }
  11752. },
  11753. _handleGetDataSetOutputResponse: function(requestResponse) {
  11754. var firstData = this._getFirstInResponseArray(requestResponse);
  11755. if (firstData) {
  11756. this.objectInformation.dataSetOutputInfo = {
  11757. 'creationTime': ContentStoreObject.getCreationDate(firstData, true, 'short', true),
  11758. 'dataSize': firstData.dataSize,
  11759. 'dataDescriptor': firstData.dataDescriptor,
  11760. 'owner': firstData.owner
  11761. };
  11762. }
  11763. },
  11764. _handleGetPackageSuccess: function(requestResponse) {
  11765. var firstData = this._getFirstInResponseArray(requestResponse);
  11766. if (firstData) {
  11767. var objToUpdate = ContentStoreObject.getBaseMetadataModelPackage(this.objectInformation) ||
  11768. ContentStoreObject.getMetadataModelPackage(this.objectInformation) ||
  11769. ContentStoreObject.getBaseModule(this.objectInformation) ||
  11770. ContentStoreObject.getModule(this.objectInformation);
  11771. objToUpdate[ContentStoreObject.DEFAULT_NAME] = firstData.defaultName;
  11772. objToUpdate[ContentStoreObject.ANCESTORS] = firstData.ancestors;
  11773. }
  11774. },
  11775. _handleGetShortcutTargetDataSuccess: function(requestResponse) {
  11776. var firstData = this._getFirstInResponseArray(requestResponse);
  11777. if (firstData) {
  11778. var objToUpdate = this.objectInformation.target && this.objectInformation.target[0];
  11779. if (objToUpdate) {
  11780. objToUpdate.defaultName = firstData.defaultName;
  11781. objToUpdate.ancestors = firstData.ancestors;
  11782. }
  11783. }
  11784. },
  11785. _handleGetReportMetadataModelPackageSuccess: function(requestResponse) {
  11786. if (requestResponse && requestResponse.data && requestResponse.data.data) {
  11787. var data = _.find(requestResponse.data.data, function (element) { return element.type === 'report'; });
  11788. this.objectInformation.refReportSelfLink = ContentStoreObject.getSelfLink(data);
  11789. this.objectInformation.metadataModelPackage = data.metadataModelPackage;
  11790. }
  11791. },
  11792. // Used for Properties tab
  11793. _getObjectType: function() {
  11794. return UIHelper.getProperties(ContentStoreObject.getType(this.objectInformation));
  11795. },
  11796. _getPropertiesToQuery: function() {
  11797. this._objType = this._getObjectType();
  11798. if (this._objType === 'unknown') {
  11799. this.logger.log('PropertiesPageView: No mapping for object type ' + this.objectInformation.type);
  11800. }
  11801. return PropertiesGeneralTab.getPropertiesToQuery(this._objType);
  11802. },
  11803. _getTabItems: function() {
  11804. var tabItems = [];
  11805. var objectType = this._getObjectType();
  11806. // Check to make sure the objectType is supported. If not, default to unknown
  11807. var supportedObjectTabs = this._oPropertiesPageViewDefinitions.tabs;
  11808. if (!supportedObjectTabs[objectType]) {
  11809. objectType = 'unknown';
  11810. }
  11811. supportedObjectTabs[objectType].forEach(function(tab) {
  11812. if (this._isTabDisplayed(tab)) {
  11813. tabItems.push({
  11814. 'name': StringResource.get(tab.name),
  11815. 'module': tab.module,
  11816. 'objectInfo': this.objectInformation,
  11817. 'glassContext': this.glassContext,
  11818. 'slideout': this.slideout
  11819. });
  11820. }
  11821. }.bind(this));
  11822. return tabItems;
  11823. },
  11824. _isTabDisplayed: function(tab) {
  11825. var missingRequiredCapabilities = false;
  11826. if (tab.requiredCapabilities) {
  11827. missingRequiredCapabilities = tab.requiredCapabilities.some(function(capability) {
  11828. return !this.glassContext.hasCapability(capability);
  11829. }.bind(this));
  11830. }
  11831. if ((!this.glassContext.isDevInstall() && tab.devMode) ||
  11832. (tab.requiredPermissions && !UIHelper.hasPermissions(this.objectInformation.permissions, tab.requiredPermissions)) ||
  11833. missingRequiredCapabilities) {
  11834. return false;
  11835. }
  11836. return true;
  11837. }
  11838. });
  11839. return PropertiesPageView;
  11840. });
  11841. /*
  11842. *+------------------------------------------------------------------------+
  11843. *| Licensed Materials - Property of IBM
  11844. *| IBM Cognos Products: Content Explorer
  11845. *| (C) Copyright IBM Corp. 2015, 2019
  11846. *|
  11847. *| US Government Users Restricted Rights - Use, duplication or disclosure
  11848. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  11849. *+------------------------------------------------------------------------+
  11850. */
  11851. define('bi/content_apps/common/ui/list_actions/LegacyArtifactDefaultActionHandlerBase',[
  11852. 'bi/glass/core/Class',
  11853. 'bi/content_apps/utils/C10Utils',
  11854. 'underscore'
  11855. ], function(Class, C10Utils, _) {
  11856. 'use strict';
  11857. var LegacyArtifactDefaultActionHandlerBase = Class.extend({
  11858. init: function(options) {
  11859. LegacyArtifactDefaultActionHandlerBase.inherited('init', this, arguments);
  11860. _.extend(this, options);
  11861. },
  11862. canExecute: function(options) {
  11863. void(options);
  11864. return true;
  11865. },
  11866. _replaceBackURL: function(url) {
  11867. var index = url.indexOf('backURL=');
  11868. var urlWithoutBack = url;
  11869. if (index !== -1) {
  11870. urlWithoutBack = url.substring(0, index - 1);
  11871. var endIndex = url.indexOf('&', index);
  11872. if (endIndex !== -1) {
  11873. urlWithoutBack += url.substring(endIndex);
  11874. }
  11875. }
  11876. var backURL = '../utils/close.html';
  11877. url = urlWithoutBack + '&backURL=' + encodeURIComponent(backURL);
  11878. url += '&ui.backURL=' + encodeURIComponent(backURL);
  11879. return url;
  11880. },
  11881. _getLegacyLaunchURL: function(options) {
  11882. var selectedContext = options.target.activeObject.aSelectedContext;
  11883. var navServiceEndpoint = LegacyArtifactDefaultActionHandlerBase.NAVService + selectedContext[0].id + '?json=';
  11884. this.options = options;
  11885. return options.glassContext.getCoreSvc('.Ajax').ajax({
  11886. 'url': navServiceEndpoint,
  11887. 'dataType': 'text',
  11888. 'type': 'GET'
  11889. })
  11890. .then(function(result) {
  11891. result = result && result.data;
  11892. if (result) {
  11893. /* TODO - do we need this?? Seems a little.. bad. */
  11894. var parsedResponse = eval('parsedResponse=' + result); // NOSONAR: eval is needed here
  11895. if (parsedResponse.feed) {
  11896. var oType = parsedResponse.feed.cm$objectClass;
  11897. var oTargetType = parsedResponse.feed.cm$targetObjectClass;
  11898. var launchURL;
  11899. var links = parsedResponse.feed.link;
  11900. for (var i = 0; i < links.length; i = i + 1) {
  11901. if (links[i].rel === 'alternate' && links[i].type === 'application/octet-stream') {
  11902. launchURL = links[i].href;
  11903. }
  11904. }
  11905. if (launchURL) {
  11906. if (C10Utils.isPowerPlay(oType)) {
  11907. if (this.options.target.runOptions) {
  11908. launchURL = launchURL.replace('&ui.crnfrm=HTML','&ui.crnfrm=PDF');
  11909. if (this.options.target.runOptions.prompt) {
  11910. launchURL += '&ui.crnp=true';
  11911. } else {
  11912. launchURL = launchURL.replace('&ui.crnp=true', '');
  11913. }
  11914. }
  11915. }
  11916. }
  11917. if (launchURL && oType !== 'URL' && oTargetType !== 'URL') {
  11918. launchURL = this._replaceBackURL(launchURL);
  11919. }
  11920. var payLoad = {
  11921. launchURL: launchURL,
  11922. oType: oType,
  11923. oTargetType: oTargetType,
  11924. navFeed: parsedResponse
  11925. };
  11926. return Promise.resolve(payLoad);
  11927. } else {
  11928. return Promise.reject(new Error());
  11929. }
  11930. } else {
  11931. Promise.reject(new Error());
  11932. }
  11933. }.bind(this));
  11934. }
  11935. });
  11936. LegacyArtifactDefaultActionHandlerBase.NAVService = 'v1/disp/atom/cm/id/';
  11937. return LegacyArtifactDefaultActionHandlerBase;
  11938. });
  11939. /*
  11940. *+------------------------------------------------------------------------+
  11941. *| Licensed Materials - Property of IBM
  11942. *| IBM Cognos Products: content-apps
  11943. *| (C) Copyright IBM Corp. 2015, 2018
  11944. *|
  11945. *| US Government Users Restricted Rights - Use, duplication or disclosure
  11946. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  11947. *+------------------------------------------------------------------------+
  11948. */
  11949. define('bi/content_apps/common/ui/list_actions/LegacyArtifactActionHandler',[
  11950. 'underscore',
  11951. 'bi/content_apps/common/ui/list_actions/LegacyArtifactDefaultActionHandlerBase',
  11952. 'bacontentnav/utils/ContentStoreObject',
  11953. 'bacontentnav/utils/GlassContextHelper'
  11954. ], function(_, BaseActionHandler, ContentStoreObject, GlassContextHelper) {
  11955. 'use strict';
  11956. var LegacyArtifactActionHandler = BaseActionHandler.extend({
  11957. init: function(options) {
  11958. LegacyArtifactActionHandler.inherited('init', this, arguments);
  11959. _.extend(this, options);
  11960. },
  11961. canExecute: function() {
  11962. return true;
  11963. },
  11964. doAction: function(options) {
  11965. var content = options.target.activeObject.aSelectedContext[0];
  11966. if (content.type === 'myPageletRef' || content.type === 'pagelet') {
  11967. return options.glassContext.getCoreSvc('.Config').getConfigValue('ContentApps/enableMyPortalPages')
  11968. .then(function(isFeatureEnabled) {
  11969. if (isFeatureEnabled === 'true') {
  11970. if (content.type === 'myPageletRef') {
  11971. content.id = content.target;
  11972. }
  11973. content.objRef = content.id;
  11974. return options.glassContext.appController.openAppView('pagelet', { content: content });
  11975. } else {
  11976. return this._doLegacyAction(options);
  11977. }
  11978. }.bind(this));
  11979. } else {
  11980. return this._doLegacyAction(options);
  11981. }
  11982. },
  11983. _doLegacyAction: function(options) {
  11984. return this._getLegacyLaunchURL(options).then(function(payLoad) {
  11985. var launchURL = payLoad.launchURL;
  11986. var item = options.target.activeObject.aSelectedContext[0];
  11987. var runPermissions = ContentStoreObject.hasPermissions(item, ['execute']);
  11988. if (launchURL) {
  11989. if (options.target.runOptions !== undefined) {
  11990. launchURL = launchURL.replace('ui.action=edit', 'ui.action=run');
  11991. if (options.target.runOptions.prompt) {
  11992. launchURL = launchURL + '&ui.crnp=true';
  11993. } else {
  11994. launchURL = launchURL + '&ui.crnp=false';
  11995. }
  11996. }
  11997. var newTab = this._openUrl(launchURL);
  11998. // resolve if there's tab or it was a file ('file'-protocol URLs don't create a tab)
  11999. if (newTab || (launchURL.indexOf('file:') === 0) || (launchURL.indexOf('\\\\') === 0)) {
  12000. return Promise.resolve();
  12001. } else {
  12002. return Promise.reject(new Error('Could not launch a new tab.'));
  12003. }
  12004. } else if(!launchURL && (options.target.itemId.indexOf('powerPlay8Report') !== -1) && runPermissions) {
  12005. // the launch url comes back as undefined from the atom api if the user does not have powerplay capability
  12006. // APAR 140674 workaround to open a power play report as pdf for users without the capability
  12007. var contentLocale = GlassContextHelper.getUserPreference(options.glassContext, 'contentLocale');
  12008. var productLocale = GlassContextHelper.getUserPreference(options.glassContext, 'productLocale');
  12009. var outputId = options.target.activeObject.aSelectedContext[0].id;
  12010. var name = options.target.activeObject.aSelectedContext[0].defaultName;
  12011. var url = 'v1/disp?b_action=powerPlayService&ui.gateway=/bi/v1/disp&ui.action=run&ui.crnfrm=PDF&ui.crnp=true&LA='+productLocale+'&LO='+contentLocale+'&crnobj='+ item.searchPath +'&ui.tool=PowerplayStudio&ui.format=PDF&ui.object=storeID(%22' + outputId + '%22)&ui.name=' + _.escape(name);
  12012. url = url + '&cv.header=false&ui.backURL=%2fcps4%2fportlets%2fcommon%2fclose.html';
  12013. this._openUrl(url);
  12014. return Promise.resolve();
  12015. } else {
  12016. return Promise.reject(new Error('No URL associated with the artifact.'));
  12017. }
  12018. }.bind(this));
  12019. },
  12020. _openUrl: function(url) {
  12021. return window.open(url);
  12022. }
  12023. });
  12024. return LegacyArtifactActionHandler;
  12025. });
  12026. /*
  12027. *+------------------------------------------------------------------------+
  12028. *| Licensed Materials - Property of IBM
  12029. *| IBM Cognos Products: BI Content Explorer
  12030. *| (C) Copyright IBM Corp. 2018
  12031. *|
  12032. *| US Government Users Restricted Rights - Use, duplication or disclosure
  12033. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  12034. *+------------------------------------------------------------------------+
  12035. */
  12036. define('bi/content_apps/common/ui/list_actions/AddURLAction',[
  12037. 'jquery',
  12038. 'underscore',
  12039. 'bacontentnav/common/ui/list_actions/ListAction',
  12040. 'bi/content_apps/nls/StringResource',
  12041. 'bacontentnav/utils/ContentManagement',
  12042. 'bacontentnav/utils/GlassContextHelper',
  12043. 'bacontentnav/utils/ActionHelper',
  12044. 'bi/content_apps/common/ui/list_actions/LegacyArtifactActionHandler',
  12045. 'bi/commons/utils/BidiUtil'
  12046. // jshint -W072
  12047. ], function($, _, ListAction, StringResource, ContentManagement, GlassContextHelper, ActionHelper, LegacyArtifactActionHandler, BidiUtil) {
  12048. // jshint +W072
  12049. 'use strict';
  12050. var AddFolderAction = ListAction.extend({
  12051. init: function(options) {
  12052. _.extend(this, options);
  12053. this.contentList = this.hostView.view;
  12054. this.listControl = this.hostView.listControl;
  12055. this.glassContext = this.hostView.glassContext;
  12056. this.logger = this.glassContext.getCoreSvc('.Logger');
  12057. this.legacyHandler = new LegacyArtifactActionHandler();
  12058. this.renderFromReact = this.hostView.renderFromReact;
  12059. if(this.listControl && !this.renderFromReact) {
  12060. this.url = this.listControl.url;
  12061. this.aData = this.listControl._dTable.fnGetData();
  12062. } else {
  12063. this.url = this.hostView.url;
  12064. this.aData = this.contentList && this.contentList.state && this.contentList.state.files;
  12065. }
  12066. },
  12067. execute: function(data) {
  12068. var displayName = data.defaultName;
  12069. data.type = 'URL';
  12070. var requestOptions = {
  12071. 'headers': {
  12072. 'Accept': 'application/json',
  12073. 'Content-Type': 'application/json'
  12074. },
  12075. 'type': 'POST',
  12076. 'url': this.url,
  12077. 'data': JSON.stringify(data)
  12078. };
  12079. return this.glassContext.getCoreSvc('.Ajax').ajax(requestOptions)
  12080. .then(function(response) {
  12081. // if the domain was not acceptable Content Service will still create the item but with an empty 'alternate' link
  12082. // so as a work-around we will check for it's presence and show an error and delete the asset if it's missing
  12083. var location = response.jqXHR.getResponseHeader('location');
  12084. var id = this._extractIDFromLocation(location);
  12085. var mruInfo = {
  12086. 'id': id,
  12087. 'type': data.type,
  12088. 'defaultName': data.defaultName
  12089. };
  12090. var options = {
  12091. 'glassContext': this.glassContext,
  12092. 'target': {
  12093. 'activeObject': {
  12094. 'aSelectedContext': [{
  12095. 'id': id
  12096. }]
  12097. }
  12098. }
  12099. };
  12100. return this.legacyHandler._getLegacyLaunchURL(options)
  12101. .then(function(payLoad) {
  12102. if (!payLoad.launchURL) {
  12103. // delete the invalid asset
  12104. var requestOptions = {
  12105. 'type': 'DELETE',
  12106. 'url': location
  12107. };
  12108. return this.glassContext.getCoreSvc('.Ajax').ajax(requestOptions)
  12109. .then(function() {
  12110. this._showError(StringResource.get('unacceptableDomain', {
  12111. viewAcceptableDomains: StringResource.get('viewAcceptableDomains')
  12112. }));
  12113. }.bind(this))
  12114. .catch(function(err) {
  12115. return this._handleError(data, err);
  12116. }.bind(this));
  12117. } else {
  12118. return this._onSuccess(displayName, mruInfo);
  12119. }
  12120. }.bind(this))
  12121. .catch(function(err) {
  12122. // this just means we're unable to verify the domain so just log the error and finish up
  12123. this.logger.error('problem fetching info on newly-created URL', err);
  12124. data.id = id;
  12125. return this._onSuccess(displayName, mruInfo);
  12126. }.bind(this));
  12127. }.bind(this))
  12128. .catch(function(err) {
  12129. return this._handleError(data, err);
  12130. }.bind(this));
  12131. },
  12132. _onSuccess: function(displayName, mruInfo) {
  12133. if(this.listControl && !this.renderFromReact) {
  12134. this.listControl.updateDatatable();
  12135. } else {
  12136. this.contentList.fetchListData(this.url);
  12137. }
  12138. GlassContextHelper.displayToast(this.glassContext, StringResource.get('toastCreateNewURL', {
  12139. 'nameofURL': BidiUtil.enforceTextDirection(displayName)
  12140. }));
  12141. this.hostView.close();
  12142. this.glassContext.getSvc('.Content')
  12143. .then(function(contentSvc) {
  12144. return contentSvc.addToMRU(mruInfo);
  12145. });
  12146. return Promise.resolve();
  12147. },
  12148. _handleError: function(data, err) {
  12149. // check for client side error
  12150. var messages = {
  12151. 'itemsOverLimit': StringResource.get('itemsOverLimit', {
  12152. itemName: data.defaultName
  12153. }),
  12154. 'nameLengthError': StringResource.get('errorMessageLengthURLName')
  12155. };
  12156. if(this.listControl && !this.renderFromReact){
  12157. return ActionHelper.handleAddItemError(this.listControl, data, err, messages)
  12158. .then(function() {
  12159. // resolved a name conflict so try again
  12160. return this.execute(data);
  12161. }.bind(this))
  12162. .fail(function (err) {
  12163. this._showError('', err);
  12164. return Promise.reject(err);
  12165. }.bind(this));
  12166. } else {
  12167. return this.handleAddItemError(data, err)
  12168. .then(function(data) {
  12169. // resolved a name conflict so try again
  12170. return this.execute(data);
  12171. }.bind(this))
  12172. .fail(function (err) {
  12173. this._showError('', err);
  12174. return Promise.reject(err);
  12175. }.bind(this));
  12176. }
  12177. },
  12178. _showError: function(message, err) {
  12179. if(this.listControl && !this.renderFromReact) {
  12180. this.listControl.updateDatatable();
  12181. } else {
  12182. this.contentList.fetchListData(this.url);
  12183. }
  12184. if (err) {
  12185. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  12186. } else {
  12187. this.hostView.showErrorMessage(message, 'warn');
  12188. }
  12189. this.hostView.enableSubmitButton();
  12190. },
  12191. _getNewNameString: function(data) {
  12192. var nameList = [];
  12193. this.aData.forEach(function(rowData) { // Get a small list of names that has the substring data.defaultName
  12194. var name = rowData.defaultName.toLowerCase();
  12195. if (name.indexOf(data.defaultName.toLowerCase()) === 0) {
  12196. nameList.push(name);
  12197. }
  12198. });
  12199. var newNameString;
  12200. for (var i = 1; i <= nameList.length; i++) {
  12201. newNameString = data.defaultName + ' (' + i + ')';
  12202. if (!nameList.includes(newNameString.toLowerCase())) {
  12203. break;
  12204. }
  12205. }
  12206. this.count = i;
  12207. return newNameString;
  12208. },
  12209. handleAddItemError: function(data, err) {
  12210. // check for client side error
  12211. if (err.code === 400) {
  12212. // if name duplication, try to increment (up to 20)
  12213. if (ContentManagement.isNameConflict(err)) {
  12214. var newNameString = this._getNewNameString(data);
  12215. if (this.count < 20) {
  12216. data.defaultName = newNameString;
  12217. return Promise.resolve(data);
  12218. } else {
  12219. GlassContextHelper.displayToast(this.glassContext, StringResource.get('itemsOverLimit', {
  12220. itemName: data.defaultName
  12221. }),{ type: 'error' });
  12222. return Promise.reject(err.message);
  12223. }
  12224. } else if (data.defaultName.length > 255) {
  12225. // If the URL name is > than 255 characters
  12226. GlassContextHelper.displayToast(this.glassContext, StringResource.get('errorMessageLengthURLName'),
  12227. { type: 'error' });
  12228. return Promise.reject(err.message);
  12229. }
  12230. } else {
  12231. return Promise.reject(err);
  12232. }
  12233. },
  12234. _extractIDFromLocation: function(location) {
  12235. // want everything after the last slash (/bi/v1/objects/i752E8C17A5A149649BD6A26FF8978073)
  12236. return location.slice(location.lastIndexOf('/') + 1);
  12237. }
  12238. });
  12239. return AddFolderAction;
  12240. });
  12241. /*
  12242. *+------------------------------------------------------------------------+
  12243. *| Licensed Materials - Property of IBM
  12244. *| IBM Cognos Products: Content Explorer
  12245. *| (C) Copyright IBM Corp. 2018, 2020
  12246. *|
  12247. *| US Government Users Restricted Rights - Use, duplication or disclosure
  12248. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  12249. *+------------------------------------------------------------------------+
  12250. */
  12251. define('bi/content_apps/ui/dialogs/DomainsDialog',[
  12252. 'bacontentnav/lib/@waca/core-client/js/core-client/ui/core/Class',
  12253. 'jquery',
  12254. 'underscore'
  12255. ], function(Class, $, _) {
  12256. var Dialog = null;
  12257. Dialog = Class.extend({
  12258. _buttons: ['ok'],
  12259. init: function(options) {
  12260. this._options = options;
  12261. this.id = 'com-ibm-ca-domainsDialogTitle';
  12262. this.contentId = 'com-ibm-ca-domainsDialogContent';
  12263. Dialog.inherited('init', this, [this._options]);
  12264. },
  12265. open: function() {
  12266. this._options.glassContext.showMessage(this.renderContent(), this._options.title, 'info', this._buttons, '', undefined, true, 'domainsDialog');
  12267. },
  12268. renderContent: function() {
  12269. var $list = $('<ul>', {
  12270. 'class': 'itemListing'
  12271. });
  12272. _.forEach(this._options.list, function(listItem) {
  12273. $list.append(
  12274. $('<li>', {
  12275. 'class': 'listItem',
  12276. 'html': listItem
  12277. })
  12278. );
  12279. });
  12280. var $div = $('<div>');
  12281. $div.append($list);
  12282. return $div.html();
  12283. }
  12284. });
  12285. return Dialog;
  12286. });
  12287. /*
  12288. *+------------------------------------------------------------------------+
  12289. *| Licensed Materials - Property of IBM
  12290. *| IBM Cognos Products: Content Explorer
  12291. *| (C) Copyright IBM Corp. 2018, 2020
  12292. *|
  12293. *| US Government Users Restricted Rights - Use, duplication or disclosure
  12294. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  12295. *+------------------------------------------------------------------------+
  12296. */
  12297. define('bi/content_apps/ui/views/AddURLView',[
  12298. 'underscore',
  12299. 'bi/glass/app/ContentView',
  12300. 'bi/content_apps/common/ui/list_actions/AddURLAction',
  12301. 'bi/content_apps/nls/StringResource',
  12302. 'bacontentnav/utils/ContentStoreObject',
  12303. 'bacontentnav/utils/GlassContextHelper',
  12304. 'bi/content_apps/ui/dialogs/DomainsDialog',
  12305. 'bi/commons/utils/BidiUtil',
  12306. 'bi/commons/ui/KeyCodes'
  12307. // jshint -W072
  12308. ], function(_, ContentView, AddURLAction, StringResource, ContentStoreObject, GlassContextHelper, DomainsDialog, BidiUtil, KeyCodes) {
  12309. // jshint +W072
  12310. 'use strict';
  12311. var AddURLView = ContentView.extend({
  12312. propertyUIControlModule: 'bi/commons/ui/properties/PropertyUIControl',
  12313. init: function(options) {
  12314. _.extend(this, options);
  12315. AddURLView.inherited('init', this, arguments);
  12316. this.CONFIGVALUE_VALIDDOMAINLIST = 'CAF.caf_validDomainList';
  12317. this.url = this.url && this.url._meta && this.url._meta.links && this.url._meta.links.items && this.url._meta.links.items.url;
  12318. this.contentList = this.view;
  12319. this.renderFromReact = options.renderFromReact;
  12320. this.addURLAction = new AddURLAction({
  12321. 'hostView': this
  12322. });
  12323. },
  12324. render: function() {
  12325. return new Promise(function(resolve) {
  12326. this._renderFormItems(resolve, this._buildFormItems());
  12327. }.bind(this));
  12328. },
  12329. _renderFormItems: function(resolve, items) {
  12330. require([this.propertyUIControlModule], function(PropertyUIControl) {
  12331. this.$el.addClass(this._getAddURLViewClass());
  12332. this._oPropertyUIControl = new PropertyUIControl({
  12333. 'glassContext': this.glassContext,
  12334. 'el': this.$el,
  12335. 'items': items
  12336. });
  12337. this._oPropertyUIControl.render().then(function() {
  12338. this.submitButton = this.$el.find('.primary');
  12339. $('input', this.$el).each(function(i, node) {
  12340. $(node).on('keydown', this._onKeydown.bind(this, $(node)));
  12341. }.bind(this));
  12342. resolve(this._oPropertyUIControl);
  12343. }.bind(this));
  12344. }.bind(this));
  12345. },
  12346. /**
  12347. * Class to be placed on the AddURLView
  12348. **/
  12349. _getAddURLViewClass: function() {
  12350. return 'AddURLView';
  12351. },
  12352. _buildFormItems: function() {
  12353. var title = StringResource.get('newURLLabel');
  12354. return [
  12355. {
  12356. 'value': title,
  12357. 'type': 'Banner',
  12358. 'svgIcon': '#common-url',
  12359. 'svgToolTip': 'URL',
  12360. 'ariaLabel': title
  12361. },
  12362. {
  12363. 'name': 'instructions',
  12364. 'label': StringResource.get('newURLDesc'),
  12365. 'type': 'HintText'
  12366. },
  12367. {
  12368. 'name': 'defaultName',
  12369. 'label': StringResource.get('name'),
  12370. 'placeHolderText': StringResource.get('urlNamePlaceholder'),
  12371. 'newLook': true,
  12372. 'value': '',
  12373. 'type': 'InputLabel',
  12374. 'multiline': true,
  12375. 'readOnly': false
  12376. },
  12377. {
  12378. 'type': 'Separator'
  12379. },
  12380. {
  12381. 'name': 'defaultDescription',
  12382. 'label': StringResource.get('description'),
  12383. 'placeHolderText': StringResource.get('descriptionPlaceholder'),
  12384. 'value': '',
  12385. 'type': 'TextArea',
  12386. 'editable': true,
  12387. 'multiline': true,
  12388. 'validator': {
  12389. 'maxLength': 1024
  12390. }
  12391. },
  12392. {
  12393. 'type': 'Separator'
  12394. },
  12395. {
  12396. 'name': 'uri',
  12397. 'label': StringResource.get('URL'),
  12398. 'placeHolderText': StringResource.get('urlPlaceholder'),
  12399. 'newLook': true,
  12400. 'value': '',
  12401. 'type': 'InputLabel',
  12402. 'multiline': true,
  12403. 'readOnly': false
  12404. },
  12405. {
  12406. type: 'SingleLineLinks',
  12407. name: 'viewAcceptableDomains',
  12408. items: [{
  12409. align: 'right',
  12410. items : [
  12411. {
  12412. 'type' : 'text',
  12413. 'value' : StringResource.get('viewAcceptableDomains'),
  12414. clickCallback: function() {
  12415. this._showAcceptableDomains();
  12416. }.bind(this)
  12417. }
  12418. ]
  12419. }]
  12420. },
  12421. {
  12422. 'type': 'Footer',
  12423. 'items': [
  12424. {
  12425. 'type': 'Button',
  12426. 'label': StringResource.get('ok'),
  12427. 'onSelect': this._onSubmitClick.bind(this),
  12428. 'primary': true
  12429. },
  12430. {
  12431. 'type': 'Button',
  12432. 'label': StringResource.get('cancel'),
  12433. 'onSelect': this._onCancelClick.bind(this),
  12434. 'primary': false
  12435. }
  12436. ]
  12437. }
  12438. ];
  12439. },
  12440. _onCancelClick: function() {
  12441. this.slideout.hide();
  12442. },
  12443. _onSubmitClick: function() {
  12444. var data = this._processSubmittedData();
  12445. if (data.missing.length === 0) {
  12446. this.disableSubmitButton();
  12447. return this.addURLAction.execute(data.props)
  12448. .then(function() {
  12449. if(this.listControl && !this.renderFromReact) {
  12450. this.listControl.updateDatatable();
  12451. } else {
  12452. this.contentList.fetchListData(this.url);
  12453. }
  12454. }.bind(this));
  12455. } else {
  12456. var message = StringResource.get('fieldsAreMandatory');
  12457. this.showErrorMessage(message, 'warn');
  12458. this.enableSubmitButton();
  12459. }
  12460. },
  12461. _onKeydown: function(node, event) {
  12462. if (event.keyCode === KeyCodes.ENTER) {
  12463. // this is to circumvent a weird issue where glass wasn't considering a field modified when it had focus *sigh...*
  12464. node.blur();
  12465. this._onSubmitClick();
  12466. event.stopPropagation();
  12467. }
  12468. },
  12469. _processSubmittedData: function() {
  12470. var data = {
  12471. 'props': this._oPropertyUIControl.getModifiedProperties(),
  12472. 'missing': []
  12473. };
  12474. this._checkInputValue('defaultName', data, StringResource.get('name'));
  12475. this._checkInputValue('uri', data, StringResource.get('URL'));
  12476. return data;
  12477. },
  12478. _checkInputValue: function(valueName, data, missingLabel) {
  12479. // for some reason input fields containing only whitespace come back as: NaN, so checking these explicitly. *sigh...*
  12480. if (typeof data.props[valueName] === 'undefined' || _.isNaN(data.props[valueName]) || data.props[valueName].trim() === '') {
  12481. data.props[valueName] = '';
  12482. // only add to missing list if label was provided
  12483. if (missingLabel) {
  12484. data.missing.push(missingLabel);
  12485. }
  12486. }
  12487. },
  12488. showErrorMessage: function(message, type) {
  12489. this.glassContext.appController.showErrorMessage(message, StringResource.get(type));
  12490. },
  12491. _showAcceptableDomains: function() {
  12492. if (this.domainsDialog) {
  12493. this.domainsDialog.open();
  12494. } else {
  12495. return this.glassContext.getCoreSvc('.Config').getConfigValue(this.CONFIGVALUE_VALIDDOMAINLIST)
  12496. .then(function(result) {
  12497. // for some weird reason, if no domains were added to the whitelist, the respone is: 'myDefault'
  12498. // so treating this as: 'no entries', I'll add it to the bugs I'm logging around this
  12499. // so ultimately the list has one item which says: 'No entries' *sigh...*
  12500. if (result === 'myDefault') {
  12501. result = StringResource.get('noEntries');
  12502. }
  12503. var options = {
  12504. 'glassContext': this.glassContext,
  12505. 'type': 'acceptableDomains',
  12506. 'title': StringResource.get('acceptableDomains'),
  12507. 'list': result && result.split(','),
  12508. 'width': '600px'
  12509. };
  12510. this.domainsDialog = new DomainsDialog(options);
  12511. this.domainsDialog.open();
  12512. }.bind(this))
  12513. .catch(function(err) {
  12514. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  12515. }.bind(this));
  12516. }
  12517. },
  12518. disableSubmitButton: function() {
  12519. this.submitButton.prop('disabled', true);
  12520. },
  12521. enableSubmitButton: function() {
  12522. this.submitButton.prop('disabled', false);
  12523. },
  12524. close: function() {
  12525. this._onCancelClick();
  12526. }
  12527. });
  12528. return AddURLView;
  12529. });
  12530. /*
  12531. *+------------------------------------------------------------------------+
  12532. *| Licensed Materials - Property of IBM
  12533. *| IBM Cognos Products: Content Explorer
  12534. *| (C) Copyright IBM Corp. 2017, 2020
  12535. *|
  12536. *| US Government Users Restricted Rights - Use, duplication or disclosure
  12537. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  12538. *+------------------------------------------------------------------------+
  12539. */
  12540. define('bi/content_apps/CABaseContentView',[
  12541. 'bacontentnav/utils/GlassContextHelper',
  12542. 'bacontentnav/common/BaseContentWideView',
  12543. 'bacontentnav/nls/StringResource',
  12544. './PropertiesPageView',
  12545. 'bi/content_apps/ui/views/AddURLView',
  12546. 'bacontentnav/utils/ContentStoreObject',
  12547. 'bacontentnav/utils/UIHelper',
  12548. 'bi/commons/utils/BrowserUtils',
  12549. 'underscore'
  12550. ], function(GlassContextHelper, BaseContentWideView, StringResource, PropertiesPageView, AddURLView, ContentStoreObject, UIHelper, BrowserUtils, _) {
  12551. 'use strict';
  12552. var MY_FOLDERS = '.my_folders';
  12553. var CABaseContentView = BaseContentWideView.extend({
  12554. init: function(options) {
  12555. void(options);
  12556. CABaseContentView.inherited('init', this, arguments);
  12557. this.contentListFacets = UIHelper.getFilterFacets(['content']);
  12558. this.contentListFilterItems = UIHelper.getConfiguration('filter').items || [];
  12559. this.contentListSortIndexes = UIHelper.getConfiguration('sort').indexes;
  12560. this.allowUploadFiles = !BrowserUtils.isIPad();
  12561. this.options = options;
  12562. if (this.options.slideout && this.options.slideout.el) {
  12563. this.contentPane = this.options.slideout.el.querySelector('.pane-content');
  12564. }
  12565. },
  12566. showProperties: function(objectInformation, options) {
  12567. if (this._propertiesOpen) {
  12568. //update the object info in the exising PropertiesPageView
  12569. if (options && options.target && options.target.activeObject && options.target.activeObject.onPropertiesClose) {
  12570. this.propertiesSlideout.contentView.updateObjectInformationModel(objectInformation, options.target.activeObject.onPropertiesClose);
  12571. } else {
  12572. this.propertiesSlideout.contentView.updateObjectInformationModel(objectInformation);
  12573. }
  12574. } else {
  12575. this.togglePropertiesMode();
  12576. // rendering from react, use the provided glass context
  12577. if (options && options.glassContext && options.target.activeObject.parentSlideout && options.target.activeObject.onPropertiesClose) {
  12578. this.propertiesSlideout = options.glassContext.appController.showSlideOut({
  12579. label: StringResource.get('properties', {
  12580. objectName: objectInformation.defaultName
  12581. }),
  12582. position: options.target.activeObject.parentSlideout ? null : 'right',
  12583. parent: options.target.activeObject.parentSlideout,
  12584. width: '400',
  12585. enableTabLooping: true,
  12586. hideOnParentClick: false,
  12587. onHide: function() {
  12588. this._focus();
  12589. this.togglePropertiesMode();
  12590. if (this.propertiesSlideout && this.propertiesSlideout.contentView) {
  12591. this.propertiesSlideout.contentView.onHide().then(function() {
  12592. options.target.activeObject.onPropertiesClose();
  12593. this.propertiesSlideout.hide();
  12594. this._propertiesOpen = false;
  12595. }.bind(this)).catch(function(){
  12596. var uiControl = this.propertiesSlideout.contentView.getPropertyUIControl();
  12597. if (uiControl) {
  12598. var namePropety = uiControl.getProperty('defaultName');
  12599. namePropety.getHTMLControl().val(objectInformation.defaultName);
  12600. namePropety._onBlur();
  12601. namePropety.remove();
  12602. namePropety.render();
  12603. }
  12604. this._propertiesOpen = false;
  12605. }.bind(this));
  12606. }
  12607. }.bind(this),
  12608. content: {
  12609. module: PropertiesPageView,
  12610. parentView: this,
  12611. objectInformation: objectInformation,
  12612. glassContext: options.glassContext
  12613. },
  12614. resizable: true
  12615. });
  12616. } else {
  12617. // not rendering from react, use this.glassContext
  12618. this.propertiesSlideout = this.glassContext.appController.showSlideOut({
  12619. label: StringResource.get('properties', {
  12620. objectName: objectInformation.defaultName
  12621. }),
  12622. position: this.slideout ? null : 'right',
  12623. parent: this.slideout,
  12624. width: '400',
  12625. enableTabLooping: true,
  12626. hideOnParentClick: false,
  12627. onHide: function() {
  12628. this._focus();
  12629. this.togglePropertiesMode();
  12630. if (this.propertiesSlideout && this.propertiesSlideout.contentView) {
  12631. this.propertiesSlideout.contentView.onHide().then(function() {
  12632. this.propertiesSlideout.hide();
  12633. this._propertiesOpen = false;
  12634. }.bind(this)).catch(function(){
  12635. var uiControl = this.propertiesSlideout.contentView.getPropertyUIControl();
  12636. if (uiControl) {
  12637. var namePropety = uiControl.getProperty('defaultName');
  12638. namePropety.getHTMLControl().val(objectInformation.defaultName);
  12639. namePropety._onBlur();
  12640. namePropety.remove();
  12641. namePropety.render();
  12642. }
  12643. this._propertiesOpen = false;
  12644. }.bind(this));
  12645. }
  12646. }.bind(this),
  12647. content: {
  12648. module: PropertiesPageView,
  12649. parentView: this,
  12650. objectInformation: objectInformation,
  12651. glassContext: this.glassContext
  12652. },
  12653. resizable: true
  12654. });
  12655. }
  12656. }
  12657. },
  12658. getFilterSpec: function() {
  12659. var filterSpec = [];
  12660. _.forEach(this.contentListFilterItems, function(item) {
  12661. // note: assumption that there's a message with key the same as the item
  12662. filterSpec.push({
  12663. name: item,
  12664. label: item.displayLabel || StringResource.get(item),
  12665. value: item
  12666. });
  12667. });
  12668. return filterSpec;
  12669. },
  12670. getSortSpec: function() {
  12671. return {
  12672. sortBy: {
  12673. name: 'name',
  12674. modificationTime: 'modificationTime'
  12675. },
  12676. order: {
  12677. sortedAscending: 'asc',
  12678. sortedDescending: 'desc'
  12679. }
  12680. };
  12681. },
  12682. getSortMappingSpec: function() {
  12683. return {
  12684. name: ['groupByFolder', 'name'],
  12685. modificationTime: ['groupByFolder', 'modificationTime'],
  12686. type: ['groupByType', 'name']
  12687. };
  12688. },
  12689. commonDataManipulationCallback: function(rawData, sortIndexes) {
  12690. if (sortIndexes === null) {
  12691. return;
  12692. }
  12693. rawData.data.forEach(function(data) {
  12694. // Add a couple of calculated fields 'groupByFolder' and 'groupByType' based on the 'type' value
  12695. var dataType = UIHelper.getDisplayType(data);
  12696. if (UIHelper.isContainer(dataType)) {
  12697. data.groupByFolder = sortIndexes.folders;
  12698. if (UIHelper.isGroup(dataType, 'packages')) {
  12699. data.groupByType = sortIndexes.packages;
  12700. } else {
  12701. data.groupByType = data.groupByFolder;
  12702. }
  12703. } else {
  12704. // Anything else
  12705. data.groupByFolder = sortIndexes.others;
  12706. // For Type sort
  12707. if (UIHelper.isGroup(dataType, 'report')) {
  12708. data.groupByType = sortIndexes.reports;
  12709. } else if (UIHelper.isGroup(dataType, 'dashboard')) {
  12710. data.groupByType = sortIndexes.dashboards;
  12711. } else if (UIHelper.isGroup(dataType, 'data')) {
  12712. data.groupByType = sortIndexes.data;
  12713. } else if (UIHelper.isGroup(dataType, 'exploration')) {
  12714. data.groupByType = sortIndexes.explorations;
  12715. } else if (UIHelper.isGroup(dataType, 'stories')) {
  12716. data.groupByType = sortIndexes.stories;
  12717. } else {
  12718. // Anything else
  12719. data.groupByType = sortIndexes.others;
  12720. }
  12721. }
  12722. });
  12723. },
  12724. getGroupByColumnAPI: function() {
  12725. return {
  12726. columnIndex: this.GROUP_BY_TYPE_COLUMN_INDEX,
  12727. getGroupName: function(group) {
  12728. var msgKey = _.find(Object.keys(this.contentListSortIndexes), function(sortIndex) {
  12729. return this.contentListSortIndexes[sortIndex] === group;
  12730. }.bind(this));
  12731. return msgKey && StringResource.get(msgKey) || group;
  12732. }.bind(this),
  12733. shouldGroup: function(api) {
  12734. var sortInfo = api.order();
  12735. return sortInfo && sortInfo[0] && sortInfo[0][0] === this.GROUP_BY_TYPE_COLUMN_INDEX;
  12736. }.bind(this)
  12737. };
  12738. },
  12739. getNewItemSpec: function() {
  12740. var types = [];
  12741. return new Promise(function(resolve){
  12742. var userProfileSettings = this.glassContext.services.userProfile && this.glassContext.services.userProfile.userProfileSettings;
  12743. var allowCreateURL = !(userProfileSettings &&
  12744. userProfileSettings.ui_excludedFeatures &&
  12745. userProfileSettings.ui_excludedFeatures.ids &&
  12746. userProfileSettings.ui_excludedFeatures.ids.indexOf('com.ibm.bi.contentApps.URL') >= 0);
  12747. var allowNewFolder = !(userProfileSettings &&
  12748. userProfileSettings.ui_excludedFeatures &&
  12749. userProfileSettings.ui_excludedFeatures.ids &&
  12750. userProfileSettings.ui_excludedFeatures.ids.indexOf('com.ibm.bi.contentApps.Folder') >= 0);
  12751. var inTeamContent = this.ancestors && this.ancestors[0].id === '.public_folders';
  12752. if (allowNewFolder || !inTeamContent) {
  12753. types.push({
  12754. type: 'folder'
  12755. });
  12756. }
  12757. if (allowCreateURL) {
  12758. types.push({
  12759. type: 'URL'
  12760. });
  12761. }
  12762. if (this.canUploadFiles() && this.allowUploadFiles){
  12763. types.push({ type: 'fileUpload' });
  12764. }
  12765. resolve(types);
  12766. }.bind(this));
  12767. },
  12768. showNewURL: function() {
  12769. if (!this._newURLOpen) {
  12770. this.toggleNewURLMode();
  12771. }
  12772. this.newURLSlideout = this.glassContext.appController.showSlideOut({
  12773. label: StringResource.get('newURLLabel'),
  12774. position: this.slideout ? null : 'right',
  12775. parent: this.slideout,
  12776. width: '400',
  12777. enableTabLooping: true,
  12778. onHide: function() {
  12779. if (this._newURLOpen) {
  12780. this.toggleNewURLMode();
  12781. }
  12782. if (this.newURLSlideout && this.newURLSlideout.contentView && this.newURLSlideout.contentView.onHide) {
  12783. this.newURLSlideout.contentView.onHide().then(function() {
  12784. this.newURLSlideout.hide();
  12785. }.bind(this));
  12786. } else {
  12787. this.newURLSlideout.hide();
  12788. }
  12789. }.bind(this),
  12790. content: {
  12791. module: AddURLView,
  12792. view: this,
  12793. glassContext: this.glassContext,
  12794. listControl: this._listControl
  12795. }
  12796. });
  12797. },
  12798. getFileUploader: function() {
  12799. if (!this.fUploaderPromise ) {
  12800. this.fUploaderPromise = this.glassContext.getSvc('.FileUpload')
  12801. .then(function(fileUploader) {
  12802. if (fileUploader.el === undefined) {
  12803. fileUploader.el = this.glassContext.cachedPerspectives[0].currentContentView.el;
  12804. fileUploader.container = document.createElement('div');
  12805. }
  12806. return fileUploader;
  12807. }.bind(this))
  12808. .catch(function(err) {
  12809. // display the error and continue
  12810. this.glassContext.appController.showErrorMessage(err);
  12811. return null;
  12812. }.bind(this));
  12813. }
  12814. return this.fUploaderPromise;
  12815. },
  12816. getSearchPath: function() {
  12817. var options = {
  12818. url: this.selfUrl,
  12819. dataType: 'json',
  12820. type: 'GET',
  12821. data: {
  12822. fields: 'searchPath'
  12823. }
  12824. };
  12825. return this.glassContext.getCoreSvc('.Ajax').ajax(options)
  12826. .then(function(response) {
  12827. this.parentObj = response.data.data[0];
  12828. if ((this.selfUrl.indexOf(MY_FOLDERS) > -1)) {
  12829. this.parentObj.searchPath = undefined;
  12830. }
  12831. }.bind(this))
  12832. .catch(function(err) {
  12833. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  12834. throw err;
  12835. }.bind(this));
  12836. },
  12837. uploadFile: function() {
  12838. if (this.canUploadFiles() && this.allowUploadFiles){
  12839. return this.getFileUploader().then(function(fileUploader) {
  12840. var fileDestination;
  12841. if ( this.parentObj && !this.parentObj.searchPath && this.selfUrl.indexOf(MY_FOLDERS) > -1 ) {
  12842. fileDestination = MY_FOLDERS;
  12843. fileUploader.showFilePicker(null, null, null, { destination: fileDestination });
  12844. } else if (!this.parentObj || !this.parentObj.searchPath) {
  12845. return this.getSearchPath().then(function() {
  12846. fileDestination = this.parentObj.searchPath || MY_FOLDERS;
  12847. fileUploader.showFilePicker(null, null, null, { destination: fileDestination });
  12848. }.bind(this));
  12849. } else {
  12850. fileDestination = this.parentObj.searchPath || MY_FOLDERS;
  12851. fileUploader.showFilePicker(null, null, null, { destination: fileDestination });
  12852. }
  12853. }.bind(this));
  12854. } else {
  12855. return Promise.resolve();
  12856. }
  12857. },
  12858. canUploadFiles: function() {
  12859. return this.glassContext.hasCapability('canUploadFiles');
  12860. },
  12861. createNewItem: function(type) {
  12862. if (type === 'folder') {
  12863. this._addFolder();
  12864. } else if (type === 'URL') {
  12865. this.showNewURL();
  12866. } else if (type === 'fileUpload') {
  12867. this.uploadFile();
  12868. } else {
  12869. this.logger.warn('Attempting to create unsupported item: ' + type);
  12870. }
  12871. },
  12872. _focus: function() {
  12873. this.$el.focus();
  12874. }
  12875. });
  12876. return CABaseContentView;
  12877. });
  12878. /*
  12879. *+------------------------------------------------------------------------+
  12880. *| Licensed Materials - Property of IBM
  12881. *| IBM Cognos Products: Content Explorer
  12882. *| (C) Copyright IBM Corp. 2015, 2018
  12883. *|
  12884. *| US Government Users Restricted Rights - Use, duplication or disclosure
  12885. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  12886. *+------------------------------------------------------------------------+
  12887. */
  12888. define('bi/content_apps/LegacyCATeamFoldersView',[
  12889. './CABaseContentView',
  12890. 'bacontentnav/utils/ContentStoreObject',
  12891. 'bacontentnav/utils/ContentServiceUrls',
  12892. 'bacontentnav/nls/StringResource'
  12893. ], function(CABaseContentView, ContentStoreObject, ContentServiceUrls, StringResource) {
  12894. 'use strict';
  12895. var CATeamFoldersView = CABaseContentView.extend({
  12896. stateId: 'TeamFoldersView',
  12897. GROUP_BY_TYPE_COLUMN_INDEX: 4,
  12898. init: function() {
  12899. this.showParentPropertiesButton = true;
  12900. /*eslint no-unused-vars: 0*/
  12901. CATeamFoldersView.inherited('init', this, arguments);
  12902. this.addURLParameters({
  12903. 'fields': 'tenantID'
  12904. });
  12905. this.filterMenuNamePrefix = 'TEAMCONTENT_';
  12906. this.emptyIcon = '#ba_content_nav-shared_64';
  12907. this.dataManipulationCallback = this.commonDataManipulationCallback;
  12908. },
  12909. _getDefaultRequestURL: function() {
  12910. return ContentServiceUrls.getPublicFoldersURL() + '/items';
  12911. },
  12912. _getDefaultSelfURL: function() {
  12913. return ContentServiceUrls.getPublicFoldersURL();
  12914. },
  12915. _getColumnSpecification: function() {
  12916. var columnSpecs = [{
  12917. 'type': 'Icon',
  12918. 'accessibleLabel': StringResource.get('itemType')
  12919. }];
  12920. var nameProps = {
  12921. 'type': 'MultipleProperties',
  12922. 'orientation': 'horizontal',
  12923. 'items': [{
  12924. 'type': 'Time',
  12925. 'displayInline': true,
  12926. 'propertyName': ContentStoreObject.MODIFICATION_TIME
  12927. }]
  12928. };
  12929. if (this._showTenantInfo()) {
  12930. nameProps.items.push({
  12931. 'type': 'Tenant',
  12932. 'propertyName': ContentStoreObject.TENANT_NAME,
  12933. 'showAsActiveLink': false
  12934. });
  12935. }
  12936. columnSpecs.push({
  12937. 'type': 'MultipleProperties',
  12938. 'orientation': 'vertical',
  12939. 'items': [{
  12940. 'type': 'Name'
  12941. },
  12942. nameProps
  12943. ]
  12944. });
  12945. // There is a invisible column for ModifiedTime along with Name.
  12946. // This second 'hidden' column is required to allow DataTable to sort on ModifiedTime.
  12947. columnSpecs.push({
  12948. 'type': 'Time',
  12949. 'propertyName': ContentStoreObject.MODIFICATION_TIME,
  12950. 'visible': false
  12951. });
  12952. // Here is another invisible column groupByFolder for the calculated grouping value
  12953. columnSpecs.push({
  12954. 'type': 'Text',
  12955. 'propertyName': 'groupByFolder',
  12956. 'visible': false
  12957. });
  12958. // Here is another invisible column groupByType for the calculated grouping value
  12959. columnSpecs.push({
  12960. 'type': 'Text',
  12961. 'propertyName': 'groupByType',
  12962. 'visible': false
  12963. });
  12964. if (this._showTenantInfo()) {
  12965. // There is an invisible column for Tenant along with Name.
  12966. // This second 'hidden' column is required to allow DataTable to sort on Tenant.
  12967. columnSpecs.push({
  12968. 'type': 'Tenant',
  12969. 'propertyName': ContentStoreObject.TENANT_NAME,
  12970. 'visible': false
  12971. });
  12972. }
  12973. columnSpecs.push({
  12974. 'type': 'ContextMenu'
  12975. });
  12976. return columnSpecs;
  12977. },
  12978. getSortSpec: function() {
  12979. var sortSpec = CATeamFoldersView.inherited('getSortSpec', this, arguments);
  12980. if (this._showTenantInfo()) {
  12981. sortSpec.sortBy.tenant = 'tenantName';
  12982. }
  12983. // for Type sort
  12984. sortSpec.sortBy.type = 'type';
  12985. return sortSpec;
  12986. },
  12987. _showTenantInfo: function() {
  12988. var ups = this.glassContext.getCoreSvc('.UserProfile');
  12989. return ups.tenants && ups.tenants.length > 0;
  12990. },
  12991. getDefaultSort: function() {
  12992. return [
  12993. [3, 'asc'],
  12994. [1, 'asc']
  12995. ];
  12996. }
  12997. });
  12998. return CATeamFoldersView;
  12999. });
  13000. /*
  13001. *+------------------------------------------------------------------------+
  13002. *| Licensed Materials - Property of IBM
  13003. *| IBM Cognos Products: Content Explorer
  13004. *| (C) Copyright IBM Corp. 2015, 2018
  13005. *|
  13006. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13007. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13008. *+------------------------------------------------------------------------+
  13009. */
  13010. define('bi/content_apps/LegacyCAMyContentView',[
  13011. './CABaseContentView',
  13012. 'bacontentnav/utils/ContentStoreObject',
  13013. 'bacontentnav/utils/ContentServiceUrls',
  13014. 'bacontentnav/nls/StringResource'
  13015. ], function(CABaseContentView, ContentStoreObject, ContentServiceUrls, StringResource) {
  13016. 'use strict';
  13017. var LegacyCAMyContentView = CABaseContentView.extend({
  13018. stateId: 'CAMyContentView',
  13019. GROUP_BY_TYPE_COLUMN_INDEX: 4,
  13020. init: function() {
  13021. LegacyCAMyContentView.inherited('init', this, arguments);
  13022. this.filterMenuNamePrefix = 'MYCONTENT_';
  13023. this.emptyIcon = '#ba_content_nav-personal_64';
  13024. this.dataManipulationCallback = this.commonDataManipulationCallback;
  13025. },
  13026. _getDefaultRequestURL: function() {
  13027. return ContentServiceUrls.getMyFoldersURL() + '/items';
  13028. },
  13029. _getDefaultSelfURL: function() {
  13030. return ContentServiceUrls.getMyFoldersURL();
  13031. },
  13032. getRootAncestor: function() {
  13033. return ContentStoreObject.getRootMyFoldersAncestors();
  13034. },
  13035. _getColumnSpecification: function() {
  13036. var columnSpecs = [{
  13037. 'type': 'Icon',
  13038. 'accessibleLabel': StringResource.get('itemType')
  13039. }];
  13040. columnSpecs.push({
  13041. 'type': 'MultipleProperties',
  13042. 'orientation': 'vertical',
  13043. 'items': [{
  13044. 'type': 'Name'
  13045. //'scope': 'row'
  13046. }, {
  13047. 'type': 'Time',
  13048. 'displayInline': true,
  13049. 'propertyName': ContentStoreObject.MODIFICATION_TIME
  13050. }]
  13051. });
  13052. columnSpecs.push({
  13053. 'type': 'Time',
  13054. 'propertyName': ContentStoreObject.MODIFICATION_TIME,
  13055. 'visible': false
  13056. });
  13057. // Here is another invisible column groupByFolder for the calculated grouping value
  13058. columnSpecs.push({
  13059. 'type': 'Text',
  13060. 'propertyName': 'groupByFolder',
  13061. 'visible': false
  13062. });
  13063. // Here is another invisible column groupByType for the calculated grouping value
  13064. columnSpecs.push({
  13065. 'type': 'Text',
  13066. 'propertyName': 'groupByType',
  13067. 'visible': false
  13068. });
  13069. columnSpecs.push({
  13070. 'type': 'ContextMenu'
  13071. });
  13072. return columnSpecs;
  13073. },
  13074. getSortSpec: function() {
  13075. var sortSpec = LegacyCAMyContentView.inherited('getSortSpec', this, arguments);
  13076. // For Type sort
  13077. sortSpec.sortBy.type = 'type';
  13078. return sortSpec;
  13079. },
  13080. getDefaultSort: function() {
  13081. return [
  13082. [3, 'asc'],
  13083. [1, 'asc']
  13084. ];
  13085. }
  13086. });
  13087. return LegacyCAMyContentView;
  13088. });
  13089. /**
  13090. * Licensed Materials - Property of IBM
  13091. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014
  13092. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  13093. */
  13094. define('bacontentnav/lib/gemini/app/ui/toolbar_components/Label',[ 'jquery', '../../util/View', 'underscore' ], function($, View, _) {
  13095. var Label = null;
  13096. /**
  13097. * Represents a drop down menu that can be added to an app bar
  13098. */
  13099. Label = View.extend({
  13100. baseClass: 'toolbar',
  13101. /**
  13102. * Creates a Label item
  13103. *
  13104. * @param spec -
  13105. * The menu item spec
  13106. * @param root -
  13107. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  13108. */
  13109. init: function(spec) {
  13110. _.extend(this, spec);
  13111. this._initLabel();
  13112. Label.inherited('init', this, arguments);
  13113. },
  13114. /**
  13115. * Draws the Label
  13116. */
  13117. render: function() {
  13118. this.$el
  13119. .empty()
  13120. .addClass(this.baseClass + 'InactiveItem')
  13121. .attr('id', this.viewId);
  13122. this._updateLabel();
  13123. if (this.style) {
  13124. this.$el.addClass(this.style);
  13125. }
  13126. if (this.isStatusLabel) {
  13127. this.$el.attr('role', 'status');
  13128. }
  13129. if (this.editable) {
  13130. this.$el.attr('tabindex','0').inlineEditor(this.changedAction, {
  13131. style: {width: 'auto'},
  13132. noEmptyText: true
  13133. });
  13134. }
  13135. return this;
  13136. },
  13137. _initLabel: function() {
  13138. //If label is a string, simply render this string statically,
  13139. //otherwise, use _getLabel and _updateLabel to keep the UI and
  13140. //model in synch.
  13141. if($.type(this.label) === 'object') {
  13142. this._getLabel = this.label.get;
  13143. this.label.onChange(this._updateLabel, this);
  13144. }
  13145. },
  13146. _getLabel: function() {
  13147. return this.label;
  13148. },
  13149. _updateLabel: function() {
  13150. this.text(this._getLabel());
  13151. },
  13152. /**
  13153. * Changes the text of the label
  13154. */
  13155. text: function(value) {
  13156. this.$el.text(value);
  13157. }
  13158. });
  13159. return Label;
  13160. });
  13161. /*
  13162. *+------------------------------------------------------------------------+
  13163. *| Licensed Materials - Property of IBM
  13164. *| IBM Cognos Products: Content Explorer
  13165. *| (C) Copyright IBM Corp. 2015, 2016
  13166. *|
  13167. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13168. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13169. *+------------------------------------------------------------------------+
  13170. */
  13171. define('bacontentnav/common/ui/EllipsisLabel',[
  13172. '../../lib/gemini/app/ui/toolbar_components/Label',
  13173. '../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  13174. 'underscore'
  13175. ],
  13176. function(Label, ContentFormatter, _) {
  13177. 'use strict';
  13178. var EllipsisLabel = Label.extend({
  13179. text: function(value) {
  13180. this.$el.text(_.unescape(value));
  13181. if (this.style) {
  13182. this.$el.addClass(this.style);
  13183. }
  13184. ContentFormatter.middleShortenString(this.$el[0]);
  13185. }
  13186. });
  13187. return EllipsisLabel;
  13188. });
  13189. /*
  13190. *+------------------------------------------------------------------------+
  13191. *| Licensed Materials - Property of IBM
  13192. *| IBM Cognos Products: Content Explorer
  13193. *| (C) Copyright IBM Corp. 2017, 2018
  13194. *|
  13195. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13196. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13197. *+------------------------------------------------------------------------+
  13198. */
  13199. define('bacontentnav/MRUView',[
  13200. './common/BaseContentWideView',
  13201. './common/ui/EllipsisLabel',
  13202. './utils/ContentServiceUrls',
  13203. './nls/StringResource'
  13204. ], function(
  13205. BaseContentWideView, EllipsisLabel, ContentServiceUrls, StringResource) {
  13206. 'use strict';
  13207. var MRUView = BaseContentWideView.extend({
  13208. stateId: 'MRUView',
  13209. requiresAssetVerification: true,
  13210. init: function(options) {
  13211. void(options);
  13212. MRUView.inherited('init', this, arguments);
  13213. this.filterMenuNamePrefix = 'MRU_';
  13214. this.emptyIcon = '#ba_content_nav-time_64';
  13215. },
  13216. _getDefaultRequestURL: function() {
  13217. return ContentServiceUrls.getMRUURL();
  13218. },
  13219. _getModuleName: function() {
  13220. return 'bi/content_apps/MRUView';
  13221. },
  13222. contentbarItems: function() {
  13223. return [{
  13224. 'name': 'nameLabel',
  13225. 'position': 'leading',
  13226. 'style': 'nameLabel',
  13227. 'module': EllipsisLabel,
  13228. 'label': StringResource.get('recentlyViewed')
  13229. }];
  13230. },
  13231. renderContent: function() {
  13232. return this.glassContext.getSvc('.Content')
  13233. .then(function(contentSvc){
  13234. this._contentSvc = contentSvc;
  13235. return MRUView.inherited('renderContent', this, arguments);
  13236. }.bind(this));
  13237. },
  13238. getListControlOptions: function() {
  13239. return {
  13240. 'ajaxProp': '',
  13241. 'emptyFolderString': StringResource.get('emptyRecentList'),
  13242. 'showEmptyNewFolderButton': false,
  13243. 'rowLimit': this._contentSvc.getMRUMaxSize(),
  13244. 'getJSONDataCallback': this._contentSvc.getMRUList.bind(this._contentSvc)
  13245. };
  13246. },
  13247. getDefaultSort: function() {
  13248. return [];
  13249. },
  13250. _getColumnSpecification: function() {
  13251. return [{
  13252. 'type': 'Icon'
  13253. }, {
  13254. 'type': 'MultipleProperties',
  13255. 'items': [{
  13256. 'type': 'Name'
  13257. }, {
  13258. 'type': 'Text',
  13259. 'propertyName': 'formatedPath',
  13260. 'clickCallback': this.openSlideoutView.bind(this),
  13261. 'showAsActiveLink': false
  13262. }]
  13263. }, {
  13264. 'type': 'ContextMenu'
  13265. }];
  13266. }
  13267. });
  13268. return MRUView;
  13269. });
  13270. /*
  13271. *+------------------------------------------------------------------------+
  13272. *| Licensed Materials - Property of IBM
  13273. *| IBM Cognos Products: Content Explorer
  13274. *| (C) Copyright IBM Corp. 2017, 2018
  13275. *|
  13276. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13277. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13278. *+------------------------------------------------------------------------+
  13279. */
  13280. define('bi/content_apps/CAMRUView',[
  13281. 'bacontentnav/MRUView',
  13282. 'bacontentnav/nls/StringResource',
  13283. 'bacontentnav/utils/ContentStoreObject',
  13284. './PropertiesPageView'
  13285. ], function(
  13286. MRUView, StringResource, ContentStoreObject, PropertiesPageView) {
  13287. 'use strict';
  13288. var CAMRUView = MRUView.extend({
  13289. stateId: 'CAMRUView',
  13290. init: function() {
  13291. CAMRUView.inherited('init', this, arguments);
  13292. },
  13293. showProperties: function(objectInformation) {
  13294. if (!this._propertiesOpen) {
  13295. this.togglePropertiesMode();
  13296. }
  13297. this.propertiesSlideout = this.glassContext.appController.showSlideOut({
  13298. 'label': StringResource.get('properties', {
  13299. 'objectName': objectInformation.defaultName
  13300. }),
  13301. 'position': this.slideout ? null : 'right',
  13302. 'parent': this.slideout,
  13303. 'width': '400',
  13304. 'enableTabLooping': true,
  13305. 'onHide': function() {
  13306. if (this._propertiesOpen) {
  13307. this.togglePropertiesMode();
  13308. }
  13309. if (this.propertiesSlideout && this.propertiesSlideout.contentView) {
  13310. this.propertiesSlideout.contentView.onHide().then(function() {
  13311. //remove propertiesPageView
  13312. this.propertiesSlideout.hide();
  13313. }.bind(this));
  13314. }
  13315. }.bind(this),
  13316. 'content': {
  13317. 'module': PropertiesPageView,
  13318. 'parentView': this,
  13319. 'objectInformation': objectInformation,
  13320. 'glassContext': this.glassContext
  13321. },
  13322. 'resizable': true
  13323. });
  13324. }
  13325. });
  13326. return CAMRUView;
  13327. });
  13328. /*
  13329. *+------------------------------------------------------------------------+
  13330. *| Licensed Materials - Property of IBM
  13331. *| IBM Cognos Products: Content Explorer
  13332. *| (C) Copyright IBM Corp. 2015, 2018
  13333. *|
  13334. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13335. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13336. *+------------------------------------------------------------------------+
  13337. */
  13338. define('bacontentnav/search/SearchBar',[
  13339. 'jquery',
  13340. 'underscore',
  13341. '../lib/@waca/core-client/js/core-client/ui/View',
  13342. '../lib/@waca/core-client/js/core-client/utils/Utils',
  13343. '../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  13344. '../nls/StringResource',
  13345. 'jquery-ui'
  13346. ], function($, _, View, Utils, BidiUtil, StringResources) {
  13347. var SearchBar = null;
  13348. /**
  13349. * Represents a search bar that can be added to an app bar
  13350. */
  13351. SearchBar = View.extend({
  13352. events: {
  13353. 'clicktap': 'action'
  13354. },
  13355. baseClass: 'toolbar',
  13356. getSuggestUrl: 'v1/suggest/cm',
  13357. /**
  13358. * Creates a search bar
  13359. */
  13360. init: function(spec) {
  13361. _.extend(this, spec);
  13362. SearchBar.inherited('init', this, arguments);
  13363. this.searchBarCutDetected = false;
  13364. // search input
  13365. this.$input = $('<input class="searchinput">')
  13366. .attr({
  13367. 'type': 'search',
  13368. 'value': this.value,
  13369. 'placeholder': this.label,
  13370. 'title': this.label,
  13371. 'maxlength': 256,
  13372. 'role': 'combobox',
  13373. 'aria-autocomplete': 'list'
  13374. })
  13375. .on('search', this.search.bind(this))
  13376. .on('change', this.updateButtonItems.bind(this))
  13377. .bind('cut', function() {
  13378. setTimeout(function() {
  13379. this.reinitializeSearchBar();
  13380. }.bind(this));
  13381. }.bind(this))
  13382. .keyup(function(e) {
  13383. if (e.which === 13) {
  13384. this.search(e);
  13385. } else if (e.which !== 9 && e.which !== 16) {
  13386. // if not tab/shift
  13387. this.updateButtonItems();
  13388. }
  13389. setTimeout(function() {
  13390. if (!this.$input.val() && (!this.searchBarCutDetected)) {
  13391. this.clear();
  13392. }
  13393. }.bind(this));
  13394. }.bind(this))
  13395. .autocomplete({
  13396. source: function(request, srcresponse) {
  13397. var _term = request.term ? request.term.trim() : '';
  13398. if (_term.length > 0) {
  13399. var params = {
  13400. filter: 'type|' + this.view.defaultTypes.join('|'),
  13401. term: request.term,
  13402. hide_internal: 'all'
  13403. };
  13404. this.glassContext.getCoreSvc('.Ajax').ajax({
  13405. url: this.getSuggestUrl + '?' + $.param(params, true)
  13406. })
  13407. .then(function(response) {
  13408. srcresponse(response.data.results);
  13409. });
  13410. }
  13411. }.bind(this),
  13412. open: function() {
  13413. // Note: This is temporary code to bring the suggestions list box to the front
  13414. // This should be changed at the css level.
  13415. this.$input.autocomplete('widget').addClass('search-autocomplete');
  13416. this.$input.autocomplete('widget').find('li')
  13417. .on('clicktap', function(event) {
  13418. event.stopPropagation();
  13419. this.setSearchString($(event.target).text());
  13420. this.search(event);
  13421. }.bind(this))
  13422. .each(function() {
  13423. this.dir = BidiUtil.resolveBaseTextDir(this.innerHTML);
  13424. });
  13425. return false;
  13426. }.bind(this)
  13427. });
  13428. BidiUtil.initElementForBidi(this.$input[0]);
  13429. // search button
  13430. this.$searchButton = $('<button class="s4h" disabled/>')
  13431. .attr({
  13432. 'type': 'button',
  13433. 'title': StringResources.get('search')
  13434. });
  13435. Utils.setIcon(this.$searchButton, 'common-search');
  13436. // clear search button
  13437. this.$clearSearchButton = $('<button class="s4hReset" />')
  13438. .attr({
  13439. 'type': 'reset',
  13440. 'title': StringResources.get('clear')
  13441. })
  13442. .on('clicktap', this.clear.bind(this));
  13443. Utils.setIcon(this.$clearSearchButton, 'common-close-cancel-error');
  13444. },
  13445. /**
  13446. * Draws the Search bar
  13447. */
  13448. render: function() {
  13449. this.$el
  13450. .empty()
  13451. .addClass('searchbar appbarIcon appbarItem filled s4hBar')
  13452. .append(this.$searchButton, [this.$input, this.$clearSearchButton]);
  13453. if (!this.value) {
  13454. this.$el.removeClass('filled');
  13455. }
  13456. return Promise.resolve(this);
  13457. },
  13458. show: function(noFocus) {
  13459. if (this.isHidden()) {
  13460. this.$input.fadeIn('fast');
  13461. this.$searchButton.fadeIn('fast');
  13462. this.$clearSearchButton.fadeIn('fast');
  13463. this.$el.slideDown('fast');
  13464. if (!noFocus) {
  13465. this.setFocus();
  13466. this.$input.select();
  13467. }
  13468. }
  13469. },
  13470. search: function(e) {
  13471. this.searchBarCutDetected = false;
  13472. var searchString = this.getSearchString();
  13473. if (searchString) {
  13474. this.$input.blur();
  13475. this.view.searchTerm = searchString;
  13476. this.view.execSearch(true);
  13477. if (e) {
  13478. e.preventDefault();
  13479. }
  13480. }
  13481. },
  13482. resetState: function() {
  13483. this.view.resetState();
  13484. },
  13485. clear: function() {
  13486. this.view.clearView();
  13487. this.showHideClearSearchButton();
  13488. this.setFocus();
  13489. },
  13490. setSearchString: function(searchString) {
  13491. var str = _.isString(searchString) ? searchString : '';
  13492. if (this.getSearchString() !== str) {
  13493. this.$input.val(str);
  13494. }
  13495. this.showHideClearSearchButton();
  13496. },
  13497. getSearchString: function() {
  13498. return this.$input.val().trim();
  13499. },
  13500. hide: function(preserveInput) {
  13501. if (!this.$el.is(':hidden')) {
  13502. this.$el.slideUp('fast');
  13503. this.$input
  13504. .fadeOut('fast')
  13505. .blur();
  13506. if (!preserveInput) {
  13507. this.$input.val('');
  13508. }
  13509. this.$searchButton.fadeOut('fast');
  13510. this.$clearSearchButton.fadeOut('fast');
  13511. }
  13512. },
  13513. isHidden: function() {
  13514. return this.$el.is(':hidden');
  13515. },
  13516. showHideClearSearchButton: function() {
  13517. if (this.$input.val()) {
  13518. this.$el.addClass('filled');
  13519. } else {
  13520. this.$el.removeClass('filled');
  13521. }
  13522. },
  13523. setFocus: function() {
  13524. this.$input.focus();
  13525. },
  13526. /**
  13527. * Updates the button state for filters/etc.
  13528. */
  13529. updateButtonItems: function() {
  13530. this.view.showHideContentBarItems();
  13531. this.showHideClearSearchButton();
  13532. },
  13533. reinitializeSearchBar: function() {
  13534. if (!this.$input.val()) {
  13535. this.clear();
  13536. this.searchBarCutDetected = true;
  13537. }
  13538. }
  13539. });
  13540. return SearchBar;
  13541. });
  13542. /*
  13543. *+------------------------------------------------------------------------+
  13544. *| Licensed Materials - Property of IBM
  13545. *| IBM Cognos Products: Content Explorer
  13546. *| (C) Copyright IBM Corp. 2015, 2018
  13547. *|
  13548. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13549. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13550. *+------------------------------------------------------------------------+
  13551. */
  13552. define('bacontentnav/search/SearchFolderView',[
  13553. '../common/BaseContentWideView',
  13554. '../utils/ContentStoreObject',
  13555. '../utils/UIHelper',
  13556. '../nls/StringResource',
  13557. 'underscore'
  13558. ], function(BaseContentWideView, ContentStoreObject, UIHelper, StringResource, _) {
  13559. 'use strict';
  13560. var SearchFolderView = BaseContentWideView.extend({
  13561. stateId: 'SearchFolderView',
  13562. emptyIcon: '#ba_content_nav-personal_64',
  13563. init: function() {
  13564. SearchFolderView.inherited('init', this, arguments);
  13565. this.contentListFacets = UIHelper.getFilterFacets(['content']);
  13566. },
  13567. getModuleName: function() {
  13568. return 'bacontentnav/search/SearchFolderView';
  13569. },
  13570. renderContent: function() {
  13571. var ancestorType = this.ancestors && this.ancestors.length > 0 && this.ancestors[0].type;
  13572. if (ancestorType === 'directory') {
  13573. this.stateId = 'MyContentView';
  13574. this.emptyIcon = '#ba_content_nav-personal_64';
  13575. } else if (ancestorType === 'content') {
  13576. this.stateId = 'TeamFoldersView';
  13577. this.emptyIcon = '#ba_content_nav-shared_64';
  13578. } else {
  13579. this.stateId = 'SearchFolderView';
  13580. }
  13581. return this.renderContentList({
  13582. 'columns': this._getColumnSpecification(),
  13583. 'url': this.url,
  13584. 'selectedRow': this.selectedRow,
  13585. 'emptyIcon': this.emptyIcon
  13586. });
  13587. },
  13588. _getColumnSpecification: function() {
  13589. var columnSpecs = [{
  13590. 'type': 'Icon',
  13591. 'accessibleLabel': StringResource.get('itemType')
  13592. }];
  13593. columnSpecs.push({
  13594. 'type': 'MultipleProperties',
  13595. 'orientation': 'vertical',
  13596. 'items': [{
  13597. 'type': 'Name'
  13598. }, {
  13599. 'type': 'Time',
  13600. 'displayInline': true,
  13601. 'propertyName': ContentStoreObject.MODIFICATION_TIME
  13602. }]
  13603. });
  13604. // This invisible spec is required for sorting/filtering purposes,
  13605. // as these functions cannot get the data from "MultipleProperties"
  13606. columnSpecs.push({
  13607. 'type': 'Time',
  13608. 'propertyName': ContentStoreObject.MODIFICATION_TIME,
  13609. 'visible': false
  13610. });
  13611. columnSpecs.push({
  13612. 'type': 'ContextMenu'
  13613. });
  13614. return columnSpecs;
  13615. },
  13616. getFilterSpec: function() {
  13617. var filterSpec = [];
  13618. _.forEach(UIHelper.getConfiguration('filter').items, function(item) {
  13619. // note: assumption that there's a message with key the same as the item
  13620. filterSpec.push({
  13621. name: item,
  13622. label: item.displayLabel || StringResource.get(item),
  13623. value: item
  13624. });
  13625. });
  13626. return filterSpec;
  13627. },
  13628. showProperties: function(objectInformation) {
  13629. if (!this.propertiesView) {
  13630. return;
  13631. }
  13632. if (!this._propertiesOpen) {
  13633. this.togglePropertiesMode();
  13634. }
  13635. this.propertiesSlideout = this.glassContext.appController.showSlideOut({
  13636. 'label': StringResource.get('properties', {
  13637. 'objectName': objectInformation.defaultName
  13638. }),
  13639. 'position': this.slideout ? null : 'right',
  13640. 'parent': this.slideout,
  13641. 'width': '400',
  13642. 'enableTabLooping': true,
  13643. 'onHide': function() {
  13644. if (this._propertiesOpen) {
  13645. this.togglePropertiesMode();
  13646. }
  13647. if (this.propertiesSlideout && this.propertiesSlideout.contentView) {
  13648. this.propertiesSlideout.contentView.onHide().then(function() {
  13649. //remove propertiesPageView
  13650. this.propertiesSlideout.hide();
  13651. }.bind(this));
  13652. }
  13653. }.bind(this),
  13654. 'content': {
  13655. 'module': this.propertiesView,
  13656. 'parentView': this,
  13657. 'objectInformation': objectInformation,
  13658. 'glassContext': this.glassContext
  13659. },
  13660. 'resizable': true
  13661. });
  13662. }
  13663. });
  13664. return SearchFolderView;
  13665. });
  13666. /*
  13667. *+------------------------------------------------------------------------+
  13668. *| Licensed Materials - Property of IBM
  13669. *| IBM Cognos Products: ba-content-nav
  13670. *| (C) Copyright IBM Corp. 2017, 2018
  13671. *|
  13672. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13673. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13674. *+------------------------------------------------------------------------+
  13675. */
  13676. define('bacontentnav/common/SearchFilterViewController',['underscore', 'moment', './FilterViewController'], function(_, Moment, FilterViewController) {
  13677. 'use strict';
  13678. /*
  13679. * This class is a sub class of FilterViewController for the search view.
  13680. */
  13681. var SearchFilterViewController = FilterViewController.extend({
  13682. /**
  13683. * Constructor
  13684. * @param options.view {string} - container's view
  13685. * @override
  13686. */
  13687. init: function(options) {
  13688. void(options);
  13689. SearchFilterViewController.inherited('init', this, arguments);
  13690. },
  13691. /**
  13692. * Sets the date for modificationTime queries
  13693. * @override
  13694. **/
  13695. setDefaultFilters: function() {
  13696. SearchFilterViewController.inherited('setDefaultFilters', this, arguments);
  13697. this.filterObject.modificationTime.today += '|true|false';
  13698. this.filterObject.modificationTime.yesterday += '|true|false';
  13699. this.filterObject.modificationTime.pastWeek += '|true|false';
  13700. this.filterObject.modificationTime.pastMonth += '|true|false';
  13701. }
  13702. });
  13703. return SearchFilterViewController;
  13704. });
  13705. /*
  13706. *+------------------------------------------------------------------------+
  13707. *| Licensed Materials - Property of IBM
  13708. *| IBM Cognos Products: Content Explorer
  13709. *| (C) Copyright IBM Corp. 2015, 2021
  13710. *|
  13711. *| US Government Users Restricted Rights - Use, duplication or disclosure
  13712. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  13713. *+------------------------------------------------------------------------+
  13714. */
  13715. define('bacontentnav/search/BaseSearchView',[
  13716. 'jquery',
  13717. 'moment-timezone',
  13718. './SearchBar',
  13719. './SearchFolderView',
  13720. '../nls/StringResource',
  13721. '../common/ContentListPageView',
  13722. '../utils/ContentStoreObject',
  13723. '../utils/UIHelper',
  13724. '../common/SearchFilterViewController',
  13725. 'underscore'
  13726. ], function($, Moment, SearchBar, SearchFolderView, StringResources, ContentListPageView, ContentStoreObject, UIHelper, SearchFilterViewController, _) {
  13727. 'use strict';
  13728. var EMPTY_SEARCH_ICON = '#ba_content_nav-search_64';
  13729. var Search = ContentListPageView.extend({
  13730. init: function(options) {
  13731. Search.inherited('init', this, arguments);
  13732. var searchConfig = UIHelper.getConfiguration('search');
  13733. this.searchURL = searchConfig.URL;
  13734. this.savedSearchURL = searchConfig.savedURL;
  13735. this.searchReturnParams = searchConfig.returnParams || '';
  13736. this.disabledActions = searchConfig.disabledActions || [];
  13737. this.defaultTypes = UIHelper.getTypes(['content']) || [];
  13738. //content service might not be set properly in ContentStoreObject
  13739. if (this.glassContext) {
  13740. ContentStoreObject.setGlassContext(this.glassContext);
  13741. }
  13742. //our filterview controller
  13743. this.filterViewController = options.filterViewController || new SearchFilterViewController({
  13744. filterSpecs: this._getColumnSpecification.bind(this),
  13745. view: this,
  13746. filterObject: UIHelper.getFilterFacets(['content']),
  13747. setResultLimit: true
  13748. });
  13749. /*
  13750. * Object containing groups being filtered against as keys
  13751. * and the filter strings to be applied as the values.
  13752. * It is modified when the user changes their facet selections, or instigates a new search,
  13753. * and is used to figure out which facets are being applied when rendering the facets view.
  13754. */
  13755. this.filterViewController.resetSelected();
  13756. /*
  13757. * Storage location of resultSetSize from the server.
  13758. */
  13759. this.resultsetSize = 0;
  13760. this.searchTerm = '';
  13761. this.savedSearchDeleteClicked = false;
  13762. this.savedSearchclicked = false;
  13763. // set up search bar
  13764. this.searchBar = new SearchBar({
  13765. 'name': 'searchInput',
  13766. 'module': SearchBar,
  13767. 'position': 'leading',
  13768. 'glassContext': this.glassContext,
  13769. 'view': this,
  13770. 'label': StringResources.get('searchAllYourData'),
  13771. 'value': ''
  13772. });
  13773. this.searchBarRendered = false;
  13774. this.on('filterState:change', this.onFilterStateChange.bind(this));
  13775. this.on('filterState:changeDate', this.onFilterStateChange.bind(this));
  13776. this.on('filterState:changeResutLimit', this.onFilterStateChange.bind(this));
  13777. },
  13778. remove: function() {
  13779. Search.inherited('remove', this, arguments);
  13780. this.off('filterState:change');
  13781. this.off('filterState:changeDate');
  13782. this.off('filterState:changeResutLimit');
  13783. },
  13784. //callback from the filter
  13785. onFilterStateChange: function() {
  13786. this._updateStroke();
  13787. this.execSearch(false);
  13788. },
  13789. /**
  13790. * @override
  13791. */
  13792. _getColumnSpecification: function() {
  13793. return this._getBaseColumnSpec();
  13794. },
  13795. /**
  13796. * @override
  13797. */
  13798. getListControlOptions: function() {
  13799. return { setFocusOnDraw:false };
  13800. },
  13801. /**
  13802. * Updates the filter button's stroke
  13803. */
  13804. _updateStroke: function() {
  13805. var svg = this.$el.find('.facetButton .svgIcon');
  13806. if (svg) {
  13807. if (this.filterViewController.isDirty()) {
  13808. UIHelper.addStroke(svg);
  13809. } else {
  13810. UIHelper.removeStroke(svg);
  13811. }
  13812. }
  13813. },
  13814. /**
  13815. * Sets the search term in the searchBar. Does not execute the search.
  13816. */
  13817. setSearchTerm: function(term) {
  13818. this.searchTerm = (_.isString(term) ? term : '').trim();
  13819. this.searchBar.setSearchString(this.searchTerm);
  13820. },
  13821. /**
  13822. * Gets the currently set search term as a string.
  13823. */
  13824. getSearchTerm: function() {
  13825. return this.searchTerm.trim();
  13826. },
  13827. setFocus: function() {
  13828. // shouldn't need this check, but...
  13829. if (_.isFunction(this.searchBar && this.searchBar.setFocus)) {
  13830. this.searchBar.setFocus();
  13831. } else {
  13832. Search.inherited('setFocus', this, arguments);
  13833. }
  13834. },
  13835. showHideContentBarItems: function() {
  13836. if (this.contentBar) {
  13837. var facetButton = this.contentBar.itemMap.facetButton.$el.find('button');
  13838. var savedSearchButton = this.contentBar.itemMap.savedSearchButton.$el.find('button');
  13839. var isDisabled = this.filterViewController.isDirty() === false && this.resultsetSize === 0;
  13840. facetButton.prop('disabled', isDisabled);
  13841. savedSearchButton.prop('disabled', isDisabled);
  13842. if (!this.filterViewController.isDirty()) {
  13843. this.filterViewController.removeFilteredClass(facetButton);
  13844. }
  13845. }
  13846. },
  13847. getViewContainerClass: function() {
  13848. return 'ContentListPageView ContentWideView SearchPageView';
  13849. },
  13850. contentbarItems: function() {
  13851. return [{
  13852. 'name': 'nameLabel',
  13853. 'module': 'bacontentnav/lib/gemini/app/ui/toolbar_components/Label',
  13854. 'className': 'searchLabel',
  13855. 'responsive': false,
  13856. 'label': StringResources.get('search')
  13857. }, {
  13858. 'name': 'savedSearchButton',
  13859. 'module': 'bacontentnav/common/ui/contentbar_components/Button',
  13860. 'position': 'trailing',
  13861. 'label': StringResources.get('saveSearch'),
  13862. 'responsive': false,
  13863. 'className': 'saveSearchButton',
  13864. 'icon': 'ba_content_nav-save_16',
  13865. 'bSVG': true,
  13866. 'disabled': true,
  13867. 'action': this.saveSearchClicked.bind(this)
  13868. }, {
  13869. 'name': 'facetButton',
  13870. 'module': 'bacontentnav/common/ui/contentbar_components/Button',
  13871. 'position': 'trailing',
  13872. 'label': StringResources.get('narrowYourSearch'),
  13873. 'responsive': false,
  13874. 'className': 'facetButton',
  13875. 'icon': 'common-filter',
  13876. 'bSVG': true,
  13877. 'disabled': true,
  13878. 'pushed': false,
  13879. 'action': this.facetClicked.bind(this)
  13880. }];
  13881. },
  13882. renderContent: function() {
  13883. return this.renderSavedSearch();
  13884. },
  13885. saveSlideoutWidth: function() {
  13886. var width = this.$el.width();
  13887. UIHelper.saveSlideoutWidth(this.id, width);
  13888. },
  13889. _calcExtraNonTableHeight: function(tableView) {
  13890. var searchbarHeight = tableView.$el.children('.SearchPageView .searchbar').outerHeight(true) || 40,
  13891. searchResultHeight = tableView.$el.find('.ca-listContainer .propertyRow').outerHeight(true) || 40;
  13892. return searchbarHeight + searchResultHeight;
  13893. },
  13894. _renderContentList: function(params, resetFacets) {
  13895. if (_.isObject(params)) {
  13896. params = '?' + $.param(params, true);
  13897. }
  13898. params = _.isString(params) ? params : '';
  13899. return this.renderContentList({
  13900. 'disableColumnHeaders': this.disableColumnHeaders,
  13901. 'columns': this._getColumnSpecification(),
  13902. 'ajaxProp': 'results',
  13903. 'showEmptyNewFolderButton': false,
  13904. 'multiSelect': false,
  13905. 'emptyFolderString': StringResources.get('searchReturnedNoResults'),
  13906. 'emptyParagraphString': StringResources.get('tryChangingSearchTerms'),
  13907. 'url': this.searchURL + params,
  13908. 'defaultSort': [],
  13909. 'emptyIcon': EMPTY_SEARCH_ICON,
  13910. 'calcExtraNonTableHeight': this._calcExtraNonTableHeight,
  13911. 'dataManipulationCallback': function(resetFacetsFlag, response) {
  13912. response.results = response.results || [];
  13913. // filter via expected display types to detect, for example, explorations as different from dashboards
  13914. var selectedDisplayTypes = this._getSelectedDisplayTypes();
  13915. if (selectedDisplayTypes.length !== 0) {
  13916. response.results = _.filter(response.results, function(result) {
  13917. return selectedDisplayTypes.indexOf(UIHelper.getDisplayType(result)) !== -1;
  13918. }.bind(this));
  13919. }
  13920. this.resultsetSize = response.results.length;
  13921. if (resetFacetsFlag) {
  13922. this.showHideContentBarItems();
  13923. }
  13924. if (response.totalResults) {
  13925. this._showSearchResultsCaption(this.resultsetSize);
  13926. }
  13927. if (this.resultsetSize === 0) {
  13928. //focus the search string
  13929. this.setFocus();
  13930. }
  13931. }.bind(this, resetFacets)
  13932. })
  13933. .catch(function(e){
  13934. //show an error
  13935. this.glassContext.appController.showToast(StringResources.get('errorWithSearch'), {
  13936. 'type': 'error',
  13937. 'preventDuplicates': false
  13938. });
  13939. //rethrow it
  13940. throw(e);
  13941. }.bind(this));
  13942. },
  13943. renderSavedSearch: function() {
  13944. var _resizeCallback = null;
  13945. return this.renderContentList({
  13946. 'disableColumnHeaders': true,
  13947. 'columns': this._getSavedSearchColumnSpecification(),
  13948. 'ajaxProp': '',
  13949. 'showEmptyNewFolderButton': false,
  13950. 'emptyFolderString': StringResources.get('haventSavedSearches'),
  13951. 'emptyParagraphString': StringResources.get('clickTheSaveButton'),
  13952. 'url': this.savedSearchURL,
  13953. 'defaultSort': [],
  13954. 'rightClickContextMenu': false,
  13955. 'multiSelect': false,
  13956. 'rowLimit': 10,
  13957. 'emptyIcon': EMPTY_SEARCH_ICON,
  13958. 'calcExtraNonTableHeight': this._calcExtraNonTableHeight,
  13959. 'resizeCallback': function() {
  13960. if (_resizeCallback) {
  13961. clearTimeout(_resizeCallback);
  13962. }
  13963. _resizeCallback = setTimeout(this.saveSlideoutWidth.bind(this), 500);
  13964. }.bind(this),
  13965. 'dataManipulationCallback': function(response) {
  13966. response.sort(function(x, y) {
  13967. var date1 = new Date(x.timestamp);
  13968. var date2 = new Date(y.timestamp);
  13969. return date2 - date1;
  13970. });
  13971. if (response.length !== 0) {
  13972. this._showSavedSearchLabel();
  13973. }
  13974. }.bind(this)
  13975. });
  13976. },
  13977. execSearch: function(resetFlag) {
  13978. if (this.getSearchTerm() && this.getSearchTerm().length > 0) {
  13979. this.removeContentList();
  13980. // do a reset if requested
  13981. if (resetFlag === true) {
  13982. this.resetState();
  13983. }
  13984. // set up search parameters, adding current filters
  13985. var params = {
  13986. 'fields': this.searchReturnParams,
  13987. results: this.filterViewController.getResultLimit(),
  13988. query: this.getSearchTerm(),
  13989. hide_internal: 'all',
  13990. filter: []
  13991. };
  13992. //filtered by time?
  13993. if (this.filterViewController.getModificationTime()) {
  13994. params.filter.push('modificationTime|' + this.filterViewController.getModificationTime());
  13995. }
  13996. //filtered by type?
  13997. if (this._getFilteredTypes().length > 0) {
  13998. params.filter.push('type|' + this._getFilteredTypes().join('|'));
  13999. }
  14000. //debounce this to ensure we don't rerender too many times
  14001. if (!this._debouncedDraw) {
  14002. this._debouncedDraw = _.debounce(
  14003. this._renderContentList.bind(this)
  14004. , 300);
  14005. }
  14006. return this._debouncedDraw(params, resetFlag);
  14007. }
  14008. },
  14009. /**
  14010. * Resets our state. Removes all filters, search parameters, etc.
  14011. */
  14012. resetState: function() {
  14013. this.resultsetSize = 0;
  14014. this.filterViewController.resetSelected();
  14015. this.showHideContentBarItems();
  14016. this._updateStroke();
  14017. },
  14018. /**
  14019. Renders and shows the content bar if it's required
  14020. **/
  14021. _renderContentBar: function() {
  14022. return this._createContentBar()
  14023. .then(function(contentBar) {
  14024. if (contentBar) {
  14025. contentBar.show();
  14026. }
  14027. return this._updateAppBar()
  14028. .then(function() {
  14029. if (!this.searchBarRendered) {
  14030. this.$el.append(this.searchBar.$el);
  14031. this.searchBar.render();
  14032. this.searchBarRendered = true;
  14033. }
  14034. return contentBar;
  14035. }.bind(this));
  14036. }.bind(this));
  14037. },
  14038. /**
  14039. * Clears out the search view. Including the state, searchterm and content list.
  14040. * @param searchTerm if provided, the search bar will be repopulated with this search string after clearing.
  14041. */
  14042. clearView: function(searchTerm) {
  14043. this.resetState();
  14044. this._updateStroke();
  14045. //will default to '' if searchTerm is undefined.
  14046. this.setSearchTerm(searchTerm);
  14047. this.removeContentList();
  14048. this.renderContent();
  14049. this.showHideContentBarItems();
  14050. },
  14051. _getBaseColumnSpec: function() {
  14052. var columns = [];
  14053. columns.push({
  14054. 'type': 'Icon'
  14055. });
  14056. var multiPropItems = [];
  14057. multiPropItems.push({
  14058. 'type': 'Name'
  14059. });
  14060. multiPropItems.push({
  14061. 'type': 'Location',
  14062. 'clickCallback': this._navigateParent.bind(this),
  14063. 'showAsActiveLink': false
  14064. });
  14065. columns.push({
  14066. 'type': 'MultipleProperties',
  14067. 'items': multiPropItems
  14068. });
  14069. columns.push({
  14070. 'type': 'ContextMenu'
  14071. });
  14072. return columns;
  14073. },
  14074. _getSavedSearchColumnSpecification: function() {
  14075. return [{
  14076. 'type': 'Text',
  14077. 'propertyName': 'name',
  14078. 'clickCallback': this._savedSearch.bind(this)
  14079. }, {
  14080. 'type': 'ClickableIcon',
  14081. 'name': 'remove',
  14082. 'a11yLabel': StringResources.get('remove'),
  14083. 'icon': 'common-close-cancel-error',
  14084. 'clickCallback': this._deleteSavedSearch.bind(this)
  14085. }];
  14086. },
  14087. _savedSearch: function(oData) {
  14088. this.setSearchTerm(oData.name);
  14089. this.execSearch(true);
  14090. },
  14091. _showSavedSearchLabel: function() {
  14092. var $savedSearchContainter = this.$el.find('.ca-listContainer');
  14093. if (!$savedSearchContainter.hasClass('savedSearch')) {
  14094. $savedSearchContainter.addClass('savedSearch').prepend('<div id="savedSearchLabel" class="propertyRow">' + StringResources.get('savedSearch') + '</div>');
  14095. }
  14096. },
  14097. _showSearchResultsCaption: function(size) {
  14098. var $savedSearchContainter = this.$el.find('.ca-listContainer');
  14099. var $searchResults = $savedSearchContainter.find('.propertyRow.searchResultsCaption');
  14100. if (size !== 0) {
  14101. if ($searchResults.length == 0) {
  14102. $savedSearchContainter.addClass('searchResults').prepend('<div class="propertyRow searchResultsCaption">' + size + ' ' + StringResources.get('results') + '</div>');
  14103. } else {
  14104. $searchResults.text(size + ' ' + StringResources.get('results'));
  14105. }
  14106. }
  14107. },
  14108. _deleteSavedSearch: function(oData) {
  14109. if (!this.savedSearchDeleteClicked) {
  14110. this.savedSearchDeleteClicked = true;
  14111. var options = {
  14112. 'dataType': 'json',
  14113. 'type': 'DELETE',
  14114. 'url': oData.url
  14115. };
  14116. return this.glassContext.getCoreSvc('.Ajax').ajax(options)
  14117. .then(function() {
  14118. this.savedSearchDeleteClicked = false;
  14119. this.refresh();
  14120. this.glassContext.appController.showToast(StringResources.get('searchWasDeleted'), {
  14121. 'type': 'success',
  14122. 'preventDuplicates': false
  14123. });
  14124. }.bind(this))
  14125. .catch(function(err) {
  14126. this.savedSearchDeleteClicked = false;
  14127. this.glassContext.appController.showToast(StringResources.get('searchWasntDeleted'), {
  14128. 'type': 'error',
  14129. 'preventDuplicates': false
  14130. });
  14131. return Promise.reject(err);
  14132. }.bind(this));
  14133. } else {
  14134. return Promise.resolve();
  14135. }
  14136. },
  14137. _showSlideOut: function(options) {
  14138. this.glassContext.appController.showSlideOut({
  14139. parent: this.slideout,
  14140. label: ContentStoreObject.getName(options.oData),
  14141. position: 'left',
  14142. width: options.width || '400',
  14143. closeSlideouts: true,
  14144. content: {
  14145. showBreadcrumbs: true,
  14146. showFilter: true,
  14147. showAddFolder: false,
  14148. showNewItem: true,
  14149. module: SearchFolderView,
  14150. url: options.selfLink + '/items',
  14151. selfUrl: options.selfLink,
  14152. selectedRow: options.selectedRow,
  14153. ancestors: options.ancestors,
  14154. propertiesView: this.propertiesView,
  14155. getNewItemSpec: function() { return Promise.resolve([ { type: 'folder' } ]); },
  14156. createNewItem: function() { this._addFolder(); }
  14157. },
  14158. resizable: true
  14159. });
  14160. },
  14161. navigate: function(oData) {
  14162. var selfLink = ContentStoreObject.getSelfLink(oData);
  14163. var ancestors = [];
  14164. for (var i in oData.ancestors) {
  14165. ancestors.push(ContentStoreObject.buildAncestorEntry(oData.ancestors[i]));
  14166. }
  14167. ancestors.push(ContentStoreObject.buildAncestorEntry(oData));
  14168. this._showSlideOut({
  14169. oData: oData,
  14170. width: '576',
  14171. selfLink: selfLink,
  14172. ancestors: ancestors
  14173. });
  14174. },
  14175. _navigateParent: function(oData) {
  14176. var selfLink = ContentStoreObject.getSelfLink(oData.ancestors[oData.ancestors.length - 1]);
  14177. // so _selectRow can hide properties page
  14178. this.propertiesOverride = true;
  14179. var ancestors = [];
  14180. for (var i in oData.ancestors) {
  14181. ancestors.push(ContentStoreObject.buildAncestorEntry(oData.ancestors[i]));
  14182. }
  14183. this._showSlideOut({
  14184. oData: oData,
  14185. selfLink: selfLink,
  14186. selectedRow: ['id', oData.id],
  14187. ancestors: ancestors
  14188. });
  14189. },
  14190. facetClicked: function() {
  14191. if (this.contentBar.itemMap.facetButton.pushed === false && this.contentBar.itemMap.facetButton.$el.find('button').prop('disabled') === false) {
  14192. var filterButton = this.contentBar.itemMap.facetButton.$el.find('button');
  14193. this.contentBar.itemMap.facetButton.pushed = true;
  14194. this.filterViewController.addFilteredClass(filterButton);
  14195. this.glassContext.appController.showSlideOut({
  14196. 'parent': this.slideout,
  14197. 'label': StringResources.get('narrowYourSearch'),
  14198. 'width': '200px',
  14199. 'content': {
  14200. 'module': 'bacontentnav/common/FilterView',
  14201. 'view': this,
  14202. 'searchBarController': null, //no search
  14203. 'filterController': this.filterViewController
  14204. }
  14205. }).on('hide', function() {
  14206. this.filterViewController.removeFilteredClass(filterButton);
  14207. this.contentBar.itemMap.facetButton.pushed = false;
  14208. this.setFocus();
  14209. }.bind(this));
  14210. }
  14211. },
  14212. saveSearchClicked: function() {
  14213. if (!this.savedSearchclicked) {
  14214. this.savedSearchclicked = true;
  14215. this.glassContext.getCoreSvc('.Ajax').ajax({
  14216. url: this.savedSearchURL
  14217. })
  14218. .then(this.saveSearchValidate.bind(this))
  14219. .catch(function(err) {
  14220. void(err);
  14221. this.glassContext.appController.showToast(StringResources.get('searchWasntSaved'), {
  14222. 'type': 'error',
  14223. 'preventDuplicates': false
  14224. });
  14225. this.logger.error('Could not get saved searches');
  14226. this.savedSearchclicked = false;
  14227. }.bind(this));
  14228. }
  14229. },
  14230. saveSearchValidate: function(res) {
  14231. var response = res.data;
  14232. if (response.length >= 10) {
  14233. this.glassContext.appController.showToast(StringResources.get('saveTenSearches') + ' ' + StringResources.get('deleteASearch'), {
  14234. 'type': 'warning',
  14235. 'preventDuplicates': false
  14236. });
  14237. this.savedSearchclicked = false;
  14238. } else {
  14239. var flag = true;
  14240. for (var i in response) {
  14241. if (response[i].query === this.getSearchTerm()) {
  14242. flag = false;
  14243. var options = {
  14244. 'dataType': 'json',
  14245. 'type': 'DELETE',
  14246. 'url': response[i].url
  14247. };
  14248. this.glassContext.getCoreSvc('.Ajax').ajax(options)
  14249. .then(this.saveSearch.bind(this));
  14250. break;
  14251. }
  14252. }
  14253. if (flag) {
  14254. this.saveSearch();
  14255. }
  14256. }
  14257. },
  14258. saveSearch: function() {
  14259. var searchTerm = this.getSearchTerm();
  14260. var ajaxData = JSON.stringify({
  14261. 'name': searchTerm,
  14262. 'query': searchTerm
  14263. });
  14264. var options = {
  14265. url: this.savedSearchURL,
  14266. type: 'POST',
  14267. contentType: 'application/json',
  14268. data: ajaxData
  14269. };
  14270. return this.glassContext.getCoreSvc('.Ajax').ajax(options)
  14271. .then(function() {
  14272. this.glassContext.appController.showToast(StringResources.get('searchWasSaved'), {
  14273. 'type': 'success',
  14274. 'preventDuplicates': false
  14275. });
  14276. }.bind(this))
  14277. .catch(function() {
  14278. this.glassContext.appController.showToast(StringResources.get('searchWasntSaved'), {
  14279. 'type': 'error',
  14280. 'preventDuplicates': false
  14281. });
  14282. this.logger.error('Could not post saved search');
  14283. }.bind(this))
  14284. .finally(function() {
  14285. this.savedSearchclicked = false;
  14286. }.bind(this));
  14287. },
  14288. /**
  14289. * Returns the currently selected display types
  14290. * @return {array}
  14291. */
  14292. _getSelectedDisplayTypes: function() {
  14293. return this.filterViewController ? this.filterViewController.getSelectedTypes() : '';
  14294. },
  14295. /**
  14296. * Returns the currently selected content-service types
  14297. * @return {array}
  14298. */
  14299. _getFilteredTypes: function() {
  14300. var types = [];
  14301. _.each(this._getSelectedDisplayTypes(), function(displayType){
  14302. types.push(UIHelper.getType(displayType));
  14303. });
  14304. // if there were no selected types, use the default types
  14305. return types.length === 0 ? this.defaultTypes : types;
  14306. }
  14307. });
  14308. return Search;
  14309. });
  14310. /*
  14311. *+------------------------------------------------------------------------+
  14312. *| Licensed Materials - Property of IBM
  14313. *| IBM Cognos Products: Content Explorer
  14314. *| (C) Copyright IBM Corp. 2015, 2018
  14315. *|
  14316. *| US Government Users Restricted Rights - Use, duplication or disclosure
  14317. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  14318. *+------------------------------------------------------------------------+
  14319. */
  14320. define('bacontentnav/search/SearchFlyoutView',['./BaseSearchView'], function(BaseSearchView) {
  14321. 'use strict';
  14322. var Search = BaseSearchView.extend({
  14323. disableColumnHeaders: true,
  14324. getModuleName: function() {
  14325. return 'bacontentnav/search/SearchFlyoutView';
  14326. },
  14327. _getColumnSpecification: function() {
  14328. return this._getBaseColumnSpec();
  14329. }
  14330. });
  14331. return Search;
  14332. });
  14333. /*
  14334. *+------------------------------------------------------------------------+
  14335. *| Licensed Materials - Property of IBM
  14336. *| IBM Cognos Products: Content Explorer
  14337. *| (C) Copyright IBM Corp. 2015, 2018
  14338. *|
  14339. *| US Government Users Restricted Rights - Use, duplication or disclosure
  14340. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  14341. *+------------------------------------------------------------------------+
  14342. */
  14343. define('bi/content_apps/CASearchFlyoutView',[
  14344. 'bacontentnav/search/SearchFlyoutView',
  14345. 'bacontentnav/nls/StringResource',
  14346. './PropertiesPageView'
  14347. ], function(SearchFlyoutView, StringResource, PropertiesPageView) {
  14348. 'use strict';
  14349. var CASearchFlyoutView = SearchFlyoutView.extend({
  14350. stateId: 'CASearchFlyoutView',
  14351. init: function(options) {
  14352. void(options);
  14353. CASearchFlyoutView.inherited('init', this, arguments);
  14354. // used by SearchFolderView - consider refactoring
  14355. this.propertiesView = PropertiesPageView;
  14356. },
  14357. //todo: this piece of code should be moved to bacontentnav, so it can be shared.
  14358. showProperties: function(objectInformation) {
  14359. if (!this._propertiesOpen) {
  14360. this.togglePropertiesMode();
  14361. }
  14362. this.propertiesSlideout = this.glassContext.appController.showSlideOut({
  14363. 'label': StringResource.get('properties', {
  14364. 'objectName': objectInformation.defaultName
  14365. }),
  14366. 'position': this.slideout ? null : 'right',
  14367. 'parent': this.slideout,
  14368. 'width': '400',
  14369. 'enableTabLooping': true,
  14370. 'onHide': function() {
  14371. this._focus();
  14372. if (this._propertiesOpen) {
  14373. this.togglePropertiesMode();
  14374. }
  14375. if (this.propertiesSlideout && this.propertiesSlideout.contentView) {
  14376. this.propertiesSlideout.contentView.onHide().then(function() {
  14377. //remove propertiesPageView
  14378. this.propertiesSlideout.hide();
  14379. }.bind(this));
  14380. }
  14381. }.bind(this),
  14382. 'content': {
  14383. 'module': PropertiesPageView,
  14384. 'parentView': this,
  14385. 'objectInformation': objectInformation,
  14386. 'glassContext': this.glassContext
  14387. },
  14388. 'resizable': true
  14389. });
  14390. },
  14391. _focus: function() {
  14392. this.$el.focus();
  14393. }
  14394. });
  14395. return CASearchFlyoutView;
  14396. });
  14397. /*
  14398. *+------------------------------------------------------------------------+
  14399. *| Licensed Materials - Property of IBM
  14400. *| IBM Cognos Products: Content Explorer
  14401. *| (C) Copyright IBM Corp. 2016, 2018
  14402. *|
  14403. *| US Government Users Restricted Rights - Use, duplication or disclosure
  14404. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  14405. *+------------------------------------------------------------------------+
  14406. */
  14407. define('bi/content_apps/GenericFolderWideView',[
  14408. 'bacontentnav/nls/StringResource',
  14409. 'bacontentnav/utils/ContentStoreObject',
  14410. './CABaseContentView',
  14411. './PropertiesPageView',
  14412. 'underscore'
  14413. ], function(StringResource, ContentStoreObject, CABaseContentView, PropertiesPageView, _) {
  14414. 'use strict';
  14415. var GenericFolderWideView = CABaseContentView.extend({
  14416. stateId: 'GenericFolderView',
  14417. GROUP_BY_TYPE_COLUMN_INDEX: 4,
  14418. init: function(options) {
  14419. this.showParentPropertiesButton = true;
  14420. _.extend(this, options);
  14421. /*eslint no-unused-vars: 0*/
  14422. GenericFolderWideView.inherited('init', this, arguments);
  14423. this.addURLParameters({
  14424. 'fields': 'owner.defaultName,modificationTime'
  14425. });
  14426. //
  14427. this.dataManipulationCallback = this.commonDataManipulationCallback;
  14428. //always show the new item
  14429. this.showNewItem = true;
  14430. this.showAddFolder = false;
  14431. },
  14432. _getColumnSpecification: function() {
  14433. var columnSpecs = [{
  14434. 'type': 'Icon',
  14435. 'accessibleLabel': StringResource.get('itemType')
  14436. }];
  14437. var nameProps = {
  14438. 'type': 'MultipleProperties',
  14439. 'orientation': 'horizontal',
  14440. 'items': [{
  14441. 'type': 'Time',
  14442. 'displayInline': true,
  14443. 'propertyName': ContentStoreObject.MODIFICATION_TIME
  14444. }]
  14445. };
  14446. columnSpecs.push({
  14447. 'type': 'MultipleProperties',
  14448. 'orientation': 'vertical',
  14449. 'items': [{
  14450. 'type': 'Name'
  14451. },
  14452. nameProps
  14453. ]
  14454. });
  14455. // There is a invisible column for ModifiedTime along with Name.
  14456. // This second 'hidden' column is required to allow DataTable to sort on ModifiedTime.
  14457. columnSpecs.push({
  14458. 'type': 'Time',
  14459. 'propertyName': ContentStoreObject.MODIFICATION_TIME,
  14460. 'visible': false
  14461. });
  14462. // Here is another invisible column groupByFolder for the calculated grouping value
  14463. columnSpecs.push({
  14464. 'type': 'Text',
  14465. 'propertyName': 'groupByFolder',
  14466. 'visible': false
  14467. });
  14468. // Here is another invisible column groupByType for the calculated grouping value
  14469. columnSpecs.push({
  14470. 'type': 'Text',
  14471. 'propertyName': 'groupByType',
  14472. 'visible': false
  14473. });
  14474. columnSpecs.push({
  14475. 'type': 'ContextMenu'
  14476. });
  14477. return columnSpecs;
  14478. },
  14479. /**
  14480. Appropriately shows properties in either the child pane or a pane on the left
  14481. */
  14482. showProperties: function(objectInformation) {
  14483. if (!this._propertiesOpen) {
  14484. this.togglePropertiesMode();
  14485. }
  14486. this.propertiesSlideout = this.glassContext.appController.showSlideOut({
  14487. 'label': StringResource.get('properties', {
  14488. 'objectName': objectInformation.defaultName
  14489. }),
  14490. 'position': this.slideout ? null : 'left',
  14491. 'parent': this.slideout,
  14492. 'width': '400',
  14493. 'enableTabLooping': true,
  14494. 'onHide': function() {
  14495. if (this._propertiesOpen) {
  14496. this.togglePropertiesMode();
  14497. }
  14498. if (this.propertiesSlideout && this.propertiesSlideout.contentView) {
  14499. this.propertiesSlideout.contentView.onHide().then(function() {
  14500. //remove propertiesPageView
  14501. this.propertiesSlideout.hide();
  14502. }.bind(this));
  14503. }
  14504. }.bind(this),
  14505. 'content': {
  14506. 'module': PropertiesPageView,
  14507. 'parentView': this,
  14508. 'objectInformation': objectInformation,
  14509. 'glassContext': this.glassContext
  14510. }
  14511. });
  14512. },
  14513. getSortSpec: function() {
  14514. var sortSpec = GenericFolderWideView.inherited('getSortSpec', this, arguments);
  14515. // ensure we can sort by type
  14516. sortSpec.sortBy.type = 'type';
  14517. return sortSpec;
  14518. },
  14519. getDefaultSort: function() {
  14520. return [
  14521. [3, 'asc'],
  14522. [1, 'asc']
  14523. ];
  14524. }
  14525. });
  14526. return GenericFolderWideView;
  14527. });
  14528. /*
  14529. *+------------------------------------------------------------------------+
  14530. *| Licensed Materials - Property of IBM
  14531. *| IBM Cognos Products: Content Explorer
  14532. *| (C) Copyright IBM Corp. 2015, 2016
  14533. *|
  14534. *| US Government Users Restricted Rights - Use, duplication or disclosure
  14535. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  14536. *+------------------------------------------------------------------------+
  14537. */
  14538. define('bacontentnav/common/ui/contentbar_components/Button',['jquery', '../../../lib/gemini/app/ui/toolbar_components/Button'], function($, GeminiButton) {
  14539. 'use strict';
  14540. var Button = null;
  14541. /**
  14542. * Represents a drop down menu that can be added to an app bar
  14543. */
  14544. Button = GeminiButton.extend({
  14545. events: {
  14546. 'primaryaction': '_handleClick',
  14547. 'mousedown': '_handleStartDrag',
  14548. 'dragdown': '_handleStartDrag'
  14549. },
  14550. render: function() {
  14551. Button.inherited('render', this, arguments);
  14552. var $button = $(this.$el).find('button');
  14553. //should not need to do this but chrome and firefox does not seem to put it in the taborder so add it in directly
  14554. if (this.hiddenOnRender) {
  14555. this.$el.hide();
  14556. $button.attr('tabindex', '-1');
  14557. } else {
  14558. $button.attr('tabindex', '0');
  14559. }
  14560. if (this.displayLabel) {
  14561. var $icon = $(this.$el).find('svg');
  14562. $button.append($("<span class='buttonLabel'>" + this.label + '</span>'));
  14563. $icon.css('float', 'left');
  14564. }
  14565. return this;
  14566. }
  14567. });
  14568. return Button;
  14569. });
  14570. /*
  14571. *+------------------------------------------------------------------------+
  14572. *| Licensed Materials - Property of IBM
  14573. *| IBM Cognos Products: Content Explorer
  14574. *| (C) Copyright IBM Corp. 2015
  14575. *|
  14576. *| US Government Users Restricted Rights - Use, duplication or disclosure
  14577. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  14578. *+------------------------------------------------------------------------+
  14579. */
  14580. define('bacontentnav/common/ui/contentbar_components/HiddenLabel',['jquery', '../../../lib/gemini/app/ui/toolbar_components/Button'], function($, GeminiButton) {
  14581. var HiddenLabel = null;
  14582. /**
  14583. * represents a hidden label for accessibility purposes
  14584. */
  14585. HiddenLabel = GeminiButton.extend({
  14586. events: {},
  14587. render: function() {
  14588. return this;
  14589. }
  14590. });
  14591. return HiddenLabel;
  14592. });
  14593. /**
  14594. * Licensed Materials - Property of IBM
  14595. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  14596. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14597. */
  14598. define('bacontentnav/lib/gemini/app/ui/toolbar_components/MenuWithTick',[
  14599. './Menu',
  14600. 'underscore',
  14601. 'text!../templates/Menu.html',
  14602. '../../../../@waca/core-client/js/core-client/ui/properties/CheckBox',
  14603. '../../../../../nls/StringResource'
  14604. ], function(Menu, _, template, CheckBox, StringResource) {
  14605. var MenuWithTickItem = null;
  14606. /**
  14607. * Represents a drop down menu that can be added to an app bar
  14608. */
  14609. MenuWithTickItem = Menu.extend({
  14610. templateString: template,
  14611. /**
  14612. * Creates a new menu item
  14613. *
  14614. * @param spec -
  14615. * The menu item spec
  14616. * @param root -
  14617. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  14618. */
  14619. init: function(spec) {
  14620. _.extend(this, spec);
  14621. MenuWithTickItem.inherited('init', this, arguments);
  14622. },
  14623. _templateParams: function() {
  14624. var params = MenuWithTickItem.inherited('_templateParams', this, arguments);
  14625. params.showTick = true;
  14626. params.showTitle = true;
  14627. params.label = StringResource.get('filterHeader');
  14628. return params;
  14629. },
  14630. /**
  14631. * Updates checked mark and aria-checked attributes in given menuItem
  14632. */
  14633. updateMenuItemTick: function($MenuItem, checked, disabled) {
  14634. if ($MenuItem) {
  14635. var checkbox = $MenuItem.find('.checkbox');
  14636. var menuItemLink = $MenuItem.find('a');
  14637. var checkboxParent = $MenuItem.find('.clickable');
  14638. if (checkbox && checkboxParent && menuItemLink && menuItemLink[0] && checkbox[0]) {
  14639. if (checked) {
  14640. checkbox.addClass('checked');
  14641. }
  14642. else {
  14643. checkbox.removeClass('checked');
  14644. }
  14645. if (disabled) {
  14646. checkboxParent.addClass('disabled');
  14647. }
  14648. else {
  14649. checkboxParent.removeClass('disabled');
  14650. }
  14651. menuItemLink[0].setAttribute('aria-checked', checked ? true : false);
  14652. checkbox[0].setAttribute('aria-checked', checked ? true : false);
  14653. checkbox[0].setAttribute('aria-disabled', disabled ? true : false);
  14654. }
  14655. }
  14656. }
  14657. });
  14658. return MenuWithTickItem;
  14659. });
  14660. /**
  14661. * Licensed Materials - Property of IBM
  14662. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2018
  14663. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14664. */
  14665. define('bacontentnav/lib/gemini/app/ui/toolbar_components/ToggleMenuBar',[
  14666. 'underscore',
  14667. './MenuWithTick',
  14668. '../../../../@waca/core-client/js/core-client/ui/properties/CheckBox'
  14669. ], function(_, MenuWithTick, CheckBox) {
  14670. 'use strict';
  14671. var ToggleMenuBar = null;
  14672. /**
  14673. * Represents a drop down menu that can be added to an app bar
  14674. */
  14675. ToggleMenuBar = MenuWithTick.extend({
  14676. /**
  14677. * Creates a new item
  14678. *
  14679. * @param spec -
  14680. * The item spec
  14681. * @param root -
  14682. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  14683. */
  14684. init: function(spec) {
  14685. _.extend(this, spec);
  14686. ToggleMenuBar.inherited('init', this, arguments);
  14687. this.itemMap = {};
  14688. this.checkedFilters = [];
  14689. },
  14690. _handleClick: function(event){
  14691. event.stopPropagation();
  14692. this.onCheckboxChange(event.currentTarget.id);
  14693. },
  14694. _handleKeyboard: function(event) {
  14695. var keyCode = event.which || event.keyCode || event.charCode;
  14696. var $target = $(event.target);
  14697. // Only override the enter and space keys. Else pass on to base class
  14698. if ((keyCode === 13 || keyCode === 32) && !$target.hasClass('dropdown-toggle')){
  14699. event.stopPropagation();
  14700. this.onCheckboxChange(event.target.parentNode.id);
  14701. }
  14702. else {
  14703. ToggleMenuBar.inherited('_handleKeyboard', this, arguments);
  14704. }
  14705. },
  14706. /**
  14707. * Toggle Spec
  14708. * ------------------------------------------------------------
  14709. *
  14710. * - Default: 'All content' is selected
  14711. * - All checkboxes are checked
  14712. * - 'All content' is disabled and checked
  14713. *
  14714. * - When an option is unselected
  14715. * - That option becomes unchecked
  14716. * - 'All content' becomes unchecked
  14717. *
  14718. * - When 'All Content' is selected (when possible)
  14719. * - Return it back to 'All Content' state (see Default)
  14720. *
  14721. * - When an option is selected that makes all options checked
  14722. * - Return it back to 'All Content' state (see Default)
  14723. *
  14724. */
  14725. /**
  14726. * Follow filter multi-select spec
  14727. */
  14728. updateSelectedItem: function() {
  14729. // First, unselect all
  14730. _.each(this.items, function(item) {
  14731. this.updateMenuItemTick(this.itemMap[this._getItemId(item.name)], false, false);
  14732. }.bind(this));
  14733. // Then select all that are expected to be selected
  14734. _.each(this.checkedFilters, function(id) {
  14735. this.updateMenuItemTick(this.itemMap[id], true, false);
  14736. }.bind(this));
  14737. },
  14738. /**
  14739. * The following function is called when a checkbox from the ToggleMenu is clicked.
  14740. * @param id -
  14741. * The id of the checkbox that was clicked
  14742. */
  14743. onCheckboxChange: function(id) {
  14744. this._performAction(id); // Perform the actual filter
  14745. if (id === this._getItemId(this.items[0].name)) {
  14746. // All was selected
  14747. if ( this.checkedFilters.indexOf(this._getItemId(this.items[0].name)) > -1 ) {
  14748. // Remove all filters
  14749. this.removeAllFilters();
  14750. }
  14751. else {
  14752. // Add all filters
  14753. this.selectAllFilters();
  14754. }
  14755. }
  14756. else {
  14757. if (this.checkedFilters.indexOf(id) > -1) {
  14758. // Remove this filter
  14759. this.checkedFilters.splice(this.checkedFilters.indexOf(id), 1);
  14760. }
  14761. else {
  14762. // Add this filter
  14763. this.checkedFilters.push(id);
  14764. }
  14765. if (this.checkedFilters.length < this.items.length && this.checkedFilters.indexOf(this._getItemId(this.items[0].name)) > -1) {
  14766. // Handle when 'All' needs to be automatically removed
  14767. this.checkedFilters.splice(this.checkedFilters.indexOf(this._getItemId(this.items[0].name)), 1);
  14768. }
  14769. else if (this.checkedFilters.length === this.items.length - 1 && !this.checkedFilters.indexOf(this._getItemId(this.items[0].name)) > -1) {
  14770. // Handle when 'All' needs to be automatically selected
  14771. this.checkedFilters.push(this._getItemId(this.items[0].name));
  14772. }
  14773. }
  14774. this.updateSelectedItem();
  14775. },
  14776. selectAllFilters: function() {
  14777. this.checkedFilters = []; // Empty current set of filters
  14778. _.each(this.items, function(item) {
  14779. this.checkedFilters.push(this._getItemId(item.name));
  14780. }.bind(this));
  14781. },
  14782. removeAllFilters: function() {
  14783. this.checkedFilters = [];
  14784. },
  14785. render: function() {
  14786. var promise = ToggleMenuBar.inherited('render', this, arguments);
  14787. this.selectAllFilters();
  14788. this.updateSelectedItem();
  14789. if (this.updateLabel) {
  14790. _.each(this.items, function(item) {
  14791. if (item.checked) {
  14792. this.updateSelectedItem();
  14793. }
  14794. }.bind(this));
  14795. if (!this.sCheckedItemName) {
  14796. this.updateSelectedItem();
  14797. }
  14798. }
  14799. return promise;
  14800. },
  14801. _buildDropDown: function() {
  14802. var promise = ToggleMenuBar.inherited('_buildDropDown', this, arguments);
  14803. //populate itemMap to reference elements by name
  14804. _.each(this.items, function(item) {
  14805. var id = this._getItemId(item.name);
  14806. this.itemMap[id] = this.$menu.find('#' + id);
  14807. // Add a checkbox control to each item in the Filter dropdown
  14808. var propertyControl = this.itemMap[id].find('.propertyRow');
  14809. if (propertyControl) {
  14810. var checkbox = new CheckBox({
  14811. 'el': propertyControl,
  14812. 'id': id,
  14813. 'name': item.name,
  14814. 'position': 'leading',
  14815. 'nestedUIControl': true,
  14816. 'readOnly': false,
  14817. 'onChange': function(name) {
  14818. var changeId = this._getItemId(name);
  14819. this.onCheckboxChange(changeId);
  14820. }.bind(this)
  14821. });
  14822. checkbox.render();
  14823. }
  14824. // Add each item to the list of checked items (all items are checked by default)
  14825. this.checkedFilters.push(id);
  14826. }.bind(this));
  14827. this.updateSelectedItem();
  14828. return promise;
  14829. },
  14830. remove: function() {
  14831. _.each(this.itemMap, function(item) {
  14832. if (item.remove) {
  14833. item.remove();
  14834. }
  14835. });
  14836. ToggleMenuBar.inherited('remove', this, arguments);
  14837. }
  14838. });
  14839. return ToggleMenuBar;
  14840. });
  14841. /*
  14842. *+------------------------------------------------------------------------+
  14843. *| Licensed Materials - Property of IBM
  14844. *| IBM Cognos Products: Content Explorer
  14845. *| (C) Copyright IBM Corp. 2015,2017
  14846. *|
  14847. *| US Government Users Restricted Rights - Use, duplication or disclosure
  14848. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  14849. *+------------------------------------------------------------------------+
  14850. */
  14851. define('bacontentnav/common/ui/contentbar_components/ToggleMenuBar',['jquery', '../../../lib/gemini/app/ui/toolbar_components/ToggleMenuBar', '../../../lib/@waca/core-client/js/core-client/utils/Utils'], function($, GeminiToggleMenuBar, Utils) {
  14852. var ToggleMenuBar = null;
  14853. /**
  14854. * Represents a drop down menu that can be added to an app bar
  14855. */
  14856. ToggleMenuBar = GeminiToggleMenuBar.extend({
  14857. events: {
  14858. 'clicktap .dropdown-toggle': '_handleClick',
  14859. 'clicktap .dropdown-menuitem': '_handleClick',
  14860. 'keydown': '_handleKeyboard'
  14861. },
  14862. render: function() {
  14863. ToggleMenuBar.inherited('render', this, arguments);
  14864. if (this.icon) {
  14865. if (this.iconRightAlign) {
  14866. this.$toggle.append(this.$iconImage);
  14867. }
  14868. if (this.bSVG) {
  14869. Utils.setIcon(this.$iconImage, this.icon);
  14870. }
  14871. }
  14872. this.$toggle = this.className ? this.$toggle.addClass(this.className) : this.$toggle;
  14873. }
  14874. });
  14875. return ToggleMenuBar;
  14876. });
  14877. /**
  14878. * Licensed Materials - Property of IBM
  14879. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2014, 2017
  14880. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14881. */
  14882. define('bacontentnav/lib/gemini/app/ui/toolbar_components/MenuWithActive',[ './Menu', 'underscore', 'text!../templates/Menu.html', '../../../../../nls/StringResource'], function(Menu, _, template, StringResource) {
  14883. var MenuWithActive = null;
  14884. /**
  14885. * Represents a drop down menu that can be added to an app bar
  14886. */
  14887. MenuWithActive = Menu.extend({
  14888. templateString: template,
  14889. /**
  14890. * Creates a new menu item
  14891. *
  14892. * @param spec -
  14893. * The menu item spec
  14894. * @param root -
  14895. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  14896. */
  14897. init: function(spec) {
  14898. _.extend(this, spec);
  14899. MenuWithActive.inherited('init', this, arguments);
  14900. },
  14901. _templateParams: function() {
  14902. var params = MenuWithActive.inherited('_templateParams', this, arguments);
  14903. params.isSort = true;
  14904. params.showTitle = true;
  14905. params.label = StringResource.get('sortHeader');
  14906. return params;
  14907. },
  14908. /**
  14909. * Updates checked mark and aria-checked attributes in given menuItem
  14910. */
  14911. updateMenuItemActive: function($MenuItem, checked, isAsc) {
  14912. if ($MenuItem) {
  14913. var link = $MenuItem.find('a');
  14914. var icon = link.find('span.sortDirection');
  14915. var svg = icon.find('use');
  14916. if (checked) {
  14917. link.addClass('sortByActive');
  14918. }
  14919. else {
  14920. link.removeClass('sortByActive');
  14921. }
  14922. if (isAsc != null) {
  14923. var svgId = isAsc ? '#ba_content_nav-arrow_up_16' : '#ba_content_nav-arrow_down_16';
  14924. icon[0].setAttribute('style', '');
  14925. icon[0].setAttribute('aria-label', isAsc ? StringResource.get('sortedAscending') : StringResource.get('sortedDescending'));
  14926. svg[0].setAttribute('xlink:href', svgId);
  14927. }
  14928. else {
  14929. icon[0].setAttribute('style', 'display: none;');
  14930. }
  14931. link[0].setAttribute('aria-checked', checked ? 'true' : 'false');
  14932. }
  14933. }
  14934. });
  14935. return MenuWithActive;
  14936. });
  14937. /**
  14938. * Licensed Materials - Property of IBM
  14939. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2017
  14940. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14941. */
  14942. define('bacontentnav/lib/gemini/app/ui/toolbar_components/SortMenuBar',[ './MenuWithActive', 'underscore'], function( MenuWithActive, _ ) {
  14943. 'use strict';
  14944. var SortMenuBar = null;
  14945. /**
  14946. * Represents a drop down menu that can be added to an app bar
  14947. */
  14948. SortMenuBar = MenuWithActive.extend({
  14949. itemMap: {},
  14950. sCheckedItemId: null,
  14951. updateLabel: false,
  14952. sortAscending: true,
  14953. /**
  14954. * Creates a new item
  14955. *
  14956. * @param spec -
  14957. * The item spec
  14958. * @param root -
  14959. * A reference to the root menu item, where items go if the app bar is collapsed horizontally
  14960. */
  14961. init: function(spec) {
  14962. _.extend(this, spec);
  14963. SortMenuBar.inherited('init', this, arguments);
  14964. },
  14965. toggleHandler: function(name) {
  14966. this.updateSelectedItem(this._getItemId(name));
  14967. },
  14968. /**
  14969. * Make sure only one item is selected
  14970. */
  14971. updateSelectedItem: function(id) {
  14972. var item = this.itemMap[id];
  14973. if(!item || !item.children) {
  14974. // if we haven't selected an item, we do not update the tick
  14975. return;
  14976. }
  14977. // Check if the selected item is the current selected item
  14978. if (this.sCheckedItemId === id) {
  14979. /* The selected item is already selected - therefore, flip the ascending/descending option
  14980. updateMenuItemActive( $MenuItem - the actual DOM item,
  14981. checked - whether or not that DOM element should be ACTIVE,
  14982. asc - whether or not the sort direction is ascending )
  14983. */
  14984. this.sortAscending = !this.sortAscending; // flip the value of sortAscending
  14985. this.updateMenuItemActive(this.itemMap[id], true, this.sortAscending);
  14986. }
  14987. else {
  14988. // The selected item was not already selected - therefore, unselect the current item and select the new item with direction ascending
  14989. this.sortAscending = true;
  14990. // Remove active and sort direction from old sort type
  14991. this.updateMenuItemActive(this.itemMap[this.sCheckedItemId], false, null);
  14992. // Add active and sort direction to new sort type
  14993. this.updateMenuItemActive(this.itemMap[id], true, this.sortAscending);
  14994. // Update the current sort by name
  14995. this.sCheckedItemId = id;
  14996. }
  14997. if (this.updateLabel) {
  14998. if (this.$menuLabel.length > 0 && item.children) {
  14999. this.$menuLabel.text(item.children('a').attr('aria-label'));
  15000. }
  15001. }
  15002. },
  15003. render: function() {
  15004. var promise = SortMenuBar.inherited('render', this, arguments);
  15005. if (this.updateLabel) {
  15006. _.each(this.items, function(item) {
  15007. if (item.checked) {
  15008. this.updateSelectedItem(this._getItemId(item.name));
  15009. }
  15010. }.bind(this));
  15011. if (!this.sCheckedItemId) {
  15012. this.updateSelectedItem(this._getItemId(this.items[0].name));
  15013. }
  15014. }
  15015. return promise;
  15016. },
  15017. _performAction: function(id) {
  15018. this.updateSelectedItem(id);
  15019. SortMenuBar.inherited('_performAction', this, arguments);
  15020. },
  15021. _getItemNameFromID: function(id) {
  15022. var prefix = this.viewId + '_';
  15023. return id.substr(prefix.length);
  15024. },
  15025. _templateParams: function() {
  15026. var params = SortMenuBar.inherited('_templateParams', this, arguments);
  15027. params.isSort = true;
  15028. return params;
  15029. },
  15030. _buildDropDown: function() {
  15031. var promise = SortMenuBar.inherited('_buildDropDown', this, arguments);
  15032. //populate itemMap to reference elements by name
  15033. _.each(this.items, function(item) {
  15034. var id = this._getItemId(item.name);
  15035. this.itemMap[id] = this.$menu.find('#' + id);
  15036. if (item.sorted) {
  15037. this.sCheckedItemId = id;
  15038. this.updateMenuItemActive(this.itemMap[this.sCheckedItemId], true, this.sortAscending);
  15039. }
  15040. }.bind(this));
  15041. return promise;
  15042. },
  15043. remove: function() {
  15044. _.each(this.itemMap, function(item) {
  15045. if (item.remove) {
  15046. item.remove();
  15047. }
  15048. });
  15049. SortMenuBar.inherited('remove', this, arguments);
  15050. }
  15051. });
  15052. return SortMenuBar;
  15053. });
  15054. /*
  15055. *+------------------------------------------------------------------------+
  15056. *| Licensed Materials - Property of IBM
  15057. *| IBM Cognos Products: Content Explorer
  15058. *| (C) Copyright IBM Corp. 2015, 2017
  15059. *|
  15060. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15061. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15062. *+------------------------------------------------------------------------+
  15063. */
  15064. define('bacontentnav/common/ui/contentbar_components/SortMenuBar',['jquery', '../../../lib/gemini/app/ui/toolbar_components/SortMenuBar', '../../../lib/@waca/core-client/js/core-client/utils/Utils'], function($, GeminiToggleMenuBar, Utils) {
  15065. var SortMenuBar = null;
  15066. /**
  15067. * Represents a drop down menu that can be added to an app bar
  15068. */
  15069. SortMenuBar = GeminiToggleMenuBar.extend({
  15070. events: {
  15071. 'clicktap .dropdown-toggle': '_handleClick',
  15072. 'clicktap .dropdown-menuitem': '_handleClick',
  15073. 'keydown': '_handleKeyboard'
  15074. },
  15075. render: function() {
  15076. SortMenuBar.inherited('render', this, arguments);
  15077. if (this.icon) {
  15078. if (this.iconRightAlign) {
  15079. this.$toggle.append(this.$iconImage);
  15080. }
  15081. if (this.bSVG) {
  15082. Utils.setIcon(this.$iconImage, this.icon);
  15083. }
  15084. }
  15085. this.$toggle = this.className ? this.$toggle.addClass(this.className) : this.$toggle;
  15086. }
  15087. });
  15088. return SortMenuBar;
  15089. });
  15090. /*
  15091. *+------------------------------------------------------------------------+
  15092. *| Licensed Materials - Property of IBM
  15093. *| IBM Cognos Products: Content Explorer
  15094. *| (C) Copyright IBM Corp. 2017, 2019
  15095. *|
  15096. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15097. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15098. *+------------------------------------------------------------------------+
  15099. */
  15100. define('bacontentnav/common/ui/list_columns/Column',[
  15101. '../../../lib/@waca/core-client/js/core-client/ui/core/Class',
  15102. '../../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  15103. '../../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  15104. '../../../utils/MRUHelper',
  15105. '../../../utils/UIHelper',
  15106. 'underscore'
  15107. ], function(Class, ContentFormatter, BidiUtil, MRUHelper, UIHelper, _) {
  15108. 'use strict';
  15109. /*****
  15110. options: getDataFn - function that can overwrite the default behavior
  15111. retrieving the data for the column. The function is passed the json object
  15112. the contains the data and is expected to return the specific data from that argument
  15113. **/
  15114. var Column = Class.extend({
  15115. init: function(options) {
  15116. _.extend(this, options);
  15117. if (!this._bNavigable) {
  15118. this._bNavigable = $.isFunction(this.clickCallback);
  15119. }
  15120. },
  15121. getSpec: function() {
  15122. var hasConsole = typeof console;
  15123. void(hasConsole);
  15124. },
  15125. /**
  15126. returns the data for this column. If a dataFn has been provided it
  15127. uses that otherwise it calls _data()
  15128. **/
  15129. getData: function(oData) {
  15130. if (this.getDataFn) {
  15131. return this.getDataFn(oData);
  15132. } else {
  15133. return this._getData(oData);
  15134. }
  15135. },
  15136. /**
  15137. Override if your column returns data
  15138. **/
  15139. _getData: function() {
  15140. return '';
  15141. },
  15142. /**
  15143. Override if your property has special logic when creating the cell
  15144. **/
  15145. createCell: function(parentNode, sData) {
  15146. var $parent = $(parentNode);
  15147. $parent.text(_.unescape(sData));
  15148. },
  15149. getListControl: function() {
  15150. return this.listControl;
  15151. },
  15152. createEllipseCell: function(nParent, sData, oData) {
  15153. var $parent = $(nParent);
  15154. $parent.addClass('ellipsis_cell');
  15155. var safeData = _.unescape(sData);
  15156. var divClass = 'nameColumnDiv';
  15157. if (this._bNavigable) {
  15158. divClass += ' contentListFocusable';
  15159. if (oData.type !== 'folder' && UIHelper.isValid(oData) &&
  15160. (this.listControl && UIHelper.hasRequiredCapabilities(oData, this.listControl.typesToOpen, this.listControl.capabilitiesRequired))) {
  15161. divClass += ' clickable';
  15162. }
  15163. }
  15164. if (BidiUtil.userPreferredTextDir) {
  15165. safeData = BidiUtil.enforceTextDirection(safeData);
  15166. }
  15167. var $div = $('<div></div>', {
  15168. 'title': safeData,
  15169. 'text': safeData,
  15170. 'class': divClass,
  15171. 'tabindex': '-1'
  15172. });
  15173. $parent[0].fnResizeCallback = function() {
  15174. $div[0].textContent = safeData;
  15175. this.getMiddleShortenString($div[0]);
  15176. if (BidiUtil.userPreferredTextDir !== '') {
  15177. if (($parent.hasClass('location') || ($parent.hasClass('text') && $div[0].textContent.indexOf('>') >= 0))) {
  15178. $div[0].textContent = BidiUtil.enforceTextDirectionForLocation($div[0].textContent);
  15179. $div[0].title = BidiUtil.enforceTextDirectionForLocation(safeData);
  15180. } else {
  15181. $div.attr('dir', BidiUtil.resolveBaseTextDir($div[0].textContent));
  15182. }
  15183. }
  15184. }.bind(this);
  15185. $parent.empty().append($div);
  15186. this.addClickAction($div, nParent, sData, oData);
  15187. return $div;
  15188. },
  15189. processTextForEllipses: function(nTd) {
  15190. var $td = $(nTd);
  15191. if ($td[0].fnResizeCallback) {
  15192. $td[0].fnResizeCallback();
  15193. }
  15194. },
  15195. getMiddleShortenString: function(content) {
  15196. ContentFormatter.middleShortenString(content);
  15197. },
  15198. /**
  15199. * Override if you need to add a click action on a ellipse enabled cell
  15200. */
  15201. addClickAction: function($div, nParent, sData, oData) {
  15202. if (!_.isUndefined(this.clickCallback)) {
  15203. $div.addClass('contentListFocusable');
  15204. $div.on('primaryaction', function(e) {
  15205. this.clickCallback(oData, e);
  15206. }.bind(this));
  15207. }
  15208. },
  15209. /**
  15210. * Common functionality for creating a context menu
  15211. */
  15212. onContextMenu: function(oData, event) {
  15213. if (!event.shiftKey && !event.ctrlKey) {
  15214. event.stopPropagation();
  15215. var listControl = this.getListControl();
  15216. //
  15217. if (_.isFunction(listControl._hideSlideoutChildrenToTheRight)){
  15218. listControl._hideSlideoutChildrenToTheRight();
  15219. }
  15220. listControl._clearRows(); //show context menu for single select items only
  15221. listControl.handleClick(event);
  15222. var showContextMenu = function() {
  15223. listControl.getActionPayload(event).then(function(actionPayload) {
  15224. this.glassContext.appController.showContextMenu(actionPayload);
  15225. }.bind(this));
  15226. }.bind(this);
  15227. var view = listControl.contentView || {};
  15228. if (MRUHelper.requiresAssetVerification(view)) {
  15229. MRUHelper.verifyAccess(this.glassContext, oData && oData.id)
  15230. .then(function(hasAccess) {
  15231. if (hasAccess) {
  15232. showContextMenu();
  15233. } else if (view.slideout) {
  15234. view.slideout.hide();
  15235. }
  15236. });
  15237. } else {
  15238. showContextMenu();
  15239. }
  15240. return false;
  15241. }
  15242. }
  15243. });
  15244. return Column;
  15245. });
  15246. /*
  15247. *+------------------------------------------------------------------------+
  15248. *| Licensed Materials - Property of IBM
  15249. *| IBM Cognos Products: Content Explorer
  15250. *| (C) Copyright IBM Corp. 2016, 2018
  15251. *|
  15252. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15253. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15254. *+------------------------------------------------------------------------+
  15255. */
  15256. define('bacontentnav/common/ui/list_columns/BaseIcon',[
  15257. './Column'
  15258. ], function(Column) {
  15259. 'use strict';
  15260. var BaseIcon = Column.extend({
  15261. getSpec: function() {
  15262. return Promise.resolve({
  15263. 'name': this.name,
  15264. 'bSortable': false,
  15265. 'sClass': 'icon ellipsesButton_cell',
  15266. 'hiddenLabel': this.name,
  15267. 'width': '40px',
  15268. 'mData': this.getData.bind(this),
  15269. 'fnCreatedCell': this.createCell.bind(this)
  15270. });
  15271. },
  15272. /**
  15273. * takes the node and appends the result of the createObjectImg function to it
  15274. * createObjectImg should be defined by child classes
  15275. */
  15276. createCell: function(nParent, sData, oData) {
  15277. var $parent = $(nParent);
  15278. var objectImg = this.createObjectImg(oData);
  15279. $parent.empty().append(objectImg);
  15280. $parent.attr('aria-label', this.a11yLabel);
  15281. this.addClickAction(objectImg, nParent, sData, oData);
  15282. },
  15283. /**
  15284. * Override to define your own icon in the cell
  15285. */
  15286. createObjectImg: function(){
  15287. var $div = $('<div>', {
  15288. role: 'img',
  15289. tabindex: '-1'
  15290. });
  15291. return $div;
  15292. }
  15293. });
  15294. return BaseIcon;
  15295. });
  15296. /*
  15297. *+------------------------------------------------------------------------+
  15298. *| Licensed Materials - Property of IBM
  15299. *| IBM Cognos Products: Content Explorer
  15300. *| (C) Copyright IBM Corp. 2015, 2018
  15301. *|
  15302. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15303. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15304. *+------------------------------------------------------------------------+
  15305. */
  15306. define('bacontentnav/common/ui/list_columns/Icon',[
  15307. './BaseIcon',
  15308. '../../../utils/UIHelper',
  15309. '../../../utils/ContentStoreObject',
  15310. '../../../nls/StringResource',
  15311. '../../../lib/@waca/core-client/js/core-client/utils/Utils'
  15312. ], function(BaseIcon, UIHelper, ContentStoreObject, StringResource, Utils) {
  15313. 'use strict';
  15314. var Icon = BaseIcon.extend({
  15315. getSpec: function(){
  15316. return Icon.inherited('getSpec', this, arguments).then(function(spec){
  15317. spec.name = 'icon';
  15318. spec.headerClass = 'headerIcon';
  15319. return spec;
  15320. });
  15321. },
  15322. _getData: function(oRowData) {
  15323. return UIHelper.getFilterType(oRowData);
  15324. },
  15325. createObjectImg: function(oData) {
  15326. var type = UIHelper.getDisplayType(oData);
  15327. var hidden = ContentStoreObject.getHidden(oData);
  15328. var disabled = ContentStoreObject.getDisabled(oData);
  15329. var sXLink = UIHelper.getTypeSVGIconFromObject(oData);
  15330. var tooltip = UIHelper.getTypeNameFromObject(oData);
  15331. var a11yLabel = tooltip;
  15332. var sClass = 'svgIcon';
  15333. if (hidden) {
  15334. sClass += ' dimmed';
  15335. a11yLabel = 'hidden ' + a11yLabel;
  15336. }
  15337. if (sXLink) {
  15338. // Overlay disabled icon decorator
  15339. var iconObject = '<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="' + sXLink + '"></use>';
  15340. if (disabled) {
  15341. var iconDisabledOverlay = '<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#common-disabled" x="5" y="5" height="10" width="12" style="stroke: #ff0000;"></use>';
  15342. iconObject += iconDisabledOverlay;
  15343. a11yLabel = 'disabled ' + a11yLabel;
  15344. } else if (UIHelper.getIconFill(type)) {
  15345. iconObject = '<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="' + sXLink + '" style="fill: ' + UIHelper.getIconFill(type) + '"></use>';
  15346. }
  15347. // Add view decorator unless it is a report view - new icon does not require decorator (June 2017)
  15348. if (UIHelper.isSVGIconDecorated(type)) {
  15349. iconObject += '<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#common-view_decorator" x="5" y="5" height="10" width="12"></use>';
  15350. }
  15351. return Utils.embedSVGIcon($('<div role="img" alt="' + tooltip + '" title="' + tooltip + '"><svg role="presentation" class="' + sClass + '">' + iconObject + '<text>' + a11yLabel + '</text></svg></div>'));
  15352. }
  15353. return $('<div></div>', {
  15354. 'alt': tooltip,
  15355. 'title': tooltip,
  15356. 'height': '30px',
  15357. 'width': '30px'
  15358. });
  15359. }
  15360. });
  15361. return Icon;
  15362. });
  15363. /*
  15364. *+------------------------------------------------------------------------+
  15365. *| Licensed Materials - Property of IBM
  15366. *| IBM Cognos Products: Content Explorer
  15367. *| (C) Copyright IBM Corp. 2015, 2016, 2017
  15368. *|
  15369. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15370. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15371. *+------------------------------------------------------------------------+
  15372. */
  15373. define('bacontentnav/common/ui/list_columns/AccountIcon',[
  15374. './Icon'
  15375. ], function(Icon) {
  15376. 'use strict';
  15377. var AccountIcon = Icon.extend({
  15378. getData: function(oRowData) {
  15379. return oRowData.objectClass;
  15380. }
  15381. });
  15382. return AccountIcon;
  15383. });
  15384. /*
  15385. *+------------------------------------------------------------------------+
  15386. *| Licensed Materials - Property of IBM
  15387. *| IBM Cognos Products: Content Explorer
  15388. *| (C) Copyright IBM Corp. 2015, 2018
  15389. *|
  15390. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15391. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15392. *+------------------------------------------------------------------------+
  15393. */
  15394. define('bacontentnav/common/ui/list_columns/BirdBeakMenu',[
  15395. './Column',
  15396. '../../../common/ui/BreadcrumbDropDown',
  15397. '../../../nls/StringResource',
  15398. '../../../lib/@waca/core-client/js/core-client/utils/Utils'
  15399. ], function(Column, DropDownMenu, StringResource, Utils) {
  15400. 'use strict';
  15401. var BirdBeakMenu = Column.extend({
  15402. getSpec: function() {
  15403. return Promise.resolve({
  15404. //'name': 'Set PermissionAAAA',
  15405. 'bSortable': false,
  15406. 'sClass': 'ellipsesButton_cell',
  15407. 'hiddenLabel': this.name,
  15408. 'mData': function() {
  15409. return ''; //This is a workaround for the assumption that all ListControl elements look to the row data for information
  15410. },
  15411. 'fnCreatedCell': function(nTd, sData, oData) {
  15412. void(oData);
  15413. var $td = $(nTd);
  15414. var $div = $('<div></div>', {
  15415. 'class': 'ellipsesButton forceRowSelection'
  15416. });
  15417. $div.attr('role', 'link');
  15418. $div.attr('tabindex', '-1');
  15419. $div.attr('title', this.name);
  15420. this._createDropDown($div);
  15421. $td.empty().append($div);
  15422. }.bind(this)
  15423. });
  15424. },
  15425. _createDropDown: function($parentEl) {
  15426. var $div = $('<div>').addClass('contentListFocusable').appendTo($parentEl);
  15427. Utils.setIcon($div, 'common-titan-arrow-down');
  15428. this.ddMenu = new DropDownMenu({
  15429. dropDownMenuSpec: {
  15430. 'title': this.name || '',
  15431. 'id': 'birdBeakId',
  15432. 'label': 'BirdBeak',
  15433. 'items': this.menuItems,
  15434. 'actionElement': $div[0],
  15435. 'ddMenuPlacement': 'bottom'
  15436. }
  15437. });
  15438. this.ddMenu.render().then(function(el) {
  15439. $div.append(el);
  15440. });
  15441. $parentEl.addClass('birdBeak');
  15442. }
  15443. });
  15444. return BirdBeakMenu;
  15445. });
  15446. /*
  15447. *+------------------------------------------------------------------------+
  15448. *| Licensed Materials - Property of IBM
  15449. *| IBM Cognos Products: Content Explorer
  15450. *| (C) Copyright IBM Corp. 2015, 2018
  15451. *|
  15452. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15453. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15454. *+------------------------------------------------------------------------+
  15455. */
  15456. define('bacontentnav/common/ui/list_columns/ClickableIcon',[
  15457. '../../../lib/@waca/core-client/js/core-client/utils/Utils',
  15458. './BaseIcon'
  15459. ], function(utils, BaseIcon) {
  15460. 'use strict';
  15461. /**
  15462. @param options.name {string} - Item name
  15463. @param options.clickCallback {function} - Optional, callback function to call when the user clicks on the icon
  15464. @param options.icon {string} - The icon to display, in standard svg format
  15465. **/
  15466. var ClickableIcon = BaseIcon.extend({
  15467. createObjectImg: function(){
  15468. var $div = $('<div>', {
  15469. 'class': 'ellipsesButton forceRowSelection',
  15470. 'title': this.a11yLabel,
  15471. 'role': 'link',
  15472. 'tabindex': '-1'
  15473. });
  15474. utils.setIcon($div, this.icon);
  15475. return $div;
  15476. }
  15477. });
  15478. return ClickableIcon;
  15479. });
  15480. /*
  15481. *+------------------------------------------------------------------------+
  15482. *| Licensed Materials - Property of IBM
  15483. *| IBM Cognos Products: Content Explorer
  15484. *| (C) Copyright IBM Corp. 2015, 2018
  15485. *|
  15486. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15487. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15488. *+------------------------------------------------------------------------+
  15489. */
  15490. define('bacontentnav/common/ui/list_columns/ContextMenu',[
  15491. '../../../lib/@waca/core-client/js/core-client/utils/Utils',
  15492. '../../../nls/StringResource',
  15493. './BaseIcon',
  15494. 'underscore'
  15495. ], function(Utils, StringResource, BaseIcon, _) {
  15496. 'use strict';
  15497. var ContextMenu = BaseIcon.extend({
  15498. init: function(options) {
  15499. ContextMenu.inherited('init', this, arguments);
  15500. _.extend(this, options);
  15501. this.clickCallback = this.onContextMenu;
  15502. this.a11yLabel = StringResource.get('moreActionsMenu');
  15503. },
  15504. getSpec: function(){
  15505. return ContextMenu.inherited('getSpec', this, arguments).then(function(spec){
  15506. spec.name = 'properties';
  15507. return spec;
  15508. });
  15509. },
  15510. createObjectImg: function(){
  15511. var $div = $('<div></div>', {
  15512. 'class': 'ellipsesButton forceRowSelection',
  15513. 'title': StringResource.get('more'),
  15514. 'tabindex': '-1'
  15515. });
  15516. Utils.setIcon($div, 'common-menuoverflow');
  15517. return $div;
  15518. }
  15519. });
  15520. return ContextMenu;
  15521. });
  15522. /*
  15523. *+------------------------------------------------------------------------+
  15524. *| Licensed Materials - Property of IBM
  15525. *| IBM Cognos Products: Content Explorer
  15526. *| (C) Copyright IBM Corp. 2015, 2018
  15527. *|
  15528. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15529. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15530. *+------------------------------------------------------------------------+
  15531. */
  15532. define('bacontentnav/common/ui/list_columns/Location',[
  15533. '../../../utils/ContentStoreObject',
  15534. '../../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  15535. './Column',
  15536. '../../../nls/StringResource',
  15537. 'underscore'
  15538. ], function(ContentStoreObject, ContentFormatter, Column, StringResource,_) {
  15539. 'use strict';
  15540. var Location = Column.extend({
  15541. getSpec: function() {
  15542. return Promise.resolve({
  15543. 'name': 'location',
  15544. 'label': StringResource.get('location'),
  15545. 'headerClass': 'location',
  15546. 'mData': this.getData.bind(this),
  15547. 'sClass': 'location',
  15548. 'weight': 20,
  15549. 'fnCreatedCell': this.createEllipseCell.bind(this),
  15550. 'formatContent': this.processTextForEllipses.bind(this)
  15551. });
  15552. },
  15553. _getData: function(oRowData) {
  15554. return _.escape(ContentStoreObject.getLocation(oRowData));
  15555. },
  15556. addClickAction: function($div, nParent, sData, oData) {
  15557. if (this.clickCallback) {
  15558. $div.addClass(this.showAsActiveLink !== false ? 'active' : 'clickable');
  15559. $div.attr('role', 'link');
  15560. $div.on('primaryaction', function(evt) {
  15561. void(evt);
  15562. this.clickCallback(oData);
  15563. }.bind(this));
  15564. }
  15565. }
  15566. });
  15567. return Location;
  15568. });
  15569. /*
  15570. *+------------------------------------------------------------------------+
  15571. *| Licensed Materials - Property of IBM
  15572. *| IBM Cognos Products: Content Explorer
  15573. *| (C) Copyright IBM Corp. 2015, 2018
  15574. *|
  15575. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15576. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15577. *+------------------------------------------------------------------------+
  15578. */
  15579. define('bacontentnav/common/ui/list_columns/MultipleProperties',[
  15580. 'require',
  15581. '../../../utils/ContentStoreObject',
  15582. './Column'
  15583. ], function(LocalRequire, ContentStoreObject, Column) {
  15584. 'use strict';
  15585. /**
  15586. @param options.items [objects] - array of properties to display
  15587. @param options.weight {number} - Weight of the column
  15588. @param options.orientation {string} - [horizontal | vertical] Orientation display, defaults to 'vertical'
  15589. **/
  15590. var MultipleProperties = Column.extend({
  15591. getSpec: function() {
  15592. this._oProperties = [];
  15593. var aPromises = [];
  15594. // Loop through all the items and create an object for them
  15595. $.each(this.items, function(index, item) {
  15596. if (item.type) {
  15597. var path = item.module || './' + item.type;
  15598. aPromises.push(new Promise(function(resolve) {
  15599. LocalRequire([path], function(Module) {
  15600. // Create the column object and save it in the item object for reference later
  15601. item.obj = this.getListControl().createColumnObject(item, Module);
  15602. item.obj.getSpec().then(function(spec) {
  15603. item.spec = spec;
  15604. resolve();
  15605. });
  15606. }.bind(this));
  15607. }.bind(this)));
  15608. }
  15609. }.bind(this));
  15610. // We've loaded all the columns
  15611. return Promise.all(aPromises).then(function() {
  15612. return {
  15613. 'name': this.items[0].spec.name,
  15614. 'label': this.items[0].spec.label,
  15615. 'sClass': 'nowrap',
  15616. 'weight': this.weight || 20,
  15617. 'fnCreatedCell': this.createCell.bind(this),
  15618. 'mData': this.getData.bind(this),
  15619. 'formatContent': this.formatContent.bind(this)
  15620. };
  15621. }.bind(this));
  15622. },
  15623. /**
  15624. Need this so that the column gets correctly sorted. Currently,
  15625. all the UX spec have the name first in these types of columns
  15626. **/
  15627. _getData: function(oRowData) {
  15628. if (this.items[0].spec.mData) {
  15629. return this.items[0].spec.mData(oRowData);
  15630. } else {
  15631. // Default to Name
  15632. return oRowData[ContentStoreObject.DEFAULT_NAME];
  15633. }
  15634. },
  15635. createCell: function(parentNode, sData, oData) {
  15636. var horizontal = this.orientation === 'horizontal';
  15637. var $parentNode = $(parentNode);
  15638. $parentNode.empty();
  15639. if (!horizontal) {
  15640. $parentNode.addClass('multiProp');
  15641. } else {
  15642. $parentNode.addClass('multiPropHorizontal');
  15643. }
  15644. $.each(this.items, function(index, item) {
  15645. // Each sub property will be contained in a div
  15646. var $div = $('<div>').addClass(item.type.toLowerCase());
  15647. if (horizontal) {
  15648. $div.addClass('textDivInline');
  15649. } else {
  15650. $div.addClass('textDiv');
  15651. }
  15652. $parentNode.append($div);
  15653. // Call the properties 'createCell' method passing the div as the parent
  15654. item.spec.fnCreatedCell($div[0], item.obj.getData(oData), oData);
  15655. });
  15656. },
  15657. /**
  15658. Some properties have special formating needs, loop through all the properties
  15659. and call their 'formatContent' methods
  15660. **/
  15661. formatContent: function(nTd) {
  15662. var $nTd = $(nTd);
  15663. $.each(this.items, function(index, item) {
  15664. if (item.spec.formatContent) {
  15665. var itemContainer = $nTd.find('.' + item.type.toLowerCase());
  15666. if (itemContainer.length) {
  15667. item.spec.formatContent(itemContainer);
  15668. }
  15669. }
  15670. });
  15671. }
  15672. });
  15673. return MultipleProperties;
  15674. });
  15675. /*
  15676. *+------------------------------------------------------------------------+
  15677. *| Licensed Materials - Property of IBM
  15678. *| IBM Cognos Products: Content Explorer
  15679. *| (C) Copyright IBM Corp. 2015, 2019
  15680. *|
  15681. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15682. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15683. *+------------------------------------------------------------------------+
  15684. */
  15685. define('bacontentnav/common/ui/list_columns/Name',[
  15686. 'underscore',
  15687. './Column',
  15688. '../list_actions/DefaultAction',
  15689. '../list_actions/DefaultActionHandler',
  15690. '../../../utils/ContentStoreObject',
  15691. '../../../nls/StringResource',
  15692. '../../../utils/UIHelper',
  15693. '../../../lib/@waca/core-client/js/core-client/ui/KeyCodes'
  15694. ], function(_, Column, DefaultAction, DefaultActionHandler, ContentStoreObject, StringResource, UIHelper, KeyCodes) {
  15695. 'use strict';
  15696. /**
  15697. options.navigateCallback {function} - function to call when the user clicks on a container. The link to navigate to and breadcrumb information will be passed in the callback
  15698. **/
  15699. var Name = Column.extend({
  15700. _bNavigable: true,
  15701. getSpec: function() {
  15702. return Promise.resolve({
  15703. 'name': 'name',
  15704. 'label': StringResource.get('name'),
  15705. 'headerClass': 'name',
  15706. 'mData': this.getData.bind(this),
  15707. 'sClass': 'name',
  15708. 'weight': 20,
  15709. 'fnCreatedCell': this.createEllipseCell.bind(this),
  15710. 'formatContent': this.processTextForEllipses.bind(this),
  15711. 'type': 'natural-ci'
  15712. });
  15713. },
  15714. _getData: function(oRowData) {
  15715. return _.escape(oRowData[ContentStoreObject.DEFAULT_NAME]);
  15716. },
  15717. addClickAction: function($div, nParent, sData, oData) {
  15718. return new Promise(function(resolve /*, reject*/ ) {
  15719. var objType = ContentStoreObject.getType(oData);
  15720. var listControl = this.getListControl();
  15721. if (!this.navigateOnly || (UIHelper.isContainer(objType) && !listControl.singleSelectCallback)) {
  15722. var promise;
  15723. var defaultAction = new DefaultAction({
  15724. 'glassContext': this.glassContext,
  15725. 'oData': oData,
  15726. 'listControl': listControl
  15727. });
  15728. // Search results don't return any permissions, so always show the item as a link
  15729. if (UIHelper.isValid(oData)) {
  15730. promise = oData[ContentStoreObject.PERMISSIONS] ? defaultAction.canExecute() : Promise.resolve(true);
  15731. } else {
  15732. promise = Promise.resolve(false);
  15733. }
  15734. // If the promise is resolved
  15735. promise.then(function(defaultAction, bCanExecute) {
  15736. if (bCanExecute) {
  15737. $div.on('primaryaction', function(bCanExecute, evt) {
  15738. if (evt.shiftKey || evt.ctrlKey || evt.metaKey) {
  15739. resolve();
  15740. return; // shortcut the action
  15741. } else if (evt.which === KeyCodes.SPACE) { // why?
  15742. // so _selectRow can hide properties page
  15743. this.listControl.contentView.propertiesOverride = true;
  15744. // hide slideout on launch if not navigating
  15745. if (!UIHelper.isContainer(objType)) {
  15746. this.glassContext.appController.hideSlideOut();
  15747. }
  15748. } else {
  15749. DefaultActionHandler.executeAction({
  15750. evt: evt,
  15751. oData: oData,
  15752. listControl: listControl,
  15753. glassContext: this.glassContext,
  15754. action: defaultAction
  15755. });
  15756. }
  15757. }.bind(this, defaultAction));
  15758. $div.addClass('active').attr('role', 'link');
  15759. }
  15760. resolve();
  15761. }.bind(this, defaultAction)).catch(function() {
  15762. // Can't execute, just ignore the rejected promise
  15763. resolve();
  15764. });
  15765. } else {
  15766. if (UIHelper.isContainer(objType) && ContentStoreObject.hasPermissions(oData, ['traverse'])) {
  15767. $div.addClass('active').attr('role', 'link');
  15768. }
  15769. resolve();
  15770. }
  15771. // add 'idle' class for automation
  15772. if (ContentStoreObject.getDisabled(oData) || !UIHelper.isValid(oData) ||
  15773. (this.listControl && !UIHelper.hasRequiredCapabilities(oData, this.listControl.typesToOpen, this.listControl.capabilitiesRequired))) {
  15774. $div.addClass('dimmed idle');
  15775. $div.parent().parent().addClass('dimmed idle'); // this looks unsafe?
  15776. }
  15777. }.bind(this));
  15778. }
  15779. });
  15780. return Name;
  15781. });
  15782. /*
  15783. *+------------------------------------------------------------------------+
  15784. *| Licensed Materials - Property of IBM
  15785. *| IBM Cognos Products: Content Explorer
  15786. *| (C) Copyright IBM Corp. 2015, 2018
  15787. *|
  15788. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15789. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15790. *+------------------------------------------------------------------------+
  15791. */
  15792. define('bacontentnav/common/ui/list_columns/Owner',[
  15793. '../../../utils/ContentStoreObject',
  15794. '../../../nls/StringResource',
  15795. './Column',
  15796. 'underscore'
  15797. ], function(ContentStoreObject, StringResource, Column, _) {
  15798. 'use strict';
  15799. var Owner = Column.extend({
  15800. getSpec: function() {
  15801. return Promise.resolve({
  15802. 'name': 'owner',
  15803. 'label': StringResource.get('owner'),
  15804. 'sClass': 'nowrap',
  15805. 'weight': 10,
  15806. 'mData': this.getData.bind(this),
  15807. 'fnCreatedCell': this.createCell.bind(this)
  15808. });
  15809. },
  15810. _getData: function(oRowData) {
  15811. return _.escape(ContentStoreObject.getOwnerName(oRowData));
  15812. }
  15813. });
  15814. return Owner;
  15815. });
  15816. /*
  15817. *+------------------------------------------------------------------------+
  15818. *| Licensed Materials - Property of IBM
  15819. *| IBM Cognos Products: Content Explorer
  15820. *| (C) Copyright IBM Corp. 2015, 2018
  15821. *|
  15822. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15823. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15824. *+------------------------------------------------------------------------+
  15825. */
  15826. define('bacontentnav/common/ui/list_columns/Text',[
  15827. '../../../nls/StringResource',
  15828. './Column',
  15829. 'underscore'
  15830. ], function(StringResource, Column,_) {
  15831. 'use strict';
  15832. /**
  15833. Generic class that display the property as text
  15834. **/
  15835. var Text = Column.extend({
  15836. /**
  15837. @param options.propertyName {string} - name of the property where the text can be found
  15838. @param options.label {string} - Optional, the column header
  15839. @param options.clickCallback {function} - Optional, callback function to call when the user clicks on the text
  15840. @param options.showAsActiveLink {boolean} - Optional, if the text should be blue or not. Default is true if clickCallback is specified
  15841. **/
  15842. init: function(options) {
  15843. Text.inherited('init', this, arguments);
  15844. _.extend(this, options);
  15845. },
  15846. getSpec: function() {
  15847. return Promise.resolve({
  15848. 'name': this.propertyName,
  15849. 'label': this.label,
  15850. 'sClass': 'nowrap',
  15851. 'weight': 10,
  15852. 'mData': this.getData.bind(this),
  15853. 'fnCreatedCell': this.createEllipseCell.bind(this),
  15854. 'formatContent': this.processTextForEllipses.bind(this),
  15855. 'visible': this.visible
  15856. });
  15857. },
  15858. _getData: function(oRowData) {
  15859. return _.escape(oRowData[this.propertyName]) || '';
  15860. },
  15861. addClickAction: function($div, nParent, sData, oData) {
  15862. if (this.clickCallback) {
  15863. $div.addClass(this.showAsActiveLink !== false ? 'active' : 'clickable');
  15864. $div.attr('role', 'link');
  15865. $div.on('primaryaction', function(evt) {
  15866. // Only perform an action if no item is in creation mode (i.e. NewFolder) and we're not doing multiselect
  15867. if (evt.shiftKey || evt.ctrlKey || evt.metaKey || this.listControl.isMultitouchActive()) {
  15868. return;
  15869. }
  15870. this.clickCallback(oData);
  15871. }.bind(this));
  15872. }
  15873. }
  15874. });
  15875. return Text;
  15876. });
  15877. /*
  15878. *+------------------------------------------------------------------------+
  15879. *| Licensed Materials - Property of IBM
  15880. *| IBM Cognos Products: Content Explorer
  15881. *| (C) Copyright IBM Corp. 2015, 2018
  15882. *|
  15883. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15884. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15885. *+------------------------------------------------------------------------+
  15886. */
  15887. define('bacontentnav/common/ui/list_columns/Permission',[
  15888. '../../../utils/ContentStoreObject',
  15889. '../../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  15890. '../../../nls/StringResource',
  15891. './Text',
  15892. '../../../utils/ContentManagement',
  15893. '../../../utils/PolicyHelper'
  15894. ], function(ContentStoreObject, ContentFormatter, StringResource, Text, ContentManagement, PolicyHelper) {
  15895. 'use strict';
  15896. /**
  15897. options.navigateCallback {function} - function to call when the user clicks on a container. The link to navigate to and breadcrumb information will be passed in the callback
  15898. **/
  15899. var Permission = Text.extend({
  15900. getSpec: function() {
  15901. return Promise.resolve({
  15902. 'name': 'policy',
  15903. 'label': StringResource.get('permissionHeader'),
  15904. 'headerClass': 'name',
  15905. 'mData': this.getData.bind(this),
  15906. 'sClass': 'name',
  15907. 'weight': 10,
  15908. 'fnCreatedCell': this.createEllipseCell.bind(this),
  15909. 'formatContent': this.processTextForEllipses.bind(this)
  15910. });
  15911. },
  15912. _getData: function(oRowData) {
  15913. return PolicyHelper.getSimplifiedPermissions(oRowData.permissions);
  15914. },
  15915. addClickAction: function($div, nParent, sData, oData) {
  15916. if (this.clickCallback) {
  15917. $div.addClass(this.showAsActiveLink !== false ? 'active' : 'clickable');
  15918. $div.attr('role', 'link');
  15919. $div.on('primaryaction', function(evt) {
  15920. // Only perform an action if no item is in creation mode (i.e. NewFolder) and we're not doing multiselect
  15921. if (evt.shiftKey || evt.ctrlKey || evt.metaKey || this.listControl.isMultitouchActive()) {
  15922. return;
  15923. }
  15924. /*jshint unused: false */
  15925. this.clickCallback(oData);
  15926. }.bind(this, oData));
  15927. }
  15928. }
  15929. });
  15930. return Permission;
  15931. });
  15932. /*
  15933. *+------------------------------------------------------------------------+
  15934. *| Licensed Materials - Property of IBM
  15935. *| IBM Cognos Products: Content Explorer
  15936. *| (C) Copyright IBM Corp. 2016, 2018
  15937. *|
  15938. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15939. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15940. *+------------------------------------------------------------------------+
  15941. */
  15942. define('bacontentnav/common/ui/list_columns/RadioButtons',[
  15943. '../../../lib/@waca/core-client/js/core-client/utils/Utils',
  15944. './BaseIcon'
  15945. ], function(Utils, Icon) {
  15946. 'use strict';
  15947. var RadioButtons = Icon.extend({
  15948. createObjectImg: function() {
  15949. var $div = $('<div>', {
  15950. role: 'img',
  15951. tabindex: '-1',
  15952. 'class': 'roundButton'
  15953. });
  15954. var $svg = $('<svg><circle class="outer" cx="8" cy="8" r="7"></circle><circle class="radioBtn inner" cx="8" cy="8" r="5"></circle></svg>');
  15955. $div.html($svg);
  15956. return $div;
  15957. }
  15958. });
  15959. return RadioButtons;
  15960. });
  15961. /*
  15962. *+------------------------------------------------------------------------+
  15963. *| Licensed Materials - Property of IBM
  15964. *| IBM Cognos Products: Content Explorer
  15965. *| (C) Copyright IBM Corp. 2017, 2018
  15966. *|
  15967. *| US Government Users Restricted Rights - Use, duplication or disclosure
  15968. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  15969. *+------------------------------------------------------------------------+
  15970. */
  15971. define('bacontentnav/common/ui/list_columns/Tenant',[
  15972. '../../../utils/ContentStoreObject',
  15973. '../../../nls/StringResource',
  15974. './Column',
  15975. 'underscore'
  15976. ], function(ContentStoreObject, StringResource, Column, _) {
  15977. 'use strict';
  15978. var Tenant = Column.extend({
  15979. _bNavigable: true,
  15980. getSpec: function() {
  15981. return Promise.resolve({
  15982. 'name': 'tenantName',
  15983. 'label': StringResource.get('tenant'),
  15984. 'headerClass': 'name',
  15985. 'mData': this.getData.bind(this),
  15986. 'sClass': 'name',
  15987. 'weight': 15,
  15988. 'fnCreatedCell': this.createEllipseCell.bind(this),
  15989. 'formatContent': this.processTextForEllipses.bind(this),
  15990. 'type': 'natural-ci'
  15991. });
  15992. },
  15993. _getData: function(oRowData) {
  15994. return this._getTenantNameByID(_.escape(oRowData[ContentStoreObject.TENANT_ID]));
  15995. },
  15996. _getTenantNameByID: function(tenantID) {
  15997. var tenantName;
  15998. if (tenantID === '') {
  15999. tenantName = tenantID;
  16000. } else {
  16001. var tenants = this.glassContext.getCoreSvc('.UserProfile').tenants;
  16002. var tenant = _.find(tenants, function(tenant){
  16003. return tenant.tenantID === tenantID;
  16004. });
  16005. if (tenant) {
  16006. tenantName = tenant.defaultName;
  16007. } else {
  16008. tenantName = tenantID;
  16009. }
  16010. }
  16011. return _.escape(tenantName);
  16012. }
  16013. });
  16014. return Tenant;
  16015. });
  16016. /*
  16017. *+------------------------------------------------------------------------+
  16018. *| Licensed Materials - Property of IBM
  16019. *| IBM Cognos Products: Content Explorer
  16020. *| (C) Copyright IBM Corp. 2015, 2017
  16021. *|
  16022. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16023. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16024. *+------------------------------------------------------------------------+
  16025. */
  16026. define('bacontentnav/common/ui/list_columns/Time',[
  16027. '../../../utils/ContentStoreObject',
  16028. '../../../nls/StringResource',
  16029. './Column',
  16030. '../../../lib/@waca/core-client/js/core-client/utils/DateTimeUtils',
  16031. '../../../utils/GlassContextHelper',
  16032. 'underscore'
  16033. ], function(ContentStoreObject, StringResource, Column, DateTimeUtils, GlassContextHelper, _) {
  16034. 'use strict';
  16035. /**
  16036. Class that knows how to correctly format time
  16037. **/
  16038. var Time = Column.extend({
  16039. COLUMN_LABELS: {
  16040. 'modificationTime': StringResource.get('modificationTime'),
  16041. 'timestamp': StringResource.get('lastUsed')
  16042. },
  16043. displayInline: false,
  16044. /**
  16045. @param options.propertyName {string} - name of the property where the GMT time can be found in the JSON response
  16046. @param options.label {string} - Optional, the Time class knows the label for the most common time properties.
  16047. @param options.displayInline {boolean} - optional, if the time is diaplayed in a line
  16048. **/
  16049. init: function(options) {
  16050. Time.inherited('init', this, arguments);
  16051. _.extend(this, options);
  16052. if (!this.label) {
  16053. this.label = this.COLUMN_LABELS[this.propertyName];
  16054. }
  16055. },
  16056. getSpec: function() {
  16057. return Promise.resolve({
  16058. 'name': this.propertyName,
  16059. 'label': this.label,
  16060. 'sClass': 'nowrap',
  16061. 'width': '100px',
  16062. 'mData': this.getData.bind(this),
  16063. 'fnCreatedCell': this.createCell.bind(this),
  16064. 'visible': this.visible
  16065. });
  16066. },
  16067. _getData: function(oRowData) {
  16068. return oRowData[this.propertyName] || '';
  16069. },
  16070. createCell: function(parentNode, sData) {
  16071. var $parent = $(parentNode);
  16072. if (sData === '') {
  16073. $parent.text('---');
  16074. } else {
  16075. var date = DateTimeUtils.formatDate(sData, 'short', GlassContextHelper.getLocaleTime(this.glassContext)).toString();
  16076. var time = DateTimeUtils.formatTime(sData, 'short', GlassContextHelper.getLocaleTime(this.glassContext)).toString();
  16077. if (this.displayInline) {
  16078. var timestamp = [date, time].join(' ');
  16079. var $timestamp = $('<div>', {
  16080. 'text': timestamp,
  16081. 'class': 'modifiedTime displayInline'
  16082. });
  16083. $parent.text('');
  16084. $parent.append($timestamp);
  16085. } else {
  16086. var $date = $('<div>').text(date);
  16087. var $time = $('<div>', {
  16088. 'text': time,
  16089. 'class': 'modifiedTime'
  16090. });
  16091. $parent.text('');
  16092. $parent.append($date, $time);
  16093. }
  16094. }
  16095. }
  16096. });
  16097. return Time;
  16098. });
  16099. /*
  16100. *+------------------------------------------------------------------------+
  16101. *| Licensed Materials - Property of IBM
  16102. *| IBM Cognos Products: Content Explorer
  16103. *| (C) Copyright IBM Corp. 2017
  16104. *|
  16105. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16106. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16107. *+------------------------------------------------------------------------+
  16108. */
  16109. // This file is used to create the require.js layers. Only the entry points are necessary
  16110. define('bacontentnav/common/ui/list_columns/all',[
  16111. './AccountIcon',
  16112. './BirdBeakMenu',
  16113. './ClickableIcon',
  16114. './ContextMenu',
  16115. './Location',
  16116. './MultipleProperties',
  16117. './Name',
  16118. './Owner',
  16119. './Permission',
  16120. './RadioButtons',
  16121. './Tenant',
  16122. './Time'
  16123. ], function() {
  16124. 'use strict';
  16125. });
  16126. /*
  16127. *+------------------------------------------------------------------------+
  16128. *| Licensed Materials - Property of IBM
  16129. *| IBM Cognos Products: ba-content-nav
  16130. *| (C) Copyright IBM Corp. 2018
  16131. *|
  16132. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16133. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16134. *+------------------------------------------------------------------------+
  16135. */
  16136. define('bacontentnav/common/ui/list_actions/TargetListAction',[
  16137. './ListAction'
  16138. ], function(ListAction) {
  16139. 'use strict'; //NOSONAR
  16140. /**
  16141. * This list action should try to use the original target of the action (the event target), and not one provided via indirection, such as through a shortcut.
  16142. */
  16143. var TargetListAction = ListAction.extend({
  16144. getSelectedContext: function(options) {
  16145. // if available, return the event target selected context
  16146. var activeObject = options && options.target && options.target.activeObject;
  16147. return activeObject && (activeObject.targetSelectedContext || activeObject.aSelectedContext);
  16148. }
  16149. });
  16150. return TargetListAction;
  16151. });
  16152. /*
  16153. *+------------------------------------------------------------------------+
  16154. *| Licensed Materials - Property of IBM
  16155. *| IBM Cognos Products: Content Explorer
  16156. *| (C) Copyright IBM Corp. 2017, 2020
  16157. *|
  16158. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16159. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16160. *+------------------------------------------------------------------------+
  16161. */
  16162. define('bacontentnav/ui/dialogs/ErrorDialog',[
  16163. '../../lib/@waca/core-client/js/core-client/ui/core/Class',
  16164. '../../nls/StringResource',
  16165. 'jquery',
  16166. 'underscore'
  16167. ], function(Class, StringResource, $, _) {
  16168. var Dialog = null;
  16169. Dialog = Class.extend({
  16170. _buttons: ['ok'],
  16171. init: function(options) {
  16172. void(Class);
  16173. this._options = options;
  16174. _.defaults(this._options, { details: true });
  16175. Dialog.inherited('init', this, [this._options]);
  16176. },
  16177. open: function() {
  16178. this._options.glassContext.showMessage(this.renderContent(), this._options.title, 'error', this._buttons, this._options.width, undefined, true, 'errorDialog');
  16179. },
  16180. renderContent: function() {
  16181. var node = $('<div>');
  16182. if (this._options.details && this._options.msg) {
  16183. node.append('<h3>' + StringResource.get('details') + '</h3>');
  16184. node.append(
  16185. $('<textarea>', {
  16186. 'class': 'errorDetails',
  16187. 'html': _.escape(this._options.msg)
  16188. })
  16189. );
  16190. } else {
  16191. node.append(
  16192. $('<div>', {
  16193. 'class': 'messageBox ' + this.type,
  16194. 'html': _.escape(this._options.msg)
  16195. })
  16196. );
  16197. }
  16198. return node.html();
  16199. }
  16200. });
  16201. return Dialog;
  16202. });
  16203. /*
  16204. *+------------------------------------------------------------------------+
  16205. *| Licensed Materials - Property of IBM
  16206. *| IBM Cognos Products: Content Explorer
  16207. *| (C) Copyright IBM Corp. 2015, 2020
  16208. *|
  16209. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16210. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16211. *+------------------------------------------------------------------------+
  16212. */
  16213. define('bacontentnav/common/ui/list_actions/DeleteAction',[
  16214. 'underscore',
  16215. './TargetListAction',
  16216. '../../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  16217. '../../../utils/ContentServiceUrls',
  16218. '../../../utils/ContentStoreObject',
  16219. '../../../utils/GlassContextHelper',
  16220. '../../../nls/StringResource',
  16221. '../../../lib/@waca/core-client/js/core-client/ui/dialogs/ConfirmationDialog',
  16222. '../../../ui/dialogs/ErrorDialog'
  16223. ], function(_, TargetListAction, BidiUtil, ContentServiceUrls, ContentStoreObject, GlassContextHelper, StringResource, ConfirmationDialog, ErrorDialog) {
  16224. 'use strict'; //NOSONAR
  16225. var itemsToDelete = [];
  16226. var DeleteAction = TargetListAction.extend({
  16227. isItemVisible: function(options) {
  16228. if (DeleteAction.inherited('isItemVisible', this, [options])) {
  16229. var selectedContext = this.getSelectedContext(options);
  16230. if (selectedContext) {
  16231. return _.every(selectedContext, function(selection) {
  16232. return ContentStoreObject.hasPermissions(selection, ['write']);
  16233. });
  16234. }
  16235. }
  16236. return false;
  16237. },
  16238. execute: function(options) {
  16239. var aSelectionContext = this.getSelectedContext(options);
  16240. if (!aSelectionContext) {
  16241. return;
  16242. }
  16243. //create array of intersection of items waiting to be deleted and items currently selected
  16244. var commonValues = _.filter(aSelectionContext, function (item1) {
  16245. return _.some(this, function (item2) {
  16246. return item1.id === item2.id;
  16247. });
  16248. }, itemsToDelete);
  16249. //check if intersection is greater than 0, if it is show error dialog and return
  16250. if(commonValues.length > 0){
  16251. this.showDuplicateDeleteError(options.glassContext);
  16252. return;
  16253. }
  16254. var listControl = this.getListControl(options);
  16255. var unableDeleteIndex = [];
  16256. var totalSelectedItems = aSelectionContext.length;
  16257. aSelectionContext = _.filter(aSelectionContext, function(el, index) {
  16258. if (ContentStoreObject.hasPermissions(el, ['write'])) {
  16259. return true;
  16260. }
  16261. unableDeleteIndex.push(index);
  16262. return false;
  16263. });
  16264. var oDialog;
  16265. if (aSelectionContext.length === totalSelectedItems) {
  16266. oDialog = new ConfirmationDialog('confirmDelete', StringResource.get('confirmDelete'), StringResource.get('confirmDeleteMessage'));
  16267. } else {
  16268. var unableDelete = totalSelectedItems - aSelectionContext.length;
  16269. oDialog = new ConfirmationDialog('confirmDelete', StringResource.get('confirmDelete'), StringResource.get('confirmDeleteAllowed', {
  16270. number: unableDelete
  16271. }));
  16272. }
  16273. oDialog.ok = this.onOk.bind(oDialog, listControl);
  16274. oDialog.cancel = this.onCancel.bind(oDialog, listControl);
  16275. oDialog.confirm(this.onConfirm.bind(this, aSelectionContext, options, unableDeleteIndex));
  16276. oDialog.renderContent($('<div>'));
  16277. oDialog._container().addClass('contentDeleteConfirmDialog');
  16278. },
  16279. onOk: function(listControl) {
  16280. if (listControl && listControl.getSelectedRows) {
  16281. // On OK focus to the next row after deletion, if there is no next row, focus to the previous row.
  16282. var firstRow = $(listControl.getSelectedRows()[0]);
  16283. if (firstRow.next().length) {
  16284. firstRow = firstRow.next();
  16285. } else if (firstRow.prev().length) {
  16286. firstRow = firstRow.prev();
  16287. }
  16288. this.setLaunchPoint(firstRow.find('.ellipsesButton_cell')[0]);
  16289. }
  16290. ConfirmationDialog.inherited('ok', this, arguments);
  16291. if (this._confirmCallback) {
  16292. this._confirmCallback();
  16293. }
  16294. },
  16295. onCancel: function(listControl) {
  16296. if (listControl && listControl.getSelectedRows) {
  16297. this.setLaunchPoint($(listControl.getSelectedRows()[0]).find('.ellipsesButton_cell')[0]);
  16298. }
  16299. ConfirmationDialog.inherited('cancel', this, arguments);
  16300. if (this._cancelCallback) {
  16301. this._cancelCallback();
  16302. }
  16303. },
  16304. onConfirm: function(aSelectionContext, options, unableDeleteIndex) {
  16305. itemsToDelete = aSelectionContext;
  16306. var glassContext = options.glassContext;
  16307. var eventRouter = glassContext.getCoreSvc('.Events');
  16308. var url, sText;
  16309. var listControl = this.getListControl(options);
  16310. if (listControl && !options.target.activeObject.renderFromReact) {
  16311. listControl.aSelectedRows = _.filter(listControl.aSelectedRows, function(el, index) {
  16312. return !_.contains(unableDeleteIndex, index);
  16313. });
  16314. }
  16315. if (aSelectionContext.length === 1) {
  16316. url = ContentStoreObject.getSelfLink(aSelectionContext[0]) + '?force=true&recursive=true';
  16317. sText = StringResource.get('toastDoneDeletingSingular', {
  16318. 'nameOfItem': BidiUtil.enforceTextDirection(aSelectionContext[0].defaultName)
  16319. });
  16320. } else {
  16321. for (var i = 0; i < aSelectionContext.length; i += 1) {
  16322. if (i === 0) {
  16323. url = ContentServiceUrls.getBaseObjectsURL() + '?ids=' + aSelectionContext[i].id;
  16324. } else {
  16325. url += ',' + aSelectionContext[i].id;
  16326. }
  16327. }
  16328. url += '&force=true&recursive=true';
  16329. sText = StringResource.get('toastDoneDeleting', {
  16330. 'noOfItems': aSelectionContext.length
  16331. });
  16332. }
  16333. eventRouter.trigger('deleteAction:begin', aSelectionContext);
  16334. glassContext.getCoreSvc('.Ajax').ajax({
  16335. 'dataType': 'json',
  16336. 'type': 'DELETE',
  16337. 'url': url
  16338. }).then(function() {
  16339. itemsToDelete = [];
  16340. if (listControl && !options.target.activeObject.renderFromReact) {
  16341. listControl.removeSelectedRows();
  16342. if (listControl.contentView.slideout && listControl.contentView.slideout.child) {
  16343. listControl.contentView.slideout.child.remove();
  16344. }
  16345. }
  16346. aSelectionContext.forEach(function(context) {
  16347. glassContext.getSvc('.Content').then(function(contentSvc){
  16348. contentSvc.removeFromMRU(context);
  16349. });
  16350. });
  16351. GlassContextHelper.displayToast(glassContext, sText);
  16352. eventRouter.trigger('deleteAction:done', aSelectionContext);
  16353. if (options.target.activeObject.onDelete){
  16354. options.target.activeObject.onDelete(aSelectionContext);
  16355. }
  16356. })
  16357. .catch(function(err) {
  16358. if(err && err.requestInfo.jqXHR.responseJSON.errorCode === 'caf'){
  16359. var options = {
  16360. 'type': 'repeatedDeleteError',
  16361. 'title': StringResource.get('repeatedDeleteError'),
  16362. 'msg': err.jqXHR.responseJSON.messages.join('\n'),
  16363. 'width': '600px',
  16364. 'glassContext': glassContext
  16365. };
  16366. var eDialog = new ErrorDialog(options);
  16367. eDialog.open();
  16368. } else {
  16369. GlassContextHelper.showAjaxServiceError(glassContext, err);
  16370. }
  16371. eventRouter.trigger('deleteAction:fail', aSelectionContext);
  16372. });
  16373. },
  16374. showDuplicateDeleteError: function(glassContext){
  16375. var errorDialogOptions = {
  16376. 'type': 'repeatedDeleteError',
  16377. 'title': StringResource.get('repeatedDeleteErrorTitle'),
  16378. 'msg': StringResource.get('repeatedDeleteError'),
  16379. 'width': '600px',
  16380. 'glassContext': glassContext
  16381. };
  16382. var eDialog = new ErrorDialog(errorDialogOptions);
  16383. eDialog.open();
  16384. }
  16385. });
  16386. return DeleteAction;
  16387. });
  16388. /**
  16389. * Licensed Materials - Property of IBM
  16390. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2017
  16391. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  16392. */
  16393. define('bacontentnav/common/ui/ContentGenericDialog',['../../lib/@waca/core-client/js/core-client/ui/dialogs/GenericViewDialog', 'underscore'], function(GenericViewDialog, _) {
  16394. 'use strict';
  16395. /**
  16396. Dialog that renders a generic view:
  16397. the view should implement:
  16398. getButtonSpec: returns a button spec in the form that Gemini BaseDialog would accept
  16399. this dialog gets passed into the view through options in the constructor(options.dialog)
  16400. this dialog exposes the jquery nodes of the buttons through the {defaultId,value} map
  16401. **/
  16402. var ContentGenericDialog = GenericViewDialog.extend({
  16403. /**
  16404. @constructor
  16405. @param options.title - title displayed at the top of the dialog
  16406. @param options.module - module for the view to be displayed inside of the dialog (this module should implement fn:getButtonSpec)
  16407. @param options.viewOtpions - options that are to be passed into the constructor of module (above)
  16408. @param options.cssClass - css class string that will be appended to the modalDialog div
  16409. **/
  16410. init: function(options) {
  16411. ContentGenericDialog.inherited('init', this, arguments);
  16412. this.title = options.title;
  16413. this.viewClass = options.viewClass;
  16414. this.viewOptions = options.viewOptions;
  16415. this.buttonNodes = {};
  16416. this.cssClass = options.cssClass || '';
  16417. this.view = new this.viewClass(_.extend(this.viewOptions, {
  16418. 'dialog': this
  16419. }));
  16420. if (this.view.getButtonSpec) {
  16421. this._buttons = this.view.getButtonSpec(options);
  16422. }
  16423. },
  16424. show: function() {
  16425. ContentGenericDialog.inherited('show', this, arguments);
  16426. this._container().find('.modalDialog').addClass(this.cssClass);
  16427. },
  16428. enableButton: function(id) {
  16429. var button = this._container().find('.dialogButton.' + id);
  16430. button.removeClass('disabled');
  16431. button.attr('tabindex', '0');
  16432. button.attr('aria-disabled', 'false');
  16433. },
  16434. disableButton: function(id) {
  16435. var button = this._container().find('.dialogButton.' + id);
  16436. button.addClass('disabled');
  16437. button.attr('tabindex', '-1');
  16438. button.attr('aria-disabled', 'true');
  16439. }
  16440. });
  16441. return ContentGenericDialog;
  16442. });
  16443. /*
  16444. *+------------------------------------------------------------------------+
  16445. *| Licensed Materials - Property of IBM
  16446. *| IBM Cognos Products: Content Explorer
  16447. *| (C) Copyright IBM Corp. 2015, 2020
  16448. *|
  16449. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16450. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16451. *+------------------------------------------------------------------------+
  16452. */
  16453. define('bacontentnav/ui/dialogs/CopyMoveDialog',[
  16454. '../../nls/StringResource',
  16455. '../../utils/ContentStoreObject',
  16456. '../../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  16457. '../../common/ui/ContentGenericDialog',
  16458. '../../lib/@waca/core-client/js/core-client/utils/BidiUtil'
  16459. ], function(StringResource, ContentStoreObject, ContentFormatter, ContentGenericDialog, BidiUtil) {
  16460. 'use strict'; //NOSONAR
  16461. var CopyMoveDialog = ContentGenericDialog.extend({
  16462. _bShortenTitle: false,
  16463. _subtitleNode: null,
  16464. init: function() {
  16465. CopyMoveDialog.inherited('init', this, arguments);
  16466. },
  16467. renderTitle: function(node) {
  16468. var inputObjects = this.view.inputObjects;
  16469. var titleRow = $('<div>', {
  16470. 'class': 'copyMoveDialogTitleRow'
  16471. });
  16472. node.append(titleRow);
  16473. var title = $('<div>', {
  16474. 'class': 'copyMoveDialogTitle'
  16475. }).text(CopyMoveDialog.getStaticPartOfDialogTitle(this.viewOptions.type));
  16476. var subtitle = $('<div>', {
  16477. 'class': 'copyMoveDialogSubtitle'
  16478. });
  16479. titleRow.append(title, subtitle);
  16480. this._bShortenTitle = (inputObjects.length === 1);
  16481. subtitle.text(CopyMoveDialog.getVariablePartOfDialogTitle(inputObjects));
  16482. if (this._bShortenTitle) {
  16483. subtitle.attr('dir', BidiUtil.resolveBaseTextDir(subtitle.text()));
  16484. }
  16485. this._subtitleNode = subtitle;
  16486. return node;
  16487. },
  16488. show: function() {
  16489. /*jshint unused: false */
  16490. CopyMoveDialog.inherited('show', this, arguments);
  16491. var container = this._container();
  16492. container.addClass('copyMoveDialog');
  16493. if (this._bShortenTitle) {
  16494. ContentFormatter.middleShortenString(this._subtitleNode.get(0));
  16495. }
  16496. },
  16497. cancel: function() {
  16498. // TODO: revisit this - not all dialog views have a list control
  16499. if (this.view.getListControl && typeof(this.view.getListControl) === 'function' && this.view.getListControl().cancelActions) {
  16500. this.view.getListControl().cancelActions();
  16501. }
  16502. CopyMoveDialog.inherited('cancel', this, arguments);
  16503. }
  16504. });
  16505. CopyMoveDialog.getVariablePartOfDialogTitle = function(inputObjects) {
  16506. var sTitle;
  16507. var noOfItems = inputObjects.length;
  16508. if (noOfItems === 1) {
  16509. sTitle = ContentStoreObject.getName(inputObjects[0]);
  16510. } else {
  16511. sTitle = StringResource.get('noOfItemSelected', {
  16512. 'noOfItems': inputObjects.length
  16513. });
  16514. }
  16515. return sTitle;
  16516. };
  16517. CopyMoveDialog.getStaticPartOfDialogTitle = function(dialogType) {
  16518. var key = null;
  16519. if(dialogType === 'copyMoveDialog') {
  16520. key = 'copyMove';
  16521. } else if(dialogType === 'shortcutDialog') {
  16522. key = 'createShortcutDialogTitle';
  16523. }
  16524. return key !== null ? StringResource.get(key) : null;
  16525. };
  16526. CopyMoveDialog.getAriaLabelForDialogTitle = function(dialogType, inputObjects) {
  16527. return CopyMoveDialog.getStaticPartOfDialogTitle(dialogType) + ' ' + CopyMoveDialog.getVariablePartOfDialogTitle(inputObjects);
  16528. };
  16529. return CopyMoveDialog;
  16530. });
  16531. /*
  16532. *+------------------------------------------------------------------------+
  16533. *| Licensed Materials - Property of IBM
  16534. *| IBM Cognos Products: ba-content-nav
  16535. *| (C) Copyright IBM Corp. 2015, 2018
  16536. *|
  16537. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16538. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16539. *+------------------------------------------------------------------------+
  16540. */
  16541. define('bacontentnav/common/ui/list_actions/ManageContentAction',[
  16542. 'require',
  16543. 'underscore',
  16544. './TargetListAction',
  16545. '../../../ui/dialogs/CopyMoveDialog',
  16546. '../../../utils/GlassContextHelper',
  16547. '../../../utils/ContentStoreObject'
  16548. ], function(LocalRequire, _, TargetListAction, CopyMoveDialog, GlassContextHelper, ContentStoreObject) {
  16549. 'use strict'; //NOSONAR
  16550. var ManageContentAction = TargetListAction.extend({
  16551. isItemVisible: function(options) {
  16552. if (ManageContentAction.inherited('isItemVisible', this, [options])) {
  16553. var selectedContext = this.getSelectedContext(options);
  16554. if (selectedContext) {
  16555. return _.every(selectedContext, function(selection) {
  16556. return ContentStoreObject.hasPermissions(selection, ['read', 'write', 'traverse']);
  16557. });
  16558. }
  16559. }
  16560. return false;
  16561. },
  16562. execute: function(options) {
  16563. var inputObjects = this.getSelectedContext(options);
  16564. var listControl = this.getListControl(options);
  16565. if ((!listControl && options.target.activeObject.contentView && options.glassContext) || options.target.activeObject.renderFromReact) {
  16566. listControl = {
  16567. contentView: options.target.activeObject.contentView,
  16568. glassContext: options.glassContext
  16569. };
  16570. }
  16571. this._getAncestors(listControl, inputObjects).then(function(ancestors) {
  16572. LocalRequire(['../../../ManageContentDialogView'], function(ManageContentDialogView) {
  16573. var dialog = new CopyMoveDialog({
  16574. 'viewClass': ManageContentDialogView,
  16575. 'cssClass': 'contentListDialog',
  16576. 'id': 'ca_copymovedialog',
  16577. 'titleAriaLabel': CopyMoveDialog.getAriaLabelForDialogTitle(this._getModalType(), inputObjects),
  16578. 'viewOptions': this.getCopyMoveDialogViewOptions(listControl, inputObjects, ancestors)
  16579. });
  16580. dialog.open();
  16581. }.bind(this));
  16582. }.bind(this));
  16583. },
  16584. // Return the options for when we open the CopyMoveDialog
  16585. // can be overridden.
  16586. getCopyMoveDialogViewOptions: function(listControl, inputObjects, ancestors) {
  16587. return {
  16588. 'glassContext': listControl.glassContext,
  16589. 'type': this._getModalType(),
  16590. 'ancestors': ancestors,
  16591. 'showBreadcrumbs': true,
  16592. 'url': listControl.contentView.url,
  16593. 'selfUrl': listControl.contentView.selfUrl,
  16594. 'inputObjects': inputObjects,
  16595. 'showAddFolder': true,
  16596. 'invokingListControl': listControl,
  16597. 'moveDisabled': false
  16598. };
  16599. },
  16600. _getAncestors: function(listControl, inputObjects) {
  16601. var ancestors = listControl.contentView.getAncestors();
  16602. if (ancestors && ancestors.length > 0) {
  16603. return Promise.resolve(ancestors.slice());
  16604. } else {
  16605. // Only query for ancestors if all the input objects are from the same folder
  16606. if (this._areAllInputObjectsFromSameFolder(inputObjects)) {
  16607. return listControl.glassContext.getCoreSvc('.Ajax').ajax({
  16608. url: ContentStoreObject.getSelfLink(inputObjects[0]),
  16609. dataType: 'json',
  16610. type: 'GET',
  16611. data: {
  16612. 'fields': 'ancestors'
  16613. }
  16614. })
  16615. .then(function(response) {
  16616. var data = response.data && response.data.data && response.data.data[0];
  16617. // set the ancestors on each input object before returning them
  16618. if (data && data.ancestors) {
  16619. var ancestors = ContentStoreObject.getAncestors(data);
  16620. _.each(inputObjects, function(inputObject) {
  16621. inputObject.ancestors = ancestors.slice();
  16622. });
  16623. return Promise.resolve(ancestors.slice());
  16624. } else {
  16625. return Promise.resolve([]);
  16626. }
  16627. })
  16628. .catch(function(err) {
  16629. GlassContextHelper.showAjaxServiceError(this.glassContext, err);
  16630. return Promise.reject(err);
  16631. }.bind(this));
  16632. } else {
  16633. // We have a mix of input object locations, so do send any specific ancestor to the copy/move dialog
  16634. return Promise.resolve([]);
  16635. }
  16636. }
  16637. },
  16638. _areAllInputObjectsFromSameFolder: function(inputObjects) {
  16639. var inputObjectsAllFromSameFolder = true;
  16640. for (var i = 1; i < inputObjects.length; i = i + 1) {
  16641. if (inputObjects[0].formatedPath) {
  16642. if (inputObjects[0].formatedPath !== inputObjects[i].formatedPath) {
  16643. inputObjectsAllFromSameFolder = false;
  16644. break;
  16645. }
  16646. } else {
  16647. if (!ContentStoreObject.ancestorsEqual(inputObjects[0].ancestors, inputObjects[i].ancestors)) {
  16648. inputObjectsAllFromSameFolder = false;
  16649. break;
  16650. }
  16651. }
  16652. }
  16653. return inputObjectsAllFromSameFolder;
  16654. },
  16655. _getModalType: function() {
  16656. return 'copyMoveDialog';
  16657. }
  16658. });
  16659. return ManageContentAction;
  16660. });
  16661. /*
  16662. *+------------------------------------------------------------------------+
  16663. *| Licensed Materials - Property of IBM
  16664. *| IBM Cognos Products: Content Explorer
  16665. *| (C) Copyright IBM Corp. 2015, 2018
  16666. *|
  16667. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16668. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16669. *+------------------------------------------------------------------------+
  16670. */
  16671. define('bacontentnav/common/ui/list_actions/ManageContentActionCopyOnly',[
  16672. '../../../utils/ContentStoreObject',
  16673. './ManageContentAction',
  16674. 'underscore'
  16675. ], function(ContentStoreObject, ManageContentAction, _) {
  16676. 'use strict'; //NOSONAR
  16677. var ManageContentActionCopyOnly = ManageContentAction.extend({
  16678. isItemVisible: function(options) {
  16679. var selectedContext = this.getSelectedContext(options);
  16680. if (selectedContext) {
  16681. return _.every(selectedContext, function(selection) {
  16682. return ContentStoreObject.hasPermissions(selection, ['read']) && !ContentStoreObject.hasPermissions(selection, ['write', 'traverse']);
  16683. });
  16684. }
  16685. },
  16686. // returns the options for when we open the CopyMoveDialog
  16687. // can be overriden.
  16688. getCopyMoveDialogViewOptions: function(listControl, inputObjects, ancestors) {
  16689. return {
  16690. 'glassContext': listControl.glassContext,
  16691. 'type': this._getModalType(),
  16692. 'ancestors': ancestors,
  16693. 'showBreadcrumbs': true,
  16694. 'url': listControl.contentView.url,
  16695. 'selfUrl': listControl.contentView.selfUrl,
  16696. 'inputObjects': inputObjects,
  16697. 'showAddFolder': true,
  16698. 'invokingListControl': listControl,
  16699. 'moveDisabled' : true
  16700. };
  16701. }
  16702. });
  16703. return ManageContentActionCopyOnly;
  16704. });
  16705. /*
  16706. *+------------------------------------------------------------------------+
  16707. *| Licensed Materials - Property of IBM
  16708. *| IBM Cognos Products: Content Explorer
  16709. *| (C) Copyright IBM Corp. 2015, 2018
  16710. *|
  16711. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16712. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16713. *+------------------------------------------------------------------------+
  16714. */
  16715. define('bacontentnav/common/ui/list_actions/MRURemoveAction',[
  16716. './ListAction'
  16717. ], function(ListAction) {
  16718. 'use strict';
  16719. var MRURemoveAction = ListAction.extend({
  16720. isItemVisible: function(options) {
  16721. return this.hasStateID(options, 'CAMRUView');
  16722. },
  16723. execute: function(options) {
  16724. var contentServicePromise = options.glassContext.getSvc('.Content');
  16725. var aPromises = [];
  16726. this.getSelectedContext(options).forEach(function(mruEntry) {
  16727. aPromises.push(
  16728. contentServicePromise.then(function(contentSvc){
  16729. contentSvc.removeFromMRU(mruEntry);
  16730. }));
  16731. });
  16732. return Promise.all(aPromises)
  16733. .then(function() {
  16734. this.getListControl().updateDatatable();
  16735. this.getListControl().removeSelectedRows();
  16736. }.bind(this));
  16737. }
  16738. });
  16739. return MRURemoveAction;
  16740. });
  16741. /*
  16742. *+------------------------------------------------------------------------+
  16743. *| Licensed Materials - Property of IBM
  16744. *| IBM Cognos Products: Content Explorer
  16745. *| (C) Copyright IBM Corp. 2015, 2018
  16746. *|
  16747. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16748. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16749. *+------------------------------------------------------------------------+
  16750. */
  16751. define('bacontentnav/common/ui/list_actions/NavigateContainerAction',[
  16752. '../../../lib/@waca/core-client/js/core-client/ui/core/Class',
  16753. '../../../utils/ContentStoreObject',
  16754. 'underscore'
  16755. ], function(Class, ContentStoreObject, _) {
  16756. 'use strict';
  16757. var NavigateContainerAction = Class.extend({
  16758. init: function(options) {
  16759. NavigateContainerAction.inherited('init', this, arguments);
  16760. _.extend(this, options);
  16761. },
  16762. /**
  16763. * We require traverse to be able to navigate into a container
  16764. */
  16765. canExecute: function(options) {
  16766. var selectedContext = options.target.activeObject.aSelectedContext;
  16767. return ContentStoreObject.hasPermissions(selectedContext[0], ['traverse']);
  16768. },
  16769. doAction: function(object) {
  16770. var listControl = object.target.activeObject.oListControl;
  16771. var selectedObjects = object.target.activeObject.aSelectedContext;
  16772. if (listControl && selectedObjects.length === 1) {
  16773. listControl.contentView.navigate(selectedObjects[0], listControl.getSelectedRows()[0]);
  16774. return Promise.resolve();
  16775. } else {
  16776. return Promise.reject(new Error('No objects selected'));
  16777. }
  16778. }
  16779. });
  16780. return NavigateContainerAction;
  16781. });
  16782. /*
  16783. *+------------------------------------------------------------------------+
  16784. *| Licensed Materials - Property of IBM
  16785. *| IBM Cognos Products: Content Explorer
  16786. *| (C) Copyright IBM Corp. 2016, 2017
  16787. *|
  16788. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16789. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16790. *+------------------------------------------------------------------------+
  16791. */
  16792. // This file is used to create the require layers. Only the entry points are necessary
  16793. define('bacontentnav/common/ui/list_actions/all',[
  16794. './AddFolderAction',
  16795. './DefaultAction',
  16796. './DeleteAction',
  16797. './ManageContentAction',
  16798. './ManageContentActionCopyOnly',
  16799. './MRURemoveAction',
  16800. './NavigateContainerAction'
  16801. ], function() {
  16802. 'use strict';
  16803. });
  16804. define('text!bacontentnav/common/templates/ContentViewSwitcherTemplate.html',[],function () { return '<div class="contentViewSwitcher{{?it.showRootFolderName}} showRootFolderName{{?}}">\n\t<table role="presentation">\n\t\t<tbody>\n\t\t\t{{~it.rows :row:index}}\n\t\t\t\t<tr role="button" tabindex="0" class="rootSelector{{=index}}">\n\t\t\t\t\t<td class="icon" {{?!it.showRootFolderName}}title="{{=_.escape(row.defaultName)}}"{{?}}>\n\t\t\t\t\t\t<svg class="svgIcon">\n\t\t\t\t\t\t\t<use style="pointer-events: none;" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="{{=row.svgIcon}}"></use>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</td>\n\t\t\t\t\t{{?it.showRootFolderName}}\n\t\t\t\t\t<td class="name">\n\t\t\t\t\t\t<div title="{{=_.escape(row.defaultName)}}" class="active">{{=_.escape(row.defaultName)}}</div>\n\t\t\t\t\t</td>\n\t\t\t\t\t{{?}}\n\t\t\t\t</tr>\n\t\t\t{{~}}\n\t\t</tbody>\n\t</table>\n</div>\n';});
  16805. /*
  16806. *+------------------------------------------------------------------------+
  16807. *| Licensed Materials - Property of IBM
  16808. *| IBM Cognos Products: Content Explorer
  16809. *| (C) Copyright IBM Corp. 2015, 2020
  16810. *|
  16811. *| US Government Users Restricted Rights - Use, duplication or disclosure
  16812. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  16813. *+------------------------------------------------------------------------+
  16814. */
  16815. define('bacontentnav/common/ContentSelectionDialogView',[
  16816. 'text!./templates/ContentViewSwitcherTemplate.html',
  16817. './ContentListPageView',
  16818. '../nls/StringResource',
  16819. '../utils/ContentStoreObject',
  16820. '../lib/@waca/core-client/js/core-client/utils/ContentFormatter',
  16821. '../utils/UIHelper',
  16822. '../utils/ContentServiceUrls',
  16823. '../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  16824. 'doT',
  16825. '../lib/@waca/core-client/js/core-client/ui/KeyCodes',
  16826. 'underscore'
  16827. ], function(contentViewSwitcherTemplate, ContentListPageView, StringResource, ContentStoreObject, ContentFormatter, UIHelper, ContentServiceUrls, BidiUtil, dot, KeyCodes, _) {
  16828. 'use strict';
  16829. var ContentSelectionDialogView = ContentListPageView.extend({
  16830. GROUP_BY_TYPE_COLUMN_INDEX: 4,
  16831. stateId: 'ContentSelectionDialogView',
  16832. showDestination: true,
  16833. showRootFolderName: false,
  16834. /**
  16835. @options.showDestination {boolean} - default is true
  16836. @options.showRootFolderName {boolean} - default is false
  16837. @options.filterByTypes {string} - regular expression filter by content type(s). For example, if you want to only display folders, packages, and reports; set to "folder|package|report".
  16838. @options.onClickItemCallback {function} - if you want to be notified when clicking an item on content list
  16839. @options.dataManipulationCallback {function} - optional, called after the Ajax call to do any changes to the response before the datatable renders it
  16840. **/
  16841. init: function(options) {
  16842. /*jshint unused: false */
  16843. ContentSelectionDialogView.inherited('init', this, arguments);
  16844. this.contentListSortIndexes = UIHelper.getConfiguration('sort').indexes;
  16845. this.contentContainer = $('<div></div>', {
  16846. 'class': 'dialogContentContainer'
  16847. });
  16848. this.contentListContainer = $('<div></div>', {
  16849. 'class': 'contentListContainer'
  16850. });
  16851. this.$el.append(this.contentContainer);
  16852. this.contentContainer.append(this.contentListContainer);
  16853. var userProfileSettings = options.glassContext.getCoreSvc('.UserProfile') && options.glassContext.getCoreSvc('.UserProfile').userProfileSettings;
  16854. var myContentHidden = userProfileSettings &&
  16855. userProfileSettings.ui_excludedFeatures &&
  16856. userProfileSettings.ui_excludedFeatures.ids &&
  16857. userProfileSettings.ui_excludedFeatures.ids.indexOf('com.ibm.bi.contentApps.myContentFoldersSlideout') >= 0;
  16858. var teamContentHidden = false;
  16859. if (options.alwaysShowTeamContent !== true) {
  16860. teamContentHidden = userProfileSettings &&
  16861. userProfileSettings.ui_excludedFeatures &&
  16862. userProfileSettings.ui_excludedFeatures.ids &&
  16863. userProfileSettings.ui_excludedFeatures.ids.indexOf('com.ibm.bi.contentApps.teamFoldersSlideout') >= 0;
  16864. }
  16865. if (!this.ancestors || this.ancestors.length === 0) {
  16866. if (teamContentHidden) {
  16867. this.ancestors = [ContentStoreObject.getRootMyFoldersAncestors()];
  16868. } else {
  16869. this.ancestors = [this.getRootAncestor()];
  16870. }
  16871. }
  16872. var myFolder = ContentStoreObject.getRootMyFoldersAncestors();
  16873. var publicFolder = ContentStoreObject.getRootPublicFoldersAncestor();
  16874. var folderArray = [];
  16875. if(myContentHidden !== true){
  16876. folderArray.push(myFolder);
  16877. } if (teamContentHidden !== true) {
  16878. folderArray.push(publicFolder);
  16879. } if (!this.ancestors || this.ancestors.length === 0) {
  16880. if (teamContentHidden === true) {
  16881. this.folder = 'my_folders';
  16882. }
  16883. this.ancestors = [this.getRootAncestor()];
  16884. }
  16885. this.rootObjects = options.rootObjects || folderArray;
  16886. this.ancestorsMap = {};
  16887. this.rootObjects.forEach(function(rootObject) {
  16888. rootObject.svgIcon = UIHelper.getSVGIconForType(ContentStoreObject.getType(rootObject));
  16889. this.ancestorsMap[rootObject.id] = rootObject.id === this.ancestors[0].id ? this.ancestors : [rootObject];
  16890. }.bind(this));
  16891. this.selectedRootId = this.ancestors[0].id;
  16892. var ancestorsLength = this.ancestors.length;
  16893. var itemsLink = ContentStoreObject.getItemsLink(this.ancestors[ancestorsLength - 1]);
  16894. //ContentStoreObject use _meta.links.self to build items link, in case it is not there, try to build it with selfurl;
  16895. this.url = itemsLink ? itemsLink : this._buildItemsLinkWithSelfUrl(this.ancestors[ancestorsLength - 1].selfUrl);
  16896. this.selfUrl = ContentStoreObject.getSelfLink(this.ancestors[ancestorsLength - 1]);
  16897. this.navigateOnRowSelect = true;
  16898. this.dataManipulationCallback = options.dataManipulationCallback;
  16899. this.addURLParameters({
  16900. 'nav_filter': 'true',
  16901. 'fields': 'defaultName,disabled,hidden,permissions,userInterfaces,iconURI,defaultScreenTip,tags'
  16902. });
  16903. if (this.multiSelect) {
  16904. this.GROUP_BY_TYPE_COLUMN_INDEX = 5;
  16905. }
  16906. },
  16907. _buildItemsLinkWithSelfUrl: function(selfUrl) {
  16908. return selfUrl + '/items';
  16909. },
  16910. _getModuleName: function() {
  16911. return '../ContentSelectionDialogView';
  16912. },
  16913. renderContent: function() {
  16914. jQuery.fn.dataTableExt.oSort['string-asc'] = function(a, b) {
  16915. a = a.toString().toLowerCase();
  16916. b = b.toString().toLowerCase();
  16917. return UIHelper.getCollator().compare(a, b);
  16918. };
  16919. jQuery.fn.dataTableExt.oSort['string-desc'] = function(a, b) {
  16920. a = a.toString().toLowerCase();
  16921. b = b.toString().toLowerCase();
  16922. return UIHelper.getCollator().compare(a, b) * -1;
  16923. };
  16924. delete jQuery.fn.dataTableExt.oSort['string-pre'];
  16925. this.contentHeader = $('<div>', {
  16926. 'class': 'dialogContentHeader'
  16927. });
  16928. this.contentFooter = $('<div>', {
  16929. 'class': 'dialogContentFooter'
  16930. });
  16931. this.$el.prepend(this.contentHeader);
  16932. this.$el.append(
  16933. this.contentFooter);
  16934. var dataManipulationCallback = this.dataManipulationCallback || this.commonDataManipulationCallback;
  16935. var renderContentListOptions = {
  16936. 'browserResize': false,
  16937. 'disableColumnHeaders': true,
  16938. 'multiSelect': false,
  16939. 'canSelectCallback': this.canSelectCallback,
  16940. 'selectAcrossFolders': this.selectAcrossFolders,
  16941. 'selectAcrossFoldersSelectionChangeCallback': this.selectAcrossFoldersSelectionChangeCallback,
  16942. 'rightClickContextMenu': false,
  16943. 'columns': this._getColumnSpecification(),
  16944. 'url': this.url,
  16945. 'defaultSort': this.getDefaultSort(),
  16946. 'filterByTypes': this.filterByTypes,
  16947. 'typesToOpen': this.typesToOpen,
  16948. 'capabilitiesRequired': this.capabilitiesRequired,
  16949. 'dataManipulationCallback': dataManipulationCallback,
  16950. 'groupByColumnAPI': this.getGroupByColumnAPI(),
  16951. 'skipYBound': true // don't need to calculate the y-bound as it is constrained by dialog
  16952. };
  16953. if (this.multiSelect) {
  16954. renderContentListOptions.multiSelect = true;
  16955. }
  16956. var fRenderContentViewSwitcher = this.teamContentOnly === true ? function() {
  16957. return Promise.resolve();
  16958. } : this._renderContentViewSwitcher.bind(this);
  16959. return this._renderHeader()
  16960. .then(this._fetchCustomFolder.bind(this))
  16961. .then(fRenderContentViewSwitcher)
  16962. .then(this._renderFooter.bind(this))
  16963. .then(this.renderContentList.bind(this, renderContentListOptions))
  16964. .then(this._postRenderContent.bind(this));
  16965. },
  16966. _fetchCustomFolder: function() {
  16967. var userProfileSettings = this.glassContext.getCoreSvc('.UserProfile').userProfileSettings;
  16968. var customFolder = userProfileSettings && userProfileSettings.ui_teamFolders;
  16969. var path = customFolder && customFolder.pathRef;
  16970. if (path) {
  16971. path = path.replace(/^\//, '');
  16972. var pathURL = ContentServiceUrls.getBasePathURL() + encodeURIComponent(path);
  16973. return this.glassContext.getCoreSvc('.Ajax').ajax({
  16974. dataType: 'json',
  16975. url: pathURL
  16976. }).then(function(result) {
  16977. var cmObj = result.data.data[0];
  16978. cmObj.svgIcon = '#ba_content_nav-custom-folder_24';
  16979. this.ancestorsMap[cmObj.id] = cmObj.id === this.ancestors[0].id ? this.ancestors : [cmObj];
  16980. this.rootObjects.push(cmObj);
  16981. return Promise.resolve();
  16982. }.bind(this))
  16983. .catch(function(err){
  16984. this.logger.error(err);
  16985. return Promise.resolve();
  16986. }.bind(this));
  16987. } else {
  16988. return Promise.resolve();
  16989. }
  16990. },
  16991. //Override as necessary
  16992. _renderHeader: function() {
  16993. return Promise.resolve(true);
  16994. },
  16995. _renderFooter: function() {
  16996. this._renderDestinationInfo();
  16997. return Promise.resolve(true);
  16998. },
  16999. _renderDestinationInfo: function() {
  17000. if (!this.showDestination) {
  17001. return;
  17002. }
  17003. var destinationLabel = $('<div>', {
  17004. 'class': 'destinationLabel'
  17005. });
  17006. destinationLabel.text(StringResource.get('destination'));
  17007. this.destinationValue = $('<div>', {
  17008. 'class': 'destinationValue'
  17009. });
  17010. var destinationSection = $('<div>', {
  17011. 'class': 'destinationSection'
  17012. }).append(destinationLabel, this.destinationValue);
  17013. this.contentFooter.append(destinationSection);
  17014. this._updateDestination();
  17015. return destinationSection;
  17016. },
  17017. _postRenderContent: function() {
  17018. //Override if there is a need for special behaviour after content is rendered.
  17019. //Should return promise
  17020. return Promise.resolve(true);
  17021. },
  17022. //Renders the left portion of the content selection dialog
  17023. _renderContentViewSwitcher: function() {
  17024. var sHtml = dot.template(contentViewSwitcherTemplate)({
  17025. 'rows': this.rootObjects,
  17026. 'showRootFolderName': this.showRootFolderName
  17027. });
  17028. this.contentContainer.prepend(sHtml);
  17029. this._addSwitchRootFolderEventHandler();
  17030. this._updateContentViewSwitcher();
  17031. return Promise.resolve();
  17032. },
  17033. _addSwitchRootFolderEventHandler: function() {
  17034. this.rootObjects.forEach(function(rootObject, index) {
  17035. var rowNode = this.contentContainer.find('.rootSelector' + index);
  17036. rowNode.click(function() {
  17037. if (!rowNode.hasClass('selected')) {
  17038. this._switchRootFolder(rootObject);
  17039. }
  17040. }.bind(this));
  17041. rowNode.keydown(this._keydownHandler.bind(this, rowNode, rootObject));
  17042. }.bind(this));
  17043. },
  17044. _keydownHandler: function(rowNode, rootObject, evt) {
  17045. var result = true;
  17046. if (evt.keyCode === KeyCodes.SPACE || evt.keyCode === KeyCodes.ENTER) {
  17047. if (!rowNode.hasClass('selected')) {
  17048. this._switchRootFolder(rootObject);
  17049. result = false;
  17050. }
  17051. }
  17052. return result;
  17053. },
  17054. _updateContentViewSwitcher: function() {
  17055. this.rootObjects.forEach(function(rootObject, index) {
  17056. var rowNode = this.contentContainer.find('.rootSelector' + index);
  17057. if (rootObject.id === this.selectedRootId) {
  17058. rowNode.addClass('selected');
  17059. rowNode.attr('aria-pressed', 'true');
  17060. } else {
  17061. rowNode.removeClass('selected');
  17062. rowNode.attr('aria-pressed', 'false');
  17063. }
  17064. }.bind(this));
  17065. },
  17066. _switchRootFolder: function(rootObject) {
  17067. // Save the ancestor of the previously selected root
  17068. this.ancestorsMap[this.selectedRootId] = this.ancestors;
  17069. this.selectedRootId = rootObject.id;
  17070. this.ancestors = this.ancestorsMap[rootObject.id];
  17071. var lastAncestor = this.ancestors.pop();
  17072. this.navigate(lastAncestor);
  17073. },
  17074. /**
  17075. Defines the columns for the data table. The structure and properties of the definition come
  17076. from the datatable API.
  17077. **/
  17078. _getColumnSpecification: function() {
  17079. var columnSpecs = [{
  17080. 'type': 'Icon'
  17081. }, {
  17082. 'type': 'Name',
  17083. 'navigateOnly': true
  17084. }];
  17085. // There is a invisible column for ModifiedTime along with Name.
  17086. // This second 'hidden' column is required to allow DataTable to sort on ModifiedTime.
  17087. columnSpecs.push({
  17088. 'type': 'Time',
  17089. 'propertyName': ContentStoreObject.MODIFICATION_TIME,
  17090. 'visible': false
  17091. });
  17092. // Here is another invisible column groupByFolder for the calculated grouping value
  17093. columnSpecs.push({
  17094. 'type': 'Text',
  17095. 'propertyName': 'groupByFolder',
  17096. 'visible': false
  17097. });
  17098. // Here is another invisible column groupByType for the calculated grouping value
  17099. columnSpecs.push({
  17100. 'type': 'Text',
  17101. 'propertyName': 'groupByType',
  17102. 'visible': false
  17103. });
  17104. if (this.multiSelect) {
  17105. // push checkbox to the columnSpec when multiSelect enabled
  17106. columnSpecs.unshift({
  17107. 'type': 'Checkbox'
  17108. });
  17109. }
  17110. return columnSpecs;
  17111. },
  17112. _updateButtonsState: function() {
  17113. //Override as necessary;
  17114. },
  17115. updateDialog: function(oData) {
  17116. this._updateContentViewSwitcher();
  17117. this._updateDestination();
  17118. this._updateButtonsState(oData);
  17119. },
  17120. _updateDestination: function() {
  17121. if (!this.showDestination || !this.ancestors || !this.ancestors.length) {
  17122. return;
  17123. }
  17124. var destination = ContentStoreObject.getName(this.ancestors[this.ancestors.length - 1]);
  17125. this.destinationValue.text(destination);
  17126. ContentFormatter.middleShortenString(this.destinationValue.get(0));
  17127. var dir = BidiUtil.resolveBaseTextDir(this.destinationValue.text());
  17128. if (dir.length > 0) {
  17129. this.destinationValue.attr('dir', dir);
  17130. }
  17131. },
  17132. navigate: function(oData) {
  17133. if (this.onClickItemCallback) {
  17134. this.onClickItemCallback(oData);
  17135. }
  17136. ContentSelectionDialogView.inherited('navigate', this, arguments);
  17137. this.updateDialog(oData);
  17138. },
  17139. getDefaultSort: function() {
  17140. if (this.multiSelect) {
  17141. return [
  17142. [4, 'asc'],
  17143. [2, 'asc']
  17144. ];
  17145. } else {
  17146. return [
  17147. [3, 'asc'],
  17148. [1, 'asc']
  17149. ];
  17150. }
  17151. },
  17152. getSortSpec: function() {
  17153. return {
  17154. sortBy: {
  17155. name: 'name',
  17156. modificationTime: 'modificationTime'
  17157. },
  17158. order: {
  17159. sortedAscending: 'asc',
  17160. sortedDescending: 'desc'
  17161. }
  17162. };
  17163. },
  17164. getSortMappingSpec: function() {
  17165. return {
  17166. name: ['groupByFolder', 'name'],
  17167. modificationTime: ['groupByFolder', 'modificationTime'],
  17168. type: ['groupByType', 'name']
  17169. };
  17170. },
  17171. commonDataManipulationCallback: function(rawData, sortIndexes) {
  17172. if (sortIndexes === null) {
  17173. return;
  17174. }
  17175. rawData.data.forEach(function(data) {
  17176. // Add a couple of calculated fields 'groupByFolder' and 'groupByType' based on the 'type' value
  17177. var dataType = UIHelper.getDisplayType(data);
  17178. if (UIHelper.isContainer(dataType)) {
  17179. data.groupByFolder = sortIndexes.folders;
  17180. data.groupByType = data.groupByFolder;
  17181. } else {
  17182. // Anything else
  17183. data.groupByFolder = sortIndexes.others;
  17184. // For Type sort
  17185. if (UIHelper.isGroup(dataType, 'report')) {
  17186. data.groupByType = sortIndexes.reports;
  17187. } else if (UIHelper.isGroup(dataType, 'dashboard')) {
  17188. data.groupByType = sortIndexes.dashboards;
  17189. } else if (UIHelper.isGroup(dataType, 'data')) {
  17190. data.groupByType = sortIndexes.data;
  17191. } else if (UIHelper.isGroup(dataType, 'exploration')) {
  17192. data.groupByType = sortIndexes.explorations;
  17193. } else {
  17194. // Anything else
  17195. data.groupByType = sortIndexes.others;
  17196. }
  17197. }
  17198. });
  17199. },
  17200. getGroupByColumnAPI: function() {
  17201. return {
  17202. 'columnIndex': this.GROUP_BY_TYPE_COLUMN_INDEX,
  17203. 'getGroupName': function(group) {
  17204. var msgKey = _.find(Object.keys(this.contentListSortIndexes), function(sortIndex) {
  17205. return this.contentListSortIndexes[sortIndex] === group;
  17206. }.bind(this));
  17207. return msgKey && StringResource.get(msgKey) || group;
  17208. }.bind(this),
  17209. 'shouldGroup': function(api) {
  17210. var sortInfo = api.order();
  17211. return sortInfo && sortInfo[0] && sortInfo[0][0] === this.GROUP_BY_TYPE_COLUMN_INDEX;
  17212. }.bind(this)
  17213. };
  17214. }
  17215. });
  17216. return ContentSelectionDialogView;
  17217. });
  17218. define('text!bacontentnav/ui/views/templates/OpenView.html',[],function () { return '<!-- Licensed Materials - Property of IBM\n\n IBM Cognos Products: Cognos Analytics\n\n (C) Copyright IBM Corp. 2016\n\n US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.\n-->\n<div class="openView">\n\t<div class="selectFolderView"></div>\n</div>\n';});
  17219. /**
  17220. * Licensed Materials - Property of IBM
  17221. *
  17222. * IBM Cognos Products: BI UI Commons
  17223. *
  17224. * Copyright IBM Corp. 2015, 2020
  17225. *
  17226. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17227. */
  17228. //jshint maxparams:9
  17229. define('bacontentnav/ui/views/OpenView',[
  17230. 'jquery',
  17231. 'doT',
  17232. '../../lib/@waca/core-client/js/core-client/ui/core/View',
  17233. '../../common/ContentSelectionDialogView',
  17234. '../../utils/ContentStoreObject',
  17235. '../../utils/UIHelper',
  17236. 'text!./templates/OpenView.html',
  17237. '../../nls/StringResource'
  17238. ], function($, doT, BaseView, ContentView, ContentStoreObject, UIHelper, template, StringResources) {
  17239. /**
  17240. * Open view. This class renders a view with a folder selection section and an input to enter the file name.
  17241. *
  17242. * @param - options
  17243. *
  17244. * {
  17245. * 'glassContext': <glass context object> // Glass context object
  17246. * 'onOpen':function(){} // Callback when the view is opened
  17247. * 'onSelectionChange': function(selection){} // Callback when the folder selection has changed. The callback receives the selection object as a parameter
  17248. * }
  17249. *
  17250. */
  17251. var OpenView = BaseView.extend({
  17252. templateString: template,
  17253. events: {},
  17254. isDialog: false,
  17255. onDefaultAction: null, // default - no action. This is used for dialogs.
  17256. init: function(options) {
  17257. OpenView.inherited('init', this, arguments);
  17258. $.extend(this, options);
  17259. this._contentViewclass = this._contentViewClass || ContentView;
  17260. this._selectedItems = [];
  17261. },
  17262. render: function() {
  17263. this.$el.empty();
  17264. var sHtml = this.dotTemplate({
  17265. openLabel: this.filesToOpenTitle || StringResources.get('filesToOpen')
  17266. });
  17267. this.$el.append(sHtml);
  17268. var contentViewOptions = {
  17269. $el: this.$('.selectFolderView'),
  17270. 'glassContext': this.glassContext,
  17271. 'breadcrumbs': [{
  17272. 'label': this.defaultName || StringResources.get('teamFolders'),
  17273. 'url': this.url || '/v1/objects/.public_folders/items',
  17274. 'selfUrl': this.selfUrl || '/v1/objects/.public_folders'
  17275. }],
  17276. 'showBreadcrumbs': true,
  17277. 'showAddFolder': false,
  17278. 'showFilter': !this.filterByTypes || this.filterByTypes.length === 0,
  17279. 'showDestination': false,
  17280. 'url': this.url || 'v1/objects/.public_folders/items',
  17281. 'selfUrl': this.selfUrl || 'v1/objects/.public_folders',
  17282. 'rootObjects': this.rootObjects,
  17283. 'ancestors': ContentStoreObject.getAncestors({
  17284. ancestors: this.ancestors
  17285. }),
  17286. 'inputObjects': [],
  17287. 'filterByTypes': this.filterByTypes,
  17288. 'typesToOpen': this.typesToOpen,
  17289. 'capabilitiesRequired': this.capabilitiesRequired,
  17290. 'dataManipulationCallback': this.dataManipulationCallback,
  17291. 'teamContentOnly': this.teamContentOnly,
  17292. 'isDialog': this.isDialog,
  17293. 'onDefaultAction': this.onDefaultAction,
  17294. 'alwaysShowTeamContent': this.alwaysShowTeamContent
  17295. };
  17296. if (this.multiSelect) {
  17297. contentViewOptions.multiSelect = true;
  17298. contentViewOptions.canSelectCallback = this.canSelect.bind(this);
  17299. contentViewOptions.selectAcrossFolders = true;
  17300. contentViewOptions.selectAcrossFoldersSelectionChangeCallback = this.onMultiSelectionChange.bind(this);
  17301. } else {
  17302. contentViewOptions.onClickItemCallback = this.onSelectionChange.bind(this);
  17303. }
  17304. this.contentView = new this._contentViewclass(contentViewOptions);
  17305. if (this.contentView.addURLParameters) {
  17306. this.contentView.addURLParameters({
  17307. 'fields': 'searchPath'
  17308. });
  17309. if (this.extraUrlParameters) {
  17310. this.contentView.addURLParameters({
  17311. 'fields': this.extraUrlParameters
  17312. });
  17313. }
  17314. if (this.capabilitiesRequired) {
  17315. this.contentView.addURLParameters({
  17316. 'fields': 'effectiveUserCapabilities'
  17317. });
  17318. }
  17319. }
  17320. this.contentView.render();
  17321. this.$fileNames = this.$('.fileNames');
  17322. },
  17323. remove: function() {
  17324. OpenView.inherited('remove', this, arguments);
  17325. this.contentView.remove();
  17326. this._emptySelection();
  17327. },
  17328. /**
  17329. * Get an array of select objects
  17330. */
  17331. getSelectedItems: function() {
  17332. return this._selectedItems;
  17333. },
  17334. canSelect: function(data) {
  17335. return this._isTypeToOpen(UIHelper.getFilterType(data)) === true;
  17336. },
  17337. /**
  17338. * Default selection change callback. To be provide by the called in the constructor options
  17339. */
  17340. onSelectionChange: function(data) {
  17341. // To be provided by caller in constructor options to handle selection change
  17342. if (this._isSelected(data) === false) {
  17343. if (this._isTypeToOpen(UIHelper.getFilterType(data)) === true) {
  17344. if (!this.multiSelect) {
  17345. this._emptySelection();
  17346. }
  17347. this._selectedItems.push(data);
  17348. } else if (!this.multiSelect) {
  17349. this._emptySelection();
  17350. }
  17351. }
  17352. this._toggleOpenButton();
  17353. },
  17354. onMultiSelectionChange: function(selection) {
  17355. this._selectedItems = selection;
  17356. this.parent.updateSelectionCount(this._selectedItems.length);
  17357. this._toggleOpenButton();
  17358. },
  17359. _emptySelection: function() {
  17360. this._selectedItems = [];
  17361. },
  17362. clearAllSelected: function() {
  17363. if (this.contentView) {
  17364. this.contentView.clearAllSelected();
  17365. }
  17366. },
  17367. _setFocusAfterDeleteSelectedItem: function() {
  17368. this.parent.setFocus();
  17369. },
  17370. _toggleOpenButton: function() {
  17371. var openButton = this.parent.findFooterButton('open_button');
  17372. if (this._selectedItems.length === 0 || this.getSelectedItems()[0].disabled) {
  17373. openButton.disable();
  17374. } else {
  17375. openButton.enable();
  17376. }
  17377. },
  17378. _isTypeToOpen: function(type) {
  17379. var types = this.typesToOpen,
  17380. len = types ? types.length : 0,
  17381. ret = (len === 0);
  17382. for (var i = 0; i < len; i++) {
  17383. if (type === types[i]) {
  17384. ret = true;
  17385. break;
  17386. }
  17387. }
  17388. return ret;
  17389. },
  17390. _isSelected: function(data) {
  17391. var len = this._selectedItems.length,
  17392. item;
  17393. for (var i = 0; i < len; i++) {
  17394. item = this._selectedItems[i];
  17395. if (item.id === data.id) {
  17396. return true;
  17397. }
  17398. }
  17399. return false;
  17400. }
  17401. });
  17402. return OpenView;
  17403. });
  17404. /**
  17405. * Licensed Materials - Property of IBM
  17406. *
  17407. * IBM Cognos Products: BI UI Commons
  17408. *
  17409. * Copyright IBM Corp. 2015, 2021
  17410. *
  17411. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17412. */
  17413. define('bacontentnav/ui/dialogs/OpenDialog',['../../lib/@waca/core-client/js/core-client/ui/dialogs/GenericViewDialog',
  17414. '../views/OpenView',
  17415. '../../nls/StringResource'
  17416. ], function (BaseDialog, OpenView, StringResources) {
  17417. /**
  17418. * Create a save as dialog that will be used to select a folder and a file name.
  17419. *
  17420. * @param - options
  17421. * {
  17422. * glassContext: <glassContextObject>, // Glass context object.
  17423. * typesToOpen: string array, contains all types to open, for example: ['report']
  17424. * multiSelect: boolean, if true, support multiple files open
  17425. * onOpenCallback: function(items){ } // Callback when locations are selected.
  17426. * onCancelCallback: function(){ } // Callback when cancel button is pressed.
  17427. * options.primaryBtnText: String customized primary button text than the default "OK"
  17428. * options.dialogTitle: String customized dialog title than the default open dialog title
  17429. * options.filtersByTypes: Array customized 'filters by types' than the default open dialog supports
  17430. * options.dataManipulationCallback {functions} - Passed to the list control. Function will get called before the rendering of the data
  17431. * viewOptions.url String , viewOptions.selfUrl String and viewOptions.ancestors Array of objects are three parameters
  17432. * to customize the initial folder when dialog opens
  17433. * }
  17434. *
  17435. */
  17436. var OpenDialog = BaseDialog.extend({
  17437. init: function (options) {
  17438. this.options = options;
  17439. var typesToFilter = 'folder|package';
  17440. var typesToOpen = options['typesToOpen'];
  17441. for (var i = 0; i < typesToOpen.length; i++) {
  17442. typesToFilter = typesToFilter + '|' + typesToOpen[i];
  17443. }
  17444. var dialogOptions = {
  17445. 'buttons': [{
  17446. 'text': options.primaryBtnText || StringResources.get('open'),
  17447. 'handler': this.ok.bind(this),
  17448. 'type': 'primary',
  17449. 'defaultId': 'open_button'
  17450. },
  17451. {
  17452. 'handler': this.cancel.bind(this),
  17453. 'defaultId': 'cancel'
  17454. }],
  17455. 'viewClass': OpenView,
  17456. 'id': 'openDialogTitle',
  17457. 'title': options.dialogTitle || StringResources.get('openDialogTitle'),
  17458. 'viewOptions': {
  17459. 'ancestors': options.ancestors,
  17460. 'url': options.url,
  17461. 'selfUrl': options.selfUrl,
  17462. 'glassContext': options.glassContext,
  17463. 'onOpen': this.onOpen.bind(this),
  17464. 'isDialog': true,
  17465. 'onDefaultAction': this.onDefaultAction.bind(this),
  17466. 'filesToOpenTitle': options.filesToOpenTitle || StringResources.get('filesToOpen'),
  17467. 'typesToOpen': options['typesToOpen'] || [],
  17468. 'capabilitiesRequired': options['capabilitiesRequired'] || undefined,
  17469. 'multiSelect': options['multiSelect'] || false,
  17470. 'parent': this,
  17471. 'filterByTypes': options.filtersByTypes || [typesToFilter] || undefined,
  17472. 'rootObjects': options.rootObjects,
  17473. 'extraUrlParameters': this._getExtraUrlParameters(options['extraUrlParameters'], typesToOpen),
  17474. 'dataManipulationCallback': options.dataManipulationCallback,
  17475. 'teamContentOnly': options.teamContentOnly,
  17476. 'alwaysShowTeamContent': options.alwaysShowTeamContent || false
  17477. }
  17478. };
  17479. OpenDialog.inherited('init', this, [dialogOptions]);
  17480. },
  17481. _getExtraUrlParameters: function (extraUrlParameters, typesToOpen) {
  17482. var extraParams = extraUrlParameters || [];
  17483. // CANAV-3259: fetch base object for reportView usage
  17484. if (typesToOpen && typesToOpen.length > 0 && typesToOpen.indexOf('reportView') !== -1) {
  17485. extraParams.push('base.defaultName');
  17486. }
  17487. return extraParams;
  17488. },
  17489. renderFooter: function () {
  17490. var n = OpenDialog.inherited('renderFooter', this, arguments);
  17491. if (this.options.multiSelect) {
  17492. this._selectionCount = $('<span>', { 'class': 'selectionCount' });
  17493. var noOfItemSelected = StringResources.get('noOfItemSelected', {
  17494. 'noOfItems': 0
  17495. });
  17496. this._selectionCount.text(noOfItemSelected);
  17497. this._selectionCount.attr('aria-label', noOfItemSelected);
  17498. var footer = n.find('.footerContainer');
  17499. var clearSelection = $('<span class="clearSelection"><a role="button" tabindex="0"></a></span>');
  17500. footer.addClass('selectionCounter');
  17501. footer.prepend(clearSelection);
  17502. footer.prepend(this._selectionCount);
  17503. clearSelection = clearSelection.find('a');
  17504. clearSelection.text(StringResources.get('clearAllSelected'));
  17505. clearSelection.attr('aria-label', StringResources.get('clearAllSelected'));
  17506. clearSelection.on('primaryaction', function () {
  17507. if (this.view) {
  17508. this.view.clearAllSelected();
  17509. }
  17510. }.bind(this));
  17511. }
  17512. return n;
  17513. },
  17514. updateSelectionCount: function (count) {
  17515. var noOfItemSelected = StringResources.get('noOfItemSelected', {
  17516. 'noOfItems': count
  17517. });
  17518. this._selectionCount.text(noOfItemSelected);
  17519. },
  17520. /**
  17521. * Called when the dialog is opened
  17522. */
  17523. onOpen: function () {
  17524. var container = this._container();
  17525. container.addClass('openDialog');
  17526. container.find('.dialogHeader');
  17527. container.find('.modalDialog').addClass('contentListDialog');
  17528. container.find('footer').attr('role', 'contentinfo').attr('aria-label', StringResources.get('openDialogFooter'));
  17529. this.findFooterButton('open_button').disable();
  17530. },
  17531. /**
  17532. * Called when the save button is clicked
  17533. */
  17534. ok: function () {
  17535. if (this.options.onOpenCallback) {
  17536. this.options.onOpenCallback(this.view.getSelectedItems());
  17537. }
  17538. OpenDialog.inherited('ok', this, arguments);
  17539. this.hide();
  17540. },
  17541. /**
  17542. * Called when the cancel button is clicked
  17543. */
  17544. cancel: function () {
  17545. if (this.options.onCancelCallback) {
  17546. this.options.onCancelCallback();
  17547. }
  17548. OpenDialog.inherited('cancel', this, arguments);
  17549. },
  17550. setFocus: function () {
  17551. this._container().find('.dialogButton.secondary')[0].focus();
  17552. },
  17553. onDefaultAction: function () {
  17554. this.ok();
  17555. }
  17556. });
  17557. return OpenDialog;
  17558. });
  17559. define('text!bacontentnav/ui/views/templates/SaveAsView.html',[],function () { return '<!-- Licensed Materials - Property of IBM\n\n IBM Cognos Products: Cognos Analytics\n\n (C) Copyright IBM Corp. 2016\n\n US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.\n-->\n<div class="saveAsView">\n\t<div class="selectFolderView"></div>\n\t<div class="fileNameSection">\n\t\t<div class="saveAsLabel">{{!it.saveAsLabel}}</div>\n\t\t<input class="fileName" type="text" value="{{!it.defaultNameValue}}" aria-label="{{!it.saveAsLabel}}" tabindex="0">\n\t</div>\n</div>';});
  17560. /**
  17561. * Licensed Materials - Property of IBM
  17562. *
  17563. * IBM Cognos Products: ba-content-nav
  17564. *
  17565. * Copyright IBM Corp. 2015, 2020
  17566. *
  17567. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17568. */
  17569. define('bacontentnav/ui/views/SaveAsView',[
  17570. 'jquery',
  17571. '../../lib/@waca/core-client/js/core-client/ui/KeyCodes',
  17572. '../../lib/@waca/core-client/js/core-client/ui/core/View',
  17573. '../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  17574. '../../common/ContentSelectionDialogView',
  17575. '../../utils/ContentServiceUrls',
  17576. '../../utils/ContentStoreObject',
  17577. '../../utils/UIHelper',
  17578. '../../nls/StringResource',
  17579. 'text!./templates/SaveAsView.html'
  17580. ], function($, KeyCodes, BaseView, BidiUtil, ContentSelectionDialogView, ContentServiceUrls, ContentStoreObject, UIHelper, StringResources, template) {
  17581. /**
  17582. * SaveAs view. This class renders a view with a folder selection section and an input to enter the file name.
  17583. *
  17584. * @param - options
  17585. *
  17586. * {
  17587. * 'glassContext': <glass context object> // Glass context object
  17588. * 'defaultFileName': 'some name', // Default file name value
  17589. * 'onOpen':function(){} // Callback when the view is opened
  17590. * 'onSelectionChange': function(selection){} // Callback when the folder selection has changed. The callback receives the selection object as a parameter
  17591. * }
  17592. *
  17593. */
  17594. var SaveAsView = BaseView.extend({
  17595. templateString: template,
  17596. events: {},
  17597. init: function(options) {
  17598. SaveAsView.inherited('init', this, arguments);
  17599. $.extend(this, options);
  17600. this._contentViewclass = this._contentViewClass || ContentSelectionDialogView;
  17601. },
  17602. render: function() {
  17603. this._createContentView();
  17604. this.contentView.render();
  17605. var nameInput = this.$('input.fileName');
  17606. nameInput.on('keydown', this._onKeyDown.bind(this));
  17607. BidiUtil.initElementForBidi(nameInput[0]);
  17608. },
  17609. _createContentView: function() {
  17610. this.$el.empty();
  17611. var sHtml = this.dotTemplate({
  17612. defaultNameValue: this.defaultFileName || this.glassContext.appController.currentAppView.currentContentView.title || '',
  17613. saveAsLabel: this.inputLabel || StringResources.get('saveAsLabel')
  17614. });
  17615. this.$el.append(sHtml);
  17616. this.contentView = new this._contentViewclass({
  17617. $el: this.$('.selectFolderView'),
  17618. 'glassContext': this.glassContext,
  17619. 'showBreadcrumbs': true,
  17620. 'showAddFolder': true,
  17621. 'url': this.url || ContentServiceUrls.getPublicFoldersContentURL(),
  17622. 'selfUrl': this.selfUrl || ContentServiceUrls.getPublicFoldersURL(),
  17623. 'ancestors': ContentStoreObject.getAncestors({ ancestors: this.ancestors }),
  17624. 'inputObjects': [],
  17625. 'alwaysShowTeamContent': this.alwaysShowTeamContent,
  17626. 'navigateCallback': function(data) {
  17627. this.onNavigation(data);
  17628. }.bind(this),
  17629. 'listControlCallback': this._updateSaveAsName.bind(this)
  17630. });
  17631. },
  17632. _onKeyDown: function(evt) {
  17633. var keyCode = evt.keyCode;
  17634. if (keyCode === KeyCodes.ENTER && this.getFileName().replace(/\s+/g, '').length !== 0) {
  17635. this.saveOnKeyDown();
  17636. // Return false to stop propagation, in the case where the dialog is destroyed by pressing enter, the focus goes back on the button that pressed it and re-open the dialog.
  17637. return false;
  17638. }
  17639. },
  17640. _updateSaveAsName: function(data) {
  17641. if (!UIHelper.isContainer(data.type)) {
  17642. var temp = this.$('input.fileName');
  17643. temp.attr('value', data.defaultName);
  17644. }
  17645. },
  17646. remove: function() {
  17647. SaveAsView.inherited('remove', this, arguments);
  17648. this.contentView.remove();
  17649. },
  17650. /**
  17651. * Get the current selection
  17652. */
  17653. getSelection: function() {
  17654. this.selection = {
  17655. 'url': this.contentView.url
  17656. };
  17657. return this.selection;
  17658. },
  17659. /**
  17660. * Get the filename value
  17661. */
  17662. getFileName: function() {
  17663. return this.$('.fileName').val();
  17664. },
  17665. /**
  17666. * Default selection change callback. To be provide by the called in the constructor options
  17667. */
  17668. onSelectionChange: function() {
  17669. // To be provided by caller in constructor options to handle selection change
  17670. }
  17671. });
  17672. return SaveAsView;
  17673. });
  17674. define('text!bacontentnav/ui/dialogs/template/saveAsProgressIndicator.html',[],function () { return '<div class="saveAsInProgress">\n <div class="saveAsInProgress__indicator"></div>\n <label class="saveAsInProgress__indicator-label">{{!it.loadText}}</label>\n</div>';});
  17675. /**
  17676. * Licensed Materials - Property of IBM
  17677. *
  17678. * IBM Cognos Products: ba-content-nav
  17679. *
  17680. * Copyright IBM Corp. 2015, 2020
  17681. *
  17682. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17683. */
  17684. define('bacontentnav/ui/dialogs/SaveAsDialog',['underscore',
  17685. '../../lib/@waca/core-client/js/core-client/ui/dialogs/ConfirmationDialog',
  17686. '../../lib/@waca/core-client/js/core-client/ui/dialogs/GenericViewDialog',
  17687. '../../lib/@waca/core-client/js/core-client/utils/BidiUtil',
  17688. '../views/SaveAsView',
  17689. '../../utils/UIHelper',
  17690. '../../utils/ContentStoreObject',
  17691. '../../utils/ContentServiceUrls',
  17692. '../../utils/GlassContextHelper',
  17693. '../../nls/StringResource',
  17694. 'text!./template/saveAsProgressIndicator.html',
  17695. 'ca-ui-toolkit',
  17696. 'react',
  17697. 'react-dom'
  17698. ],
  17699. function(_, ConfirmationDialog, GenericViewDialog, BidiUtil, SaveAsView, UIHelper, ContentStoreObject, ContentServiceUrls, GlassContextHelper, StringResource, saveAsProgressIndicatorTemplate, uiToolkit, React, ReactDOM) {
  17700. /**
  17701. * Create a save as dialog that will be used to select a folder and a file name.
  17702. * A service object can be passed to the dialog in order to implement the saving process and returns a Promise. Doing so will show an overwrite dialog if the promise returns an error.
  17703. * Note: If passing a service, onSave won't be called.
  17704. *
  17705. * @param - options
  17706. * {
  17707. * glassContext: <glassContextObject>, // Glass context object.
  17708. * defaultFileName: "some name", // Default file name to be used in the save dialog.
  17709. * onSave: function(selection, filename) {} // Callback when the location is selected. The callback has 3 parameters:
  17710. * 1 - Selected folder object
  17711. * 2 - File name string
  17712. * onHide: function() {} // Callback when dialog is hidden.
  17713. * viewOptions.url String , viewOptions.selfUrl String and viewOptions.ancestors Array of objects are three parameters
  17714. * to customize the initial folder when dialog opens
  17715. *
  17716. * service: {
  17717. * save: function (service, selection, filename, overwrite) // Save function returning a promise.
  17718. * : Promise() // The promise should be resolved when the save succeed, or can reject
  17719. * // with the following object: { isDuplicate: true }
  17720. * }
  17721. *
  17722. * }
  17723. *
  17724. */
  17725. var SaveAsDialog = GenericViewDialog.extend({
  17726. templateString: saveAsProgressIndicatorTemplate,
  17727. init: function(options) {
  17728. this.options = options;
  17729. var dialogOptions = _.defaults(options, {
  17730. 'buttons': [ {
  17731. 'text': StringResource.get('save'),
  17732. 'handler': this.ok.bind(this),
  17733. 'type': 'primary',
  17734. 'defaultId': 'save_button'
  17735. }, 'cancel' ],
  17736. 'viewClass': SaveAsView,
  17737. 'id': 'saveDialogTitle',
  17738. 'title': StringResource.get('saveDialogTitle'),
  17739. 'viewOptions': {
  17740. 'ancestors': this.isRenderFromReact() ? this.options.service.context.target.activeObject.ancestors : options.ancestors,
  17741. 'url': options.url,
  17742. 'selfUrl': options.selfUrl,
  17743. 'glassContext': options.glassContext,
  17744. 'defaultFileName': options.defaultFileName,
  17745. 'inputLabel': options.inputLabel,
  17746. 'alwaysShowTeamContent': options.alwaysShowTeamContent || false,
  17747. 'onOpen':this.onOpen.bind(this),
  17748. 'onHide':this.onHide.bind(this),
  17749. 'onNavigation': this._onNavi.bind(this),
  17750. 'saveOnKeyDown': this.ok.bind(this)
  17751. }
  17752. });
  17753. // clean up and use core services
  17754. this.glassContext = options.glassContext;
  17755. if (this.glassContext && this.glassContext.getCoreSvc) {
  17756. this.logger = this.glassContext.getCoreSvc('.Logger');
  17757. } else {
  17758. this.logger = { error: function() {} }; // unit test requires :(
  17759. }
  17760. this.inputEventAdded = false;
  17761. SaveAsDialog.inherited('init', this, [ dialogOptions ]);
  17762. },
  17763. _onNavi: function() {
  17764. this._updateButtons();
  17765. if(!this.inputEventAdded){
  17766. this.inputEventAdded = true;
  17767. this._container().find('.fileName').on('input', function() {
  17768. this._updateButtons();
  17769. }.bind(this));
  17770. }
  17771. },
  17772. _isSaveButtonDisabled: function() {
  17773. // check UI capabilities
  17774. var doesNotHaveWritePermission = false;
  17775. if (!this.view.getFileName().trim()) {
  17776. return Promise.resolve(true);
  17777. }
  17778. var saveAsCapabilities = UIHelper.getConfiguration('capabilities')['saveAs'];
  17779. if (saveAsCapabilities.publicFolder === false) {
  17780. // check for public folder
  17781. var selection = this.view.getSelection();
  17782. if (selection && selection.url === ContentServiceUrls.getPublicFoldersContentURL()) {
  17783. return Promise.resolve(true);
  17784. }
  17785. }
  17786. if (saveAsCapabilities.requiresParentWritePermissions === true) {
  17787. // check for write permissions of parent
  17788. var parentObj = this.view.contentView.parentObj;
  17789. if (parentObj && parentObj.permissions) {
  17790. doesNotHaveWritePermission = parentObj.permissions.indexOf('write') === -1;
  17791. return Promise.resolve(doesNotHaveWritePermission);
  17792. } else {
  17793. return this.view.contentView.getParentProperties().then(function() {
  17794. parentObj = this.view.contentView.parentObj;
  17795. if (parentObj && parentObj.permissions) {
  17796. doesNotHaveWritePermission = parentObj.permissions.indexOf('write') === -1;
  17797. }
  17798. return Promise.resolve(doesNotHaveWritePermission);
  17799. }.bind(this));
  17800. }
  17801. } else {
  17802. return Promise.resolve(false);
  17803. }
  17804. },
  17805. _updateButtons: function() {
  17806. return this._isSaveButtonDisabled().then(function(disabled) {
  17807. if (disabled) {
  17808. this.saveButton.disable();
  17809. } else {
  17810. this.saveButton.enable();
  17811. }
  17812. }.bind(this));
  17813. },
  17814. /**
  17815. * Called when the dialog is opened
  17816. */
  17817. onOpen: function() {
  17818. var container = this._container();
  17819. container.addClass('saveDialog');
  17820. container.find('.dialogHeader');
  17821. container.find('.modalDialog').addClass('contentListDialog');
  17822. container.find('footer').attr('role','contentinfo').attr('aria-label', StringResource.get('saveDialogFooter'));
  17823. this.saveButton = this.findFooterButton('save_button');
  17824. this._onNavi();
  17825. },
  17826. /**
  17827. * Called when the save button is clicked
  17828. */
  17829. ok: function() {
  17830. if (this.saveButton.isEnabled()) {
  17831. if (this.options.service) {
  17832. this._onSaveService(this.view.getSelection(), this.view.getFileName(), false);
  17833. } else {
  17834. this.options.onSave(this.view.getSelection(), this.view.getFileName());
  17835. }
  17836. } else {
  17837. GlassContextHelper.displayToast(this.glassContext, StringResource.get('toastNoCapabilityForContainer', {
  17838. 'nameOfContainer': BidiUtil.enforceTextDirection(this._getDestinationName())
  17839. }), {
  17840. 'type': 'warning'
  17841. });
  17842. }
  17843. },
  17844. /**
  17845. * Called on dialog hiding
  17846. */
  17847. onHide: function(){
  17848. if(this.options !== 'undefined' && _.isFunction(this.options.onHide)) {
  17849. this.options.onHide();
  17850. }
  17851. },
  17852. setFocus: function(){
  17853. this._container().find('.fileName')[0].focus();
  17854. },
  17855. _onSaveService: function(selection, name, overwrite) {
  17856. if (!_.isFunction(this.options.service.save)) {
  17857. this.logger.error('SaveAsDialog service save undefined.');
  17858. } else {
  17859. try {
  17860. this._doSaveService(selection, name, overwrite);
  17861. } catch (e) {
  17862. this.logger.error(e);
  17863. }
  17864. }
  17865. },
  17866. _renderProgressIndicator: function (){
  17867. var progressIndicatorEl = this.dotTemplate({
  17868. loadText: StringResource.get('loading')
  17869. });
  17870. // occupy the space to avoid dialog size changing due to min height
  17871. this._saveAsView = this.view.$el.find('.saveAsView');
  17872. this._saveAsView.addClass('invisible');//bootstrap class name
  17873. this.view.$el.append(progressIndicatorEl);
  17874. this._$saveAsInProgressIndicator = this.view.$el.find('.saveAsInProgress__indicator');
  17875. this._$saveAsInProgress = this.view.$el.find('.saveAsInProgress');
  17876. ReactDOM.render(React.createElement(uiToolkit.ProgressIndicator), this._$saveAsInProgressIndicator.get(0));
  17877. this.saveButton.disable();
  17878. },
  17879. _doSaveService: function(selection, name, overwrite) {
  17880. this._renderProgressIndicator();
  17881. var assets = this.view.contentView.getListControl().getDatatable().fnGetData();
  17882. this.options.service.save(this.options.service, selection, name, !!overwrite)
  17883. .catch(function(errorObject) {
  17884. if (errorObject) {
  17885. if (errorObject.isDuplicate === true) {
  17886. var sameNameFolder = _.filter(assets, function(asset){ return asset.defaultName === name && UIHelper.isContainer(asset.type); });
  17887. if(sameNameFolder.length > 0) {
  17888. GlassContextHelper.displayToast(this.glassContext, StringResource.get('toastSaveErrorSameNameDifferentType', {
  17889. 'nameOfItem': name
  17890. }), {
  17891. 'type': 'warning'
  17892. });
  17893. } else {
  17894. var oDialog = this._getConfirmRefreshDialog(name);
  17895. oDialog.confirm(function() {
  17896. this._onSaveService(selection, name, true);
  17897. }.bind(this));
  17898. }
  17899. } else if (errorObject.isReplaceFailed === true) {
  17900. GlassContextHelper.displayToast(this.glassContext, StringResource.get('toastSaveErrorSameNameDifferentType', {
  17901. 'nameOfItem': name
  17902. }), {
  17903. 'type': 'warning'
  17904. });
  17905. } else {
  17906. this.logger.error(errorObject);
  17907. }
  17908. }
  17909. }.bind(this)).finally(function(){
  17910. this._saveAsView.removeClass('invisible');//bootstrap class name
  17911. this._$saveAsInProgress.remove();
  17912. this.saveButton.enable();
  17913. if (this.isRenderFromReact()){
  17914. this.options.service.context.target.activeObject.onCloseSaveDialog();
  17915. }
  17916. }.bind(this));
  17917. },
  17918. isRenderFromReact: function() {
  17919. var renderFromReact = this.options.service
  17920. && this.options.service.context
  17921. && this.options.service.context.target
  17922. && this.options.service.context.target.activeObject
  17923. && this.options.service.context.target.activeObject.renderFromReact === true;
  17924. return renderFromReact;
  17925. },
  17926. _getConfirmRefreshDialog: function(fileName) {
  17927. return new ConfirmationDialog('confirmRefresh', StringResource.get('confirmRefreshUpload'), StringResource.get('msgConfirmRefreshUpload', {
  17928. fileName: fileName
  17929. }));
  17930. },
  17931. _getDestinationName: function() {
  17932. var destination = '';
  17933. if (this.view && this.view.contentView) {
  17934. var ancestors = this.view.contentView.ancestors;
  17935. if (ancestors) {
  17936. destination = ContentStoreObject.getName(ancestors[ancestors.length - 1]);
  17937. }
  17938. }
  17939. return destination;
  17940. }
  17941. });
  17942. return SaveAsDialog;
  17943. });
  17944. /*
  17945. *+------------------------------------------------------------------------+
  17946. *| Licensed Materials - Property of IBM
  17947. *| IBM Cognos Products: Content Explorer
  17948. *| (C) Copyright IBM Corp. 2018
  17949. *|
  17950. *| US Government Users Restricted Rights - Use, duplication or disclosure
  17951. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  17952. *+------------------------------------------------------------------------+
  17953. */
  17954. define('bacontentnav/services/ContentDialogFactory',[
  17955. '../ui/dialogs/OpenDialog',
  17956. '../ui/dialogs/SaveAsDialog'
  17957. ], function(OpenDialog, SaveAsDialog) {
  17958. var ContentDialogFactory = function() {};
  17959. ContentDialogFactory.prototype.createOpenDialog = function(options) {
  17960. return new OpenDialog(options);
  17961. };
  17962. ContentDialogFactory.prototype.createSaveAsDialog = function(options) {
  17963. return new SaveAsDialog(options);
  17964. };
  17965. return ContentDialogFactory;
  17966. });
  17967. define("js/content_apps/folderBundle", function(){});